00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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