refactoring: move generalized operations to StorageBackendSerialized 61/246361/2
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 28 Oct 2020 10:10:58 +0000 (11:10 +0100)
committerAdrian Szyndela <adrian.s@samsung.com>
Fri, 30 Oct 2020 11:47:33 +0000 (12:47 +0100)
Change-Id: I9abb90ff1d81970d939ca3f80b784c9b7b60ab23

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 feba813..f2a5bec 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
 */
-#include "include/fb_generated.h"
-#include "serialized_convert.hpp"
 #include "storage_backend_flatbuffers.hpp"
-#include "tslog.hpp"
-#include <boost/tokenizer.hpp>
-#include <string>
 
 using namespace FB;
 using ldp_xml_parser::MatchItemSend;
@@ -32,171 +27,6 @@ const unsigned int FB_ID_SIZE = 4;
 
 } // anonymous namespace
 
-template <typename T>
-struct type_helper;
-
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::makeDecisionItem(const DecisionItem *item) const {
-       return ldp_xml_parser::DecisionItem(makeDecision(decisionItemGetDecision(item)),
-                                                        stringGetCStr(decisionItemGetPrivilege(item)));
-}
-
-boost::string_ref StorageBackendFlatbuffers::toStringRef(const flatbuffers::String *str) const {
-       return boost::string_ref(stringGetCStr(str), stringGetSize(str));
-}
-
-template <typename T, typename I>
-bool StorageBackendFlatbuffers::match(const T &match, const I *i) const {
-       return match.match(makeMessageType(itemSrGetMessageType(i)),
-                                          toStringRef(itemSrGetInterface(i)),
-                                          toStringRef(itemSrGetPath(i)),
-                                          toStringRef(itemSrGetMember(i)),
-                                          toStringRef(itemSrGetName(i)),
-                                          itemSrGetIsNamePrefix(i),
-                                          makeDecision(decisionItemGetDecision(itemGetDecisionItem(i))));
-}
-
-bool StorageBackendFlatbuffers::match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const {
-       return match.match(makeBusAccessType(itemAccessGetType(item)), itemAccessGetUid(item), itemAccessGetGid(item));
-}
-
-template <typename T, typename P = typename type_helper<T>::policy_type>
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, const P *policy, ldp_serialization::ItemsType) const {
-       const auto *v = policyGetItems(policy);
-       auto rend = containerGetReverseIteratorEnd(v);
-       for (auto rit = containerGetReverseIterator(v); rit != rend; ++rit) {
-               if (match(item, *rit))
-                       return makeDecisionItem(itemGetDecisionItem(*rit));
-       }
-       return ldp_xml_parser::Decision::ANY;
-}
-
-auto StorageBackendFlatbuffers::getDecisionItemFromTree(const FB::PolicyOwnNode *node,
-                                                        const tokenizer::iterator &tokens_end,
-                                                        tokenizer::iterator &iterator) const {
-       if (iterator == tokens_end) {
-               if (makeDecision(decisionItemGetDecision(ownNodeGetDecisionItem(node))) != ldp_xml_parser::Decision::ANY)
-                       return ownNodeGetDecisionItem(node);
-               else
-                       return ownNodeGetPrefixDecisionItem(node);
-       }
-
-       auto children = ownNodeGetChildren(node);
-
-       if (containerEmpty(children))
-               return ownNodeGetPrefixDecisionItem(node);
-
-       auto child = containerLookupByKey(children, iterator->c_str());
-       if (!child.first)
-               return ownNodeGetPrefixDecisionItem(node);
-
-       ++iterator;
-       auto child_decision = getDecisionItemFromTree(child.second, tokens_end, iterator);
-       if (makeDecision(decisionItemGetDecision(child_decision)) == ldp_xml_parser::Decision::ANY)
-               return ownNodeGetPrefixDecisionItem(node);
-
-       return child_decision;
-}
-
-template <>
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const ldp_xml_parser::MatchItemOwn &item,
-                                                                        const PolicyOwn *policy,
-                                                                        ldp_serialization::TreeType) const {
-       if (item.getName().length() == 0)
-               return ldp_xml_parser::Decision::DENY;
-
-       boost::char_separator<char> separator(".");
-       tokenizer tokens(item.getName(), separator);
-
-       auto iterator = tokens.begin();
-
-       return makeDecisionItem(getDecisionItemFromTree(policyGetTree(policy), tokens.end(), iterator));
-}
-
-template <typename MatchItem, typename Map>
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const MatchItem &item, const Map &map, id_t id) const {
-       if (containerEmpty(map))
-               return ldp_xml_parser::Decision::ANY;
-
-       auto elem = containerLookupByKey(map, id);
-       if (!elem.first)
-               return ldp_xml_parser::Decision::ANY;
-       return getDecisionItem(item, setUserGroupGetPolicy(elem.second));
-}
-
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const MatchItemSend &item, const FB::PolicySend *policy) const {
-
-       if (!policyHasIndex(policy))
-               return getDecisionItem(item, policy, ldp_serialization::ItemsType());   // make it old way for old databases
-
-       auto index = policyGetIndex(policy);
-
-       uint32_t currentBest = 0;
-
-       auto updateCurrentBest = [&currentBest, &item, &policy, this](const auto &vec) {
-               // look from the back, the rule is the same as for the full database
-               // we now only check among less elements, because the database is indexed to small lists
-               // item_scores are in increasing order in the index, and they serve also as ids of the policy rules
-               for (auto item_score_it = containerGetReverseIterator(vec);
-                    item_score_it != containerGetReverseIteratorEnd(vec);
-                    item_score_it++) {
-                       auto db_items = policyGetItems(policy);
-                       auto db_item = containerLookupByIndex(db_items, *item_score_it - 1); // rules are indexed/scored from 1
-                       if (*item_score_it > currentBest && match(item, db_item)) {
-                               currentBest = *item_score_it;
-                               return;
-                       } else if (*item_score_it <= currentBest) {
-                               // there is no need to look further as we can't improve the score anymore
-                               return;
-                       }
-               }
-       };
-
-       auto searchAndUpdateCurrentBest = [&currentBest, &index, &updateCurrentBest, this](boost::string_ref name_ref) {
-               // we need to create C-string for flatbuffers lookups
-               // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify
-               // input string and keeps only the length
-               std::string name(name_ref.data(), name_ref.size());
-
-               if (containerEmpty(index))
-                       return;
-
-               // check if there are any rules for the name
-               auto fit = containerLookupByKey(index, name.c_str());
-               if (!fit.first)
-                       return;
-
-               // check if there's any chance to get better score
-               if (policyIndexGetBestScore(fit.second) <= currentBest)
-                       return;
-
-               // look for better score
-               updateCurrentBest(policyIndexGetItemRefs(fit.second));
-       };
-
-       auto prefixIndex = policyGetPrefixIndex(policy);
-
-       // iterate over names
-       for (const auto &name: item.getNames()) {
-               // find and check the no-prefix rules
-               searchAndUpdateCurrentBest(name);
-
-               // check the prefix rules
-               updateCurrentBest(prefixIndex);
-       }
-
-       // check no-name rules
-       searchAndUpdateCurrentBest("");
-
-       // if a matching rule was found, return the decision
-       if (currentBest > 0) {
-               auto db_item = containerLookupByIndex(policyGetItems(policy), currentBest - 1);
-               return makeDecisionItem(itemGetDecisionItem(db_item));
-       }
-
-       // or if no matching rule was not found, return the default decision
-       return ldp_xml_parser::Decision::ANY;
-}
-
 void StorageBackendFlatbuffers::release() {
        file = nullptr;
 }
