annotate json/value.h @ 15:d5758530a039 tip

oF0.84 Retina, and iPhone support
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Tue, 12 May 2015 15:48:52 +0100
parents 426d645d8e69
children
rev   line source
rt300@13 1 #ifndef CPPTL_JSON_H_INCLUDED
rt300@13 2 # define CPPTL_JSON_H_INCLUDED
rt300@13 3
rt300@13 4 # include "forwards.h"
rt300@13 5 # include <string>
rt300@13 6 # include <vector>
rt300@13 7
rt300@13 8 # ifndef JSON_USE_CPPTL_SMALLMAP
rt300@13 9 # include <map>
rt300@13 10 # else
rt300@13 11 # include <cpptl/smallmap.h>
rt300@13 12 # endif
rt300@13 13 # ifdef JSON_USE_CPPTL
rt300@13 14 # include <cpptl/forwards.h>
rt300@13 15 # endif
rt300@13 16
rt300@13 17 /** \brief JSON (JavaScript Object Notation).
rt300@13 18 */
rt300@13 19 namespace Json {
rt300@13 20
rt300@13 21 /** \brief Type of the value held by a Value object.
rt300@13 22 */
rt300@13 23 enum ValueType
rt300@13 24 {
rt300@13 25 nullValue = 0, ///< 'null' value
rt300@13 26 intValue, ///< signed integer value
rt300@13 27 uintValue, ///< unsigned integer value
rt300@13 28 realValue, ///< double value
rt300@13 29 stringValue, ///< UTF-8 string value
rt300@13 30 booleanValue, ///< bool value
rt300@13 31 arrayValue, ///< array value (ordered list)
rt300@13 32 objectValue ///< object value (collection of name/value pairs).
rt300@13 33 };
rt300@13 34
rt300@13 35 enum CommentPlacement
rt300@13 36 {
rt300@13 37 commentBefore = 0, ///< a comment placed on the line before a value
rt300@13 38 commentAfterOnSameLine, ///< a comment just after a value on the same line
rt300@13 39 commentAfter, ///< a comment on the line after a value (only make sense for root value)
rt300@13 40 numberOfCommentPlacement
rt300@13 41 };
rt300@13 42
rt300@13 43 //# ifdef JSON_USE_CPPTL
rt300@13 44 // typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
rt300@13 45 // typedef CppTL::AnyEnumerator<const Value &> EnumValues;
rt300@13 46 //# endif
rt300@13 47
rt300@13 48 /** \brief Lightweight wrapper to tag static string.
rt300@13 49 *
rt300@13 50 * Value constructor and objectValue member assignement takes advantage of the
rt300@13 51 * StaticString and avoid the cost of string duplication when storing the
rt300@13 52 * string or the member name.
rt300@13 53 *
rt300@13 54 * Example of usage:
rt300@13 55 * \code
rt300@13 56 * Json::Value aValue( StaticString("some text") );
rt300@13 57 * Json::Value object;
rt300@13 58 * static const StaticString code("code");
rt300@13 59 * object[code] = 1234;
rt300@13 60 * \endcode
rt300@13 61 */
rt300@13 62 class JSON_API StaticString
rt300@13 63 {
rt300@13 64 public:
rt300@13 65 explicit StaticString( const char *czstring )
rt300@13 66 : str_( czstring )
rt300@13 67 {
rt300@13 68 }
rt300@13 69
rt300@13 70 operator const char *() const
rt300@13 71 {
rt300@13 72 return str_;
rt300@13 73 }
rt300@13 74
rt300@13 75 const char *c_str() const
rt300@13 76 {
rt300@13 77 return str_;
rt300@13 78 }
rt300@13 79
rt300@13 80 private:
rt300@13 81 const char *str_;
rt300@13 82 };
rt300@13 83
rt300@13 84 /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
rt300@13 85 *
rt300@13 86 * This class is a discriminated union wrapper that can represents a:
rt300@13 87 * - signed integer [range: Value::minInt - Value::maxInt]
rt300@13 88 * - unsigned integer (range: 0 - Value::maxUInt)
rt300@13 89 * - double
rt300@13 90 * - UTF-8 string
rt300@13 91 * - boolean
rt300@13 92 * - 'null'
rt300@13 93 * - an ordered list of Value
rt300@13 94 * - collection of name/value pairs (javascript object)
rt300@13 95 *
rt300@13 96 * The type of the held value is represented by a #ValueType and
rt300@13 97 * can be obtained using type().
rt300@13 98 *
rt300@13 99 * values of an #objectValue or #arrayValue can be accessed using operator[]() methods.
rt300@13 100 * Non const methods will automatically create the a #nullValue element
rt300@13 101 * if it does not exist.
rt300@13 102 * The sequence of an #arrayValue will be automatically resize and initialized
rt300@13 103 * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
rt300@13 104 *
rt300@13 105 * The get() methods can be used to obtanis default value in the case the required element
rt300@13 106 * does not exist.
rt300@13 107 *
rt300@13 108 * It is possible to iterate over the list of a #objectValue values using
rt300@13 109 * the getMemberNames() method.
rt300@13 110 */
rt300@13 111 class JSON_API Value
rt300@13 112 {
rt300@13 113 friend class ValueIteratorBase;
rt300@13 114 # ifdef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 115 friend class ValueInternalLink;
rt300@13 116 friend class ValueInternalMap;
rt300@13 117 # endif
rt300@13 118 public:
rt300@13 119 typedef std::vector<std::string> Members;
rt300@13 120 typedef ValueIterator iterator;
rt300@13 121 typedef ValueConstIterator const_iterator;
rt300@13 122 typedef Json::UInt UInt;
rt300@13 123 typedef Json::Int Int;
rt300@13 124 typedef UInt ArrayIndex;
rt300@13 125
rt300@13 126 static const Value null;
rt300@13 127 static const Int minInt;
rt300@13 128 static const Int maxInt;
rt300@13 129 static const UInt maxUInt;
rt300@13 130
rt300@13 131 private:
rt300@13 132 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
rt300@13 133 # ifndef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 134 class CZString
rt300@13 135 {
rt300@13 136 public:
rt300@13 137 enum DuplicationPolicy
rt300@13 138 {
rt300@13 139 noDuplication = 0,
rt300@13 140 duplicate,
rt300@13 141 duplicateOnCopy
rt300@13 142 };
rt300@13 143 CZString( int index );
rt300@13 144 CZString( const char *cstr, DuplicationPolicy allocate );
rt300@13 145 CZString( const CZString &other );
rt300@13 146 ~CZString();
rt300@13 147 CZString &operator =( const CZString &other );
rt300@13 148 bool operator<( const CZString &other ) const;
rt300@13 149 bool operator==( const CZString &other ) const;
rt300@13 150 int index() const;
rt300@13 151 const char *c_str() const;
rt300@13 152 bool isStaticString() const;
rt300@13 153 private:
rt300@13 154 void swap( CZString &other );
rt300@13 155 const char *cstr_;
rt300@13 156 int index_;
rt300@13 157 };
rt300@13 158
rt300@13 159 public:
rt300@13 160 # ifndef JSON_USE_CPPTL_SMALLMAP
rt300@13 161 typedef std::map<CZString, Value> ObjectValues;
rt300@13 162 # else
rt300@13 163 typedef CppTL::SmallMap<CZString, Value> ObjectValues;
rt300@13 164 # endif // ifndef JSON_USE_CPPTL_SMALLMAP
rt300@13 165 # endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 166 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
rt300@13 167
rt300@13 168 public:
rt300@13 169 /** \brief Create a default Value of the given type.
rt300@13 170
rt300@13 171 This is a very useful constructor.
rt300@13 172 To create an empty array, pass arrayValue.
rt300@13 173 To create an empty object, pass objectValue.
rt300@13 174 Another Value can then be set to this one by assignment.
rt300@13 175 This is useful since clear() and resize() will not alter types.
rt300@13 176
rt300@13 177 Examples:
rt300@13 178 \code
rt300@13 179 Json::Value null_value; // null
rt300@13 180 Json::Value arr_value(Json::arrayValue); // []
rt300@13 181 Json::Value obj_value(Json::objectValue); // {}
rt300@13 182 \endcode
rt300@13 183 */
rt300@13 184 Value( ValueType type = nullValue );
rt300@13 185 Value( Int value );
rt300@13 186 Value( UInt value );
rt300@13 187 Value( double value );
rt300@13 188 Value( const char *value );
rt300@13 189 Value( const char *beginValue, const char *endValue );
rt300@13 190 /** \brief Constructs a value from a static string.
rt300@13 191
rt300@13 192 * Like other value string constructor but do not duplicate the string for
rt300@13 193 * internal storage. The given string must remain alive after the call to this
rt300@13 194 * constructor.
rt300@13 195 * Example of usage:
rt300@13 196 * \code
rt300@13 197 * Json::Value aValue( StaticString("some text") );
rt300@13 198 * \endcode
rt300@13 199 */
rt300@13 200 Value( const StaticString &value );
rt300@13 201 Value( const std::string &value );
rt300@13 202 # ifdef JSON_USE_CPPTL
rt300@13 203 Value( const CppTL::ConstString &value );
rt300@13 204 # endif
rt300@13 205 Value( bool value );
rt300@13 206 Value( const Value &other );
rt300@13 207 ~Value();
rt300@13 208
rt300@13 209 Value &operator=( const Value &other );
rt300@13 210 /// Swap values.
rt300@13 211 /// \note Currently, comments are intentionally not swapped, for
rt300@13 212 /// both logic and efficiency.
rt300@13 213 void swap( Value &other );
rt300@13 214
rt300@13 215 ValueType type() const;
rt300@13 216
rt300@13 217 bool operator <( const Value &other ) const;
rt300@13 218 bool operator <=( const Value &other ) const;
rt300@13 219 bool operator >=( const Value &other ) const;
rt300@13 220 bool operator >( const Value &other ) const;
rt300@13 221
rt300@13 222 bool operator ==( const Value &other ) const;
rt300@13 223 bool operator !=( const Value &other ) const;
rt300@13 224
rt300@13 225 int compare( const Value &other );
rt300@13 226
rt300@13 227 const char *asCString() const;
rt300@13 228 std::string asString() const;
rt300@13 229 # ifdef JSON_USE_CPPTL
rt300@13 230 CppTL::ConstString asConstString() const;
rt300@13 231 # endif
rt300@13 232 Int asInt() const;
rt300@13 233 UInt asUInt() const;
rt300@13 234 double asDouble() const;
rt300@13 235 bool asBool() const;
rt300@13 236
rt300@13 237 bool isNull() const;
rt300@13 238 bool isBool() const;
rt300@13 239 bool isInt() const;
rt300@13 240 bool isUInt() const;
rt300@13 241 bool isIntegral() const;
rt300@13 242 bool isDouble() const;
rt300@13 243 bool isNumeric() const;
rt300@13 244 bool isString() const;
rt300@13 245 bool isArray() const;
rt300@13 246 bool isObject() const;
rt300@13 247
rt300@13 248 bool isConvertibleTo( ValueType other ) const;
rt300@13 249
rt300@13 250 /// Number of values in array or object
rt300@13 251 UInt size() const;
rt300@13 252
rt300@13 253 /// \brief Return true if empty array, empty object, or null;
rt300@13 254 /// otherwise, false.
rt300@13 255 bool empty() const;
rt300@13 256
rt300@13 257 /// Return isNull()
rt300@13 258 bool operator!() const;
rt300@13 259
rt300@13 260 /// Remove all object members and array elements.
rt300@13 261 /// \pre type() is arrayValue, objectValue, or nullValue
rt300@13 262 /// \post type() is unchanged
rt300@13 263 void clear();
rt300@13 264
rt300@13 265 /// Resize the array to size elements.
rt300@13 266 /// New elements are initialized to null.
rt300@13 267 /// May only be called on nullValue or arrayValue.
rt300@13 268 /// \pre type() is arrayValue or nullValue
rt300@13 269 /// \post type() is arrayValue
rt300@13 270 void resize( UInt size );
rt300@13 271
rt300@13 272 /// Access an array element (zero based index ).
rt300@13 273 /// If the array contains less than index element, then null value are inserted
rt300@13 274 /// in the array so that its size is index+1.
rt300@13 275 /// (You may need to say 'value[0u]' to get your compiler to distinguish
rt300@13 276 /// this from the operator[] which takes a string.)
rt300@13 277 Value &operator[]( UInt index );
rt300@13 278 /// Access an array element (zero based index )
rt300@13 279 /// (You may need to say 'value[0u]' to get your compiler to distinguish
rt300@13 280 /// this from the operator[] which takes a string.)
rt300@13 281 const Value &operator[]( UInt index ) const;
rt300@13 282 /// If the array contains at least index+1 elements, returns the element value,
rt300@13 283 /// otherwise returns defaultValue.
rt300@13 284 Value get( UInt index,
rt300@13 285 const Value &defaultValue ) const;
rt300@13 286 /// Return true if index < size().
rt300@13 287 bool isValidIndex( UInt index ) const;
rt300@13 288 /// \brief Append value to array at the end.
rt300@13 289 ///
rt300@13 290 /// Equivalent to jsonvalue[jsonvalue.size()] = value;
rt300@13 291 Value &append( const Value &value );
rt300@13 292
rt300@13 293 /// Access an object value by name, create a null member if it does not exist.
rt300@13 294 Value &operator[]( const char *key );
rt300@13 295 /// Access an object value by name, returns null if there is no member with that name.
rt300@13 296 const Value &operator[]( const char *key ) const;
rt300@13 297 /// Access an object value by name, create a null member if it does not exist.
rt300@13 298 Value &operator[]( const std::string &key );
rt300@13 299 /// Access an object value by name, returns null if there is no member with that name.
rt300@13 300 const Value &operator[]( const std::string &key ) const;
rt300@13 301 /** \brief Access an object value by name, create a null member if it does not exist.
rt300@13 302
rt300@13 303 * If the object as no entry for that name, then the member name used to store
rt300@13 304 * the new entry is not duplicated.
rt300@13 305 * Example of use:
rt300@13 306 * \code
rt300@13 307 * Json::Value object;
rt300@13 308 * static const StaticString code("code");
rt300@13 309 * object[code] = 1234;
rt300@13 310 * \endcode
rt300@13 311 */
rt300@13 312 Value &operator[]( const StaticString &key );
rt300@13 313 # ifdef JSON_USE_CPPTL
rt300@13 314 /// Access an object value by name, create a null member if it does not exist.
rt300@13 315 Value &operator[]( const CppTL::ConstString &key );
rt300@13 316 /// Access an object value by name, returns null if there is no member with that name.
rt300@13 317 const Value &operator[]( const CppTL::ConstString &key ) const;
rt300@13 318 # endif
rt300@13 319 /// Return the member named key if it exist, defaultValue otherwise.
rt300@13 320 Value get( const char *key,
rt300@13 321 const Value &defaultValue ) const;
rt300@13 322 /// Return the member named key if it exist, defaultValue otherwise.
rt300@13 323 Value get( const std::string &key,
rt300@13 324 const Value &defaultValue ) const;
rt300@13 325 # ifdef JSON_USE_CPPTL
rt300@13 326 /// Return the member named key if it exist, defaultValue otherwise.
rt300@13 327 Value get( const CppTL::ConstString &key,
rt300@13 328 const Value &defaultValue ) const;
rt300@13 329 # endif
rt300@13 330 /// \brief Remove and return the named member.
rt300@13 331 ///
rt300@13 332 /// Do nothing if it did not exist.
rt300@13 333 /// \return the removed Value, or null.
rt300@13 334 /// \pre type() is objectValue or nullValue
rt300@13 335 /// \post type() is unchanged
rt300@13 336 Value removeMember( const char* key );
rt300@13 337 /// Same as removeMember(const char*)
rt300@13 338 Value removeMember( const std::string &key );
rt300@13 339
rt300@13 340 /// Return true if the object has a member named key.
rt300@13 341 bool isMember( const char *key ) const;
rt300@13 342 /// Return true if the object has a member named key.
rt300@13 343 bool isMember( const std::string &key ) const;
rt300@13 344 # ifdef JSON_USE_CPPTL
rt300@13 345 /// Return true if the object has a member named key.
rt300@13 346 bool isMember( const CppTL::ConstString &key ) const;
rt300@13 347 # endif
rt300@13 348
rt300@13 349 /// \brief Return a list of the member names.
rt300@13 350 ///
rt300@13 351 /// If null, return an empty list.
rt300@13 352 /// \pre type() is objectValue or nullValue
rt300@13 353 /// \post if type() was nullValue, it remains nullValue
rt300@13 354 Members getMemberNames() const;
rt300@13 355
rt300@13 356 //# ifdef JSON_USE_CPPTL
rt300@13 357 // EnumMemberNames enumMemberNames() const;
rt300@13 358 // EnumValues enumValues() const;
rt300@13 359 //# endif
rt300@13 360
rt300@13 361 /// Comments must be //... or /* ... */
rt300@13 362 void setComment( const char *comment,
rt300@13 363 CommentPlacement placement );
rt300@13 364 /// Comments must be //... or /* ... */
rt300@13 365 void setComment( const std::string &comment,
rt300@13 366 CommentPlacement placement );
rt300@13 367 bool hasComment( CommentPlacement placement ) const;
rt300@13 368 /// Include delimiters and embedded newlines.
rt300@13 369 std::string getComment( CommentPlacement placement ) const;
rt300@13 370
rt300@13 371 std::string toStyledString() const;
rt300@13 372
rt300@13 373 const_iterator begin() const;
rt300@13 374 const_iterator end() const;
rt300@13 375
rt300@13 376 iterator begin();
rt300@13 377 iterator end();
rt300@13 378
rt300@13 379 private:
rt300@13 380 Value &resolveReference( const char *key,
rt300@13 381 bool isStatic );
rt300@13 382
rt300@13 383 # ifdef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 384 inline bool isItemAvailable() const
rt300@13 385 {
rt300@13 386 return itemIsUsed_ == 0;
rt300@13 387 }
rt300@13 388
rt300@13 389 inline void setItemUsed( bool isUsed = true )
rt300@13 390 {
rt300@13 391 itemIsUsed_ = isUsed ? 1 : 0;
rt300@13 392 }
rt300@13 393
rt300@13 394 inline bool isMemberNameStatic() const
rt300@13 395 {
rt300@13 396 return memberNameIsStatic_ == 0;
rt300@13 397 }
rt300@13 398
rt300@13 399 inline void setMemberNameIsStatic( bool isStatic )
rt300@13 400 {
rt300@13 401 memberNameIsStatic_ = isStatic ? 1 : 0;
rt300@13 402 }
rt300@13 403 # endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 404
rt300@13 405 private:
rt300@13 406 struct CommentInfo
rt300@13 407 {
rt300@13 408 CommentInfo();
rt300@13 409 ~CommentInfo();
rt300@13 410
rt300@13 411 void setComment( const char *text );
rt300@13 412
rt300@13 413 char *comment_;
rt300@13 414 };
rt300@13 415
rt300@13 416 //struct MemberNamesTransform
rt300@13 417 //{
rt300@13 418 // typedef const char *result_type;
rt300@13 419 // const char *operator()( const CZString &name ) const
rt300@13 420 // {
rt300@13 421 // return name.c_str();
rt300@13 422 // }
rt300@13 423 //};
rt300@13 424
rt300@13 425 union ValueHolder
rt300@13 426 {
rt300@13 427 Int int_;
rt300@13 428 UInt uint_;
rt300@13 429 double real_;
rt300@13 430 bool bool_;
rt300@13 431 char *string_;
rt300@13 432 # ifdef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 433 ValueInternalArray *array_;
rt300@13 434 ValueInternalMap *map_;
rt300@13 435 #else
rt300@13 436 ObjectValues *map_;
rt300@13 437 # endif
rt300@13 438 } value_;
rt300@13 439 ValueType type_ : 8;
rt300@13 440 int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
rt300@13 441 # ifdef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 442 unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
rt300@13 443 int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
rt300@13 444 # endif
rt300@13 445 CommentInfo *comments_;
rt300@13 446 };
rt300@13 447
rt300@13 448
rt300@13 449 /** \brief Experimental and untested: represents an element of the "path" to access a node.
rt300@13 450 */
rt300@13 451 class PathArgument
rt300@13 452 {
rt300@13 453 public:
rt300@13 454 friend class Path;
rt300@13 455
rt300@13 456 PathArgument();
rt300@13 457 PathArgument( UInt index );
rt300@13 458 PathArgument( const char *key );
rt300@13 459 PathArgument( const std::string &key );
rt300@13 460
rt300@13 461 private:
rt300@13 462 enum Kind
rt300@13 463 {
rt300@13 464 kindNone = 0,
rt300@13 465 kindIndex,
rt300@13 466 kindKey
rt300@13 467 };
rt300@13 468 std::string key_;
rt300@13 469 UInt index_;
rt300@13 470 Kind kind_;
rt300@13 471 };
rt300@13 472
rt300@13 473 /** \brief Experimental and untested: represents a "path" to access a node.
rt300@13 474 *
rt300@13 475 * Syntax:
rt300@13 476 * - "." => root node
rt300@13 477 * - ".[n]" => elements at index 'n' of root node (an array value)
rt300@13 478 * - ".name" => member named 'name' of root node (an object value)
rt300@13 479 * - ".name1.name2.name3"
rt300@13 480 * - ".[0][1][2].name1[3]"
rt300@13 481 * - ".%" => member name is provided as parameter
rt300@13 482 * - ".[%]" => index is provied as parameter
rt300@13 483 */
rt300@13 484 class Path
rt300@13 485 {
rt300@13 486 public:
rt300@13 487 Path( const std::string &path,
rt300@13 488 const PathArgument &a1 = PathArgument(),
rt300@13 489 const PathArgument &a2 = PathArgument(),
rt300@13 490 const PathArgument &a3 = PathArgument(),
rt300@13 491 const PathArgument &a4 = PathArgument(),
rt300@13 492 const PathArgument &a5 = PathArgument() );
rt300@13 493
rt300@13 494 const Value &resolve( const Value &root ) const;
rt300@13 495 Value resolve( const Value &root,
rt300@13 496 const Value &defaultValue ) const;
rt300@13 497 /// Creates the "path" to access the specified node and returns a reference on the node.
rt300@13 498 Value &make( Value &root ) const;
rt300@13 499
rt300@13 500 private:
rt300@13 501 typedef std::vector<const PathArgument *> InArgs;
rt300@13 502 typedef std::vector<PathArgument> Args;
rt300@13 503
rt300@13 504 void makePath( const std::string &path,
rt300@13 505 const InArgs &in );
rt300@13 506 void addPathInArg( const std::string &path,
rt300@13 507 const InArgs &in,
rt300@13 508 InArgs::const_iterator &itInArg,
rt300@13 509 PathArgument::Kind kind );
rt300@13 510 void invalidPath( const std::string &path,
rt300@13 511 int location );
rt300@13 512
rt300@13 513 Args args_;
rt300@13 514 };
rt300@13 515
rt300@13 516 /** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value.
rt300@13 517 *
rt300@13 518 * - makeMemberName() and releaseMemberName() are called to respectively duplicate and
rt300@13 519 * free an Json::objectValue member name.
rt300@13 520 * - duplicateStringValue() and releaseStringValue() are called similarly to
rt300@13 521 * duplicate and free a Json::stringValue value.
rt300@13 522 */
rt300@13 523 class ValueAllocator
rt300@13 524 {
rt300@13 525 public:
rt300@13 526 enum { unknown = (unsigned)-1 };
rt300@13 527
rt300@13 528 virtual ~ValueAllocator();
rt300@13 529
rt300@13 530 virtual char *makeMemberName( const char *memberName ) = 0;
rt300@13 531 virtual void releaseMemberName( char *memberName ) = 0;
rt300@13 532 virtual char *duplicateStringValue( const char *value,
rt300@13 533 unsigned int length = unknown ) = 0;
rt300@13 534 virtual void releaseStringValue( char *value ) = 0;
rt300@13 535 };
rt300@13 536
rt300@13 537 #ifdef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 538 /** \brief Allocator to customize Value internal map.
rt300@13 539 * Below is an example of a simple implementation (default implementation actually
rt300@13 540 * use memory pool for speed).
rt300@13 541 * \code
rt300@13 542 class DefaultValueMapAllocator : public ValueMapAllocator
rt300@13 543 {
rt300@13 544 public: // overridden from ValueMapAllocator
rt300@13 545 virtual ValueInternalMap *newMap()
rt300@13 546 {
rt300@13 547 return new ValueInternalMap();
rt300@13 548 }
rt300@13 549
rt300@13 550 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
rt300@13 551 {
rt300@13 552 return new ValueInternalMap( other );
rt300@13 553 }
rt300@13 554
rt300@13 555 virtual void destructMap( ValueInternalMap *map )
rt300@13 556 {
rt300@13 557 delete map;
rt300@13 558 }
rt300@13 559
rt300@13 560 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
rt300@13 561 {
rt300@13 562 return new ValueInternalLink[size];
rt300@13 563 }
rt300@13 564
rt300@13 565 virtual void releaseMapBuckets( ValueInternalLink *links )
rt300@13 566 {
rt300@13 567 delete [] links;
rt300@13 568 }
rt300@13 569
rt300@13 570 virtual ValueInternalLink *allocateMapLink()
rt300@13 571 {
rt300@13 572 return new ValueInternalLink();
rt300@13 573 }
rt300@13 574
rt300@13 575 virtual void releaseMapLink( ValueInternalLink *link )
rt300@13 576 {
rt300@13 577 delete link;
rt300@13 578 }
rt300@13 579 };
rt300@13 580 * \endcode
rt300@13 581 */
rt300@13 582 class JSON_API ValueMapAllocator
rt300@13 583 {
rt300@13 584 public:
rt300@13 585 virtual ~ValueMapAllocator();
rt300@13 586 virtual ValueInternalMap *newMap() = 0;
rt300@13 587 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
rt300@13 588 virtual void destructMap( ValueInternalMap *map ) = 0;
rt300@13 589 virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
rt300@13 590 virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
rt300@13 591 virtual ValueInternalLink *allocateMapLink() = 0;
rt300@13 592 virtual void releaseMapLink( ValueInternalLink *link ) = 0;
rt300@13 593 };
rt300@13 594
rt300@13 595 /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
rt300@13 596 * \internal previous_ & next_ allows for bidirectional traversal.
rt300@13 597 */
rt300@13 598 class JSON_API ValueInternalLink
rt300@13 599 {
rt300@13 600 public:
rt300@13 601 enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
rt300@13 602 enum InternalFlags {
rt300@13 603 flagAvailable = 0,
rt300@13 604 flagUsed = 1
rt300@13 605 };
rt300@13 606
rt300@13 607 ValueInternalLink();
rt300@13 608
rt300@13 609 ~ValueInternalLink();
rt300@13 610
rt300@13 611 Value items_[itemPerLink];
rt300@13 612 char *keys_[itemPerLink];
rt300@13 613 ValueInternalLink *previous_;
rt300@13 614 ValueInternalLink *next_;
rt300@13 615 };
rt300@13 616
rt300@13 617
rt300@13 618 /** \brief A linked page based hash-table implementation used internally by Value.
rt300@13 619 * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
rt300@13 620 * list in each bucket to handle collision. There is an addional twist in that
rt300@13 621 * each node of the collision linked list is a page containing a fixed amount of
rt300@13 622 * value. This provides a better compromise between memory usage and speed.
rt300@13 623 *
rt300@13 624 * Each bucket is made up of a chained list of ValueInternalLink. The last
rt300@13 625 * link of a given bucket can be found in the 'previous_' field of the following bucket.
rt300@13 626 * The last link of the last bucket is stored in tailLink_ as it has no following bucket.
rt300@13 627 * Only the last link of a bucket may contains 'available' item. The last link always
rt300@13 628 * contains at least one element unless is it the bucket one very first link.
rt300@13 629 */
rt300@13 630 class JSON_API ValueInternalMap
rt300@13 631 {
rt300@13 632 friend class ValueIteratorBase;
rt300@13 633 friend class Value;
rt300@13 634 public:
rt300@13 635 typedef unsigned int HashKey;
rt300@13 636 typedef unsigned int BucketIndex;
rt300@13 637
rt300@13 638 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
rt300@13 639 struct IteratorState
rt300@13 640 {
rt300@13 641 IteratorState()
rt300@13 642 : map_(0)
rt300@13 643 , link_(0)
rt300@13 644 , itemIndex_(0)
rt300@13 645 , bucketIndex_(0)
rt300@13 646 {
rt300@13 647 }
rt300@13 648 ValueInternalMap *map_;
rt300@13 649 ValueInternalLink *link_;
rt300@13 650 BucketIndex itemIndex_;
rt300@13 651 BucketIndex bucketIndex_;
rt300@13 652 };
rt300@13 653 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
rt300@13 654
rt300@13 655 ValueInternalMap();
rt300@13 656 ValueInternalMap( const ValueInternalMap &other );
rt300@13 657 ValueInternalMap &operator =( const ValueInternalMap &other );
rt300@13 658 ~ValueInternalMap();
rt300@13 659
rt300@13 660 void swap( ValueInternalMap &other );
rt300@13 661
rt300@13 662 BucketIndex size() const;
rt300@13 663
rt300@13 664 void clear();
rt300@13 665
rt300@13 666 bool reserveDelta( BucketIndex growth );
rt300@13 667
rt300@13 668 bool reserve( BucketIndex newItemCount );
rt300@13 669
rt300@13 670 const Value *find( const char *key ) const;
rt300@13 671
rt300@13 672 Value *find( const char *key );
rt300@13 673
rt300@13 674 Value &resolveReference( const char *key,
rt300@13 675 bool isStatic );
rt300@13 676
rt300@13 677 void remove( const char *key );
rt300@13 678
rt300@13 679 void doActualRemove( ValueInternalLink *link,
rt300@13 680 BucketIndex index,
rt300@13 681 BucketIndex bucketIndex );
rt300@13 682
rt300@13 683 ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
rt300@13 684
rt300@13 685 Value &setNewItem( const char *key,
rt300@13 686 bool isStatic,
rt300@13 687 ValueInternalLink *link,
rt300@13 688 BucketIndex index );
rt300@13 689
rt300@13 690 Value &unsafeAdd( const char *key,
rt300@13 691 bool isStatic,
rt300@13 692 HashKey hashedKey );
rt300@13 693
rt300@13 694 HashKey hash( const char *key ) const;
rt300@13 695
rt300@13 696 int compare( const ValueInternalMap &other ) const;
rt300@13 697
rt300@13 698 private:
rt300@13 699 void makeBeginIterator( IteratorState &it ) const;
rt300@13 700 void makeEndIterator( IteratorState &it ) const;
rt300@13 701 static bool equals( const IteratorState &x, const IteratorState &other );
rt300@13 702 static void increment( IteratorState &iterator );
rt300@13 703 static void incrementBucket( IteratorState &iterator );
rt300@13 704 static void decrement( IteratorState &iterator );
rt300@13 705 static const char *key( const IteratorState &iterator );
rt300@13 706 static const char *key( const IteratorState &iterator, bool &isStatic );
rt300@13 707 static Value &value( const IteratorState &iterator );
rt300@13 708 static int distance( const IteratorState &x, const IteratorState &y );
rt300@13 709
rt300@13 710 private:
rt300@13 711 ValueInternalLink *buckets_;
rt300@13 712 ValueInternalLink *tailLink_;
rt300@13 713 BucketIndex bucketsSize_;
rt300@13 714 BucketIndex itemCount_;
rt300@13 715 };
rt300@13 716
rt300@13 717 /** \brief A simplified deque implementation used internally by Value.
rt300@13 718 * \internal
rt300@13 719 * It is based on a list of fixed "page", each page contains a fixed number of items.
rt300@13 720 * Instead of using a linked-list, a array of pointer is used for fast item look-up.
rt300@13 721 * Look-up for an element is as follow:
rt300@13 722 * - compute page index: pageIndex = itemIndex / itemsPerPage
rt300@13 723 * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
rt300@13 724 *
rt300@13 725 * Insertion is amortized constant time (only the array containing the index of pointers
rt300@13 726 * need to be reallocated when items are appended).
rt300@13 727 */
rt300@13 728 class JSON_API ValueInternalArray
rt300@13 729 {
rt300@13 730 friend class Value;
rt300@13 731 friend class ValueIteratorBase;
rt300@13 732 public:
rt300@13 733 enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
rt300@13 734 typedef Value::ArrayIndex ArrayIndex;
rt300@13 735 typedef unsigned int PageIndex;
rt300@13 736
rt300@13 737 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
rt300@13 738 struct IteratorState // Must be a POD
rt300@13 739 {
rt300@13 740 IteratorState()
rt300@13 741 : array_(0)
rt300@13 742 , currentPageIndex_(0)
rt300@13 743 , currentItemIndex_(0)
rt300@13 744 {
rt300@13 745 }
rt300@13 746 ValueInternalArray *array_;
rt300@13 747 Value **currentPageIndex_;
rt300@13 748 unsigned int currentItemIndex_;
rt300@13 749 };
rt300@13 750 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
rt300@13 751
rt300@13 752 ValueInternalArray();
rt300@13 753 ValueInternalArray( const ValueInternalArray &other );
rt300@13 754 ValueInternalArray &operator =( const ValueInternalArray &other );
rt300@13 755 ~ValueInternalArray();
rt300@13 756 void swap( ValueInternalArray &other );
rt300@13 757
rt300@13 758 void clear();
rt300@13 759 void resize( ArrayIndex newSize );
rt300@13 760
rt300@13 761 Value &resolveReference( ArrayIndex index );
rt300@13 762
rt300@13 763 Value *find( ArrayIndex index ) const;
rt300@13 764
rt300@13 765 ArrayIndex size() const;
rt300@13 766
rt300@13 767 int compare( const ValueInternalArray &other ) const;
rt300@13 768
rt300@13 769 private:
rt300@13 770 static bool equals( const IteratorState &x, const IteratorState &other );
rt300@13 771 static void increment( IteratorState &iterator );
rt300@13 772 static void decrement( IteratorState &iterator );
rt300@13 773 static Value &dereference( const IteratorState &iterator );
rt300@13 774 static Value &unsafeDereference( const IteratorState &iterator );
rt300@13 775 static int distance( const IteratorState &x, const IteratorState &y );
rt300@13 776 static ArrayIndex indexOf( const IteratorState &iterator );
rt300@13 777 void makeBeginIterator( IteratorState &it ) const;
rt300@13 778 void makeEndIterator( IteratorState &it ) const;
rt300@13 779 void makeIterator( IteratorState &it, ArrayIndex index ) const;
rt300@13 780
rt300@13 781 void makeIndexValid( ArrayIndex index );
rt300@13 782
rt300@13 783 Value **pages_;
rt300@13 784 ArrayIndex size_;
rt300@13 785 PageIndex pageCount_;
rt300@13 786 };
rt300@13 787
rt300@13 788 /** \brief Experimental: do not use. Allocator to customize Value internal array.
rt300@13 789 * Below is an example of a simple implementation (actual implementation use
rt300@13 790 * memory pool).
rt300@13 791 \code
rt300@13 792 class DefaultValueArrayAllocator : public ValueArrayAllocator
rt300@13 793 {
rt300@13 794 public: // overridden from ValueArrayAllocator
rt300@13 795 virtual ~DefaultValueArrayAllocator()
rt300@13 796 {
rt300@13 797 }
rt300@13 798
rt300@13 799 virtual ValueInternalArray *newArray()
rt300@13 800 {
rt300@13 801 return new ValueInternalArray();
rt300@13 802 }
rt300@13 803
rt300@13 804 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
rt300@13 805 {
rt300@13 806 return new ValueInternalArray( other );
rt300@13 807 }
rt300@13 808
rt300@13 809 virtual void destruct( ValueInternalArray *array )
rt300@13 810 {
rt300@13 811 delete array;
rt300@13 812 }
rt300@13 813
rt300@13 814 virtual void reallocateArrayPageIndex( Value **&indexes,
rt300@13 815 ValueInternalArray::PageIndex &indexCount,
rt300@13 816 ValueInternalArray::PageIndex minNewIndexCount )
rt300@13 817 {
rt300@13 818 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
rt300@13 819 if ( minNewIndexCount > newIndexCount )
rt300@13 820 newIndexCount = minNewIndexCount;
rt300@13 821 void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
rt300@13 822 if ( !newIndexes )
rt300@13 823 throw std::bad_alloc();
rt300@13 824 indexCount = newIndexCount;
rt300@13 825 indexes = static_cast<Value **>( newIndexes );
rt300@13 826 }
rt300@13 827 virtual void releaseArrayPageIndex( Value **indexes,
rt300@13 828 ValueInternalArray::PageIndex indexCount )
rt300@13 829 {
rt300@13 830 if ( indexes )
rt300@13 831 free( indexes );
rt300@13 832 }
rt300@13 833
rt300@13 834 virtual Value *allocateArrayPage()
rt300@13 835 {
rt300@13 836 return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
rt300@13 837 }
rt300@13 838
rt300@13 839 virtual void releaseArrayPage( Value *value )
rt300@13 840 {
rt300@13 841 if ( value )
rt300@13 842 free( value );
rt300@13 843 }
rt300@13 844 };
rt300@13 845 \endcode
rt300@13 846 */
rt300@13 847 class JSON_API ValueArrayAllocator
rt300@13 848 {
rt300@13 849 public:
rt300@13 850 virtual ~ValueArrayAllocator();
rt300@13 851 virtual ValueInternalArray *newArray() = 0;
rt300@13 852 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
rt300@13 853 virtual void destructArray( ValueInternalArray *array ) = 0;
rt300@13 854 /** \brief Reallocate array page index.
rt300@13 855 * Reallocates an array of pointer on each page.
rt300@13 856 * \param indexes [input] pointer on the current index. May be \c NULL.
rt300@13 857 * [output] pointer on the new index of at least
rt300@13 858 * \a minNewIndexCount pages.
rt300@13 859 * \param indexCount [input] current number of pages in the index.
rt300@13 860 * [output] number of page the reallocated index can handle.
rt300@13 861 * \b MUST be >= \a minNewIndexCount.
rt300@13 862 * \param minNewIndexCount Minimum number of page the new index must be able to
rt300@13 863 * handle.
rt300@13 864 */
rt300@13 865 virtual void reallocateArrayPageIndex( Value **&indexes,
rt300@13 866 ValueInternalArray::PageIndex &indexCount,
rt300@13 867 ValueInternalArray::PageIndex minNewIndexCount ) = 0;
rt300@13 868 virtual void releaseArrayPageIndex( Value **indexes,
rt300@13 869 ValueInternalArray::PageIndex indexCount ) = 0;
rt300@13 870 virtual Value *allocateArrayPage() = 0;
rt300@13 871 virtual void releaseArrayPage( Value *value ) = 0;
rt300@13 872 };
rt300@13 873 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 874
rt300@13 875
rt300@13 876 /** \brief base class for Value iterators.
rt300@13 877 *
rt300@13 878 */
rt300@13 879 class ValueIteratorBase
rt300@13 880 {
rt300@13 881 public:
rt300@13 882 typedef unsigned int size_t;
rt300@13 883 typedef int difference_type;
rt300@13 884 typedef ValueIteratorBase SelfType;
rt300@13 885
rt300@13 886 ValueIteratorBase();
rt300@13 887 #ifndef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 888 explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
rt300@13 889 #else
rt300@13 890 ValueIteratorBase( const ValueInternalArray::IteratorState &state );
rt300@13 891 ValueIteratorBase( const ValueInternalMap::IteratorState &state );
rt300@13 892 #endif
rt300@13 893
rt300@13 894 bool operator ==( const SelfType &other ) const
rt300@13 895 {
rt300@13 896 return isEqual( other );
rt300@13 897 }
rt300@13 898
rt300@13 899 bool operator !=( const SelfType &other ) const
rt300@13 900 {
rt300@13 901 return !isEqual( other );
rt300@13 902 }
rt300@13 903
rt300@13 904 difference_type operator -( const SelfType &other ) const
rt300@13 905 {
rt300@13 906 return computeDistance( other );
rt300@13 907 }
rt300@13 908
rt300@13 909 /// Return either the index or the member name of the referenced value as a Value.
rt300@13 910 Value key() const;
rt300@13 911
rt300@13 912 /// Return the index of the referenced Value. -1 if it is not an arrayValue.
rt300@13 913 UInt index() const;
rt300@13 914
rt300@13 915 /// Return the member name of the referenced Value. "" if it is not an objectValue.
rt300@13 916 const char *memberName() const;
rt300@13 917
rt300@13 918 protected:
rt300@13 919 Value &deref() const;
rt300@13 920
rt300@13 921 void increment();
rt300@13 922
rt300@13 923 void decrement();
rt300@13 924
rt300@13 925 difference_type computeDistance( const SelfType &other ) const;
rt300@13 926
rt300@13 927 bool isEqual( const SelfType &other ) const;
rt300@13 928
rt300@13 929 void copy( const SelfType &other );
rt300@13 930
rt300@13 931 private:
rt300@13 932 #ifndef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 933 Value::ObjectValues::iterator current_;
rt300@13 934 // Indicates that iterator is for a null value.
rt300@13 935 bool isNull_;
rt300@13 936 #else
rt300@13 937 union
rt300@13 938 {
rt300@13 939 ValueInternalArray::IteratorState array_;
rt300@13 940 ValueInternalMap::IteratorState map_;
rt300@13 941 } iterator_;
rt300@13 942 bool isArray_;
rt300@13 943 #endif
rt300@13 944 };
rt300@13 945
rt300@13 946 /** \brief const iterator for object and array value.
rt300@13 947 *
rt300@13 948 */
rt300@13 949 class ValueConstIterator : public ValueIteratorBase
rt300@13 950 {
rt300@13 951 friend class Value;
rt300@13 952 public:
rt300@13 953 typedef unsigned int size_t;
rt300@13 954 typedef int difference_type;
rt300@13 955 typedef const Value &reference;
rt300@13 956 typedef const Value *pointer;
rt300@13 957 typedef ValueConstIterator SelfType;
rt300@13 958
rt300@13 959 ValueConstIterator();
rt300@13 960 private:
rt300@13 961 /*! \internal Use by Value to create an iterator.
rt300@13 962 */
rt300@13 963 #ifndef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 964 explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
rt300@13 965 #else
rt300@13 966 ValueConstIterator( const ValueInternalArray::IteratorState &state );
rt300@13 967 ValueConstIterator( const ValueInternalMap::IteratorState &state );
rt300@13 968 #endif
rt300@13 969 public:
rt300@13 970 SelfType &operator =( const ValueIteratorBase &other );
rt300@13 971
rt300@13 972 SelfType operator++( int )
rt300@13 973 {
rt300@13 974 SelfType temp( *this );
rt300@13 975 ++*this;
rt300@13 976 return temp;
rt300@13 977 }
rt300@13 978
rt300@13 979 SelfType operator--( int )
rt300@13 980 {
rt300@13 981 SelfType temp( *this );
rt300@13 982 --*this;
rt300@13 983 return temp;
rt300@13 984 }
rt300@13 985
rt300@13 986 SelfType &operator--()
rt300@13 987 {
rt300@13 988 decrement();
rt300@13 989 return *this;
rt300@13 990 }
rt300@13 991
rt300@13 992 SelfType &operator++()
rt300@13 993 {
rt300@13 994 increment();
rt300@13 995 return *this;
rt300@13 996 }
rt300@13 997
rt300@13 998 reference operator *() const
rt300@13 999 {
rt300@13 1000 return deref();
rt300@13 1001 }
rt300@13 1002 };
rt300@13 1003
rt300@13 1004
rt300@13 1005 /** \brief Iterator for object and array value.
rt300@13 1006 */
rt300@13 1007 class ValueIterator : public ValueIteratorBase
rt300@13 1008 {
rt300@13 1009 friend class Value;
rt300@13 1010 public:
rt300@13 1011 typedef unsigned int size_t;
rt300@13 1012 typedef int difference_type;
rt300@13 1013 typedef Value &reference;
rt300@13 1014 typedef Value *pointer;
rt300@13 1015 typedef ValueIterator SelfType;
rt300@13 1016
rt300@13 1017 ValueIterator();
rt300@13 1018 ValueIterator( const ValueConstIterator &other );
rt300@13 1019 ValueIterator( const ValueIterator &other );
rt300@13 1020 private:
rt300@13 1021 /*! \internal Use by Value to create an iterator.
rt300@13 1022 */
rt300@13 1023 #ifndef JSON_VALUE_USE_INTERNAL_MAP
rt300@13 1024 explicit ValueIterator( const Value::ObjectValues::iterator &current );
rt300@13 1025 #else
rt300@13 1026 ValueIterator( const ValueInternalArray::IteratorState &state );
rt300@13 1027 ValueIterator( const ValueInternalMap::IteratorState &state );
rt300@13 1028 #endif
rt300@13 1029 public:
rt300@13 1030
rt300@13 1031 SelfType &operator =( const SelfType &other );
rt300@13 1032
rt300@13 1033 SelfType operator++( int )
rt300@13 1034 {
rt300@13 1035 SelfType temp( *this );
rt300@13 1036 ++*this;
rt300@13 1037 return temp;
rt300@13 1038 }
rt300@13 1039
rt300@13 1040 SelfType operator--( int )
rt300@13 1041 {
rt300@13 1042 SelfType temp( *this );
rt300@13 1043 --*this;
rt300@13 1044 return temp;
rt300@13 1045 }
rt300@13 1046
rt300@13 1047 SelfType &operator--()
rt300@13 1048 {
rt300@13 1049 decrement();
rt300@13 1050 return *this;
rt300@13 1051 }
rt300@13 1052
rt300@13 1053 SelfType &operator++()
rt300@13 1054 {
rt300@13 1055 increment();
rt300@13 1056 return *this;
rt300@13 1057 }
rt300@13 1058
rt300@13 1059 reference operator *() const
rt300@13 1060 {
rt300@13 1061 return deref();
rt300@13 1062 }
rt300@13 1063 };
rt300@13 1064
rt300@13 1065
rt300@13 1066 } // namespace Json
rt300@13 1067
rt300@13 1068
rt300@13 1069 #endif // CPPTL_JSON_H_INCLUDED