Home | History | Annotate | Download | only in libpropertyinfoserializer
      1 //
      2 // Copyright (C) 2017 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef PROPERTY_INFO_SERIALIZER_TRIE_BUILDER_H
     18 #define PROPERTY_INFO_SERIALIZER_TRIE_BUILDER_H
     19 
     20 #include <memory>
     21 #include <set>
     22 #include <string>
     23 #include <vector>
     24 
     25 namespace android {
     26 namespace properties {
     27 
     28 struct PropertyEntryBuilder {
     29   PropertyEntryBuilder() : context(nullptr), type(nullptr) {}
     30   PropertyEntryBuilder(const std::string& name, const std::string* context, const std::string* type)
     31       : name(name), context(context), type(type) {}
     32   std::string name;
     33   const std::string* context;
     34   const std::string* type;
     35 };
     36 
     37 class TrieBuilderNode {
     38  public:
     39   TrieBuilderNode(const std::string& name) : property_entry_(name, nullptr, nullptr) {}
     40 
     41   TrieBuilderNode* FindChild(const std::string& name) {
     42     for (auto& child : children_) {
     43       if (child.name() == name) return &child;
     44     }
     45     return nullptr;
     46   }
     47 
     48   const TrieBuilderNode* FindChild(const std::string& name) const {
     49     for (const auto& child : children_) {
     50       if (child.name() == name) return &child;
     51     }
     52     return nullptr;
     53   }
     54 
     55   TrieBuilderNode* AddChild(const std::string& name) { return &children_.emplace_back(name); }
     56 
     57   bool AddPrefixContext(const std::string& prefix, const std::string* context,
     58                         const std::string* type) {
     59     if (std::find_if(prefixes_.begin(), prefixes_.end(),
     60                      [&prefix](const auto& t) { return t.name == prefix; }) != prefixes_.end()) {
     61       return false;
     62     }
     63 
     64     prefixes_.emplace_back(prefix, context, type);
     65     return true;
     66   }
     67 
     68   bool AddExactMatchContext(const std::string& exact_match, const std::string* context,
     69                             const std::string* type) {
     70     if (std::find_if(exact_matches_.begin(), exact_matches_.end(), [&exact_match](const auto& t) {
     71           return t.name == exact_match;
     72         }) != exact_matches_.end()) {
     73       return false;
     74     }
     75 
     76     exact_matches_.emplace_back(exact_match, context, type);
     77     return true;
     78   }
     79 
     80   const std::string& name() const { return property_entry_.name; }
     81   const std::string* context() const { return property_entry_.context; }
     82   void set_context(const std::string* context) { property_entry_.context = context; }
     83   const std::string* type() const { return property_entry_.type; }
     84   void set_type(const std::string* type) { property_entry_.type = type; }
     85 
     86   const PropertyEntryBuilder property_entry() const { return property_entry_; }
     87 
     88   const std::vector<TrieBuilderNode>& children() const { return children_; }
     89   const std::vector<PropertyEntryBuilder>& prefixes() const { return prefixes_; }
     90   const std::vector<PropertyEntryBuilder>& exact_matches() const { return exact_matches_; }
     91 
     92  private:
     93   PropertyEntryBuilder property_entry_;
     94   std::vector<TrieBuilderNode> children_;
     95   std::vector<PropertyEntryBuilder> prefixes_;
     96   std::vector<PropertyEntryBuilder> exact_matches_;
     97 };
     98 
     99 class TrieBuilder {
    100  public:
    101   TrieBuilder(const std::string& default_context, const std::string& default_type);
    102   bool AddToTrie(const std::string& name, const std::string& context, const std::string& type,
    103                  bool exact, std::string* error);
    104 
    105   const TrieBuilderNode builder_root() const { return builder_root_; }
    106   const std::set<std::string>& contexts() const { return contexts_; }
    107   const std::set<std::string>& types() const { return types_; }
    108 
    109  private:
    110   bool AddToTrie(const std::string& name, const std::string* context, const std::string* type,
    111                  bool exact, std::string* error);
    112   const std::string* StringPointerFromContainer(const std::string& string,
    113                                                 std::set<std::string>* container);
    114 
    115   TrieBuilderNode builder_root_;
    116   std::set<std::string> contexts_;
    117   std::set<std::string> types_;
    118 };
    119 
    120 }  // namespace properties
    121 }  // namespace android
    122 
    123 #endif
    124