<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [

<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
%docentities;

]>
<!-- Module User's Guide -->

<chapter>

    <title>&adminguide;</title>

    <section>
    <title>Overview</title>
    <para>
		This module provides operations on JSON strings using JANSSON
		library. It has support for JSON-PATH operations.
    </para>
    </section>

    <section>
    <title>Dependencies</title>
    <section>
        <title>&kamailio; Modules</title>
        <para>
        The following modules must be loaded before this module:
            <itemizedlist>
            <listitem>
            <para>
                <emphasis>None</emphasis>
            </para>
            </listitem>
            </itemizedlist>
        </para>
    </section>
    <section>
        <title>External Libraries or Applications</title>
        <para>
        The following libraries or applications must be installed before running
        &kamailio; with this module loaded:
            <itemizedlist>
            <listitem>
            <para>
                <emphasis>jansson (http://www.digip.org/jansson/)</emphasis>, tested with: 2.2+
            </para>
            </listitem>
            </itemizedlist>
        </para>
    </section>
    </section>

    <section>
    <title>Functions</title>
    <section id="jansson.f.jansson_get">
        <title>
            <function moreinfo="none">jansson_get(path, src, dst)</function>
        </title>
        <para>
			Copy the value at the location 'path' from the json object 'src'
			and store it in variable 'dst'. The path can also be a simple field name
			(a key), if it does not include any path separator. To retrieve the
			value of a field that includes path separators in the name, use
			jansson_get_field().
        </para>
        <para>
			The 'src' can be a static string or a dynamic string with variables.
        </para>
        <para>
			The path string supports dot delimited notation (e.g. foo.bar.baz),
			array notation (e.g. [0]), or a combination of the two (e.g. foo.bar[0][1].baz).
        </para>
        <para>
            Returns FALSE if the data can not be parsed, TRUE otherwise.
        </para>
        <para>
			The function can put a string, integer, null, or new json string into destination.
			If the path can't be found in the JSON data structure, the pvar is not changed.
			If it had a previous
	    value, that value remains unchanged.
        </para>
        <para>
			<emphasis>Note:</emphasis> For JSON-Integer values exceeding the C-Integer
			boundaries, a String representing the number is returned.
        </para>
        <example>
        <title><function>jansson_get</function> usage</title>
        <programlisting format="linespecific">
...
if(!jansson_get("inner.deep.list[3]", "$var(myjson)", "$var(n)")) {
	xlog("L_ERR", "Can't parse json data");
}
xlog("L_INFO", "foo is $var(n)");
...
jansson_get("test", "{\"test\":\"abc\",\"idx\":20}", "$var(n)");
...
        </programlisting>
        </example>
    </section>
    <section id="jansson.f.jansson_pv_get">
        <title>
            <function moreinfo="none">jansson_pv_get(key/path, srcvar, dst)</function>
        </title>
        <para>
			Similar to jansson_get(), but the 'srcvar' parameter can be only a
			variable name.
        </para>
        <example>
        <title><function>jansson_pv_get</function> usage</title>
        <programlisting format="linespecific">
...
if(!jansson_pv_get("inner.deep.list[3]", "$var(myjson)", "$var(n)")) {
	xlog("L_ERR", "Can't parse json data");
}
xlog("L_INFO", "foo is $var(n)");
...
        </programlisting>
        </example>
    </section>
    <section id="jansson.f.jansson_set">
        <title>
            <function moreinfo="none">jansson_set(type, key/path, value, result)</function>
        </title>
        <para>
            Insert 'value' as 'type' at location 'path' into 'result'.
        </para>
        <para>
            The path string works the same as in jansson_get.
        </para>
        <para>
			Valid 'type' parameters are 'integer', 'real', 'string', 'object', 'array',
			'true', 'false', and 'null'  as well as abbreviated names such as 'int', 'str',
			and 'obj'. 'value' is ignored when type is 'true', 'false', or 'null'.
        </para>
        <para>
			<emphasis>Note:</emphasis> If you want to insert a JSON-Integer value exceeding
			the C-Integer boundaries (e.g. C-type long), then the number can be provided as a string.
        </para>
        <example>
        <title><function>jansson_set</function> usage</title>
        <programlisting format="linespecific">
...
# create a new json object and put a string in it at key "mystr"
jansson_set("string", "mystr", "my input string", "$var(myjson)");
# $var(myjson) =='{"mystr":"my input string"}'

# add other values
jansson_set("integer", "count", 9000, "$var(myjson)");
jansson_set("true", "mybool", 0, "$var(myjson)");
jansson_set("real", "pi", "3.14159", "$var(myjson)");
# $var(myjson) == '{"mystr":"my input string", "count":9000, "mybool":true, "pi":3.14159}'

# add a nested object
jansson_set("obj", "myobj", '{"foo":"bar"}', "$var(myjson)");
# $var(myjson) =='{"mystr":"my input string", "count":9000, "mybool":true, "pi":3.14159, "myobj":{"foo":"bar"}}'

# change the nested object
jansson_set("str", "myobj.foo", "baz", "$var(myjson)");
# $var(myjson) == '{"mystr":"my input string", "count":9000, "mybool":true, "pi":3.14159, "myobj":{"foo":"baz"}}'
...
        </programlisting>
        </example>
    </section>
    <section id="jansson.f.jansson_append">
        <title>
            <function moreinfo="none">jansson_append(type, key/path, value, result)</function>
        </title>
        <para>
			Like jansson_set but can be used to append to arrays. It can also be used to combine
			two json objects.
        </para>
        <para>
			Note that when appending a json object to another json object, if there is a key
			that is shared between the two objects, that value will be overwritten by the new object.
        </para>
        <example>
        <title><function>jansson_append</function> usage</title>
        <programlisting format="linespecific">
...
# create a new json array and append values to it
$var(myarray) = '[]';
jansson_append("int", "", 0, "$var(myarray)");
jansson_append("int", "", 1, "$var(myarray)");
jansson_append("int", "", 2, "$var(myarray)");
jansson_append("int", "", 3, "$var(myarray)");
jansson_append("int", "", 4, "$var(myarray)");
# $var(myarray) == '[0,1,2,3,4]'

# add that array to an object
jansson_set("array", "list", $var(myarray), "$var(myjson)");
# $var(myjson) == '{"list":[0,1,2,3,4]}'

# append another value to the list
jansson_append("int", "list", 5, "$var(myjson)");
# $var(myjson) == '{"list":[0,1,2,3,4,5]}'

# combining two json objects
$var(newobj) = '{"b":2, "c":3}';
jansson_append('obj', "", '{"a":1, "b":100}', "$var(newobj)");
# $var(newobj) == '{"a":1,"b":100","c":3}';
...
        </programlisting>
        </example>
    </section>
    <section id="jansson.f.jansson_array_size">
        <title>
            <function moreinfo="none">jansson_array_size(key/path, src, dst)</function>
        </title>
        <para>
            Puts the size of the array in 'src' at location 'path' into the pvar 'dst'.
        </para>
        <para>
            This is particularly useful for looping through an array. See example.
        </para>
        <example>
        <title><function>jansson_array_size</function> usage</title>
        <programlisting format="linespecific">
...
$var(array) = "{\"loopme\":[0,1,2,3,4,5]}";
$var(count) = 0;
jansson_array_size("loopme", $var(array), "$var(size)");
while($var(count) &lt; $var(size)) {
    jansson_get("loopme[$var(count)]", $var(array), "$var(v)");
    xlog("loopme[$var(count)] == $var(v)\n");
    $var(count) = $var(count) + 1;
}
...
        </programlisting>
        </example>
        <example>
        <title>array concatenation</title>
        <programlisting format="linespecific">
...
$var(count) = 0;
$var(appendme) = '[0,1]';
$var(mylist) = '[2,3,4,5]';
jansson_array_size("", $var(mylist), "$var(appendme_size)");
while($var(count) &lt; $var(appendme_size)) {
    jansson_get("[$var(count)]", $var(mylist), "$var(tmp)");
    jansson_append('int', "", $var(tmp), "$var(appendme)");
    $var(count) = $var(count) + 1;
}
...
        </programlisting>
        </example>
    </section>
    <section id="jansson.f.jansson_xdecode">
        <title>
            <function moreinfo="none">jansson_xdecode(json, xavp)</function>
        </title>
        <para>
            Parse a JSON string in 'json' and store the elements in xapv 'xavp'.
            Top-level JSON must be an object or an array of objects.
            Nested arrays and objects are not decoded but stored as string.
        </para>
        <example>
        <title><function>jansson_xdecode</function> usage</title>
        <programlisting format="linespecific">
...
jansson_xdecode('{"foo":"bar"}', "js");
xlog("foo is $xavp(js=>foo)");
...
        </programlisting>
        </example>
    </section>
    <section id="jansson.f.jansson_xencode">
        <title>
            <function moreinfo="none">jansson_xencode(xavp, pv)</function>
        </title>
        <para>
            Encode the items in the xavp 'xavp' as JSON and store the result in a pv.
            Nested xavp's are not supported.
        </para>
        <example>
        <title><function>jansson_xencode</function> usage</title>
        <programlisting format="linespecific">
...
$xavp(a=>foo) = "bar";
jansson_xencode("a", "$var(js)");
# $var(js) = '{"foo":"bar"}'
...
        </programlisting>
        </example>
    </section>
    <section id="jansson.f.jansson_get_field">
        <title>
            <function moreinfo="none">jansson_get_field(field_name, src, dst)</function>
        </title>
        <para>
			Copy the value of the field 'field_name' from json object 'src'
			and store it in pvar 'dst'. The field name is not evaluated as JSON
			path, therefore it has a different behaviour than jansson_get() and
			can be used when the field name contains path delimiters.
        </para>
        <para>
			Note that till version 5.7.x, this function was similar to jansson_get(),
			after that its behaviour changed to work as described above. Also,
			the order of parameters changed.
        </para>
        <example>
        <title><function>jansson_get_field</function> usage</title>
        <programlisting format="linespecific">
...
jansson_get_field("foo", "{'foo':'bar'}", "$var(foo)");
xlog("foo is $var(foo)");
jansson_get_field("foo.foz", "{'foo.foz':'bar.buz'}", "$var(foofoz)");
xlog("foo.foz is $var(foofoz)");
...
        </programlisting>
        </example>
    </section>
    </section>
</chapter>
