diff options
author | Adrian Szyndela <adrian.s@samsung.com> | 2020-10-28 08:10:29 +0100 |
---|---|---|
committer | Adrian Szyndela <adrian.s@samsung.com> | 2020-10-30 12:37:28 +0100 |
commit | 861655ed3072bb21cdc2111baddd63845f7a2cd0 (patch) | |
tree | 8bb08c11f14457322574a433ec120fb153877bd7 | |
parent | 78f6d28c12222f43dc1fef678333d95005a19432 (diff) | |
download | libdbuspolicy-861655ed3072bb21cdc2111baddd63845f7a2cd0.tar.gz libdbuspolicy-861655ed3072bb21cdc2111baddd63845f7a2cd0.tar.bz2 libdbuspolicy-861655ed3072bb21cdc2111baddd63845f7a2cd0.zip |
printing: use generic data extracting interface
It eliminates any konwledge of Flatbuffers structures, types, and methods
of data extracting from the printing module.
Change-Id: I5da411f3878b8cb13e9962a7f6c994063446304a
-rw-r--r-- | src/internal/print_content.cpp | 242 | ||||
-rw-r--r-- | src/internal/print_content.hpp | 267 | ||||
-rw-r--r-- | src/internal/storage_backend_flatbuffers.cpp | 6 | ||||
-rw-r--r-- | src/internal/storage_backend_flatbuffers.hpp | 2 | ||||
-rw-r--r-- | src/internal/storage_backend_serialized.cpp | 5 | ||||
-rw-r--r-- | src/internal/storage_backend_serialized.hpp | 3 |
6 files changed, 284 insertions, 241 deletions
diff --git a/src/internal/print_content.cpp b/src/internal/print_content.cpp index cdded17..0264e9a 100644 --- a/src/internal/print_content.cpp +++ b/src/internal/print_content.cpp @@ -16,251 +16,37 @@ #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) diff --git a/src/internal/print_content.hpp b/src/internal/print_content.hpp index 78f6381..24369d5 100644 --- a/src/internal/print_content.hpp +++ b/src/internal/print_content.hpp @@ -17,15 +17,276 @@ #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 { diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index 868aa1f..1b0b84e 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -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 <> \ diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index 107c55b..f5181ff 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -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 diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp index 12959d3..8337ee0 100644 --- a/src/internal/storage_backend_serialized.cpp +++ b/src/internal/storage_backend_serialized.cpp @@ -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); diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index 9438f86..1074b76 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -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 |