X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fhashcomp.cpp;h=88b9b582cfa86a7feec9bc56c8010db08f05679a;hb=1b7c615062a7b203c7fc3ce4c56e16eb671f7c15;hp=ee485591f9ba182ef5a93f0ddef505d42300c175;hpb=8942c3cd3217e5c68f01e3cb344709971921fc97;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index ee485591f..88b9b582c 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -3,38 +3,23 @@ * +------------------------------------+ * * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. - * E-mail: - * - * + * 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. * * --------------------------------------------------- */ using namespace std; -#include "inspircd_config.h" #include "inspircd.h" -#include #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 const char lowermap[255]; /****************************************************** * @@ -60,39 +45,73 @@ extern const 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; + +/* 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) +{ + if (n) + { + for (char* t = n; *t; t++) + *t = lowermap[(unsigned char)*t]; + } +} -size_t nspace::hash::operator()(const struct in_addr &a) const +size_t nspace::hash::operator()(const insp_inaddr &a) const { - size_t q; - memcpy(&q,&a,sizeof(size_t)); - return q; + size_t q; + memcpy(&q,&a,sizeof(size_t)); + return q; } size_t nspace::hash::operator()(const string &s) const { - char a[MAXBUF]; - static struct hash strhash; - strlcpy(a,s.c_str(),MAXBUF); - strlower(a); - return strhash(a); + 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 irc::StrHashComp::operator()(const std::string& s1, const std::string& s2) const { - irc::string a = s1.c_str(); - irc::string b = s2.c_str(); - return (a == b); + 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]); } -bool irc::InAddr_HashComp::operator()(const in_addr &s1, const in_addr &s2) const +bool irc::InAddr_HashComp::operator()(const insp_inaddr &s1, const insp_inaddr &s2) const { - return (s1.s_addr == s1.s_addr); +#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 } /****************************************************** @@ -102,39 +121,37 @@ bool irc::InAddr_HashComp::operator()(const in_addr &s1, const in_addr &s2) cons * 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[(unsigned)c1st] == lowermap[(unsigned)c2nd]; + return lowermap[(unsigned char)c1st] == lowermap[(unsigned char)c2nd]; } bool irc::irc_char_traits::ne(char c1st, char c2nd) { - return lowermap[(unsigned)c1st] != lowermap[(unsigned)c2nd]; + return lowermap[(unsigned char)c1st] != lowermap[(unsigned char)c2nd]; } bool irc::irc_char_traits::lt(char c1st, char c2nd) { - return lowermap[(unsigned)c1st] < lowermap[(unsigned)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(unsigned int i = 0; i < n; i++) { - if(lowermap[(unsigned)*str1] > lowermap[(unsigned)*str2]) - return 1; + if(lowermap[(unsigned char)*str1] > lowermap[(unsigned char)*str2]) + return 1; - if(lowermap[(unsigned)*str1] < lowermap[(unsigned)*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++; @@ -152,19 +169,19 @@ irc::string operator+ (irc::string& leftval, std::string& rightval) return leftval + irc::string(rightval.c_str()); } -std::string operator== (std::string& leftval, irc::string& rightval) +bool operator== (std::string& leftval, irc::string& rightval) { return (leftval == std::string(rightval.c_str())); } -irc::string operator== (irc::string& leftval, std::string& rightval) +bool operator== (irc::string& leftval, std::string& rightval) { - return (rightval == irc::string(leftval.c_str())); + 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[(unsigned)*s1] != lowermap[(unsigned)c]) + while(n-- > 0 && lowermap[(unsigned char)*s1] != lowermap[(unsigned char)c]) s1++; return s1; } @@ -182,3 +199,79 @@ std::istream& operator>>(std::istream &is, irc::string &str) 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() +{ +}