printing: use generic data extracting interface 57/246357/2
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 28 Oct 2020 07:10:29 +0000 (08:10 +0100)
committerAdrian Szyndela <adrian.s@samsung.com>
Fri, 30 Oct 2020 11:37:28 +0000 (12:37 +0100)
It eliminates any konwledge of Flatbuffers structures, types, and methods
of data extracting from the printing module.

Change-Id: I5da411f3878b8cb13e9962a7f6c994063446304a

src/internal/print_content.cpp
src/internal/print_content.hpp
src/internal/storage_backend_flatbuffers.cpp
src/internal/storage_backend_flatbuffers.hpp
src/internal/storage_backend_serialized.cpp
src/internal/storage_backend_serialized.hpp

index cdded17..0264e9a 100644 (file)
 #include "policy.hpp"
 #include "print_content.hpp"
 #include "serialized_convert.hpp"
-#include <boost/algorithm/string/predicate.hpp>
+#include "storage_backend_xml_printing.hpp"
+#include <boost/utility/string_ref.hpp>
 #include <ostream>
 
-/************ PRINTING CONTENT ********************/
-std::ostream &print_content_item_own(std::ostream &stream, const std::string &name, bool is_prefix) {
-       return stream << "ItemOwn: service(" << (name.empty() ? "*" : name) << "), pref(" << is_prefix << ")";
-}
-
-namespace {
-const char* message_access[] = {"USER", "GROUP", "ALL_USERS", "ALL_GROUPS"};
-inline const char* __access_type_to_str(ldp_xml_parser::BusAccessType type) {
-       return message_access[static_cast<std::size_t>(type)];
-}
-}
-
-namespace print_content {
-static bool xml_format = false;
-void use_xml_format(const bool xml) {
-       xml_format = xml;
-}
-}
-
-template <typename T>
-std::ostream &print_val(std::ostream &stream, const boost::string_ref &name, const T &val) {
-       return stream << name << "(" << val << ")";
-}
-
-template <typename T>
-std::ostream &print_next_val(std::ostream &stream, const boost::string_ref &name, const T &val) {
-       stream << ", ";
-       return print_val(stream, name, val);
-}
-
-std::ostream &print_content_item_access(std::ostream &stream,
-                                                                               ldp_xml_parser::BusAccessType type,
-                                                                               uid_t uid,
-                                                                               gid_t gid,
-                                                                               const ldp_xml_parser::DecisionItem &decisionItem) {
-       stream << "ItemAccess: ";
-       print_val(stream, "type", __access_type_to_str(type));
-       print_next_val(stream, "uid", uid);
-       print_next_val(stream, "gid", gid);
-       return print_next_val(stream, "decision", decisionItem);
-}
-
-namespace {
-static const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL"};
-static inline const char* __message_type_to_str(ldp_xml_parser::MessageType type) {
-       return message_type[static_cast<std::size_t>(type)];
-}
-}
-
-std::ostream &print_content_item_sr(std::ostream &stream,
-                                                                       const boost::string_ref &item_type,
-                                                                       const boost::string_ref &name,
-                                                                       const boost::string_ref &interface,
-                                                                       const boost::string_ref &member,
-                                                                       const boost::string_ref &path,
-                                                                       ldp_xml_parser::MessageType type,
-                                                                       const ldp_xml_parser::DecisionItem &decisionItem,
-                                                                       const bool is_prefix)
-{
-       stream << item_type << ": ";
-       if (is_prefix)
-               print_val(stream, "name_prefix", name);
-       else
-               print_val(stream, "name", name);
-       print_next_val(stream, "inter", interface);
-       print_next_val(stream, "member", member);
-       print_next_val(stream, "path", path);
-       print_next_val(stream, "type", __message_type_to_str(type));
-       return print_next_val(stream, "decision", decisionItem);
-}
-
-std::ostream &print_content_item_sr_xml(std::ostream &stream,
-                                                                       const boost::string_ref &item_type,
-                                                                       const boost::string_ref &name,
-                                                                       const boost::string_ref &interface,
-                                                                       const boost::string_ref &member,
-                                                                       const boost::string_ref &path,
-                                                                       ldp_xml_parser::MessageType type,
-                                                                       const ldp_xml_parser::DecisionItem &decisionItem,
-                                                                       const bool is_prefix)
-{
-       const char *strDecision[] = {"any", "allow", "deny", "check"};
-       const char *sr;
-       std::string type_str;
-
-       if (item_type == "ItemSend")
-               sr = "send";
-       else
-               sr = "receive";
-
-       stream << "<" << strDecision[static_cast<std::size_t>(decisionItem.getDecision())] << " ";
-       if (is_prefix)
-               stream << sr << "_destination_prefix=\"" << name << "\" ";
-       else if (!name.empty())
-               stream << sr << "_" << (item_type == "ItemSend" ? "destination" : "sender") << "=\"" << name << "\" ";
-
-       if (!path.empty())
-               stream << sr << "_" << "path=\"" << path << "\" ";
-       if (!interface.empty())
-               stream << sr << "_" << "interface=\"" << interface << "\" ";
-       if (!member.empty())
-               stream << sr << "_" << "member=\"" << member << "\" ";
-       if (!decisionItem.getPrivilege().empty())
-               stream << sr << "_" << "privilege=\"" << decisionItem.getPrivilege() << "\" ";
-
-       type_str = __message_type_to_str(type);
-       std::transform(type_str.begin(), type_str.end(), type_str.begin(), [](unsigned char c){ return std::tolower(c); });
-
-       if (type_str != "any")
-               stream << sr << "_" << "type=\"" << type_str << "\" ";
-
-       return stream << "/>";
-}
-
-namespace {
-static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"};
-static inline const char* __decision_to_str(ldp_xml_parser::Decision dec) {
-       return message_decision[static_cast<std::size_t>(dec)];
-}
-}
-
-std::ostream &print_content_decision_item(std::ostream &stream,
-                                                                                 ldp_xml_parser::Decision decision,
-                                                                                 const boost::string_ref &privilege) {
-       stream << __decision_to_str(decision);
-       if (!privilege.empty())
-               stream << ":" << privilege;
-       return stream;
-}
-
-template <typename T>
-void printContentItem(std::ostream &stream, const T *item);
-
-template <> void printContentItem(std::ostream &stream, const FB::ItemAccess *item) {
-       print_content_item_access(stream, ldp_serialized::makeBusAccessType(item->type()), item->uid(),
-                       item->gid(), ldp_serialized::makeDecisionItem(item->decision()));
-}
-
-template <typename T>
-void printContentItemSR(std::ostream &stream, const boost::string_ref &item_type, const T *item) {
-       auto print_func = (print_content::xml_format ? print_content_item_sr_xml : print_content_item_sr);
-       print_func(stream, item_type, item->name()->c_str(), item->interface()->c_str(),
-                       item->member()->c_str(), item->path()->c_str(), ldp_serialized::makeMessageType(item->type()),
-                       ldp_serialized::makeDecisionItem(item->decision()), item->is_name_prefix());
-}
-
-template <> void printContentItem(std::ostream &stream, const FB::ItemSend *item) {
-       printContentItemSR(stream, "ItemSend", item);
-}
-
-template <> void printContentItem(std::ostream &stream, const FB::ItemReceive *item) {
-       printContentItemSR(stream, "ItemReceive", item);
-}
-
-template <typename T>
-void printContentPolicy(std::ostream &stream, const T *policy) {
-       for (const auto *i: *policy->items()) {
-               printContentItem(stream, i);
-               stream << std::endl;
-       }
-}
-
-void printDecisionItem(std::ostream &stream, const FB::DecisionItem *item) {
-       print_content_decision_item(stream, ldp_serialized::makeDecision(item->decision()), item->privilege()->c_str());
-}
-
-void printTreeLevel(std::ostream &stream, const FB::PolicyOwnNode *node, unsigned indent) {
-       for (decltype(indent) i = 0; i < indent; ++i)
-               stream << "\t";
-       stream << "| " << node->token()->c_str() << " (" << node->children()->size() << ") | ";
-       printDecisionItem(stream, node->decision_item());
-       stream << " ";
-       printDecisionItem(stream, node->prefix_decision_item());
-       stream << std::endl;
-
-       for (const auto &i: *node->children())
-               printTreeLevel(stream, i, indent+1);
-}
-
-template <> void printContentPolicy(std::ostream &stream, const FB::PolicyOwn *policy) {
-       printTreeLevel(stream, policy->tree(), 0);
-}
-
-template <typename T>
-void printContentUserGroup(std::ostream &stream, const T *set) {
-       for (const auto *i: *set->user()) {
-               stream << "user: " << i->id() << std::endl;
-               printContentPolicy(stream, i->policy());
-       }
-
-       for (const auto *i: *set->group()) {
-               stream << "group: " << i->id() << std::endl;
-               printContentPolicy(stream, i->policy());
-       }
-}
-
-template <> void printContentUserGroup(std::ostream &, const FB::AccessSet *) {}
-
-template <typename T>
-void printContentSet(std::ostream &stream, const T *set) {
-       stream << "context default" << std::endl;
-       printContentPolicy(stream, set->context_default());
-       stream << "context mandatory" << std::endl;
-       printContentPolicy(stream, set->context_mandatory());
-
-       printContentUserGroup(stream, set);
-}
-
-namespace FB {
-std::ostream &operator<<(std::ostream &stream, const FB::File &file) {
-       printContentSet(stream, file.m_own_set());
-       printContentSet(stream, file.m_send_set());
-       printContentSet(stream, file.m_receive_set());
-       printContentSet(stream, file.m_access_set());
-       return stream;
-}
-}
+using namespace print_content;
 
 /********* PRINTING ITEMS PARSED FROM XML *******************/
 namespace ldp_xml_parser {
 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemOwn &item) {
-       return print_content_item_own(stream, item.getName(), item.isPrefix());
+       auto name = item.getName();
+       return stream << "ItemOwn: service(" << (name.empty() ? "*" : name) << "), pref(" << item.isPrefix() << ")";
 }
 
 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemSend &item) {
-       auto print_func = (print_content::xml_format ? print_content_item_sr_xml : print_content_item_sr);
-       return print_func(stream, "ItemSend", item.getName(), item.getInterface(), item.getMember(),
-                       item.getPath(), item.getType(), item.getDecision(), item.isNamePrefix());
+       contentPrinter(ldp_xml_parser::StorageBackendXMLPrinting(), stream).printItem(item, ldp_serialization::SendType());
+       return stream;
 }
 
 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemReceive &item) {
-       auto print_func = (print_content::xml_format ? print_content_item_sr_xml : print_content_item_sr);
-       return print_func(stream, "ItemReceive", item.getName(), item.getInterface(), item.getMember(),
-                       item.getPath(), item.getType(), item.getDecision(), item.isNamePrefix());
+       contentPrinter(ldp_xml_parser::StorageBackendXMLPrinting(), stream).printItem(item, ldp_serialization::ReceiveType());
+       return stream;
 }
 
 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemAccess &item) {
-       return print_content_item_access(stream, item.getType(), item.getUid(), item.getGid(), item.getDecision());
+       contentPrinter(ldp_xml_parser::StorageBackendXMLPrinting(), stream).printItem(item, ldp_serialization::AccessType());
+       return stream;
 }
 
 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::DecisionItem &item) {
-       return print_content_decision_item(stream, item.getDecision(), item.getPrivilege());
+       contentPrinter(ldp_xml_parser::StorageBackendXMLPrinting(), stream).printDecisionItem(item);
+       return stream;
 }
 std::ostream &operator<<(std::ostream& stream, const MatchItemOwn &item)
 {
@@ -274,7 +60,7 @@ std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemSR
                stream << name << " ";
 
        return stream << "), interface(" << item.interface << "), member(" << item.member <<
-               "), path(" << item.path << "), type(" << __message_type_to_str(item.type) << ")";
+               "), path(" << item.path << "), type(" << ContentPrinterXMLData::messageTypeToStr(item.type) << ")";
 }
 
 std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemSend &item)
