1*3118701fSmlelstv.\" $NetBSD: libmj.3,v 1.10 2018/11/13 14:52:30 mlelstv Exp $ 200d25ba4Sagc.\" 300d25ba4Sagc.\" Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org> 400d25ba4Sagc.\" All rights reserved. 500d25ba4Sagc.\" 600d25ba4Sagc.\" Redistribution and use in source and binary forms, with or without 700d25ba4Sagc.\" modification, are permitted provided that the following conditions 800d25ba4Sagc.\" are met: 900d25ba4Sagc.\" 1. Redistributions of source code must retain the above copyright 1000d25ba4Sagc.\" notice, this list of conditions and the following disclaimer. 1100d25ba4Sagc.\" 2. Redistributions in binary form must reproduce the above copyright 1200d25ba4Sagc.\" notice, this list of conditions and the following disclaimer in the 1300d25ba4Sagc.\" documentation and/or other materials provided with the distribution. 1400d25ba4Sagc.\" 1500d25ba4Sagc.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1600d25ba4Sagc.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1700d25ba4Sagc.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1800d25ba4Sagc.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1900d25ba4Sagc.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2000d25ba4Sagc.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2100d25ba4Sagc.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2200d25ba4Sagc.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2300d25ba4Sagc.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2400d25ba4Sagc.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2500d25ba4Sagc.\" 26f1fc57f9Ssevan.Dd April 3, 2018 2700d25ba4Sagc.Dt LIBMJ 3 2800d25ba4Sagc.Os 2900d25ba4Sagc.Sh NAME 3000d25ba4Sagc.Nm libmj 3100d25ba4Sagc.Nd minimalist JSON lightweight data interchange library 3200d25ba4Sagc.Sh LIBRARY 3300d25ba4Sagc.Lb libmj 3400d25ba4Sagc.Sh SYNOPSIS 3500d25ba4Sagc.In mj.h 3600d25ba4Sagc.Ft int 3700d25ba4Sagc.Fo mj_create 3800d25ba4Sagc.Fa "mj_t *atom" "const char *text" "..." 3900d25ba4Sagc.Fc 4000d25ba4Sagc.Ft int 4100d25ba4Sagc.Fo mj_parse 4200d25ba4Sagc.Fa "mj_t *atom" "const char *text" "int *tokfrom" "int *tokto" "int *toktype" 4300d25ba4Sagc.Fc 4400d25ba4Sagc.Ft int 4500d25ba4Sagc.Fo mj_append 4600d25ba4Sagc.Fa "mj_t *atom" "const char *text" "..." 4700d25ba4Sagc.Fc 4800d25ba4Sagc.Ft int 4900d25ba4Sagc.Fo mj_append_field 5000d25ba4Sagc.Fa "mj_t *atom" "const char *fieldname" "const char *text" "..." 5100d25ba4Sagc.Fc 5200d25ba4Sagc.Ft int 5300d25ba4Sagc.Fo mj_deepcopy 5400d25ba4Sagc.Fa "mj_t *dest" "mj_t *src" 5500d25ba4Sagc.Fc 5600d25ba4Sagc.Ft void 5700d25ba4Sagc.Fo mj_delete 5800d25ba4Sagc.Fa "mj_t *atom" 5900d25ba4Sagc.Fc 6000d25ba4Sagc.Pp 6100d25ba4SagcAccess to objects and array entries is made using the following functions: 6200d25ba4Sagc.Ft int 6300d25ba4Sagc.Fo mj_arraycount 6400d25ba4Sagc.Fa "mj_t *atom" 6500d25ba4Sagc.Fc 6600d25ba4Sagc.Ft int 6700d25ba4Sagc.Fo mj_object_find 6800d25ba4Sagc.Fa "mj_t *atom" "const char *name" "const unsigned startpoint" 6900d25ba4Sagc.Fa "const unsigned incr" 7000d25ba4Sagc.Fc 7100d25ba4Sagc.Ft mj_t * 7200d25ba4Sagc.Fo mj_get_atom 7300d25ba4Sagc.Fa "mj_t *atom" "..." 7400d25ba4Sagc.Fc 7500d25ba4Sagc.Pp 7600d25ba4SagcJSON object output functions: 7700d25ba4Sagc.Ft int 7800d25ba4Sagc.Fo mj_snprint 7900d25ba4Sagc.Fa "char *buffer" "size_t size" "mj_t *atom" 8000d25ba4Sagc.Fc 8100d25ba4Sagc.Ft int 8200d25ba4Sagc.Fo mj_asprint 8300d25ba4Sagc.Fa "char **buffer" "mj_t *atom" 8400d25ba4Sagc.Fc 8500d25ba4Sagc.Ft int 8600d25ba4Sagc.Fo mj_string_size 8700d25ba4Sagc.Fa "mj_t *atom" 8800d25ba4Sagc.Fc 8973f34b00Sagc.Ft int 9073f34b00Sagc.Fo mj_pretty 9173f34b00Sagc.Fa "mj_t *atom" "void *stream" "unsigned depth" "const char *trailer" 9273f34b00Sagc.Fc 93e63e4d57Sagc.Ft const char * 94e63e4d57Sagc.Fo mj_string_rep 95e63e4d57Sagc.Fa "mj_t *atom" 96e63e4d57Sagc.Fc 9700d25ba4Sagc.Sh DESCRIPTION 9800d25ba4Sagc.Nm 9900d25ba4Sagcis a small library interface to allow JSON text to be created and parsed. 10000d25ba4SagcJSON is the Java Script Object Notation, 101cdcd9578Sagca lightweight data-interchange format, standardised by the ECMA. 10200d25ba4SagcThe library name 10300d25ba4Sagc.Nm 10400d25ba4Sagcis derived from a further acronym of 10500d25ba4Sagc.Dq minimalist JSON . 10600d25ba4Sagc.\" Hey, Mary! 10700d25ba4Sagc.Pp 10800d25ba4SagcThe 10900d25ba4Sagc.Nm 110394defd1Swizlibrary can be used to create a string in memory which contains a textual 11100d25ba4Sagcrepresentation of a number of objects, arbitrarily structured. 11200d25ba4SagcThe library can also be used to reconstruct the structure. 11300d25ba4SagcData can thus be serialised easily and efficiently, and data structures 11400d25ba4Sagcrebuilt to produce the original structure of the data. 11500d25ba4Sagc.Pp 11600d25ba4SagcJSON contains basic units called atoms, the two 11700d25ba4Sagcbasic atoms being strings and numbers. 118cdcd9578SagcThree other useful atomic values are provided: 11900d25ba4Sagc.Dq null , 12000d25ba4Sagc.Dq false , 12100d25ba4Sagcand 12200d25ba4Sagc.Dq true . 12300d25ba4SagcAtoms can be grouped together as key/value pairs in an 12400d25ba4Sagc.Dq object , 12500d25ba4Sagcand as individual, ordered atoms, in an 12600d25ba4Sagc.Dq array . 12700d25ba4Sagc.Pp 12800d25ba4SagcTo create a new object, the 12900d25ba4Sagc.Fn mj_create 130cdcd9578Sagcfunction is used. 13100d25ba4SagcIt can be deleted using the 13200d25ba4Sagc.Fn mj_delete 13300d25ba4Sagcfunction. 13400d25ba4Sagc.Pp 13500d25ba4SagcAtoms, objects and arrays can be appended 13600d25ba4Sagcto arrays and objects using the 13700d25ba4Sagc.Fn mj_append 13800d25ba4Sagcfunction. 13900d25ba4Sagc.Pp 14000d25ba4SagcObjects can be printed out 14100d25ba4Sagcby using the 14200d25ba4Sagc.Fn mj_snprint 14300d25ba4Sagcfunction. 14400d25ba4SagcThe size of a string of JSON text can be calculated 14500d25ba4Sagcusing the 14600d25ba4Sagc.Fn mj_string_size 14700d25ba4Sagcfunction. 14800d25ba4SagcA utility function 14900d25ba4Sagc.Fn mj_asprint 15000d25ba4Sagcis provided which will allocate space dynamically, 15100d25ba4Sagcusing 15200d25ba4Sagc.Xr calloc 3 , 15300d25ba4Sagcand the JSON serialised text is copied into it. 15400d25ba4SagcThis memory can later be de-allocated using 15500d25ba4Sagc.Xr free 3 . 15673f34b00SagcFor formatted output to a 157cdcd9578Sagc.Vt FILE * 15873f34b00Sagcstream, the 15973f34b00Sagc.Fn mj_pretty 16073f34b00Sagcfunction is used. 16173f34b00SagcThe calling interface gives the ability to indent the 16273f34b00Sagcoutput to a given 16373f34b00Sagc.Fa depth 164*3118701fSmlelstvin characters and for the formatted output to be followed by a 16573f34b00Sagc.Fa trailer 166394defd1Swizstring, which is usually 167394defd1Swiz.Dv NULL 168394defd1Swizfor external calls, but can be any valid string. 16973f34b00SagcOutput is sent to the 17073f34b00Sagc.Fa stream 17173f34b00Sagcfile stream. 17200d25ba4Sagc.Pp 17300d25ba4SagcThe 17400d25ba4Sagc.Fa type 17500d25ba4Sagcargument given to the 17600d25ba4Sagc.Fn mj_create , 17773f34b00Sagc.Fn mj_append , 17873f34b00Sagcand 17900d25ba4Sagc.Fn mj_append_field 18000d25ba4Sagcfunctions is taken from a list of 18100d25ba4Sagc.Dq false 18200d25ba4Sagc.Dq true 18300d25ba4Sagc.Dq null 18400d25ba4Sagc.Dq number 18500d25ba4Sagc.Dq integer 18600d25ba4Sagc.Dq string 18700d25ba4Sagc.Dq array 18800d25ba4Sagcand 18900d25ba4Sagc.Dq object 19000d25ba4Sagctypes. 19100d25ba4SagcAn integer differs from a number in that it cannot take on 19200d25ba4Sagcany floating point values. 19300d25ba4SagcIt is implemented internally using a signed 64-bit integer type. 19400d25ba4SagcThis restriction of values for an integer type may be removed at a later date. 19500d25ba4Sagc.Pp 19600d25ba4SagcWithin a JSON object, the key values can be iterated over using an integer 197394defd1Swizindex to access the individual JSON objects. 19800d25ba4SagcThe index can also be found using the 19900d25ba4Sagc.Fn mj_object_find 20000d25ba4Sagcfunction. 20100d25ba4Sagc.Pp 20200d25ba4SagcThe way objects arrays are implemented in 20300d25ba4Sagc.Nm 20400d25ba4Sagcis by using varying-sized arrays internally. 20500d25ba4SagcObjects have the field name as the even entry in this internal array, 20600d25ba4Sagcwith the value being the odd entry. 20700d25ba4SagcArrays are implemented as a simple array. 20800d25ba4SagcThus, to find an object in an array using 20900d25ba4Sagc.Fn mj_object_find , 210394defd1Swiza value of 1 should be used as the increment value. 21100d25ba4SagcThis means that every entry in the internal array will be examined, 21200d25ba4Sagcand the first match after the starting point will be returned. 21300d25ba4SagcFor objects, an incremental value of 2 should be used, 21400d25ba4Sagcand an even start value should be specified. 215e63e4d57Sagc.Pp 216e63e4d57SagcString values should be created and appended using two parameters in 217e63e4d57Sagcthe stdarg fields, that of the string itself, and its length in bytes 218e63e4d57Sagcimmediately after the string. 219e63e4d57SagcA value of 2207b95ccb1Swiz.Dv \-1 221e63e4d57Sagcmay be used if the string length is not known. 222e63e4d57Sagc.Sh EXAMPLES 223cdcd9578SagcThe following code fragment will make a JSON object 224e63e4d57Sagcout of the string 225e63e4d57Sagc.Dq Hello <USERNAME>\en 226e63e4d57Sagcin the 227e63e4d57Sagcbuffer called 228cdcd9578Sagc.Va buf 229e63e4d57Sagcwhere 2309835dc7aSsevan.Dq USER 231e63e4d57Sagcis the name of the user taken from the runtime environment. 232e63e4d57SagcThe encoded text will be in an allocated buffer called 2339835dc7aSsevan.Va s . 234e63e4d57Sagc.Bd -literal -offset indent 235e63e4d57Sagcmj_t atom; 236e63e4d57Sagcchar buf[BUFSIZ]; 237e63e4d57Sagcchar *s; 238e63e4d57Sagcint cc; 239e63e4d57Sagc 240e63e4d57Sagc(void) memset(\*[Am]atom, 0x0, sizeof(atom)); 241e63e4d57Sagccc = snprintf(buf, sizeof(buf), "Hello %s\en", getenv("USER")); 242e63e4d57Sagcmj_create(\*[Am]atom, "string", buf, cc); 243e63e4d57Sagccc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_JSON_ENCODE); 244e63e4d57Sagc.Ed 245e63e4d57Sagc.Pp 246cdcd9578SagcNext, the following example will take the (binary) text which has been encoded into 247e63e4d57SagcJSON and is in the buffer 248cdcd9578Sagc.Va buf , 249e63e4d57Sagcsuch as in the previous example, and re-create the original text: 250e63e4d57Sagc.Bd -literal -offset indent 251e63e4d57Sagcint from, to, tok, cc; 252e63e4d57Sagcchar *s; 253e63e4d57Sagcmj_t atom; 254e63e4d57Sagc 255e63e4d57Sagc(void) memset(\*[Am]atom, 0x0, sizeof(atom)); 256e63e4d57Sagcfrom = to = tok = 0; 257e63e4d57Sagcmj_parse(\*[Am]atom, buf, \*[Am]from, \*[Am]to, \*[Am]tok); 258e63e4d57Sagccc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_HUMAN); 259e63e4d57Sagcprintf("%.*s", cc, s); 260e63e4d57Sagc.Ed 261e63e4d57Sagc.Pp 262e63e4d57SagcThe 263cdcd9578Sagc.Va s 264e63e4d57Sagcpointer points to allocated storage with the original NUL-terminated string 265e63e4d57Sagcin it. 26600d25ba4Sagc.Sh SEE ALSO 26700d25ba4Sagc.Xr calloc 3 , 26800d25ba4Sagc.Xr free 3 26900d25ba4Sagc.Rs 270394defd1Swiz.%Q Ecma International 271394defd1Swiz.%D December 2009 272394defd1Swiz.%T ECMA-262: ECMAScript Language Specification 27300d25ba4Sagc.%U http://www.ecma-international.org/publications/files/ecma-st/ECMA-262.pdf 274394defd1Swiz.%O 5th Edition 27500d25ba4Sagc.Re 27600d25ba4Sagc.Sh HISTORY 27700d25ba4SagcThe 27800d25ba4Sagc.Nm 27900d25ba4Sagclibrary first appeared in 28000d25ba4Sagc.Nx 6.0 . 281394defd1Swiz.Sh AUTHORS 282a5684d07Swiz.An Alistair Crooks Aq Mt agc@NetBSD.org 28300d25ba4Sagcwrote this implementation and manual page. 284