blob: 4995b59cf16e418811df538a8d765fe34aaa9fea [file] [log] [blame] [raw]
<!DOCTYPE html><html><head><meta charset="utf-8" /><meta content="IE=edge" http-equiv="X-UA-Compatible" /><meta content="width=device-width, initial-scale=1, maximum-scale=2.0, user-scalable=yes, minimal-ui=yes" name="viewport" /><title>facil.io - FIOBJ Generic Functions</title><meta content="facil.io - FIOBJ Generic Functions" name="description" /><link href="https://fonts.googleapis.com/css?family=Montserrat|Quicksand|Karla" rel="stylesheet" type="text/css" /><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script><link href="/assets/styles/main.css" rel="stylesheet" type="text/css" /><script type="application/ld+json">{"@context":"http://schema.org","@type":"WebSite","url":"http://facil.io","name":"facil.io","description":"facil.io - a light web application framework in C, with support for HTTP, WebSockets and Pub/Sub out of the box.","keywords":"C, web, framework, websockets, websocket, realtime, real-time, easy","image":"http://facil.io/website/logo/facil-io.svg","author":[{"@type":"Person","name":"Bo (Myst)","url":"http://stackoverflow.com/users/4025095/myst","email":"bo(at)facil.io"}],"sourceOrganization":{"@context":"http://schema.org","@type":"Organization","name":"Plezi","url":"http://facil.io","description":"facil.io - a light web application framework in C, with support for HTTP, WebSockets and Pub/Sub out of the box.","logo":"http://facil.io/website/logo/facil-io.svg","image":"http://facil.io/website/logo/facil-io.svg","email":"bo(at)facil.io","member":[{"@type":"Person","name":"Bo (Myst)","url":"http://stackoverflow.com/users/4025095/myst","email":"bo(at)facil.io"}]}}</script><meta content="facil.io" name="apple-mobile-web-app-title" /><meta content="facil.io - the C Web Application Framework" name="application-name" /><meta content="#b91d47" name="msapplication-TileColor" /><meta content="/mstile-144x144.png" name="msapplication-TileImage" /><meta content="#ffffff" name="theme-color" /></head><body><a href="/" id="logo"></a><input id="show_nav" type="checkbox" /><nav id="top_nav"><ul><li><a href="/0.7.x/index">Latest Docs</a></li><li><a href="https://github.com/boazsegev/facil.io" target="_blank">Source Code</a></li><li><a href="javascript: change_themes();" id="theme">Night Theme</a></li></ul></nav><input id="show_sidebar" type="checkbox" /><nav id="side_bar"><h2 id="version-0-6-x"><a href="/0.6.x/index">Version 0.6.x</a></h2>
<ul>
<li><a href="/0.6.x/api">API Overview</a></li>
<li><a href="/0.6.x/modules">The Modules</a></li>
</ul>
<h3 id="core-api"><a href="/0.6.x/facil">Core API</a></h3>
<ul>
<li><a href="/0.6.x/defer">Event scheduling</a></li>
<li><a href="/0.6.x/evio">Low Level Polling</a></li>
<li><a href="/0.6.x/sock">Low Level Sockets</a></li>
<li><a href="/0.6.x/fio_mem">Memory Allocation</a></li>
</ul>
<h3 id="extensions">Extensions</h3>
<ul>
<li><a href="/0.6.x/http">HTTP</a></li>
<li><a href="/0.6.x/websockets">WebSockets</a></li>
<li><a href="/0.6.x/pubsub">Pub/Sub</a></li>
<li><a href="/0.6.x/fio_cli">CLI (command line)</a></li>
</ul>
<h3 id="the-fiobj-types"><a href="/0.6.x/fiobj">The FIOBJ types</a></h3>
<ul>
<li><a href="/0.6.x/fiobj_primitives">Primitives</a></li>
<li><a href="/0.6.x/fiobj_numbers">Numbers</a></li>
<li><a href="/0.6.x/fiobj_str">Strings</a></li>
<li><a href="/0.6.x/fiobj_ary">Array</a></li>
<li><a href="/0.6.x/fiobj_hash">HashMap</a></li>
<li><a href="/0.6.x/fiobj_json">JSON</a></li>
</ul>
<h3 id="core-types"><a href="/0.6.x/types">Core Types</a></h3>
<ul>
<li><a href="/0.6.x/fio_ary">C Arrays</a></li>
<li><a href="/0.6.x/fio_hashmap">C HashMap</a></li>
<li><a href="/0.6.x/fio_llist">Linked Lists</a></li>
</ul>
</nav><div id="md_container"><div class='toc'><ul>
<li>
<a href="#facil-io-fiobj-generic-functions">facil.io - FIOBJ Generic Functions</a>
<ul>
<li>
<ul>
<li>
<a href="#fiobj-memory-management">FIOBJ Memory Management</a>
<ul>
<li>
<a href="#fiobj_dup"><code>fiobj_dup</code></a>
</li>
<li>
<a href="#fiobj_free"><code>fiobj_free</code></a>
</li>
</ul>
</li>
<li>
<a href="#fiobj-soft-type-recognition">FIOBJ Soft Type Recognition</a>
<ul>
<li>
<a href="#fiobj_type"><code>fiobj_type</code></a>
</li>
<li>
<a href="#fiobj_type_is"><code>fiobj_type_is</code></a>
</li>
<li>
<a href="#fiobj_type_name"><code>fiobj_type_name</code></a>
</li>
</ul>
</li>
<li>
<a href="#object-equality-truthfulness">Object Equality / Truthfulness</a>
<ul>
<li>
<a href="#fiobj_is_true"><code>fiobj_is_true</code></a>
</li>
<li>
<a href="#fiobj_iseq"><code>fiobj_iseq</code></a>
</li>
</ul>
</li>
<li>
<a href="#object-conversion">Object Conversion</a>
<ul>
<li>
<a href="#fiobj_obj2num"><code>fiobj_obj2num</code></a>
</li>
<li>
<a href="#fiobj_obj2float"><code>fiobj_obj2float</code></a>
</li>
<li>
<a href="#fiobj_obj2cstr"><code>fiobj_obj2cstr</code></a>
</li>
<li>
<a href="#fiobj_obj2hash"><code>fiobj_obj2hash</code></a>
</li>
</ul>
</li>
<li>
<a href="#iteration">Iteration</a>
<ul>
<li>
<a href="#fiobj_each1"><code>fiobj_each1</code></a>
</li>
<li>
<a href="#fiobj_each2"><code>fiobj_each2</code></a>
</li>
<li>
<a href="#fiobj_hash_key_in_loop"><code>fiobj_hash_key_in_loop</code></a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div><h1 id="facil-io-fiobj-generic-functions">facil.io - FIOBJ Generic Functions</h1>
<p>Some <code>FIOBJ</code> functions can be called for any <code>FIOBJ</code> object, regardless of their type.</p>
<p>These generic functions are listed here.</p>
<h3 id="fiobj-memory-management">FIOBJ Memory Management</h3>
<h4 id="fiobj_dup"><code>fiobj_dup</code></h4>
<pre><code class='highlight'><span class="n">FIOBJ</span> <span class="n">fiobj_dup</span><span class="p">(</span><span class="n">FIOBJ</span><span class="p">);</span>
</code></pre>
<p>Heuristic copy with a preference for copy by reference(!), to minimize allocations.</p>
<p>This usually means the only action performed is reference count increase.</p>
<p>Always returns the value passed along.</p>
<h4 id="fiobj_free"><code>fiobj_free</code></h4>
<pre><code class='highlight'><span class="kt">void</span> <span class="n">fiobj_free</span><span class="p">(</span><span class="n">FIOBJ</span><span class="p">);</span>
</code></pre>
<p>Frees the object and any of it&#39;s &quot;children&quot;.</p>
<p>This function affects nested objects, meaning that when an Array or a Hash object is passed along, it&#39;s children (the nested objects) are also freed.</p>
<p>For Hash objects, only the value objects are deallocated. The <code>keys</code> aren&#39;t &quot;owned&quot; by the Hash Map and therefore they aren&#39;t automatically allocated.</p>
<h3 id="fiobj-soft-type-recognition">FIOBJ Soft Type Recognition</h3>
<h4 id="fiobj_type"><code>fiobj_type</code></h4>
<pre><code class='highlight'><span class="n">fiobj_type_enum</span> <span class="n">fiobj_type</span><span class="p">(</span><span class="n">FIOBJ</span> <span class="n">o</span><span class="p">);</span>
</code></pre>
<p>Returns the object&#39;s type.</p>
<p>Valid return values are:
<code>FIOBJ_T_NULL</code> - Object is the primitive <code>null</code>
* <code>FIOBJ_T_TRUE</code> - Object is the primitive <code>true</code>
* <code>FIOBJ_T_FALSE</code> - Object is the primitive <code>false</code>
* <code>FIOBJ_T_NUMBER</code> - Object is a number.
* <code>FIOBJ_T_FLOAT</code> - Object is a floating point number (<code>double</code>).
* <code>FIOBJ_T_STRING</code> - Object is a binary String.
* <code>FIOBJ_T_ARRAY</code> - Object is a FIOBJ array.
* <code>FIOBJ_T_HASH</code> - Object is a FIOBJ hash.
* <code>FIOBJ_T_DATA</code> - Object is a data stream, either wrapping a temporary file or a memory block.
* <code>FIOBJ_T_UNKNOWN</code> - Object type is unknown (a user&#39;s type).</p>
<h4 id="fiobj_type_is"><code>fiobj_type_is</code></h4>
<pre><code class='highlight'><span class="kt">size_t</span> <span class="n">fiobj_type_is</span><span class="p">(</span><span class="n">FIOBJ</span> <span class="n">o</span><span class="p">,</span> <span class="n">fiobj_type_enum</span> <span class="n">type</span><span class="p">)</span>
</code></pre>
<p>This is faster than getting the type, since parts of the switch statement are optimized away (they are calculated during compile time).</p>
<h4 id="fiobj_type_name"><code>fiobj_type_name</code></h4>
<pre><code class='highlight'><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">fiobj_type_name</span><span class="p">(</span><span class="k">const</span> <span class="n">FIOBJ</span> <span class="n">obj</span><span class="p">);</span>
</code></pre>
<p>Returns a C string naming the objects dynamic type.</p>
<h3 id="object-equality-truthfulness">Object Equality / Truthfulness</h3>
<h4 id="fiobj_is_true"><code>fiobj_is_true</code></h4>
<pre><code class='highlight'><span class="kt">int</span> <span class="n">fiobj_is_true</span><span class="p">(</span><span class="k">const</span> <span class="n">FIOBJ</span><span class="p">);</span>
</code></pre>
<p>Tests if an object evaluates as TRUE.</p>
<p>This is object type specific. For example, empty strings might evaluate as FALSE, even though they aren&#39;t a boolean type.</p>
<h4 id="fiobj_iseq"><code>fiobj_iseq</code></h4>
<pre><code class='highlight'><span class="kt">int</span> <span class="n">fiobj_iseq</span><span class="p">(</span><span class="k">const</span> <span class="n">FIOBJ</span> <span class="n">obj1</span><span class="p">,</span> <span class="k">const</span> <span class="n">FIOBJ</span> <span class="n">obj2</span><span class="p">);</span>
</code></pre>
<p>Deeply compares two objects. No hashing or recursive function calls are
involved.</p>
<p>Uses a similar algorithm to <code>fiobj_each2</code>, except adjusted to two objects.</p>
<p>Hash objects are order sensitive. To be equal, Hash keys must match in order.</p>
<p>Returns 1 if true and 0 if false.</p>
<h3 id="object-conversion">Object Conversion</h3>
<h4 id="fiobj_obj2num"><code>fiobj_obj2num</code></h4>
<pre><code class='highlight'><span class="kt">intptr_t</span> <span class="n">fiobj_obj2num</span><span class="p">(</span><span class="k">const</span> <span class="n">FIOBJ</span> <span class="n">obj</span><span class="p">);</span>
</code></pre>
<p>Returns an Object&#39;s numerical value.</p>
<p>If a String is passed to the function, it will be parsed assuming base 10
numerical data.</p>
<p>Hashes and Arrays return their object count.</p>
<p>IO objects return the length of their data.</p>
<p>A type error results in 0.</p>
<h4 id="fiobj_obj2float"><code>fiobj_obj2float</code></h4>
<pre><code class='highlight'><span class="kt">double</span> <span class="n">fiobj_obj2float</span><span class="p">(</span><span class="k">const</span> <span class="n">FIOBJ</span> <span class="n">obj</span><span class="p">);</span>
</code></pre>
<p>Returns a Float&#39;s value.</p>
<p>If a String is passed to the function, they will benparsed assuming base 10
numerical data.</p>
<p>A type error results in 0.</p>
<h4 id="fiobj_obj2cstr"><code>fiobj_obj2cstr</code></h4>
<pre><code class='highlight'><span class="n">fio_cstr_s</span> <span class="n">fiobj_obj2cstr</span><span class="p">(</span><span class="k">const</span> <span class="n">FIOBJ</span> <span class="n">obj</span><span class="p">);</span>
</code></pre>
<p>Returns a C String (NUL terminated) using the <code>fio_cstr_s</code> data type.</p>
<p>The Sting in binary safe and might contain NUL bytes in the middle as well as
a terminating NUL.</p>
<p>If a a Number or a Float are passed to the function, they
will be parsed as a <em>temporary</em>, thread-safe, String.</p>
<p>Numbers will be represented in base 10 numerical data.</p>
<p>A type error results in NULL (i.e. object can&#39;t be represented automatically as a String).</p>
<h4 id="fiobj_obj2hash"><code>fiobj_obj2hash</code></h4>
<pre><code class='highlight'><span class="kt">uint64_t</span> <span class="n">fiobj_obj2hash</span><span class="p">(</span><span class="k">const</span> <span class="n">FIOBJ</span> <span class="n">o</span><span class="p">);</span>
</code></pre>
<p>Calculates an Objects&#39;s SipHash value for possible use as a HashMap key.</p>
<p>The Object MUST answer to the fiobj_obj2cstr, or the result is unusable. In other woords, Hash Objects and Arrays can NOT be used for Hash keys.</p>
<h3 id="iteration">Iteration</h3>
<h4 id="fiobj_each1"><code>fiobj_each1</code></h4>
<pre><code class='highlight'><span class="kt">size_t</span> <span class="n">fiobj_each1</span><span class="p">(</span><span class="n">FIOBJ</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">start_at</span><span class="p">,</span>
<span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">task</span><span class="p">)(</span><span class="n">FIOBJ</span> <span class="n">obj</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">arg</span><span class="p">),</span> <span class="kt">void</span> <span class="o">*</span><span class="n">arg</span><span class="p">);</span>
</code></pre>
<p>Single layer iteration using a callback for each nested fio object.</p>
<p>Accepts any <code>FIOBJ</code> type but only collections (Arrays and Hashes) are
processed. The container itself (the Array or the Hash) is <strong>not</strong> processed
(unlike <code>fiobj_each2</code>).</p>
<p>The callback task function must accept an object and an opaque user pointer.</p>
<p>Hash objects pass along only the value object. The keys can be accessed using the <a href="#fiobj_hash_key_in_loop"><code>fiobj_hash_key_in_loop</code></a> function.</p>
<p>If the callback returns -1, the loop is broken. Any other value is ignored.</p>
<p>Returns the &quot;stop&quot; position, i.e., the number of items processed + the
starting point.</p>
<h4 id="fiobj_each2"><code>fiobj_each2</code></h4>
<pre><code class='highlight'><span class="kt">size_t</span> <span class="n">fiobj_each2</span><span class="p">(</span><span class="n">FIOBJ</span><span class="p">,</span> <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">task</span><span class="p">)(</span><span class="n">FIOBJ</span> <span class="n">obj</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">arg</span><span class="p">),</span> <span class="kt">void</span> <span class="o">*</span><span class="n">arg</span><span class="p">);</span>
</code></pre>
<p>Deep iteration using a callback for each fio object, including the parent.</p>
<p>Accepts any <code>FIOBJ</code> type.</p>
<p>Collections (Arrays, Hashes) are deeply probed and shouldn&#39;t be edited
during an <code>fiobj_each2</code> call (or weird things may happen).</p>
<p>The callback task function must accept an object and an opaque user pointer.</p>
<p>Hash objects keys are available using the <a href="#fiobj_hash_key_in_loop"><code>fiobj_hash_key_in_loop</code></a> function.</p>
<p>Notice that when passing collections to the function, the collection itself
is sent to the callback followed by it&#39;s children (if any). This is true also
for nested collections (a nested Hash will be sent first, followed by the
nested Hash&#39;s children and then followed by the rest of it&#39;s siblings.</p>
<p>If the callback returns -1, the loop is broken. Any other value is ignored.</p>
<h4 id="fiobj_hash_key_in_loop"><code>fiobj_hash_key_in_loop</code></h4>
<pre><code class='highlight'><span class="n">FIOBJ</span> <span class="n">fiobj_hash_key_in_loop</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span>
</code></pre>
<p>Returns the key for the object in the current <code>fiobj_each</code> loop (if any).</p>
</div><a href="/" id="sign"></a><div class="hidden" id="notice"><a class="notice_close" onclick="hide_notice()">X</a><div id="notice_text"></div></div><script>function change_themes() {
if(localStorage.getItem("theme") == 'dark') {
localStorage.setItem("theme", "light");
} else {
localStorage.setItem("theme", "dark");
}
$('body')[0].className = localStorage.getItem("theme");
set_theme_link();
$('#show_nav').attr('checked', false);
return false;
};
function sidebar_name() { return window.location.pathname.slice(0, window.location.pathname.lastIndexOf("/")); }
function on_sidebar_link(e) {
sessionStorage.setItem("sidebar.expect", sidebar_name());
sessionStorage.setItem("sidebar.pos", document.getElementById("side_bar").scrollTop);
}
function load_sidebar_pos() {
var e = document.getElementById("side_bar");
if(!e) {
console.warn("No sidebar detected");
return;
}
var expect = sidebar_name();
if(sessionStorage.getItem("sidebar.expect") == expect) {
e.scrollTo(0, parseInt(sessionStorage.getItem("sidebar.pos")));
} else {
sessionStorage.setItem("sidebar.expect", false);
sessionStorage.setItem("sidebar.pos", 0);
}
if(e) {
// add link callbacks
var links = document.links;
var count = links.length;
for (var i = 0; i < count; i++) {
var href = links[i].href;
if(href.startsWith(document.location.origin)) {
href = href.slice(document.location.origin.length);
}
if(href.startsWith(expect)) {
/* add link event */
links[i].addEventListener("click", on_sidebar_link);
}
}
}
};
load_sidebar_pos();
function set_theme_link() {
$("#theme").html( ( (localStorage.getItem("theme") == 'dark') ? "Day" : "Night") + " Theme" );
}
$('body')[0].className = (localStorage.getItem("theme") == 'dark') ? "dark" : "light";
set_theme_link();
function show_notice() { document.getElementById("notice").classList.remove('hidden'); };
function hide_notice() { document.getElementById("notice").classList.add('hidden'); };
$('#toc').on("touchstart", function (e) { return true; } );
$('#toc').on("hover", function (e) { return true; } );
// hljs.initHighlighting();
// Google Analytics
// if(location.hostname != "localhost") {
// (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
// (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
// m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
// })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
// ga('create', 'UA-69931401-1', 'auto');
// ga('send', 'pageview');
// }</script></body></html>