]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/base.h
Remove an unneeded forward declaration and typedef
[user/henk/code/inspircd.git] / include / base.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #ifndef __BASE_H__ 
15 #define __BASE_H__ 
16
17 #include "inspircd_config.h"
18 #include <time.h>
19 #include <map>
20 #include <deque>
21 #include <string>
22
23 /** A private data store for an Extensible class */
24 typedef std::map<std::string,char*> ExtensibleStore;
25
26 /** The base class for all inspircd classes.
27  * Wherever possible, all classes you create should inherit from this,
28  * giving them the ability to be passed to various core functions
29  * as 'anonymous' classes.
30 */ 
31 class CoreExport classbase
32 {
33  public:
34         /** Time that the object was instantiated (used for TS calculation etc)
35         */
36         time_t age;
37
38         /** Constructor.
39          * Sets the object's time
40          */
41         classbase();
42
43         /** Destructor.
44          * Does sweet FA.
45          */
46         virtual ~classbase() { }
47 };
48
49 /** class Extensible is the parent class of many classes such as User and Channel.
50  * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
51  * a map associated with the object. In this way modules can store their own custom information within user
52  * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
53  * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
54  * supports arbitary data storage).
55  */
56 class CoreExport Extensible : public classbase
57 {
58         /** Private data store.
59          * Holds all extensible metadata for the class.
60          */
61         ExtensibleStore Extension_Items;
62         
63 public:
64
65         /** Extend an Extensible class.
66          *
67          * @param key The key parameter is an arbitary string which identifies the extension data
68          * @param p This parameter is a pointer to any data you wish to associate with the object
69          *
70          * You must provide a key to store the data as via the parameter 'key' and store the data
71          * in the templated parameter 'p'.
72          * The data will be inserted into the map. If the data already exists, you may not insert it
73          * twice, Extensible::Extend will return false in this case.
74          *
75          * @return Returns true on success, false if otherwise
76          */
77         template<typename T> bool Extend(const std::string &key, T* p)
78         {
79                 /* This will only add an item if it doesnt already exist,
80                  * the return value is a std::pair of an iterator to the
81                  * element, and a bool saying if it was actually inserted.
82                  */
83                 return this->Extension_Items.insert(std::make_pair(key, (char*)p)).second;
84         }
85
86         /** Extend an Extensible class.
87          *
88          * @param key The key parameter is an arbitary string which identifies the extension data
89          *
90          * You must provide a key to store the data as via the parameter 'key', this single-parameter
91          * version takes no 'data' parameter, this is used purely for boolean values.
92          * The key will be inserted into the map with a NULL 'data' pointer. If the key already exists
93          * then you may not insert it twice, Extensible::Extend will return false in this case.
94          *
95          * @return Returns true on success, false if otherwise
96          */
97         bool Extend(const std::string &key)
98         {
99                 /* This will only add an item if it doesnt already exist,
100                  * the return value is a std::pair of an iterator to the
101                  * element, and a bool saying if it was actually inserted.
102                  */
103                 return this->Extension_Items.insert(std::make_pair(key, (char*)NULL)).second;
104         }
105
106         /** Shrink an Extensible class.
107          *
108          * @param key The key parameter is an arbitary string which identifies the extension data
109          *
110          * You must provide a key name. The given key name will be removed from the classes data. If
111          * you provide a nonexistent key (case is important) then the function will return false.
112          * @return Returns true on success.
113          */
114         bool Shrink(const std::string &key);
115         
116         /** Get an extension item.
117          *
118          * @param key The key parameter is an arbitary string which identifies the extension data
119          * @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter.
120          * @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
121          */
122         template<typename T> bool GetExt(const std::string &key, T* &p)
123         {
124                 ExtensibleStore::iterator iter = this->Extension_Items.find(key); /* Find the item */
125                 if(iter != this->Extension_Items.end())
126                 {
127                         p = (T*)iter->second;   /* Item found */
128                         return true;
129                 }
130                 else
131                 {
132                         p = NULL;               /* Item not found */
133                         return false;
134                 }
135         }
136         
137         /** Get an extension item.
138          *
139          * @param key The key parameter is an arbitary string which identifies the extension data
140          * @return Returns true if the item was found and false if it was not.
141          * 
142          * This single-parameter version only checks if the key exists, it does nothing with
143          * the 'data' field and is probably only useful in conjunction with the single-parameter
144          * version of Extend().
145          */
146         bool GetExt(const std::string &key)
147         {
148                 return (this->Extension_Items.find(key) != this->Extension_Items.end());
149         }
150
151         /** Get a list of all extension items names.
152          * @param list A deque of strings to receive the list
153          * @return This function writes a list of all extension items stored in this object by name into the given deque and returns void.
154          */
155         void GetExtList(std::deque<std::string> &list);
156 };
157
158 /** BoolSet is a utility class designed to hold eight bools in a bitmask.
159  * Use BoolSet::Set and BoolSet::Get to set and get bools in the bitmask,
160  * and Unset and Invert for special operations upon them.
161  */
162 class CoreExport BoolSet : public classbase
163 {
164         /** Actual bit values */
165         char bits;
166
167  public:
168
169         /** The default constructor initializes the BoolSet to all values unset.
170          */
171         BoolSet();
172
173         /** This constructor copies the default bitmask from a char
174          */
175         BoolSet(char bitmask);
176
177         /** The Set method sets one bool in the set.
178          *
179          * @param number The number of the item to set. This must be between 0 and 7.
180          */
181         void Set(int number);
182
183         /** The Get method returns the value of one bool in the set
184          *
185          * @param number The number of the item to retrieve. This must be between 0 and 7.
186          *
187          * @return True if the item is set, false if it is unset.
188          */
189         bool Get(int number);
190
191         /** The Unset method unsets one value in the set
192          *
193          * @param number The number of the item to set. This must be between 0 and 7.
194          */
195         void Unset(int number);
196
197         /** The Unset method inverts (flips) one value in the set
198          *
199          * @param number The number of the item to invert. This must be between 0 and 7.
200          */
201         void Invert(int number);
202
203         /** Compare two BoolSets
204          */
205         bool operator==(BoolSet other);
206
207         /** OR two BoolSets together
208          */
209         BoolSet operator|(BoolSet other);
210         
211         /** AND two BoolSets together
212          */
213         BoolSet operator&(BoolSet other);
214
215         /** Assign one BoolSet to another
216          */
217         bool operator=(BoolSet other);
218 };
219
220 /** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
221  * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or
222  * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not
223  * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user
224  * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time.
225  */
226 class CoreExport CoreException : public std::exception
227 {
228  protected:
229         /** Holds the error message to be displayed
230          */
231         const std::string err;
232         /** Source of the exception
233          */
234         const std::string source;
235  public:
236         /** Default constructor, just uses the error mesage 'Core threw an exception'.
237          */
238         CoreException() : err("Core threw an exception"), source("The core") {}
239         /** This constructor can be used to specify an error message before throwing.
240          */
241         CoreException(const std::string &message) : err(message), source("The core") {}
242         /** This constructor can be used to specify an error message before throwing,
243          * and to specify the source of the exception.
244          */
245         CoreException(const std::string &message, const std::string &src) : err(message), source(src) {}
246         /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
247          * Actually no, it does nothing. Never mind.
248          * @throws Nothing!
249          */
250         virtual ~CoreException() throw() {};
251         /** Returns the reason for the exception.
252          * The module should probably put something informative here as the user will see this upon failure.
253          */
254         virtual const char* GetReason()
255         {
256                 return err.c_str();
257         }
258
259         virtual const char* GetSource()
260         {
261                 return source.c_str();
262         }
263 };
264
265 class CoreExport ModuleException : public CoreException
266 {
267  public:
268         /** Default constructor, just uses the error mesage 'Module threw an exception'.
269          */
270         ModuleException() : CoreException("Module threw an exception", "A Module") {}
271
272         /** This constructor can be used to specify an error message before throwing.
273          */
274         ModuleException(const std::string &message) : CoreException(message, "A Module") {}
275         /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
276          * Actually no, it does nothing. Never mind.
277          * @throws Nothing!
278          */
279         virtual ~ModuleException() throw() {};
280 };
281
282 #endif