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

File Contents

# User Rev Content
1 sf-pippijn 1.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 */