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
191
192
193
194
195
196
197
198
|
JSON(2) JSON(2)
NAME
Jinit, Jtokenise, Jfind, Jnext, Jtokstr - JSON parser
SYNOPSIS
#include <u.h>
#include <libc.h>
#include <json.h>
typedef enum{
JBool,
JNum,
JNil,
JObj,
JArr,
JStr,
} Jtype;
typedef struct{
Jtype type;
char *start;
char *end;
uint nsub;
} Jtok;
typedef struct{
uint ntok, mtok;
Jtok *tokens;
uint stktop;
uint tokstk[JStksz];
} Jparser;
void Jinit(Jparser *p)
void Jterm(Jparser *p);
int Jtokenise(Jparser *p, char *s)
char *Jtokstr(Jtok *t)
int Jfind(Jparser *p, uint i, char *s)
uint Jnext(Jparser *p, uint i)
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.
A parser object p is initialised using Jinit. The parser
object contains the number of tokens found ntok and an array
JSON(2) JSON(2)
of tokens tokens. The other fields are for internal use. As
memory is dynamically allocated, an initialised parser p
must be terminated with Jterm after use.
An initialised parser object is populated with tokens using
Jtokenise. Jtokenise accepts parser p and a string s and
returns a filled Jparser structure containing tokens found
in s. S is unaltered.
Each token Jtoken has a type Jtype, pointers to the start
and end of the token's location in the JSON string, and a
count nsub of the number of subtokens. The types of a token
are
JBool
Boolean value. Token must be either 't' or 'f'.
JNum A real number.
JNil Nill token matching 'n'.
JObj An object (dictionary) containing key:value pairs.
JArr An array.
JStr A string.
The pointers start and end point to the beginning character
of the token and to one character after the end of the token
respectively. The exception are JStr tokens, where start
points to the first character after the double quote and end
points to the terminating double quote. As arrays JArr and
objects JObj are the only types allowing subelements, nsub
is necessarily 0 for JBool, JNum, JNil, and JStr.
The functions Jtokstr, Jfind and Jnext are functions for
working with Jtokstr takes a token and extracts out the
string pointed to by the token. The string is null termi-
nated and escaped characters are handled appropriately. As
Jtokstr uses a static buffer, the string returned is
destroyed on the next call.
Jfind is used to find specifically named attributes within a
JObj. Given an index into the tokens array of pā which must
be a JObj ā and the name of an attribute s, Jfind returns
the index of the token corresponding to the value matching
the attribute name. If no attribute is found then Jfind
returns -1.
Finally, Jnext takes and index and calculates the index of
the next element at that depth. It is used for skipping
over JObjs and JArrs which can contain a number of
JSON(2) JSON(2)
subelements.
BUGS
The parser does not implement a full grammar so some JSON
errors are not detected when parsing.
|