annotate json/value.h @ 52:89944ab3e129 tip

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