As shown in [Usage at a glance](../readme.md#usage-at-a-glance), a JSON text can be parsed into DOM, and then the DOM can be queried and modfied easily, and finally be converted back to JSON text.
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.
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.
In the following, details about querying individual types are discussed.
By default, `SizeType` is typedef of `unsigned`. In most systems, array is limited to store up to 2^32-1 elements.
You may access the elements in array by integer literal, for example, `a[1]`, `a[2]`. However, `a[0]` will generate a compiler error. It is because two overloaded operators `operator[](SizeType)` and `operator[](const char*)` is avaliable, and C++ can treat `0` as a null pointer. Workarounds:
*`a[SizeType(0)]`
*`a[0u]`
Array is similar to `std::vector`, instead of using indices, you may also use iterator to access all the elements.
```cpp
for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
Note that, when `operator[](const char*)` cannot find the member, it will fail an assertion.
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:
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() == ture`. But a value `y` containing -3000000000 will only makes `x.IsInt64() == true`.
When obtaining the numeric values, `GetDouble()` will convert internal integer representation to a `double`. Note that, `int` and `uint` can be safely convert to `double`, but `int64_t` and `uint64_t` may lose precision (since mantissa of `double` is only 52-bits).
In addition to `GetString()`, the `Value` class also contains `GetStringLength()`. Here explains why.
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.
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.
For example, after parsing a the following JSON string to `Document d`.
```js
{ "s" : "a\u0000b" }
```
The correct length of the value `"a\u0000b"` is 3. But `strlen()` returns 1.
`GetStringLength()` can also improve performance, as user may often need to call `strlen()` for allocating buffer.
Besides, `std::string` also support a constructor:
```cpp
string( const char* s, size_type count);
```
which accepts the length of string as parameter. This constructor supports storing null character within the string, and should also provide better performance.
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,
```cpp
Value a(123);
Value b(456);
b = a; // a becomes a Null value, b becomes number 123.
```

Why? What is the advantage of this semantics?
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.
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.
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.
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()`.
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.
To make memory allocation customizable, RapidJSON requires user to pass an instance of allocator, whenever an operation may require allocation. This design is more flexible than STL's allocator type per class, as we can assign an allocator instance for each allocation.
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.
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.
This tutorial shows the basics of DOM tree query and manipulation. There are several important concepts in RapidJSON:
1. [Streams](stream.md) are channels for reading/writing JSON, which can be a in-memory string, or file stream, etc. Uesr can also create their streams.
2. [Encoding](encoding.md) defines which character set is used in streams and memory. RapidJSON also provide Unicode conversion/validation internally.
3. [DOM](dom.md)'s basics are already covered in this tutorial. Uncover more advanced features such as insitu-parsing, other parsing options and advanced usages.
4. [SAX](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.
5. [Performance](performance.md) shows some in-house and thirdparty benchmarks.
6. [Implementation](implementation.md) describes some internal designs and techniques of RapidJSON.
You may also refer to the FAQ, API documentation, examples and unit tests.