ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/dclient/include/json/value.h
Revision: 1.1
Committed: Sun Oct 17 08:14:54 2010 UTC (13 years, 8 months ago) by sf-pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
initial import

File Contents

# Content
1 #pragma once
2
3 #include "adt/make.h"
4 #include "forwards.h"
5
6 #include <map>
7 #include <string>
8 #include <vector>
9
10 /** \brief JSON (JavaScript Object Notation).
11 */
12 namespace Json
13 {
14 /** \brief Type of the value held by a Value object.
15 */
16 enum ValueType
17 {
18 nullValue = 0, ///< 'null' value */
19 intValue, ///< signed integer value */
20 uintValue, ///< unsigned integer value */
21 realValue, ///< double value */
22 stringValue, ///< UTF-8 string value */
23 booleanValue, ///< bool value */
24 arrayValue, ///< array value (ordered list) */
25 objectValue ///< object value (collection of name/value pairs). */
26 };
27
28 enum CommentPlacement
29 {
30 commentBefore = 0, ///< a comment placed on the line before a value */
31 commentAfterOnSameLine, ///< a comment just after a value on the same line */
32 commentAfter, ///< a comment on the line after a value (only make sense for root value) */
33 numberOfCommentPlacement
34 };
35
36 /** \brief Lightweight wrapper to tag static string.
37 *
38 * Value constructor and objectValue member assignement takes advantage of the
39 * StaticString and avoid the cost of string duplication when storing the
40 * string or the member name.
41 *
42 * Example of usage:
43 * \code
44 * Json::Value aValue( StaticString("some text") );
45 * Json::Value object;
46 * static const StaticString code("code");
47 * object[code] = 1234;
48 * \endcode
49 */
50 class JSON_API StaticString
51 {
52 public:
53 explicit StaticString (const char *czstring)
54 : str_ (czstring)
55 {
56 }
57
58 const char *c_str () const
59 {
60 return str_;
61 }
62
63 private:
64 const char *str_;
65 };
66
67 /** \brief Represents a <a href="http://www.json.org">JSON</a> value.
68 *
69 * This class is a discriminated union wrapper that can represents a:
70 * - signed integer [range: Value::minInt - Value::maxInt]
71 * - unsigned integer (range: 0 - Value::maxUInt)
72 * - double
73 * - UTF-8 string
74 * - boolean
75 * - 'null'
76 * - an ordered list of Value
77 * - collection of name/value pairs (javascript object)
78 *
79 * The type of the held value is represented by a #ValueType and
80 * can be obtained using type().
81 *
82 * values of an #objectValue or #arrayValue can be accessed using operator[]() methods.
83 * Non const methods will automatically create the a #nullValue element
84 * if it does not exist.
85 * The sequence of an #arrayValue will be automatically resize and initialized
86 * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
87 *
88 * The get() methods can be used to obtanis default value in the case the required element
89 * does not exist.
90 *
91 * It is possible to iterate over the list of a #objectValue values using
92 * the getMemberNames() method.
93 */
94 class JSON_API Value
95 {
96 friend class ValueIteratorBase;
97
98 public:
99 typedef std::vector<std::string> Members;
100 typedef ValueIterator iterator;
101 typedef ValueConstIterator const_iterator;
102 typedef Json::UInt UInt;
103 typedef Json::Int Int;
104 typedef UInt ArrayIndex;
105
106 static const Value null;
107 static const Int minInt;
108 static const Int maxInt;
109 static const UInt maxUInt;
110
111 private:
112 class CZString
113 {
114 public:
115 enum DuplicationPolicy
116 {
117 noDuplication = 0,
118 duplicate,
119 duplicateOnCopy
120 };
121 CZString (int index);
122 CZString (const char *cstr, DuplicationPolicy allocate);
123 CZString (const CZString &other);
124 ~CZString ();
125 CZString &operator = (const CZString &other);
126 bool operator < (const CZString &other) const;
127 bool operator == (const CZString &other) const;
128 int index () const;
129 const char *c_str () const;
130 bool isStaticString () const;
131
132 private:
133 void swap (CZString &other);
134 const char *cstr_;
135 long index_;
136 };
137
138 public:
139 typedef std::map<CZString, Value> ObjectValues;
140
141 public:
142 /** \brief Create a default Value of the given type.
143 *
144 * This is a very useful constructor.
145 * To create an empty array, pass arrayValue.
146 * To create an empty object, pass objectValue.
147 * Another Value can then be set to this one by assignment.
148 * This is useful since clear() and resize() will not alter types.
149 *
150 * Examples:
151 * \code
152 * Json::Value null_value; // null
153 * Json::Value arr_value(Json::arrayValue); // []
154 * Json::Value obj_value(Json::objectValue); // {}
155 * \endcode
156 */
157 Value (ValueType type = nullValue);
158 Value (Int value);
159 Value (UInt value);
160 Value (double value);
161 Value (const char *value);
162 Value (const char *beginValue, const char *endValue);
163 Value (make::array const &value);
164 Value (make::map const &value);
165 /** \brief Constructs a value from a static string.
166 *
167 * Like other value string constructor but do not duplicate the string for
168 * internal storage. The given string must remain alive after the call to this
169 * constructor.
170 * Example of usage:
171 * \code
172 * Json::Value aValue( StaticString("some text") );
173 * \endcode
174 */
175 Value (const StaticString &value);
176 Value (const std::string &value);
177 Value (bool value);
178 Value (const Value &other);
179 ~Value ();
180
181 Value &operator = (const Value &other);
182 /*
183 * / Swap values.
184 * / \note Currently, comments are intentionally not swapped, for
185 * / both logic and efficiency.
186 */
187 void swap (Value &other);
188
189 ValueType type () const;
190
191 bool operator < (const Value &other) const;
192 bool operator <= (const Value &other) const;
193 bool operator >= (const Value &other) const;
194 bool operator > (const Value &other) const;
195
196 bool operator == (const Value &other) const;
197 bool operator != (const Value &other) const;
198
199 int compare (const Value &other);
200
201 const char *asCString () const;
202 std::string asString () const;
203 Int asInt () const;
204 UInt asUInt () const;
205 double asDouble () const;
206 bool asBool () const;
207
208 bool isNull () const;
209 bool isBool () const;
210 bool isInt () const;
211 bool isUInt () const;
212 bool isIntegral () const;
213 bool isDouble () const;
214 bool isNumeric () const;
215 bool isString () const;
216 bool isArray () const;
217 bool isObject () const;
218
219 bool isConvertibleTo (ValueType other) const;
220
221 /* / Number of values in array or object */
222 UInt size () const;
223
224 /*
225 * / \brief Return true if empty array, empty object, or null;
226 * / otherwise, false.
227 */
228 bool empty () const;
229
230 /* / Return isNull() */
231 bool operator ! () const;
232
233 /*
234 * / Remove all object members and array elements.
235 * / \pre type() is arrayValue, objectValue, or nullValue
236 * / \post type() is unchanged
237 */
238 void clear ();
239
240 /*
241 * / Resize the array to size elements.
242 * / New elements are initialized to null.
243 * / May only be called on nullValue or arrayValue.
244 * / \pre type() is arrayValue or nullValue
245 * / \post type() is arrayValue
246 */
247 void resize (UInt size);
248
249 /*
250 * / Access an array element (zero based index ).
251 * / If the array contains less than index element, then null value are inserted
252 * / in the array so that its size is index+1.
253 * / (You may need to say 'value[0u]' to get your compiler to distinguish
254 * / this from the operator[] which takes a string.)
255 */
256 Value &operator [] (UInt index);
257 Value &operator [] (int index) { return (*this)[UInt (index)]; }
258 /*
259 * / Access an array element (zero based index )
260 * / (You may need to say 'value[0u]' to get your compiler to distinguish
261 * / this from the operator[] which takes a string.)
262 */
263 const Value &operator [] (UInt index) const;
264 /*
265 * / If the array contains at least index+1 elements, returns the element value,
266 * / otherwise returns defaultValue.
267 */
268 Value get (UInt index, const Value &defaultValue) const;
269 /* / Return true if index < size(). */
270 bool isValidIndex (UInt index) const;
271 /*
272 * / \brief Append value to array at the end.
273 * /
274 * / Equivalent to jsonvalue[jsonvalue.size()] = value;
275 */
276 Value &append (const Value &value);
277
278 /* / Access an object value by name, create a null member if it does not exist. */
279 Value &operator [] (const char *key);
280 /* / Access an object value by name, returns null if there is no member with that name. */
281 const Value &operator [] (const char *key) const;
282 /* / Access an object value by name, create a null member if it does not exist. */
283 Value &operator [] (const std::string &key);
284 /* / Access an object value by name, returns null if there is no member with that name. */
285 const Value &operator [] (const std::string &key) const;
286 /** \brief Access an object value by name, create a null member if it does not exist.
287 *
288 * If the object as no entry for that name, then the member name used to store
289 * the new entry is not duplicated.
290 * Example of use:
291 * \code
292 * Json::Value object;
293 * static const StaticString code("code");
294 * object[code] = 1234;
295 * \endcode
296 */
297 Value &operator [] (const StaticString &key);
298 /* / Return the member named key if it exist, defaultValue otherwise. */
299 Value get (const char *key, const Value &defaultValue) const;
300 /* / Return the member named key if it exist, defaultValue otherwise. */
301 Value get (const std::string &key, const Value &defaultValue) const;
302 /*
303 * / \brief Remove and return the named member.
304 * /
305 * / Do nothing if it did not exist.
306 * / \return the removed Value, or null.
307 * / \pre type() is objectValue or nullValue
308 * / \post type() is unchanged
309 */
310 Value removeMember (const char *key);
311 /* / Same as removeMember(const char*) */
312 Value removeMember (const std::string &key);
313
314 /* / Return true if the object has a member named key. */
315 bool isMember (const char *key) const;
316 /* / Return true if the object has a member named key. */
317 bool isMember (const std::string &key) const;
318
319 /*
320 * / \brief Return a list of the member names.
321 * /
322 * / If null, return an empty list.
323 * / \pre type() is objectValue or nullValue
324 * / \post if type() was nullValue, it remains nullValue
325 */
326 Members getMemberNames () const;
327
328 /* / Comments must be //... or / * ... * / */
329 void setComment (const char *comment, CommentPlacement placement);
330 /* / Comments must be //... or / * ... * / */
331 void setComment (const std::string &comment, CommentPlacement placement);
332 bool hasComment (CommentPlacement placement) const;
333 /* / Include delimiters and embedded newlines. */
334 std::string getComment (CommentPlacement placement) const;
335
336 std::string toStyledString () const;
337
338 const_iterator begin () const;
339 const_iterator end () const;
340
341 iterator begin ();
342 iterator end ();
343
344 private:
345 Value &resolveReference (const char *key, bool isStatic);
346
347 private:
348 struct CommentInfo
349 {
350 CommentInfo ();
351 ~CommentInfo ();
352
353 void setComment (const char *text);
354
355 char *comment_;
356 };
357
358 /*
359 * struct MemberNamesTransform
360 * {
361 * typedef const char *result_type;
362 * const char *operator()( const CZString &name ) const
363 * {
364 * return name.c_str();
365 * }
366 * };
367 */
368
369 union ValueHolder
370 {
371 Int int_;
372 UInt uint_;
373 double real_;
374 bool bool_;
375 char *string_;
376 ObjectValues *map_;
377 } value_;
378 CommentInfo *comments_;
379 ValueType type_;
380 bool allocated_;
381 };
382
383
384 /** \brief Experimental and untested: represents an element of the "path" to access a node.
385 */
386 class PathArgument
387 {
388 public:
389 friend class Path;
390
391 PathArgument ();
392 PathArgument (UInt index);
393 PathArgument (const char *key);
394 PathArgument (const std::string &key);
395
396 private:
397 enum Kind
398 {
399 kindNone = 0,
400 kindIndex,
401 kindKey
402 };
403 std::string key_;
404 UInt index_;
405 Kind kind_;
406 };
407
408 /** \brief Experimental and untested: represents a "path" to access a node.
409 *
410 * Syntax:
411 * - "." => root node
412 * - ".[n]" => elements at index 'n' of root node (an array value)
413 * - ".name" => member named 'name' of root node (an object value)
414 * - ".name1.name2.name3"
415 * - ".[0][1][2].name1[3]"
416 * - ".%" => member name is provided as parameter
417 * - ".[%]" => index is provied as parameter
418 */
419 class Path
420 {
421 public:
422 Path (const std::string &path, const PathArgument &a1 = PathArgument (), const PathArgument &a2 = PathArgument (), const PathArgument &a3 = PathArgument (), const PathArgument &a4 = PathArgument (), const PathArgument &a5 = PathArgument ());
423
424 const Value &resolve (const Value &root) const;
425 Value resolve (const Value &root, const Value &defaultValue) const;
426 /* / Creates the "path" to access the specified node and returns a reference on the node. */
427 Value &make (Value &root) const;
428
429 private:
430 typedef std::vector<const PathArgument *> InArgs;
431 typedef std::vector<PathArgument> Args;
432
433 void makePath (const std::string &path, const InArgs &in);
434 void addPathInArg (const std::string &path, const InArgs &in, InArgs::const_iterator &itInArg, PathArgument::Kind kind);
435 void invalidPath (const std::string &path, int location);
436
437 Args args_;
438 };
439
440 /** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value.
441 *
442 * - makeMemberName() and releaseMemberName() are called to respectively duplicate and
443 * free an Json::objectValue member name.
444 * - duplicateStringValue() and releaseStringValue() are called similarly to
445 * duplicate and free a Json::stringValue value.
446 */
447 class ValueAllocator
448 {
449 public:
450 enum {
451 unknown = (unsigned)-1
452 };
453
454 virtual
455 ~ValueAllocator ();
456
457 virtual char *makeMemberName (const char *memberName) = 0;
458 virtual void releaseMemberName (char *memberName) = 0;
459 virtual char *duplicateStringValue (const char *value, unsigned int length = unknown) = 0;
460 virtual void releaseStringValue (char *value) = 0;
461 };
462
463 /** \brief base class for Value iterators.
464 *
465 */
466 class ValueIteratorBase
467 {
468 public:
469 typedef unsigned int size_t;
470 typedef int difference_type;
471 typedef ValueIteratorBase SelfType;
472
473 ValueIteratorBase ();
474 explicit ValueIteratorBase (const Value::ObjectValues::iterator &current);
475
476 bool operator == (const SelfType &other) const
477 {
478 return isEqual (other);
479 }
480
481 bool operator != (const SelfType &other) const
482 {
483 return !isEqual (other);
484 }
485
486 difference_type operator - (const SelfType &other) const
487 {
488 return computeDistance (other);
489 }
490
491 /* / Return either the index or the member name of the referenced value as a Value. */
492 Value key () const;
493
494 /* / Return the index of the referenced Value. -1 if it is not an arrayValue. */
495 UInt index () const;
496
497 /* / Return the member name of the referenced Value. "" if it is not an objectValue. */
498 const char *memberName () const;
499
500 protected:
501 Value &deref () const;
502
503 void increment ();
504
505 void decrement ();
506
507 difference_type computeDistance (const SelfType &other) const;
508
509 bool isEqual (const SelfType &other) const;
510
511 void copy (const SelfType &other);
512
513 private:
514 Value::ObjectValues::iterator current_;
515 /* Indicates that iterator is for a null value. */
516 bool isNull_;
517 };
518
519 /** \brief const iterator for object and array value.
520 *
521 */
522 class ValueConstIterator
523 : public ValueIteratorBase
524 {
525 friend class Value;
526
527 public:
528 typedef unsigned int size_t;
529 typedef int difference_type;
530 typedef const Value &reference;
531 typedef const Value *pointer;
532 typedef ValueConstIterator SelfType;
533
534 ValueConstIterator ();
535
536 private:
537 /*! \internal Use by Value to create an iterator.
538 */
539 explicit ValueConstIterator (const Value::ObjectValues::iterator &current);
540
541 public:
542 SelfType & operator = (const ValueIteratorBase &other);
543
544 SelfType operator ++ (int)
545 {
546 SelfType temp (*this);
547
548 ++*this;
549 return temp;
550 }
551
552 SelfType operator -- (int)
553 {
554 SelfType temp (*this);
555
556 --*this;
557 return temp;
558 }
559
560 SelfType &operator -- ()
561 {
562 decrement ();
563 return *this;
564 }
565
566 SelfType &operator ++ ()
567 {
568 increment ();
569 return *this;
570 }
571
572 reference operator * () const
573 {
574 return deref ();
575 }
576 };
577
578
579 /** \brief Iterator for object and array value.
580 */
581 class ValueIterator
582 : public ValueIteratorBase
583 {
584 friend class Value;
585
586 public:
587 typedef unsigned int size_t;
588 typedef int difference_type;
589 typedef Value &reference;
590 typedef Value *pointer;
591 typedef ValueIterator SelfType;
592
593 ValueIterator ();
594 ValueIterator (const ValueConstIterator &other);
595 ValueIterator (const ValueIterator &other);
596
597 private:
598 /*! \internal Use by Value to create an iterator.
599 */
600 explicit ValueIterator (const Value::ObjectValues::iterator &current);
601
602 public:
603 SelfType &operator = (const SelfType &other);
604
605 SelfType operator ++ (int)
606 {
607 SelfType temp (*this);
608
609 ++*this;
610 return temp;
611 }
612
613 SelfType operator -- (int)
614 {
615 SelfType temp (*this);
616
617 --*this;
618 return temp;
619 }
620
621 SelfType &operator -- ()
622 {
623 decrement ();
624 return *this;
625 }
626
627 SelfType &operator ++ ()
628 {
629 increment ();
630 return *this;
631 }
632
633 reference operator * () const
634 {
635 return deref ();
636 }
637 };
638 } /* namespace Json */