| /** @file |
| |
| A brief file description |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| /***************************************************************************** |
| * |
| * HostLookup.h - Interface to general purpose matcher |
| * |
| * |
| ****************************************************************************/ |
| |
| #pragma once |
| |
| #include <vector> |
| #include <string> |
| #include <string_view> |
| #include <functional> |
| #include <unordered_map> |
| |
| // HostLookup constants |
| constexpr int HOST_TABLE_DEPTH = 3; // Controls the max number of levels in the logical tree |
| constexpr int HOST_ARRAY_MAX = 8; // Sets the fixed array size |
| |
| class CharIndex; |
| class HostArray; |
| |
| // The data in the HostMatcher tree is pointers to HostBranches. No duplicates keys permitted in the tree. To handle |
| // multiple data items bound the same key, the HostBranch has the lead_indexs array which stores pointers (in the form |
| // of array indexes) to HostLeaf structs |
| // |
| // There is HostLeaf struct for each data item put into the table |
| // |
| struct HostLeaf { |
| /// Type of leaf. |
| enum Type { |
| LEAF_INVALID, |
| HOST_PARTIAL, |
| HOST_COMPLETE, |
| DOMAIN_COMPLETE, |
| DOMAIN_PARTIAL, |
| }; |
| Type type{LEAF_INVALID}; ///< Type of this leaf instance. |
| std::string match; // Contains a copy of the match data |
| bool isNot{false}; // used by any fasssst path ... |
| void *opaque_data{nullptr}; // Data associated with this leaf |
| |
| HostLeaf() {} |
| HostLeaf(std::string_view name, void *data) : opaque_data(data) |
| { |
| if (!name.empty() && name.front() == '!') { |
| name.remove_prefix(1); |
| isNot = true; |
| } |
| match.assign(name); |
| } |
| }; |
| |
| struct HostBranch { |
| /// Branch type. |
| enum Type { |
| HOST_TERMINAL, |
| HOST_HASH, |
| HOST_INDEX, |
| HOST_ARRAY, |
| }; |
| |
| using HostTable = std::unordered_map<std::string_view, HostBranch *>; |
| |
| using LeafIndices = std::vector<int>; |
| |
| /// Type of data in this branch. |
| union Level { |
| std::nullptr_t _nil; ///< HOST_TERMINAL |
| HostTable *_table; ///< HOST_HASH |
| CharIndex *_index; ///< HOST_INDEX |
| HostArray *_array; ///< HOST_ARRAY |
| void *_ptr; ///< As generic pointer. |
| }; |
| |
| ~HostBranch(); |
| int level_idx{0}; // what level in the tree. the root is level 0 |
| Type type{HOST_TERMINAL}; // tells what kind of data structure is next_level is |
| Level next_level{nullptr}; // opaque pointer to lookup structure |
| LeafIndices leaf_indices; // HostLeaf indices. |
| std::string key; |
| }; |
| |
| // |
| // End Host Lookup Helper types |
| // |
| |
| struct HostLookupState { |
| HostBranch *cur{nullptr}; |
| int table_level{0}; |
| int array_index{0}; |
| std::string_view hostname; ///< Original host name. |
| std::string_view hostname_stub; ///< Remaining host name to search. |
| }; |
| |
| class HostLookup |
| { |
| public: |
| using LeafArray = std::vector<HostLeaf>; |
| using PrintFunc = std::function<void(void *)>; |
| |
| HostLookup(std::string_view name); |
| void NewEntry(std::string_view match_data, bool domain_record, void *opaque_data_in); |
| void AllocateSpace(int num_entries); |
| bool Match(std::string_view host); |
| bool Match(std::string_view host, void **opaque_ptr); |
| bool MatchFirst(std::string_view host, HostLookupState *s, void **opaque_ptr); |
| bool MatchNext(HostLookupState *s, void **opaque_ptr); |
| |
| void Print(PrintFunc const &f) const; |
| void Print() const; |
| |
| LeafArray * |
| get_leaf_array() |
| { |
| return &leaf_array; |
| } |
| |
| private: |
| using HostTable = HostBranch::HostTable; |
| using LeafIndices = HostBranch::LeafIndices; |
| |
| void TableInsert(std::string_view match_data, int index, bool domain_record); |
| HostBranch *TableNewLevel(HostBranch *from, std::string_view level_data); |
| HostBranch *InsertBranch(HostBranch *insert_in, std::string_view level_data); |
| HostBranch *FindNextLevel(HostBranch *from, std::string_view level_data, bool bNotProcess = false); |
| bool MatchArray(HostLookupState *s, void **opaque_ptr, LeafIndices &array, bool host_done); |
| |
| void PrintHostBranch(const HostBranch *hb, PrintFunc const &f) const; |
| |
| HostBranch root; // The top of the search tree |
| LeafArray leaf_array; // array of all leaves in tree |
| std::string matcher_name; // Used for Debug/Warning/Error messages |
| }; |