]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/json.h
Allow support for multiple dns results per request. This is a significant change...
[user/henk/code/inspircd.git] / src / modules / json.h
1 #ifndef JSON_H
2 #define JSON_H
3
4 #include <string>
5 #include <vector>
6 #include <map>
7 #include <deque>
8 #include <stack>
9
10 #if __GNUC__ >= 3
11 # define maybe_expect(expr,value)       __builtin_expect ((expr),(value))
12 # define is_const(expr)                 __builtin_constant_p ((expr))
13 #else
14 # define maybe_expect(expr,value)       (expr)
15 # define is_const(expr)                 0
16 #endif
17
18 #define expect_false(expr) maybe_expect ((expr) != 0, 0)
19 #define expect_true(expr)  maybe_expect ((expr) != 0, 1)
20
21 #ifdef __GNUC__
22 # define CURFUNC       __PRETTY_FUNCTION__
23 #elif defined(__BORLANDC__)
24 # define CURFUNC       __FUNC__
25 #else
26 # define CURFUNC       __FUNCTION__
27 #endif
28
29 namespace json
30 {
31   class ValueIterator;
32   class ValueConstIterator;
33
34   enum ValueType
35     {
36       nullValue = 0,
37       intValue,
38       uintValue,
39       realValue,
40       stringValue,
41       booleanValue,
42       arrayValue,
43       objectValue
44     };
45
46   class StaticString
47   {
48   public:
49     explicit StaticString (char const *czstring)
50       : str_ (czstring)
51     {
52     }
53
54     operator char const *() const
55     {
56       return str_;
57     }
58
59     char const *c_str() const
60     {
61       return str_;
62     }
63
64   private:
65     char const *str_;
66   };
67
68   class Value 
69   {
70     friend class ValueIteratorBase;
71   public:
72     typedef std::vector<std::string> Members;
73     typedef ValueIterator iterator;
74     typedef ValueConstIterator const_iterator;
75     typedef unsigned ArrayIndex;
76
77     static const Value null;
78     static const int minInt;
79     static const int maxInt;
80     static const unsigned maxUInt;
81
82   private:
83     class CZString 
84     {
85     public:
86       enum DuplicationPolicy 
87         {
88           noDuplication = 0,
89           duplicate,
90           duplicateOnCopy
91         };
92       CZString (int index);
93       CZString (char const *cstr, DuplicationPolicy allocate);
94       CZString (const CZString &other);
95       ~CZString ();
96       CZString &operator = (const CZString &other);
97       bool operator < (const CZString &other) const;
98       bool operator == (const CZString &other) const;
99       int index () const;
100       char const *c_str () const;
101       bool isStaticString () const;
102     private:
103       void swap (CZString &other);
104       char const *cstr_;
105       int index_;
106     };
107
108   public:
109     typedef std::map<CZString, Value> ObjectValues;
110
111   public:
112     Value (ValueType type = nullValue);
113     Value (int value);
114     Value (unsigned value);
115     Value (double value);
116     Value (char const *value);
117     Value (const StaticString &value);
118     Value (const std::string &value);
119     Value (bool value);
120     Value (const Value &other);
121     ~Value ();
122
123     Value &operator = (const Value &other);
124
125     void swap (Value &other);
126
127     ValueType type () const;
128
129     bool operator < (const Value &other) const;
130     bool operator <= (const Value &other) const;
131     bool operator >= (const Value &other) const;
132     bool operator > (const Value &other) const;
133
134     bool operator == (const Value &other) const;
135     bool operator != (const Value &other) const;
136
137     operator char const * () const;
138     operator std::string () const;
139     operator int () const;
140     operator unsigned () const;
141     operator double () const;
142     operator bool () const;
143
144     bool isNull () const;
145     bool isBool () const;
146     bool isInt () const;
147     bool isUInt () const;
148     bool isIntegral () const;
149     bool isDouble () const;
150     bool isNumeric () const;
151     bool isString () const;
152     bool isArray () const;
153     bool isObject () const;
154
155     bool isConvertibleTo (ValueType other) const;
156
157     unsigned size () const;
158
159     bool empty () const;
160
161     bool operator ! () const;
162
163     void clear ();
164
165     void resize (unsigned size);
166
167     Value &operator [] (int index);
168     Value &operator [] (unsigned index);
169     const Value &operator [] (int index) const;
170     const Value &operator [] (unsigned index) const;
171     Value get (int index, const Value &defaultValue) const;
172     Value get (unsigned index, const Value &defaultValue) const;
173     bool isValidIndex (int index) const;
174     bool isValidIndex (unsigned index) const;
175
176     Value &append (const Value &value);
177
178     Value &operator [] (char const *key);
179     const Value &operator [] (char const *key) const;
180     Value &operator [] (const std::string &key);
181     const Value &operator [] (const std::string &key) const;
182     Value &operator [] (const StaticString &key);
183     Value get (char const *key, const Value &defaultValue) const;
184     Value get (const std::string &key, const Value &defaultValue) const;
185     Value removeMember (char const* key);
186     Value removeMember (const std::string &key);
187
188     bool isMember (char const *key) const;
189     bool isMember (const std::string &key) const;
190
191     Members getMemberNames () const;
192
193     const_iterator begin () const;
194     const_iterator end () const;
195
196     iterator begin ();
197     iterator end ();
198
199   private:
200     Value &resolveReference (char const *key, bool isStatic);
201
202     struct MemberNamesTransform
203     {
204       typedef char const *result_type;
205       char const *operator () (const CZString &name) const
206       {
207         return name.c_str ();
208       }
209     };
210
211     union ValueHolder
212     {
213       int               int_;
214       unsigned          uint_;
215       double            real_;
216       bool              bool_;
217       char              *string_;
218       ObjectValues      *map_;
219     } value_;
220
221     ValueType   type_      : 8;
222     int         allocated_ : 1;
223   };
224
225
226   class ValueAllocator
227   {
228   public:
229     enum { unknown = (unsigned)-1 };
230
231     virtual ~ValueAllocator ();
232
233     virtual char *makeMemberName (char const *memberName) = 0;
234     virtual void releaseMemberName (char *memberName) = 0;
235     virtual char *duplicateStringValue (char const *value, 
236                                         unsigned length = unknown) = 0;
237     virtual void releaseStringValue (char *value) = 0;
238   };
239
240   class ValueIteratorBase
241   {
242   public:
243     typedef unsigned size_t;
244     typedef int difference_type;
245     typedef ValueIteratorBase SelfType;
246
247     ValueIteratorBase ();
248     explicit ValueIteratorBase (const Value::ObjectValues::iterator &current);
249
250     bool operator == (const SelfType &other) const
251     {
252       return isEqual (other);
253     }
254
255     bool operator != (const SelfType &other) const
256     {
257       return !isEqual (other);
258     }
259
260     difference_type operator - (const SelfType &other) const
261     {
262       return computeDistance (other);
263     }
264
265     Value key () const;
266
267     unsigned index () const;
268
269     char const *memberName () const;
270
271   protected:
272     Value &deref () const;
273
274     void increment ();
275
276     void decrement ();
277
278     difference_type computeDistance (const SelfType &other) const;
279
280     bool isEqual (const SelfType &other) const;
281
282     void copy (const SelfType &other);
283
284   private:
285     Value::ObjectValues::iterator current_;
286   };
287
288   class ValueConstIterator : public ValueIteratorBase
289   {
290     friend class Value;
291   public:
292     typedef unsigned size_t;
293     typedef int difference_type;
294     typedef const Value &reference;
295     typedef const Value *pointer;
296     typedef ValueConstIterator SelfType;
297
298     ValueConstIterator ();
299   private:
300     explicit ValueConstIterator (const Value::ObjectValues::iterator &current);
301   public:
302     SelfType &operator = (const ValueIteratorBase &other);
303
304     SelfType operator ++ (int)
305     {
306       SelfType temp (*this);
307       ++*this;
308       return temp;
309     }
310
311     SelfType operator -- (int)
312     {
313       SelfType temp (*this);
314       --*this;
315       return temp;
316     }
317
318     SelfType &operator -- ()
319     {
320       decrement ();
321       return *this;
322     }
323
324     SelfType &operator ++ ()
325     {
326       increment ();
327       return *this;
328     }
329
330     reference operator * () const
331     {
332       return deref ();
333     }
334   };
335
336
337   class ValueIterator : public ValueIteratorBase
338   {
339     friend class Value;
340   public:
341     typedef unsigned size_t;
342     typedef int difference_type;
343     typedef Value &reference;
344     typedef Value *pointer;
345     typedef ValueIterator SelfType;
346
347     ValueIterator ();
348     ValueIterator (const ValueConstIterator &other);
349     ValueIterator (const ValueIterator &other);
350
351   private:
352     explicit ValueIterator (const Value::ObjectValues::iterator &current);
353
354   public:
355
356     SelfType &operator = (const SelfType &other);
357
358     SelfType operator ++ (int)
359     {
360       SelfType temp (*this);
361       ++*this;
362       return temp;
363     }
364
365     SelfType operator -- (int)
366     {
367       SelfType temp (*this);
368       --*this;
369       return temp;
370     }
371
372     SelfType &operator -- ()
373     {
374       decrement ();
375       return *this;
376     }
377
378     SelfType &operator ++ ()
379     {
380       increment ();
381       return *this;
382     }
383
384     reference operator * () const
385     {
386       return deref ();
387     }
388   };
389 } // namespace json
390
391 namespace json
392 {
393   class Value;
394
395   class Reader
396   {
397   public:
398     typedef char const *Location;
399
400     Reader ();
401
402     bool parse (const std::string &document, Value &root);
403     bool parse (char const *beginDoc, char const *endDOc, Value &root);
404     bool parse (std::istream &, Value &root);
405
406     std::string error_msgs () const;
407
408   private:
409     enum TokenType
410       {
411         tokenEndOfStream = 0,
412         tokenObjectBegin,
413         tokenObjectEnd,
414         tokenArrayBegin,
415         tokenArrayEnd,
416         tokenString,
417         tokenNumber,
418         tokenTrue,
419         tokenFalse,
420         tokenNull,
421         tokenArraySeparator,
422         tokenMemberSeparator,
423         tokenComment,
424         tokenError
425       };
426
427     class Token
428     {
429     public:
430       TokenType type_;
431       Location start_;
432       Location end_;
433     };
434
435     class ErrorInfo
436     {
437     public:
438       Token token_;
439       std::string message_;
440       Location extra_;
441     };
442
443     typedef std::deque<ErrorInfo> Errors;
444
445     bool expectToken (TokenType type, Token &token, char const *message);
446     bool readToken (Token &token);
447     void skipSpaces ();
448     bool match (Location pattern, 
449                 int patternLength);
450     bool readString ();
451     void readNumber ();
452     bool readValue ();
453     bool readObject ();
454     bool readArray ();
455     bool decodeNumber (Token &token);
456     bool decodeString (Token &token);
457     bool decodeString (Token &token, std::string &decoded);
458     bool decodeDouble (Token &token);
459     bool decodeUnicodeEscapeSequence (Token &token, 
460                                       Location &current, 
461                                       Location end, 
462                                       unsigned &unicode);
463     bool addError (const std::string &message, 
464                    Token &token,
465                    Location extra = 0);
466     bool recoverFromError (TokenType skipUntilToken);
467     bool addErrorAndRecover (const std::string &message, 
468                              Token &token,
469                              TokenType skipUntilToken);
470     void skipUntilSpace ();
471     Value &currentValue ();
472     char getNextChar ();
473     void getLocationLineAndColumn (Location location,
474                                    int &line,
475                                    int &column) const;
476     std::string getLocationLineAndColumn (Location location) const;
477    
478     typedef std::stack<Value *> Nodes;
479     Nodes nodes_;
480     Errors errors_;
481     std::string document_;
482     Location begin_;
483     Location end_;
484     Location current_;
485     Location lastValueEnd_;
486     Value *lastValue_;
487   };
488
489   std::istream& operator >> (std::istream&, Value&);
490
491 } // namespace json
492
493 namespace json
494 {
495   class Value;
496
497   class Writer
498   {
499   public:
500     Writer () { }
501     ~Writer () { }
502
503   public:
504     std::string write (const Value &root);
505
506   private:
507     void writeValue (const Value &value);
508
509     std::string document_;
510   };
511
512   std::string valueToString (int value);
513   std::string valueToString (unsigned value);
514   std::string valueToString (double value);
515   std::string valueToString (bool value);
516   std::string valueToQuotedString (char const *value);
517 } // namespace json
518
519 /*
520  * JSON-RPC implementation in C++
521  */
522
523 namespace json
524 {
525   namespace rpc
526   {
527     typedef void (Module::*method) (HTTPRequest *http, Value &request, Value &response);
528
529     struct mfp
530     {
531       Module const *mod;
532       method mth;
533     };
534
535     typedef std::map<std::string, mfp> method_map;
536     extern method_map methods;
537   
538     void add_method (char *name, Module const *mod, method mth);
539     void service (HTTPRequest *http, Value &request, Value &response);
540     void process (HTTPRequest *http, std::string &response, char const *request);
541   }
542 }
543
544 #endif // JSON_H