X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=include%2Fhashcomp.h;h=2d6be15a9be097d09d40c2f0e362fde5bf3991fa;hb=5e9a6b9186a8cbaaf65ae7d9cd9c0c033c91b497;hp=b22f65272a81cbe85da5772b6d9ecdb7ae240b61;hpb=e25e200024db92c4584660e9d144902cfd4d626e;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/include/hashcomp.h b/include/hashcomp.h index b22f65272..2d6be15a9 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -2,12 +2,9 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. - * E-mail: - * - * + * InspIRCd: (C) 2002-2007 InspIRCd Development Team + * See: http://www.inspircd.org/wiki/index.php/Credits * - * Written by Craig Edwards, Craig McLure, and others. * This program is free but copyrighted software; see * the file COPYING for details. * @@ -132,6 +129,8 @@ namespace irc class stringjoiner { private: + /** Output string + */ std::string joined; public: /** Join elements of a vector, between (and including) begin and end @@ -232,9 +231,17 @@ namespace irc class tokenstream { private: + /** Original string + */ std::string tokens; + /** Last position of a seperator token + */ std::string::iterator last_starting_position; + /** Current string position + */ std::string::iterator n; + /** True if the last value was an ending value + */ bool last_pushed; public: /** Create a tokenstream and fill it with the provided data @@ -243,37 +250,45 @@ namespace irc ~tokenstream(); /** Fetch the next token from the stream - * @returns The next token is returned, or an empty string if none remain + * @return The next token is returned, or an empty string if none remain */ const std::string GetToken(); }; - /** irc::commasepstream allows for splitting comma seperated lists. - * Lists passed to irc::commasepstream should not contain spaces - * after the commas, or this will be taken to be part of the item - * data. Each successive call to commasepstream::GetToken() returns + /** irc::sepstream allows for splitting token seperated lists. + * Each successive call to sepstream::GetToken() returns * the next token, until none remain, at which point the method returns * an empty string. */ class sepstream : public classbase { private: + /** Original string + */ std::string tokens; + /** Last position of a seperator token + */ std::string::iterator last_starting_position; + /** Current string position + */ std::string::iterator n; + /** Seperator value + */ char sep; public: - /** Create a commasepstream and fill it with the provided data + /** Create a sepstream and fill it with the provided data */ sepstream(const std::string &source, char seperator); virtual ~sepstream(); /** Fetch the next token from the stream - * @returns The next token is returned, or an empty string if none remain + * @return The next token is returned, or an empty string if none remain */ virtual const std::string GetToken(); }; + /** A derived form of sepstream, which seperates on commas + */ class commasepstream : public sepstream { public: @@ -282,6 +297,8 @@ namespace irc } }; + /** A derived form of sepstream, which seperates on spaces + */ class spacesepstream : public sepstream { public: @@ -290,6 +307,186 @@ namespace irc } }; + /** The portparser class seperates out a port range into integers. + * A port range may be specified in the input string in the form + * "6660,6661,6662-6669,7020". The end of the stream is indicated by + * a return value of 0 from portparser::GetToken(). If you attempt + * to specify an illegal range (e.g. one where start >= end, or + * start or end < 0) then GetToken() will return the first element + * of the pair of numbers. + */ + class portparser : public classbase + { + private: + /** Used to split on commas + */ + commasepstream* sep; + /** Current position in a range of ports + */ + long in_range; + /** Starting port in a range of ports + */ + long range_begin; + /** Ending port in a range of ports + */ + long range_end; + /** Allow overlapped port ranges + */ + bool overlapped; + /** Used to determine overlapping of ports + * without O(n) algorithm being used + */ + std::map overlap_set; + /** Returns true if val overlaps an existing range + */ + bool Overlaps(long val); + public: + /** Create a portparser and fill it with the provided data + * @param source The source text to parse from + * @param allow_overlapped Allow overlapped ranges + */ + portparser(const std::string &source, bool allow_overlapped = true); + /** Frees the internal commasepstream object + */ + ~portparser(); + /** Fetch the next token from the stream + * @return The next port number is returned, or 0 if none remain + */ + long GetToken(); + }; + + /** Used to hold a bitfield definition in dynamicbitmask. + * You must be allocated one of these by dynamicbitmask::Allocate(), + * you should not fill the values yourself! + */ + typedef std::pair bitfield; + + /** The irc::dynamicbitmask class is used to maintain a bitmap of + * boolean values, which can grow to any reasonable size no matter + * how many bitfields are in it. + * + * It starts off at 32 bits in size, large enough to hold 32 boolean + * values, with a memory allocation of 8 bytes. If you allocate more + * than 32 bits, the class will grow the bitmap by 8 bytes at a time + * for each set of 8 bitfields you allocate with the Allocate() + * method. + * + * This method is designed so that multiple modules can be allocated + * bit values in a bitmap dynamically, rather than having to define + * costs in a fixed size unsigned integer and having the possibility + * of collisions of values in different third party modules. + * + * IMPORTANT NOTE: + * + * To use this class, you must derive from it. + * This is because each derived instance has its own freebits array + * which can determine what bitfields are allocated on a TYPE BY TYPE + * basis, e.g. an irc::dynamicbitmask type for userrecs, and one for + * chanrecs, etc. You should inheret it in a very simple way as follows. + * The base class will resize and maintain freebits as required, you are + * just required to make the pointer static and specific to this class + * type. + * + * \code + * class mydbitmask : public irc::dynamicbitmask + * { + * private: + * + * static unsigned char* freebits; + * + * public: + * + * mydbitmask() : irc::dynamicbitmask() + * { + * freebits = new unsigned char[this->bits_size]; + * memset(freebits, 0, this->bits_size); + * } + * + * ~mydbitmask() + * { + * delete[] freebits; + * } + * + * unsigned char* GetFreeBits() + * { + * return freebits; + * } + * + * void SetFreeBits(unsigned char* freebt) + * { + * freebits = freebt; + * } + * }; + * \endcode + */ + class dynamicbitmask : public classbase + { + private: + /** Data bits. We start with four of these, + * and we grow the bitfield as we allocate + * more than 32 entries with Allocate(). + */ + unsigned char* bits; + protected: + /** Current set size (size of freebits and bits). + * Both freebits and bits will ALWAYS be the + * same length. + */ + unsigned char bits_size; + public: + /** Allocate the initial memory for bits and + * freebits and zero the memory. + */ + dynamicbitmask(); + + /** Free the memory used by bits and freebits + */ + virtual ~dynamicbitmask(); + + /** Allocate an irc::bitfield. + * @return An irc::bitfield which can be used + * with Get, Deallocate and Toggle methods. + * @throw Can throw std::bad_alloc if there is + * no ram left to grow the bitmask. + */ + bitfield Allocate(); + + /** Deallocate an irc::bitfield. + * @param An irc::bitfield to deallocate. + * @return True if the bitfield could be + * deallocated, false if it could not. + */ + bool Deallocate(bitfield &pos); + + /** Toggle the value of a bitfield. + * @param pos A bitfield to allocate, previously + * allocated by dyamicbitmask::Allocate(). + * @param state The state to set the field to. + */ + void Toggle(bitfield &pos, bool state); + + /** Get the value of a bitfield. + * @param pos A bitfield to retrieve, previously + * allocated by dyamicbitmask::Allocate(). + * @return The value of the bitfield. + * @throw Will throw ModuleException if the bitfield + * you provide is outside of the range + * 0 >= bitfield.first < size_bits. + */ + bool Get(bitfield &pos); + + /** Return the size in bytes allocated to the bits + * array. + * Note that the actual allocation is twice this, + * as there are an equal number of bytes allocated + * for the freebits array. + */ + unsigned char GetSize(); + + virtual unsigned char* GetFreeBits() { return NULL; } + + virtual void SetFreeBits(unsigned char* freebits) { } + }; /** The irc_char_traits class is used for RFC-style comparison of strings. * This class is used to implement irc::string, a case-insensitive, RFC- @@ -324,7 +521,7 @@ namespace irc */ typedef basic_string > string; - const char* Spacify(char* n); + const char* Spacify(const char* n); } /* Define operators for using >> and << with irc::string to an ostream on an istream. */ @@ -341,4 +538,17 @@ irc::string operator+ (irc::string& leftval, std::string& rightval); bool operator== (std::string& leftval, irc::string& rightval); bool operator== (irc::string& leftval, std::string& rightval); +std::string assign(const irc::string &other); +irc::string assign(const std::string &other); + +namespace nspace +{ + /** Hashing function to hash irc::string + */ + template<> struct hash + { + size_t operator()(const irc::string &s) const; + }; +} + #endif