146 lines
96 KiB
HTML
146 lines
96 KiB
HTML
|
|
<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=author content="Niels Lohmann"><link href=https://json.nlohmann.me/features/binary_values/ rel=canonical><link rel=icon href=../../assets/images/favicon.png><meta name=generator content="mkdocs-1.4.2, mkdocs-material-8.5.10"><title>Binary Values - JSON for Modern C++</title><link rel=stylesheet href=../../assets/stylesheets/main.975780f9.min.css><link rel=stylesheet href=../../assets/stylesheets/palette.2505c338.min.css><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback"><style>:root{--md-text-font:"Roboto";--md-code-font:"JetBrains Mono"}</style><link rel=stylesheet href=../../css/custom.css><script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo> <script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#binary-values class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <header class=md-header data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../.. title="JSON for Modern C++" class="md-header__button md-logo" aria-label="JSON for Modern C++" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> JSON for Modern C++ </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Binary Values </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to dark mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_2 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z"/></svg> </label> <input class=md-option data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme=slate data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to light mode" type=radio name=__palette id=__palette_2> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12c0-2.42-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>binary_with_subtype</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary_t</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>},</span><span class=w> </span><span class=mi>42</span><span class=p>);</span><span class=w></span>
|
||
|
|
</code></pre></div> <p>There are several convenience functions to check and set the subtype:</p> <div class=highlight><pre><span></span><code><span class=n>binary</span><span class=p>.</span><span class=n>has_subtype</span><span class=p>();</span><span class=w> </span><span class=c1>// returns false</span>
|
||
|
|
<span class=n>binary_with_subtype</span><span class=p>.</span><span class=n>has_subtype</span><span class=p>();</span><span class=w> </span><span class=c1>// returns true</span>
|
||
|
|
|
||
|
|
<span class=n>binary_with_subtype</span><span class=p>.</span><span class=n>clear_subtype</span><span class=p>();</span><span class=w></span>
|
||
|
|
<span class=n>binary_with_subtype</span><span class=p>.</span><span class=n>has_subtype</span><span class=p>();</span><span class=w> </span><span class=c1>// returns true</span>
|
||
|
|
|
||
|
|
<span class=n>binary_with_subtype</span><span class=p>.</span><span class=n>set_subtype</span><span class=p>(</span><span class=mi>42</span><span class=p>);</span><span class=w></span>
|
||
|
|
<span class=n>binary</span><span class=p>.</span><span class=n>set_subtype</span><span class=p>(</span><span class=mi>23</span><span class=p>);</span><span class=w></span>
|
||
|
|
|
||
|
|
<span class=n>binary</span><span class=p>.</span><span class=n>subtype</span><span class=p>();</span><span class=w> </span><span class=c1>// returns 23</span>
|
||
|
|
</code></pre></div> <p>As <code>json::binary_t</code> is subclassing <code>std::vector<std::uint8_t></code>, all member functions are available:</p> <div class=highlight><pre><span></span><code><span class=n>binary</span><span class=p>.</span><span class=n>size</span><span class=p>();</span><span class=w> </span><span class=c1>// returns 4</span>
|
||
|
|
<span class=n>binary</span><span class=p>[</span><span class=mi>1</span><span class=p>];</span><span class=w> </span><span class=c1>// returns 0xFE</span>
|
||
|
|
</code></pre></div> <p>JSON values can be constructed from <code>json::binary_t</code>:</p> <div class=highlight><pre><span></span><code><span class=n>json</span><span class=w> </span><span class=n>j</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>binary</span><span class=p>;</span><span class=w></span>
|
||
|
|
</code></pre></div> <p>Binary values are primitive values just like numbers or strings:</p> <div class=highlight><pre><span></span><code><span class=n>j</span><span class=p>.</span><span class=n>is_binary</span><span class=p>();</span><span class=w> </span><span class=c1>// returns true</span>
|
||
|
|
<span class=n>j</span><span class=p>.</span><span class=n>is_primitive</span><span class=p>();</span><span class=w> </span><span class=c1>// returns true</span>
|
||
|
|
</code></pre></div> <p>Given a binary JSON value, the <code>binary_t</code> can be accessed by reference as via <code>get_binary()</code>:</p> <div class=highlight><pre><span></span><code><span class=n>j</span><span class=p>.</span><span class=n>get_binary</span><span class=p>().</span><span class=n>has_subtype</span><span class=p>();</span><span class=w> </span><span class=c1>// returns true</span>
|
||
|
|
<span class=n>j</span><span class=p>.</span><span class=n>get_binary</span><span class=p>().</span><span class=n>size</span><span class=p>();</span><span class=w> </span><span class=c1>// returns 4</span>
|
||
|
|
</code></pre></div> <p>For convenience, binary JSON values can be constructed via <code>json::binary</code>:</p> <div class=highlight><pre><span></span><code><span class=k>auto</span><span class=w> </span><span class=n>j2</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>},</span><span class=w> </span><span class=mi>23</span><span class=p>);</span><span class=w></span>
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>j3</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>});</span><span class=w></span>
|
||
|
|
|
||
|
|
<span class=n>j2</span><span class=w> </span><span class=o>==</span><span class=w> </span><span class=n>j</span><span class=p>;</span><span class=w> </span><span class=c1>// returns true</span>
|
||
|
|
<span class=n>j3</span><span class=p>.</span><span class=n>get_binary</span><span class=p>().</span><span class=n>has_subtype</span><span class=p>();</span><span class=w> </span><span class=c1>// returns false</span>
|
||
|
|
<span class=n>j3</span><span class=p>.</span><span class=n>get_binary</span><span class=p>().</span><span class=n>subtype</span><span class=p>();</span><span class=w> </span><span class=c1>// returns std::uint64_t(-1) as j3 has no subtype</span>
|
||
|
|
</code></pre></div> <h2 id=serialization>Serialization<a class=headerlink href=#serialization title="Permanent link">¶</a></h2> <p>Binary values are serialized differently according to the formats.</p> <h3 id=json>JSON<a class=headerlink href=#json title="Permanent link">¶</a></h3> <p>JSON does not have a binary type, and this library does not introduce a new type as this would break conformance. Instead, binary values are serialized as an object with two keys: <code>bytes</code> holds an array of integers, and <code>subtype</code> is an integer or <code>null</code>.</p> <details class=example> <summary>Example</summary> <p>Code:</p> <div class=highlight><pre><span></span><code><span class=c1>// create a binary value of subtype 42</span>
|
||
|
|
<span class=n>json</span><span class=w> </span><span class=n>j</span><span class=p>;</span><span class=w></span>
|
||
|
|
<span class=n>j</span><span class=p>[</span><span class=s>"binary"</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>},</span><span class=w> </span><span class=mi>42</span><span class=p>);</span><span class=w></span>
|
||
|
|
|
||
|
|
<span class=c1>// serialize to standard output</span>
|
||
|
|
<span class=n>std</span><span class=o>::</span><span class=n>cout</span><span class=w> </span><span class=o><<</span><span class=w> </span><span class=n>j</span><span class=p>.</span><span class=n>dump</span><span class=p>(</span><span class=mi>2</span><span class=p>)</span><span class=w> </span><span class=o><<</span><span class=w> </span><span class=n>std</span><span class=o>::</span><span class=n>endl</span><span class=p>;</span><span class=w></span>
|
||
|
|
</code></pre></div> <p>Output:</p> <div class=highlight><pre><span></span><code><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"binary"</span><span class=p>:</span><span class=w> </span><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"bytes"</span><span class=p>:</span><span class=w> </span><span class=p>[</span><span class=mi>202</span><span class=p>,</span><span class=w> </span><span class=mi>254</span><span class=p>,</span><span class=w> </span><span class=mi>186</span><span class=p>,</span><span class=w> </span><span class=mi>190</span><span class=p>],</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"subtype"</span><span class=p>:</span><span class=w> </span><span class=mi>42</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=p>}</span><span class=w></span>
|
||
|
|
<span class=p>}</span><span class=w></span>
|
||
|
|
</code></pre></div> </details> <div class="admonition warning"> <p class=admonition-title>No roundtrip for binary values</p> <p>The JSON parser will not parse the objects generated by binary values back to binary values. This is by design to remain standards compliant. Serializing binary values to JSON is only implemented for debugging purposes.</p> </div> <h3 id=bjdata>BJData<a class=headerlink href=#bjdata title="Permanent link">¶</a></h3> <p><a href=../binary_formats/bjdata/ >BJData</a> neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library.</p> <details class=example> <summary>Example</summary> <p>Code:</p> <div class=highlight><pre><span></span><code><span class=c1>// create a binary value of subtype 42 (will be ignored in BJData)</span>
|
||
|
|
<span class=n>json</span><span class=w> </span><span class=n>j</span><span class=p>;</span><span class=w></span>
|
||
|
|
<span class=n>j</span><span class=p>[</span><span class=s>"binary"</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>},</span><span class=w> </span><span class=mi>42</span><span class=p>);</span><span class=w></span>
|
||
|
|
|
||
|
|
<span class=c1>// convert to BJData</span>
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>v</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>to_bjdata</span><span class=p>(</span><span class=n>j</span><span class=p>);</span><span class=w> </span>
|
||
|
|
</code></pre></div> <p><code>v</code> is a <code>std::vector<std::uint8t></code> with the following 20 elements:</p> <div class=highlight><pre><span></span><code><span class=mh>0x7B</span><span class=w> </span><span class=c1>// '{'</span>
|
||
|
|
<span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x06</span><span class=w> </span><span class=c1>// i 6 (length of the key)</span>
|
||
|
|
<span class=w> </span><span class=mh>0x62</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x6E</span><span class=w> </span><span class=mh>0x61</span><span class=w> </span><span class=mh>0x72</span><span class=w> </span><span class=mh>0x79</span><span class=w> </span><span class=c1>// "binary"</span>
|
||
|
|
<span class=w> </span><span class=mh>0x5B</span><span class=w> </span><span class=c1>// '['</span>
|
||
|
|
<span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=mh>0xCA</span><span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=mh>0xFE</span><span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=mh>0xBA</span><span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=mh>0xBE</span><span class=w> </span><span class=c1>// content (each byte prefixed with 'U')</span>
|
||
|
|
<span class=w> </span><span class=mh>0x5D</span><span class=w> </span><span class=c1>// ']'</span>
|
||
|
|
<span class=mh>0x7D</span><span class=w> </span><span class=c1>// '}'</span>
|
||
|
|
</code></pre></div> <p>The following code uses the type and size optimization for UBJSON:</p> <div class=highlight><pre><span></span><code><span class=c1>// convert to UBJSON using the size and type optimization</span>
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>v</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>to_bjdata</span><span class=p>(</span><span class=n>j</span><span class=p>,</span><span class=w> </span><span class=nb>true</span><span class=p>,</span><span class=w> </span><span class=nb>true</span><span class=p>);</span><span class=w></span>
|
||
|
|
</code></pre></div> <p>The resulting vector has 22 elements; the optimization is not effective for examples with few values:</p> <div class=highlight><pre><span></span><code><span class=mh>0x7B</span><span class=w> </span><span class=c1>// '{'</span>
|
||
|
|
<span class=w> </span><span class=mh>0x23</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x01</span><span class=w> </span><span class=c1>// '#' 'i' type of the array elements: unsigned integers</span>
|
||
|
|
<span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x06</span><span class=w> </span><span class=c1>// i 6 (length of the key)</span>
|
||
|
|
<span class=w> </span><span class=mh>0x62</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x6E</span><span class=w> </span><span class=mh>0x61</span><span class=w> </span><span class=mh>0x72</span><span class=w> </span><span class=mh>0x79</span><span class=w> </span><span class=c1>// "binary"</span>
|
||
|
|
<span class=w> </span><span class=mh>0x5B</span><span class=w> </span><span class=c1>// '[' array</span>
|
||
|
|
<span class=w> </span><span class=mh>0x24</span><span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=c1>// '$' 'U' type of the array elements: unsigned integers</span>
|
||
|
|
<span class=w> </span><span class=mh>0x23</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x04</span><span class=w> </span><span class=c1>// '#' i 4 number of array elements</span>
|
||
|
|
<span class=w> </span><span class=mh>0xCA</span><span class=w> </span><span class=mh>0xFE</span><span class=w> </span><span class=mh>0xBA</span><span class=w> </span><span class=mh>0xBE</span><span class=w> </span><span class=c1>// content</span>
|
||
|
|
</code></pre></div> <p>Note that subtype (42) is <strong>not</strong> serialized and that UBJSON has <strong>no binary type</strong>, and deserializing <code>v</code> would yield the following value:</p> <div class=highlight><pre><span></span><code><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"binary"</span><span class=p>:</span><span class=w> </span><span class=p>[</span><span class=mi>202</span><span class=p>,</span><span class=w> </span><span class=mi>254</span><span class=p>,</span><span class=w> </span><span class=mi>186</span><span class=p>,</span><span class=w> </span><span class=mi>190</span><span class=p>]</span><span class=w></span>
|
||
|
|
<span class=p>}</span><span class=w></span>
|
||
|
|
</code></pre></div> </details> <h3 id=bson>BSON<a class=headerlink href=#bson title="Permanent link">¶</a></h3> <p><a href=../binary_formats/bson/ >BSON</a> supports binary values and subtypes. If a subtype is given, it is used and added as unsigned 8-bit integer. If no subtype is given, the generic binary subtype 0x00 is used.</p> <details class=example> <summary>Example</summary> <p>Code:</p> <div class=highlight><pre><span></span><code><span class=c1>// create a binary value of subtype 42</span>
|
||
|
|
<span class=n>json</span><span class=w> </span><span class=n>j</span><span class=p>;</span><span class=w></span>
|
||
|
|
<span class=n>j</span><span class=p>[</span><span class=s>"binary"</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>},</span><span class=w> </span><span class=mi>42</span><span class=p>);</span><span class=w></span>
|
||
|
|
|
||
|
|
<span class=c1>// convert to BSON</span>
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>v</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>to_bson</span><span class=p>(</span><span class=n>j</span><span class=p>);</span><span class=w> </span>
|
||
|
|
</code></pre></div> <p><code>v</code> is a <code>std::vector<std::uint8t></code> with the following 22 elements:</p> <div class=highlight><pre><span></span><code><span class=mh>0x16</span><span class=w> </span><span class=mh>0x00</span><span class=w> </span><span class=mh>0x00</span><span class=w> </span><span class=mh>0x00</span><span class=w> </span><span class=c1>// number of bytes in the document</span>
|
||
|
|
<span class=w> </span><span class=mh>0x05</span><span class=w> </span><span class=c1>// binary value</span>
|
||
|
|
<span class=w> </span><span class=mh>0x62</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x6E</span><span class=w> </span><span class=mh>0x61</span><span class=w> </span><span class=mh>0x72</span><span class=w> </span><span class=mh>0x79</span><span class=w> </span><span class=mh>0x00</span><span class=w> </span><span class=c1>// key "binary" + null byte</span>
|
||
|
|
<span class=w> </span><span class=mh>0x04</span><span class=w> </span><span class=mh>0x00</span><span class=w> </span><span class=mh>0x00</span><span class=w> </span><span class=mh>0x00</span><span class=w> </span><span class=c1>// number of bytes</span>
|
||
|
|
<span class=w> </span><span class=mh>0x2a</span><span class=w> </span><span class=c1>// subtype</span>
|
||
|
|
<span class=w> </span><span class=mh>0xCA</span><span class=w> </span><span class=mh>0xFE</span><span class=w> </span><span class=mh>0xBA</span><span class=w> </span><span class=mh>0xBE</span><span class=w> </span><span class=c1>// content</span>
|
||
|
|
<span class=mh>0x00</span><span class=w> </span><span class=c1>// end of the document</span>
|
||
|
|
</code></pre></div> <p>Note that the serialization preserves the subtype, and deserializing <code>v</code> would yield the following value:</p> <div class=highlight><pre><span></span><code><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"binary"</span><span class=p>:</span><span class=w> </span><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"bytes"</span><span class=p>:</span><span class=w> </span><span class=p>[</span><span class=mi>202</span><span class=p>,</span><span class=w> </span><span class=mi>254</span><span class=p>,</span><span class=w> </span><span class=mi>186</span><span class=p>,</span><span class=w> </span><span class=mi>190</span><span class=p>],</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"subtype"</span><span class=p>:</span><span class=w> </span><span class=mi>42</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=p>}</span><span class=w></span>
|
||
|
|
<span class=p>}</span><span class=w></span>
|
||
|
|
</code></pre></div> </details> <h3 id=cbor>CBOR<a class=headerlink href=#cbor title="Permanent link">¶</a></h3> <p><a href=../binary_formats/cbor/ >CBOR</a> supports binary values, but no subtypes. Subtypes will be serialized as tags. Any binary value will be serialized as byte strings. The library will choose the smallest representation using the length of the byte array.</p> <details class=example> <summary>Example</summary> <p>Code:</p> <div class=highlight><pre><span></span><code><span class=c1>// create a binary value of subtype 42</span>
|
||
|
|
<span class=n>json</span><span class=w> </span><span class=n>j</span><span class=p>;</span><span class=w></span>
|
||
|
|
<span class=n>j</span><span class=p>[</span><span class=s>"binary"</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>},</span><span class=w> </span><span class=mi>42</span><span class=p>);</span><span class=w></span>
|
||
|
|
|
||
|
|
<span class=c1>// convert to CBOR</span>
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>v</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>to_cbor</span><span class=p>(</span><span class=n>j</span><span class=p>);</span><span class=w> </span>
|
||
|
|
</code></pre></div> <p><code>v</code> is a <code>std::vector<std::uint8t></code> with the following 15 elements:</p> <div class=highlight><pre><span></span><code><span class=mh>0xA1</span><span class=w> </span><span class=c1>// map(1)</span>
|
||
|
|
<span class=w> </span><span class=mh>0x66</span><span class=w> </span><span class=c1>// text(6)</span>
|
||
|
|
<span class=w> </span><span class=mh>0x62</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x6E</span><span class=w> </span><span class=mh>0x61</span><span class=w> </span><span class=mh>0x72</span><span class=w> </span><span class=mh>0x79</span><span class=w> </span><span class=c1>// "binary"</span>
|
||
|
|
<span class=w> </span><span class=mh>0xD8</span><span class=w> </span><span class=mh>0x2A</span><span class=w> </span><span class=c1>// tag(42)</span>
|
||
|
|
<span class=w> </span><span class=mh>0x44</span><span class=w> </span><span class=c1>// bytes(4)</span>
|
||
|
|
<span class=w> </span><span class=mh>0xCA</span><span class=w> </span><span class=mh>0xFE</span><span class=w> </span><span class=mh>0xBA</span><span class=w> </span><span class=mh>0xBE</span><span class=w> </span><span class=c1>// content</span>
|
||
|
|
</code></pre></div> <p>Note that the subtype is serialized as tag. However, parsing tagged values yield a parse error unless <code>json::cbor_tag_handler_t::ignore</code> or <code>json::cbor_tag_handler_t::store</code> is passed to <code>json::from_cbor</code>.</p> <div class=highlight><pre><span></span><code><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"binary"</span><span class=p>:</span><span class=w> </span><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"bytes"</span><span class=p>:</span><span class=w> </span><span class=p>[</span><span class=mi>202</span><span class=p>,</span><span class=w> </span><span class=mi>254</span><span class=p>,</span><span class=w> </span><span class=mi>186</span><span class=p>,</span><span class=w> </span><span class=mi>190</span><span class=p>],</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"subtype"</span><span class=p>:</span><span class=w> </span><span class=kc>null</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=p>}</span><span class=w></span>
|
||
|
|
<span class=p>}</span><span class=w></span>
|
||
|
|
</code></pre></div> </details> <h3 id=messagepack>MessagePack<a class=headerlink href=#messagepack title="Permanent link">¶</a></h3> <p><a href=../binary_formats/messagepack/ >MessagePack</a> supports binary values and subtypes. If a subtype is given, the ext family is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, ext8, ext16, and ext32. The subtype is then added as signed 8-bit integer.</p> <p>If no subtype is given, the bin family (bin8, bin16, bin32) is used.</p> <details class=example> <summary>Example</summary> <p>Code:</p> <div class=highlight><pre><span></span><code><span class=c1>// create a binary value of subtype 42</span>
|
||
|
|
<span class=n>json</span><span class=w> </span><span class=n>j</span><span class=p>;</span><span class=w></span>
|
||
|
|
<span class=n>j</span><span class=p>[</span><span class=s>"binary"</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>},</span><span class=w> </span><span class=mi>42</span><span class=p>);</span><span class=w></span>
|
||
|
|
|
||
|
|
<span class=c1>// convert to MessagePack</span>
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>v</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>to_msgpack</span><span class=p>(</span><span class=n>j</span><span class=p>);</span><span class=w> </span>
|
||
|
|
</code></pre></div> <p><code>v</code> is a <code>std::vector<std::uint8t></code> with the following 14 elements:</p> <div class=highlight><pre><span></span><code><span class=mh>0x81</span><span class=w> </span><span class=c1>// fixmap1</span>
|
||
|
|
<span class=w> </span><span class=mh>0xA6</span><span class=w> </span><span class=c1>// fixstr6</span>
|
||
|
|
<span class=w> </span><span class=mh>0x62</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x6E</span><span class=w> </span><span class=mh>0x61</span><span class=w> </span><span class=mh>0x72</span><span class=w> </span><span class=mh>0x79</span><span class=w> </span><span class=c1>// "binary"</span>
|
||
|
|
<span class=w> </span><span class=mh>0xD6</span><span class=w> </span><span class=c1>// fixext4</span>
|
||
|
|
<span class=w> </span><span class=mh>0x2A</span><span class=w> </span><span class=c1>// subtype</span>
|
||
|
|
<span class=w> </span><span class=mh>0xCA</span><span class=w> </span><span class=mh>0xFE</span><span class=w> </span><span class=mh>0xBA</span><span class=w> </span><span class=mh>0xBE</span><span class=w> </span><span class=c1>// content</span>
|
||
|
|
</code></pre></div> <p>Note that the serialization preserves the subtype, and deserializing <code>v</code> would yield the following value:</p> <div class=highlight><pre><span></span><code><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"binary"</span><span class=p>:</span><span class=w> </span><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"bytes"</span><span class=p>:</span><span class=w> </span><span class=p>[</span><span class=mi>202</span><span class=p>,</span><span class=w> </span><span class=mi>254</span><span class=p>,</span><span class=w> </span><span class=mi>186</span><span class=p>,</span><span class=w> </span><span class=mi>190</span><span class=p>],</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"subtype"</span><span class=p>:</span><span class=w> </span><span class=mi>42</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=p>}</span><span class=w></span>
|
||
|
|
<span class=p>}</span><span class=w></span>
|
||
|
|
</code></pre></div> </details> <h3 id=ubjson>UBJSON<a class=headerlink href=#ubjson title="Permanent link">¶</a></h3> <p><a href=../binary_formats/ubjson/ >UBJSON</a> neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library.</p> <details class=example> <summary>Example</summary> <p>Code:</p> <div class=highlight><pre><span></span><code><span class=c1>// create a binary value of subtype 42 (will be ignored in UBJSON)</span>
|
||
|
|
<span class=n>json</span><span class=w> </span><span class=n>j</span><span class=p>;</span><span class=w></span>
|
||
|
|
<span class=n>j</span><span class=p>[</span><span class=s>"binary"</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>binary</span><span class=p>({</span><span class=mh>0xCA</span><span class=p>,</span><span class=w> </span><span class=mh>0xFE</span><span class=p>,</span><span class=w> </span><span class=mh>0xBA</span><span class=p>,</span><span class=w> </span><span class=mh>0xBE</span><span class=p>},</span><span class=w> </span><span class=mi>42</span><span class=p>);</span><span class=w></span>
|
||
|
|
|
||
|
|
<span class=c1>// convert to UBJSON</span>
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>v</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>to_ubjson</span><span class=p>(</span><span class=n>j</span><span class=p>);</span><span class=w> </span>
|
||
|
|
</code></pre></div> <p><code>v</code> is a <code>std::vector<std::uint8t></code> with the following 20 elements:</p> <div class=highlight><pre><span></span><code><span class=mh>0x7B</span><span class=w> </span><span class=c1>// '{'</span>
|
||
|
|
<span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x06</span><span class=w> </span><span class=c1>// i 6 (length of the key)</span>
|
||
|
|
<span class=w> </span><span class=mh>0x62</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x6E</span><span class=w> </span><span class=mh>0x61</span><span class=w> </span><span class=mh>0x72</span><span class=w> </span><span class=mh>0x79</span><span class=w> </span><span class=c1>// "binary"</span>
|
||
|
|
<span class=w> </span><span class=mh>0x5B</span><span class=w> </span><span class=c1>// '['</span>
|
||
|
|
<span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=mh>0xCA</span><span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=mh>0xFE</span><span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=mh>0xBA</span><span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=mh>0xBE</span><span class=w> </span><span class=c1>// content (each byte prefixed with 'U')</span>
|
||
|
|
<span class=w> </span><span class=mh>0x5D</span><span class=w> </span><span class=c1>// ']'</span>
|
||
|
|
<span class=mh>0x7D</span><span class=w> </span><span class=c1>// '}'</span>
|
||
|
|
</code></pre></div> <p>The following code uses the type and size optimization for UBJSON:</p> <div class=highlight><pre><span></span><code><span class=c1>// convert to UBJSON using the size and type optimization</span>
|
||
|
|
<span class=k>auto</span><span class=w> </span><span class=n>v</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>json</span><span class=o>::</span><span class=n>to_ubjson</span><span class=p>(</span><span class=n>j</span><span class=p>,</span><span class=w> </span><span class=nb>true</span><span class=p>,</span><span class=w> </span><span class=nb>true</span><span class=p>);</span><span class=w></span>
|
||
|
|
</code></pre></div> <p>The resulting vector has 23 elements; the optimization is not effective for examples with few values:</p> <div class=highlight><pre><span></span><code><span class=mh>0x7B</span><span class=w> </span><span class=c1>// '{'</span>
|
||
|
|
<span class=w> </span><span class=mh>0x24</span><span class=w> </span><span class=c1>// '$' type of the object elements</span>
|
||
|
|
<span class=w> </span><span class=mh>0x5B</span><span class=w> </span><span class=c1>// '[' array</span>
|
||
|
|
<span class=w> </span><span class=mh>0x23</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x01</span><span class=w> </span><span class=c1>// '#' i 1 number of object elements</span>
|
||
|
|
<span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x06</span><span class=w> </span><span class=c1>// i 6 (length of the key)</span>
|
||
|
|
<span class=w> </span><span class=mh>0x62</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x6E</span><span class=w> </span><span class=mh>0x61</span><span class=w> </span><span class=mh>0x72</span><span class=w> </span><span class=mh>0x79</span><span class=w> </span><span class=c1>// "binary"</span>
|
||
|
|
<span class=w> </span><span class=mh>0x24</span><span class=w> </span><span class=mh>0x55</span><span class=w> </span><span class=c1>// '$' 'U' type of the array elements: unsigned integers</span>
|
||
|
|
<span class=w> </span><span class=mh>0x23</span><span class=w> </span><span class=mh>0x69</span><span class=w> </span><span class=mh>0x04</span><span class=w> </span><span class=c1>// '#' i 4 number of array elements</span>
|
||
|
|
<span class=w> </span><span class=mh>0xCA</span><span class=w> </span><span class=mh>0xFE</span><span class=w> </span><span class=mh>0xBA</span><span class=w> </span><span class=mh>0xBE</span><span class=w> </span><span class=c1>// content</span>
|
||
|
|
</code></pre></div> <p>Note that subtype (42) is <strong>not</strong> serialized and that UBJSON has <strong>no binary type</strong>, and deserializing <code>v</code> would yield the following value:</p> <div class=highlight><pre><span></span><code><span class=p>{</span><span class=w></span>
|
||
|
|
<span class=w> </span><span class=nt>"binary"</span><span class=p>:</span><span class=w> </span><span class=p>[</span><span class=mi>202</span><span class=p>,</span><span class=w> </span><span class=mi>254</span><span class=p>,</span><span class=w> </span><span class=mi>186</span><span class=p>,</span><span class=w> </span><span class=mi>190</span><span class=p>]</span><span class=w></span>
|
||
|
|
<span class=p>}</span><span class=w></span>
|
||
|
|
</code></pre></div> </details> <hr> <div class=md-source-file> <small> Last update: <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date">March 8, 2023</span> </small> </div> </article> </div> <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var tab,labels=set.querySelector(".tabbed-labels");for(tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script> </div> <a href=# class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12Z"/></svg> Back to top </a> </main> <footer class=md-footer> <nav class="md-footer__inner md-grid" aria-label=Footer> <a href=../binary_formats/ubjson/ class="md-footer__link md-footer__link--prev" aria-label="Previous: UBJSON" rel=prev> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg> </div> <div class=md-footer__title> <div class=md-ellipsis> <span class=md-footer__direction> Previous </span> UBJSON </div> </div> </a> <a href=../comments/ class="md-footer__link md-footer__link--next" aria-label="Next: Comments" rel=next> <div class=md-footer__title> <div class=md-ellipsis> <span class=md-footer__direction> Next </span> Comments </div> </div> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4Z"/></svg> </div> </a> </nav> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class=md-copyright> <div class=md-copyright__highlight> Copyright © 2013 - 2022 Niels Lohmann </div> </div> <div class=md-social> <a href=https://github.com/nlohmann target=_blank rel=noopener title=github.com class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 496 512"><!-- Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg> </a> <a href=https://twitter.com/nlohmann target=_blank rel=noopener title=twitter.com class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="M459.37 15
|