fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / rapidjson-1.1.0 / doc / tutorial.md
1 # Tutorial
2
3 This tutorial introduces the basics of the Document Object Model(DOM) API.
4
5 As shown in [Usage at a glance](@ref index), a JSON can be parsed into DOM, and then the DOM can be queried and modified easily, and finally be converted back to JSON.
6
7 [TOC]
8
9 # Value & Document {#ValueDocument}
10
11 Each JSON value is stored in a type called `Value`. A `Document`, representing the DOM, contains the root `Value` of the DOM tree. All public types and functions of RapidJSON are defined in the `rapidjson` namespace.
12
13 # Query Value {#QueryValue}
14
15 In this section, we will use excerpt of `example/tutorial/tutorial.cpp`.
16
17 Assumes we have a JSON stored in a C string (`const char* json`):
18 ~~~~~~~~~~js
19 {
20     "hello": "world",
21     "t": true ,
22     "f": false,
23     "n": null,
24     "i": 123,
25     "pi": 3.1416,
26     "a": [1, 2, 3, 4]
27 }
28 ~~~~~~~~~~
29
30 Parse it into a `Document`:
31 ~~~~~~~~~~cpp
32 #include "rapidjson/document.h"
33
34 using namespace rapidjson;
35
36 // ...
37 Document document;
38 document.Parse(json);
39 ~~~~~~~~~~
40
41 The JSON is now parsed into `document` as a *DOM tree*:
42
43 ![DOM in the tutorial](diagram/tutorial.png)
44
45 Since the update to RFC 7159, the root of a conforming JSON document can be any JSON value.  In earlier RFC 4627, only objects or arrays were allowed as root values. In this case, the root is an object.
46 ~~~~~~~~~~cpp
47 assert(document.IsObject());
48 ~~~~~~~~~~
49
50 Let's query whether a `"hello"` member exists in the root object. Since a `Value` can contain different types of value, we may need to verify its type and use suitable API to obtain the value. In this example, `"hello"` member associates with a JSON string.
51 ~~~~~~~~~~cpp
52 assert(document.HasMember("hello"));
53 assert(document["hello"].IsString());
54 printf("hello = %s\n", document["hello"].GetString());
55 ~~~~~~~~~~
56
57 ~~~~~~~~~~
58 world
59 ~~~~~~~~~~
60
61 JSON true/false values are represented as `bool`.
62 ~~~~~~~~~~cpp
63 assert(document["t"].IsBool());
64 printf("t = %s\n", document["t"].GetBool() ? "true" : "false");
65 ~~~~~~~~~~
66
67 ~~~~~~~~~~
68 true
69 ~~~~~~~~~~
70
71 JSON null can be queryed by `IsNull()`.
72 ~~~~~~~~~~cpp
73 printf("n = %s\n", document["n"].IsNull() ? "null" : "?");
74 ~~~~~~~~~~
75
76 ~~~~~~~~~~
77 null
78 ~~~~~~~~~~
79
80 JSON number type represents all numeric values. However, C++ needs more specific type for manipulation.
81
82 ~~~~~~~~~~cpp
83 assert(document["i"].IsNumber());
84
85 // In this case, IsUint()/IsInt64()/IsUInt64() also return true.
86 assert(document["i"].IsInt());          
87 printf("i = %d\n", document["i"].GetInt());
88 // Alternative (int)document["i"]
89
90 assert(document["pi"].IsNumber());
91 assert(document["pi"].IsDouble());
92 printf("pi = %g\n", document["pi"].GetDouble());
93 ~~~~~~~~~~
94
95 ~~~~~~~~~~
96 i = 123
97 pi = 3.1416
98 ~~~~~~~~~~
99
100 JSON array contains a number of elements.
101 ~~~~~~~~~~cpp
102 // Using a reference for consecutive access is handy and faster.
103 const Value& a = document["a"];
104 assert(a.IsArray());
105 for (SizeType i = 0; i < a.Size(); i++) // Uses SizeType instead of size_t
106         printf("a[%d] = %d\n", i, a[i].GetInt());
107 ~~~~~~~~~~
108
109 ~~~~~~~~~~
110 a[0] = 1
111 a[1] = 2
112 a[2] = 3
113 a[3] = 4
114 ~~~~~~~~~~
115
116 Note that, RapidJSON does not automatically convert values between JSON types. If a value is a string, it is invalid to call `GetInt()`, for example. In debug mode it will fail an assertion. In release mode, the behavior is undefined.
117
118 In the following, details about querying individual types are discussed.
119
120 ## Query Array {#QueryArray}
121
122 By default, `SizeType` is typedef of `unsigned`. In most systems, array is limited to store up to 2^32-1 elements.
123
124 You may access the elements in array by integer literal, for example, `a[0]`, `a[1]`, `a[2]`.
125
126 Array is similar to `std::vector`, instead of using indices, you may also use iterator to access all the elements.
127 ~~~~~~~~~~cpp
128 for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
129     printf("%d ", itr->GetInt());
130 ~~~~~~~~~~
131
132 And other familiar query functions:
133 * `SizeType Capacity() const`
134 * `bool Empty() const`
135
136 ### Range-based For Loop (New in v1.1.0)
137
138 When C++11 is enabled, you can use range-based for loop to access all elements in an array.
139
140 ~~~~~~~~~~cpp
141 for (auto& v : a.GetArray())
142     printf("%d ", v.GetInt());
143 ~~~~~~~~~~
144
145 ## Query Object {#QueryObject}
146
147 Similar to array, we can access all object members by iterator:
148
149 ~~~~~~~~~~cpp
150 static const char* kTypeNames[] = 
151     { "Null", "False", "True", "Object", "Array", "String", "Number" };
152
153 for (Value::ConstMemberIterator itr = document.MemberBegin();
154     itr != document.MemberEnd(); ++itr)
155 {
156     printf("Type of member %s is %s\n",
157         itr->name.GetString(), kTypeNames[itr->value.GetType()]);
158 }
159 ~~~~~~~~~~
160
161 ~~~~~~~~~~
162 Type of member hello is String
163 Type of member t is True
164 Type of member f is False
165 Type of member n is Null
166 Type of member i is Number
167 Type of member pi is Number
168 Type of member a is Array
169 ~~~~~~~~~~
170
171 Note that, when `operator[](const char*)` cannot find the member, it will fail an assertion.
172
173 If we are unsure whether a member exists, we need to call `HasMember()` before calling `operator[](const char*)`. However, this incurs two lookup. A better way is to call `FindMember()`, which can check the existence of member and obtain its value at once:
174
175 ~~~~~~~~~~cpp
176 Value::ConstMemberIterator itr = document.FindMember("hello");
177 if (itr != document.MemberEnd())
178     printf("%s\n", itr->value.GetString());
179 ~~~~~~~~~~
180
181 ### Range-based For Loop (New in v1.1.0)
182
183 When C++11 is enabled, you can use range-based for loop to access all members in an object.
184
185 ~~~~~~~~~~cpp
186 for (auto& m : document.GetObject())
187     printf("Type of member %s is %s\n",
188         m.name.GetString(), kTypeNames[m.value.GetType()]);
189 ~~~~~~~~~~
190
191 ## Querying Number {#QueryNumber}
192
193 JSON provide a single numerical type called Number. Number can be integer or real numbers. RFC 4627 says the range of Number is specified by parser.
194
195 As C++ provides several integer and floating point number types, the DOM tries to handle these with widest possible range and good performance.
196
197 When a Number is parsed, it is stored in the DOM as either one of the following type:
198
199 Type       | Description
200 -----------|---------------------------------------
201 `unsigned` | 32-bit unsigned integer
202 `int`      | 32-bit signed integer
203 `uint64_t` | 64-bit unsigned integer
204 `int64_t`  | 64-bit signed integer
205 `double`   | 64-bit double precision floating point
206
207 When querying a number, you can check whether the number can be obtained as target type:
208
209 Checking          | Obtaining
210 ------------------|---------------------
211 `bool IsNumber()` | N/A
212 `bool IsUint()`   | `unsigned GetUint()`
213 `bool IsInt()`    | `int GetInt()`
214 `bool IsUint64()` | `uint64_t GetUint64()`
215 `bool IsInt64()`  | `int64_t GetInt64()`
216 `bool IsDouble()` | `double GetDouble()`
217
218 Note that, an integer value may be obtained in various ways without conversion. For example, A value `x` containing 123 will make `x.IsInt() == x.IsUint() == x.IsInt64() == x.IsUint64() == true`. But a value `y` containing -3000000000 will only makes `x.IsInt64() == true`.
219
220 When obtaining the numeric values, `GetDouble()` will convert internal integer representation to a `double`. Note that, `int` and `unsigned` can be safely convert to `double`, but `int64_t` and `uint64_t` may lose precision (since mantissa of `double` is only 52-bits).
221
222 ## Query String {#QueryString}
223
224 In addition to `GetString()`, the `Value` class also contains `GetStringLength()`. Here explains why.
225
226 According to RFC 4627, JSON strings can contain Unicode character `U+0000`, which must be escaped as `"\u0000"`. The problem is that, C/C++ often uses null-terminated string, which treats ``\0'` as the terminator symbol.
227
228 To conform RFC 4627, RapidJSON supports string containing `U+0000`. If you need to handle this, you can use `GetStringLength()` API to obtain the correct length of string.
229
230 For example, after parsing a the following JSON to `Document d`:
231
232 ~~~~~~~~~~js
233 { "s" :  "a\u0000b" }
234 ~~~~~~~~~~
235 The correct length of the value `"a\u0000b"` is 3. But `strlen()` returns 1.
236
237 `GetStringLength()` can also improve performance, as user may often need to call `strlen()` for allocating buffer.
238
239 Besides, `std::string` also support a constructor:
240
241 ~~~~~~~~~~cpp
242 string(const char* s, size_t count);
243 ~~~~~~~~~~
244
245 which accepts the length of string as parameter. This constructor supports storing null character within the string, and should also provide better performance.
246
247 ## Comparing values
248
249 You can use `==` and `!=` to compare values. Two values are equal if and only if they are have same type and contents. You can also compare values with primitive types. Here is an example.
250
251 ~~~~~~~~~~cpp
252 if (document["hello"] == document["n"]) /*...*/;    // Compare values
253 if (document["hello"] == "world") /*...*/;          // Compare value with literal string
254 if (document["i"] != 123) /*...*/;                  // Compare with integers
255 if (document["pi"] != 3.14) /*...*/;                // Compare with double.
256 ~~~~~~~~~~
257
258 Array/object compares their elements/members in order. They are equal if and only if their whole subtrees are equal.
259
260 Note that, currently if an object contains duplicated named member, comparing equality with any object is always `false`.
261
262 # Create/Modify Values {#CreateModifyValues}
263
264 There are several ways to create values. After a DOM tree is created and/or modified, it can be saved as JSON again using `Writer`.
265
266 ## Change Value Type {#ChangeValueType}
267 When creating a Value or Document by default constructor, its type is Null. To change its type, call `SetXXX()` or assignment operator, for example:
268
269 ~~~~~~~~~~cpp
270 Document d; // Null
271 d.SetObject();
272
273 Value v;    // Null
274 v.SetInt(10);
275 v = 10;     // Shortcut, same as above
276 ~~~~~~~~~~
277
278 ### Overloaded Constructors
279 There are also overloaded constructors for several types:
280
281 ~~~~~~~~~~cpp
282 Value b(true);    // calls Value(bool)
283 Value i(-123);    // calls Value(int)
284 Value u(123u);    // calls Value(unsigned)
285 Value d(1.5);     // calls Value(double)
286 ~~~~~~~~~~
287
288 To create empty object or array, you may use `SetObject()`/`SetArray()` after default constructor, or using the `Value(Type)` in one shot:
289
290 ~~~~~~~~~~cpp
291 Value o(kObjectType);
292 Value a(kArrayType);
293 ~~~~~~~~~~
294
295 ## Move Semantics {#MoveSemantics}
296
297 A very special decision during design of RapidJSON is that, assignment of value does not copy the source value to destination value. Instead, the value from source is moved to the destination. For example,
298
299 ~~~~~~~~~~cpp
300 Value a(123);
301 Value b(456);
302 b = a;         // a becomes a Null value, b becomes number 123.
303 ~~~~~~~~~~
304
305 ![Assignment with move semantics.](diagram/move1.png)
306
307 Why? What is the advantage of this semantics?
308
309 The simple answer is performance. For fixed size JSON types (Number, True, False, Null), copying them is fast and easy. However, For variable size JSON types (String, Array, Object), copying them will incur a lot of overheads. And these overheads are often unnoticed. Especially when we need to create temporary object, copy it to another variable, and then destruct it.
310
311 For example, if normal *copy* semantics was used:
312
313 ~~~~~~~~~~cpp
314 Document d;
315 Value o(kObjectType);
316 {
317     Value contacts(kArrayType);
318     // adding elements to contacts array.
319     // ...
320     o.AddMember("contacts", contacts, d.GetAllocator());  // deep clone contacts (may be with lots of allocations)
321     // destruct contacts.
322 }
323 ~~~~~~~~~~
324
325 ![Copy semantics makes a lots of copy operations.](diagram/move2.png)
326
327 The object `o` needs to allocate a buffer of same size as contacts, makes a deep clone of it, and then finally contacts is destructed. This will incur a lot of unnecessary allocations/deallocations and memory copying.
328
329 There are solutions to prevent actual copying these data, such as reference counting and garbage collection(GC).
330
331 To make RapidJSON simple and fast, we chose to use *move* semantics for assignment. It is similar to `std::auto_ptr` which transfer ownership during assignment. Move is much faster and simpler, it just destructs the original value, `memcpy()` the source to destination, and finally sets the source as Null type.
332
333 So, with move semantics, the above example becomes:
334
335 ~~~~~~~~~~cpp
336 Document d;
337 Value o(kObjectType);
338 {
339     Value contacts(kArrayType);
340     // adding elements to contacts array.
341     o.AddMember("contacts", contacts, d.GetAllocator());  // just memcpy() of contacts itself to the value of new member (16 bytes)
342     // contacts became Null here. Its destruction is trivial.
343 }
344 ~~~~~~~~~~
345
346 ![Move semantics makes no copying.](diagram/move3.png)
347
348 This is called move assignment operator in C++11. As RapidJSON supports C++03, it adopts move semantics using assignment operator, and all other modifying function like `AddMember()`, `PushBack()`.
349
350 ### Move semantics and temporary values {#TemporaryValues}
351
352 Sometimes, it is convenient to construct a Value in place, before passing it to one of the "moving" functions, like `PushBack()` or `AddMember()`.  As temporary objects can't be converted to proper Value references, the convenience function `Move()` is available:
353
354 ~~~~~~~~~~cpp
355 Value a(kArrayType);
356 Document::AllocatorType& allocator = document.GetAllocator();
357 // a.PushBack(Value(42), allocator);       // will not compile
358 a.PushBack(Value().SetInt(42), allocator); // fluent API
359 a.PushBack(Value(42).Move(), allocator);   // same as above
360 ~~~~~~~~~~
361
362 ## Create String {#CreateString}
363 RapidJSON provide two strategies for storing string.
364
365 1. copy-string: allocates a buffer, and then copy the source data into it.
366 2. const-string: simply store a pointer of string.
367
368 Copy-string is always safe because it owns a copy of the data. Const-string can be used for storing string literal, and in-situ parsing which we will mentioned in Document section.
369
370 To make memory allocation customizable, RapidJSON requires user to pass an instance of allocator, whenever an operation may require allocation. This design is needed to prevent storing a allocator (or Document) pointer per Value.
371
372 Therefore, when we assign a copy-string, we call this overloaded `SetString()` with allocator:
373
374 ~~~~~~~~~~cpp
375 Document document;
376 Value author;
377 char buffer[10];
378 int len = sprintf(buffer, "%s %s", "Milo", "Yip"); // dynamically created string.
379 author.SetString(buffer, len, document.GetAllocator());
380 memset(buffer, 0, sizeof(buffer));
381 // author.GetString() still contains "Milo Yip" after buffer is destroyed
382 ~~~~~~~~~~
383
384 In this example, we get the allocator from a `Document` instance. This is a common idiom when using RapidJSON. But you may use other instances of allocator.
385
386 Besides, the above `SetString()` requires length. This can handle null characters within a string. There is another `SetString()` overloaded function without the length parameter. And it assumes the input is null-terminated and calls a `strlen()`-like function to obtain the length.
387
388 Finally, for string literal or string with safe life-cycle can use const-string version of `SetString()`, which lacks allocator parameter.  For string literals (or constant character arrays), simply passing the literal as parameter is safe and efficient:
389
390 ~~~~~~~~~~cpp
391 Value s;
392 s.SetString("rapidjson");    // can contain null character, length derived at compile time
393 s = "rapidjson";             // shortcut, same as above
394 ~~~~~~~~~~
395
396 For character pointer, the RapidJSON requires to mark it as safe before using it without copying. This can be achieved by using the `StringRef` function:
397
398 ~~~~~~~~~cpp
399 const char * cstr = getenv("USER");
400 size_t cstr_len = ...;                 // in case length is available
401 Value s;
402 // s.SetString(cstr);                  // will not compile
403 s.SetString(StringRef(cstr));          // ok, assume safe lifetime, null-terminated
404 s = StringRef(cstr);                   // shortcut, same as above
405 s.SetString(StringRef(cstr,cstr_len)); // faster, can contain null character
406 s = StringRef(cstr,cstr_len);          // shortcut, same as above
407
408 ~~~~~~~~~
409
410 ## Modify Array {#ModifyArray}
411 Value with array type provides similar APIs as `std::vector`.
412
413 * `Clear()`
414 * `Reserve(SizeType, Allocator&)`
415 * `Value& PushBack(Value&, Allocator&)`
416 * `template <typename T> GenericValue& PushBack(T, Allocator&)`
417 * `Value& PopBack()`
418 * `ValueIterator Erase(ConstValueIterator pos)`
419 * `ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)`
420
421 Note that, `Reserve(...)` and `PushBack(...)` may allocate memory for the array elements, therefore require an allocator.
422
423 Here is an example of `PushBack()`:
424
425 ~~~~~~~~~~cpp
426 Value a(kArrayType);
427 Document::AllocatorType& allocator = document.GetAllocator();
428
429 for (int i = 5; i <= 10; i++)
430     a.PushBack(i, allocator);   // allocator is needed for potential realloc().
431
432 // Fluent interface
433 a.PushBack("Lua", allocator).PushBack("Mio", allocator);
434 ~~~~~~~~~~
435
436 Differs from STL, `PushBack()`/`PopBack()` returns the array reference itself. This is called _fluent interface_.
437
438 If you want to add a non-constant string or a string without sufficient lifetime (see [Create String](#CreateString)) to the array, you need to create a string Value by using the copy-string API.  To avoid the need for an intermediate variable, you can use a [temporary value](#TemporaryValues) in place:
439
440 ~~~~~~~~~~cpp
441 // in-place Value parameter
442 contact.PushBack(Value("copy", document.GetAllocator()).Move(), // copy string
443                  document.GetAllocator());
444
445 // explicit parameters
446 Value val("key", document.GetAllocator()); // copy string
447 contact.PushBack(val, document.GetAllocator());
448 ~~~~~~~~~~
449
450 ## Modify Object {#ModifyObject}
451 Object is a collection of key-value pairs (members). Each key must be a string value. To modify an object, either add or remove members. THe following APIs are for adding members:
452
453 * `Value& AddMember(Value&, Value&, Allocator& allocator)`
454 * `Value& AddMember(StringRefType, Value&, Allocator&)`
455 * `template <typename T> Value& AddMember(StringRefType, T value, Allocator&)`
456
457 Here is an example.
458
459 ~~~~~~~~~~cpp
460 Value contact(kObject);
461 contact.AddMember("name", "Milo", document.GetAllocator());
462 contact.AddMember("married", true, document.GetAllocator());
463 ~~~~~~~~~~
464
465 The name parameter with `StringRefType` is similar to the interface of `SetString` function for string values. These overloads are used to avoid the need for copying the `name` string, as constant key names are very common in JSON objects.
466
467 If you need to create a name from a non-constant string or a string without sufficient lifetime (see [Create String](#CreateString)), you need to create a string Value by using the copy-string API.  To avoid the need for an intermediate variable, you can use a [temporary value](#TemporaryValues) in place:
468
469 ~~~~~~~~~~cpp
470 // in-place Value parameter
471 contact.AddMember(Value("copy", document.GetAllocator()).Move(), // copy string
472                   Value().Move(),                                // null value
473                   document.GetAllocator());
474
475 // explicit parameters
476 Value key("key", document.GetAllocator()); // copy string name
477 Value val(42);                             // some value
478 contact.AddMember(key, val, document.GetAllocator());
479 ~~~~~~~~~~
480
481 For removing members, there are several choices: 
482
483 * `bool RemoveMember(const Ch* name)`: Remove a member by search its name (linear time complexity).
484 * `bool RemoveMember(const Value& name)`: same as above but `name` is a Value.
485 * `MemberIterator RemoveMember(MemberIterator)`: Remove a member by iterator (_constant_ time complexity).
486 * `MemberIterator EraseMember(MemberIterator)`: similar to the above but it preserves order of members (linear time complexity).
487 * `MemberIterator EraseMember(MemberIterator first, MemberIterator last)`: remove a range of members, preserves order (linear time complexity).
488
489 `MemberIterator RemoveMember(MemberIterator)` uses a "move-last" trick to achieve constant time complexity. Basically the member at iterator is destructed, and then the last element is moved to that position. So the order of the remaining members are changed.
490
491 ## Deep Copy Value {#DeepCopyValue}
492 If we really need to copy a DOM tree, we can use two APIs for deep copy: constructor with allocator, and `CopyFrom()`.
493
494 ~~~~~~~~~~cpp
495 Document d;
496 Document::AllocatorType& a = d.GetAllocator();
497 Value v1("foo");
498 // Value v2(v1); // not allowed
499
500 Value v2(v1, a);                      // make a copy
501 assert(v1.IsString());                // v1 untouched
502 d.SetArray().PushBack(v1, a).PushBack(v2, a);
503 assert(v1.IsNull() && v2.IsNull());   // both moved to d
504
505 v2.CopyFrom(d, a);                    // copy whole document to v2
506 assert(d.IsArray() && d.Size() == 2); // d untouched
507 v1.SetObject().AddMember("array", v2, a);
508 d.PushBack(v1, a);
509 ~~~~~~~~~~
510
511 ## Swap Values {#SwapValues}
512
513 `Swap()` is also provided.
514
515 ~~~~~~~~~~cpp
516 Value a(123);
517 Value b("Hello");
518 a.Swap(b);
519 assert(a.IsString());
520 assert(b.IsInt());
521 ~~~~~~~~~~
522
523 Swapping two DOM trees is fast (constant time), despite the complexity of the trees.
524
525 # What's next {#WhatsNext}
526
527 This tutorial shows the basics of DOM tree query and manipulation. There are several important concepts in RapidJSON:
528
529 1. [Streams](doc/stream.md) are channels for reading/writing JSON, which can be a in-memory string, or file stream, etc. User can also create their streams.
530 2. [Encoding](doc/encoding.md) defines which character encoding is used in streams and memory. RapidJSON also provide Unicode conversion/validation internally.
531 3. [DOM](doc/dom.md)'s basics are already covered in this tutorial. Uncover more advanced features such as *in situ* parsing, other parsing options and advanced usages.
532 4. [SAX](doc/sax.md) is the foundation of parsing/generating facility in RapidJSON. Learn how to use `Reader`/`Writer` to implement even faster applications. Also try `PrettyWriter` to format the JSON.
533 5. [Performance](doc/performance.md) shows some in-house and third-party benchmarks.
534 6. [Internals](doc/internals.md) describes some internal designs and techniques of RapidJSON.
535
536 You may also refer to the [FAQ](doc/faq.md), API documentation, examples and unit tests.