aboutsummaryrefslogtreecommitdiff
path: root/json.man
blob: d6867e9d5ee5aa3a2d3718411deb2ce3f2c50281 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
.TH JSON 2
.SH NAME
Jinit, Jtokenise, Jfind, Jnext, Jtokstr \- JSON parser
.SH SYNOPSIS
.B #include <u.h>
.br
.B #include <libc.h>
.br
.B #include <json.h>
.PP
.nf
.ft L
typedef enum{
	JBool,
	JNum,
	JNil,
	JObj,
	JArr,
	JStr,
} Jtype;
.fi
.PP
.nf
.ft L
typedef struct{
	Jtype type;
	char *start;
	char *end;
	uint nsub;
} Jtok;
.fi
.PP
.nf
.ft L
typedef struct{
	uint ntok, mtok;
	Jtok *tokens;
	uint stktop;
	uint tokstk[JStksz];
} Jparser;
.fi
.PP
.B
void Jinit(Jparser *p)
.PP
.B
void Jterm(Jparser *p);
.PP
.B
int Jtokenise(Jparser *p, char *s)
.PP
.B
char *Jtokstr(Jtok *t)
.PP
.B
int Jfind(Jparser *p, uint i, char *s)
.PP
.B
uint Jnext(Jparser *p, uint i)
.PP
.SH DESCRIPTION
These routines implement a fast, in-memory JSON parser.  The parser
operates on a string which is expected to contain the full JSON text.
The string is not altered in any way.
.PP
A parser object
.I p
is initialised using
.IR Jinit .
The parser object contains the number of tokens found
.I ntok
and an array of tokens
.IR tokens .
The other fields are for internal use.  As memory is dynamically
allocated, an initialised parser
.I p
must be terminated with
.I Jterm
after use.
.PP
An initialised parser object is populated with tokens using
.IR Jtokenise .
.I Jtokenise
accepts parser
.I p
and a string
.I s
and returns a filled
.I Jparser
structure containing tokens found in
.IR s .
.I S
is unaltered.
.PP
Each token
.I Jtoken
has a type
.IR Jtype ,
pointers to the
.I start
and 
.I end
of the token's location in the JSON string,
and a count
.I nsub
of the number of subtokens.  The types of a token are
.TP
.I JBool
Boolean value.  Token must be either 't' or 'f'.
.TP
.I JNum
A real number.
.TP
.I JNil
Nill token matching 'n'.
.TP
.I JObj
An object (dictionary) containing key:value pairs.
.TP
.I JArr
An array.
.TP
.I JStr
A string.
.PP
The pointers
.I start
and
.I end
point to the beginning character of the token and to one character
after the end of the token respectively.  The exception are
.I JStr
tokens, where
.I start
points to the first character after the double quote and
.I end
points to the terminating double quote.  As arrays
.I JArr
and objects
.I JObj
are the only types allowing subelements, 
.I nsub
is necessarily 0 for 
.IR JBool ,
.IR JNum ,
.IR JNil ,
and
.IR JStr .
.PP
The functions
.IR Jtokstr ,
.IR Jfind
and
.I Jnext are functions for working with the tokens.
.I Jtokstr
takes a token and extracts out the string pointed to by the token.
The string is null terminated and escaped characters are handled
appropriately.  As
.I Jtokstr
uses a static buffer, the string returned is destroyed on the next
call.
.PP
.I Jfind
is used to find specifically named attributes within a 
.IR JObj .
Given an index into the
.I tokens
array of
.IR p 
which must be a
.I JObj
– and the name of an attribute
.IR s ,
.I Jfind
returns the index of the token corresponding to the value matching the
attribute name.  If no attribute is found then
.I Jfind
returns -1.
.PP
Finally,
.I Jnext
takes and index and calculates the index of the next element at that
depth.  It is used for skipping over
.IR JObj s
and
.IR JArr s
which can contain a number of subelements.
.SH BUGS
The parser does not implement a full grammar so some JSON errors are
not detected when parsing.