1.\" $NetBSD: libmj.3,v 1.7 2014/02/17 07:23:18 agc Exp $ 2.\" 3.\" Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org> 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25.\" 26.Dd February 16, 2014 27.Dt LIBMJ 3 28.Os 29.Sh NAME 30.Nm libmj 31.Nd minimalist JSON lightweight data interchange library 32.Sh LIBRARY 33.Lb libmj 34.Sh SYNOPSIS 35.In mj.h 36.Ft int 37.Fo mj_create 38.Fa "mj_t *atom" "const char *text" "..." 39.Fc 40.Ft int 41.Fo mj_parse 42.Fa "mj_t *atom" "const char *text" "int *tokfrom" "int *tokto" "int *toktype" 43.Fc 44.Ft int 45.Fo mj_append 46.Fa "mj_t *atom" "const char *text" "..." 47.Fc 48.Ft int 49.Fo mj_append_field 50.Fa "mj_t *atom" "const char *fieldname" "const char *text" "..." 51.Fc 52.Ft int 53.Fo mj_deepcopy 54.Fa "mj_t *dest" "mj_t *src" 55.Fc 56.Ft void 57.Fo mj_delete 58.Fa "mj_t *atom" 59.Fc 60.Pp 61Access to objects and array entries is made using the following functions: 62.Ft int 63.Fo mj_arraycount 64.Fa "mj_t *atom" 65.Fc 66.Ft int 67.Fo mj_object_find 68.Fa "mj_t *atom" "const char *name" "const unsigned startpoint" 69.Fa "const unsigned incr" 70.Fc 71.Ft mj_t * 72.Fo mj_get_atom 73.Fa "mj_t *atom" "..." 74.Fc 75.Pp 76JSON object output functions: 77.Ft int 78.Fo mj_snprint 79.Fa "char *buffer" "size_t size" "mj_t *atom" 80.Fc 81.Ft int 82.Fo mj_asprint 83.Fa "char **buffer" "mj_t *atom" 84.Fc 85.Ft int 86.Fo mj_string_size 87.Fa "mj_t *atom" 88.Fc 89.Ft int 90.Fo mj_pretty 91.Fa "mj_t *atom" "void *stream" "unsigned depth" "const char *trailer" 92.Fc 93.Ft const char * 94.Fo mj_string_rep 95.Fa "mj_t *atom" 96.Fc 97.Sh DESCRIPTION 98.Nm 99is a small library interface to allow JSON text to be created and parsed. 100JSON is the Java Script Object Notation, 101a lightweight data-interchange format, standardised by the ECMA. 102The library name 103.Nm 104is derived from a further acronym of 105.Dq minimalist JSON . 106.\" Hey, Mary! 107.Pp 108The 109.Nm 110library can be used to create a string in memory which contains a textual 111representation of a number of objects, arbitrarily structured. 112The library can also be used to reconstruct the structure. 113Data can thus be serialised easily and efficiently, and data structures 114rebuilt to produce the original structure of the data. 115.Pp 116JSON contains basic units called atoms, the two 117basic atoms being strings and numbers. 118Three other useful atomic values are provided: 119.Dq null , 120.Dq false , 121and 122.Dq true . 123Atoms can be grouped together as key/value pairs in an 124.Dq object , 125and as individual, ordered atoms, in an 126.Dq array . 127.Pp 128To create a new object, the 129.Fn mj_create 130function is used. 131It can be deleted using the 132.Fn mj_delete 133function. 134.Pp 135Atoms, objects and arrays can be appended 136to arrays and objects using the 137.Fn mj_append 138function. 139.Pp 140Objects can be printed out 141by using the 142.Fn mj_snprint 143function. 144The size of a string of JSON text can be calculated 145using the 146.Fn mj_string_size 147function. 148A utility function 149.Fn mj_asprint 150is provided which will allocate space dynamically, 151using 152.Xr calloc 3 , 153and the JSON serialised text is copied into it. 154This memory can later be de-allocated using 155.Xr free 3 . 156For formatted output to a 157.Vt FILE * 158stream, the 159.Fn mj_pretty 160function is used. 161The calling interface gives the ability to indent the 162output to a given 163.Fa depth 164and for the formatted output to be followed by a 165.Fa trailer 166string, which is usually 167.Dv NULL 168for external calls, but can be any valid string. 169Output is sent to the 170.Fa stream 171file stream. 172.Pp 173The 174.Fa type 175argument given to the 176.Fn mj_create , 177.Fn mj_append , 178and 179.Fn mj_append_field 180functions is taken from a list of 181.Dq false 182.Dq true 183.Dq null 184.Dq number 185.Dq integer 186.Dq string 187.Dq array 188and 189.Dq object 190types. 191An integer differs from a number in that it cannot take on 192any floating point values. 193It is implemented internally using a signed 64-bit integer type. 194This restriction of values for an integer type may be removed at a later date. 195.Pp 196Within a JSON object, the key values can be iterated over using an integer 197index to access the individual JSON objects. 198The index can also be found using the 199.Fn mj_object_find 200function. 201.Pp 202The way objects arrays are implemented in 203.Nm 204is by using varying-sized arrays internally. 205Objects have the field name as the even entry in this internal array, 206with the value being the odd entry. 207Arrays are implemented as a simple array. 208Thus, to find an object in an array using 209.Fn mj_object_find , 210a value of 1 should be used as the increment value. 211This means that every entry in the internal array will be examined, 212and the first match after the starting point will be returned. 213For objects, an incremental value of 2 should be used, 214and an even start value should be specified. 215.Pp 216String values should be created and appended using two parameters in 217the stdarg fields, that of the string itself, and its length in bytes 218immediately after the string. 219A value of 220.Dv \-1 221may be used if the string length is not known. 222.Sh EXAMPLES 223The following code fragment will make a JSON object 224out of the string 225.Dq Hello <USERNAME>\en 226in the 227buffer called 228.Va buf 229where 230.Dq USERNAME 231is the name of the user taken from the runtime environment. 232The encoded text will be in an allocated buffer called 233.Va s 234.Bd -literal -offset indent 235mj_t atom; 236char buf[BUFSIZ]; 237char *s; 238int cc; 239 240(void) memset(\*[Am]atom, 0x0, sizeof(atom)); 241cc = snprintf(buf, sizeof(buf), "Hello %s\en", getenv("USER")); 242mj_create(\*[Am]atom, "string", buf, cc); 243cc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_JSON_ENCODE); 244.Ed 245.Pp 246Next, the following example will take the (binary) text which has been encoded into 247JSON and is in the buffer 248.Va buf , 249such as in the previous example, and re-create the original text: 250.Bd -literal -offset indent 251int from, to, tok, cc; 252char *s; 253mj_t atom; 254 255(void) memset(\*[Am]atom, 0x0, sizeof(atom)); 256from = to = tok = 0; 257mj_parse(\*[Am]atom, buf, \*[Am]from, \*[Am]to, \*[Am]tok); 258cc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_HUMAN); 259printf("%.*s", cc, s); 260.Ed 261.Pp 262The 263.Va s 264pointer points to allocated storage with the original NUL-terminated string 265in it. 266.Sh SEE ALSO 267.Xr calloc 3 , 268.Xr free 3 269.Rs 270.%Q Ecma International 271.%D December 2009 272.%T ECMA-262: ECMAScript Language Specification 273.%U http://www.ecma-international.org/publications/files/ecma-st/ECMA-262.pdf 274.%O 5th Edition 275.Re 276.Sh HISTORY 277The 278.Nm 279library first appeared in 280.Nx 6.0 . 281.Sh AUTHORS 282.An Alistair Crooks Aq Mt agc@NetBSD.org 283wrote this implementation and manual page. 284