anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
hashcomp.cpp (3575B)
1 /* 2 * 3 * (C) 2002-2011 InspIRCd Development Team 4 * (C) 2008-2022 Anope Team <team@anope.org> 5 * 6 * Please read COPYING and README for further details. 7 */ 8 9 #include "services.h" 10 #include "hashcomp.h" 11 #include "anope.h" 12 13 /* Case map in use by Anope */ 14 std::locale Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>()); 15 /* Cache of the above case map, forced upper */ 16 static unsigned char case_map_upper[256], case_map_lower[256]; 17 18 /* called whenever Anope::casemap is modified to rebuild the casemap cache */ 19 void Anope::CaseMapRebuild() 20 { 21 const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap); 22 23 for (unsigned i = 0; i < sizeof(case_map_upper); ++i) 24 { 25 case_map_upper[i] = ct.toupper(i); 26 case_map_lower[i] = ct.tolower(i); 27 } 28 } 29 30 unsigned char Anope::tolower(unsigned char c) 31 { 32 return case_map_lower[c]; 33 } 34 35 unsigned char Anope::toupper(unsigned char c) 36 { 37 return case_map_upper[c]; 38 } 39 40 /* 41 * 42 * This is an implementation of a special string class, ci::string, 43 * which is a case-insensitive equivalent to std::string. 44 * 45 */ 46 47 bool ci::ci_char_traits::eq(char c1st, char c2nd) 48 { 49 return case_map_upper[static_cast<unsigned char>(c1st)] == case_map_upper[static_cast<unsigned char>(c2nd)]; 50 } 51 52 bool ci::ci_char_traits::ne(char c1st, char c2nd) 53 { 54 return !eq(c1st, c2nd); 55 } 56 57 bool ci::ci_char_traits::lt(char c1st, char c2nd) 58 { 59 return case_map_upper[static_cast<unsigned char>(c1st)] < case_map_upper[static_cast<unsigned char>(c2nd)]; 60 } 61 62 int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n) 63 { 64 for (unsigned i = 0; i < n; ++i) 65 { 66 unsigned char c1 = case_map_upper[static_cast<unsigned char>(*str1)], 67 c2 = case_map_upper[static_cast<unsigned char>(*str2)]; 68 69 if (c1 > c2) 70 return 1; 71 else if (c1 < c2) 72 return -1; 73 else if (!c1 || !c2) 74 return 0; 75 76 ++str1; 77 ++str2; 78 } 79 return 0; 80 } 81 82 const char *ci::ci_char_traits::find(const char *s1, int n, char c) 83 { 84 while (n-- > 0 && case_map_upper[static_cast<unsigned char>(*s1)] != case_map_upper[static_cast<unsigned char>(c)]) 85 ++s1; 86 return n >= 0 ? s1 : NULL; 87 } 88 89 bool ci::less::operator()(const Anope::string &s1, const Anope::string &s2) const 90 { 91 return s1.ci_str().compare(s2.ci_str()) < 0; 92 } 93 94 sepstream::sepstream(const Anope::string &source, char separator, bool ae) : tokens(source), sep(separator), pos(0), allow_empty(ae) 95 { 96 } 97 98 bool sepstream::GetToken(Anope::string &token) 99 { 100 if (this->StreamEnd()) 101 { 102 token.clear(); 103 return false; 104 } 105 106 if (!this->allow_empty) 107 { 108 this->pos = this->tokens.find_first_not_of(this->sep, this->pos); 109 if (this->pos == std::string::npos) 110 { 111 this->pos = this->tokens.length() + 1; 112 token.clear(); 113 return false; 114 } 115 } 116 117 size_t p = this->tokens.find(this->sep, this->pos); 118 if (p == std::string::npos) 119 p = this->tokens.length(); 120 121 token = this->tokens.substr(this->pos, p - this->pos); 122 this->pos = p + 1; 123 124 return true; 125 } 126 127 bool sepstream::GetToken(Anope::string &token, int num) 128 { 129 int i; 130 for (i = 0; i < num + 1 && this->GetToken(token); ++i); 131 return i == num + 1; 132 } 133 134 int sepstream::NumTokens() 135 { 136 int i; 137 Anope::string token; 138 for (i = 0; this->GetToken(token); ++i); 139 return i; 140 } 141 142 bool sepstream::GetTokenRemainder(Anope::string &token, int num) 143 { 144 if (this->GetToken(token, num)) 145 { 146 if (!this->StreamEnd()) 147 token += sep + this->GetRemaining(); 148 149 return true; 150 } 151 152 return false; 153 } 154 155 const Anope::string sepstream::GetRemaining() 156 { 157 return !this->StreamEnd() ? this->tokens.substr(this->pos) : ""; 158 } 159 160 bool sepstream::StreamEnd() 161 { 162 return this->pos > this->tokens.length(); 163 }