summaryrefslogtreecommitdiff
path: root/include/anope.h
diff options
context:
space:
mode:
authorNaram Qashat <cyberbotx@cyberbotx.com>2010-07-25 21:58:20 -0400
committerNaram Qashat <cyberbotx@cyberbotx.com>2010-07-25 21:58:20 -0400
commitae38212c1ce829c783edf971081c90137abb49a0 (patch)
tree5c652d9cdc38103dec6fa112d57fca882b4e3e44 /include/anope.h
parent15d7f0f6fe8bb903275f603f734c13f65f3aa906 (diff)
Epic commit to replace most of the strings in Anope with a single Anope::string class, plus some other little fixes here and there. If you follow 1.9.x development and are testing things, THIS is one of those things that NEEDS testing.
Diffstat (limited to 'include/anope.h')
-rw-r--r--include/anope.h363
1 files changed, 363 insertions, 0 deletions
diff --git a/include/anope.h b/include/anope.h
new file mode 100644
index 000000000..e73f04157
--- /dev/null
+++ b/include/anope.h
@@ -0,0 +1,363 @@
+/*
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for furhter details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ */
+
+#ifndef ANOPE_H
+#define ANOPE_H
+
+#include <string>
+#include <vector>
+#include "hashcomp.h"
+
+struct Message;
+
+namespace Anope
+{
+ /**
+ * A wrapper string class around all the other string classes, this class will
+ * allow us to only require one type of string everywhere that can be converted
+ * at any time to a specific type of string.
+ */
+ class string
+ {
+ private:
+ /**
+ * The actual string is stored in an std::string as it can be converted to
+ * ci::string, irc::string, or a C-style string at any time.
+ */
+ std::string _string;
+ public:
+ /**
+ * Extras.
+ */
+ typedef std::string::iterator iterator;
+ typedef std::string::const_iterator const_iterator;
+ typedef std::string::reverse_iterator reverse_iterator;
+ typedef std::string::const_reverse_iterator const_reverse_iterator;
+ typedef std::string::size_type size_type;
+ static const size_type npos = static_cast<size_type>(-1);
+
+ /**
+ * Constructors that can take in any type of string.
+ */
+ string() : _string("") { }
+ string(char chr) : _string() { _string = chr; }
+ string(size_type n, char chr) : _string(n, chr) { }
+ string(const char *_str) : _string(_str) { }
+ string(const std::string &_str) : _string(_str) { }
+ string(const ci::string &_str) : _string(_str.c_str()) { }
+ string(const irc::string &_str) : _string(_str.c_str()) { }
+ string(const string &_str, size_type pos = 0, size_type n = npos) : _string(_str._string, pos, n) { }
+ template <class InputIterator> string(InputIterator first, InputIterator last) : _string(first, last) { }
+
+ /**
+ * Assignment operators, so any type of string can be assigned to this class.
+ */
+ inline string &operator=(char chr) { this->_string = chr; return *this; }
+ inline string &operator=(const char *_str) { this->_string = _str; return *this; }
+ inline string &operator=(const std::string &_str) { this->_string = _str; return *this; }
+ inline string &operator=(const ci::string &_str) { this->_string = _str.c_str(); return *this; }
+ inline string &operator=(const irc::string &_str) { this->_string = _str.c_str(); return *this; }
+ inline string &operator=(const string &_str) { if (this != &_str) this->_string = _str._string; return *this; }
+
+ /**
+ * Equality operators, to compare to any type of string.
+ */
+ inline bool operator==(const char *_str) const { return this->_string == _str; }
+ inline bool operator==(const std::string &_str) const { return this->_string == _str; }
+ inline bool operator==(const ci::string &_str) const { return ci::string(this->_string.c_str()) == _str; }
+ inline bool operator==(const irc::string &_str) const { return irc::string(this->_string.c_str()) == _str; }
+ inline bool operator==(const string &_str) const { return this->_string == _str._string; }
+
+ inline bool equals_cs(const char *_str) const { return this->_string == _str; }
+ inline bool equals_cs(const std::string &_str) const { return this->_string == _str; }
+ inline bool equals_cs(const ci::string &_str) const { return this->_string == _str.c_str(); }
+ inline bool equals_cs(const irc::string &_str) const { return this->_string == _str.c_str(); }
+ inline bool equals_cs(const string &_str) const { return this->_string == _str._string; }
+
+ inline bool equals_ci(const char *_str) const { return ci::string(this->_string.c_str()) == _str; }
+ inline bool equals_ci(const std::string &_str) const { return ci::string(this->_string.c_str()) == _str.c_str(); }
+ inline bool equals_ci(const ci::string &_str) const { return _str == this->_string.c_str(); }
+ inline bool equals_ci(const irc::string &_str) const { return ci::string(this->_string.c_str()) == _str.c_str(); }
+ inline bool equals_ci(const string &_str) const { return ci::string(this->_string.c_str()) == _str._string.c_str(); }
+
+ inline bool equals_irc(const char *_str) const { return irc::string(this->_string.c_str()) == _str; }
+ inline bool equals_irc(const std::string &_str) const { return irc::string(this->_string.c_str()) == _str.c_str(); }
+ inline bool equals_irc(const ci::string &_str) const { return irc::string(this->_string.c_str()) == _str.c_str(); }
+ inline bool equals_irc(const irc::string &_str) const { return _str == this->_string.c_str(); }
+ inline bool equals_irc(const string &_str) const { return irc::string(this->_string.c_str()) == _str._string.c_str(); }
+
+ /**
+ * Inequality operators, exact opposites of the above.
+ */
+ inline bool operator!=(const char *_str) const { return !operator==(_str); }
+ inline bool operator!=(const std::string &_str) const { return !operator==(_str); }
+ inline bool operator!=(const ci::string &_str) const { return !operator==(_str); }
+ inline bool operator!=(const irc::string &_str) const { return !operator==(_str); }
+ inline bool operator!=(const string &_str) const { return !operator==(_str); }
+
+ /**
+ * Compound addition operators, overloaded to do concatenation.
+ */
+ inline string &operator+=(char chr) { this->_string += chr; return *this; }
+ inline string &operator+=(const char *_str) { this->_string += _str; return *this; }
+ inline string &operator+=(const std::string &_str) { this->_string += _str; return *this; }
+ inline string &operator+=(const ci::string &_str) { this->_string += _str.c_str(); return *this; }
+ inline string &operator+=(const irc::string &_str) { this->_string += _str.c_str(); return *this; }
+ inline string &operator+=(const string &_str) { if (this != &_str) this->_string += _str._string; return *this; }
+
+ /**
+ * Addition operators, overloaded to do concatenation.
+ */
+ inline const string operator+(char chr) const { return string(*this) += chr; }
+ inline const string operator+(const char *_str) const { return string(*this) += _str; }
+ inline const string operator+(const std::string &_str) const { return string(*this) += _str; }
+ inline const string operator+(const ci::string &_str) const { return string(*this) += _str; }
+ inline const string operator+(const irc::string &_str) const { return string(*this) += _str; }
+ inline const string operator+(const string &_str) const { return string(*this) += _str; }
+
+ friend const string operator+(char chr, const string &str);
+ friend const string operator+(const char *_str, const string &str);
+ friend const string operator+(const std::string &_str, const string &str);
+ friend const string operator+(const ci::string &_str, const string &str);
+ friend const string operator+(const irc::string &_str, const string &str);
+
+ /**
+ * Less-than operator.
+ */
+ inline bool operator<(const string &_str) const { return this->_string < _str._string; }
+
+ /**
+ * The following functions return the various types of strings.
+ */
+ inline const char *c_str() const { return this->_string.c_str(); }
+ inline std::string &str() { return this->_string; }
+ inline const std::string &str() const { return this->_string; }
+ inline ci::string ci_str() const { return ci::string(this->_string.c_str()); }
+ inline irc::string irc_str() const { return irc::string(this->_string.c_str()); }
+
+ /**
+ * Returns if the string is empty or not.
+ */
+ inline bool empty() const { return this->_string.empty(); }
+
+ /**
+ * Returns the string's length.
+ */
+ inline size_type length() const { return this->_string.length(); }
+
+ /**
+ * Erases characters from the string.
+ */
+ inline iterator erase(const iterator &i) { return this->_string.erase(i); }
+ inline iterator erase(const iterator &first, const iterator &last) { return this->_string.erase(first, last); }
+ inline void erase(size_type pos = 0, size_type n = std::string::npos) { this->_string.erase(pos, n); }
+
+ /**
+ * Clears the string.
+ */
+ inline void clear() { this->_string.clear(); }
+
+ /**
+ * Find substrings of the string.
+ */
+ inline size_type find(const string &_str, size_type pos = 0) const { return this->_string.find(_str._string, pos); }
+ inline size_type find(char chr, size_type pos = 0) const { return this->_string.find(chr, pos); }
+ 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); }
+ inline size_type find_ci(char chr, size_type pos = 0) const { return ci::string(this->_string.c_str()).find(chr, pos); }
+
+ inline size_type rfind(const string &_str, size_type pos = npos) const { return this->_string.rfind(_str._string, pos); }
+ inline size_type rfind(char chr, size_type pos = npos) const { return this->_string.rfind(chr, pos); }
+ 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); }
+ inline size_type rfind_ci(char chr, size_type pos = npos) const { return ci::string(this->_string.c_str()).rfind(chr, pos); }
+
+ inline size_type find_first_of(const string &_str, size_type pos = 0) const { return this->_string.find_first_of(_str._string, pos); }
+ 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); }
+
+ 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); }
+ 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); }
+
+ inline size_type find_last_of(const string &_str, size_type pos = npos) const { return this->_string.find_last_of(_str._string, pos); }
+ 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); }
+
+ 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); }
+ 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); }
+
+ /**
+ * Determine if string consists of only numbers.
+ */
+ inline bool is_number_only() const { return this->find_first_not_of("0123456789.-") == npos; }
+
+ /**
+ * Replace parts of the string.
+ */
+ inline string replace(size_type pos, size_type n, const string &_str) { return string(this->_string.replace(pos, n, _str._string)); }
+ 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)); }
+ inline string replace(size_type pos, size_type n, size_type n1, char chr) { return string(this->_string.replace(pos, n, n1, chr)); }
+ inline string replace(iterator first, iterator last, const string &_str) { return string(this->_string.replace(first, last, _str._string)); }
+ inline string replace(iterator first, iterator last, size_type n, char chr) { return string(this->_string.replace(first, last, n, chr)); }
+ template <class InputIterator> inline string replace(iterator first, iterator last, InputIterator f, InputIterator l) { return string(this->_string.replace(first, last, f, l)); }
+ inline string replace_all_cs(const string &_orig, const string &_repl)
+ {
+ Anope::string new_string = *this;
+ size_type pos = new_string.find(_orig), orig_length = _orig.length();
+ while (pos != npos)
+ {
+ new_string.replace(pos, pos + orig_length, _repl);
+ pos = new_string.find(_orig, pos + orig_length);
+ }
+ return new_string;
+ }
+ inline string replace_all_ci(const string &_orig, const string &_repl)
+ {
+ Anope::string new_string = *this;
+ size_type pos = new_string.find_ci(_orig), orig_length = _orig.length();
+ while (pos != npos)
+ {
+ new_string.replace(pos, pos + orig_length, _repl);
+ pos = new_string.find_ci(_orig, pos + orig_length);
+ }
+ return new_string;
+ }
+
+ /**
+ * Get a substring of the string.
+ */
+ inline string substr(size_type pos = 0, size_type n = npos) const { return string(this->_string.substr(pos, n)); }
+
+ /**
+ * Iterators to the string.
+ */
+ inline iterator begin() { return this->_string.begin(); }
+ inline const_iterator begin() const { return this->_string.begin(); }
+ inline iterator end() { return this->_string.end(); }
+ inline const_iterator end() const { return this->_string.end(); }
+ inline reverse_iterator rbegin() { return this->_string.rbegin(); }
+ inline const_reverse_iterator rbegin() const { return this->_string.rbegin(); }
+ inline reverse_iterator rend() { return this->_string.rend(); }
+ inline const_reverse_iterator rend() const { return this->_string.rend(); }
+
+ /**
+ * Subscript operator, to access individual characters of the string.
+ */
+ inline char &operator[](size_type n) { return this->_string[n]; }
+ inline const char &operator[](size_type n) const { return this->_string[n]; }
+
+ /**
+ * Stream insertion operator, must be friend because they cannot be inside the class.
+ */
+ friend std::ostream &operator<<(std::ostream &os, const string &_str);
+ };
+
+ inline std::ostream &operator<<(std::ostream &os, const string &_str) { return os << _str._string; }
+
+ inline const string operator+(char chr, const string &str) { string tmp(chr); tmp += str; return tmp; }
+ inline const string operator+(const char *_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
+ inline const string operator+(const std::string &_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
+ inline const string operator+(const ci::string &_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
+ inline const string operator+(const irc::string &_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
+
+ static const char *const compiled = __TIME__ " " __DATE__;
+
+ extern string Version();
+
+ extern string Build();
+
+ /** Check whether two strings match.
+ * @param str The string to check against the pattern (e.g. foobar)
+ * @param mask The pattern to check (e.g. foo*bar)
+ * @param case_sensitive Whether or not the match is case sensitive, default false.
+ */
+ extern bool Match(const Anope::string &str, const Anope::string &mask, bool case_sensitive = false);
+
+ /** Add a message to Anope
+ * @param name The message name as sent by the IRCd
+ * @param func A callback function that will be called when this message is received
+ * @return The new message object
+ */
+ extern Message *AddMessage(const string &name, int (*func)(const string &source, int ac, const char **av));
+
+ /** Deletes a message from Anope
+ * XXX Im not sure what will happen if this function is called indirectly from message function pointed to by this message.. must check
+ * @param m The message
+ * @return true if the message was found and deleted, else false
+ */
+ extern bool DelMessage(Message *m);
+
+ /** Returns a list of pointers to message handlers
+ * @param The message name as sent by the IRCd
+ * @return a vector with pointers to the messagehandlers (you can bind more than one handler to a message)
+ */
+ extern std::vector<Message *> FindMessage(const string &name);
+}
+
+/** 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 CoreExport sepstream
+{
+ private:
+ /** Original string.
+ */
+ Anope::string tokens;
+ /** Last position of a seperator token
+ */
+ Anope::string::iterator last_starting_position;
+ /** Current string position
+ */
+ Anope::string::iterator n;
+ /** Seperator value
+ */
+ char sep;
+ public:
+ /** Create a sepstream and fill it with the provided data
+ */
+ sepstream(const Anope::string &source, char seperator);
+ virtual ~sepstream() { }
+
+ /** Fetch the next token from the stream
+ * @param token The next token from the stream is placed here
+ * @return True if tokens still remain, false if there are none left
+ */
+ virtual bool GetToken(Anope::string &token);
+
+ /** Fetch the entire remaining stream, without tokenizing
+ * @return The remaining part of the stream
+ */
+ virtual const Anope::string GetRemaining();
+
+ /** Returns true if the end of the stream has been reached
+ * @return True if the end of the stream has been reached, otherwise false
+ */
+ virtual bool StreamEnd();
+};
+
+/** A derived form of sepstream, which seperates on commas
+ */
+class commasepstream : public sepstream
+{
+ public:
+ /** Initialize with comma seperator
+ */
+ commasepstream(const Anope::string &source) : sepstream(source, ',') { }
+};
+
+/** A derived form of sepstream, which seperates on spaces
+ */
+class spacesepstream : public sepstream
+{
+ public:
+ /** Initialize with space seperator
+ */
+ spacesepstream(const Anope::string &source) : sepstream(source, ' ') { }
+};
+
+#endif // ANOPE_H