index 78f6381..24369d5 100644 (file)
 
 #include "include/fb_generated.h"
 #include "policy.hpp"
+#include "serialization_traits.hpp"
+#include "serialized_convert.hpp"
 
+#include <boost/utility/string_ref.hpp>
 #include <ostream>
+#include <type_traits>
 
 namespace print_content {
-void use_xml_format(const bool xml);
+
+class ContentPrinterXMLData {
+public:
+       static constexpr const char *decisionToStr(ldp_xml_parser::Decision dec) {
+               const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"};
+               return message_decision[static_cast<std::size_t>(dec)];
+       }
+
+       static constexpr const char *accessTypeToStr(ldp_xml_parser::BusAccessType type) {
+               const char* message_access[] = {"USER", "GROUP", "ALL_USERS", "ALL_GROUPS"};
+               return message_access[static_cast<std::size_t>(type)];
+       }
+
+       static constexpr const char *messageTypeToStr(ldp_xml_parser::MessageType type) {
+               const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL"};
+               return message_type[static_cast<std::size_t>(type)];
+       }
+};
+
+template <typename StorageBackendDatabase>
+class ContentPrinter {
+       const StorageBackendDatabase &__db;
+
+       std::ostream &__stream;
+       bool __xml_format;
+
+       void printDecisionItem(ldp_xml_parser::Decision decision,
+                              const boost::string_ref &privilege) {
+               __stream << ContentPrinterXMLData::decisionToStr(decision);
+               if (!privilege.empty())
+                       __stream << ":" << privilege;
+       }
+
+       template <typename T>
+       void printVal(const boost::string_ref &name, const T &val) {
+               __stream << name << "(" << val << ")";
+       }
+
+       template <typename T>
+       void printValFun(const boost::string_ref &name, const T &fun) {
+               __stream << name << "(";
+               fun();
+               __stream << ")";
+       }
+
+       template <typename T>
+       void printNextVal(const boost::string_ref &name, const T &val) {
+               __stream << ", ";
+               printVal(name, val);
+       }
+
+       template <typename T>
+       void printNextValFun(const boost::string_ref &name, const T &fun) {
+               __stream << ", ";
+               printValFun(name, fun);
+       }
+
+       void printItemSRXML(boost::string_ref item_type,
+                               boost::string_ref name,
+                               boost::string_ref interface,
+                               boost::string_ref member,
+                               boost::string_ref path,
+                               ldp_xml_parser::MessageType type,
+                               const ldp_xml_parser::Decision &decision,
+                               boost::string_ref decisionPrivilege,
+                               const bool is_prefix) {
+               const char *strDecision[] = {"any", "allow", "deny", "check"};
+               std::string type_str;
+
+               __stream << "<" << strDecision[static_cast<std::size_t>(decision)] << " ";
+               if (is_prefix)
+                       __stream << item_type << "_destination_prefix=\"" << name << "\" ";
+               else if (!name.empty())
+                       __stream << item_type << "_" << (item_type == "send" ? "destination" : "sender") << "=\"" << name << "\" ";
+
+               if (!path.empty())
+                       __stream << item_type << "_" << "path=\"" << path << "\" ";
+               if (!interface.empty())
+                       __stream << item_type << "_" << "interface=\"" << interface << "\" ";
+               if (!member.empty())
+                       __stream << item_type << "_" << "member=\"" << member << "\" ";
+               if (!decisionPrivilege.empty())
+                       __stream << item_type << "_" << "privilege=\"" << decisionPrivilege << "\" ";
+
+               type_str = ContentPrinterXMLData::messageTypeToStr(type);
+               std::transform(type_str.begin(), type_str.end(), type_str.begin(), [](unsigned char c){ return std::tolower(c); });
+
+               if (type_str != "any")
+                       __stream << item_type << "_" << "type=\"" << type_str << "\" ";
+
+               __stream << "/>";
+       }
+
+       template <typename String>
+       boost::string_ref toStringRef(const String &str) const {
+               return boost::string_ref(__db.stringGetCStr(str), __db.stringGetSize(str));
+       }
+
+public:
+       ContentPrinter(const StorageBackendDatabase &database, std::ostream &stream, bool xml_format = false)
+       : __db{database},
+         __stream{stream},
+         __xml_format{xml_format}
+       {}
+
+       template <typename DecisionItem>
+       void printDecisionItem(const DecisionItem &decision_item) {
+               printDecisionItem(ldp_serialized::makeDecision(__db.decisionItemGetDecision(decision_item)),
+                                                              __db.stringGetCStr(__db.decisionItemGetPrivilege(decision_item)));
+       }
+
+       template <typename ItemSR>
+       void printItemSRXML(const ItemSR &item, boost::string_ref item_type) {
+               auto decisionItem = __db.itemGetDecisionItem(item);
+               printItemSRXML(item_type,
+                                  toStringRef(__db.itemSrGetName(item)),
+                                          toStringRef(__db.itemSrGetInterface(item)),
+                                          toStringRef(__db.itemSrGetMember(item)),
+                                          toStringRef(__db.itemSrGetPath(item)),
+                                          ldp_serialized::makeMessageType(__db.itemSrGetMessageType(item)),
+                                          ldp_serialized::makeDecision(__db.decisionItemGetDecision(decisionItem)),
+                                          toStringRef(__db.decisionItemGetPrivilege(decisionItem)),
+                                          __db.itemSrGetIsNamePrefix(item));
+       }
+
+       template <typename ItemSR>
+       void printItemSRText(const ItemSR &item, boost::string_ref item_type) {
+               __stream << item_type << ": ";
+               auto name = toStringRef(__db.itemSrGetName(item));
+               if (__db.itemSrGetIsNamePrefix(item))
+                       printVal("name_prefix", name);
+               else
+                       printVal("name", name);
+               printNextVal("inter", toStringRef(__db.itemSrGetInterface(item)));
+               printNextVal("member", toStringRef(__db.itemSrGetMember(item)));
+               printNextVal("path", toStringRef(__db.itemSrGetPath(item)));
+               auto message_type = ldp_serialized::makeMessageType(__db.itemSrGetMessageType(item));
+               printNextVal("type", ContentPrinterXMLData::messageTypeToStr(message_type));
+               printNextValFun("decision", [&] { printDecisionItem(__db.itemGetDecisionItem(item)); });
+       }
+
+       template <typename ItemSR>
+       void printItemSR(const ItemSR &item, boost::string_ref item_type, boost::string_ref item_type_xml) {
+               if (__xml_format)
+                       printItemSRXML(item, item_type_xml);
+               else
+                       printItemSRText(item, item_type);
+       }
+
+       template <typename Item>
+       void printItem(const Item &item, ldp_serialization::SendType) {
+               printItemSR(item, "ItemSend", "send");
+       }
+
+       template <typename Item>
+       void printItem(const Item &item, ldp_serialization::ReceiveType) {
+               printItemSR(item, "ItemReceive", "receive");
+       }
+
+       template <typename Item>
+       void printItem(const Item &item, ldp_serialization::AccessType) {
+               __stream << "ItemAccess: ";
+               auto type = ldp_serialized::makeBusAccessType(__db.itemAccessGetType(item));
+               printVal("type", ContentPrinterXMLData::accessTypeToStr(type));
+               printNextVal("uid", __db.itemAccessGetUid(item));
+               printNextVal("gid", __db.itemAccessGetGid(item));
+               printNextValFun("decision", [&] { printDecisionItem(__db.itemGetDecisionItem(item)); });
+       }
+
+       template <typename Item>
+       void printItem(const Item &item)
+       {
+               printItem(item, typename ldp_serialization::ItemType<Item>::result());
+       }
+
+       template <typename Policy>
+       void printPolicy(const Policy &policy, ldp_serialization::ItemsType) {
+               auto items = __db.policyGetItems(policy);
+               auto end = __db.containerGetIteratorEnd(items);
+               for (auto i = __db.containerGetIterator(items); i != end; i++) {
+                       printItem(*i);
+                       __stream << std::endl;
+               }
+       }
+
+       template <typename PolicyOwnNode>
+       void printTreeLevel(const PolicyOwnNode &node, unsigned level) {
+               for (decltype(level) i = 0; i < level; ++i)
+                       __stream << "\t";
+
+               __stream << "| " << __db.stringGetCStr(__db.ownNodeGetToken(node)) << " (" << __db.containerGetSize(__db.ownNodeGetChildren(node)) << ") | ";
+               printDecisionItem(__db.ownNodeGetDecisionItem(node));
+               __stream << " ";
+               printDecisionItem(__db.ownNodeGetPrefixDecisionItem(node));
+               __stream << std::endl;
+
+               auto children = __db.ownNodeGetChildren(node);
+               auto end = __db.containerGetIteratorEnd(children);
+               for (auto i = __db.containerGetIterator(children); i != end; i++)
+                       printTreeLevel(*i, level+1);
+       }
+
+       template <typename Policy>
+       void printPolicy(const Policy &policy, ldp_serialization::TreeType) {
+               printTreeLevel(__db.policyGetTree(policy), 0);
+       }
+
+       template <typename Policy>
+       void printPolicy(const Policy &policy) {
+               printPolicy(policy, typename ldp_serialization::PolicyContentType<Policy>::result());
+       }
+
+       template <typename SetUserGroup>
+       void printSetUserGroupMap(const SetUserGroup &set_user_group, const char *message) {
+               auto end = __db.containerGetIteratorEnd(set_user_group);
+               for (auto i = __db.containerGetIterator(set_user_group); i != end; i++) {
+                       __stream << message << ": " << __db.setUserGroupGetId(*i) << std::endl;
+                       printPolicy(__db.setUserGroupGetPolicy(*i));
+               }
+       }
+
+       template <typename Set>
+       void printSetUserGroup(const Set &set, std::true_type) {
+               printSetUserGroupMap(__db.setGetUser(set), "user");
+               printSetUserGroupMap(__db.setGetGroup(set), "group");
+       }
+
+       template <typename Set>
+       void printSetUserGroup(const Set &, std::false_type)
+       {
+               // print nothing for sets without user and group maps
+       }
+
+       template <typename Set>
+       void printSet(const Set &set) {
+               __stream << "context default" << std::endl;
+               printPolicy(__db.setGetContextDefault(set));
+               __stream << "context mandatory" << std::endl;
+               printPolicy(__db.setGetContextMandatory(set));
+
+               printSetUserGroup(set, typename ldp_serialization::HasUserGroup<Set>::result());
+       }
+
+       template <typename File>
+       std::ostream &printFile(const File &file) {
+               printSet(__db.fileGetOwnSet(file));
+               printSet(__db.fileGetSendSet(file));
+               printSet(__db.fileGetReceiveSet(file));
+               printSet(__db.fileGetAccessSet(file));
+               return __stream;
+       }
+
+       std::ostream &printContent() {
+               return printFile(__db.getFile());
+       }
+};
+
+template <typename DB>
+auto contentPrinter(const DB &db, std::ostream &stream, bool xml_format = false) {
+       return ContentPrinter<DB>(db, stream, xml_format);
 }
 
-namespace FB {
-std::ostream &operator<<(std::ostream &stream, const FB::File &file);
 }
 
 namespace ldp_xml_parser {
index 868aa1f..1b0b84e 100644 (file)
@@ -14,7 +14,6 @@
  * limitations under the License.
 */
 #include "include/fb_generated.h"
-#include "print_content.hpp"
 #include "serialized_convert.hpp"
 #include "storage_backend_flatbuffers.hpp"
 #include "tslog.hpp"
@@ -208,11 +207,6 @@ bool StorageBackendFlatbuffers::initFromData(const uint8_t *mem, size_t size, bo
        return file != nullptr;
 }
 
-void StorageBackendFlatbuffers::printContent(const bool xml_format) const {
-       print_content::use_xml_format(xml_format);
-       std::cerr << *file;
-}
-
 /*************************************************/
 #define TYPE_HELPER(T, t) \
        template <> \
index 107c55b..f5181ff 100644 (file)
@@ -31,8 +31,6 @@ public:
        bool initFromData(const uint8_t *serialized_data, size_t length, bool verify);
        void release();
 
-       void printContent(const bool xml_format = false) const;
-
        // Supported template parameters are:
        // MatchPolicyOwn, MatchPolicySend, MatchPolicyReceive
        // and - only for Contexts - MatchPolicyAccess
index 12959d3..8337ee0 100644 (file)
@@ -20,6 +20,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE. */
 
+#include "print_content.hpp"
 #include "storage_backend_serialized.hpp"
 #include "transaction_guard.hpp"
 #include "tslog.hpp"
@@ -90,6 +91,10 @@ bool StorageBackendSerialized::initFromData(const uint8_t *serialized_data, size
        return impl.initFromData(serialized_data, length, verify);
 }
 
+void StorageBackendSerialized::printContent(bool xml_format) const {
+       print_content::contentPrinter(impl, std::cerr, xml_format).printContent();
+}
+
 void StorageBackendSerialized::releaseMMap() {
        assert(MAP_FAILED != __mem);
        assert(0 != __length);
index 9438f86..1074b76 100644 (file)
@@ -37,8 +37,7 @@ public:
        bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false);
        void release();
 
-       void printContent(bool xml_format = false) const
-       { impl.printContent(xml_format); }
+       void printContent(bool xml_format = false) const;
 
        // Supported template parameters are:
        // MatchItemOwn, MatchItemSend, MatchItemReceive