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