libwebsockets
Lightweight C library for HTML5 websockets
lws-lejp.h
Go to the documentation of this file.
1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25/** \defgroup lejp JSON parser
26 * ##JSON parsing related functions
27 * \ingroup lwsapi
28 *
29 * LEJP is an extremely lightweight JSON stream parser included in lws.
30 */
31//@{
32struct lejp_ctx;
33
34#if !defined(LWS_ARRAY_SIZE)
35#define LWS_ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0]))
36#endif
37#define LEJP_FLAG_WS_KEEP 64
38#define LEJP_FLAG_WS_COMMENTLINE 32
39
57};
58
83};
84
85#define LEJP_FLAG_CB_IS_VALUE 64
86
90
94
96
102 LEJPCB_VAL_STR_START = 11, /* notice handle separately */
105
108
111
113};
114
115/**
116 * _lejp_callback() - User parser actions
117 * \param ctx: LEJP context
118 * \param reason: Callback reason
119 *
120 * Your user callback is associated with the context at construction time,
121 * and receives calls as the parsing progresses.
122 *
123 * All of the callbacks may be ignored and just return 0.
124 *
125 * The reasons it might get called, found in @reason, are:
126 *
127 * LEJPCB_CONSTRUCTED: The context was just constructed... you might want to
128 * perform one-time allocation for the life of the context.
129 *
130 * LEJPCB_DESTRUCTED: The context is being destructed... if you made any
131 * allocations at construction-time, you can free them now
132 *
133 * LEJPCB_START: Parsing is beginning at the first byte of input
134 *
135 * LEJPCB_COMPLETE: Parsing has completed successfully. You'll get a 0 or
136 * positive return code from lejp_parse indicating the
137 * amount of unused bytes left in the input buffer
138 *
139 * LEJPCB_FAILED: Parsing failed. You'll get a negative error code
140 * returned from lejp_parse
141 *
142 * LEJPCB_PAIR_NAME: When a "name":"value" pair has had the name parsed,
143 * this callback occurs. You can find the new name at
144 * the end of ctx->path[]
145 *
146 * LEJPCB_VAL_TRUE: The "true" value appeared
147 *
148 * LEJPCB_VAL_FALSE: The "false" value appeared
149 *
150 * LEJPCB_VAL_NULL: The "null" value appeared
151 *
152 * LEJPCB_VAL_NUM_INT: A string representing an integer is in ctx->buf
153 *
154 * LEJPCB_VAL_NUM_FLOAT: A string representing a float is in ctx->buf
155 *
156 * LEJPCB_VAL_STR_START: We are starting to parse a string, no data yet
157 *
158 * LEJPCB_VAL_STR_CHUNK: We filled the string buffer in the ctx, but it's not
159 * the end of the string. We produce this to spill the
160 * intermediate buffer to the user code, so we can handle
161 * huge JSON strings using only the small buffer in the
162 * ctx. If the whole JSON string fits in the ctx buffer,
163 * you won't get these callbacks.
164 *
165 * LEJPCB_VAL_STR_END: String parsing has completed, the last chunk of the
166 * string is in ctx->buf.
167 *
168 * LEJPCB_ARRAY_START: An array started
169 *
170 * LEJPCB_ARRAY_END: An array ended
171 *
172 * LEJPCB_OBJECT_START: An object started
173 *
174 * LEJPCB_OBJECT_END: An object ended
175 */
176LWS_EXTERN signed char _lejp_callback(struct lejp_ctx *ctx, char reason);
177
178typedef signed char (*lejp_callback)(struct lejp_ctx *ctx, char reason);
179
180#ifndef LEJP_MAX_PARSING_STACK_DEPTH
181#define LEJP_MAX_PARSING_STACK_DEPTH 8
182#endif
183#ifndef LEJP_MAX_DEPTH
184#define LEJP_MAX_DEPTH 16
185#endif
186#ifndef LEJP_MAX_INDEX_DEPTH
187#define LEJP_MAX_INDEX_DEPTH 12
188#endif
189#ifndef LEJP_MAX_PATH
190#define LEJP_MAX_PATH 192
191#endif
192#ifndef LEJP_STRING_CHUNK
193/* must be >= 30 to assemble floats */
194#define LEJP_STRING_CHUNK 254
195#endif
196
198 LEJP_SEEN_MINUS = (1 << 0),
199 LEJP_SEEN_POINT = (1 << 1),
201 LEJP_SEEN_EXP = (1 << 3)
203
205 char s; /* lejp_state stack*/
206 char p; /* path length */
207 char i; /* index array length */
208 char b; /* user bitfield */
209};
210
212 void *user; /* private to the stack level */
213 signed char (*callback)(struct lejp_ctx *ctx, char reason);
214 const char * const *paths;
218};
219
220struct lejp_ctx {
221
222 /* sorted by type for most compact alignment
223 *
224 * pointers
225 */
226 void *user;
227
228 /* arrays */
229
232 uint16_t i[LEJP_MAX_INDEX_DEPTH]; /* index array */
236
237 /* size_t */
238
239 size_t path_stride; /* 0 means default ptr size, else stride */
240
241 /* int */
242
244
245 /* short */
246
248#define LEJP_FLAG_FEAT_OBJECT_INDEXES (1 << 0)
249#define LEJP_FLAG_FEAT_LEADING_WC (1 << 1)
250#define LEJP_FLAG_LATEST
254
255 /* char */
256
260 uint8_t sp; /* stack head */
261 uint8_t ipos; /* index stack depth */
266 uint8_t pst_sp; /* parsing stack head */
268};
269
270LWS_VISIBLE LWS_EXTERN void
272 signed char (*callback)(struct lejp_ctx *ctx, char reason),
273 void *user, const char * const *paths, unsigned char paths_count);
274
275LWS_VISIBLE LWS_EXTERN void
277
278LWS_VISIBLE LWS_EXTERN int
279lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len);
280
281LWS_VISIBLE LWS_EXTERN void
283 signed char (*callback)(struct lejp_ctx *ctx, char reason));
284
285/*
286 * push the current paths / paths_count and lejp_cb to a stack in the ctx, and
287 * start using the new ones
288 */
289LWS_VISIBLE LWS_EXTERN int
290lejp_parser_push(struct lejp_ctx *ctx, void *user, const char * const *paths,
291 unsigned char paths_count, lejp_callback lejp_cb);
292
293/*
294 * pop the previously used paths / paths_count and lejp_cb, and continue
295 * parsing using those as before
296 */
297LWS_VISIBLE LWS_EXTERN int
299
300/* exported for use when reevaluating a path for use with a subcontext */
301LWS_VISIBLE LWS_EXTERN void
303
304LWS_VISIBLE LWS_EXTERN int
305lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len);
306
307LWS_VISIBLE LWS_EXTERN const char *
309//@}
lejp_states
Definition: lws-lejp.h:40
@ LEJP_MP_VALUE_TOK
Definition: lws-lejp.h:54
@ LEJP_MP_STRING
Definition: lws-lejp.h:44
@ LEJP_M_P
Definition: lws-lejp.h:43
@ LEJP_MP_STRING_ESC_U4
Definition: lws-lejp.h:49
@ LEJP_MP_VALUE_NUM_EXP
Definition: lws-lejp.h:53
@ LEJP_MEMBERS
Definition: lws-lejp.h:42
@ LEJP_MP_STRING_ESC_U1
Definition: lws-lejp.h:46
@ LEJP_MP_DELIM
Definition: lws-lejp.h:50
@ LEJP_IDLE
Definition: lws-lejp.h:41
@ LEJP_MP_VALUE_NUM_INT
Definition: lws-lejp.h:52
@ LEJP_MP_STRING_ESC_U3
Definition: lws-lejp.h:48
@ LEJP_MP_ARRAY_END
Definition: lws-lejp.h:56
@ LEJP_MP_COMMA_OR_END
Definition: lws-lejp.h:55
@ LEJP_MP_STRING_ESC
Definition: lws-lejp.h:45
@ LEJP_MP_VALUE
Definition: lws-lejp.h:51
@ LEJP_MP_STRING_ESC_U2
Definition: lws-lejp.h:47
size_t path_stride
Definition: lws-lejp.h:239
LWS_VISIBLE LWS_EXTERN void lejp_construct(struct lejp_ctx *ctx, signed char(*callback)(struct lejp_ctx *ctx, char reason), void *user, const char *const *paths, unsigned char paths_count)
struct _lejp_stack st[LEJP_MAX_DEPTH]
Definition: lws-lejp.h:231
uint8_t outer_array
Definition: lws-lejp.h:267
#define LEJP_FLAG_FEAT_OBJECT_INDEXES
Definition: lws-lejp.h:248
uint8_t f
Definition: lws-lejp.h:259
uint8_t path_match
Definition: lws-lejp.h:263
uint16_t uni
Definition: lws-lejp.h:247
#define LEJP_MAX_PATH
Definition: lws-lejp.h:190
#define LEJP_MAX_PARSING_STACK_DEPTH
Definition: lws-lejp.h:181
uint8_t sp
Definition: lws-lejp.h:260
uint8_t pst_sp
Definition: lws-lejp.h:266
uint8_t ipos
Definition: lws-lejp.h:261
LWS_VISIBLE LWS_EXTERN int lejp_parser_pop(struct lejp_ctx *ctx)
lejp_reasons
Definition: lws-lejp.h:59
@ LEJP_REJECT_ILLEGAL_HEX
Definition: lws-lejp.h:67
@ LEJP_REJECT_MP_C_OR_E_NEITHER
Definition: lws-lejp.h:80
@ LEJP_REJECT_MP_VAL_NUM_FORMAT
Definition: lws-lejp.h:71
@ LEJP_REJECT_MP_ARRAY_END_MISSING
Definition: lws-lejp.h:76
@ LEJP_REJECT_UNKNOWN
Definition: lws-lejp.h:81
@ LEJP_CONTINUE
Definition: lws-lejp.h:60
@ LEJP_REJECT_MP_DELIM_MISSING_COLON
Definition: lws-lejp.h:68
@ LEJP_REJECT_MP_C_OR_E_UNDERF
Definition: lws-lejp.h:74
@ LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC
Definition: lws-lejp.h:66
@ LEJP_REJECT_MP_VAL_TOK_UNKNOWN
Definition: lws-lejp.h:73
@ LEJP_REJECT_MP_C_OR_E_NOTARRAY
Definition: lws-lejp.h:75
@ LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC
Definition: lws-lejp.h:70
@ LEJP_REJECT_MEMBERS_NO_CLOSE
Definition: lws-lejp.h:62
@ LEJP_REJECT_MP_DELIM_ISTACK
Definition: lws-lejp.h:78
@ LEJP_REJECT_IDLE_NO_BRACE
Definition: lws-lejp.h:61
@ LEJP_REJECT_CALLBACK
Definition: lws-lejp.h:82
@ LEJP_REJECT_NUM_TOO_LONG
Definition: lws-lejp.h:79
@ LEJP_REJECT_MP_STRING_UNDERRUN
Definition: lws-lejp.h:64
@ LEJP_REJECT_MP_NO_OPEN_QUOTE
Definition: lws-lejp.h:63
@ LEJP_REJECT_MP_ILLEGAL_CTRL
Definition: lws-lejp.h:65
@ LEJP_REJECT_STACK_OVERFLOW
Definition: lws-lejp.h:77
@ LEJP_REJECT_MP_DELIM_BAD_VALUE_START
Definition: lws-lejp.h:69
@ LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP
Definition: lws-lejp.h:72
uint8_t count_paths
Definition: lws-lejp.h:262
lejp_callbacks
Definition: lws-lejp.h:87
@ LEJPCB_VAL_FALSE
Definition: lws-lejp.h:98
@ LEJPCB_OBJECT_END
Definition: lws-lejp.h:110
@ LEJPCB_USER_START
Definition: lws-lejp.h:112
@ LEJPCB_START
Definition: lws-lejp.h:91
@ LEJPCB_VAL_NUM_FLOAT
Definition: lws-lejp.h:101
@ LEJPCB_ARRAY_END
Definition: lws-lejp.h:107
@ LEJPCB_OBJECT_START
Definition: lws-lejp.h:109
@ LEJPCB_VAL_TRUE
Definition: lws-lejp.h:97
@ LEJPCB_VAL_NUM_INT
Definition: lws-lejp.h:100
@ LEJPCB_CONSTRUCTED
Definition: lws-lejp.h:88
@ LEJPCB_FAILED
Definition: lws-lejp.h:93
@ LEJPCB_COMPLETE
Definition: lws-lejp.h:92
@ LEJPCB_ARRAY_START
Definition: lws-lejp.h:106
@ LEJPCB_VAL_STR_END
Definition: lws-lejp.h:104
@ LEJPCB_VAL_NULL
Definition: lws-lejp.h:99
@ LEJPCB_VAL_STR_CHUNK
Definition: lws-lejp.h:103
@ LEJPCB_VAL_STR_START
Definition: lws-lejp.h:102
@ LEJPCB_DESTRUCTED
Definition: lws-lejp.h:89
@ LEJPCB_PAIR_NAME
Definition: lws-lejp.h:95
LWS_VISIBLE LWS_EXTERN void lejp_check_path_match(struct lejp_ctx *ctx)
num_flags
Definition: lws-lejp.h:197
@ LEJP_SEEN_EXP
Definition: lws-lejp.h:201
@ LEJP_SEEN_POINT
Definition: lws-lejp.h:199
@ LEJP_SEEN_MINUS
Definition: lws-lejp.h:198
@ LEJP_SEEN_POST_POINT
Definition: lws-lejp.h:200
LWS_VISIBLE LWS_EXTERN int lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len)
#define LEJP_FLAG_FEAT_LEADING_WC
Definition: lws-lejp.h:249
void * user
Definition: lws-lejp.h:226
LWS_VISIBLE LWS_EXTERN void lejp_change_callback(struct lejp_ctx *ctx, signed char(*callback)(struct lejp_ctx *ctx, char reason))
LWS_EXTERN signed char _lejp_callback(struct lejp_ctx *ctx, char reason)
#define LEJP_STRING_CHUNK
Definition: lws-lejp.h:194
uint8_t path_match_len
Definition: lws-lejp.h:264
LWS_VISIBLE LWS_EXTERN const char * lejp_error_to_string(int e)
uint8_t npos
Definition: lws-lejp.h:257
uint8_t wildcount
Definition: lws-lejp.h:265
LWS_VISIBLE LWS_EXTERN int lejp_parser_push(struct lejp_ctx *ctx, void *user, const char *const *paths, unsigned char paths_count, lejp_callback lejp_cb)
#define LEJP_FLAG_CB_IS_VALUE
Definition: lws-lejp.h:85
#define LEJP_MAX_DEPTH
Definition: lws-lejp.h:184
LWS_VISIBLE LWS_EXTERN void lejp_destruct(struct lejp_ctx *ctx)
signed char(* lejp_callback)(struct lejp_ctx *ctx, char reason)
Definition: lws-lejp.h:178
uint16_t flags
Definition: lws-lejp.h:253
uint8_t dcount
Definition: lws-lejp.h:258
#define LEJP_MAX_INDEX_DEPTH
Definition: lws-lejp.h:187
#define LEJP_FLAG_WS_KEEP
Definition: lws-lejp.h:37
char buf[LEJP_STRING_CHUNK+1]
Definition: lws-lejp.h:235
char path[LEJP_MAX_PATH]
Definition: lws-lejp.h:234
uint32_t line
Definition: lws-lejp.h:243
struct _lejp_parsing_stack pst[LEJP_MAX_PARSING_STACK_DEPTH]
Definition: lws-lejp.h:230
LWS_VISIBLE LWS_EXTERN int lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len)
uint8_t count_paths
Definition: lws-lejp.h:215
signed char(* callback)(struct lejp_ctx *ctx, char reason)
Definition: lws-lejp.h:213
const char *const * paths
Definition: lws-lejp.h:214
uint8_t path_match
Definition: lws-lejp.h:217