The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

hashcomp.h

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *          the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 #ifndef _HASHCOMP_H_
00015 #define _HASHCOMP_H_
00016 
00017 #include <cstring>
00018 //#include "inspircd_config.h"
00019 //#include "socket.h"
00020 #include "hash_map.h"
00021 
00022 /*******************************************************
00023  * This file contains classes and templates that deal
00024  * with the comparison and hashing of 'irc strings'.
00025  * An 'irc string' is a string which compares in a
00026  * case insensitive manner, and as per RFC 1459 will
00027  * treat [ identical to {, ] identical to }, and \
00028  * as identical to |.
00029  *
00030  * Our hashing functions are designed  to accept
00031  * std::string and compare/hash them as type irc::string
00032  * by converting them internally. This makes them
00033  * backwards compatible with other code which is not
00034  * aware of irc::string.
00035  *******************************************************/
00036 
00037 #ifndef LOWERMAP
00038 #define LOWERMAP
00039 
00043 unsigned const char rfc_case_insensitive_map[256] = {
00044         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,                                   /* 0-19 */
00045         20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,                         /* 20-39 */
00046         40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,                         /* 40-59 */
00047         60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,             /* 60-79 */
00048         112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 94, 95, 96, 97, 98, 99,           /* 80-99 */
00049         100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,     /* 100-119 */
00050         120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,     /* 120-139 */
00051         140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,     /* 140-159 */
00052         160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,     /* 160-179 */
00053         180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,     /* 180-199 */
00054         200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,     /* 200-219 */
00055         220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,     /* 220-239 */
00056         240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255                          /* 240-255 */
00057 };
00058 
00059 /*
00060  * case sensitive map.
00061  */
00062 unsigned const char case_sensitive_map[256] = {
00063         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
00064         21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
00065         41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
00066         61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
00067         81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
00068         101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
00069         121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
00070         141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
00071         161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
00072         181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200,
00073         201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
00074         221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240,
00075         241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
00076 };
00077 
00078 #endif
00079 
00082 namespace irc
00083 {
00084 
00089         struct StrHashComp
00090         {
00093                 bool operator()(const std::string& s1, const std::string& s2) const;
00094         };
00095 
00100         struct irc_char_traits : std::char_traits<char> {
00101 
00107                 static bool eq(char c1st, char c2nd);
00108 
00114                 static bool ne(char c1st, char c2nd);
00115 
00121                 static bool lt(char c1st, char c2nd);
00122 
00130                 static CoreExport int compare(const char* str1, const char* str2, size_t n);
00131 
00138                 static CoreExport const char* find(const char* s1, int  n, char c);
00139         };
00140 
00146         CoreExport std::string hex(const unsigned char *raw, size_t rawsz);
00147 
00150         typedef std::basic_string<char, irc_char_traits, std::allocator<char> > string;
00151 
00158         class CoreExport stringjoiner : public classbase
00159         {
00160          private:
00163                 std::string joined;
00164          public:
00171                 stringjoiner(const std::string &seperator, const std::vector<std::string> &sequence, int begin, int end);
00178                 stringjoiner(const std::string &seperator, const std::deque<std::string> &sequence, int begin, int end);
00185                 stringjoiner(const std::string &seperator, const char* const* sequence, int begin, int end);
00186 
00190                 std::string& GetJoined();
00191         };
00192 
00197         class CoreExport modestacker : public classbase
00198         {
00199          private:
00200                 InspIRCd* ServerInstance;
00203                 std::deque<std::string> sequence;
00208                 bool adding;
00209          public:
00214                 modestacker(InspIRCd* Instance, bool add);
00223                 void Push(char modeletter, const std::string &parameter);
00231                 void Push(char modeletter);
00234                 void PushPlus();
00237                 void PushMinus();
00254                 int GetStackedLine(std::deque<std::string> &result, int max_line_size = 360);
00255         };
00256 
00269         class CoreExport tokenstream : public classbase
00270         {
00271          private:
00274                 std::string tokens;
00277                 std::string::iterator last_starting_position;
00280                 std::string::iterator n;
00283                 bool last_pushed;
00284          public:
00287                 tokenstream(const std::string &source);
00288                 ~tokenstream();
00289 
00294                 bool GetToken(std::string &token);
00295 
00300                 bool GetToken(irc::string &token);
00301 
00306                 bool GetToken(int &token);
00307 
00312                 bool GetToken(long &token);
00313         };
00314 
00320         class CoreExport sepstream : public classbase
00321         {
00322          private:
00325                 std::string tokens;
00328                 std::string::iterator last_starting_position;
00331                 std::string::iterator n;
00334                 char sep;
00335          public:
00338                 sepstream(const std::string &source, char seperator);
00339                 virtual ~sepstream();
00340 
00345                 virtual bool GetToken(std::string &token);
00346 
00350                 virtual const std::string GetRemaining();
00351 
00355                 virtual bool StreamEnd();
00356         };
00357 
00360         class CoreExport commasepstream : public sepstream
00361         {
00362          public:
00365                 commasepstream(const std::string &source) : sepstream(source, ',')
00366                 {
00367                 }
00368         };
00369 
00372         class CoreExport spacesepstream : public sepstream
00373         {
00374          public:
00377                 spacesepstream(const std::string &source) : sepstream(source, ' ')
00378                 {
00379                 }
00380         };
00381 
00390         class CoreExport portparser : public classbase
00391         {
00392          private:
00395                 commasepstream* sep;
00398                 long in_range;
00401                 long range_begin;
00404                 long range_end;
00407                 bool overlapped;
00411                 std::map<long, bool> overlap_set;
00414                 bool Overlaps(long val);
00415          public:
00420                 portparser(const std::string &source, bool allow_overlapped = true);
00423                 ~portparser();
00427                 long GetToken();
00428         };
00429 
00434         typedef std::pair<size_t, unsigned char> bitfield;
00435 
00494         class CoreExport dynamicbitmask : public classbase
00495         {
00496          private:
00501                 unsigned char* bits;
00502          protected:
00507                 unsigned char bits_size;
00508          public:
00512                 dynamicbitmask();
00513 
00516                 virtual ~dynamicbitmask();
00517 
00524                 bitfield Allocate();
00525 
00531                 bool Deallocate(bitfield &pos);
00532 
00538                 void Toggle(bitfield &pos, bool state);
00539 
00548                 bool Get(bitfield &pos);
00549 
00556                 unsigned char GetSize();
00557 
00560                 virtual unsigned char* GetFreeBits() { return NULL; }
00561 
00564                 virtual void SetFreeBits(unsigned char* freebits) { freebits = freebits; }
00565         };
00566 
00571         CoreExport const char* Spacify(const char* n);
00572 }
00573 
00574 /* Define operators for using >> and << with irc::string to an ostream on an istream. */
00575 /* This was endless fun. No. Really. */
00576 /* It was also the first core change Ommeh made, if anyone cares */
00577 
00580 inline std::ostream& operator<<(std::ostream &os, const irc::string &str) { return os << str.c_str(); }
00581 
00584 inline std::istream& operator>>(std::istream &is, irc::string &str)
00585 {
00586         std::string tmp;
00587         is >> tmp;
00588         str = tmp.c_str();
00589         return is;
00590 }
00591 
00592 /* Define operators for + and == with irc::string to std::string for easy assignment
00593  * and comparison
00594  *
00595  * Operator +
00596  */
00597 inline std::string operator+ (std::string& leftval, irc::string& rightval)
00598 {
00599         return leftval + std::string(rightval.c_str());
00600 }
00601 
00602 /* Define operators for + and == with irc::string to std::string for easy assignment
00603  * and comparison
00604  *
00605  * Operator +
00606  */
00607 inline irc::string operator+ (irc::string& leftval, std::string& rightval)
00608 {
00609         return leftval + irc::string(rightval.c_str());
00610 }
00611 
00612 /* Define operators for + and == with irc::string to std::string for easy assignment
00613  * and comparison
00614  *
00615  * Operator ==
00616  */
00617 inline bool operator== (const std::string& leftval, const irc::string& rightval)
00618 {
00619         return (leftval.c_str() == rightval);
00620 }
00621 
00622 /* Define operators for + and == with irc::string to std::string for easy assignment
00623  * and comparison
00624  *
00625  * Operator ==
00626  */
00627 inline bool operator== (const irc::string& leftval, const std::string& rightval)
00628 {
00629         return (leftval == rightval.c_str());
00630 }
00631 
00632 /* Define operators != for irc::string to std::string for easy comparison
00633  */
00634 inline bool operator!= (const irc::string& leftval, const std::string& rightval)
00635 {
00636         return !(leftval == rightval.c_str());
00637 }
00638 
00639 /* Define operators != for std::string to irc::string for easy comparison
00640  */
00641 inline bool operator!= (const std::string& leftval, const irc::string& rightval)
00642 {
00643         return !(leftval.c_str() == rightval);
00644 }
00645 
00646 // FIXME MAXBUF messes up these
00647 #if 0
00648 template<std::size_t N>
00649 static inline bool operator == (std::string const &lhs, char const (&rhs)[N])
00650 {
00651         return lhs.length() == N - 1 && !std::memcmp(lhs.data(), rhs, N - 1);
00652 }
00653 
00654 template<std::size_t N>
00655 static inline bool operator != (std::string const &lhs, char const (&rhs)[N])
00656 {
00657         return !(lhs == rhs);
00658 }
00659 #endif
00660 
00663 inline std::string assign(const irc::string &other) { return other.c_str(); }
00664 
00667 inline irc::string assign(const std::string &other) { return other.c_str(); }
00668 
00671 inline std::string& trim(std::string &str)
00672 {
00673         std::string::size_type start = str.find_first_not_of(" ");
00674         std::string::size_type end = str.find_last_not_of(" ");
00675         if (start == std::string::npos || end == std::string::npos)
00676                 str = "";
00677         else
00678                 str = str.substr(start, end-start+1);
00679 
00680         return str;
00681 }
00682 
00686 BEGIN_HASHMAP_NAMESPACE
00687 
00690 #ifdef WINDOWS
00691         template<> class CoreExport hash_compare<irc::string, std::less<irc::string> >
00692         {
00693         public:
00694                 enum { bucket_size = 4, min_buckets = 8 }; /* Got these numbers from the CRT source, if anyone wants to change them feel free. */
00695 
00698                 bool operator()(const irc::string & s1, const irc::string & s2) const
00699                 {
00700                         if(s1.length() != s2.length()) return true;
00701                         return (irc::irc_char_traits::compare(s1.c_str(), s2.c_str(), s1.length()) < 0);
00702                 }
00703 
00706                 size_t operator()(const irc::string & s) const;
00707         };
00708 
00709         template<> class CoreExport hash_compare<std::string, std::less<std::string> >
00710         {
00711         public:
00712                 enum { bucket_size = 4, min_buckets = 8 }; /* Again, from the CRT source */
00713 
00716                 bool operator()(const std::string & s1, const std::string & s2) const
00717                 {
00718                         if(s1.length() != s2.length()) return true;
00719                         return (irc::irc_char_traits::compare(s1.c_str(), s2.c_str(), s1.length()) < 0);
00720                 }
00721 
00726                 size_t operator()(const std::string & s) const;
00727         };
00728 #else
00729 
00730         template<> struct hash<irc::string>
00731         {
00736                 size_t operator()(const irc::string &s) const;
00737         };
00738 
00739         /* XXX FIXME: Implement a hash function overriding std::string's that works with TR1! */
00740 
00741 #ifdef HASHMAP_DEPRECATED
00742         struct insensitive
00743 #else
00744         template<> struct hash<std::string>
00745 #endif
00746         {
00747                 size_t operator()(const std::string &s) const;
00748         };
00749 
00750 #endif
00751 
00755         void strlower(char *n);
00756 
00757 END_HASHMAP_NAMESPACE
00758 
00759 #endif
00760