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

206 lines
24 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: Introduction</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>
</div><!-- top -->
<!-- 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><div class="header">
<div class="headertitle"><div class="title">Introduction </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p ><a class="anchor" id="md_README_temp"></a> MPack is a C implementation of an encoder and decoder for the <a href="http://msgpack.org/">MessagePack</a> serialization format. It is:</p>
<ul>
<li>Simple and easy to use</li>
<li>Secure against untrusted data</li>
<li>Lightweight, suitable for embedded</li>
<li><a href="http://ludocode.github.io/mpack/">Extensively documented</a></li>
<li><a href="https://github.com/ludocode/schemaless-benchmarks#speed---desktop-pc">Extremely fast</a></li>
</ul>
<p >The core of MPack contains a buffered reader and writer, and a tree-style parser that decodes into a tree of dynamically typed nodes. Helper functions can be enabled to read values of expected type, to work with files, to grow buffers or allocate strings automatically, to check UTF-8 encoding, and more.</p>
<p >The MPack code is small enough to be embedded directly into your codebase. Simply download the <a href="https://github.com/ludocode/mpack/releases">amalgamation package</a> and add <code>mpack.h</code> and <code>mpack.c</code> to your project.</p>
<p >MPack supports all modern compilers, all desktop and smartphone OSes, WebAssembly, <a href="https://github.com/ludocode/mpack-linux-kernel">inside the Linux kernel</a>, and even 8-bit microcontrollers such as Arduino. The MPack featureset can be customized at compile-time to set which features, components and debug checks are compiled, and what dependencies are available.</p>
<h1><a class="anchor" id="autotoc_md1"></a>
The Node API</h1>
<p >The Node API parses a chunk of MessagePack data into an immutable tree of dynamically-typed nodes. A series of helper functions can be used to extract data of specific types from each node.</p>
<div class="fragment"><div class="line"><span class="comment">// parse a file into a node tree</span></div>
<div class="line"><a class="code hl_typedef" href="group__node.html#ga9c76cfdb08042d6412b5c745bca928a7">mpack_tree_t</a> tree;</div>
<div class="line"><a class="code hl_function" href="group__node.html#ga06c2d81ce29bf282a1466bd94a207d2a">mpack_tree_init_filename</a>(&amp;tree, <span class="stringliteral">&quot;homepage-example.mp&quot;</span>, 0);</div>
<div class="line"><a class="code hl_function" href="group__node.html#ga92b59a8d5b062df0dcd2386ec5cfe57b">mpack_tree_parse</a>(&amp;tree);</div>
<div class="line"><a class="code hl_typedef" href="group__node.html#ga08f46371c0c59a2e4dd7bdf1891fb3cb">mpack_node_t</a> root = <a class="code hl_function" href="group__node.html#ga2c49262ce28699d5ec90db09b5fd2eee">mpack_tree_root</a>(&amp;tree);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// extract the example data on the msgpack homepage</span></div>
<div class="line"><span class="keywordtype">bool</span> compact = <a class="code hl_function" href="group__node.html#gad15f3dba3fe1c0b5b7d9ed5d2c34215a">mpack_node_bool</a>(<a class="code hl_function" href="group__node.html#ga6ce515ec366036b1602bafe65a56ef7e">mpack_node_map_cstr</a>(root, <span class="stringliteral">&quot;compact&quot;</span>));</div>
<div class="line"><span class="keywordtype">int</span> schema = <a class="code hl_function" href="group__node.html#ga0180b62e35f1438807cec5f1dc747f3d">mpack_node_i32</a>(<a class="code hl_function" href="group__node.html#ga6ce515ec366036b1602bafe65a56ef7e">mpack_node_map_cstr</a>(root, <span class="stringliteral">&quot;schema&quot;</span>));</div>
<div class="line"> </div>
<div class="line"><span class="comment">// clean up and check for errors</span></div>
<div class="line"><span class="keywordflow">if</span> (<a class="code hl_function" href="group__node.html#gabf57acbc8356be8fab13a64f78986fdc">mpack_tree_destroy</a>(&amp;tree) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) {</div>
<div class="line"> fprintf(stderr, <span class="stringliteral">&quot;An error occurred decoding the data!\n&quot;</span>);</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line">}</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__node_html_ga0180b62e35f1438807cec5f1dc747f3d"><div class="ttname"><a href="group__node.html#ga0180b62e35f1438807cec5f1dc747f3d">mpack_node_i32</a></div><div class="ttdeci">int32_t mpack_node_i32(mpack_node_t node)</div><div class="ttdoc">Returns the 32-bit signed value of the node.</div></div>
<div class="ttc" id="agroup__node_html_ga06c2d81ce29bf282a1466bd94a207d2a"><div class="ttname"><a href="group__node.html#ga06c2d81ce29bf282a1466bd94a207d2a">mpack_tree_init_filename</a></div><div class="ttdeci">void mpack_tree_init_filename(mpack_tree_t *tree, const char *filename, size_t max_bytes)</div><div class="ttdoc">Initializes a tree to parse the given file.</div></div>
<div class="ttc" id="agroup__node_html_ga08f46371c0c59a2e4dd7bdf1891fb3cb"><div class="ttname"><a href="group__node.html#ga08f46371c0c59a2e4dd7bdf1891fb3cb">mpack_node_t</a></div><div class="ttdeci">struct mpack_node_t mpack_node_t</div><div class="ttdoc">A handle to node data in a parsed MPack tree.</div><div class="ttdef"><b>Definition:</b> mpack-node.h:63</div></div>
<div class="ttc" id="agroup__node_html_ga2c49262ce28699d5ec90db09b5fd2eee"><div class="ttname"><a href="group__node.html#ga2c49262ce28699d5ec90db09b5fd2eee">mpack_tree_root</a></div><div class="ttdeci">mpack_node_t mpack_tree_root(mpack_tree_t *tree)</div><div class="ttdoc">Returns the root node of the tree, if the tree is not in an error state.</div></div>
<div class="ttc" id="agroup__node_html_ga6ce515ec366036b1602bafe65a56ef7e"><div class="ttname"><a href="group__node.html#ga6ce515ec366036b1602bafe65a56ef7e">mpack_node_map_cstr</a></div><div class="ttdeci">mpack_node_t mpack_node_map_cstr(mpack_node_t node, const char *cstr)</div><div class="ttdoc">Returns the value node in the given map for the given null-terminated string key.</div></div>
<div class="ttc" id="agroup__node_html_ga92b59a8d5b062df0dcd2386ec5cfe57b"><div class="ttname"><a href="group__node.html#ga92b59a8d5b062df0dcd2386ec5cfe57b">mpack_tree_parse</a></div><div class="ttdeci">void mpack_tree_parse(mpack_tree_t *tree)</div><div class="ttdoc">Parses a MessagePack message into a tree of immutable nodes.</div></div>
<div class="ttc" id="agroup__node_html_ga9c76cfdb08042d6412b5c745bca928a7"><div class="ttname"><a href="group__node.html#ga9c76cfdb08042d6412b5c745bca928a7">mpack_tree_t</a></div><div class="ttdeci">struct mpack_tree_t mpack_tree_t</div><div class="ttdoc">An MPack tree parser to parse a blob or stream of MessagePack.</div><div class="ttdef"><b>Definition:</b> mpack-node.h:82</div></div>
<div class="ttc" id="agroup__node_html_gabf57acbc8356be8fab13a64f78986fdc"><div class="ttname"><a href="group__node.html#gabf57acbc8356be8fab13a64f78986fdc">mpack_tree_destroy</a></div><div class="ttdeci">mpack_error_t mpack_tree_destroy(mpack_tree_t *tree)</div><div class="ttdoc">Destroys the tree.</div></div>
<div class="ttc" id="agroup__node_html_gad15f3dba3fe1c0b5b7d9ed5d2c34215a"><div class="ttname"><a href="group__node.html#gad15f3dba3fe1c0b5b7d9ed5d2c34215a">mpack_node_bool</a></div><div class="ttdeci">bool mpack_node_bool(mpack_node_t node)</div><div class="ttdoc">Returns the bool value of the node.</div></div>
</div><!-- fragment --><p >Note that no additional error handling is needed in the above code. If the file is missing or corrupt, if map keys are missing or if nodes are not in the expected types, special "nil" nodes and false/zero values are returned and the tree is placed in an error state. An error check is only needed before using the data.</p>
<p >The above example allocates nodes automatically. A fixed node pool can be provided to the parser instead in memory-constrained environments. For maximum performance and minimal memory usage, the <a class="el" href="md_docs_expect.html">Expect API</a> can be used to parse data of a predefined schema.</p>
<h1><a class="anchor" id="autotoc_md2"></a>
The Write API</h1>
<p >The Write API encodes structured data to MessagePack.</p>
<div class="fragment"><div class="line"><span class="comment">// encode to memory buffer</span></div>
<div class="line"><span class="keywordtype">char</span>* data;</div>
<div class="line"><span class="keywordtype">size_t</span> size;</div>
<div class="line"><a class="code hl_typedef" href="group__writer.html#gabdb207d4ba6a6ae47efa5ede13436f31">mpack_writer_t</a> writer;</div>
<div class="line"><a class="code hl_function" href="group__writer.html#ga0aa3b265fb5ece9c4cba0f2b1bfbdb53">mpack_writer_init_growable</a>(&amp;writer, &amp;data, &amp;size);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// write the example on the msgpack homepage</span></div>
<div class="line"><a class="code hl_function" href="group__writer.html#ga5849bab4afebddae63bb03f5dce5f7d8">mpack_build_map</a>(&amp;writer);</div>
<div class="line"><a class="code hl_function" href="group__writer.html#ga3bd01df04f36b5feb770f449b83995b6">mpack_write_cstr</a>(&amp;writer, <span class="stringliteral">&quot;compact&quot;</span>);</div>
<div class="line"><a class="code hl_function" href="group__writer.html#ga5d8fa89f571534f5ddbdf81f5bbd5de8">mpack_write_bool</a>(&amp;writer, <span class="keyword">true</span>);</div>
<div class="line"><a class="code hl_function" href="group__writer.html#ga3bd01df04f36b5feb770f449b83995b6">mpack_write_cstr</a>(&amp;writer, <span class="stringliteral">&quot;schema&quot;</span>);</div>
<div class="line"><a class="code hl_function" href="group__writer.html#gab2e3cd22bad53b31bed85d7b46d135c9">mpack_write_uint</a>(&amp;writer, 0);</div>
<div class="line"><a class="code hl_function" href="group__writer.html#ga10d9f55e0a512d88ede66bbbc543f711">mpack_complete_map</a>(&amp;writer);</div>
<div class="line"> </div>
<div class="line"><span class="comment">// finish writing</span></div>
<div class="line"><span class="keywordflow">if</span> (<a class="code hl_function" href="group__writer.html#ga1cf5a2d9b687d94f637a36123ef7cec0">mpack_writer_destroy</a>(&amp;writer) != <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a642a07519ef145fc9dd1068230c4a661">mpack_ok</a>) {</div>
<div class="line"> fprintf(stderr, <span class="stringliteral">&quot;An error occurred encoding the data!\n&quot;</span>);</div>
<div class="line"> <span class="keywordflow">return</span>;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="comment">// use the data</span></div>
<div class="line">do_something_with_data(data, size);</div>
<div class="line">free(data);</div>
<div class="ttc" id="agroup__writer_html_ga0aa3b265fb5ece9c4cba0f2b1bfbdb53"><div class="ttname"><a href="group__writer.html#ga0aa3b265fb5ece9c4cba0f2b1bfbdb53">mpack_writer_init_growable</a></div><div class="ttdeci">void mpack_writer_init_growable(mpack_writer_t *writer, char **data, size_t *size)</div><div class="ttdoc">Initializes an MPack writer using a growable buffer.</div></div>
<div class="ttc" id="agroup__writer_html_ga10d9f55e0a512d88ede66bbbc543f711"><div class="ttname"><a href="group__writer.html#ga10d9f55e0a512d88ede66bbbc543f711">mpack_complete_map</a></div><div class="ttdeci">void mpack_complete_map(struct mpack_writer_t *writer)</div><div class="ttdoc">Completes a map being built.</div></div>
<div class="ttc" id="agroup__writer_html_ga1cf5a2d9b687d94f637a36123ef7cec0"><div class="ttname"><a href="group__writer.html#ga1cf5a2d9b687d94f637a36123ef7cec0">mpack_writer_destroy</a></div><div class="ttdeci">mpack_error_t mpack_writer_destroy(mpack_writer_t *writer)</div><div class="ttdoc">Cleans up the MPack writer, flushing and closing the underlying stream, if any.</div></div>
<div class="ttc" id="agroup__writer_html_ga3bd01df04f36b5feb770f449b83995b6"><div class="ttname"><a href="group__writer.html#ga3bd01df04f36b5feb770f449b83995b6">mpack_write_cstr</a></div><div class="ttdeci">void mpack_write_cstr(mpack_writer_t *writer, const char *cstr)</div><div class="ttdoc">Writes a null-terminated string.</div></div>
<div class="ttc" id="agroup__writer_html_ga5849bab4afebddae63bb03f5dce5f7d8"><div class="ttname"><a href="group__writer.html#ga5849bab4afebddae63bb03f5dce5f7d8">mpack_build_map</a></div><div class="ttdeci">void mpack_build_map(struct mpack_writer_t *writer)</div><div class="ttdoc">Starts building a map.</div></div>
<div class="ttc" id="agroup__writer_html_ga5d8fa89f571534f5ddbdf81f5bbd5de8"><div class="ttname"><a href="group__writer.html#ga5d8fa89f571534f5ddbdf81f5bbd5de8">mpack_write_bool</a></div><div class="ttdeci">void mpack_write_bool(mpack_writer_t *writer, bool value)</div><div class="ttdoc">Writes a boolean.</div></div>
<div class="ttc" id="agroup__writer_html_gab2e3cd22bad53b31bed85d7b46d135c9"><div class="ttname"><a href="group__writer.html#gab2e3cd22bad53b31bed85d7b46d135c9">mpack_write_uint</a></div><div class="ttdeci">void mpack_write_uint(mpack_writer_t *writer, uint64_t value)</div><div class="ttdoc">Writes an unsigned integer in the most efficient packing available.</div><div class="ttdef"><b>Definition:</b> mpack-writer.h:589</div></div>
<div class="ttc" id="agroup__writer_html_gabdb207d4ba6a6ae47efa5ede13436f31"><div class="ttname"><a href="group__writer.html#gabdb207d4ba6a6ae47efa5ede13436f31">mpack_writer_t</a></div><div class="ttdeci">struct mpack_writer_t mpack_writer_t</div><div class="ttdoc">A buffered MessagePack encoder.</div><div class="ttdef"><b>Definition:</b> mpack-writer.h:66</div></div>
</div><!-- fragment --><p >In the above example, we encode to a growable memory buffer. The writer can instead write to a pre-allocated or stack-allocated buffer (with up-front sizes for compound types), avoiding the need for memory allocation. The writer can also be provided with a flush function (such as a file or socket write function) to call when the buffer is full or when writing is done.</p>
<p >If any error occurs, the writer is placed in an error state. The writer will flag an error if too much data is written, if the wrong number of elements are written, if an allocation failure occurs, if the data could not be flushed, etc. No additional error handling is needed in the above code; any subsequent writes are ignored when the writer is in an error state, so you don't need to check every write for errors.</p>
<p >The above example uses <code><a class="el" href="group__writer.html#ga5849bab4afebddae63bb03f5dce5f7d8" title="Starts building a map.">mpack_build_map()</a></code> to automatically determine the number of key-value pairs contained. If you know up-front the number of elements needed, you can pass it to <code><a class="el" href="group__writer.html#ga5c54c857ce7f0bdcea9b2df349cbcc61" title="Opens a map.">mpack_start_map()</a></code> instead. In that case the corresponding <code><a class="el" href="group__writer.html#gabf0ab209845e7c9c3df7aa00b0d59a03" title="Finishes writing a map.">mpack_finish_map()</a></code> will assert in debug mode that the expected number of elements were actually written, which is something that other MessagePack C/C++ libraries may not do.</p>
<h1><a class="anchor" id="autotoc_md3"></a>
Comparison With Other Parsers</h1>
<p >MPack is rich in features while maintaining very high performance and a small code footprint. Here's a short feature table comparing it to other C parsers:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadLeft"></th><th class="markdownTableHeadCenter"><a href="https://github.com/ludocode/mpack">MPack</a><br />
(v1.1) </th><th class="markdownTableHeadCenter"><a href="https://github.com/msgpack/msgpack-c">msgpack-c</a><br />
(v3.3.0) </th><th class="markdownTableHeadCenter"><a href="https://github.com/camgunz/cmp">CMP</a><br />
(v19) </th><th class="markdownTableHeadCenter"><a href="https://github.com/clwi/CWPack">CWPack</a><br />
(v1.3.1) </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">No libc requirement </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">Growable memory writer </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter">✓* </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">File I/O helpers </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter">✓* </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">Stateful error handling </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">Incremental parser </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">Tree stream parser </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">Compound size tracking </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">Automatic compound size </td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td><td class="markdownTableBodyCenter"></td></tr>
</table>
<p >A larger feature comparison table is available <a class="el" href="md_docs_features.html">here</a> which includes descriptions of the various entries in the table.</p>
<p ><a href="https://github.com/ludocode/schemaless-benchmarks">This benchmarking suite</a> compares the performance of MPack to other implementations of schemaless serialization formats. MPack outperforms all JSON and MessagePack libraries (except <a href="https://github.com/clwi/CWPack">CWPack</a>), and in some tests MPack is several times faster than <a href="https://github.com/miloyip/rapidjson">RapidJSON</a> for equivalent data.</p>
<h1><a class="anchor" id="autotoc_md4"></a>
Why Not Just Use JSON?</h1>
<p >Conceptually, MessagePack stores data similarly to JSON: they are both composed of simple values such as numbers and strings, stored hierarchically in maps and arrays. So why not just use JSON instead? The main reason is that JSON is designed to be human-readable, so it is not as efficient as a binary serialization format:</p>
<ul>
<li>Compound types such as strings, maps and arrays are delimited, so appropriate storage cannot be allocated upfront. The whole object must be parsed to determine its size.</li>
<li>Strings are not stored in their native encoding. Special characters such as quotes and backslashes must be escaped when written and converted back when read.</li>
<li>Numbers are particularly inefficient (especially when parsing back floats), making JSON inappropriate as a base format for structured data that contains lots of numbers.</li>
<li>Binary data is not supported by JSON at all. Small binary blobs such as icons and thumbnails need to be Base64 encoded or passed out-of-band.</li>
</ul>
<p >The above issues greatly increase the complexity of the decoder. Full-featured JSON decoders are quite large, and minimal decoders tend to leave out such features as string unescaping and float parsing, instead leaving these up to the user or platform. This can lead to hard-to-find platform-specific and locale-specific bugs, as well as a greater potential for security vulnerabilites. This also significantly decreases performance, making JSON unattractive for use in applications such as mobile games.</p>
<p >While the space inefficiencies of JSON can be partially mitigated through minification and compression, the performance inefficiencies cannot. More importantly, if you are minifying and compressing the data, then why use a human-readable format in the first place?</p>
<h1><a class="anchor" id="autotoc_md5"></a>
Testing MPack</h1>
<p >The MPack build process does not build MPack into a library; it is used to build and run the unit tests. You do not need to build MPack or the unit testing suite to use MPack.</p>
<p >See test/README.md for information on how to test MPack. </p>
</div></div><!-- PageDoc -->
</div><!-- contents -->
<!-- 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>