@@ -225,81 +55,4 @@ bool StorageBackendFlatbuffers::initFromData(const uint8_t *mem, size_t size, bo
        return file != nullptr;
 }
 
-/*************************************************/
-#define TYPE_HELPER(T, t) \
-       template <> \
-       struct type_helper<ldp_xml_parser::MatchItem##T> { \
-               typedef FB::T##Set policy_set_type; \
-               typedef FB::Policy##T policy_type; \
-       }; \
-       template <> \
-       auto StorageBackendFlatbuffers::getPolicySet<ldp_xml_parser::MatchItem##T>() const { \
-               assert(file); \
-               return fileGet##T##Set(getFile()); \
-       }
-
-TYPE_HELPER(Own, own)
-TYPE_HELPER(Send, send)
-TYPE_HELPER(Receive, receive)
-TYPE_HELPER(Access, access)
-
-template <typename T, typename P>
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, P policy) const {
-       return getDecisionItem(item, policy, typename ldp_serialization::PolicyContentType<P>::result());
-}
-
-template <typename T>
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const T &item) const {
-       return getDecisionItem(item, setGetContextMandatory(getPolicySet<T>()));
-}
-
-template <typename T>
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const T &item) const {
-       return getDecisionItem(item, setGetContextDefault(getPolicySet<T>()));
-}
-
-template <typename T>
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const T &item) const {
-       return getDecisionItem(item, setGetUser(getPolicySet<T>()), uid);
-}
-template <typename T>
-ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const T &item) const {
-       return getDecisionItem(item, setGetGroup(getPolicySet<T>()), gid);
-}
-
-template <typename T>
-bool StorageBackendFlatbuffers::existsPolicyForGroup(gid_t gid) const {
-       auto map = setGetGroup(getPolicySet<T>());
-
-       if (containerEmpty(map))
-               return false;
-
-       return containerLookupByKey(map, gid).first;
-}
-
-#define T_INSTANTIATION(T) \
-       template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const ldp_xml_parser::MatchItem##T &item) const; \
-       template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const ldp_xml_parser::MatchItem##T &item) const;
-
-T_INSTANTIATION(Own)
-T_INSTANTIATION(Send)
-T_INSTANTIATION(Receive)
-T_INSTANTIATION(Access)
-
-#undef T_INSTANTIATION
-
-#define T_INSTANTIATION2(T) \
-       template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const ldp_xml_parser::MatchItem##T &item) const; \
-       template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const ldp_xml_parser::MatchItem##T &item) const; \
-       template bool StorageBackendFlatbuffers::existsPolicyForGroup<ldp_xml_parser::MatchItem##T>(gid_t) const;
-
-T_INSTANTIATION2(Own)
-T_INSTANTIATION2(Send)
-T_INSTANTIATION2(Receive)
-
-#undef T_INSTANTIATION2
-
-StorageBackendFlatbuffers::StorageBackendFlatbuffers() {}
-StorageBackendFlatbuffers::~StorageBackendFlatbuffers() {}
-
 }
