]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/rpc.h
75a7efd62077a0a3bf92dc5d3f9eb04922a07b78
[user/henk/code/inspircd.git] / src / modules / rpc.h
1 #ifndef RPC_H
2 #define RPC_H
3
4 #include <string>
5 #include <map>
6 #include <stdexcept>
7
8 class RPCValue;
9
10 typedef enum
11 {
12         RPCNull,
13         RPCBoolean,
14         RPCInteger,
15         RPCString,
16         RPCArray,
17         RPCObject
18 } RPCValueType;
19
20 typedef std::map<std::string,RPCValue*> RPCObjectContainer;
21 typedef std::vector<RPCValue*> RPCArrayContainer;
22
23 class RPCValue : public classbase
24 {
25  protected:
26         RPCValueType type;
27         void *value;
28         
29         double *CastInteger()
30         {
31                 return (double*)value;
32         }
33         
34         std::string *CastString()
35         {
36                 return (std::string*)value;
37         }
38         
39         RPCObjectContainer *CastObject()
40         {
41                 return (RPCObjectContainer*)value;
42         }
43         
44         RPCArrayContainer *CastArray()
45         {
46                 return (RPCArrayContainer*)value;
47         }
48         
49         void DestroyValue()
50         {
51                 // Some versions of GCC complain about declaration in switch statements
52                 RPCArrayContainer *a;
53                 RPCObjectContainer *o;
54                 switch (type)
55                 {
56                         case RPCInteger:
57                                 delete this->CastInteger();
58                                 break;
59                         case RPCString:
60                                 delete this->CastString();
61                                 break;
62                         case RPCArray:
63                                 a = this->CastArray();
64                                 for (RPCArrayContainer::iterator i = a->begin(); i != a->end(); i++)
65                                         delete *i;
66                                 delete a;
67                                 break;
68                         case RPCObject:
69                                 o = this->CastObject();
70                                 for (RPCObjectContainer::iterator i = o->begin(); i != o->end(); i++)
71                                         delete i->second;
72                                 delete o;
73                                 break;
74                         default:
75                                 break;
76                 }
77                 
78                 value = NULL;
79         }
80         
81         void InitValue()
82         {
83                 switch (type)
84                 {
85                         case RPCNull:
86                         case RPCBoolean:
87                                 value = NULL;
88                                 break;
89                         case RPCInteger:
90                                 value = new double;
91                                 break;
92                         case RPCString:
93                                 value = new std::string;
94                                 break;
95                         case RPCArray:
96                                 value = new RPCArrayContainer;
97                                 break;
98                         case RPCObject:
99                                 value = new RPCObjectContainer;
100                                 break;
101                 }
102         }
103         
104         RPCValue(const RPCValue &v) { }
105         
106  public:
107         RPCValue *parent;
108
109         RPCValue(RPCValue *rparent = NULL) : type(RPCNull), value(NULL), parent(rparent) { }
110         RPCValue(RPCValueType ttype, RPCValue *rparent = NULL) : type(ttype), value(NULL), parent(rparent) { InitValue(); }
111         RPCValue(bool nvalue, RPCValue *rparent = NULL) : type(RPCBoolean), value((void*)nvalue), parent(rparent) { }
112         RPCValue(double nvalue, RPCValue *rparent = NULL) : type(RPCInteger), parent(rparent) { value = new double(nvalue); }
113         RPCValue(const std::string &nvalue, RPCValue *rparent = NULL) : type(RPCString), parent(rparent) { value = new std::string(nvalue); }
114         
115         virtual ~RPCValue()
116         {
117                 DestroyValue();
118         }
119         
120         RPCValueType GetType()
121         {
122                 return type;
123         }
124         
125         void SetNull()
126         {
127                 DestroyValue();
128                 type = RPCNull;
129         }
130         
131         void SetBoolean(bool nvalue)
132         {
133                 DestroyValue();
134                 value = (void*)nvalue;
135                 type = RPCBoolean;
136         }
137         
138         void SetInteger(double nvalue)
139         {
140                 if (type == RPCInteger)
141                 {
142                         *this->CastInteger() = nvalue;
143                 }
144                 else
145                 {
146                         DestroyValue();
147                         value = new double(nvalue);
148                         type = RPCInteger;
149                 }
150         }
151         
152         void SetString(const std::string &nvalue)
153         {
154                 if (type == RPCString)
155                 {
156                         this->CastString()->assign(nvalue);
157                 }
158                 else
159                 {
160                         DestroyValue();
161                         value = new std::string(nvalue);
162                         type = RPCString;
163                 }
164         }
165         
166         void SetArray()
167         {
168                 if (type == RPCArray)
169                 {
170                         this->CastArray()->clear();
171                 }
172                 else
173                 {
174                         DestroyValue();
175                         type = RPCArray;
176                         InitValue();
177                 }
178         }
179         
180         void SetObject()
181         {
182                 if (type == RPCObject)
183                 {
184                         this->CastObject()->clear();
185                 }
186                 else
187                 {
188                         DestroyValue();
189                         type = RPCObject;
190                         InitValue();
191                 }
192         }
193         
194         void ArrayAdd(RPCValue *nvalue)
195         {
196                 if (type != RPCArray)
197                         return;
198                 RPCArrayContainer *a = this->CastArray();
199                 a->push_back(nvalue);
200                 nvalue->parent = this;
201         }
202         
203         void ObjectAdd(const std::string &key, RPCValue *nvalue)
204         {
205                 if (type != RPCObject)
206                         return;
207                 RPCObjectContainer *o = this->CastObject();
208                 o->insert(std::make_pair(key, nvalue));
209                 nvalue->parent = this;
210         }
211         
212         RPCValue *GetArray(int i)
213         {
214                 if (type != RPCArray)
215                         return NULL;
216                 RPCArrayContainer *a = this->CastArray();
217                 if ((i < 0) || (i >= (signed)a->size()))
218                         return NULL;
219                 return a->at(i);
220         }
221         
222         int ArraySize()
223         {
224                 if (type != RPCArray)
225                         return 0;
226                 RPCArrayContainer *a = this->CastArray();
227                 return a->size();
228         }
229         
230         RPCValue *GetObject(const std::string &key)
231         {
232                 if (type != RPCObject)
233                         return NULL;
234                 RPCObjectContainer *o = this->CastObject();
235                 RPCObjectContainer::iterator it = o->find(key);
236                 if (it == o->end())
237                         return NULL;
238                 return it->second;
239         }
240         
241         std::pair<RPCObjectContainer::iterator,RPCObjectContainer::iterator> GetObjectIterator()
242         {
243                 if (type != RPCObject)
244                         throw std::runtime_error("Cannot get iterator for a non-object RPC value");
245                 RPCObjectContainer *o = this->CastObject();
246                 return std::make_pair(o->begin(), o->end());
247         }
248         
249         std::string GetString()
250         {
251                 if (type != RPCString)
252                         return std::string();
253                 return *this->CastString();
254         }
255         
256         double GetInt()
257         {
258                 if (type != RPCInteger)
259                         return 0;
260                 return *this->CastInteger();
261         }
262         
263         bool GetBool()
264         {
265                 if (type != RPCBoolean)
266                         return 0;
267                 return (value != NULL);
268         }
269 };
270
271 class RPCRequest : public classbase
272 {
273  protected:
274         
275  public:
276         std::string method;
277         RPCValue *parameters;
278         RPCValue *result;
279         std::string provider;
280         bool claimed;
281         std::string error;
282         
283         RPCRequest(const std::string &sprovider, const std::string &smethod, RPCValue *rparameters)
284                 : method(smethod), parameters(rparameters), provider(sprovider), claimed(false)
285         {
286                 result = new RPCValue();
287         }
288         
289         ~RPCRequest()
290         {
291                 if (result)
292                         delete result;
293         }
294 };
295
296 #endif