Welcome to mirror list, hosted at ThFree Co, Russian Federation.

md_doc_pointer.html - github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3afd0d194b9bd3523b9e927a241536a7017b5d49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
<!-- HTML header for doxygen 1.8.7-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.7"/>
<title>RapidJSON: Pointer</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygenextra.css" rel="stylesheet" type="text/css"/>
</head>
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'UA-63929386-1', 'auto');
  ga('send', 'pageview');
</script>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="topbanner"><a href="https://github.com/miloyip/rapidjson" title="RapidJSON GitHub"><i class="githublogo"></i></a></div>
        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.7 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('md_doc_pointer.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark">&#160;</span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(11)"><span class="SelectionMark">&#160;</span>Groups</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(12)"><span class="SelectionMark">&#160;</span>Pages</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">Pointer </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#JsonPointer">JSON Pointer</a></li>
<li class="level1"><a href="#BasicUsage">Basic Usage</a></li>
<li class="level1"><a href="#HelperFunctions">Helper Functions</a></li>
<li class="level1"><a href="#ResolvingPointer">Resolving Pointer</a></li>
<li class="level1"><a href="#ErrorHandling">Error Handling</a></li>
<li class="level1"><a href="#URIFragment">URI Fragment Representation</a></li>
<li class="level1"><a href="#UserSuppliedTokens">User-Supplied Tokens</a></li>
</ul>
</div>
<div class="textblock"><h2>Status: experimental, shall be included in v1.1</h2>
<p>JSON Pointer is a standardized (<a href="https://tools.ietf.org/html/rfc6901">RFC6901</a>) way to select a value inside a JSON Document (DOM). This can be analogous to XPath for XML document. However, JSON Pointer is much simpler, and a single JSON Pointer only pointed to a single value.</p>
<p>Using RapidJSON's implementation of JSON Pointer can simplify some manipulations of the DOM.</p>
<h1><a class="anchor" id="JsonPointer"></a>
JSON Pointer</h1>
<p>A JSON Pointer is a list of zero-to-many tokens, each prefixed by <code>/</code>. Each token can be a string or a number. For example, given a JSON: </p><div class="fragment"><div class="line">{</div>
<div class="line">    <span class="stringliteral">&quot;foo&quot;</span> : [<span class="stringliteral">&quot;bar&quot;</span>, <span class="stringliteral">&quot;baz&quot;</span>],</div>
<div class="line">    <span class="stringliteral">&quot;pi&quot;</span> : 3.1416</div>
<div class="line">}</div>
</div><!-- fragment --><p>The following JSON Pointers resolve this JSON as:</p>
<ol type="1">
<li><code>"/foo"</code> → <code>[ "bar", "baz" ]</code></li>
<li><code>"/foo/0"</code> → <code>"bar"</code></li>
<li><code>"/foo/1"</code> → <code>"baz"</code></li>
<li><code>"/pi"</code> → <code>3.1416</code></li>
</ol>
<p>Note that, an empty JSON Pointer <code>""</code> (zero token) resolves to the whole JSON.</p>
<h1><a class="anchor" id="BasicUsage"></a>
Basic Usage</h1>
<p>The following example code is self-explanatory.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;rapidjson/pointer.h&quot;</span></div>
<div class="line"></div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><a class="code" href="namespacerapidjson.html#a660c934c2959121babf799b6cb206659">Document</a> d;</div>
<div class="line"></div>
<div class="line"><span class="comment">// Create DOM by Set()</span></div>
<div class="line"><a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a>(<span class="stringliteral">&quot;/project&quot;</span>).Set(d, <span class="stringliteral">&quot;RapidJSON&quot;</span>);</div>
<div class="line"><a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a>(<span class="stringliteral">&quot;/stars&quot;</span>).Set(d, 10);</div>
<div class="line"></div>
<div class="line"><span class="comment">// { &quot;project&quot; : &quot;RapidJSON&quot;, &quot;stars&quot; : 10 }</span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Access DOM by Get(). It return nullptr if the value does not exist.</span></div>
<div class="line"><span class="keywordflow">if</span> (<a class="code" href="namespacerapidjson.html#afb3fa116c66d834b6f4289d648cc8d6d">Value</a>* stars = <a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a>(<span class="stringliteral">&quot;/stars&quot;</span>).Get(d))</div>
<div class="line">    stars-&gt;SetInt(stars-&gt;GetInt() + 1);</div>
<div class="line"></div>
<div class="line"><span class="comment">// { &quot;project&quot; : &quot;RapidJSON&quot;, &quot;stars&quot; : 11 }</span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Set() and Create() automatically generate parents if not exist.</span></div>
<div class="line"><a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a>(<span class="stringliteral">&quot;/a/b/0&quot;</span>).Create(d);</div>
<div class="line"></div>
<div class="line"><span class="comment">// { &quot;project&quot; : &quot;RapidJSON&quot;, &quot;stars&quot; : 11, &quot;a&quot; : { &quot;b&quot; : [ null ] } }</span></div>
<div class="line"></div>
<div class="line"><span class="comment">// GetWithDefault() returns reference. And it deep clones the default value.</span></div>
<div class="line"><a class="code" href="namespacerapidjson.html#afb3fa116c66d834b6f4289d648cc8d6d">Value</a>&amp; hello = <a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a>(<span class="stringliteral">&quot;/hello&quot;</span>).GetWithDefault(d, <span class="stringliteral">&quot;world&quot;</span>);</div>
<div class="line"></div>
<div class="line"><span class="comment">// { &quot;project&quot; : &quot;RapidJSON&quot;, &quot;stars&quot; : 11, &quot;a&quot; : { &quot;b&quot; : [ null ] }, &quot;hello&quot; : &quot;world&quot; }</span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Swap() is similar to Set()</span></div>
<div class="line"><a class="code" href="namespacerapidjson.html#afb3fa116c66d834b6f4289d648cc8d6d">Value</a> x(<span class="stringliteral">&quot;C++&quot;</span>);</div>
<div class="line"><a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a>(<span class="stringliteral">&quot;/hello&quot;</span>).Swap(d, x);</div>
<div class="line"></div>
<div class="line"><span class="comment">// { &quot;project&quot; : &quot;RapidJSON&quot;, &quot;stars&quot; : 11, &quot;a&quot; : { &quot;b&quot; : [ null ] }, &quot;hello&quot; : &quot;C++&quot; }</span></div>
<div class="line"><span class="comment">// x becomes &quot;world&quot;</span></div>
<div class="line"></div>
<div class="line"><span class="comment">// Erase a member or element, return true if the value exists</span></div>
<div class="line"><span class="keywordtype">bool</span> success = <a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a>(<span class="stringliteral">&quot;/a&quot;</span>).Erase(d);</div>
<div class="line">assert(success);</div>
<div class="line"></div>
<div class="line"><span class="comment">// { &quot;project&quot; : &quot;RapidJSON&quot;, &quot;stars&quot; : 10 }</span></div>
</div><!-- fragment --><h1><a class="anchor" id="HelperFunctions"></a>
Helper Functions</h1>
<p>Since object-oriented calling convention may be non-intuitive, RapidJSON also provides helper functions, which just wrap the member functions with free-functions.</p>
<p>The following example does exactly the same as the above one.</p>
<div class="fragment"><div class="line"><a class="code" href="namespacerapidjson.html#a660c934c2959121babf799b6cb206659">Document</a> d;</div>
<div class="line"></div>
<div class="line">SetValueByPointer(d, <span class="stringliteral">&quot;/project&quot;</span>, <span class="stringliteral">&quot;RapidJSON&quot;</span>);</div>
<div class="line">SetValueByPointer(d, <span class="stringliteral">&quot;/stars&quot;</span>, 10);</div>
<div class="line"></div>
<div class="line"><span class="keywordflow">if</span> (<a class="code" href="namespacerapidjson.html#afb3fa116c66d834b6f4289d648cc8d6d">Value</a>* stars = GetValueByPointer(d, <span class="stringliteral">&quot;/stars&quot;</span>))</div>
<div class="line">    stars-&gt;SetInt(stars-&gt;GetInt() + 1);</div>
<div class="line"></div>
<div class="line">CreateValueByPointer(d, <span class="stringliteral">&quot;/a/b/0&quot;</span>);</div>
<div class="line"></div>
<div class="line"><a class="code" href="namespacerapidjson.html#afb3fa116c66d834b6f4289d648cc8d6d">Value</a>&amp; hello = GetValueByPointerWithDefault(d, <span class="stringliteral">&quot;/hello&quot;</span>, <span class="stringliteral">&quot;world&quot;</span>);</div>
<div class="line"></div>
<div class="line"><a class="code" href="namespacerapidjson.html#afb3fa116c66d834b6f4289d648cc8d6d">Value</a> x(<span class="stringliteral">&quot;C++&quot;</span>);</div>
<div class="line">SwapValueByPointer(d, <span class="stringliteral">&quot;/hello&quot;</span>, x);</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">bool</span> success = EraseValueByPointer(d, <span class="stringliteral">&quot;/a&quot;</span>);</div>
<div class="line">assert(success);</div>
</div><!-- fragment --><p>The conventions are shown here for comparison:</p>
<ol type="1">
<li><code>Pointer(source).&lt;Method&gt;(root, ...)</code></li>
<li><code>&lt;Method&gt;ValueByPointer(root, Pointer(source), ...)</code></li>
<li><code>&lt;Method&gt;ValueByPointer(root, source, ...)</code></li>
</ol>
<h1><a class="anchor" id="ResolvingPointer"></a>
Resolving Pointer</h1>
<p><code>Pointer::Get()</code> or <code>GetValueByPointer()</code> function does not modify the DOM. If the tokens cannot match a value in the DOM, it returns <code>nullptr</code>. User can use this to check whether a value exists.</p>
<p>Note that, numerical tokens can represent an array index or member name. The resolving process will match the values according to the types of value.</p>
<div class="fragment"><div class="line">{</div>
<div class="line">    <span class="stringliteral">&quot;0&quot;</span> : 123,</div>
<div class="line">    <span class="stringliteral">&quot;1&quot;</span> : [456]</div>
<div class="line">}</div>
</div><!-- fragment --><ol type="1">
<li><code>"/0"</code> → <code>123</code></li>
<li><code>"/1/0"</code> → <code>456</code></li>
</ol>
<p>The token <code>"0"</code> is treated as member name in the first pointer. It is treated as an array index in the second pointer.</p>
<p>The other functions, including <code>Create()</code>, <code>GetWithDefault()</code>, <code>Set()</code> and <code>Swap()</code>, will change the DOM. These functions will always succeed. They will create the parent values if they do not exist. If the parent values do not match the tokens, they will also be forced to change their type. Changing the type also mean fully removal of that DOM subtree.</p>
<p>Parsing the above JSON into <code>d</code>,</p>
<div class="fragment"><div class="line">SetValueByPointer(d, <span class="stringliteral">&quot;1/a&quot;</span>, 789); <span class="comment">// { &quot;0&quot; : 123, &quot;1&quot; : { &quot;a&quot; : 789 } }</span></div>
</div><!-- fragment --><h2>Resolving Minus Sign Token</h2>
<p>Besides, <a href="https://tools.ietf.org/html/rfc6901">RFC6901</a> defines a special token <code>-</code> (single minus sign), which represents the pass-the-end element of an array. <code>Get()</code> only treats this token as a member name '"-"'. Yet the other functions can resolve this for array, equivalent to calling <code>Value::PushBack()</code> to the array.</p>
<div class="fragment"><div class="line"><a class="code" href="namespacerapidjson.html#a660c934c2959121babf799b6cb206659">Document</a> d;</div>
<div class="line">d.Parse(<span class="stringliteral">&quot;{\&quot;foo\&quot;:[123]}&quot;</span>);</div>
<div class="line">SetValueByPointer(d, <span class="stringliteral">&quot;/foo/-&quot;</span>, 456); <span class="comment">// { &quot;foo&quot; : [123, 456] }</span></div>
<div class="line">SetValueByPointer(d, <span class="stringliteral">&quot;/-&quot;</span>, 789);    <span class="comment">// { &quot;foo&quot; : [123, 456], &quot;-&quot; : 789 }</span></div>
</div><!-- fragment --><h2>Resolving Document and Value</h2>
<p>When using <code>p.Get(root)</code> or <code>GetValueByPointer(root, p)</code>, <code>root</code> is a (const) <code>Value&amp;</code>. That means, it can be a subtree of the DOM.</p>
<p>The other functions have two groups of signature. One group uses <code>Document&amp; document</code> as parameter, another one uses <code>Value&amp; root</code>. The first group uses <code>document.GetAllocator()</code> for creating values. And the second group needs user to supply an allocator, like the functions in DOM.</p>
<p>All examples above do not require an allocator parameter, because the first parameter is a <code>Document&amp;</code>. But if you want to resolve a pointer to a subtree, you need to supply the allocator as in the following example:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>Person {</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">    Person() {</div>
<div class="line">        document_ = <span class="keyword">new</span> <a class="code" href="namespacerapidjson.html#a660c934c2959121babf799b6cb206659">Document</a>();</div>
<div class="line">        <span class="comment">// CreateValueByPointer() here no need allocator</span></div>
<div class="line">        SetLocation(CreateValueByPointer(*document_, <span class="stringliteral">&quot;/residence&quot;</span>), ...);</div>
<div class="line">        SetLocation(CreateValueByPointer(*document_, <span class="stringliteral">&quot;/office&quot;</span>), ...);</div>
<div class="line">    };</div>
<div class="line"></div>
<div class="line"><span class="keyword">private</span>:</div>
<div class="line">    <span class="keywordtype">void</span> SetLocation(<a class="code" href="namespacerapidjson.html#afb3fa116c66d834b6f4289d648cc8d6d">Value</a>&amp; location, <span class="keyword">const</span> <span class="keywordtype">char</span>* country, <span class="keyword">const</span> <span class="keywordtype">char</span>* addresses[2]) {</div>
<div class="line">        Value::Allocator&amp; a = document_-&gt;GetAllocator();</div>
<div class="line">        <span class="comment">// SetValueByPointer() here need allocator</span></div>
<div class="line">        SetValueByPointer(location, <span class="stringliteral">&quot;/country&quot;</span>, country, a);</div>
<div class="line">        SetValueByPointer(location, <span class="stringliteral">&quot;/address/0&quot;</span>, address[0], a);</div>
<div class="line">        SetValueByPointer(location, <span class="stringliteral">&quot;/address/1&quot;</span>, address[1], a);</div>
<div class="line">    }</div>
<div class="line"></div>
<div class="line">    <span class="comment">// ...</span></div>
<div class="line"></div>
<div class="line">    <a class="code" href="namespacerapidjson.html#a660c934c2959121babf799b6cb206659">Document</a>* document_;</div>
<div class="line">};</div>
</div><!-- fragment --><p><code>Erase()</code> or <code>EraseValueByPointer()</code> does not need allocator. And they return <code>true</code> if the value is erased successfully.</p>
<h1><a class="anchor" id="ErrorHandling"></a>
Error Handling</h1>
<p>A <code>Pointer</code> parses a source string in its constructor. If there is parsing error, <code>Pointer::IsValid()</code> returns <code>false</code>. And you can use <code>Pointer::GetParseErrorCode()</code> and <code>GetParseErrorOffset()</code> to retrieve the error information.</p>
<p>Note that, all resolving functions assumes valid pointer. Resolving with an invalid pointer causes assertion failure.</p>
<h1><a class="anchor" id="URIFragment"></a>
URI Fragment Representation</h1>
<p>In addition to the string representation of JSON pointer that we are using till now, <a href="https://tools.ietf.org/html/rfc6901">RFC6901</a> also defines the URI fragment representation of JSON pointer. URI fragment is specified in <a href="https://tools.ietf.org/html/rfc3986">RFC3986</a> "Uniform Resource Identifier (URI): Generic Syntax".</p>
<p>The main differences are that a the URI fragment always has a <code>#</code> (pound sign) in the beginning, and some characters are encoded by percent-encoding in UTF-8 sequence. For example, the following table shows different C/C++ string literals of different representations.</p>
<table class="doxtable">
<tr>
<th>String Representation </th><th>URI Fragment Representation </th><th>Pointer Tokens (UTF-8)  </th></tr>
<tr>
<td><code>"/foo/0"</code> </td><td><code>"#/foo/0"</code> </td><td><code>{"foo", 0}</code> </td></tr>
<tr>
<td><code>"/a~1b"</code> </td><td><code>"#/a~1b"</code> </td><td><code>{"a/b"}</code> </td></tr>
<tr>
<td><code>"/m~0n"</code> </td><td><code>"#/m~0n"</code> </td><td><code>{"m~n"}</code> </td></tr>
<tr>
<td><code>"/ "</code> </td><td><code>"#/%20"</code> </td><td><code>{" "}</code> </td></tr>
<tr>
<td><code>"/\\0"</code> </td><td><code>"#/%00"</code> </td><td><code>{"\\0"}</code> </td></tr>
<tr>
<td><code>"/€"</code> </td><td><code>"#/%E2%82%AC"</code> </td><td><code>{"€"}</code> </td></tr>
</table>
<p>RapidJSON fully support URI fragment representation. It automatically detects the pound sign during parsing.</p>
<h1>Stringify</h1>
<p>You may also stringify a <code>Pointer</code> to a string or other output streams. This can be done by:</p>
<div class="fragment"><div class="line"><a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a> p(...);</div>
<div class="line"><a class="code" href="namespacerapidjson.html#a51a6c35028b76e354bbb9e25d7125641">StringBuffer</a> sb;</div>
<div class="line">p.Stringify(sb);</div>
<div class="line">std::cout &lt;&lt; sb.GetString() &lt;&lt; std::endl;</div>
</div><!-- fragment --><p>It can also stringify to URI fragment reprsentation by <code>StringifyUriFragment()</code>.</p>
<h1><a class="anchor" id="UserSuppliedTokens"></a>
User-Supplied Tokens</h1>
<p>If a pointer will be resolved multiple times, it should be constructed once, and then apply it to different DOMs or in different times. This reduce time and memory allocation for constructing <code>Pointer</code> multiple times.</p>
<p>We can go one step further, to completely eliminate the parsing process and dynamic memory allocation, we can establish the token array directly:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }</span></div>
<div class="line"><span class="preprocessor">#define INDEX(i) { #i, sizeof(#i) - 1, i }</span></div>
<div class="line"></div>
<div class="line"><span class="keyword">static</span> <span class="keyword">const</span> Pointer::Token kTokens[] = { NAME(<span class="stringliteral">&quot;foo&quot;</span>), INDEX(123) };</div>
<div class="line"><span class="keyword">static</span> <span class="keyword">const</span> <a class="code" href="namespacerapidjson.html#a9c225e4848c5facd20e43084ba2a51a3">Pointer</a> p(kTokens, <span class="keyword">sizeof</span>(kTokens) / <span class="keyword">sizeof</span>(kTokens[0]));</div>
<div class="line"><span class="comment">// Equivalent to static const Pointer p(&quot;/foo/123&quot;);</span></div>
</div><!-- fragment --><p>This may be useful for memory constrained systems. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- HTML footer for doxygen 1.8.7-->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
  </ul>
</div>
<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES * * */
    var disqus_shortname = 'rapidjson-doc';
    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
	    var dt = document.createElement('div');
	    dt.id = "disqus_thread";
	    (document.getElementsByClassName('contents')[0]).appendChild(dt);
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
</body>
</html>