hashcomp.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (C) 2002-2011 InspIRCd Development Team
00004  * Copyright (C) 2008-2013 Anope Team <team@anope.org>
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  */
00009 
00010 #include "services.h"
00011 #include "hashcomp.h"
00012 #include "anope.h"
00013 
00014 /* Case map in use by Anope */
00015 std::locale Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
00016 
00017 /*
00018  *
00019  * This is an implementation of a special string class, ci::string,
00020  * which is a case-insensitive equivalent to std::string.
00021  *
00022  */
00023  
00024 bool ci::ci_char_traits::eq(char c1st, char c2nd)
00025 {
00026         const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
00027         return ct.toupper(c1st) == ct.toupper(c2nd);
00028 }
00029 
00030 bool ci::ci_char_traits::ne(char c1st, char c2nd)
00031 {
00032         const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
00033         return ct.toupper(c1st) != ct.toupper(c2nd);
00034 }
00035 
00036 bool ci::ci_char_traits::lt(char c1st, char c2nd)
00037 {
00038         const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
00039         return ct.toupper(c1st) < ct.toupper(c2nd);
00040 }
00041 
00042 int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
00043 {
00044         const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
00045 
00046         for (unsigned i = 0; i < n; ++i)
00047         {
00048                 register char c1 = ct.toupper(*str1), c2 = ct.toupper(*str2);
00049 
00050                 if (c1 > c2)
00051                         return 1;
00052                 else if (c1 < c2)
00053                         return -1;
00054                 else if (!c1 || !c2)
00055                         return 0;
00056 
00057                 ++str1;
00058                 ++str2;
00059         }
00060         return 0;
00061 }
00062 
00063 const char *ci::ci_char_traits::find(const char *s1, int n, char c)
00064 {
00065         const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
00066         register char c_u = ct.toupper(c);
00067         while (n-- > 0 && ct.toupper(*s1) != c_u)
00068                 ++s1;
00069         return n >= 0 ? s1 : NULL;
00070 }
00071 
00072 bool ci::less::operator()(const Anope::string &s1, const Anope::string &s2) const
00073 {
00074         return s1.ci_str().compare(s2.ci_str()) < 0;
00075 }
00076 
00077 sepstream::sepstream(const Anope::string &source, char seperator) : tokens(source), sep(seperator)
00078 {
00079         last_starting_position = n = tokens.begin();
00080 }
00081 
00082 bool sepstream::GetToken(Anope::string &token)
00083 {
00084         Anope::string::iterator lsp = last_starting_position;
00085 
00086         while (n != tokens.end())
00087         {
00088                 if (*n == sep || n + 1 == tokens.end())
00089                 {
00090                         last_starting_position = n + 1;
00091                         token = Anope::string(lsp, n + 1 == tokens.end() ? n + 1 : n);
00092 
00093                         while (token.length() && token.rfind(sep) == token.length() - 1)
00094                                 token.erase(token.end() - 1);
00095 
00096                         ++n;
00097 
00098                         return true;
00099                 }
00100 
00101                 ++n;
00102         }
00103 
00104         token.clear();
00105         return false;
00106 }
00107 
00108 bool sepstream::GetToken(Anope::string &token, int num)
00109 {
00110         int i;
00111         for (i = 0; i < num + 1 && this->GetToken(token); ++i);
00112         return i == num + 1;
00113 }
00114 
00115 int sepstream::NumTokens()
00116 {
00117         int i;
00118         Anope::string token;
00119         for (i = 0; this->GetToken(token); ++i);
00120         return i;
00121 }
00122 
00123 bool sepstream::GetTokenRemainder(Anope::string &token, int num)
00124 {
00125         if (this->GetToken(token, num))
00126         {
00127                 if (!this->StreamEnd())
00128                         token += sep + this->GetRemaining();
00129 
00130                 return true;
00131         }
00132 
00133         return false;
00134 }
00135 
00136 const Anope::string sepstream::GetRemaining()
00137 {
00138         return Anope::string(n, tokens.end());
00139 }
00140 
00141 bool sepstream::StreamEnd()
00142 {
00143         return n == tokens.end();
00144 }
00145