Line data Source code
1 : #ifndef OPENDDS_RTPSRELAYLIB_NAME_H 2 : #define OPENDDS_RTPSRELAYLIB_NAME_H 3 : 4 : #include "export.h" 5 : 6 : #include <set> 7 : #include <string> 8 : #include <vector> 9 : 10 : namespace RtpsRelay { 11 : 12 : class OpenDDS_RtpsRelayLib_Export Atom { 13 : public: 14 : enum Kind { 15 : CHARACTER, 16 : CHARACTER_CLASS, 17 : NEGATED_CHARACTER_CLASS, 18 : WILDCARD, 19 : GLOB 20 : }; 21 : 22 59 : explicit Atom(Kind kind) : kind_(kind), character_(0) {} 23 147 : explicit Atom(char c) : kind_(CHARACTER), character_(c) {} 24 36 : Atom(bool negated, const std::set<char>& characters) 25 36 : : kind_(negated ? NEGATED_CHARACTER_CLASS : CHARACTER_CLASS) 26 36 : , character_(0) 27 36 : , characters_(characters) {} 28 : 29 879 : Kind kind() const { return kind_; } 30 : 31 187 : char character() const { return character_; } 32 : 33 186 : const std::set<char>& characters() const { return characters_; } 34 : 35 158 : bool operator==(const Atom& other) const 36 : { 37 158 : if (kind_ != other.kind_) { 38 5 : return false; 39 : } 40 153 : switch (kind_) { 41 133 : case CHARACTER: 42 133 : return character_ == other.character_; 43 9 : case CHARACTER_CLASS: 44 : case NEGATED_CHARACTER_CLASS: 45 9 : return characters_ == other.characters_; 46 11 : default: 47 11 : return true; 48 : } 49 : } 50 : 51 5 : bool operator!=(const Atom& other) const 52 : { 53 5 : return !(*this == other); 54 : } 55 : 56 134 : bool is_pattern() const 57 : { 58 134 : switch (kind_) { 59 28 : case CHARACTER_CLASS: 60 : case NEGATED_CHARACTER_CLASS: 61 : case WILDCARD: 62 : case GLOB: 63 28 : return true; 64 106 : default: 65 106 : return false; 66 : } 67 : } 68 : 69 : private: 70 : Kind kind_; 71 : char character_; // For CHARACTER. 72 : std::set<char> characters_; // For CHARACTER_CLASS and NEGATED_CHARACTER_CLASS. 73 : }; 74 : 75 : struct AtomHash { 76 163 : std::size_t operator() (const Atom& atom) const 77 : { 78 163 : std::size_t result = atom.kind(); 79 163 : result ^= (atom.character() << 8); 80 190 : for (const auto c : atom.characters()) { 81 27 : result ^= (c << 16); 82 : } 83 163 : return result; 84 : } 85 : }; 86 : 87 : OpenDDS_RtpsRelayLib_Export std::ostream& operator<<(std::ostream& out, const Atom& atom); 88 : 89 : class OpenDDS_RtpsRelayLib_Export Name { 90 : public: 91 : typedef std::vector<Atom> Atoms; 92 : typedef Atoms::const_iterator const_iterator; 93 : 94 16 : Name() : is_pattern_(false), is_valid_(true) {} 95 : 96 60 : explicit Name(const std::string& name) : is_pattern_(false), is_valid_(true) 97 : { 98 60 : size_t idx = 0; 99 60 : parse(*this, name, idx); 100 60 : } 101 : 102 22 : bool is_valid() const { return is_valid_; } 103 37 : bool is_literal() const { return !is_pattern_; } 104 15 : bool is_pattern() const { return is_pattern_; } 105 37 : const_iterator begin() const { return atoms_.begin(); } 106 36 : const_iterator end() const { return atoms_.end(); } 107 : 108 21 : bool operator==(const Name& other) const 109 : { 110 40 : return is_pattern_ == other.is_pattern_ && 111 39 : is_valid_ == other.is_valid_ && 112 39 : atoms_ == other.atoms_; 113 : } 114 3 : bool operator!=(const Name& other) const 115 : { 116 3 : return !(*this == other); 117 : } 118 : 119 214 : void push_back(const Atom& atom) 120 : { 121 : // Don't allow consecutive globs. 122 214 : if (atom.kind() == Atom::GLOB && !atoms_.empty() && atoms_.back().kind() == Atom::GLOB) { 123 14 : return; 124 : } 125 : 126 200 : is_pattern_ = is_pattern_ || atom.is_pattern(); 127 200 : atoms_.push_back(atom); 128 : } 129 : 130 : private: 131 : Atoms atoms_; 132 : bool is_pattern_; 133 : bool is_valid_; 134 : 135 : static void parse(Name& name, const std::string& buffer, size_t& idx); 136 : static char parse_character(Name& name, const std::string& buffer, size_t& idx); 137 : static Atom parse_character_class(Name& name, const std::string& buffer, size_t& idx); 138 : static void parse_character_class_tail(Name& name, const std::string& buffer, size_t& idx, std::set<char>& characters); 139 : static void parse_character_or_range(Name& name, const std::string& buffer, size_t& idx, std::set<char>& characters); 140 : }; 141 : 142 : OpenDDS_RtpsRelayLib_Export std::ostream& operator<<(std::ostream& out, const Name& name); 143 : 144 : } 145 : 146 : #endif // RTPSRELAY_NAME_H_