index cf7d4e1..d0291aa 100644 (file)
 #include "include/fb_generated.h"
 #include "policy.hpp"
 #include "serialization_traits.hpp"
-#include <boost/tokenizer.hpp>
 #include <memory>
 
 namespace ldp_serialized {
 
 class StorageBackendFlatbuffers {
 public:
-       StorageBackendFlatbuffers();
-       ~StorageBackendFlatbuffers();
-
        bool initFromData(const uint8_t *serialized_data, size_t length, bool verify);
        void release();
 
-       // Supported template parameters are:
-       // MatchPolicyOwn, MatchPolicySend, MatchPolicyReceive
-       // and - only for Contexts - MatchPolicyAccess
-       template <typename T>
-       ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const T &item) const;
-       template <typename T>
-       ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const T &item) const;
-       template <typename T>
-       ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const T &item) const;
-       template <typename T>
-       ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const;
-
-       // This works with T set to MatchItemOwn, MatchItemSend or MatchItemReceive
-       // This is needed for filtering mapGroups. Check NaivePolicyChecker.
-       template <typename T>
-       bool existsPolicyForGroup(gid_t gid) const;
-
        const FB::File *getFile() const
        { return file; }
 
@@ -205,40 +184,8 @@ public:
        size_t stringGetSize(const flatbuffers::String *str) const
        { return str->size(); }
 
-       typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
-
 private:
        const FB::File *file{nullptr};
-
-       template <typename MatchItem>
-       auto getPolicySet() const;
-
-       template <typename T, typename P>
-       ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy, ldp_serialization::ItemsType) const;
-
-       template <typename T, typename P>
-       ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy, ldp_serialization::TreeType) const;
-
-       template <typename T, typename P>
-       ldp_xml_parser::DecisionItem getDecisionItem(const T &item, P policy) const;
-
-       ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const FB::PolicySend *policy) const;
-
-       template <typename MatchItem, typename Map>
-       ldp_xml_parser::DecisionItem getDecisionItem(const MatchItem &item, const Map &map, id_t id) const;
-
-       auto getDecisionItemFromTree(const FB::PolicyOwnNode *node,
-                                    const tokenizer::iterator &tokens_end,
-                                    tokenizer::iterator &iterator) const;
-
-       template <typename T, typename I>
-       bool match(const T &match, const I *i) const;
-
-       bool match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const;
-
-       ldp_xml_parser::DecisionItem makeDecisionItem(const FB::DecisionItem *item) const;
-
-       boost::string_ref toStringRef(const flatbuffers::String *str) const;
 };
 
 }
