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