X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fhashcomp.cpp;h=88b9b582cfa86a7feec9bc56c8010db08f05679a;hb=1b7c615062a7b203c7fc3ce4c56e16eb671f7c15;hp=a076dc46b36c51a3ad40924e34489bf06fb477a0;hpb=a79130a1e1c6fc44051acee01f77891c453e436f;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index a076dc46b..88b9b582c 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -2,36 +2,24 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * Inspire is copyright (C) 2002-2005 ChatSpike-Dev. - * E-mail: - * - * + * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. + * E-mail: + * + * * * Written by Craig Edwards, Craig McLure, and others. * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ -#include +using namespace std; + #include "inspircd.h" #include "hashcomp.h" -#include "helperfuncs.h" -#ifdef GCC3 #include -#else -#include -#endif - -#ifdef GCC3 #define nspace __gnu_cxx -#else -#define nspace std -#endif - -// from helperfuncs.cpp -extern char lowermap[255]; /****************************************************** * @@ -57,48 +45,73 @@ extern char lowermap[255]; * be considered the lowercase of {, } and |. * * This file also contains hashing methods for hashing - * in_addr structs, we use this if we want to cache IP + * insp_inaddr structs, we use this if we want to cache IP * addresses. * ******************************************************/ using namespace std; +using namespace irc::sockets; -size_t nspace::hash::operator()(const struct in_addr &a) const +/* convert a string to lowercase. Note following special circumstances + * taken from RFC 1459. Many "official" server branches still hold to this + * rule so i will too; + * + * Because of IRC's scandanavian origin, the characters {}| are + * considered to be the lower case equivalents of the characters []\, + * respectively. This is a critical issue when determining the + * equivalence of two nicknames. + */ +void nspace::strlower(char *n) { - size_t q; - memcpy(&q,&a,sizeof(size_t)); - return q; + if (n) + { + for (char* t = n; *t; t++) + *t = lowermap[(unsigned char)*t]; + } } -size_t nspace::hash::operator()(const string &s) const +size_t nspace::hash::operator()(const insp_inaddr &a) const { - char a[MAXBUF]; - static struct hash strhash; - strlcpy(a,s.c_str(),MAXBUF); - strlower(a); - return strhash(a); + size_t q; + memcpy(&q,&a,sizeof(size_t)); + return q; } -bool StrHashComp::operator()(const string& s1, const string& s2) const +size_t nspace::hash::operator()(const string &s) const { - char a[MAXBUF],b[MAXBUF]; - strlcpy(a,s1.c_str(),MAXBUF); - strlcpy(b,s2.c_str(),MAXBUF); - strlower(a); - strlower(b); - return (strcasecmp(a,b) == 0); + char a[s.length()]; + size_t t = 0; + static struct hash strhash; + + for (const char* x = s.c_str(); *x; x++) /* Faster to do it this way than */ + a[t++] = lowermap[(unsigned char)*x]; /* Seperate strlcpy and strlower */ + + a[t] = 0; + + return strhash(a); } -bool InAddr_HashComp::operator()(const in_addr &s1, const in_addr &s2) const +bool irc::StrHashComp::operator()(const std::string& s1, const std::string& s2) const { - size_t q; - size_t p; - - memcpy(&q,&s1,sizeof(size_t)); - memcpy(&p,&s2,sizeof(size_t)); + unsigned char* n1 = (unsigned char*)s1.c_str(); + unsigned char* n2 = (unsigned char*)s2.c_str(); + for (; *n1 && *n2; n1++, n2++) + if (lowermap[*n1] != lowermap[*n2]) + return false; + return (lowermap[*n1] == lowermap[*n2]); +} - return (q == p); +bool irc::InAddr_HashComp::operator()(const insp_inaddr &s1, const insp_inaddr &s2) const +{ +#ifdef IPV6 + for (int n = 0; n < 16; n++) + if (s2.s6_addr[n] != s1.s6_addr[n]) + return false; + return true; +#else + return (s1.s_addr == s1.s_addr); +#endif } /****************************************************** @@ -108,39 +121,37 @@ bool InAddr_HashComp::operator()(const in_addr &s1, const in_addr &s2) const * std::string which is not only case-insensitive but * can also do scandanavian comparisons, e.g. { = [, etc. * - * This class depends on the global 'lowermap' which is - * initialized at startup by inspircd.cpp, and contains - * the 'scandanavian' casemappings for fast irc compare. + * This class depends on the const array 'lowermap'. * ******************************************************/ bool irc::irc_char_traits::eq(char c1st, char c2nd) { - return lowermap[c1st] == lowermap[c2nd]; + return lowermap[(unsigned char)c1st] == lowermap[(unsigned char)c2nd]; } bool irc::irc_char_traits::ne(char c1st, char c2nd) { - return lowermap[c1st] != lowermap[c2nd]; + return lowermap[(unsigned char)c1st] != lowermap[(unsigned char)c2nd]; } bool irc::irc_char_traits::lt(char c1st, char c2nd) { - return lowermap[c1st] < lowermap[c2nd]; + return lowermap[(unsigned char)c1st] < lowermap[(unsigned char)c2nd]; } int irc::irc_char_traits::compare(const char* str1, const char* str2, size_t n) { - for(int i = 0; i < n; i++) + for(unsigned int i = 0; i < n; i++) { - if(lowermap[*str1] > lowermap[*str2]) - return 1; + if(lowermap[(unsigned char)*str1] > lowermap[(unsigned char)*str2]) + return 1; - if(lowermap[*str1] < lowermap[*str2]) - return -1; + if(lowermap[(unsigned char)*str1] < lowermap[(unsigned char)*str2]) + return -1; - if(*str1 == 0 || *str2 == 0) - return 0; + if(*str1 == 0 || *str2 == 0) + return 0; str1++; str2++; @@ -148,9 +159,119 @@ int irc::irc_char_traits::compare(const char* str1, const char* str2, size_t n) return 0; } +std::string operator+ (std::string& leftval, irc::string& rightval) +{ + return leftval + std::string(rightval.c_str()); +} + +irc::string operator+ (irc::string& leftval, std::string& rightval) +{ + return leftval + irc::string(rightval.c_str()); +} + +bool operator== (std::string& leftval, irc::string& rightval) +{ + return (leftval == std::string(rightval.c_str())); +} + +bool operator== (irc::string& leftval, std::string& rightval) +{ + return (rightval == std::string(leftval.c_str())); +} + const char* irc::irc_char_traits::find(const char* s1, int n, char c) { - while(n-- > 0 && lowermap[*s1] != lowermap[c]) + while(n-- > 0 && lowermap[(unsigned char)*s1] != lowermap[(unsigned char)c]) s1++; return s1; } + +/* See hashcomp.h if you care about these... */ +std::ostream& operator<<(std::ostream &os, const irc::string &str) +{ + return os << str.c_str(); +} + +std::istream& operator>>(std::istream &is, irc::string &str) +{ + std::string tmp; + is >> tmp; + str = tmp.c_str(); + return is; +} + +irc::tokenstream::tokenstream(const std::string &source) : tokens(source), last_pushed(false) +{ + /* Record starting position and current position */ + last_starting_position = tokens.begin(); + n = tokens.begin(); +} + +irc::tokenstream::~tokenstream() +{ +} + +const std::string irc::tokenstream::GetToken() +{ + std::string::iterator lsp = last_starting_position; + + while (n != tokens.end()) + { + if ((last_pushed) && (*n == ':')) + { + /* If we find a token thats not the first and starts with :, + * this is the last token on the line + */ + std::string::iterator curr = ++n; + n = tokens.end(); + return std::string(curr, tokens.end()); + } + + last_pushed = false; + + if ((*n == ' ') || (n+1 == tokens.end())) + { + /* If we find a space, or end of string, this is the end of a token. + */ + last_starting_position = n+1; + last_pushed = true; + + std::string strip(lsp, n+1 == tokens.end() ? n+1 : n++); + while ((strip.length()) && (strip.find_last_of(' ') == strip.length() - 1)) + strip.erase(strip.end() - 1); + + return strip; + } + + n++; + } + return ""; +} + +irc::commasepstream::commasepstream(const std::string &source) : tokens(source) +{ + last_starting_position = tokens.begin(); + n = tokens.begin(); +} + +const std::string irc::commasepstream::GetToken() +{ + std::string::iterator lsp = last_starting_position; + + while (n != tokens.end()) + { + if ((*n == ',') || (n+1 == tokens.end())) + { + last_starting_position = n+1; + return std::string(lsp, n+1 == tokens.end() ? n+1 : n++); + } + + n++; + } + + return ""; +} + +irc::commasepstream::~commasepstream() +{ +}