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