MeshTalos/components/mpack/docs/md_docs_reader.html
2025-12-03 20:59:51 +08:00

355 lines
51 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.5"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>MPack: Using the Reader API</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="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>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-mpack-css.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">MPack<span id="projectnumber">&#160;1.1.1</span>
</div>
<div id="projectbrief">A C encoding/decoding library for the MessagePack serialization format.</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.5 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- 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">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
</div><!-- top -->
<div><div class="header">
<div class="headertitle"><div class="title">Using the Reader API </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p >The Reader API is used to parse MessagePack incrementally with no per-element memory usage. Elements can be read one-by-one, and the content of strings and binary blobs can be read in chunks.</p>
<p >Reading incrementally is much more difficult and verbose than using the <a class="el" href="md_docs_node.html">Node API</a>. If you are not constrained in memory or performance, you should use the Node API.</p>
<h1><a class="anchor" id="autotoc_md7"></a>
The Basics</h1>
<p >A reader is first initialized against a data source. This can be a chunk of data in memory, or it can be a file or stream. A reader that uses a file or stream will read data in chunks into an internal buffer. This allows parsing very large messages efficiently with minimal memory usage.</p>
<p >Once initialized, the fundamental operation of a reader is to read a tag. A tag is a value struct of type <code>mpack_tag_t</code> that contains the value of a single element, or the metadata for a compound element.</p>
<p >Here's a minimal example that parses the first element out of a chunk of MessagePack data.</p>
<div class="fragment"><div class="line"><span class="keywordtype">bool</span> parse_first_element(<span class="keyword">const</span> <span class="keywordtype">char</span>* data, <span class="keywordtype">size_t</span> length) {</div>
<div class="line"> <a class="code hl_typedef" href="group__reader.html#gaee791c36a15344b9e57edae160c86615">mpack_reader_t</a> reader;</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#ga18f41d6786155f265769351ef550e331">mpack_reader_init_data</a>(&amp;reader, data, length);</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_typedef" href="group__common.html#ga008da69ac6b5582a893f2d2ffd37f4ac">mpack_tag_t</a> tag = <a class="code hl_function" href="group__reader.html#ga70c00ecaf381e9711f6c1d0fa92f0c2f">mpack_read_tag</a>(&amp;reader);</div>
<div class="line"> do_something_with_tag(&amp;tag);</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> <a class="code hl_function" href="group__reader.html#gac04666405e21eea6e8819182571f0d20">mpack_reader_destroy</a>(&amp;reader) == <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>;</div>
<div class="line">};</div>
<div class="ttc" id="agroup__common_html_ga008da69ac6b5582a893f2d2ffd37f4ac"><div class="ttname"><a href="group__common.html#ga008da69ac6b5582a893f2d2ffd37f4ac">mpack_tag_t</a></div><div class="ttdeci">struct mpack_tag_t mpack_tag_t</div><div class="ttdoc">An MPack tag is a MessagePack object header.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:240</div></div>
<div class="ttc" id="agroup__common_html_gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661"><div class="ttname"><a href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a></div><div class="ttdeci">@ mpack_ok</div><div class="ttdoc">No error.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:162</div></div>
<div class="ttc" id="agroup__reader_html_ga18f41d6786155f265769351ef550e331"><div class="ttname"><a href="group__reader.html#ga18f41d6786155f265769351ef550e331">mpack_reader_init_data</a></div><div class="ttdeci">void mpack_reader_init_data(mpack_reader_t *reader, const char *data, size_t count)</div><div class="ttdoc">Initializes an MPack reader to parse a pre-loaded contiguous chunk of data.</div></div>
<div class="ttc" id="agroup__reader_html_ga70c00ecaf381e9711f6c1d0fa92f0c2f"><div class="ttname"><a href="group__reader.html#ga70c00ecaf381e9711f6c1d0fa92f0c2f">mpack_read_tag</a></div><div class="ttdeci">mpack_tag_t mpack_read_tag(mpack_reader_t *reader)</div><div class="ttdoc">Reads a MessagePack object header (an MPack tag.)</div></div>
<div class="ttc" id="agroup__reader_html_gac04666405e21eea6e8819182571f0d20"><div class="ttname"><a href="group__reader.html#gac04666405e21eea6e8819182571f0d20">mpack_reader_destroy</a></div><div class="ttdeci">mpack_error_t mpack_reader_destroy(mpack_reader_t *reader)</div><div class="ttdoc">Cleans up the MPack reader, ensuring that all compound elements have been completely read.</div></div>
<div class="ttc" id="agroup__reader_html_gaee791c36a15344b9e57edae160c86615"><div class="ttname"><a href="group__reader.html#gaee791c36a15344b9e57edae160c86615">mpack_reader_t</a></div><div class="ttdeci">struct mpack_reader_t mpack_reader_t</div><div class="ttdoc">A buffered MessagePack decoder.</div><div class="ttdef"><b>Definition:</b> mpack-reader.h:84</div></div>
</div><!-- fragment --><p >The struct <code>mpack_tag_t</code> contains the element type, accessible with <code><a class="el" href="group__common.html#gaf3c75dc78631727344e154b82a73d37a" title="Gets the type of a tag.">mpack_tag_type()</a></code>. Depending on the type, you can access the value with tag accessor functions such as <code><a class="el" href="group__common.html#ga8c0f7e30e7c3484ea96b8f154bbf72a1" title="Gets the boolean value of a bool-type tag.">mpack_tag_bool_value()</a></code> or <code><a class="el" href="group__common.html#ga071204c83da525e2925b4ba13e5eafa6" title="Gets the number of elements in an array tag.">mpack_tag_array_count()</a></code>.</p>
<p >Of course, parsing single values isn't terribly useful. You'll need to know how to parse strings, maps and arrays.</p>
<h1><a class="anchor" id="autotoc_md8"></a>
Compound Types</h1>
<p >Compound types are either containers (map, array) or data chunks (strings, binary blobs). For any compound type, the tag only contains the compound type's size. You still need to read the contained data, and then you need to let the reader know that you're done reading the element (so it can check that you did it correctly.)</p>
<h2><a class="anchor" id="autotoc_md9"></a>
Containers</h2>
<p >To parse a container, you must read as many additional elements as are specified by the tag's count. Note that a map tag specifies the number of key value pairs it contains, so you must actually read double the tag's count. You must then call <code><a class="el" href="group__reader.html#gaddae460657b9a26207ed34352bff0b06" title="Finishes reading an array.">mpack_done_array()</a></code> or <code><a class="el" href="group__reader.html#ga86165fc780e7adef09f4b45aee54842a" title="Finishes reading a map.">mpack_done_map()</a></code> so that the reader can verify that you read the correct number of elements.</p>
<p >Here's an example of a function that reads a tag from a reader, then reads all of the contained elements recursively:</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> parse_element(<a class="code hl_typedef" href="group__reader.html#gaee791c36a15344b9e57edae160c86615">mpack_reader_t</a>* reader, <span class="keywordtype">int</span> depth) {</div>
<div class="line"> <span class="keywordflow">if</span> (depth &gt;= 32) { <span class="comment">// critical check!</span></div>
<div class="line"> <a class="code hl_function" href="group__reader.html#ga5c45c2e0592f16ae671cd509d8d8c512">mpack_reader_flag_error</a>(reader, <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a575cd33925a41fe7c157162b233b8308">mpack_error_too_big</a>);</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_typedef" href="group__common.html#ga008da69ac6b5582a893f2d2ffd37f4ac">mpack_tag_t</a> tag = <a class="code hl_function" href="group__reader.html#ga70c00ecaf381e9711f6c1d0fa92f0c2f">mpack_read_tag</a>(&amp;reader);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>)</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line"> </div>
<div class="line"> do_something_with_tag(&amp;tag);</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__common.html#gaf3c75dc78631727344e154b82a73d37a">mpack_tag_type</a>(&amp;tag) == <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eabc1bfe5856870df99fa51a39923e6349">mpack_type_array</a>) {</div>
<div class="line"> <span class="keywordflow">for</span> (uint32_t i = <a class="code hl_function" href="group__common.html#ga071204c83da525e2925b4ba13e5eafa6">mpack_tag_array_count</a>(&amp;tag); i &gt; 0; --i) {</div>
<div class="line"> parse_element(reader, depth + 1);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) <span class="comment">// critical check!</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#gaddae460657b9a26207ed34352bff0b06">mpack_done_array</a>(reader);</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__common.html#gaf3c75dc78631727344e154b82a73d37a">mpack_tag_type</a>(&amp;tag) == <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea0cdc6eb2c069333405d0d23602f7006a">mpack_type_map</a>) {</div>
<div class="line"> <span class="keywordflow">for</span> (uint32_t i = <a class="code hl_function" href="group__common.html#ga6fbba834bc069a6973738e00a6106c56">mpack_tag_map_count</a>(&amp;tag); i &gt; 0; --i) {</div>
<div class="line"> parse_element(reader, depth + 1);</div>
<div class="line"> parse_element(reader, depth + 1);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) <span class="comment">// critical check!</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#ga86165fc780e7adef09f4b45aee54842a">mpack_done_map</a>(reader);</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="ttc" id="agroup__common_html_ga071204c83da525e2925b4ba13e5eafa6"><div class="ttname"><a href="group__common.html#ga071204c83da525e2925b4ba13e5eafa6">mpack_tag_array_count</a></div><div class="ttdeci">uint32_t mpack_tag_array_count(mpack_tag_t *tag)</div><div class="ttdoc">Gets the number of elements in an array tag.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:536</div></div>
<div class="ttc" id="agroup__common_html_ga6fbba834bc069a6973738e00a6106c56"><div class="ttname"><a href="group__common.html#ga6fbba834bc069a6973738e00a6106c56">mpack_tag_map_count</a></div><div class="ttdeci">uint32_t mpack_tag_map_count(mpack_tag_t *tag)</div><div class="ttdoc">Gets the number of key-value pairs in a map tag.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:549</div></div>
<div class="ttc" id="agroup__common_html_gaf3c75dc78631727344e154b82a73d37a"><div class="ttname"><a href="group__common.html#gaf3c75dc78631727344e154b82a73d37a">mpack_tag_type</a></div><div class="ttdeci">mpack_type_t mpack_tag_type(mpack_tag_t *tag)</div><div class="ttdoc">Gets the type of a tag.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:432</div></div>
<div class="ttc" id="agroup__common_html_gga22f03cf1240d5a917e1b3e7be8ab327ea0cdc6eb2c069333405d0d23602f7006a"><div class="ttname"><a href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea0cdc6eb2c069333405d0d23602f7006a">mpack_type_map</a></div><div class="ttdeci">@ mpack_type_map</div><div class="ttdoc">An ordered map of key/value pairs of MessagePack objects.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:198</div></div>
<div class="ttc" id="agroup__common_html_gga22f03cf1240d5a917e1b3e7be8ab327eabc1bfe5856870df99fa51a39923e6349"><div class="ttname"><a href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eabc1bfe5856870df99fa51a39923e6349">mpack_type_array</a></div><div class="ttdeci">@ mpack_type_array</div><div class="ttdoc">An array of MessagePack objects.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:197</div></div>
<div class="ttc" id="agroup__common_html_gga9d9f282ca4183ab5190e09d04c1f74c4a575cd33925a41fe7c157162b233b8308"><div class="ttname"><a href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a575cd33925a41fe7c157162b233b8308">mpack_error_too_big</a></div><div class="ttdeci">@ mpack_error_too_big</div><div class="ttdoc">A read or write was bigger than the maximum size allowed for that operation.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:167</div></div>
<div class="ttc" id="agroup__reader_html_ga5c45c2e0592f16ae671cd509d8d8c512"><div class="ttname"><a href="group__reader.html#ga5c45c2e0592f16ae671cd509d8d8c512">mpack_reader_flag_error</a></div><div class="ttdeci">void mpack_reader_flag_error(mpack_reader_t *reader, mpack_error_t error)</div><div class="ttdoc">Places the reader in the given error state, calling the error callback if one is set.</div></div>
<div class="ttc" id="agroup__reader_html_ga79050efd2a581e8216f58d4946e7abc2"><div class="ttname"><a href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a></div><div class="ttdeci">mpack_error_t mpack_reader_error(mpack_reader_t *reader)</div><div class="ttdoc">Queries the error state of the MPack reader.</div><div class="ttdef"><b>Definition:</b> mpack-reader.h:391</div></div>
<div class="ttc" id="agroup__reader_html_ga86165fc780e7adef09f4b45aee54842a"><div class="ttname"><a href="group__reader.html#ga86165fc780e7adef09f4b45aee54842a">mpack_done_map</a></div><div class="ttdeci">void mpack_done_map(mpack_reader_t *reader)</div><div class="ttdoc">Finishes reading a map.</div><div class="ttdef"><b>Definition:</b> mpack-reader.h:772</div></div>
<div class="ttc" id="agroup__reader_html_gaddae460657b9a26207ed34352bff0b06"><div class="ttname"><a href="group__reader.html#gaddae460657b9a26207ed34352bff0b06">mpack_done_array</a></div><div class="ttdeci">void mpack_done_array(mpack_reader_t *reader)</div><div class="ttdoc">Finishes reading an array.</div><div class="ttdef"><b>Definition:</b> mpack-reader.h:761</div></div>
</div><!-- fragment --><p >WARNING: It is critical that we check for errors during each iteration of our array and map loops. If we skip these checks, malicious data could claim to contain billions of elements, throwing us into a very long loop. These checks allow us to break out as soon as we run out of data. Since this function is recursive, we've also added a depth limit to prevent bad data from causing a stack overflow.</p>
<p >(The <a class="el" href="md_docs_node.html">Node API</a> is not vulnerable to such problems. In fact, it can break out of such bad data even sooner. The Node API will automatically flag an error as soon as it realizes that there aren't enough bytes left in the message to fill the remaining elements of all open compound types. If possible, consider using the Node API.)</p>
<p >Unfortunately, the above code has a problem: it does not handle strings or binary blobs. If it encounters them, it will fail because it's not reading their contents.</p>
<h2><a class="anchor" id="autotoc_md10"></a>
Compound Data Chunks</h2>
<p >The data for chunks such as strings and binary blobs must be read separately. Bytes can be read across multiple read calls, as long the total number of bytes you read matches the number of bytes contained in the element. And as with containers, you must call <code><a class="el" href="group__reader.html#gaaad37015e0c53704d9356de06b493de6" title="Finishes reading a string.">mpack_done_str()</a></code> or <code><a class="el" href="group__reader.html#gaa4676c4b0761de4f864fd81c347a15a0" title="Finishes reading a binary data blob.">mpack_done_bin()</a></code> so that the reader can verify that you read the correct total number of bytes.</p>
<p >We can add support for strings to the previous example with the below code. In this example, we read the string incrementally in 128 byte chunks to keep memory usage at an absolute minimum:</p>
<div class="fragment"><div class="line"><span class="keywordflow">if</span> (<a class="code hl_function" href="group__common.html#gaf3c75dc78631727344e154b82a73d37a">mpack_tag_type</a>(&amp;tag) == <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea1e84e3b33ffa7dfc3bde110bd9455d12">mpack_type_str</a>) {</div>
<div class="line"> uint32_t length = <a class="code hl_function" href="group__common.html#ga6a8dc7f85c6673b68454e2ca38c07a5a">mpack_tag_str_length</a>(&amp;tag);</div>
<div class="line"> <span class="keywordtype">char</span> buffer[128];</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">while</span> (length &gt; 0) {</div>
<div class="line"> <span class="keywordtype">size_t</span> step = (length &lt; <span class="keyword">sizeof</span>(buffer)) ? length : <span class="keyword">sizeof</span>(buffer);</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#gaeb91e8d4e2a7b7f6562d8bbb7400275c">mpack_read_bytes</a>(reader, buffer, <span class="keyword">sizeof</span>(buffer);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) <span class="comment">// critical check!</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> </div>
<div class="line"> do_something_with_partial_string(buffer, step);</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_function" href="group__reader.html#gaaad37015e0c53704d9356de06b493de6">mpack_done_str</a>(reader);</div>
<div class="line">}</div>
<div class="ttc" id="agroup__common_html_ga6a8dc7f85c6673b68454e2ca38c07a5a"><div class="ttname"><a href="group__common.html#ga6a8dc7f85c6673b68454e2ca38c07a5a">mpack_tag_str_length</a></div><div class="ttdeci">uint32_t mpack_tag_str_length(mpack_tag_t *tag)</div><div class="ttdoc">Gets the length in bytes of a str-type tag.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:562</div></div>
<div class="ttc" id="agroup__common_html_gga22f03cf1240d5a917e1b3e7be8ab327ea1e84e3b33ffa7dfc3bde110bd9455d12"><div class="ttname"><a href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea1e84e3b33ffa7dfc3bde110bd9455d12">mpack_type_str</a></div><div class="ttdeci">@ mpack_type_str</div><div class="ttdoc">A string.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:195</div></div>
<div class="ttc" id="agroup__reader_html_gaaad37015e0c53704d9356de06b493de6"><div class="ttname"><a href="group__reader.html#gaaad37015e0c53704d9356de06b493de6">mpack_done_str</a></div><div class="ttdeci">void mpack_done_str(mpack_reader_t *reader)</div><div class="ttdoc">Finishes reading a string.</div><div class="ttdef"><b>Definition:</b> mpack-reader.h:783</div></div>
<div class="ttc" id="agroup__reader_html_gaeb91e8d4e2a7b7f6562d8bbb7400275c"><div class="ttname"><a href="group__reader.html#gaeb91e8d4e2a7b7f6562d8bbb7400275c">mpack_read_bytes</a></div><div class="ttdeci">void mpack_read_bytes(mpack_reader_t *reader, char *p, size_t count)</div><div class="ttdoc">Reads bytes from a string, binary blob or extension object, copying them into the given buffer.</div></div>
</div><!-- fragment --><p >As above, we need a safety check to ensure that bad data cannot get us stuck in a loop.</p>
<p >Code for <code>mpack_type_bin</code> is identical except that the type and function names contain <code>bin</code> instead of <code>str</code>.</p>
<h2><a class="anchor" id="autotoc_md11"></a>
In-Place strings</h2>
<p >The MPack reader supports accessing the data contained in compound data types directly out of the reader's buffer. This can provide zero-copy access to strings and binary blobs, provided they fit within the buffer.</p>
<p >To access string or bin data in-place, use <code><a class="el" href="group__reader.html#ga4777ac528d7abbc7313469737546e1a4" title="Reads bytes from a string, binary blob or extension object in-place in the buffer.">mpack_read_bytes_inplace()</a></code> (or <code><a class="el" href="group__reader.html#ga76af5d206358a692b2aeeec6dbeff29c" title="Reads bytes from a string in-place in the buffer and ensures they are valid UTF-8.">mpack_read_utf8_inplace()</a></code> to also check a string's UTF-8 encoding.) This provides a pointer directly into the reader's buffer, moving data around as necessary to make it fit. The previous code could be replaced with:</p>
<div class="fragment"><div class="line"><span class="keywordflow">if</span> (<a class="code hl_function" href="group__common.html#gaf3c75dc78631727344e154b82a73d37a">mpack_tag_type</a>(&amp;tag) == <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea1e84e3b33ffa7dfc3bde110bd9455d12">mpack_type_str</a>) {</div>
<div class="line"> uint32_t length = <a class="code hl_function" href="group__common.html#ga6a8dc7f85c6673b68454e2ca38c07a5a">mpack_tag_str_length</a>(&amp;tag);</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span>* data = <a class="code hl_function" href="group__reader.html#ga4777ac528d7abbc7313469737546e1a4">mpack_read_bytes_inplace</a>(reader, length);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>)</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line"> do_something_with_string(data, length);</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#gaaad37015e0c53704d9356de06b493de6">mpack_done_str</a>(reader);</div>
<div class="line">}</div>
<div class="ttc" id="agroup__reader_html_ga4777ac528d7abbc7313469737546e1a4"><div class="ttname"><a href="group__reader.html#ga4777ac528d7abbc7313469737546e1a4">mpack_read_bytes_inplace</a></div><div class="ttdeci">const char * mpack_read_bytes_inplace(mpack_reader_t *reader, size_t count)</div><div class="ttdoc">Reads bytes from a string, binary blob or extension object in-place in the buffer.</div></div>
</div><!-- fragment --><p >There's an important caveat here though: this will flag an error if the string does not fit in the buffer. If you are decoding a chunk of MessagePack data in memory (without a fill function), then this is not a problem, as it would simply mean that the message was truncated. But if you are decoding from a file or stream, you need to account for the fact that the string may not fit in the buffer.</p>
<p >To work around this, you can provide two paths for reading data depending on the size of the string. MPack provides a helper <code><a class="el" href="group__reader.html#gaa69e23a50f63c84b45f9247db9c22ad0" title="Returns true if it&#39;s a good idea to read the given number of bytes in-place.">mpack_should_read_bytes_inplace()</a></code> to tell you if it's a good idea to read in-place. Here's another example that uses zero-copy strings where possible, and falls back to an allocation otherwise:</p>
<div class="fragment"><div class="line"><span class="keywordflow">if</span> (<a class="code hl_function" href="group__common.html#gaf3c75dc78631727344e154b82a73d37a">mpack_tag_type</a>(&amp;tag) == <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea1e84e3b33ffa7dfc3bde110bd9455d12">mpack_type_str</a>) {</div>
<div class="line"> uint32_t length = <a class="code hl_function" href="group__common.html#ga6a8dc7f85c6673b68454e2ca38c07a5a">mpack_tag_str_length</a>(&amp;tag);</div>
<div class="line"> <span class="keywordflow">if</span> (length &gt;= 16 * 1024) { <span class="comment">// critical check! limit length to avoid a huge allocation</span></div>
<div class="line"> <a class="code hl_function" href="group__reader.html#ga5c45c2e0592f16ae671cd509d8d8c512">mpack_reader_flag_error</a>(reader, <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a575cd33925a41fe7c157162b233b8308">mpack_error_too_big</a>);</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#gaa69e23a50f63c84b45f9247db9c22ad0">mpack_should_read_bytes_inplace</a>(reader, length)) {</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span>* data = <a class="code hl_function" href="group__reader.html#ga4777ac528d7abbc7313469737546e1a4">mpack_read_bytes_inplace</a>(reader, length);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>)</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line"> do_something_with_string(data, length);</div>
<div class="line"> </div>
<div class="line"> } <span class="keywordflow">else</span> {</div>
<div class="line"> <span class="keywordtype">char</span>* data = malloc(length);</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#gaeb91e8d4e2a7b7f6562d8bbb7400275c">mpack_read_bytes</a>(reader, data, length);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) {</div>
<div class="line"> free(data);</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line"> }</div>
<div class="line"> do_something_with_string(data, length);</div>
<div class="line"> free(data);</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_function" href="group__reader.html#gaaad37015e0c53704d9356de06b493de6">mpack_done_str</a>(reader);</div>
<div class="line">}</div>
<div class="ttc" id="agroup__reader_html_gaa69e23a50f63c84b45f9247db9c22ad0"><div class="ttname"><a href="group__reader.html#gaa69e23a50f63c84b45f9247db9c22ad0">mpack_should_read_bytes_inplace</a></div><div class="ttdeci">bool mpack_should_read_bytes_inplace(mpack_reader_t *reader, size_t count)</div><div class="ttdoc">Returns true if it's a good idea to read the given number of bytes in-place.</div><div class="ttdef"><b>Definition:</b> mpack-reader.h:708</div></div>
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md12"></a>
Expected Types</h1>
<p >When parsing data of expected types from a dynamic stream, you will likely want to hardcode type checks before each access. For example:</p>
<div class="fragment"><div class="line"><span class="comment">// get a bool</span></div>
<div class="line"><a class="code hl_typedef" href="group__common.html#ga008da69ac6b5582a893f2d2ffd37f4ac">mpack_tag_t</a> tag = <a class="code hl_function" href="group__reader.html#ga70c00ecaf381e9711f6c1d0fa92f0c2f">mpack_read_tag</a>(reader);</div>
<div class="line"><span class="keywordflow">if</span> (<a class="code hl_function" href="group__common.html#gaf3c75dc78631727344e154b82a73d37a">mpack_tag_type</a>(&amp;tag) != <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea09eeb9595c0537ed4cdf2b11a4dd4d59">mpack_type_bool</a>) {</div>
<div class="line"> perror(<span class="stringliteral">&quot;not a bool!&quot;</span>);</div>
<div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line">}</div>
<div class="line"><span class="keywordtype">bool</span> value = <a class="code hl_function" href="group__common.html#ga8c0f7e30e7c3484ea96b8f154bbf72a1">mpack_tag_bool_value</a>(&amp;tag);</div>
<div class="ttc" id="agroup__common_html_ga8c0f7e30e7c3484ea96b8f154bbf72a1"><div class="ttname"><a href="group__common.html#ga8c0f7e30e7c3484ea96b8f154bbf72a1">mpack_tag_bool_value</a></div><div class="ttdeci">bool mpack_tag_bool_value(mpack_tag_t *tag)</div><div class="ttdoc">Gets the boolean value of a bool-type tag.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:443</div></div>
<div class="ttc" id="agroup__common_html_gga22f03cf1240d5a917e1b3e7be8ab327ea09eeb9595c0537ed4cdf2b11a4dd4d59"><div class="ttname"><a href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea09eeb9595c0537ed4cdf2b11a4dd4d59">mpack_type_bool</a></div><div class="ttdeci">@ mpack_type_bool</div><div class="ttdoc">A boolean (true or false.)</div><div class="ttdef"><b>Definition:</b> mpack-common.h:190</div></div>
</div><!-- fragment --><p >MPack provides helper functions that perform these checks in the <a class="el" href="md_docs_expect.html">Expect API</a>. The above code for example could be replaced by a single call to <code><a class="el" href="group__expect.html#gaeafa42ca3ae974494f127eb4b56ed8ae" title="Reads a boolean.">mpack_expect_bool()</a></code>. If the value is not a bool, it will flag an error and return <code>false</code>. This is the incremental reader analogue to <code><a class="el" href="group__writer.html#ga5d8fa89f571534f5ddbdf81f5bbd5de8" title="Writes a boolean.">mpack_write_bool()</a></code>.</p>
<p >These helpers are strongly recommended because they will perform range checks and lossless conversions where needed. For example, suppose you want to read an <code>int</code>. A positive integer could be stored in a tag as two different types (<code>mpack_type_int</code> or <code>mpack_type_uint</code>), and the value of that integer could be outside the range of an <code>int</code>. The functions <code><a class="el" href="group__expect.html#gae81b9d03f80e49501c9b9a695489315f" title="Reads a signed int.">mpack_expect_int()</a></code> supports both types and performs the appropriate range checks. It will convert losslessly as needed and flag an error if the value doesn't fit.</p>
<p >Note that when using the expect functions, you still need to read the contents of compound types and call the corresponding done function. A call to an expect function only replaces a call to <code><a class="el" href="group__reader.html#ga70c00ecaf381e9711f6c1d0fa92f0c2f" title="Reads a MessagePack object header (an MPack tag.)">mpack_read_tag()</a></code>. For example:</p>
<div class="fragment"><div class="line">uint32_t length = <a class="code hl_function" href="group__expect.html#ga6baba88194988c9f423630052d59f7fd">mpack_expect_str</a>(reader);</div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span>* data = <a class="code hl_function" href="group__reader.html#ga4777ac528d7abbc7313469737546e1a4">mpack_read_bytes_inplace</a>(reader, length);</div>
<div class="line"><span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) == <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>)</div>
<div class="line"> do_something_with_string(data, length);</div>
<div class="line"><a class="code hl_function" href="group__reader.html#gaaad37015e0c53704d9356de06b493de6">mpack_done_str</a>(reader);</div>
<div class="ttc" id="agroup__expect_html_ga6baba88194988c9f423630052d59f7fd"><div class="ttname"><a href="group__expect.html#ga6baba88194988c9f423630052d59f7fd">mpack_expect_str</a></div><div class="ttdeci">uint32_t mpack_expect_str(mpack_reader_t *reader)</div><div class="ttdoc">Reads the start of a string, returning its size in bytes.</div></div>
</div><!-- fragment --><p >If you want to always check that types match what you expect, head on over to the <a class="el" href="md_docs_expect.html">Expect API</a> and use these type checking functions. But if you are still interested in handling the dynamic runtime type of elements, read on.</p>
<h1><a class="anchor" id="autotoc_md13"></a>
Event-Based Parser</h1>
<p >In this example, we'll implement a SAX-style event-based parser for blobs of MessagePack using the Reader API. This is a good example of non-trivial MPack usage that handles the dynamic type of incrementally parsed MessagePack data. It's easy to convert any incremental parser to an event-based parser, as we'll soon see.</p>
<p >First let's define a header file with a list of callbacks for our parser, and our single function to launch the parser:</p>
<div class="fragment"><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>sax_callbacks_t {</div>
<div class="line"> void (*nil_element)(<span class="keywordtype">void</span>* context);</div>
<div class="line"> void (*bool_element)(<span class="keywordtype">void</span>* context, int64_t value);</div>
<div class="line"> void (*int_element)(<span class="keywordtype">void</span>* context, int64_t value);</div>
<div class="line"> void (*uint_element)(<span class="keywordtype">void</span>* context, uint64_t value);</div>
<div class="line"> void (*string_element)(<span class="keywordtype">void</span>* context, <span class="keyword">const</span> <span class="keywordtype">char</span>* data, uint32_t length);</div>
<div class="line"> </div>
<div class="line"> void (*start_map)(<span class="keywordtype">void</span>* context, uint32_t pair_count);</div>
<div class="line"> void (*start_array)(<span class="keywordtype">void</span>* context, uint32_t element_count);</div>
<div class="line"> void (*finish_map)(<span class="keywordtype">void</span>* context);</div>
<div class="line"> void (*finish_array)(<span class="keywordtype">void</span>* context);</div>
<div class="line">} sax_callbacks_t;</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">bool</span> parse_messagepack(<span class="keyword">const</span> <span class="keywordtype">char</span>* data, <span class="keywordtype">size_t</span> length,</div>
<div class="line"> <span class="keyword">const</span> sax_callbacks_t* callbacks, <span class="keywordtype">void</span>* context);</div>
</div><!-- fragment --><p >Next we'll define our <code>parse_messagepack()</code> function in a corresponding source file to set our our reader. This will wrap another function called <code>parse_element()</code>.</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> parse_element(<a class="code hl_typedef" href="group__reader.html#gaee791c36a15344b9e57edae160c86615">mpack_reader_t</a>* reader, <span class="keywordtype">int</span> depth,</div>
<div class="line"> <span class="keyword">const</span> sax_callbacks_t* callbacks, <span class="keywordtype">void</span>* context);</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">bool</span> parse_messagepack(<span class="keyword">const</span> <span class="keywordtype">char</span>* data, <span class="keywordtype">size_t</span> length,</div>
<div class="line"> <span class="keyword">const</span> sax_callbacks_t* callbacks, <span class="keywordtype">void</span>* context)</div>
<div class="line">{</div>
<div class="line"> <a class="code hl_typedef" href="group__reader.html#gaee791c36a15344b9e57edae160c86615">mpack_reader_t</a> reader;</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#ga18f41d6786155f265769351ef550e331">mpack_reader_init_data</a>(&amp;reader, data, length);</div>
<div class="line"> parse_element(&amp;reader, 0, callbacks, context);</div>
<div class="line"> <span class="keywordflow">return</span> <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a> == <a class="code hl_function" href="group__reader.html#gac04666405e21eea6e8819182571f0d20">mpack_reader_destroy</a>(&amp;reader);</div>
<div class="line">}</div>
</div><!-- fragment --><p >We'll make <code>parse_element()</code> recursive to keep things simple. This makes it extremely straightforward to implement. We just parse a tag, switch on the type, and call the appropriate callback function.</p>
<p >Note that we can access all strings in-place because the source data is a single chunk of contiguous memory.</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> parse_element(<a class="code hl_typedef" href="group__reader.html#gaee791c36a15344b9e57edae160c86615">mpack_reader_t</a>* reader, <span class="keywordtype">int</span> depth,</div>
<div class="line"> <span class="keyword">const</span> sax_callbacks_t* callbacks, <span class="keywordtype">void</span>* context)</div>
<div class="line">{</div>
<div class="line"> <span class="keywordflow">if</span> (depth &gt;= 32) { <span class="comment">// critical check!</span></div>
<div class="line"> <a class="code hl_function" href="group__reader.html#ga5c45c2e0592f16ae671cd509d8d8c512">mpack_reader_flag_error</a>(reader, <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a575cd33925a41fe7c157162b233b8308">mpack_error_too_big</a>);</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_typedef" href="group__common.html#ga008da69ac6b5582a893f2d2ffd37f4ac">mpack_tag_t</a> tag = <a class="code hl_function" href="group__reader.html#ga70c00ecaf381e9711f6c1d0fa92f0c2f">mpack_read_tag</a>(reader);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>)</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">switch</span> (<a class="code hl_function" href="group__common.html#gaf3c75dc78631727344e154b82a73d37a">mpack_tag_type</a>(&amp;tag)) {</div>
<div class="line"> <span class="keywordflow">case</span> <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eaade66ddfcf1133c0ac00015ab26bd2b4">mpack_type_nil</a>:</div>
<div class="line"> callbacks-&gt;nil_element(context);</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> <span class="keywordflow">case</span> <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea09eeb9595c0537ed4cdf2b11a4dd4d59">mpack_type_bool</a>:</div>
<div class="line"> callbacks-&gt;bool_element(context, <a class="code hl_function" href="group__common.html#ga8c0f7e30e7c3484ea96b8f154bbf72a1">mpack_tag_bool_value</a>(&amp;tag));</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> <span class="keywordflow">case</span> <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eab3ad5f31d28f4102ec5b9eee498f186e">mpack_type_int</a>:</div>
<div class="line"> callbacks-&gt;int_element(context, <a class="code hl_function" href="group__common.html#gace2efaa8a795db3365f9a0deee4e3391">mpack_tag_int_value</a>(&amp;tag));</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> <span class="keywordflow">case</span> <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eae163adb67a277a223bbfe62ff3d42654">mpack_type_uint</a>:</div>
<div class="line"> callbacks-&gt;uint_element(context, <a class="code hl_function" href="group__common.html#gaec6577f0333c2a7775c5e78757fe89f8">mpack_tag_uint_value</a>(&amp;tag));</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">case</span> <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea1e84e3b33ffa7dfc3bde110bd9455d12">mpack_type_str</a>: {</div>
<div class="line"> uint32_t length = <a class="code hl_function" href="group__common.html#ga6a8dc7f85c6673b68454e2ca38c07a5a">mpack_tag_str_length</a>(&amp;tag);</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span>* data = <a class="code hl_function" href="group__reader.html#ga4777ac528d7abbc7313469737546e1a4">mpack_read_bytes_inplace</a>(reader, length);</div>
<div class="line"> callbacks-&gt;string_element(context, data, length);</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#gaaad37015e0c53704d9356de06b493de6">mpack_done_str</a>(reader);</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">case</span> <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eabc1bfe5856870df99fa51a39923e6349">mpack_type_array</a>: {</div>
<div class="line"> uint32_t count = <a class="code hl_function" href="group__common.html#ga071204c83da525e2925b4ba13e5eafa6">mpack_tag_array_count</a>(&amp;tag);</div>
<div class="line"> callbacks-&gt;start_array(context, count);</div>
<div class="line"> <span class="keywordflow">while</span> (count-- &gt; 0) {</div>
<div class="line"> parse_element(reader, depth + 1, callbacks, context);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) <span class="comment">// critical check!</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"> callbacks-&gt;finish_array(context);</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#gaddae460657b9a26207ed34352bff0b06">mpack_done_array</a>(reader);</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">case</span> <a class="code hl_enumvalue" href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327ea0cdc6eb2c069333405d0d23602f7006a">mpack_type_map</a>: {</div>
<div class="line"> uint32_t count = <a class="code hl_function" href="group__common.html#ga6fbba834bc069a6973738e00a6106c56">mpack_tag_map_count</a>(&amp;tag);</div>
<div class="line"> callbacks-&gt;start_map(context, count);</div>
<div class="line"> <span class="keywordflow">while</span> (count-- &gt; 0) {</div>
<div class="line"> parse_element(reader, depth + 1, callbacks, context);</div>
<div class="line"> parse_element(reader, depth + 1, callbacks, context);</div>
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(reader) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) <span class="comment">// critical check!</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"> callbacks-&gt;finish_map(context);</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#ga86165fc780e7adef09f4b45aee54842a">mpack_done_map</a>(reader);</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">default</span>:</div>
<div class="line"> <a class="code hl_function" href="group__reader.html#ga5c45c2e0592f16ae671cd509d8d8c512">mpack_reader_flag_error</a>(reader, <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a8618d0842dfb9b10c09feccef4794eee">mpack_error_unsupported</a>);</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="ttc" id="agroup__common_html_gace2efaa8a795db3365f9a0deee4e3391"><div class="ttname"><a href="group__common.html#gace2efaa8a795db3365f9a0deee4e3391">mpack_tag_int_value</a></div><div class="ttdeci">int64_t mpack_tag_int_value(mpack_tag_t *tag)</div><div class="ttdoc">Gets the signed integer value of an int-type tag.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:461</div></div>
<div class="ttc" id="agroup__common_html_gaec6577f0333c2a7775c5e78757fe89f8"><div class="ttname"><a href="group__common.html#gaec6577f0333c2a7775c5e78757fe89f8">mpack_tag_uint_value</a></div><div class="ttdeci">uint64_t mpack_tag_uint_value(mpack_tag_t *tag)</div><div class="ttdoc">Gets the unsigned integer value of a uint-type tag.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:479</div></div>
<div class="ttc" id="agroup__common_html_gga22f03cf1240d5a917e1b3e7be8ab327eaade66ddfcf1133c0ac00015ab26bd2b4"><div class="ttname"><a href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eaade66ddfcf1133c0ac00015ab26bd2b4">mpack_type_nil</a></div><div class="ttdeci">@ mpack_type_nil</div><div class="ttdoc">A null value.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:189</div></div>
<div class="ttc" id="agroup__common_html_gga22f03cf1240d5a917e1b3e7be8ab327eab3ad5f31d28f4102ec5b9eee498f186e"><div class="ttname"><a href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eab3ad5f31d28f4102ec5b9eee498f186e">mpack_type_int</a></div><div class="ttdeci">@ mpack_type_int</div><div class="ttdoc">A 64-bit signed integer.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:191</div></div>
<div class="ttc" id="agroup__common_html_gga22f03cf1240d5a917e1b3e7be8ab327eae163adb67a277a223bbfe62ff3d42654"><div class="ttname"><a href="group__common.html#gga22f03cf1240d5a917e1b3e7be8ab327eae163adb67a277a223bbfe62ff3d42654">mpack_type_uint</a></div><div class="ttdeci">@ mpack_type_uint</div><div class="ttdoc">A 64-bit unsigned integer.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:192</div></div>
<div class="ttc" id="agroup__common_html_gga9d9f282ca4183ab5190e09d04c1f74c4a8618d0842dfb9b10c09feccef4794eee"><div class="ttname"><a href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a8618d0842dfb9b10c09feccef4794eee">mpack_error_unsupported</a></div><div class="ttdeci">@ mpack_error_unsupported</div><div class="ttdoc">The data read is not supported by this configuration of MPack.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:165</div></div>
</div><!-- fragment --><p >As above, the error checks within loops are critical to keep the parser safe against untrusted data.</p>
<p >This is all that is needed to convert MPack into an event-based parser. </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.5
</small></address>
</body>
</html>