anope.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  *
00011  */
00012 
00013 #ifndef ANOPE_H
00014 #define ANOPE_H
00015 
00016 #include <signal.h>
00017 
00018 #include "hashcomp.h"
00019 
00020 namespace Anope
00021 {
00027         class CoreExport string
00028         {
00029          private:
00034                 std::string _string;
00035          public:
00039                 typedef std::string::iterator iterator;
00040                 typedef std::string::const_iterator const_iterator;
00041                 typedef std::string::reverse_iterator reverse_iterator;
00042                 typedef std::string::const_reverse_iterator const_reverse_iterator;
00043                 typedef std::string::size_type size_type;
00044                 static const size_type npos = static_cast<size_type>(-1);
00045 
00049                 string() : _string("") { }
00050                 string(char chr) : _string() { _string = chr; }
00051                 string(size_type n, char chr) : _string(n, chr) { }
00052                 string(const char *_str) : _string(_str) { }
00053                 string(const char *_str, size_type n) : _string(_str, n) { }
00054                 string(const std::string &_str) : _string(_str) { }
00055                 string(const ci::string &_str) : _string(_str.c_str()) { }
00056                 string(const string &_str, size_type pos, size_type n = npos) : _string(_str._string, pos, n) { }
00057                 template <class InputIterator> string(InputIterator first, InputIterator last) : _string(first, last) { }
00058 
00062                 inline string &operator=(char chr) { this->_string = chr; return *this; }
00063                 inline string &operator=(const char *_str) { this->_string = _str; return *this; }
00064                 inline string &operator=(const std::string &_str) { this->_string = _str; return *this; }
00065                 inline string &operator=(const string &_str) { if (this != &_str) this->_string = _str._string; return *this; }
00066 
00070                 inline bool operator==(const char *_str) const { return this->_string == _str; }
00071                 inline bool operator==(const std::string &_str) const { return this->_string == _str; }
00072                 inline bool operator==(const string &_str) const { return this->_string == _str._string; }
00073 
00074                 inline bool equals_cs(const char *_str) const { return this->_string == _str; }
00075                 inline bool equals_cs(const std::string &_str) const { return this->_string == _str; }
00076                 inline bool equals_cs(const string &_str) const { return this->_string == _str._string; }
00077 
00078                 inline bool equals_ci(const char *_str) const { return ci::string(this->_string.c_str()) == _str; }
00079                 inline bool equals_ci(const std::string &_str) const { return ci::string(this->_string.c_str()) == _str.c_str(); }
00080                 inline bool equals_ci(const string &_str) const { return ci::string(this->_string.c_str()) == _str._string.c_str(); }
00081 
00085                 inline bool operator!=(const char *_str) const { return !operator==(_str); }
00086                 inline bool operator!=(const std::string &_str) const { return !operator==(_str); }
00087                 inline bool operator!=(const string &_str) const { return !operator==(_str); }
00088 
00092                 inline string &operator+=(char chr) { this->_string += chr; return *this; }
00093                 inline string &operator+=(const char *_str) { this->_string += _str; return *this; }
00094                 inline string &operator+=(const std::string &_str) { this->_string += _str; return *this; }
00095                 inline string &operator+=(const string &_str) { if (this != &_str) this->_string += _str._string; return *this; }
00096 
00100                 inline const string operator+(char chr) const { return string(*this) += chr; }
00101                 inline const string operator+(const char *_str) const { return string(*this) += _str; }
00102                 inline const string operator+(const std::string &_str) const { return string(*this) += _str; }
00103                 inline const string operator+(const string &_str) const { return string(*this) += _str; }
00104 
00105                 friend const string operator+(char chr, const string &str);
00106                 friend const string operator+(const char *_str, const string &str);
00107                 friend const string operator+(const std::string &_str, const string &str);
00108 
00112                 inline bool operator<(const string &_str) const { return this->_string < _str._string; }
00113 
00117                 inline const char *c_str() const { return this->_string.c_str(); }
00118                 inline std::string &str() { return this->_string; }
00119                 inline const std::string &str() const { return this->_string; }
00120                 inline ci::string ci_str() const { return ci::string(this->_string.c_str()); }
00121 
00125                 inline bool empty() const { return this->_string.empty(); }
00126 
00130                 inline size_type length() const { return this->_string.length(); }
00131 
00136                 inline size_type capacity() const { return this->_string.capacity(); }
00137 
00141                 inline void push_back(char c) { return this->_string.push_back(c); }
00142 
00143                 inline string& append(const string &s) { this->_string.append(s.str()); return *this; }
00144                 inline string& append(const char *s, size_t n) { this->_string.append(s, n); return *this; }
00145 
00149                 inline void resize(size_type n) { return this->_string.resize(n); }
00150 
00154                 inline iterator erase(const iterator &i) { return this->_string.erase(i); }
00155                 inline iterator erase(const iterator &first, const iterator &last) { return this->_string.erase(first, last); }
00156                 inline void erase(size_type pos = 0, size_type n = std::string::npos) { this->_string.erase(pos, n); }
00157 
00162                 inline string& ltrim()
00163                 {
00164                         while (!this->_string.empty() && isspace(this->_string[0]))
00165                                 this->_string.erase(this->_string.begin());
00166                         return *this;
00167                 }
00168 
00169                 inline string& rtrim()
00170                 {
00171                         while (!this->_string.empty() && isspace(this->_string[this->_string.length() - 1]))
00172                                 this->_string.erase(this->_string.length() - 1);
00173                         return *this;
00174                 }
00175 
00176                 inline string& trim()
00177                 {
00178                         this->ltrim();
00179                         this->rtrim();
00180                         return *this;
00181                 }
00182 
00186                 inline void clear() { this->_string.clear(); }
00187 
00191                 inline size_type find(const string &_str, size_type pos = 0) const { return this->_string.find(_str._string, pos); }
00192                 inline size_type find(char chr, size_type pos = 0) const { return this->_string.find(chr, pos); }
00193                 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); }
00194                 inline size_type find_ci(char chr, size_type pos = 0) const { return ci::string(this->_string.c_str()).find(chr, pos); }
00195 
00196                 inline size_type rfind(const string &_str, size_type pos = npos) const { return this->_string.rfind(_str._string, pos); }
00197                 inline size_type rfind(char chr, size_type pos = npos) const { return this->_string.rfind(chr, pos); }
00198                 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); }
00199                 inline size_type rfind_ci(char chr, size_type pos = npos) const { return ci::string(this->_string.c_str()).rfind(chr, pos); }
00200 
00201                 inline size_type find_first_of(const string &_str, size_type pos = 0) const { return this->_string.find_first_of(_str._string, pos); }
00202                 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); }
00203 
00204                 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); }
00205                 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); }
00206 
00207                 inline size_type find_last_of(const string &_str, size_type pos = npos) const { return this->_string.find_last_of(_str._string, pos); }
00208                 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); }
00209 
00210                 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); }
00211                 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); }
00212 
00216                 inline bool is_number_only() const { return this->find_first_not_of("0123456789.-") == npos; }
00217                 inline bool is_pos_number_only() const { return this->find_first_not_of("0123456789.") == npos; }
00218 
00222                 inline string replace(size_type pos, size_type n, const string &_str) { return string(this->_string.replace(pos, n, _str._string)); }
00223                 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)); }
00224                 inline string replace(size_type pos, size_type n, size_type n1, char chr) { return string(this->_string.replace(pos, n, n1, chr)); }
00225                 inline string replace(iterator first, iterator last, const string &_str) { return string(this->_string.replace(first, last, _str._string)); }
00226                 inline string replace(iterator first, iterator last, size_type n, char chr) { return string(this->_string.replace(first, last, n, chr)); }
00227                 template <class InputIterator> inline string replace(iterator first, iterator last, InputIterator f, InputIterator l) { return string(this->_string.replace(first, last, f, l)); }
00228                 inline string replace_all_cs(const string &_orig, const string &_repl)
00229                 {
00230                         Anope::string new_string = *this;
00231                         size_type pos = new_string.find(_orig), orig_length = _orig.length(), repl_length = _repl.length();
00232                         while (pos != npos)
00233                         {
00234                                 new_string = new_string.substr(0, pos) + _repl + new_string.substr(pos + orig_length);
00235                                 pos = new_string.find(_orig, pos + repl_length);
00236                         }
00237                         return new_string;
00238                 }
00239                 inline string replace_all_ci(const string &_orig, const string &_repl)
00240                 {
00241                         Anope::string new_string = *this;
00242                         size_type pos = new_string.find_ci(_orig), orig_length = _orig.length(), repl_length = _repl.length();
00243                         while (pos != npos)
00244                         {
00245                                 new_string = new_string.substr(0, pos) + _repl + new_string.substr(pos + orig_length);
00246                                 pos = new_string.find_ci(_orig, pos + repl_length);
00247                         }
00248                         return new_string;
00249                 }
00250 
00254                 inline string lower() const
00255                 {
00256                         Anope::string new_string = *this;
00257                         for (size_type i = 0; i < new_string.length(); ++i)
00258                                 new_string[i] = std::tolower(new_string[i], Anope::casemap);
00259                         return new_string;
00260                 }
00261 
00265                 inline string upper() const
00266                 {
00267                         Anope::string new_string = *this;
00268                         for (size_type i = 0; i < new_string.length(); ++i)
00269                                 new_string[i] = std::toupper(new_string[i], Anope::casemap);
00270                         return new_string;
00271                 }
00272 
00276                 inline string substr(size_type pos = 0, size_type n = npos) const { return string(this->_string.substr(pos, n)); }
00277 
00281                 inline iterator begin() { return this->_string.begin(); }
00282                 inline const_iterator begin() const { return this->_string.begin(); }
00283                 inline iterator end() { return this->_string.end(); }
00284                 inline const_iterator end() const { return this->_string.end(); }
00285                 inline reverse_iterator rbegin() { return this->_string.rbegin(); }
00286                 inline const_reverse_iterator rbegin() const { return this->_string.rbegin(); }
00287                 inline reverse_iterator rend() { return this->_string.rend(); }
00288                 inline const_reverse_iterator rend() const { return this->_string.rend(); }
00289 
00293                 inline char &operator[](size_type n) { return this->_string[n]; }
00294                 inline const char &operator[](size_type n) const { return this->_string[n]; }
00295 
00299                 friend std::ostream &operator<<(std::ostream &os, const string &_str);
00300                 friend std::istream &operator>>(std::istream &is, string &_str);
00301         };
00302 
00303         inline std::ostream &operator<<(std::ostream &os, const string &_str) { return os << _str._string; }
00304         /* This is not standard to make operator>> behave like operator<< in that it will allow extracting a whole line, not just one word */
00305         inline std::istream &operator>>(std::istream &is, string &_str) { return std::getline(is,  _str._string); }
00306 
00307         inline const string operator+(char chr, const string &str) { string tmp(chr); tmp += str; return tmp; }
00308         inline const string operator+(const char *_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
00309         inline const string operator+(const std::string &_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
00310 
00311         struct hash_ci
00312         {
00313                 inline size_t operator()(const string &s) const
00314                 {
00315                         return std::tr1::hash<std::string>()(s.lower().str());
00316                 }
00317         };
00318 
00319         struct hash_cs
00320         {
00321                 inline size_t operator()(const string &s) const
00322                 {
00323                         return std::tr1::hash<std::string>()(s.str());
00324                 }
00325         };
00326 
00327         struct compare
00328         {
00329                 inline bool operator()(const string &s1, const string &s2) const
00330                 {
00331                         return s1.equals_ci(s2);
00332                 }
00333         };
00334 
00335         template<typename T> class map : public std::map<string, T, ci::less> { };
00336         template<typename T> class hash_map : public std::tr1::unordered_map<string, T, hash_ci, compare> { };
00337 
00338         static const char *const compiled = __TIME__ " " __DATE__;
00339 
00342         extern CoreExport time_t StartTime;
00343 
00346         extern int ReturnValue;
00347 
00348         extern sig_atomic_t Signal;
00349         extern CoreExport bool Quitting;
00350         extern CoreExport bool Restarting;
00351         extern CoreExport Anope::string QuitReason;
00352 
00356         extern CoreExport time_t CurTime;
00357 
00360         extern CoreExport int Debug;
00361 
00364         extern CoreExport bool ReadOnly, NoFork, NoThird, NoExpire, ProtocolDebug;
00365 
00368         extern CoreExport Anope::string ServicesDir;
00369 
00372         extern CoreExport Anope::string ServicesBin;
00373 
00376         extern CoreExport Anope::string ConfigDir;
00377         extern CoreExport Anope::string DataDir;
00378         extern CoreExport Anope::string ModuleDir;
00379         extern CoreExport Anope::string LocaleDir;
00380         extern CoreExport Anope::string LogDir;
00381 
00384         extern CoreExport int CurrentUplink;
00385 
00388         extern CoreExport string Version();
00389         extern CoreExport string VersionShort();
00390         extern CoreExport string VersionBuildString();
00391         extern CoreExport int VersionMajor();
00392         extern CoreExport int VersionMinor();
00393         extern CoreExport int VersionPatch();
00394 
00399         extern bool AtTerm();
00400 
00405         extern void Fork();
00406 
00409         extern void HandleSignal();
00410 
00416         extern void Init(int ac, char **av);
00417 
00420         extern CoreExport void SaveDatabases();
00421 
00428         extern CoreExport bool Match(const string &str, const string &mask, bool case_sensitive = false, bool use_regex = false);
00429 
00434         extern CoreExport string Hex(const string &data);
00435         extern CoreExport string Hex(const char *data, unsigned len);
00436 
00441         extern CoreExport void Unhex(const string &src, string &dest);
00442         extern CoreExport void Unhex(const string &src, char *dest, size_t sz);
00443         
00448         extern CoreExport void B64Encode(const string &src, string &target);
00449         
00454         extern CoreExport void B64Decode(const string &src, string &target);
00455 
00460         extern CoreExport void Encrypt(const Anope::string &src, Anope::string &dest);
00461 
00468         extern CoreExport bool Decrypt(const Anope::string &src, Anope::string &dest);
00469 
00477         extern CoreExport string printf(const char *fmt, ...);
00478 
00482         extern CoreExport int LastErrorCode();
00483 
00487         extern CoreExport const string LastError();
00488 
00491         extern CoreExport bool IsFile(const Anope::string &file);
00492 
00497         extern CoreExport time_t DoTime(const Anope::string &s);
00498 
00504         extern CoreExport Anope::string Duration(time_t seconds, const NickCore *nc = NULL);
00505 
00511         extern CoreExport Anope::string Expires(time_t seconds, const NickCore *nc = NULL);
00512 
00518         extern CoreExport Anope::string strftime(time_t t, const NickCore *nc = NULL, bool short_output = false);
00519 
00524         extern CoreExport Anope::string NormalizeBuffer(const Anope::string &);
00525 
00529         extern void Process(const Anope::string &);
00530 
00536         extern Anope::string Resolve(const Anope::string &host, int type);
00537 }
00538 
00544 class CoreExport sepstream
00545 {
00546  private:
00549         Anope::string tokens;
00552         Anope::string::iterator last_starting_position;
00555         Anope::string::iterator n;
00558         char sep;
00559  public:
00562         sepstream(const Anope::string &source, char seperator);
00563 
00568         bool GetToken(Anope::string &token);
00569 
00575         bool GetToken(Anope::string &token, int num);
00576 
00580         template<typename T> void GetTokens(T& token)
00581         {
00582                 token.clear();
00583                 Anope::string t;
00584                 while (this->GetToken(t))
00585                         token.push_back(t);
00586         }
00587 
00593         bool GetTokenRemainder(Anope::string &token, int num);
00594 
00598         int NumTokens();
00599 
00603         const Anope::string GetRemaining();
00604 
00608         bool StreamEnd();
00609 };
00610 
00613 class commasepstream : public sepstream
00614 {
00615  public:
00618         commasepstream(const Anope::string &source) : sepstream(source, ',') { }
00619 };
00620 
00623 class spacesepstream : public sepstream
00624 {
00625  public:
00628         spacesepstream(const Anope::string &source) : sepstream(source, ' ') { }
00629 };
00630 
00637 class CoreException : public std::exception
00638 {
00639  protected:
00642         Anope::string err;
00645         Anope::string source;
00646  public:
00649         CoreException() : err("Core threw an exception"), source("The core") { }
00652         CoreException(const Anope::string &message) : err(message), source("The core") { }
00656         CoreException(const Anope::string &message, const Anope::string &src) : err(message), source(src) { }
00661         virtual ~CoreException() throw() { }
00665         virtual const Anope::string &GetReason() const
00666         {
00667                 return err;
00668         }
00669 
00670         virtual const Anope::string &GetSource() const
00671         {
00672                 return source;
00673         }
00674 };
00675 
00676 class ModuleException : public CoreException
00677 {
00678  public:
00681         ModuleException() : CoreException("Module threw an exception", "A Module") { }
00682 
00685         ModuleException(const Anope::string &message) : CoreException(message, "A Module") { }
00690         virtual ~ModuleException() throw() { }
00691 };
00692 
00693 class ConvertException : public CoreException
00694 {
00695  public:
00696         ConvertException(const Anope::string &reason = "") : CoreException(reason) { }
00697 
00698         virtual ~ConvertException() throw() { }
00699 };
00700 
00703 template<typename T> inline Anope::string stringify(const T &x)
00704 {
00705         std::ostringstream stream;
00706 
00707         if (!(stream << x))
00708                 throw ConvertException("Stringify fail");
00709 
00710         return stream.str();
00711 }
00712 
00713 template<typename T> inline void convert(const Anope::string &s, T &x, Anope::string &leftover, bool failIfLeftoverChars = true)
00714 {
00715         leftover.clear();
00716         std::istringstream i(s.str());
00717         char c;
00718         bool res = i >> x;
00719         if (!res)
00720                 throw ConvertException("Convert fail");
00721         if (failIfLeftoverChars)
00722         {
00723                 if (i.get(c))
00724                         throw ConvertException("Convert fail");
00725         }
00726         else
00727         {
00728                 std::string left;
00729                 getline(i, left);
00730                 leftover = left;
00731         }
00732 }
00733 
00734 template<typename T> inline void convert(const Anope::string &s, T &x, bool failIfLeftoverChars = true)
00735 {
00736         Anope::string Unused;
00737         convert(s, x, Unused, failIfLeftoverChars);
00738 }
00739 
00740 template<typename T> inline T convertTo(const Anope::string &s, Anope::string &leftover, bool failIfLeftoverChars = true)
00741 {
00742         T x;
00743         convert(s, x, leftover, failIfLeftoverChars);
00744         return x;
00745 }
00746 
00747 template<typename T> inline T convertTo(const Anope::string &s, bool failIfLeftoverChars = true)
00748 {
00749         T x;
00750         convert(s, x, failIfLeftoverChars);
00751         return x;
00752 }
00753 
00758 #ifdef DEBUG_BUILD
00759 # include <typeinfo>
00760 #endif
00761 template<typename T, typename O> inline T anope_dynamic_static_cast(O ptr)
00762 {
00763 #ifdef DEBUG_BUILD
00764         T ret = dynamic_cast<T>(ptr);
00765         if (ptr != NULL && ret == NULL)
00766                 throw CoreException(Anope::string("anope_dynamic_static_cast<") + typeid(T).name() + ">(" + typeid(O).name() + ") fail");
00767         return ret;
00768 #else
00769         return static_cast<T>(ptr);
00770 #endif
00771 }
00772 
00773 #endif // ANOPE_H