154 lines
16 KiB
HTML
154 lines
16 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 Node 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"> 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&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&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 Node API </div></div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<div class="textblock"><p >The Node API is used to parse MessagePack data into a tree in memory, providing DOM-style random access to its contents.</p>
|
|
<p >The Node API can parse from a chunk of data in memory, or it can pull data from a file or stream. When the Node API uses a file or stream, it collects the data for a single message into one contiguous buffer in memory as it parses. The nodes for strings and binary data simply point to the data in the buffer, minimizing copies of the data. In this sense, a tree is just an index over a contiguous MessagePack message in memory.</p>
|
|
<h1><a class="anchor" id="autotoc_md18"></a>
|
|
The Basics</h1>
|
|
<p >A tree is initialized with one of the <code>init()</code> functions, and optionally configured (e.g. with <code>mpack_set_limits()</code>.) A complete message is then parsed with <code><a class="el" href="group__node.html#ga92b59a8d5b062df0dcd2386ec5cfe57b" title="Parses a MessagePack message into a tree of immutable nodes.">mpack_tree_parse()</a></code>.</p>
|
|
<p >The data can then be accessed in random order. For example:</p>
|
|
<div class="fragment"><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> count) {</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#ga794963a10b26fbd0e1a9bff136a47ee7">mpack_tree_init_data</a>(&tree, data, count);</div>
|
|
<div class="line"> <a class="code hl_function" href="group__node.html#ga92b59a8d5b062df0dcd2386ec5cfe57b">mpack_tree_parse</a>(&tree);</div>
|
|
<div class="line"> </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>(&tree);</div>
|
|
<div class="line"> do_something_with_node(root);</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="keywordflow">return</span> <a class="code hl_function" href="group__node.html#gabf57acbc8356be8fab13a64f78986fdc">mpack_tree_destroy</a>(&tree) == <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_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_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_ga794963a10b26fbd0e1a9bff136a47ee7"><div class="ttname"><a href="group__node.html#ga794963a10b26fbd0e1a9bff136a47ee7">mpack_tree_init_data</a></div><div class="ttdeci">void mpack_tree_init_data(mpack_tree_t *tree, const char *data, size_t length)</div><div class="ttdoc">Initializes a tree parser with the given data.</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><!-- fragment --><p >As with the Expect API, the Node API contains helper functions for extracting data of expected types from the tree, and for stepping into maps and arrays. These can be nested together to quickly unpack a message.</p>
|
|
<p >For example, to parse the data on the <a href="https://msgpack.org">msgpack.org</a> homepage from a node:</p>
|
|
<div class="fragment"><div class="line"><span class="keywordtype">void</span> parse_msgpack_homepage(<a class="code hl_typedef" href="group__node.html#ga08f46371c0c59a2e4dd7bdf1891fb3cb">mpack_node_t</a> node, <span class="keywordtype">bool</span>* compact, <span class="keywordtype">int</span>* schema) {</div>
|
|
<div class="line"> *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">"compact"</span>));</div>
|
|
<div class="line"> *schema = <a class="code hl_function" href="group__node.html#ga7beb8942f1d779d6fd688a4db84a3358">mpack_node_int</a>(<a class="code hl_function" href="group__node.html#ga6ce515ec366036b1602bafe65a56ef7e">mpack_node_map_cstr</a>(root, <span class="stringliteral">"schema"</span>));</div>
|
|
<div class="line">}</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_ga7beb8942f1d779d6fd688a4db84a3358"><div class="ttname"><a href="group__node.html#ga7beb8942f1d779d6fd688a4db84a3358">mpack_node_int</a></div><div class="ttdeci">int mpack_node_int(mpack_node_t node)</div><div class="ttdoc">Returns the int value of the node.</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 >If any error occurs, these functions always return safe values and flag an error on the tree. You do not have to check the tree for errors in between each step; you only need an error check before using the data.</p>
|
|
<h1><a class="anchor" id="autotoc_md19"></a>
|
|
Continuous Streams</h1>
|
|
<p >The Node API can parse messages indefinitely from a continuous stream. This can be used for inter-process or network communications. See <a href="https://github.com/msgpack-rpc/msgpack-rpc">msgpack-rpc</a> for an example networking protocol.</p>
|
|
<p >Here's a minimal example that wraps a tree parser around a BSD socket. We've defined a <code>stream_t</code> object to contain our file descriptor and other stream state, and we use it as the tree's context.</p>
|
|
<div class="fragment"><div class="line"><span class="preprocessor">#define MAX_SIZE (1024*1024)</span></div>
|
|
<div class="line"><span class="preprocessor">#define MAX_NODES 1024</span></div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>stream_t {</div>
|
|
<div class="line"> <span class="keywordtype">int</span> fd;</div>
|
|
<div class="line">} stream_t;</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keyword">static</span> <span class="keywordtype">size_t</span> read_stream(<a class="code hl_typedef" href="group__node.html#ga9c76cfdb08042d6412b5c745bca928a7">mpack_tree_t</a>* tree, <span class="keywordtype">char</span>* buffer, <span class="keywordtype">size_t</span> count) {</div>
|
|
<div class="line"> stream_t* stream = <a class="code hl_function" href="group__node.html#gabad58d1c30187a8df21307ada572d2b2">mpack_tree_context</a>(tree);</div>
|
|
<div class="line"> ssize_t step = read(stream->fd, buffer, count);</div>
|
|
<div class="line"> <span class="keywordflow">if</span> (step <= 0)</div>
|
|
<div class="line"> <a class="code hl_function" href="group__node.html#ga46fdd2e384e7399f07a600e13962a492">mpack_tree_flag_error</a>(tree, <a class="code hl_enumvalue" href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a6581b50527f1c278f852c91bea70f847">mpack_error_io</a>);</div>
|
|
<div class="line">}</div>
|
|
<div class="line"> </div>
|
|
<div class="line"><span class="keywordtype">void</span> parse_stream(stream_t* stream) {</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#ga3e42c40a9a8ae59d231e623d180a42d8">mpack_tree_init_stream</a>(&tree, &read_stream, stream, MAX_SIZE, MAX_NODES);</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> <span class="keywordflow">while</span> (<span class="keyword">true</span>) {</div>
|
|
<div class="line"> <a class="code hl_function" href="group__node.html#ga92b59a8d5b062df0dcd2386ec5cfe57b">mpack_tree_parse</a>(&tree)</div>
|
|
<div class="line"> <span class="keywordflow">if</span> (<a class="code hl_function" href="group__node.html#gac62f4d7bfac176dd636924f201cc4712">mpack_tree_error</a>(&tree) != mpack_error_ok))</div>
|
|
<div class="line"> <span class="keywordflow">break</span>;</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> received_message(<a class="code hl_function" href="group__node.html#ga2c49262ce28699d5ec90db09b5fd2eee">mpack_tree_root</a>(&tree));</div>
|
|
<div class="line"> }</div>
|
|
<div class="line">}</div>
|
|
<div class="ttc" id="agroup__common_html_gga9d9f282ca4183ab5190e09d04c1f74c4a6581b50527f1c278f852c91bea70f847"><div class="ttname"><a href="group__common.html#gga9d9f282ca4183ab5190e09d04c1f74c4a6581b50527f1c278f852c91bea70f847">mpack_error_io</a></div><div class="ttdeci">@ mpack_error_io</div><div class="ttdoc">The reader or writer failed to fill or flush, or some other file or socket error occurred.</div><div class="ttdef"><b>Definition:</b> mpack-common.h:163</div></div>
|
|
<div class="ttc" id="agroup__node_html_ga3e42c40a9a8ae59d231e623d180a42d8"><div class="ttname"><a href="group__node.html#ga3e42c40a9a8ae59d231e623d180a42d8">mpack_tree_init_stream</a></div><div class="ttdeci">void mpack_tree_init_stream(mpack_tree_t *tree, mpack_tree_read_t read_fn, void *context, size_t max_message_size, size_t max_message_nodes)</div><div class="ttdoc">Initializes a tree parser from an unbounded stream, or a stream of unknown length.</div></div>
|
|
<div class="ttc" id="agroup__node_html_ga46fdd2e384e7399f07a600e13962a492"><div class="ttname"><a href="group__node.html#ga46fdd2e384e7399f07a600e13962a492">mpack_tree_flag_error</a></div><div class="ttdeci">void mpack_tree_flag_error(mpack_tree_t *tree, mpack_error_t error)</div><div class="ttdoc">Places the tree in the given error state, calling the error callback if one is set.</div></div>
|
|
<div class="ttc" id="agroup__node_html_gabad58d1c30187a8df21307ada572d2b2"><div class="ttname"><a href="group__node.html#gabad58d1c30187a8df21307ada572d2b2">mpack_tree_context</a></div><div class="ttdeci">void * mpack_tree_context(mpack_tree_t *tree)</div><div class="ttdoc">Returns the custom context for tree callbacks.</div><div class="ttdef"><b>Definition:</b> mpack-node.h:549</div></div>
|
|
<div class="ttc" id="agroup__node_html_gac62f4d7bfac176dd636924f201cc4712"><div class="ttname"><a href="group__node.html#gac62f4d7bfac176dd636924f201cc4712">mpack_tree_error</a></div><div class="ttdeci">mpack_error_t mpack_tree_error(mpack_tree_t *tree)</div><div class="ttdoc">Returns the error state of the tree.</div><div class="ttdef"><b>Definition:</b> mpack-node.h:508</div></div>
|
|
</div><!-- fragment --><p >The function <code>received_message()</code> will be called with each new message received from the peer.</p>
|
|
<p >The Node API contains many more features, including non-blocking parsing, optional map lookups and more. This document is a work in progress. See the Node API reference for more information. </p>
|
|
</div></div><!-- contents -->
|
|
</div><!-- PageDoc -->
|
|
<!-- start footer part -->
|
|
<hr class="footer"/><address class="footer"><small>
|
|
Generated by <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>
|