blob: a00ffc49065a8a3725909fc9bf60359f9db036f0 [file] [log] [blame]
<!-- 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.16"/>
<title>RapidJSON: SAX</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="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(initResizable);
/* @license-end */</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygenextra.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="topbanner"><a href="https://github.com/Tencent/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.16 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</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">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('md_doc_sax.html','');});
/* @license-end */
</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)">
</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="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">SAX </div> </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#Reader">Reader</a><ul><li class="level2"><a href="#Handler">Handler</a></li>
<li class="level2"><a href="#GenericReader">GenericReader</a></li>
<li class="level2"><a href="#SaxParsing">Parsing</a></li>
<li class="level2"><a href="#TokenByTokenParsing">Token-by-Token Parsing</a></li>
</ul>
</li>
<li class="level1"><a href="#Writer">Writer</a><ul><li class="level2"><a href="#WriterTemplate">Template</a></li>
<li class="level2"><a href="#PrettyWriter">PrettyWriter</a></li>
<li class="level2"><a href="#CompletenessReset">Completeness and Reset</a></li>
</ul>
</li>
<li class="level1"><a href="#SaxTechniques">Techniques</a><ul><li class="level2"><a href="#CustomDataStructure">Parsing JSON to Custom Data Structure</a></li>
<li class="level2"><a href="#Filtering">Filtering of JSON</a></li>
</ul>
</li>
</ul>
</div>
<div class="textblock"><p>The term "SAX" originated from <a href="http://en.wikipedia.org/wiki/Simple_API_for_XML">Simple API for XML</a>. We borrowed this term for JSON parsing and generation.</p>
<p>In RapidJSON, <code>Reader</code> (typedef of <code>GenericReader&lt;...&gt;</code>) is the SAX-style parser for JSON, and <code>Writer</code> (typedef of <code>GenericWriter&lt;...&gt;</code>) is the SAX-style generator for JSON.</p>
<h1><a class="anchor" id="Reader"></a>
Reader</h1>
<p><code>Reader</code> parses a JSON from a stream. While it reads characters from the stream, it analyzes the characters according to the syntax of JSON, and publishes events to a handler.</p>
<p>For example, here is a JSON.</p>
<div class="fragment"><div class="line">{</div>
<div class="line"> &quot;hello&quot;: &quot;world&quot;,</div>
<div class="line"> &quot;t&quot;: true ,</div>
<div class="line"> &quot;f&quot;: false,</div>
<div class="line"> &quot;n&quot;: null,</div>
<div class="line"> &quot;i&quot;: 123,</div>
<div class="line"> &quot;pi&quot;: 3.1416,</div>
<div class="line"> &quot;a&quot;: [1, 2, 3, 4]</div>
<div class="line">}</div>
</div><!-- fragment --><p>When a <code>Reader</code> parses this JSON, it publishes the following events to the handler sequentially:</p>
<div class="fragment"><div class="line">StartObject()</div>
<div class="line">Key(&quot;hello&quot;, 5, true)</div>
<div class="line">String(&quot;world&quot;, 5, true)</div>
<div class="line">Key(&quot;t&quot;, 1, true)</div>
<div class="line">Bool(true)</div>
<div class="line">Key(&quot;f&quot;, 1, true)</div>
<div class="line">Bool(false)</div>
<div class="line">Key(&quot;n&quot;, 1, true)</div>
<div class="line">Null()</div>
<div class="line">Key(&quot;i&quot;)</div>
<div class="line">Uint(123)</div>
<div class="line">Key(&quot;pi&quot;)</div>
<div class="line">Double(3.1416)</div>
<div class="line">Key(&quot;a&quot;)</div>
<div class="line">StartArray()</div>
<div class="line">Uint(1)</div>
<div class="line">Uint(2)</div>
<div class="line">Uint(3)</div>
<div class="line">Uint(4)</div>
<div class="line">EndArray(4)</div>
<div class="line">EndObject(7)</div>
</div><!-- fragment --><p>These events can be easily matched with the JSON, but some event parameters need further explanation. Let's see the <code>simplereader</code> example which produces exactly the same output as above:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="reader_8h.html">rapidjson/reader.h</a>&quot;</span></div>
<div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">using namespace </span><a class="code" href="namespacerapidjson.html">rapidjson</a>;</div>
<div class="line"><span class="keyword">using namespace </span>std;</div>
<div class="line"> </div>
<div class="line"><span class="keyword">struct </span>MyHandler : <span class="keyword">public</span> <a class="code" href="structrapidjson_1_1_base_reader_handler.html">BaseReaderHandler</a>&lt;UTF8&lt;&gt;, MyHandler&gt; {</div>
<div class="line"> <span class="keywordtype">bool</span> Null() { cout &lt;&lt; <span class="stringliteral">&quot;Null()&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> Bool(<span class="keywordtype">bool</span> b) { cout &lt;&lt; <span class="stringliteral">&quot;Bool(&quot;</span> &lt;&lt; boolalpha &lt;&lt; b &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> Int(<span class="keywordtype">int</span> i) { cout &lt;&lt; <span class="stringliteral">&quot;Int(&quot;</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> Uint(<span class="keywordtype">unsigned</span> u) { cout &lt;&lt; <span class="stringliteral">&quot;Uint(&quot;</span> &lt;&lt; u &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> Int64(int64_t i) { cout &lt;&lt; <span class="stringliteral">&quot;Int64(&quot;</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> Uint64(uint64_t u) { cout &lt;&lt; <span class="stringliteral">&quot;Uint64(&quot;</span> &lt;&lt; u &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> Double(<span class="keywordtype">double</span> d) { cout &lt;&lt; <span class="stringliteral">&quot;Double(&quot;</span> &lt;&lt; d &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> String(<span class="keyword">const</span> <span class="keywordtype">char</span>* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span> copy) { </div>
<div class="line"> cout &lt;&lt; <span class="stringliteral">&quot;String(&quot;</span> &lt;&lt; str &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> &lt;&lt; length &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> &lt;&lt; boolalpha &lt;&lt; copy &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl;</div>
<div class="line"> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordtype">bool</span> StartObject() { cout &lt;&lt; <span class="stringliteral">&quot;StartObject()&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> Key(<span class="keyword">const</span> <span class="keywordtype">char</span>* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span> copy) { </div>
<div class="line"> cout &lt;&lt; <span class="stringliteral">&quot;Key(&quot;</span> &lt;&lt; str &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> &lt;&lt; length &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> &lt;&lt; boolalpha &lt;&lt; copy &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl;</div>
<div class="line"> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordtype">bool</span> EndObject(<a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> memberCount) { cout &lt;&lt; <span class="stringliteral">&quot;EndObject(&quot;</span> &lt;&lt; memberCount &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> StartArray() { cout &lt;&lt; <span class="stringliteral">&quot;StartArray()&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line"> <span class="keywordtype">bool</span> EndArray(<a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> elementCount) { cout &lt;&lt; <span class="stringliteral">&quot;EndArray(&quot;</span> &lt;&lt; elementCount &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl; <span class="keywordflow">return</span> <span class="keyword">true</span>; }</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> main() {</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span> json[] = <span class="stringliteral">&quot; { \&quot;hello\&quot; : \&quot;world\&quot;, \&quot;t\&quot; : true , \&quot;f\&quot; : false, \&quot;n\&quot;: null, \&quot;i\&quot;:123, \&quot;pi\&quot;: 3.1416, \&quot;a\&quot;:[1, 2, 3, 4] } &quot;</span>;</div>
<div class="line"> </div>
<div class="line"> MyHandler handler;</div>
<div class="line"> <a class="code" href="classrapidjson_1_1_generic_reader.html">Reader</a> reader;</div>
<div class="line"> <a class="code" href="structrapidjson_1_1_generic_string_stream.html">StringStream</a> ss(json);</div>
<div class="line"> reader.<a class="code" href="classrapidjson_1_1_generic_reader.html#ac9c540b77de19661f6f45e04b9b0937b">Parse</a>(ss, handler);</div>
<div class="line">}</div>
</div><!-- fragment --><p>Note that RapidJSON uses templates to statically bind the <code>Reader</code> type and the handler type, instead of using classes with virtual functions. This paradigm can improve performance by inlining functions.</p>
<h2><a class="anchor" id="Handler"></a>
Handler</h2>
<p>As shown in the previous example, the user needs to implement a handler which consumes the events (via function calls) from the <code>Reader</code>. The handler must contain the following member functions.</p>
<div class="fragment"><div class="line"><span class="keyword">class </span><a class="code" href="classrapidjson_1_1_handler.html">Handler</a> {</div>
<div class="line"> <span class="keywordtype">bool</span> Null();</div>
<div class="line"> <span class="keywordtype">bool</span> Bool(<span class="keywordtype">bool</span> b);</div>
<div class="line"> <span class="keywordtype">bool</span> Int(<span class="keywordtype">int</span> i);</div>
<div class="line"> <span class="keywordtype">bool</span> Uint(<span class="keywordtype">unsigned</span> i);</div>
<div class="line"> <span class="keywordtype">bool</span> Int64(int64_t i);</div>
<div class="line"> <span class="keywordtype">bool</span> Uint64(uint64_t i);</div>
<div class="line"> <span class="keywordtype">bool</span> Double(<span class="keywordtype">double</span> d);</div>
<div class="line"> <span class="keywordtype">bool</span> RawNumber(<span class="keyword">const</span> Ch* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span> copy);</div>
<div class="line"> <span class="keywordtype">bool</span> String(<span class="keyword">const</span> Ch* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span> copy);</div>
<div class="line"> <span class="keywordtype">bool</span> StartObject();</div>
<div class="line"> <span class="keywordtype">bool</span> Key(<span class="keyword">const</span> Ch* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span> copy);</div>
<div class="line"> <span class="keywordtype">bool</span> EndObject(<a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> memberCount);</div>
<div class="line"> <span class="keywordtype">bool</span> StartArray();</div>
<div class="line"> <span class="keywordtype">bool</span> EndArray(<a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> elementCount);</div>
<div class="line">};</div>
</div><!-- fragment --><p><code>Null()</code> is called when the <code>Reader</code> encounters a JSON null value.</p>
<p><code>Bool(bool)</code> is called when the <code>Reader</code> encounters a JSON true or false value.</p>
<p>When the <code>Reader</code> encounters a JSON number, it chooses a suitable C++ type mapping. And then it calls <em>one</em> function out of <code>Int(int)</code>, <code>Uint(unsigned)</code>, <code>Int64(int64_t)</code>, <code>Uint64(uint64_t)</code> and <code>Double(double)</code>. If <code>kParseNumbersAsStrings</code> is enabled, <code>Reader</code> will always calls <code>RawNumber()</code> instead.</p>
<p><code>String(const char* str, SizeType length, bool copy)</code> is called when the <code>Reader</code> encounters a string. The first parameter is pointer to the string. The second parameter is the length of the string (excluding the null terminator). Note that RapidJSON supports null character <code>\0</code> inside a string. If such situation happens, <code>strlen(str) &lt; length</code>. The last <code>copy</code> indicates whether the handler needs to make a copy of the string. For normal parsing, <code>copy = true</code>. Only when <em>insitu</em> parsing is used, <code>copy = false</code>. And be aware that the character type depends on the target encoding, which will be explained later.</p>
<p>When the <code>Reader</code> encounters the beginning of an object, it calls <code>StartObject()</code>. An object in JSON is a set of name-value pairs. If the object contains members it first calls <code>Key()</code> for the name of member, and then calls functions depending on the type of the value. These calls of name-value pairs repeat until calling <code>EndObject(SizeType memberCount)</code>. Note that the <code>memberCount</code> parameter is just an aid for the handler; users who do not need this parameter may ignore it.</p>
<p>Arrays are similar to objects, but simpler. At the beginning of an array, the <code>Reader</code> calls <code>BeginArray()</code>. If there is elements, it calls functions according to the types of element. Similarly, in the last call <code>EndArray(SizeType elementCount)</code>, the parameter <code>elementCount</code> is just an aid for the handler.</p>
<p>Every handler function returns a <code>bool</code>. Normally it should return <code>true</code>. If the handler encounters an error, it can return <code>false</code> to notify the event publisher to stop further processing.</p>
<p>For example, when we parse a JSON with <code>Reader</code> and the handler detects that the JSON does not conform to the required schema, the handler can return <code>false</code> and let the <code>Reader</code> stop further parsing. This will place the <code>Reader</code> in an error state, with error code <code>kParseErrorTermination</code>.</p>
<h2><a class="anchor" id="GenericReader"></a>
GenericReader</h2>
<p>As mentioned before, <code>Reader</code> is a typedef of a template class <code>GenericReader</code>:</p>
<div class="fragment"><div class="line"><span class="keyword">namespace </span><a class="code" href="namespacerapidjson.html">rapidjson</a> {</div>
<div class="line"> </div>
<div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SourceEncoding, <span class="keyword">typename</span> TargetEncoding, <span class="keyword">typename</span> Allocator = MemoryPoolAllocator&lt;&gt; &gt;</div>
<div class="line"><span class="keyword">class </span>GenericReader {</div>
<div class="line"> <span class="comment">// ...</span></div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keyword">typedef</span> GenericReader&lt;UTF8&lt;&gt;, UTF8&lt;&gt; &gt; <a class="code" href="namespacerapidjson.html#ad5310edd1226f5b3ea82dc0d4d3740c6">Reader</a>;</div>
<div class="line"> </div>
<div class="line">} <span class="comment">// namespace rapidjson</span></div>
</div><!-- fragment --><p>The <code>Reader</code> uses UTF-8 as both source and target encoding. The source encoding means the encoding in the JSON stream. The target encoding means the encoding of the <code>str</code> parameter in <code>String()</code> calls. For example, to parse a UTF-8 stream and output UTF-16 string events, you can define a reader by:</p>
<div class="fragment"><div class="line">GenericReader&lt;UTF8&lt;&gt;, UTF16&lt;&gt; &gt; reader;</div>
</div><!-- fragment --><p>Note that, the default character type of <code>UTF16</code> is <code>wchar_t</code>. So this <code>reader</code> needs to call <code>String(const wchar_t*, SizeType, bool)</code> of the handler.</p>
<p>The third template parameter <code>Allocator</code> is the allocator type for internal data structure (actually a stack).</p>
<h2><a class="anchor" id="SaxParsing"></a>
Parsing</h2>
<p>The main function of <code>Reader</code> is used to parse JSON.</p>
<div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keywordtype">unsigned</span> parseFlags, <span class="keyword">typename</span> InputStream, <span class="keyword">typename</span> Handler&gt;</div>
<div class="line"><span class="keywordtype">bool</span> Parse(InputStream&amp; is, <a class="code" href="classrapidjson_1_1_handler.html">Handler</a>&amp; handler);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// with parseFlags = kDefaultParseFlags</span></div>
<div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> InputStream, <span class="keyword">typename</span> Handler&gt;</div>
<div class="line"><span class="keywordtype">bool</span> Parse(InputStream&amp; is, <a class="code" href="classrapidjson_1_1_handler.html">Handler</a>&amp; handler);</div>
</div><!-- fragment --><p>If an error occurs during parsing, it will return <code>false</code>. User can also call <code>bool HasParseError()</code>, <code>ParseErrorCode GetParseErrorCode()</code> and <code>size_t GetErrorOffset()</code> to obtain the error states. In fact, <code>Document</code> uses these <code>Reader</code> functions to obtain parse errors. Please refer to <a class="el" href="md_doc_dom.html">DOM</a> for details about parse errors.</p>
<h2><a class="anchor" id="TokenByTokenParsing"></a>
Token-by-Token Parsing</h2>
<p>Some users may wish to parse a JSON input stream a single token at a time, instead of immediately parsing an entire document without stopping. To parse JSON this way, instead of calling <code>Parse</code>, you can use the <code>IterativeParse</code> set of functions:</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> IterativeParseInit();</div>
<div class="line"> </div>
<div class="line"><span class="keyword">template</span> &lt;<span class="keywordtype">unsigned</span> parseFlags, <span class="keyword">typename</span> InputStream, <span class="keyword">typename</span> Handler&gt;</div>
<div class="line"><span class="keywordtype">bool</span> IterativeParseNext(InputStream&amp; is, <a class="code" href="classrapidjson_1_1_handler.html">Handler</a>&amp; handler);</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">bool</span> IterativeParseComplete();</div>
</div><!-- fragment --><p>Here is an example of iteratively parsing JSON, token by token:</p>
<div class="fragment"><div class="line">reader.IterativeParseInit();</div>
<div class="line"><span class="keywordflow">while</span> (!reader.IterativeParseComplete()) {</div>
<div class="line"> reader.IterativeParseNext&lt;<a class="code" href="namespacerapidjson.html#a81379eb4e94a0386d71d15fda882ebc9a5640cb00db7814b7f22be3683dda9835">kParseDefaultFlags</a>&gt;(is, handler);</div>
<div class="line"> <span class="comment">// Your handler has been called once.</span></div>
<div class="line">}</div>
</div><!-- fragment --><h1><a class="anchor" id="Writer"></a>
Writer</h1>
<p><code>Reader</code> converts (parses) JSON into events. <code>Writer</code> does exactly the opposite. It converts events into JSON.</p>
<p><code>Writer</code> is very easy to use. If your application only need to converts some data into JSON, it may be a good choice to use <code>Writer</code> directly, instead of building a <code>Document</code> and then stringifying it with a <code>Writer</code>.</p>
<p>In <code>simplewriter</code> example, we do exactly the reverse of <code>simplereader</code>.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;rapidjson/writer.h&quot;</span></div>
<div class="line"><span class="preprocessor">#include &quot;rapidjson/stringbuffer.h&quot;</span></div>
<div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">using namespace </span><a class="code" href="namespacerapidjson.html">rapidjson</a>;</div>
<div class="line"><span class="keyword">using namespace </span>std;</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> main() {</div>
<div class="line"> <a class="code" href="classrapidjson_1_1_generic_string_buffer.html">StringBuffer</a> s;</div>
<div class="line"> <a class="code" href="classrapidjson_1_1_writer.html">Writer&lt;StringBuffer&gt;</a> writer(s);</div>
<div class="line"> </div>
<div class="line"> writer.StartObject();</div>
<div class="line"> writer.Key(<span class="stringliteral">&quot;hello&quot;</span>);</div>
<div class="line"> writer.String(<span class="stringliteral">&quot;world&quot;</span>);</div>
<div class="line"> writer.Key(<span class="stringliteral">&quot;t&quot;</span>);</div>
<div class="line"> writer.Bool(<span class="keyword">true</span>);</div>
<div class="line"> writer.Key(<span class="stringliteral">&quot;f&quot;</span>);</div>
<div class="line"> writer.Bool(<span class="keyword">false</span>);</div>
<div class="line"> writer.Key(<span class="stringliteral">&quot;n&quot;</span>);</div>
<div class="line"> writer.Null();</div>
<div class="line"> writer.Key(<span class="stringliteral">&quot;i&quot;</span>);</div>
<div class="line"> writer.Uint(123);</div>
<div class="line"> writer.Key(<span class="stringliteral">&quot;pi&quot;</span>);</div>
<div class="line"> writer.Double(3.1416);</div>
<div class="line"> writer.Key(<span class="stringliteral">&quot;a&quot;</span>);</div>
<div class="line"> writer.StartArray();</div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i &lt; 4; i++)</div>
<div class="line"> writer.Uint(i);</div>
<div class="line"> writer.EndArray();</div>
<div class="line"> writer.EndObject();</div>
<div class="line"> </div>
<div class="line"> cout &lt;&lt; s.GetString() &lt;&lt; endl;</div>
<div class="line">}</div>
</div><!-- fragment --><div class="fragment"><div class="line">{&quot;hello&quot;:&quot;world&quot;,&quot;t&quot;:true,&quot;f&quot;:false,&quot;n&quot;:null,&quot;i&quot;:123,&quot;pi&quot;:3.1416,&quot;a&quot;:[0,1,2,3]}</div>
</div><!-- fragment --><p>There are two <code>String()</code> and <code>Key()</code> overloads. One is the same as defined in handler concept with 3 parameters. It can handle string with null characters. Another one is the simpler version used in the above example.</p>
<p>Note that, the example code does not pass any parameters in <code>EndArray()</code> and <code>EndObject()</code>. An <code>SizeType</code> can be passed but it will be simply ignored by <code>Writer</code>.</p>
<p>You may doubt that, why not just using <code>sprintf()</code> or <code>std::stringstream</code> to build a JSON?</p>
<p>There are various reasons:</p><ol type="1">
<li><code>Writer</code> must output a well-formed JSON. If there is incorrect event sequence (e.g. <code>Int()</code> just after <code>StartObject()</code>), it generates assertion fail in debug mode.</li>
<li><code>Writer::String()</code> can handle string escaping (e.g. converting code point <code>U+000A</code> to <code>\n</code>) and Unicode transcoding.</li>
<li><code>Writer</code> handles number output consistently.</li>
<li><code>Writer</code> implements the event handler concept. It can be used to handle events from <code>Reader</code>, <code>Document</code> or other event publisher.</li>
<li><code>Writer</code> can be optimized for different platforms.</li>
</ol>
<p>Anyway, using <code>Writer</code> API is even simpler than generating a JSON by ad hoc methods.</p>
<h2><a class="anchor" id="WriterTemplate"></a>
Template</h2>
<p><code>Writer</code> has a minor design difference to <code>Reader</code>. <code>Writer</code> is a template class, not a typedef. There is no <code>GenericWriter</code>. The following is the declaration.</p>
<div class="fragment"><div class="line"><span class="keyword">namespace </span><a class="code" href="namespacerapidjson.html">rapidjson</a> {</div>
<div class="line"> </div>
<div class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> OutputStream, <span class="keyword">typename</span> SourceEncoding = UTF8&lt;&gt;, <span class="keyword">typename</span> TargetEncoding = UTF8&lt;&gt;, <span class="keyword">typename</span> Allocator = CrtAllocator&lt;&gt;, <span class="keywordtype">unsigned</span> writeFlags = kWriteDefaultFlags&gt;</div>
<div class="line"><span class="keyword">class </span>Writer {</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line"> <a class="code" href="classrapidjson_1_1_writer.html#a98a421c806b456688874511f64add1f2">Writer</a>(OutputStream&amp; os, <a class="code" href="classrapidjson_1_1_allocator.html">Allocator</a>* allocator = 0, <span class="keywordtype">size_t</span> levelDepth = kDefaultLevelDepth)</div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line">} <span class="comment">// namespace rapidjson</span></div>
</div><!-- fragment --><p>The <code>OutputStream</code> template parameter is the type of output stream. It cannot be deduced and must be specified by user.</p>
<p>The <code>SourceEncoding</code> template parameter specifies the encoding to be used in <code>String(const Ch*, ...)</code>.</p>
<p>The <code>TargetEncoding</code> template parameter specifies the encoding in the output stream.</p>
<p>The <code>Allocator</code> is the type of allocator, which is used for allocating internal data structure (a stack).</p>
<p>The <code>writeFlags</code> are combination of the following bit-flags:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Parse flags </th><th class="markdownTableHeadNone">Meaning </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>kWriteNoFlags</code> </td><td class="markdownTableBodyNone">No flag is set. </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><code>kWriteDefaultFlags</code> </td><td class="markdownTableBodyNone">Default write flags. It is equal to macro <code>RAPIDJSON_WRITE_DEFAULT_FLAGS</code>, which is defined as <code>kWriteNoFlags</code>. </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>kWriteValidateEncodingFlag</code> </td><td class="markdownTableBodyNone">Validate encoding of JSON strings. </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><code>kWriteNanAndInfFlag</code> </td><td class="markdownTableBodyNone">Allow writing of <code>Infinity</code>, <code>-Infinity</code> and <code>NaN</code>. </td></tr>
</table>
<p>Besides, the constructor of <code>Writer</code> has a <code>levelDepth</code> parameter. This parameter affects the initial memory allocated for storing information per hierarchy level.</p>
<h2><a class="anchor" id="PrettyWriter"></a>
PrettyWriter</h2>
<p>While the output of <code>Writer</code> is the most condensed JSON without white-spaces, suitable for network transfer or storage, it is not easily readable by human.</p>
<p>Therefore, RapidJSON provides a <code>PrettyWriter</code>, which adds indentation and line feeds in the output.</p>
<p>The usage of <code>PrettyWriter</code> is exactly the same as <code>Writer</code>, expect that <code>PrettyWriter</code> provides a <code>SetIndent(Ch indentChar, unsigned indentCharCount)</code> function. The default is 4 spaces.</p>
<h2><a class="anchor" id="CompletenessReset"></a>
Completeness and Reset</h2>
<p>A <code>Writer</code> can only output a single JSON, which can be any JSON type at the root. Once the singular event for root (e.g. <code>String()</code>), or the last matching <code>EndObject()</code> or <code>EndArray()</code> event, is handled, the output JSON is well-formed and complete. User can detect this state by calling <code>Writer::IsComplete()</code>.</p>
<p>When a JSON is complete, the <code>Writer</code> cannot accept any new events. Otherwise the output will be invalid (i.e. having more than one root). To reuse the <code>Writer</code> object, user can call <code>Writer::Reset(OutputStream&amp; os)</code> to reset all internal states of the <code>Writer</code> with a new output stream.</p>
<h1><a class="anchor" id="SaxTechniques"></a>
Techniques</h1>
<h2><a class="anchor" id="CustomDataStructure"></a>
Parsing JSON to Custom Data Structure</h2>
<p><code>Document</code>'s parsing capability is completely based on <code>Reader</code>. Actually <code>Document</code> is a handler which receives events from a reader to build a DOM during parsing.</p>
<p>User may uses <code>Reader</code> to build other data structures directly. This eliminates building of DOM, thus reducing memory and improving performance.</p>
<p>In the following <code>messagereader</code> example, <code>ParseMessages()</code> parses a JSON which should be an object with key-string pairs.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="reader_8h.html">rapidjson/reader.h</a>&quot;</span></div>
<div class="line"><span class="preprocessor">#include &quot;rapidjson/error/en.h&quot;</span></div>
<div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;string&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;map&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">using namespace </span>std;</div>
<div class="line"><span class="keyword">using namespace </span><a class="code" href="namespacerapidjson.html">rapidjson</a>;</div>
<div class="line"> </div>
<div class="line"><span class="keyword">typedef</span> map&lt;string, string&gt; MessageMap;</div>
<div class="line"> </div>
<div class="line"><span class="keyword">struct </span>MessageHandler</div>
<div class="line"> : <span class="keyword">public</span> <a class="code" href="structrapidjson_1_1_base_reader_handler.html">BaseReaderHandler</a>&lt;UTF8&lt;&gt;, MessageHandler&gt; {</div>
<div class="line"> MessageHandler() : state_(kExpectObjectStart) {</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">bool</span> StartObject() {</div>
<div class="line"> <span class="keywordflow">switch</span> (state_) {</div>
<div class="line"> <span class="keywordflow">case</span> kExpectObjectStart:</div>
<div class="line"> state_ = kExpectNameOrObjectEnd;</div>
<div class="line"> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line"> <span class="keywordflow">default</span>:</div>
<div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">bool</span> String(<span class="keyword">const</span> <span class="keywordtype">char</span>* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span>) {</div>
<div class="line"> <span class="keywordflow">switch</span> (state_) {</div>
<div class="line"> <span class="keywordflow">case</span> kExpectNameOrObjectEnd:</div>
<div class="line"> name_ = string(str, length);</div>
<div class="line"> state_ = kExpectValue;</div>
<div class="line"> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line"> <span class="keywordflow">case</span> kExpectValue:</div>
<div class="line"> messages_.insert(MessageMap::value_type(name_, <span class="keywordtype">string</span>(str, length)));</div>
<div class="line"> state_ = kExpectNameOrObjectEnd;</div>
<div class="line"> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line"> <span class="keywordflow">default</span>:</div>
<div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">bool</span> EndObject(<a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a>) { <span class="keywordflow">return</span> state_ == kExpectNameOrObjectEnd; }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">bool</span> Default() { <span class="keywordflow">return</span> <span class="keyword">false</span>; } <span class="comment">// All other events are invalid.</span></div>
<div class="line"> </div>
<div class="line"> MessageMap messages_;</div>
<div class="line"> <span class="keyword">enum</span> State {</div>
<div class="line"> kExpectObjectStart,</div>
<div class="line"> kExpectNameOrObjectEnd,</div>
<div class="line"> kExpectValue,</div>
<div class="line"> }state_;</div>
<div class="line"> std::string name_;</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> ParseMessages(<span class="keyword">const</span> <span class="keywordtype">char</span>* json, MessageMap&amp; messages) {</div>
<div class="line"> <a class="code" href="classrapidjson_1_1_generic_reader.html">Reader</a> reader;</div>
<div class="line"> MessageHandler handler;</div>
<div class="line"> <a class="code" href="structrapidjson_1_1_generic_string_stream.html">StringStream</a> ss(json);</div>
<div class="line"> <span class="keywordflow">if</span> (reader.<a class="code" href="classrapidjson_1_1_generic_reader.html#ac9c540b77de19661f6f45e04b9b0937b">Parse</a>(ss, handler))</div>
<div class="line"> messages.swap(handler.messages_); <span class="comment">// Only change it if success.</span></div>
<div class="line"> <span class="keywordflow">else</span> {</div>
<div class="line"> <a class="code" href="group___r_a_p_i_d_j_s_o_n___e_r_r_o_r_s.html#ga7d3acf640886b1f2552dc8c4cd6dea60">ParseErrorCode</a> e = reader.<a class="code" href="classrapidjson_1_1_generic_reader.html#a042c621cf745c5ed3a6f5ff9418dd05e">GetParseErrorCode</a>();</div>
<div class="line"> <span class="keywordtype">size_t</span> o = reader.<a class="code" href="classrapidjson_1_1_generic_reader.html#ab50019e0a715320f83b7610b83dcef8f">GetErrorOffset</a>();</div>
<div class="line"> cout &lt;&lt; <span class="stringliteral">&quot;Error: &quot;</span> &lt;&lt; <a class="code" href="group___r_a_p_i_d_j_s_o_n___e_r_r_o_r_s.html#gabdaf1a7a4db30fb0e3d927fdf0fabe79">GetParseError_En</a>(e) &lt;&lt; endl;;</div>
<div class="line"> cout &lt;&lt; <span class="stringliteral">&quot; at offset &quot;</span> &lt;&lt; o &lt;&lt; <span class="stringliteral">&quot; near &#39;&quot;</span> &lt;&lt; string(json).substr(o, 10) &lt;&lt; <span class="stringliteral">&quot;...&#39;&quot;</span> &lt;&lt; endl;</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main() {</div>
<div class="line"> MessageMap messages;</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span>* json1 = <span class="stringliteral">&quot;{ \&quot;greeting\&quot; : \&quot;Hello!\&quot;, \&quot;farewell\&quot; : \&quot;bye-bye!\&quot; }&quot;</span>;</div>
<div class="line"> cout &lt;&lt; json1 &lt;&lt; endl;</div>
<div class="line"> ParseMessages(json1, messages);</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">for</span> (MessageMap::const_iterator itr = messages.begin(); itr != messages.end(); ++itr)</div>
<div class="line"> cout &lt;&lt; itr-&gt;first &lt;&lt; <span class="stringliteral">&quot;: &quot;</span> &lt;&lt; itr-&gt;second &lt;&lt; endl;</div>
<div class="line"> </div>
<div class="line"> cout &lt;&lt; endl &lt;&lt; <span class="stringliteral">&quot;Parse a JSON with invalid schema.&quot;</span> &lt;&lt; endl;</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span>* json2 = <span class="stringliteral">&quot;{ \&quot;greeting\&quot; : \&quot;Hello!\&quot;, \&quot;farewell\&quot; : \&quot;bye-bye!\&quot;, \&quot;foo\&quot; : {} }&quot;</span>;</div>
<div class="line"> cout &lt;&lt; json2 &lt;&lt; endl;</div>
<div class="line"> ParseMessages(json2, messages);</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> 0;</div>
<div class="line">}</div>
</div><!-- fragment --><div class="fragment"><div class="line">{ &quot;greeting&quot; : &quot;Hello!&quot;, &quot;farewell&quot; : &quot;bye-bye!&quot; }</div>
<div class="line">farewell: bye-bye!</div>
<div class="line">greeting: Hello!</div>
<div class="line"> </div>
<div class="line">Parse a JSON with invalid schema.</div>
<div class="line">{ &quot;greeting&quot; : &quot;Hello!&quot;, &quot;farewell&quot; : &quot;bye-bye!&quot;, &quot;foo&quot; : {} }</div>
<div class="line">Error: Terminate parsing due to Handler error.</div>
<div class="line"> at offset 59 near &#39;} }...&#39;</div>
</div><!-- fragment --><p>The first JSON (<code>json1</code>) was successfully parsed into <code>MessageMap</code>. Since <code>MessageMap</code> is a <code>std::map</code>, the printing order are sorted by the key. This order is different from the JSON's order.</p>
<p>In the second JSON (<code>json2</code>), <code>foo</code>'s value is an empty object. As it is an object, <code>MessageHandler::StartObject()</code> will be called. However, at that moment <code>state_ = kExpectValue</code>, so that function returns <code>false</code> and cause the parsing process be terminated. The error code is <code>kParseErrorTermination</code>.</p>
<h2><a class="anchor" id="Filtering"></a>
Filtering of JSON</h2>
<p>As mentioned earlier, <code>Writer</code> can handle the events published by <code>Reader</code>. <code>condense</code> example simply set a <code>Writer</code> as handler of a <code>Reader</code>, so it can remove all white-spaces in JSON. <code>pretty</code> example uses the same relationship, but replacing <code>Writer</code> by <code>PrettyWriter</code>. So <code>pretty</code> can be used to reformat a JSON with indentation and line feed.</p>
<p>Actually, we can add intermediate layer(s) to filter the contents of JSON via these SAX-style API. For example, <code>capitalize</code> example capitalize all strings in a JSON.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="reader_8h.html">rapidjson/reader.h</a>&quot;</span></div>
<div class="line"><span class="preprocessor">#include &quot;rapidjson/writer.h&quot;</span></div>
<div class="line"><span class="preprocessor">#include &quot;rapidjson/filereadstream.h&quot;</span></div>
<div class="line"><span class="preprocessor">#include &quot;rapidjson/filewritestream.h&quot;</span></div>
<div class="line"><span class="preprocessor">#include &quot;rapidjson/error/en.h&quot;</span></div>
<div class="line"><span class="preprocessor">#include &lt;vector&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;cctype&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">using namespace </span><a class="code" href="namespacerapidjson.html">rapidjson</a>;</div>
<div class="line"> </div>
<div class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> OutputHandler&gt;</div>
<div class="line"><span class="keyword">struct </span>CapitalizeFilter {</div>
<div class="line"> CapitalizeFilter(OutputHandler&amp; out) : out_(out), buffer_() {</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">bool</span> Null() { <span class="keywordflow">return</span> out_.Null(); }</div>
<div class="line"> <span class="keywordtype">bool</span> Bool(<span class="keywordtype">bool</span> b) { <span class="keywordflow">return</span> out_.Bool(b); }</div>
<div class="line"> <span class="keywordtype">bool</span> Int(<span class="keywordtype">int</span> i) { <span class="keywordflow">return</span> out_.Int(i); }</div>
<div class="line"> <span class="keywordtype">bool</span> Uint(<span class="keywordtype">unsigned</span> u) { <span class="keywordflow">return</span> out_.Uint(u); }</div>
<div class="line"> <span class="keywordtype">bool</span> Int64(int64_t i) { <span class="keywordflow">return</span> out_.Int64(i); }</div>
<div class="line"> <span class="keywordtype">bool</span> Uint64(uint64_t u) { <span class="keywordflow">return</span> out_.Uint64(u); }</div>
<div class="line"> <span class="keywordtype">bool</span> Double(<span class="keywordtype">double</span> d) { <span class="keywordflow">return</span> out_.Double(d); }</div>
<div class="line"> <span class="keywordtype">bool</span> RawNumber(<span class="keyword">const</span> <span class="keywordtype">char</span>* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span> copy) { <span class="keywordflow">return</span> out_.RawNumber(str, length, copy); }</div>
<div class="line"> <span class="keywordtype">bool</span> String(<span class="keyword">const</span> <span class="keywordtype">char</span>* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span>) { </div>
<div class="line"> buffer_.clear();</div>
<div class="line"> <span class="keywordflow">for</span> (<a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> i = 0; i &lt; length; i++)</div>
<div class="line"> buffer_.push_back(std::toupper(str[i]));</div>
<div class="line"> <span class="keywordflow">return</span> out_.String(&amp;buffer_.front(), length, <span class="keyword">true</span>); <span class="comment">// true = output handler need to copy the string</span></div>
<div class="line"> }</div>
<div class="line"> <span class="keywordtype">bool</span> StartObject() { <span class="keywordflow">return</span> out_.StartObject(); }</div>
<div class="line"> <span class="keywordtype">bool</span> Key(<span class="keyword">const</span> <span class="keywordtype">char</span>* str, <a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> length, <span class="keywordtype">bool</span> copy) { <span class="keywordflow">return</span> String(str, length, copy); }</div>
<div class="line"> <span class="keywordtype">bool</span> EndObject(<a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> memberCount) { <span class="keywordflow">return</span> out_.EndObject(memberCount); }</div>
<div class="line"> <span class="keywordtype">bool</span> StartArray() { <span class="keywordflow">return</span> out_.StartArray(); }</div>
<div class="line"> <span class="keywordtype">bool</span> EndArray(<a class="code" href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">SizeType</a> elementCount) { <span class="keywordflow">return</span> out_.EndArray(elementCount); }</div>
<div class="line"> </div>
<div class="line"> OutputHandler&amp; out_;</div>
<div class="line"> std::vector&lt;char&gt; buffer_;</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span>, <span class="keywordtype">char</span>*[]) {</div>
<div class="line"> <span class="comment">// Prepare JSON reader and input stream.</span></div>
<div class="line"> <a class="code" href="classrapidjson_1_1_generic_reader.html">Reader</a> reader;</div>
<div class="line"> <span class="keywordtype">char</span> readBuffer[65536];</div>
<div class="line"> <a class="code" href="classrapidjson_1_1_file_read_stream.html">FileReadStream</a> is(stdin, readBuffer, <span class="keyword">sizeof</span>(readBuffer));</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Prepare JSON writer and output stream.</span></div>
<div class="line"> <span class="keywordtype">char</span> writeBuffer[65536];</div>
<div class="line"> <a class="code" href="classrapidjson_1_1_file_write_stream.html">FileWriteStream</a> os(stdout, writeBuffer, <span class="keyword">sizeof</span>(writeBuffer));</div>
<div class="line"> <a class="code" href="classrapidjson_1_1_writer.html">Writer&lt;FileWriteStream&gt;</a> writer(os);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// JSON reader parse from the input stream and let writer generate the output.</span></div>
<div class="line"> CapitalizeFilter&lt;Writer&lt;FileWriteStream&gt; &gt; filter(writer);</div>
<div class="line"> <span class="keywordflow">if</span> (!reader.<a class="code" href="classrapidjson_1_1_generic_reader.html#ac9c540b77de19661f6f45e04b9b0937b">Parse</a>(is, filter)) {</div>
<div class="line"> fprintf(stderr, <span class="stringliteral">&quot;\nError(%u): %s\n&quot;</span>, (<span class="keywordtype">unsigned</span>)reader.<a class="code" href="classrapidjson_1_1_generic_reader.html#ab50019e0a715320f83b7610b83dcef8f">GetErrorOffset</a>(), <a class="code" href="group___r_a_p_i_d_j_s_o_n___e_r_r_o_r_s.html#gabdaf1a7a4db30fb0e3d927fdf0fabe79">GetParseError_En</a>(reader.<a class="code" href="classrapidjson_1_1_generic_reader.html#a042c621cf745c5ed3a6f5ff9418dd05e">GetParseErrorCode</a>()));</div>
<div class="line"> <span class="keywordflow">return</span> 1;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> 0;</div>
<div class="line">}</div>
</div><!-- fragment --><p>Note that, it is incorrect to simply capitalize the JSON as a string. For example: </p><div class="fragment"><div class="line">[&quot;Hello\nWorld&quot;]</div>
</div><!-- fragment --><p>Simply capitalizing the whole JSON would contain incorrect escape character: </p><div class="fragment"><div class="line">[&quot;HELLO\NWORLD&quot;]</div>
</div><!-- fragment --><p>The correct result by <code>capitalize</code>: </p><div class="fragment"><div class="line">[&quot;HELLO\nWORLD&quot;]</div>
</div><!-- fragment --><p>More complicated filters can be developed. However, since SAX-style API can only provide information about a single event at a time, user may need to book-keeping the contextual information (e.g. the path from root value, storage of other related values). Some processing may be easier to be implemented in DOM than SAX. </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<div class="ttc" id="aclassrapidjson_1_1_allocator_html"><div class="ttname"><a href="classrapidjson_1_1_allocator.html">Allocator</a></div><div class="ttdoc">Concept for allocating, resizing and freeing memory block.</div></div>
<div class="ttc" id="aclassrapidjson_1_1_generic_string_buffer_html"><div class="ttname"><a href="classrapidjson_1_1_generic_string_buffer.html">rapidjson::GenericStringBuffer</a></div><div class="ttdoc">Represents an in-memory output stream.</div><div class="ttdef"><b>Definition:</b> fwd.h:59</div></div>
<div class="ttc" id="astructrapidjson_1_1_generic_string_stream_html"><div class="ttname"><a href="structrapidjson_1_1_generic_string_stream.html">rapidjson::GenericStringStream</a></div><div class="ttdoc">Read-only string stream.</div><div class="ttdef"><b>Definition:</b> fwd.h:47</div></div>
<div class="ttc" id="agroup___r_a_p_i_d_j_s_o_n___e_r_r_o_r_s_html_ga7d3acf640886b1f2552dc8c4cd6dea60"><div class="ttname"><a href="group___r_a_p_i_d_j_s_o_n___e_r_r_o_r_s.html#ga7d3acf640886b1f2552dc8c4cd6dea60">rapidjson::ParseErrorCode</a></div><div class="ttdeci">ParseErrorCode</div><div class="ttdoc">Error code of parsing.</div><div class="ttdef"><b>Definition:</b> error.h:64</div></div>
<div class="ttc" id="aclassrapidjson_1_1_file_write_stream_html"><div class="ttname"><a href="classrapidjson_1_1_file_write_stream.html">rapidjson::FileWriteStream</a></div><div class="ttdoc">Wrapper of C file stream for output using fwrite().</div><div class="ttdef"><b>Definition:</b> filewritestream.h:32</div></div>
<div class="ttc" id="aclassrapidjson_1_1_file_read_stream_html"><div class="ttname"><a href="classrapidjson_1_1_file_read_stream.html">rapidjson::FileReadStream</a></div><div class="ttdoc">File byte stream for input using fread().</div><div class="ttdef"><b>Definition:</b> filereadstream.h:34</div></div>
<div class="ttc" id="anamespacerapidjson_html_a44eb33eaa523e36d466b1ced64b85c84"><div class="ttname"><a href="namespacerapidjson.html#a44eb33eaa523e36d466b1ced64b85c84">rapidjson::SizeType</a></div><div class="ttdeci">unsigned SizeType</div><div class="ttdoc">Size type (for string lengths, array sizes, etc.)</div><div class="ttdef"><b>Definition:</b> rapidjson.h:415</div></div>
<div class="ttc" id="aclassrapidjson_1_1_generic_reader_html_ac9c540b77de19661f6f45e04b9b0937b"><div class="ttname"><a href="classrapidjson_1_1_generic_reader.html#ac9c540b77de19661f6f45e04b9b0937b">rapidjson::GenericReader::Parse</a></div><div class="ttdeci">ParseResult Parse(InputStream &amp;is, Handler &amp;handler)</div><div class="ttdoc">Parse JSON text.</div><div class="ttdef"><b>Definition:</b> reader.h:559</div></div>
<div class="ttc" id="aclassrapidjson_1_1_generic_reader_html"><div class="ttname"><a href="classrapidjson_1_1_generic_reader.html">rapidjson::GenericReader</a></div><div class="ttdoc">SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.</div><div class="ttdef"><b>Definition:</b> fwd.h:88</div></div>
<div class="ttc" id="aclassrapidjson_1_1_generic_reader_html_a042c621cf745c5ed3a6f5ff9418dd05e"><div class="ttname"><a href="classrapidjson_1_1_generic_reader.html#a042c621cf745c5ed3a6f5ff9418dd05e">rapidjson::GenericReader::GetParseErrorCode</a></div><div class="ttdeci">ParseErrorCode GetParseErrorCode() const</div><div class="ttdoc">Get the ParseErrorCode of last parsing.</div><div class="ttdef"><b>Definition:</b> reader.h:685</div></div>
<div class="ttc" id="areader_8h_html"><div class="ttname"><a href="reader_8h.html">reader.h</a></div></div>
<div class="ttc" id="aclassrapidjson_1_1_writer_html_a98a421c806b456688874511f64add1f2"><div class="ttname"><a href="classrapidjson_1_1_writer.html#a98a421c806b456688874511f64add1f2">rapidjson::Writer::Writer</a></div><div class="ttdeci">Writer(OutputStream &amp;os, StackAllocator *stackAllocator=0, size_t levelDepth=kDefaultLevelDepth)</div><div class="ttdoc">Constructor.</div><div class="ttdef"><b>Definition:</b> writer.h:102</div></div>
<div class="ttc" id="anamespacerapidjson_html_a81379eb4e94a0386d71d15fda882ebc9a5640cb00db7814b7f22be3683dda9835"><div class="ttname"><a href="namespacerapidjson.html#a81379eb4e94a0386d71d15fda882ebc9a5640cb00db7814b7f22be3683dda9835">rapidjson::kParseDefaultFlags</a></div><div class="ttdoc">Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS.</div><div class="ttdef"><b>Definition:</b> reader.h:158</div></div>
<div class="ttc" id="astructrapidjson_1_1_base_reader_handler_html"><div class="ttname"><a href="structrapidjson_1_1_base_reader_handler.html">rapidjson::BaseReaderHandler</a></div><div class="ttdoc">Default implementation of Handler.</div><div class="ttdef"><b>Definition:</b> fwd.h:85</div></div>
<div class="ttc" id="aclassrapidjson_1_1_writer_html"><div class="ttname"><a href="classrapidjson_1_1_writer.html">rapidjson::Writer</a></div><div class="ttdoc">JSON writer.</div><div class="ttdef"><b>Definition:</b> fwd.h:95</div></div>
<div class="ttc" id="anamespacerapidjson_html"><div class="ttname"><a href="namespacerapidjson.html">rapidjson</a></div><div class="ttdoc">main RapidJSON namespace</div><div class="ttdef"><b>Definition:</b> rapidjson.h:409</div></div>
<div class="ttc" id="anamespacerapidjson_html_ad5310edd1226f5b3ea82dc0d4d3740c6"><div class="ttname"><a href="namespacerapidjson.html#ad5310edd1226f5b3ea82dc0d4d3740c6">rapidjson::Reader</a></div><div class="ttdeci">GenericReader&lt; UTF8&lt; char &gt;, UTF8&lt; char &gt;, CrtAllocator &gt; Reader</div><div class="ttdoc">Reader with UTF8 encoding and default allocator.</div><div class="ttdef"><b>Definition:</b> fwd.h:88</div></div>
<div class="ttc" id="agroup___r_a_p_i_d_j_s_o_n___e_r_r_o_r_s_html_gabdaf1a7a4db30fb0e3d927fdf0fabe79"><div class="ttname"><a href="group___r_a_p_i_d_j_s_o_n___e_r_r_o_r_s.html#gabdaf1a7a4db30fb0e3d927fdf0fabe79">rapidjson::GetParseError_En</a></div><div class="ttdeci">const RAPIDJSON_ERROR_CHARTYPE * GetParseError_En(ParseErrorCode parseErrorCode)</div><div class="ttdoc">Maps error code of parsing into error message.</div><div class="ttdef"><b>Definition:</b> en.h:36</div></div>
<div class="ttc" id="aclassrapidjson_1_1_generic_reader_html_ab50019e0a715320f83b7610b83dcef8f"><div class="ttname"><a href="classrapidjson_1_1_generic_reader.html#ab50019e0a715320f83b7610b83dcef8f">rapidjson::GenericReader::GetErrorOffset</a></div><div class="ttdeci">size_t GetErrorOffset() const</div><div class="ttdoc">Get the position of last parsing error in input, 0 otherwise.</div><div class="ttdef"><b>Definition:</b> reader.h:688</div></div>
<div class="ttc" id="aclassrapidjson_1_1_handler_html"><div class="ttname"><a href="classrapidjson_1_1_handler.html">Handler</a></div><div class="ttdoc">Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...</div></div>
<!-- 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>
</body>
</html>