anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

anope.h (29522B)

      1 /*
      2  *
      3  * (C) 2003-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  *
      8  * Based on the original code of Epona by Lara.
      9  * Based on the original code of Services by Andy Church.
     10  */
     11 
     12 #ifndef ANOPE_H
     13 #define ANOPE_H
     14 
     15 #include <signal.h>
     16 
     17 #include "hashcomp.h"
     18 
     19 namespace Anope
     20 {
     21 	/**
     22 	 * A wrapper string class around all the other string classes, this class will
     23 	 * allow us to only require one type of string everywhere that can be converted
     24 	 * at any time to a specific type of string.
     25 	 */
     26 	class CoreExport string
     27 	{
     28 	 private:
     29 		/**
     30 		 * The actual string is stored in an std::string as it can be converted to
     31 		 * ci::string, or a C-style string at any time.
     32 		 */
     33 		std::string _string;
     34 	 public:
     35 		/**
     36 		 * Extras.
     37 		 */
     38 		typedef std::string::iterator iterator;
     39 		typedef std::string::const_iterator const_iterator;
     40 		typedef std::string::reverse_iterator reverse_iterator;
     41 		typedef std::string::const_reverse_iterator const_reverse_iterator;
     42 		typedef std::string::size_type size_type;
     43 		static const size_type npos = static_cast<size_type>(-1);
     44 
     45 		/**
     46 		 * Constructors that can take in any type of string.
     47 		 */
     48 		string() : _string("") { }
     49 		string(char chr) : _string() { _string = chr; }
     50 		string(size_type n, char chr) : _string(n, chr) { }
     51 		string(const char *_str) : _string(_str) { }
     52 		string(const char *_str, size_type n) : _string(_str, n) { }
     53 		string(const std::string &_str) : _string(_str) { }
     54 		string(const ci::string &_str) : _string(_str.c_str()) { }
     55 		string(const string &_str, size_type pos, size_type n = npos) : _string(_str._string, pos, n) { }
     56 		template <class InputIterator> string(InputIterator first, InputIterator last) : _string(first, last) { }
     57 #if __cplusplus >= 201103L
     58 		string(const string &) = default;
     59 #endif
     60 
     61 		/**
     62 		 * Assignment operators, so any type of string can be assigned to this class.
     63 		 */
     64 		inline string &operator=(char chr) { this->_string = chr; return *this; }
     65 		inline string &operator=(const char *_str) { this->_string = _str; return *this; }
     66 		inline string &operator=(const std::string &_str) { this->_string = _str; return *this; }
     67 		inline string &operator=(const string &_str) { if (this != &_str) this->_string = _str._string; return *this; }
     68 
     69 		/**
     70 		 * Equality operators, to compare to any type of string.
     71 		 */
     72 		inline bool operator==(const char *_str) const { return this->_string == _str; }
     73 		inline bool operator==(const std::string &_str) const { return this->_string == _str; }
     74 		inline bool operator==(const string &_str) const { return this->_string == _str._string; }
     75 
     76 		inline bool equals_cs(const char *_str) const { return this->_string == _str; }
     77 		inline bool equals_cs(const std::string &_str) const { return this->_string == _str; }
     78 		inline bool equals_cs(const string &_str) const { return this->_string == _str._string; }
     79 
     80 		inline bool equals_ci(const char *_str) const { return ci::string(this->_string.c_str()) == _str; }
     81 		inline bool equals_ci(const std::string &_str) const { return ci::string(this->_string.c_str()) == _str.c_str(); }
     82 		inline bool equals_ci(const string &_str) const { return ci::string(this->_string.c_str()) == _str._string.c_str(); }
     83 
     84 		/**
     85 		 * Inequality operators, exact opposites of the above.
     86 		 */
     87 		inline bool operator!=(const char *_str) const { return !operator==(_str); }
     88 		inline bool operator!=(const std::string &_str) const { return !operator==(_str); }
     89 		inline bool operator!=(const string &_str) const { return !operator==(_str); }
     90 
     91 		/**
     92 		 * Compound addition operators, overloaded to do concatenation.
     93 		 */
     94 		inline string &operator+=(char chr) { this->_string += chr; return *this; }
     95 		inline string &operator+=(const char *_str) { this->_string += _str; return *this; }
     96 		inline string &operator+=(const std::string &_str) { this->_string += _str; return *this; }
     97 		inline string &operator+=(const string &_str) { if (this != &_str) this->_string += _str._string; return *this; }
     98 
     99 		/**
    100 		 * Addition operators, overloaded to do concatenation.
    101 		 */
    102 		inline const string operator+(char chr) const { return string(*this) += chr; }
    103 		inline const string operator+(const char *_str) const { return string(*this) += _str; }
    104 		inline const string operator+(const std::string &_str) const { return string(*this) += _str; }
    105 		inline const string operator+(const string &_str) const { return string(*this) += _str; }
    106 
    107 		friend const string operator+(char chr, const string &str);
    108 		friend const string operator+(const char *_str, const string &str);
    109 		friend const string operator+(const std::string &_str, const string &str);
    110 
    111 		/**
    112 		 * Less-than operator.
    113 		 */
    114 		inline bool operator<(const string &_str) const { return this->_string < _str._string; }
    115 
    116 		/**
    117 		 * The following functions return the various types of strings.
    118 		 */
    119 		inline const char *c_str() const { return this->_string.c_str(); }
    120 		inline const char *data() const { return this->_string.data(); }
    121 		inline std::string &str() { return this->_string; }
    122 		inline const std::string &str() const { return this->_string; }
    123 		inline ci::string ci_str() const { return ci::string(this->_string.c_str()); }
    124 
    125 		/**
    126 		 * Returns if the string is empty or not.
    127 		 */
    128 		inline bool empty() const { return this->_string.empty(); }
    129 
    130 		/**
    131 		 * Returns the string's length.
    132 		 */
    133 		inline size_type length() const { return this->_string.length(); }
    134 
    135 		/**
    136 		 * Returns the size of the currently allocated storage space in the string object.
    137 		 * This can be equal or greater than the length of the string.
    138 		 */
    139 		inline size_type capacity() const { return this->_string.capacity(); }
    140 
    141 		/**
    142 		 * Add a char to the end of the string.
    143 		 */
    144 		inline void push_back(char c) { return this->_string.push_back(c); }
    145 
    146 		inline string& append(const string &s) { this->_string.append(s.str()); return *this; }
    147 		inline string& append(const char *s, size_t n) { this->_string.append(s, n); return *this; }
    148 
    149 		/**
    150 		 * Resizes the string content to n characters.
    151 		 */
    152 		inline void resize(size_type n) { return this->_string.resize(n); }
    153 
    154 		/**
    155 		 * Erases characters from the string.
    156 		 */
    157 		inline iterator erase(const iterator &i) { return this->_string.erase(i); }
    158 		inline iterator erase(const iterator &first, const iterator &last) { return this->_string.erase(first, last); }
    159 		inline void erase(size_type pos = 0, size_type n = std::string::npos) { this->_string.erase(pos, n); }
    160 
    161 		/**
    162 		 * Trim leading and trailing white spaces from the string.
    163 		 */
    164 
    165 		inline string& ltrim(const Anope::string &what = " \t\r\n")
    166 		{
    167 			while (!this->_string.empty() && what.find(this->_string[0]) != Anope::string::npos)
    168 				this->_string.erase(this->_string.begin());
    169 			return *this;
    170 		}
    171 
    172 		inline string& rtrim(const Anope::string &what = " \t\r\n")
    173 		{
    174 			while (!this->_string.empty() && what.find(this->_string[this->_string.length() - 1]) != Anope::string::npos)
    175 				this->_string.erase(this->_string.length() - 1);
    176 			return *this;
    177 		}
    178 
    179 		inline string& trim(const Anope::string &what = " \t\r\n")
    180 		{
    181 			this->ltrim(what);
    182 			this->rtrim(what);
    183 			return *this;
    184 		}
    185 
    186 		/**
    187 		 * Clears the string.
    188 		 */
    189 		inline void clear() { this->_string.clear(); }
    190 
    191 		/**
    192 		 * Find substrings of the string.
    193 		 */
    194 		inline size_type find(const string &_str, size_type pos = 0) const { return this->_string.find(_str._string, pos); }
    195 		inline size_type find(char chr, size_type pos = 0) const { return this->_string.find(chr, pos); }
    196 		inline size_type find_ci(const string &_str, size_type pos = 0) const { return ci::string(this->_string.c_str()).find(ci::string(_str._string.c_str()), pos); }
    197 		inline size_type find_ci(char chr, size_type pos = 0) const { return ci::string(this->_string.c_str()).find(chr, pos); }
    198 
    199 		inline size_type rfind(const string &_str, size_type pos = npos) const { return this->_string.rfind(_str._string, pos); }
    200 		inline size_type rfind(char chr, size_type pos = npos) const { return this->_string.rfind(chr, pos); }
    201 		inline size_type rfind_ci(const string &_str, size_type pos = npos) const { return ci::string(this->_string.c_str()).rfind(ci::string(_str._string.c_str()), pos); }
    202 		inline size_type rfind_ci(char chr, size_type pos = npos) const { return ci::string(this->_string.c_str()).rfind(chr, pos); }
    203 
    204 		inline size_type find_first_of(const string &_str, size_type pos = 0) const { return this->_string.find_first_of(_str._string, pos); }
    205 		inline size_type find_first_of_ci(const string &_str, size_type pos = 0) const { return ci::string(this->_string.c_str()).find_first_of(ci::string(_str._string.c_str()), pos); }
    206 
    207 		inline size_type find_first_not_of(const string &_str, size_type pos = 0) const { return this->_string.find_first_not_of(_str._string, pos); }
    208 		inline size_type find_first_not_of_ci(const string &_str, size_type pos = 0) const { return ci::string(this->_string.c_str()).find_first_not_of(ci::string(_str._string.c_str()), pos); }
    209 
    210 		inline size_type find_last_of(const string &_str, size_type pos = npos) const { return this->_string.find_last_of(_str._string, pos); }
    211 		inline size_type find_last_of_ci(const string &_str, size_type pos = npos) const { return ci::string(this->_string.c_str()).find_last_of(ci::string(_str._string.c_str()), pos); }
    212 
    213 		inline size_type find_last_not_of(const string &_str, size_type pos = npos) const { return this->_string.find_last_not_of(_str._string, pos); }
    214 		inline size_type find_last_not_of_ci(const string &_str, size_type pos = npos) const { return ci::string(this->_string.c_str()).find_last_not_of(ci::string(_str._string.c_str()), pos); }
    215 
    216 		/**
    217 		 * Determine if string consists of only numbers.
    218 		 */
    219 		inline bool is_number_only() const { return this->find_first_not_of("0123456789.-") == npos; }
    220 		inline bool is_pos_number_only() const { return this->find_first_not_of("0123456789.") == npos; }
    221 
    222 		/**
    223 		 * Replace parts of the string.
    224 		 */
    225 		inline string replace(size_type pos, size_type n, const string &_str) { return string(this->_string.replace(pos, n, _str._string)); }
    226 		inline string replace(size_type pos, size_type n, const string &_str, size_type pos1, size_type n1) { return string(this->_string.replace(pos, n, _str._string, pos1, n1)); }
    227 		inline string replace(size_type pos, size_type n, size_type n1, char chr) { return string(this->_string.replace(pos, n, n1, chr)); }
    228 		inline string replace(iterator first, iterator last, const string &_str) { return string(this->_string.replace(first, last, _str._string)); }
    229 		inline string replace(iterator first, iterator last, size_type n, char chr) { return string(this->_string.replace(first, last, n, chr)); }
    230 		template <class InputIterator> inline string replace(iterator first, iterator last, InputIterator f, InputIterator l) { return string(this->_string.replace(first, last, f, l)); }
    231 		inline string replace_all_cs(const string &_orig, const string &_repl) const
    232 		{
    233 			Anope::string new_string = *this;
    234 			size_type pos = new_string.find(_orig), orig_length = _orig.length(), repl_length = _repl.length();
    235 			while (pos != npos)
    236 			{
    237 				new_string = new_string.substr(0, pos) + _repl + new_string.substr(pos + orig_length);
    238 				pos = new_string.find(_orig, pos + repl_length);
    239 			}
    240 			return new_string;
    241 		}
    242 		inline string replace_all_ci(const string &_orig, const string &_repl) const
    243 		{
    244 			Anope::string new_string = *this;
    245 			size_type pos = new_string.find_ci(_orig), orig_length = _orig.length(), repl_length = _repl.length();
    246 			while (pos != npos)
    247 			{
    248 				new_string = new_string.substr(0, pos) + _repl + new_string.substr(pos + orig_length);
    249 				pos = new_string.find_ci(_orig, pos + repl_length);
    250 			}
    251 			return new_string;
    252 		}
    253 
    254 		/**
    255 		 * Get the string in lowercase.
    256 		 */
    257 		inline string lower() const
    258 		{
    259 			Anope::string new_string = *this;
    260 			for (size_type i = 0; i < new_string.length(); ++i)
    261 				new_string[i] = Anope::tolower(new_string[i]);
    262 			return new_string;
    263 		}
    264 
    265 		/**
    266 		 * Get the string in uppercase.
    267 		 */
    268 		inline string upper() const
    269 		{
    270 			Anope::string new_string = *this;
    271 			for (size_type i = 0; i < new_string.length(); ++i)
    272 				new_string[i] = Anope::toupper(new_string[i]);
    273 			return new_string;
    274 		}
    275 
    276 		/**
    277 		 * Get a substring of the string.
    278 		 */
    279 		inline string substr(size_type pos = 0, size_type n = npos) const { return string(this->_string.substr(pos, n)); }
    280 
    281 		/**
    282 		 * Iterators to the string.
    283 		 */
    284 		inline iterator begin() { return this->_string.begin(); }
    285 		inline const_iterator begin() const { return this->_string.begin(); }
    286 		inline iterator end() { return this->_string.end(); }
    287 		inline const_iterator end() const { return this->_string.end(); }
    288 		inline reverse_iterator rbegin() { return this->_string.rbegin(); }
    289 		inline const_reverse_iterator rbegin() const { return this->_string.rbegin(); }
    290 		inline reverse_iterator rend() { return this->_string.rend(); }
    291 		inline const_reverse_iterator rend() const { return this->_string.rend(); }
    292 
    293 		/**
    294 		 * Subscript operator, to access individual characters of the string.
    295 		 */
    296 		inline char &operator[](size_type n) { return this->_string[n]; }
    297 		inline const char &operator[](size_type n) const { return this->_string[n]; }
    298 
    299 		/**
    300 		 * Stream insertion operator, must be friend because they cannot be inside the class.
    301 		 */
    302 		friend std::ostream &operator<<(std::ostream &os, const string &_str);
    303 		friend std::istream &operator>>(std::istream &is, string &_str);
    304 	};
    305 
    306 	inline std::ostream &operator<<(std::ostream &os, const string &_str) { return os << _str._string; }
    307 	/* This is not standard to make operator>> behave like operator<< in that it will allow extracting a whole line, not just one word */
    308 	inline std::istream &operator>>(std::istream &is, string &_str) { return std::getline(is,  _str._string); }
    309 
    310 	inline const string operator+(char chr, const string &str) { string tmp(chr); tmp += str; return tmp; }
    311 	inline const string operator+(const char *_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
    312 	inline const string operator+(const std::string &_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
    313 
    314 	struct hash_ci
    315 	{
    316 		inline size_t operator()(const string &s) const
    317 		{
    318 			return TR1NS::hash<std::string>()(s.lower().str());
    319 		}
    320 	};
    321 
    322 	struct hash_cs
    323 	{
    324 		inline size_t operator()(const string &s) const
    325 		{
    326 			return TR1NS::hash<std::string>()(s.str());
    327 		}
    328 	};
    329 
    330 	struct compare
    331 	{
    332 		inline bool operator()(const string &s1, const string &s2) const
    333 		{
    334 			return s1.equals_ci(s2);
    335 		}
    336 	};
    337 
    338 	template<typename T> class map : public std::map<string, T, ci::less> { };
    339 	template<typename T> class multimap : public std::multimap<string, T, ci::less> { };
    340 	template<typename T> class hash_map : public TR1NS::unordered_map<string, T, hash_ci, compare> { };
    341 
    342 #ifndef REPRODUCIBLE_BUILD
    343 	static const char *const compiled = __TIME__ " " __DATE__;
    344 #endif
    345 
    346 	/** The time Anope started.
    347 	 */
    348 	extern CoreExport time_t StartTime;
    349 
    350 	/** The value to return from main()
    351 	 */
    352 	extern int ReturnValue;
    353 
    354 	extern sig_atomic_t Signal;
    355 	extern CoreExport bool Quitting;
    356 	extern CoreExport bool Restarting;
    357 	extern CoreExport Anope::string QuitReason;
    358 
    359 	/** The current system time, which is pretty close to being accurate.
    360 	 * Use this unless you need very specific time checks
    361 	 */
    362 	extern CoreExport time_t CurTime;
    363 
    364 	/** The debug level we are running at.
    365 	 */
    366 	extern CoreExport int Debug;
    367 
    368 	/** Other command line options.
    369 	 */
    370 	extern CoreExport bool ReadOnly, NoFork, NoThird, NoExpire, ProtocolDebug;
    371 
    372 	/** The root of the services installation. Usually ~/services
    373 	 */
    374 	extern CoreExport Anope::string ServicesDir;
    375 
    376 	/** Services binary name (eg services)
    377 	 */
    378 	extern CoreExport Anope::string ServicesBin;
    379 
    380 	/** Various directory paths. These can be set at runtime by command line args
    381 	 */
    382 	extern CoreExport Anope::string ConfigDir;
    383 	extern CoreExport Anope::string DataDir;
    384 	extern CoreExport Anope::string ModuleDir;
    385 	extern CoreExport Anope::string LocaleDir;
    386 	extern CoreExport Anope::string LogDir;
    387 
    388 	/** The uplink we are currently connected to
    389 	 */
    390 	extern CoreExport int CurrentUplink;
    391 
    392 	/** Various methods to determine the Anope version running
    393 	 */
    394 	extern CoreExport string Version();
    395 	extern CoreExport string VersionShort();
    396 	extern CoreExport string VersionBuildString();
    397 	extern CoreExport int VersionMajor();
    398 	extern CoreExport int VersionMinor();
    399 	extern CoreExport int VersionPatch();
    400 
    401 	/** Determines if we are still attached to the terminal, and can print
    402 	 * messages to the user via stderr/stdout.
    403 	 * @return true if still attached
    404 	 */
    405 	extern bool AtTerm();
    406 
    407 	/** Used to "fork" the process and go into the background during initial startup
    408 	 * while we are AtTerm(). The actual fork is not done here, but earlier, and this
    409 	 * simply notifies the parent via kill() to exit().
    410 	 */
    411 	extern void Fork();
    412 
    413 	/** Does something with the signal in Anope::Signal
    414 	 */
    415 	extern void HandleSignal();
    416 
    417 	/** One of the first functions called, does general initialization such as reading
    418 	 * command line args, loading the configuration, doing the initial fork() if necessary,
    419 	 * initializing language support, loading modules, and loading databases.
    420 	 * @throws CoreException if something bad went wrong
    421 	 */
    422 	extern void Init(int ac, char **av);
    423 
    424 	/** Calls the save database event
    425 	 */
    426 	extern CoreExport void SaveDatabases();
    427 
    428 	/** Check whether two strings match.
    429 	 * @param str The string to check against the pattern (e.g. foobar)
    430 	 * @param mask The pattern to check (e.g. foo*bar)
    431 	 * @param case_sensitive Whether or not the match is case sensitive, default false.
    432 	 * @param use_regex Whether or not to try regex. case_sensitive is not used in regex.
    433 	 */
    434 	extern CoreExport bool Match(const string &str, const string &mask, bool case_sensitive = false, bool use_regex = false);
    435 
    436 	/** Converts a string to hex
    437 	 * @param the data to be converted
    438 	 * @return a anope::string containing the hex value
    439 	 */
    440 	extern CoreExport string Hex(const string &data);
    441 	extern CoreExport string Hex(const char *data, unsigned len);
    442 
    443 	/** Converts a string from hex
    444 	 * @param src The data to be converted
    445 	 * @param dest The destination string
    446 	 */
    447 	extern CoreExport void Unhex(const string &src, string &dest);
    448 	extern CoreExport void Unhex(const string &src, char *dest, size_t sz);
    449 
    450 	/** Base 64 encode a string
    451 	 * @param src The string to encode
    452 	 * @param target Where the encoded string is placed
    453 	 */
    454 	extern CoreExport void B64Encode(const string &src, string &target);
    455 
    456 	/** Base 64 decode a string
    457 	 * @param src The base64 encoded string
    458 	 * @param target The plain text result
    459 	 */
    460 	extern CoreExport void B64Decode(const string &src, string &target);
    461 
    462 	/** Encrypts what is in 'src' to 'dest'
    463 	 * @param src The source string to encrypt
    464 	 * @param dest The destination where the encrypted string is placed
    465 	 */
    466 	extern CoreExport void Encrypt(const Anope::string &src, Anope::string &dest);
    467 
    468 	/** Decrypts what is in 'src' to 'dest'.
    469 	 * @param src The source string to decrypt
    470 	 * @param dest The destination where the decrypted string is placed
    471 	 * @return true if decryption was successful. This is usually not the case
    472 	 * as most encryption methods we use are one way.
    473 	 */
    474 	extern CoreExport bool Decrypt(const Anope::string &src, Anope::string &dest);
    475 
    476 	/** Hashes a buffer with SipHash-2-4
    477 	 * @param src The start of the buffer to hash
    478 	 * @param src_sz The total number of bytes in the buffer
    479 	 * @param key A 16 byte key to hash the buffer with.
    480 	 */
    481 	extern CoreExport uint64_t SipHash24(const void *src, unsigned long src_sz, const char key[16]);
    482 
    483 	/** Returns a sequence of data formatted as the format argument specifies.
    484 	 ** After the format parameter, the function expects at least as many
    485 	 ** additional arguments as specified in format.
    486 	 * @param fmt Format of the Message
    487 	 * @param ... any number of parameters
    488 	 * @return a Anope::string
    489 	 */
    490 	extern CoreExport string printf(const char *fmt, ...);
    491 
    492 	/** Return the last error code
    493 	 * @return The error code
    494 	 */
    495 	extern CoreExport int LastErrorCode();
    496 
    497 	/** Return the last error, uses errno/GetLastError() to determine this
    498 	 * @return An error message
    499 	 */
    500 	extern CoreExport const string LastError();
    501 
    502 	/** Determines if a path is a file
    503 	 */
    504 	extern CoreExport bool IsFile(const Anope::string &file);
    505 
    506 	/** Converts a string into seconds
    507 	 * @param s The string, eg 3d
    508 	 * @return The time represented by the string, eg 259,200
    509 	 */
    510 	extern CoreExport time_t DoTime(const Anope::string &s);
    511 
    512 	/** Retrieves a human readable string representing the time in seconds
    513 	 * @param seconds The time on seconds, eg 60
    514 	 * @param nc The account to use language settings for to translate this string, if applicable
    515 	 * @return A human readable string, eg "1 minute"
    516 	 */
    517 	extern CoreExport Anope::string Duration(time_t seconds, const NickCore *nc = NULL);
    518 
    519 	/** Generates a human readable string of type "expires in ..."
    520 	 * @param expires time in seconds
    521 	 * @param nc The account to use language settings for to translate this string, if applicable
    522 	 * @return A human readable string, eg "expires in 5 days"
    523 	 */
    524 	extern CoreExport Anope::string Expires(time_t seconds, const NickCore *nc = NULL);
    525 
    526 	/** Converts a time in seconds (epoch) to a human readable format.
    527 	 * @param t The time
    528 	 * @param nc The account to use language settings for to translate this string, if applicable
    529 	 * @param short_output If true, the output is just a date (eg, "Apr 12 20:18:22 2009 MSD"), else it includes the date and how long ago/from now that date is, (eg "Apr 12 20:18:22 2009 MSD (1313 days, 9 hours, 32 minutes ago)"
    530 	 */
    531 	extern CoreExport Anope::string strftime(time_t t, const NickCore *nc = NULL, bool short_output = false);
    532 
    533 	/** Normalize buffer, stripping control characters and colors
    534 	 * @param A string to be parsed for control and color codes
    535 	 * @return A string stripped of control and color codes
    536 	 */
    537 	extern CoreExport Anope::string NormalizeBuffer(const Anope::string &);
    538 
    539 	/** Main processing routine. Parses the message and takes the appropriate action.
    540 	 * @param Raw message from the uplink
    541 	 */
    542 	extern void Process(const Anope::string &);
    543 
    544 	/** Does a blocking dns query and returns the first IP.
    545 	 * @param host host to look up
    546 	 * @param type inet addr type
    547 	 * @return the IP if it was found, else the host
    548 	 */
    549 	extern Anope::string Resolve(const Anope::string &host, int type);
    550 
    551 	/** Generate a string of random letters and numbers
    552 	 * @param len The length of the string returned
    553 	 */
    554 	extern CoreExport Anope::string Random(size_t len);
    555 }
    556 
    557 /** sepstream allows for splitting token separated lists.
    558  * Each successive call to sepstream::GetToken() returns
    559  * the next token, until none remain, at which point the method returns
    560  * an empty string.
    561  */
    562 class CoreExport sepstream
    563 {
    564  private:
    565 	/** Original string.
    566 	 */
    567 	Anope::string tokens;
    568 	/** Seperator value
    569 	 */
    570 	char sep;
    571 	/** Current string position
    572 	 */
    573 	size_t pos;
    574 	/** If set then GetToken() can return an empty string
    575 	 */
    576 	bool allow_empty;
    577  public:
    578 	/** Create a sepstream and fill it with the provided data
    579 	 */
    580 	sepstream(const Anope::string &source, char separator, bool allowempty = false);
    581 
    582 	/** Fetch the next token from the stream
    583 	 * @param token The next token from the stream is placed here
    584 	 * @return True if tokens still remain, false if there are none left
    585 	 */
    586 	bool GetToken(Anope::string &token);
    587 
    588 	/** Gets token number 'num' from the stream
    589 	 * @param token The token is placed here
    590 	 * @param num The token number to fetch
    591 	 * @return True if the token was able to be fetched
    592 	 */
    593 	bool GetToken(Anope::string &token, int num);
    594 
    595 	/** Gets every token from this stream
    596 	 * @param token Tokens are pushed back here
    597 	 */
    598 	template<typename T> void GetTokens(T& token)
    599 	{
    600 		token.clear();
    601 		Anope::string t;
    602 		while (this->GetToken(t))
    603 			token.push_back(t);
    604 	}
    605 
    606 	/** Gets token number 'num' from the stream and all remaining tokens.
    607 	 * @param token The token is placed here
    608 	 * @param num The token number to fetch
    609 	 * @return True if the token was able to be fetched
    610 	 */
    611 	bool GetTokenRemainder(Anope::string &token, int num);
    612 
    613 	/** Determines the number of tokens in this stream.
    614 	 * @return The number of tokens in this stream
    615 	 */
    616 	int NumTokens();
    617 
    618 	/** Fetch the entire remaining stream, without tokenizing
    619 	 * @return The remaining part of the stream
    620 	 */
    621 	const Anope::string GetRemaining();
    622 
    623 	/** Returns true if the end of the stream has been reached
    624 	 * @return True if the end of the stream has been reached, otherwise false
    625 	 */
    626 	bool StreamEnd();
    627 };
    628 
    629 /** A derived form of sepstream, which separates on commas
    630  */
    631 class commasepstream : public sepstream
    632 {
    633  public:
    634 	/** Initialize with comma separator
    635 	 */
    636 	commasepstream(const Anope::string &source, bool allowempty = false) : sepstream(source, ',', allowempty) { }
    637 };
    638 
    639 /** A derived form of sepstream, which separates on spaces
    640  */
    641 class spacesepstream : public sepstream
    642 {
    643  public:
    644 	/** Initialize with space separator
    645 	 */
    646 	spacesepstream(const Anope::string &source) : sepstream(source, ' ') { }
    647 };
    648 
    649 /** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
    650  * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or
    651  * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not
    652  * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user
    653  * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time.
    654  */
    655 class CoreException : public std::exception
    656 {
    657  protected:
    658 	/** Holds the error message to be displayed
    659 	 */
    660 	Anope::string err;
    661 	/** Source of the exception
    662 	 */
    663 	Anope::string source;
    664  public:
    665 	/** Default constructor, just uses the error message 'Core threw an exception'.
    666 	 */
    667 	CoreException() : err("Core threw an exception"), source("The core") { }
    668 	/** This constructor can be used to specify an error message before throwing.
    669 	 */
    670 	CoreException(const Anope::string &message) : err(message), source("The core") { }
    671 	/** This constructor can be used to specify an error message before throwing,
    672 	 * and to specify the source of the exception.
    673 	 */
    674 	CoreException(const Anope::string &message, const Anope::string &src) : err(message), source(src) { }
    675 	/** This destructor solves world hunger, cancels the world debt, and causes the world to end.
    676 	 * Actually no, it does nothing. Never mind.
    677 	 * @throws Nothing!
    678 	 */
    679 	virtual ~CoreException() throw() { }
    680 	/** Returns the reason for the exception.
    681 	 * The module should probably put something informative here as the user will see this upon failure.
    682 	 */
    683 	virtual const Anope::string &GetReason() const
    684 	{
    685 		return err;
    686 	}
    687 
    688 	virtual const Anope::string &GetSource() const
    689 	{
    690 		return source;
    691 	}
    692 };
    693 
    694 class ModuleException : public CoreException
    695 {
    696  public:
    697 	/** Default constructor, just uses the error message 'Module threw an exception'.
    698 	 */
    699 	ModuleException() : CoreException("Module threw an exception", "A Module") { }
    700 
    701 	/** This constructor can be used to specify an error message before throwing.
    702 	 */
    703 	ModuleException(const Anope::string &message) : CoreException(message, "A Module") { }
    704 	/** This destructor solves world hunger, cancels the world debt, and causes the world to end.
    705 	 * Actually no, it does nothing. Never mind.
    706 	 * @throws Nothing!
    707 	 */
    708 	virtual ~ModuleException() throw() { }
    709 };
    710 
    711 class ConvertException : public CoreException
    712 {
    713  public:
    714 	ConvertException(const Anope::string &reason = "") : CoreException(reason) { }
    715 
    716 	virtual ~ConvertException() throw() { }
    717 };
    718 
    719 /** Convert something to a string
    720  */
    721 template<typename T> inline Anope::string stringify(const T &x)
    722 {
    723 	std::ostringstream stream;
    724 
    725 	if (!(stream << x))
    726 		throw ConvertException("Stringify fail");
    727 
    728 	return stream.str();
    729 }
    730 
    731 template<typename T> inline void convert(const Anope::string &s, T &x, Anope::string &leftover, bool failIfLeftoverChars = true)
    732 {
    733 	leftover.clear();
    734 	std::istringstream i(s.str());
    735 	char c;
    736 	if (!(i >> x))
    737 		throw ConvertException("Convert fail");
    738 	if (failIfLeftoverChars)
    739 	{
    740 		if (i.get(c))
    741 			throw ConvertException("Convert fail");
    742 	}
    743 	else
    744 	{
    745 		std::string left;
    746 		getline(i, left);
    747 		leftover = left;
    748 	}
    749 }
    750 
    751 template<typename T> inline void convert(const Anope::string &s, T &x, bool failIfLeftoverChars = true)
    752 {
    753 	Anope::string Unused;
    754 	convert(s, x, Unused, failIfLeftoverChars);
    755 }
    756 
    757 template<typename T> inline T convertTo(const Anope::string &s, Anope::string &leftover, bool failIfLeftoverChars = true)
    758 {
    759 	T x;
    760 	convert(s, x, leftover, failIfLeftoverChars);
    761 	return x;
    762 }
    763 
    764 template<typename T> inline T convertTo(const Anope::string &s, bool failIfLeftoverChars = true)
    765 {
    766 	T x;
    767 	convert(s, x, failIfLeftoverChars);
    768 	return x;
    769 }
    770 
    771 /** Casts to be used instead of dynamic_cast, this uses dynamic_cast
    772  * for debug builds and static_cast on release builds
    773  * to speed up the program because dynamic_cast relies on RTTI.
    774  */
    775 #ifdef DEBUG_BUILD
    776 # include <typeinfo>
    777 template<typename T, typename O> inline T anope_dynamic_static_cast(O ptr)
    778 {
    779 	T ret = dynamic_cast<T>(ptr);
    780 	if (ptr != NULL && ret == NULL)
    781 		throw CoreException(Anope::string("anope_dynamic_static_cast<") + typeid(T).name() + ">(" + typeid(O).name() + ") fail");
    782 	return ret;
    783 }
    784 #else
    785 template<typename T, typename O> inline T anope_dynamic_static_cast(O ptr)
    786 {
    787 	return static_cast<T>(ptr);
    788 }
    789 #endif
    790 
    791 #endif // ANOPE_H