src.dualinventive.com/fw/dncm/libdi/3rdparty/mpack/docs/md_docs_expect.html

114 lines
27 KiB
HTML

<!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.11"/>
<title>MPack: Using the Expect 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>
<script type="text/javascript">
$(document).ready(function() { init_search(); });
</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 style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">MPack
&#160;<span id="projectnumber">0.8.2</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.8.11 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main&#160;Page</span></a></li>
<li class="current"><a href="pages.html"><span>Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li>
<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>
</li>
</ul>
</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">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">Using the Expect API </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>The Expect API is used to imperatively parse data of a fixed (hardcoded) schema. It is most useful when parsing very large MessagePack files, parsing in memory-constrained environments, or generating parsing code from a schema. The API is similar to <a href="https://github.com/camgunz/cmp">CMP</a>, but has many helper functions especially for map keys and expected value ranges. Some of these will be covered below.</p>
<p><em>If you are not writing code for an embedded device or generating parsing code from a schema, you should not follow this guide. You should most likely be using the Node API instead.</em></p>
<h2>A simple example</h2>
<p>Suppose we have data that we know will have the following schema:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;an array containing three elements</div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160; a UTF-8 string of at most 127 characters</div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160; a UTF-8 string of at most 127 characters</div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160; an array containing up to ten elements</div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span>&#160; where all elements are ints</div></div><!-- fragment --><p>For example, we could have the following bytes in a MessagePack file called <code>example.mp</code>:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;93 # an array containing three elements</div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160; a5 68 65 6c 6c 6f # &quot;hello&quot;</div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160; a6 77 6f 72 6c 64 21 # &quot;world!&quot;</div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160; 94 # an array containing four elements</div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span>&#160; 01 # 1</div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span>&#160; 02 # 2</div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span>&#160; 03 # 3</div><div class="line"><a name="l00008"></a><span class="lineno"> 8</span>&#160; 04 # 4</div></div><!-- fragment --><p>In JSON this would look like this:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;[</div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160; &quot;hello&quot;,</div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160; &quot;world!&quot;,</div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160; [</div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span>&#160; 1,</div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span>&#160; 2,</div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span>&#160; 3,</div><div class="line"><a name="l00008"></a><span class="lineno"> 8</span>&#160; 4</div><div class="line"><a name="l00009"></a><span class="lineno"> 9</span>&#160; ]</div><div class="line"><a name="l00010"></a><span class="lineno"> 10</span>&#160;]</div></div><!-- fragment --><p>You can use <a href="https://github.com/ludocode/msgpack-tools">msgpack-tools</a> with the above JSON to generate <code>example.mp</code>. The below code demonstrates reading this data from a file using the Expect API:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;mpack.h&quot;</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">void</span>) {</div><div class="line"></div><div class="line"> <span class="comment">// initialize a reader from a file</span></div><div class="line"> <a class="code" href="group__reader.html#gaee791c36a15344b9e57edae160c86615">mpack_reader_t</a> reader;</div><div class="line"> <a class="code" href="group__reader.html#ga957b5be20debe9f3b81b629478bda0f5">mpack_reader_init_file</a>(&amp;reader, <span class="stringliteral">&quot;example.mp&quot;</span>);</div><div class="line"></div><div class="line"> <span class="comment">// the top-level array must have exactly three elements</span></div><div class="line"> <a class="code" href="group__expect.html#ga799bb820a49f5a8a70e604466f8ab9b5">mpack_expect_array_match</a>(&amp;reader, 3);</div><div class="line"></div><div class="line"> <span class="comment">// the first two elements are short strings</span></div><div class="line"> <span class="keywordtype">char</span> first[128];</div><div class="line"> <span class="keywordtype">char</span> second[128];</div><div class="line"> <a class="code" href="group__expect.html#ga62be63032f3c84181eeed4609f0dddb4">mpack_expect_utf8_cstr</a>(&amp;reader, first, <span class="keyword">sizeof</span>(first));</div><div class="line"> <a class="code" href="group__expect.html#ga62be63032f3c84181eeed4609f0dddb4">mpack_expect_utf8_cstr</a>(&amp;reader, second, <span class="keyword">sizeof</span>(second));</div><div class="line"></div><div class="line"> <span class="comment">// next we have an array of up to ten ints</span></div><div class="line"> int32_t numbers[10];</div><div class="line"> <span class="keywordtype">size_t</span> count = <a class="code" href="group__expect.html#ga3e1599675ca83c5c03af8de220b9a826">mpack_expect_array_max</a>(&amp;reader, <span class="keyword">sizeof</span>(numbers) / <span class="keyword">sizeof</span>(numbers[0]));</div><div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = 0; i &lt; count; ++i)</div><div class="line"> numbers[i] = <a class="code" href="group__expect.html#gaddca7f73951f581f0ddf03f6755322cf">mpack_expect_i32</a>(&amp;reader);</div><div class="line"> <a class="code" href="group__reader.html#gaddae460657b9a26207ed34352bff0b06">mpack_done_array</a>(&amp;reader);</div><div class="line"></div><div class="line"> <span class="comment">// done reading the top-level array</span></div><div class="line"> <a class="code" href="group__reader.html#gaddae460657b9a26207ed34352bff0b06">mpack_done_array</a>(&amp;reader);</div><div class="line"></div><div class="line"> <span class="comment">// clean up and handle errors</span></div><div class="line"> <a class="code" href="group__common.html#ga9d9f282ca4183ab5190e09d04c1f74c4">mpack_error_t</a> error = <a class="code" href="group__reader.html#gac04666405e21eea6e8819182571f0d20">mpack_reader_destroy</a>(&amp;reader);</div><div class="line"> <span class="keywordflow">if</span> (error != <a class="code" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) {</div><div class="line"> fprintf(stderr, <span class="stringliteral">&quot;Error %i occurred reading data!\n&quot;</span>, (<span class="keywordtype">int</span>)error);</div><div class="line"> <span class="keywordflow">return</span> EXIT_FAILURE;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// we now know the data was parsed correctly and can safely</span></div><div class="line"> <span class="comment">// be used. the strings are null-terminated and valid UTF-8,</span></div><div class="line"> <span class="comment">// the array contained at most ten elements, and the numbers</span></div><div class="line"> <span class="comment">// are all within the range of an int32_t.</span></div><div class="line"> printf(<span class="stringliteral">&quot;%s\n&quot;</span>, first);</div><div class="line"> printf(<span class="stringliteral">&quot;%s\n&quot;</span>, second);</div><div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = 0; i &lt; count; ++i)</div><div class="line"> printf(<span class="stringliteral">&quot;%i &quot;</span>, numbers[i]);</div><div class="line"> printf(<span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> EXIT_SUCCESS;</div><div class="line">}</div></div><!-- fragment --><p>With the file given above, this example will print:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;hello</div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160;world!</div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160;1 2 3 4 </div></div><!-- fragment --><p>Note that there is only a single error check in this example. In fact each call to the reader is checking for errors and storing any error in the reader. These could be errors from reading data from the file, from invalid or corrupt MessagePack, or from not matching our expected types or ranges. On any call to the reader, if the reader was already in error or an error occurs during the call, a safe value is returned.</p>
<p>For example the <code><a class="el" href="group__expect.html#ga3e1599675ca83c5c03af8de220b9a826" title="Reads the start of an array with a number of elements at most max_count, returning its element count...">mpack_expect_array_max()</a></code> call above will return zero if the element is not an array, if it has more than ten elements, if the MessagePack data is corrupt, or even if the file does not exist. The <code><a class="el" href="group__expect.html#ga62be63032f3c84181eeed4609f0dddb4" title="Reads a string into the given buffer, ensures it is a valid UTF-8 string without NUL characters...">mpack_expect_utf8_cstr()</a></code> calls will also place a null-terminator at the start of the given buffer if any error occurs just in case the data is used without an error check. The error check can be performed later at a more convenient time.</p>
<h2>Maps</h2>
<p>Maps can be more complicated to read because you usually want to safely handle keys being re-ordered. MessagePack itself does not specify whether maps can be re-ordered, so if you are sticking only to MessagePack implementations that preserve ordering, it may not be strictly necessary to handle this. (MPack always preserves map key ordering.) However many MessagePack implementations will ignore the order of map keys in the original data, especially in scripting languages where the data will be parsed into or encoded from an unordered map or dict. If you plan to interoperate with them, you will need to allow keys to be re-ordered.</p>
<p>Suppose we expect to receive a map containing two key/value pairs: a key called "compact" with a boolean value, and a key called "schema" with an int value. The example on the <a href="http://msgpack.org/">MessagePack homepage</a> fits this schema, which looks like this in JSON:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;{</div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160; &quot;compact&quot;: true,</div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160; &quot;schema&quot;: 0</div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160;}</div></div><!-- fragment --><p>If we also expect the key called "compact" to always come first, then parsing this is straightforward:</p>
<div class="fragment"><div class="line"><a class="code" href="group__expect.html#gab66c8c170be1b394b397ccc041d6c133">mpack_expect_map_match</a>(&amp;reader, 2);</div><div class="line"><a class="code" href="group__expect.html#ga8f16d7ec771277e1be2a35ea0573db31">mpack_expect_cstr_match</a>(&amp;reader, <span class="stringliteral">&quot;compact&quot;</span>);</div><div class="line"><span class="keywordtype">bool</span> compact = <a class="code" href="group__expect.html#gaeafa42ca3ae974494f127eb4b56ed8ae">mpack_expect_bool</a>(&amp;reader);</div><div class="line"><a class="code" href="group__expect.html#ga8f16d7ec771277e1be2a35ea0573db31">mpack_expect_cstr_match</a>(&amp;reader, <span class="stringliteral">&quot;schema&quot;</span>);</div><div class="line"><span class="keywordtype">int</span> schema = <a class="code" href="group__expect.html#gae81b9d03f80e49501c9b9a695489315f">mpack_expect_int</a>(&amp;reader);</div><div class="line"><a class="code" href="group__reader.html#ga86165fc780e7adef09f4b45aee54842a">mpack_done_map</a>(&amp;reader);</div></div><!-- fragment --><p>If we expect the "schema" key to be optional, but always after "compact", then parsing this is longer but still straightforward:</p>
<div class="fragment"><div class="line"><span class="keywordtype">size_t</span> count = <a class="code" href="group__expect.html#ga36d86c85877f94aa7b493aaa739c8849">mpack_expect_map_max</a>(&amp;reader, 2);</div><div class="line"></div><div class="line"><a class="code" href="group__expect.html#ga8f16d7ec771277e1be2a35ea0573db31">mpack_expect_cstr_match</a>(&amp;reader, <span class="stringliteral">&quot;compact&quot;</span>);</div><div class="line"><span class="keywordtype">bool</span> compact = <a class="code" href="group__expect.html#gaeafa42ca3ae974494f127eb4b56ed8ae">mpack_expect_bool</a>(&amp;reader);</div><div class="line"></div><div class="line"><span class="keywordtype">bool</span> has_schema = <span class="keyword">false</span>;</div><div class="line"><span class="keywordtype">int</span> schema = -1;</div><div class="line"><span class="keywordflow">if</span> (count == 0) {</div><div class="line"> <a class="code" href="group__expect.html#ga8f16d7ec771277e1be2a35ea0573db31">mpack_expect_cstr_match</a>(&amp;reader, <span class="stringliteral">&quot;schema&quot;</span>);</div><div class="line"> schema = <a class="code" href="group__expect.html#gae81b9d03f80e49501c9b9a695489315f">mpack_expect_int</a>(&amp;reader);</div><div class="line">}</div><div class="line"></div><div class="line"><a class="code" href="group__reader.html#ga86165fc780e7adef09f4b45aee54842a">mpack_done_map</a>(&amp;reader);</div></div><!-- fragment --><p>If however we want to allow keys to be re-ordered, then parsing this can become a lot more verbose. You need to switch on the key, but you also need to track whether each key has been used to prevent duplicate keys and ensure that required keys were found. Using the <code><a class="el" href="group__expect.html#ga94489d03628c1fb1a3d0ac6971600fe8" title="Reads a string into the given buffer, ensures it has no null bytes, and adds a null-terminator at the...">mpack_expect_cstr()</a></code> directly for keys, this would look like this:</p>
<div class="fragment"><div class="line"><span class="keywordtype">bool</span> has_compact = <span class="keyword">false</span>;</div><div class="line"><span class="keywordtype">bool</span> compact = <span class="keyword">false</span>;</div><div class="line"><span class="keywordtype">bool</span> has_schema = <span class="keyword">false</span>;</div><div class="line"><span class="keywordtype">int</span> schema = -1;</div><div class="line"></div><div class="line"><span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = <a class="code" href="group__expect.html#ga36d86c85877f94aa7b493aaa739c8849">mpack_expect_map_max</a>(&amp;reader, 100); i &gt; 0 &amp;&amp; <a class="code" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(&amp;reader) == <a class="code" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>; --i) {</div><div class="line"> <span class="keywordtype">char</span> key[20];</div><div class="line"> <a class="code" href="group__expect.html#ga94489d03628c1fb1a3d0ac6971600fe8">mpack_expect_cstr</a>(&amp;reader, key, <span class="keyword">sizeof</span>(key));</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (strcmp(key, <span class="stringliteral">&quot;compact&quot;</span>) == 0) {</div><div class="line"> <span class="keywordflow">if</span> (has_compact)</div><div class="line"> mpack_flag_error(&amp;reader, <a class="code" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4ae53cbed8fcc42915d71ae37d121b22e8">mpack_error_data</a>); <span class="comment">// duplicate key</span></div><div class="line"> has_compact = <span class="keyword">true</span>;</div><div class="line"> compact = <a class="code" href="group__expect.html#gaeafa42ca3ae974494f127eb4b56ed8ae">mpack_expect_bool</a>(&amp;reader);</div><div class="line"></div><div class="line"> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (strcmp(key, <span class="stringliteral">&quot;schema&quot;</span>) == 0) {</div><div class="line"> <span class="keywordflow">if</span> (has_schema)</div><div class="line"> mpack_flag_error(&amp;reader, <a class="code" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4ae53cbed8fcc42915d71ae37d121b22e8">mpack_error_data</a>); <span class="comment">// duplicate key</span></div><div class="line"> has_schema = <span class="keyword">true</span>;</div><div class="line"> schema = <a class="code" href="group__expect.html#gae81b9d03f80e49501c9b9a695489315f">mpack_expect_int</a>(&amp;reader);</div><div class="line"></div><div class="line"> } <span class="keywordflow">else</span> {</div><div class="line"> <a class="code" href="group__reader.html#ga438bb2b85fbbd06cd8f10d5c8079427e">mpack_discard</a>(&amp;reader);</div><div class="line"> }</div><div class="line"></div><div class="line">}</div><div class="line"><a class="code" href="group__reader.html#ga86165fc780e7adef09f4b45aee54842a">mpack_done_map</a>(&amp;reader);</div><div class="line"></div><div class="line"><span class="comment">// compact is not optional</span></div><div class="line"><span class="keywordflow">if</span> (!has_compact)</div><div class="line"> <a class="code" href="group__reader.html#ga5c45c2e0592f16ae671cd509d8d8c512">mpack_reader_flag_error</a>(&amp;reader, <a class="code" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4ae53cbed8fcc42915d71ae37d121b22e8">mpack_error_data</a>);</div></div><!-- fragment --><p>This is obviously way too verbose. In order to simplify this code, MPack includes an Expect function called <code><a class="el" href="group__expect.html#gada27a479e6ad56faaa14528d1a3dfb26" title="Expects a string map key matching one of the strings in the given key list, marking it as found in th...">mpack_expect_key_cstr()</a></code> to switch on string keys. This function should be passed an array of key strings and an array of bool flags storing whether each key was found. It will find the key in the given string array, check for duplicate keys, and return the index of the found key (or the key count if it is unrecognized or if an error occurs.) You would use it with an <code>enum</code> and a <code>switch</code>, like this:</p>
<div class="fragment"><div class="line"><span class="keyword">enum</span> key_names {KEY_COMPACT, KEY_SCHEMA, KEY_COUNT};</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span>* keys[] = {<span class="stringliteral">&quot;compact&quot;</span> , <span class="stringliteral">&quot;schema&quot;</span> };</div><div class="line"></div><div class="line"><span class="keywordtype">bool</span> found[KEY_COUNT] = {0};</div><div class="line"><span class="keywordtype">bool</span> compact = <span class="keyword">false</span>;</div><div class="line"><span class="keywordtype">int</span> schema = -1;</div><div class="line"></div><div class="line"><span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = <a class="code" href="group__expect.html#ga36d86c85877f94aa7b493aaa739c8849">mpack_expect_map_max</a>(&amp;reader, 100); i &gt; 0 &amp;&amp; <a class="code" href="group__reader.html#ga79050efd2a581e8216f58d4946e7abc2">mpack_reader_error</a>(&amp;reader) == <a class="code" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>; --i) {</div><div class="line"> <span class="keywordflow">switch</span> (<a class="code" href="group__expect.html#gada27a479e6ad56faaa14528d1a3dfb26">mpack_expect_key_cstr</a>(&amp;reader, keys, found, key_count)) {</div><div class="line"> <span class="keywordflow">case</span> KEY_COMPACT: compact = <a class="code" href="group__expect.html#gaeafa42ca3ae974494f127eb4b56ed8ae">mpack_expect_bool</a>(&amp;reader); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> KEY_SCHEMA: schema = <a class="code" href="group__expect.html#gae81b9d03f80e49501c9b9a695489315f">mpack_expect_int</a>(&amp;reader); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">default</span>: <a class="code" href="group__reader.html#ga438bb2b85fbbd06cd8f10d5c8079427e">mpack_discard</a>(&amp;reader); <span class="keywordflow">break</span>;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// compact is not optional</span></div><div class="line"><span class="keywordflow">if</span> (!found[KEY_COMPACT])</div><div class="line"> <a class="code" href="group__reader.html#ga5c45c2e0592f16ae671cd509d8d8c512">mpack_reader_flag_error</a>(&amp;reader, <a class="code" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4ae53cbed8fcc42915d71ae37d121b22e8">mpack_error_data</a>);</div></div><!-- fragment --><p>In the above examples, the call to <code>mpack_discard(&amp;reader);</code> skips over the value for unrecognized keys, allowing the format to be extensible and providing forwards-compatibility. If you want to forbid unrecognized keys, you can flag an error (e.g. <code>mpack_reader_flag_error(&amp;reader, mpack_error_data);</code>) instead of discarding the value.</p>
<p><em>Note above the importance of using a reasonable limit on <code><a class="el" href="group__expect.html#ga36d86c85877f94aa7b493aaa739c8849" title="Reads the start of a map with a number of elements at most max_count, returning its element count...">mpack_expect_map_max()</a></code>, and of checking for errors in each iteration of the loop. If we were to leave these out, an attacker could craft a message declaring an array of a billion elements, forcing this code into an infinite loop. We specify a size of 100 here as an arbitrary limit that leaves enough space for the schema to grow in the future. If you forbid unrecognized keys, you could specify the key count as the limit. Alternatively you could specify an unlimited size (<code>UINT32_MAX</code>), as long as you are checking for errors in each iteration (since the stream will eventually run out of data.) It's safest to use both the limit and the error check, so we use both in these examples.</em></p>
<p>Unlike JSON, MessagePack supports any type as a map key, so the enum integer values can themselves be used as keys. This reduces message size at some expense of debuggability (losing some of the value of a schemaless format.) There is a simpler function <code><a class="el" href="group__expect.html#ga78f80d9fabe961d661eabe95732c2d59" title="Expects an unsigned integer map key between 0 and count-1, marking it as found in the given bool arra...">mpack_expect_key_uint()</a></code> which can be used to switch on small non-negative enum values directly.</p>
<p>On the surface this doesn't appear much shorter than the previous code, but it becomes much nicer when you have many possible keys in a map. Of course if at all possible you should consider using the Node API which is much less error-prone and will handle all of this for you. </p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.11
</small></address>
</body>
</html>