index 8337ee0..ac3c5bc 100644 (file)
  * THE SOFTWARE. */
 
 #include "print_content.hpp"
+#include "serialized_convert.hpp"
 #include "storage_backend_serialized.hpp"
 #include "transaction_guard.hpp"
 #include "tslog.hpp"
+#include <boost/tokenizer.hpp>
 #include <cassert>
 #include <fcntl.h>
 #include <sys/mman.h>
@@ -123,3 +125,239 @@ void StorageBackendSerialized::release() {
 
        impl.release();
 }
+
+template <> auto StorageBackendSerialized::getPolicySet<ldp_xml_parser::MatchItemOwn>() const {
+       return impl.fileGetOwnSet(impl.getFile());
+}
+
+template <> auto StorageBackendSerialized::getPolicySet<ldp_xml_parser::MatchItemSend>() const {
+       return impl.fileGetSendSet(impl.getFile());
+}
+
+template <> auto StorageBackendSerialized::getPolicySet<ldp_xml_parser::MatchItemReceive>() const {
+       return impl.fileGetReceiveSet(impl.getFile());
+}
+
+template <> auto StorageBackendSerialized::getPolicySet<ldp_xml_parser::MatchItemAccess>() const {
+       return impl.fileGetAccessSet(impl.getFile());
+}
+
+template <typename DI>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::makeDecisionItem(const DI &item) const {
+       return ldp_xml_parser::DecisionItem(makeDecision(impl.decisionItemGetDecision(item)),
+                                                            impl.stringGetCStr(impl.decisionItemGetPrivilege(item)));
+}
+
+template <typename String>
+boost::string_ref StorageBackendSerialized::toStringRef(const String &str) const {
+       return boost::string_ref(impl.stringGetCStr(str), impl.stringGetSize(str));
+}
+
+template <typename T, typename I>
+bool StorageBackendSerialized::match(const T &match, const I &item) const {
+       return match.match(makeMessageType(impl.itemSrGetMessageType(item)),
+                                          toStringRef(impl.itemSrGetInterface(item)),
+                                          toStringRef(impl.itemSrGetPath(item)),
+                                          toStringRef(impl.itemSrGetMember(item)),
+                                          toStringRef(impl.itemSrGetName(item)),
+                                          impl.itemSrGetIsNamePrefix(item),
+                                          makeDecision(impl.decisionItemGetDecision(impl.itemGetDecisionItem(item))));
+}
+
+template <typename I>
+bool StorageBackendSerialized::match(const ldp_xml_parser::MatchItemAccess &match, const I &item) const {
+       return match.match(makeBusAccessType(impl.itemAccessGetType(item)), impl.itemAccessGetUid(item), impl.itemAccessGetGid(item));
+}
+
+template <typename T, typename P>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy, ldp_serialization::ItemsType) const {
+       auto v = impl.policyGetItems(policy);
+       auto rend = impl.containerGetReverseIteratorEnd(v);
+       for (auto rit = impl.containerGetReverseIterator(v); rit != rend; ++rit) {
+               if (match(item, *rit))
+                       return makeDecisionItem(impl.itemGetDecisionItem(*rit));
+       }
+       return ldp_xml_parser::Decision::ANY;
+}
+
+template <typename P>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const P &policy) const {
+       if (!impl.policyHasIndex(policy))
+               return getDecisionItem(item, policy, ldp_serialization::ItemsType());   // make it old way for old databases
+
+       auto index = impl.policyGetIndex(policy);
+
+       uint32_t currentBest = 0;
+
+       auto updateCurrentBest = [&currentBest, &item, &policy, this](const auto &vec) {
+               // look from the back, the rule is the same as for the full database
+               // we now only check among less elements, because the database is indexed to small lists
+               // item_scores are in increasing order in the index, and they serve also as ids of the policy rules
+               for (auto item_score_it = impl.containerGetReverseIterator(vec);
+                        item_score_it != impl.containerGetReverseIteratorEnd(vec);
+                        item_score_it++) {
+                       auto db_items = impl.policyGetItems(policy);
+                       auto db_item = impl.containerLookupByIndex(db_items, *item_score_it - 1); // rules are indexed/scored from 1
+                       if (*item_score_it > currentBest && match(item, db_item)) {
+                               currentBest = *item_score_it;
+                               return;
+                       } else if (*item_score_it <= currentBest) {
+                               // there is no need to look further as we can't improve the score anymore
+                               return;
+                       }
+               }
+       };
+
+       auto searchAndUpdateCurrentBest = [&currentBest, &index, &updateCurrentBest, this](boost::string_ref name_ref) {
+               // we need to create C-string for the lookups
+               // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify
+               // input string and keeps only the length
+               std::string name(name_ref.data(), name_ref.size());
+
+               if (impl.containerEmpty(index))
+                       return;
+
+               // check if there are any rules for the name
+               auto fit = impl.containerLookupByKey(index, name.c_str());
+               if (!fit.first)
+                       return;
+
+               // check if there's any chance to get better score
+               if (impl.policyIndexGetBestScore(fit.second) <= currentBest)
+                       return;
+
+               // look for better score
+               updateCurrentBest(impl.policyIndexGetItemRefs(fit.second));
+       };
+
+       auto prefixIndex = impl.policyGetPrefixIndex(policy);
+
+       // iterate over names
+       for (const auto &name: item.getNames()) {
+               // find and check the no-prefix rules
+               searchAndUpdateCurrentBest(name);
+
+               // check the prefix rules
+               updateCurrentBest(prefixIndex);
+       }
+
+       // check no-name rules
+       searchAndUpdateCurrentBest("");
+
+       // if a matching rule was found, return the decision
+       if (currentBest > 0) {
+               auto db_item = impl.containerLookupByIndex(impl.policyGetItems(policy), currentBest - 1);
+               return makeDecisionItem(impl.itemGetDecisionItem(db_item));
+       }
+
+       // or if no matching rule was not found, return the default decision
+       return ldp_xml_parser::Decision::ANY;
+}
+
+template <typename OwnNode>
+auto StorageBackendSerialized::getDecisionItemFromTree(const OwnNode &node,
+                                                          const tokenizer::iterator &tokens_end,
+                                                          tokenizer::iterator &iterator) const {
+       if (iterator == tokens_end) {
+               if (makeDecision(impl.decisionItemGetDecision(impl.ownNodeGetDecisionItem(node))) != ldp_xml_parser::Decision::ANY)
+                       return impl.ownNodeGetDecisionItem(node);
+               else
+                       return impl.ownNodeGetPrefixDecisionItem(node);
+       }
+
+       auto children = impl.ownNodeGetChildren(node);
+
+       if (impl.containerEmpty(children))
+                       return impl.ownNodeGetPrefixDecisionItem(node);
+
+       auto child = impl.containerLookupByKey(children, iterator->c_str());
+       if (!child.first)
+               return impl.ownNodeGetPrefixDecisionItem(node);
+
+       ++iterator;
+       auto child_decision = getDecisionItemFromTree(child.second, tokens_end, iterator);
+       if (makeDecision(impl.decisionItemGetDecision(child_decision)) == ldp_xml_parser::Decision::ANY)
+               return impl.ownNodeGetPrefixDecisionItem(node);
+
+       return child_decision;
+}
+
+template <typename T, typename P>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy, ldp_serialization::TreeType) const {
+       if (item.getName().length() == 0)
+               return ldp_xml_parser::Decision::DENY;
+
+       boost::char_separator<char> separator(".");
+       tokenizer tokens(item.getName(), separator);
+
+       auto iterator = tokens.begin();
+
+       return makeDecisionItem(getDecisionItemFromTree(impl.policyGetTree(policy), tokens.end(), iterator));
+}
+
+template <typename T, typename P>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy) const {
+       return getDecisionItem(item, policy, typename ldp_serialization::PolicyContentType<P>::result());
+}
+
+template <typename MatchItem>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextMandatory(const MatchItem &item) const {
+       return getDecisionItem(item, impl.setGetContextMandatory(getPolicySet<MatchItem>()));
+}
+
+template <typename MatchItem>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextDefault(const MatchItem &item) const {
+       return getDecisionItem(item, impl.setGetContextDefault(getPolicySet<MatchItem>()));
+}
+
+template <typename MatchItem, typename Map>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const MatchItem &item, const Map &map, id_t id) const {
+       if (impl.containerEmpty(map))
+               return ldp_xml_parser::Decision::ANY;
+
+       auto elem = impl.containerLookupByKey(map, id);
+       if (!elem.first)
+               return ldp_xml_parser::Decision::ANY;
+       return getDecisionItem(item, impl.setUserGroupGetPolicy(elem.second));
+}
+
+template <typename MatchItem>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemUser(uid_t uid, const MatchItem &item) const {
+       return getDecisionItem(item, impl.setGetUser(getPolicySet<MatchItem>()), uid);
+}
+template <typename MatchItem>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemGroup(gid_t gid, const MatchItem &item) const {
+       return getDecisionItem(item, impl.setGetGroup(getPolicySet<MatchItem>()), gid);
+}
+
+template <typename MatchItem>
+bool StorageBackendSerialized::existsPolicyForGroup(gid_t gid) const {
+       auto map = impl.setGetGroup(getPolicySet<MatchItem>());
+
+       if (impl.containerEmpty(map))
+               return false;
+
+       return impl.containerLookupByKey(map, gid).first;
+}
+
+#define T_INSTANTIATION(T) \
+       template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextMandatory(const ldp_xml_parser::MatchItem##T &item) const; \
+       template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextDefault(const ldp_xml_parser::MatchItem##T &item) const;
+
+T_INSTANTIATION(Own)
+T_INSTANTIATION(Send)
+T_INSTANTIATION(Receive)
+T_INSTANTIATION(Access)
+
+#undef T_INSTANTIATION
+
+#define T_INSTANTIATION2(T) \
+       template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemUser(uid_t uid, const ldp_xml_parser::MatchItem##T &item) const; \
+       template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemGroup(gid_t gid, const ldp_xml_parser::MatchItem##T &item) const; \
+       template bool StorageBackendSerialized::existsPolicyForGroup<ldp_xml_parser::MatchItem##T>(gid_t) const;
+
+T_INSTANTIATION2(Own)
+T_INSTANTIATION2(Send)
+T_INSTANTIATION2(Receive)
+
+#undef T_INSTANTIATION2
index 1074b76..e010b72 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "policy.hpp"
 #include "serialization_backend.hpp"
+#include <boost/tokenizer.hpp>
 #include <sys/types.h>
 
 namespace ldp_serialized {
@@ -43,23 +44,18 @@ public:
        // MatchItemOwn, MatchItemSend, MatchItemReceive
        // and - only for Contexts - MatchItemAccess
        template <typename MatchItem>
-       ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const
-       { return impl.getDecisionItemContextMandatory(item); }
+       ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const;
        template <typename MatchItem>
-       ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const
-       { return impl.getDecisionItemContextDefault(item); }
+       ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const;
        template <typename MatchItem>
-       ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const
-       { return impl.getDecisionItemUser(uid, item); }
+       ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const;
        template <typename MatchItem>
-       ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const
-       { return impl.getDecisionItemGroup(gid, item); }
+       ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const;
 
        // This works with MatchItem set to MatchItemOwn, MatchItemSend or MatchItemReceive
        // This is needed for filtering mapGroups. Check NaivePolicyChecker.
        template <typename MatchItem>
-       bool existsPolicyForGroup(gid_t gid) const
-       { return impl.existsPolicyForGroup<MatchItem>(gid); }
+       bool existsPolicyForGroup(gid_t gid) const;
 
 private:
        typedef typename ldp_serialization::SerializationBackend::Storage Backend;
@@ -75,6 +71,43 @@ private:
 
        void releaseMMap();
        void releaseFD();
+
+       template <typename MatchItem>
+       auto getPolicySet() const;
+
+       template <typename T, typename P>
+       ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy, ldp_serialization::ItemsType) const;
+
+       template <typename T, typename P>
+       ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy, ldp_serialization::TreeType) const;
+
+       template <typename T, typename P>
+       ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy) const;
+
+       template <typename P>
+       ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const P &policy) const;
+
+       template <typename MatchItem, typename Map>
+       ldp_xml_parser::DecisionItem getDecisionItem(const MatchItem &item, const Map &map, id_t id) const;
+
+       typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
+
+       template <typename OwnNode>
+       auto getDecisionItemFromTree(const OwnNode &node,
+                                        const tokenizer::iterator &tokens,
+                                        tokenizer::iterator &iterator) const;
+
+       template <typename T, typename I>
+       bool match(const T &match, const I &item) const;
+
+       template <typename I>
+       bool match(const ldp_xml_parser::MatchItemAccess &match, const I &item) const;
+
+       template <typename DI>
+       ldp_xml_parser::DecisionItem makeDecisionItem(const DI &item) const;
+
+       template <typename String>
+       boost::string_ref toStringRef(const String &str) const;
 };
 
 }