libwebsockets
Lightweight C library for HTML5 websockets
lws-lejp.h
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
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
40enum lejp_states {
41 LEJP_IDLE = 0,
42 LEJP_MEMBERS = 1,
43 LEJP_M_P = 2,
44 LEJP_MP_STRING = LEJP_FLAG_WS_KEEP | 3,
45 LEJP_MP_STRING_ESC = LEJP_FLAG_WS_KEEP | 4,
46 LEJP_MP_STRING_ESC_U1 = LEJP_FLAG_WS_KEEP | 5,
47 LEJP_MP_STRING_ESC_U2 = LEJP_FLAG_WS_KEEP | 6,
48 LEJP_MP_STRING_ESC_U3 = LEJP_FLAG_WS_KEEP | 7,
49 LEJP_MP_STRING_ESC_U4 = LEJP_FLAG_WS_KEEP | 8,
50 LEJP_MP_DELIM = 9,
51 LEJP_MP_VALUE = 10,
52 LEJP_MP_VALUE_NUM_INT = LEJP_FLAG_WS_KEEP | 11,
53 LEJP_MP_VALUE_NUM_EXP = LEJP_FLAG_WS_KEEP | 12,
54 LEJP_MP_VALUE_TOK = LEJP_FLAG_WS_KEEP | 13,
55 LEJP_MP_COMMA_OR_END = 14,
56 LEJP_MP_ARRAY_END = 15,
57};
58
59enum lejp_reasons {
60 LEJP_CONTINUE = -1,
61 LEJP_REJECT_IDLE_NO_BRACE = -2,
62 LEJP_REJECT_MEMBERS_NO_CLOSE = -3,
63 LEJP_REJECT_MP_NO_OPEN_QUOTE = -4,
64 LEJP_REJECT_MP_STRING_UNDERRUN = -5,
65 LEJP_REJECT_MP_ILLEGAL_CTRL = -6,
66 LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC = -7,
67 LEJP_REJECT_ILLEGAL_HEX = -8,
68 LEJP_REJECT_MP_DELIM_MISSING_COLON = -9,
69 LEJP_REJECT_MP_DELIM_BAD_VALUE_START = -10,
70 LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC = -11,
71 LEJP_REJECT_MP_VAL_NUM_FORMAT = -12,
72 LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP = -13,
73 LEJP_REJECT_MP_VAL_TOK_UNKNOWN = -14,
74 LEJP_REJECT_MP_C_OR_E_UNDERF = -15,
75 LEJP_REJECT_MP_C_OR_E_NOTARRAY = -16,
76 LEJP_REJECT_MP_ARRAY_END_MISSING = -17,
77 LEJP_REJECT_STACK_OVERFLOW = -18,
78 LEJP_REJECT_MP_DELIM_ISTACK = -19,
79 LEJP_REJECT_NUM_TOO_LONG = -20,
80 LEJP_REJECT_MP_C_OR_E_NEITHER = -21,
81 LEJP_REJECT_UNKNOWN = -22,
82 LEJP_REJECT_CALLBACK = -23
83};
84
85#define LEJP_FLAG_CB_IS_VALUE 64
86
87enum lejp_callbacks {
88 LEJPCB_CONSTRUCTED = 0,
89 LEJPCB_DESTRUCTED = 1,
90
91 LEJPCB_START = 2,
92 LEJPCB_COMPLETE = 3,
93 LEJPCB_FAILED = 4,
94
95 LEJPCB_PAIR_NAME = 5,
96
97 LEJPCB_VAL_TRUE = LEJP_FLAG_CB_IS_VALUE | 6,
98 LEJPCB_VAL_FALSE = LEJP_FLAG_CB_IS_VALUE | 7,
99 LEJPCB_VAL_NULL = LEJP_FLAG_CB_IS_VALUE | 8,
100 LEJPCB_VAL_NUM_INT = LEJP_FLAG_CB_IS_VALUE | 9,
101 LEJPCB_VAL_NUM_FLOAT = LEJP_FLAG_CB_IS_VALUE | 10,
102 LEJPCB_VAL_STR_START = 11, /* notice handle separately */
103 LEJPCB_VAL_STR_CHUNK = LEJP_FLAG_CB_IS_VALUE | 12,
104 LEJPCB_VAL_STR_END = LEJP_FLAG_CB_IS_VALUE | 13,
105
106 LEJPCB_ARRAY_START = 14,
107 LEJPCB_ARRAY_END = 15,
108
109 LEJPCB_OBJECT_START = 16,
110 LEJPCB_OBJECT_END = 17,
111};
112
174LWS_EXTERN signed char _lejp_callback(struct lejp_ctx *ctx, char reason);
175
176typedef signed char (*lejp_callback)(struct lejp_ctx *ctx, char reason);
177
178#ifndef LEJP_MAX_PARSING_STACK_DEPTH
179#define LEJP_MAX_PARSING_STACK_DEPTH 5
180#endif
181#ifndef LEJP_MAX_DEPTH
182#define LEJP_MAX_DEPTH 12
183#endif
184#ifndef LEJP_MAX_INDEX_DEPTH
185#define LEJP_MAX_INDEX_DEPTH 8
186#endif
187#ifndef LEJP_MAX_PATH
188#define LEJP_MAX_PATH 128
189#endif
190#ifndef LEJP_STRING_CHUNK
191/* must be >= 30 to assemble floats */
192#define LEJP_STRING_CHUNK 254
193#endif
194
195enum num_flags {
196 LEJP_SEEN_MINUS = (1 << 0),
197 LEJP_SEEN_POINT = (1 << 1),
198 LEJP_SEEN_POST_POINT = (1 << 2),
199 LEJP_SEEN_EXP = (1 << 3)
200};
201
203 char s; /* lejp_state stack*/
204 char p; /* path length */
205 char i; /* index array length */
206 char b; /* user bitfield */
207};
208
210 void *user; /* private to the stack level */
211 signed char (*callback)(struct lejp_ctx *ctx, char reason);
212 const char * const *paths;
213 uint8_t count_paths;
214 uint8_t ppos;
215 uint8_t path_match;
216};
217
218struct lejp_ctx {
219
220 /* sorted by type for most compact alignment
221 *
222 * pointers
223 */
224 void *user;
225
226 /* arrays */
227
228 struct _lejp_parsing_stack pst[LEJP_MAX_PARSING_STACK_DEPTH];
229 struct _lejp_stack st[LEJP_MAX_DEPTH];
230 uint16_t i[LEJP_MAX_INDEX_DEPTH]; /* index array */
231 uint16_t wild[LEJP_MAX_INDEX_DEPTH]; /* index array */
232 char path[LEJP_MAX_PATH];
233 char buf[LEJP_STRING_CHUNK + 1];
234
235 /* size_t */
236
237 size_t path_stride; /* 0 means default ptr size, else stride */
238
239 /* int */
240
241 uint32_t line;
242
243 /* short */
244
245 uint16_t uni;
246
247 /* char */
248
249 uint8_t npos;
250 uint8_t dcount;
251 uint8_t f;
252 uint8_t sp; /* stack head */
253 uint8_t ipos; /* index stack depth */
254 uint8_t count_paths;
255 uint8_t path_match;
256 uint8_t path_match_len;
257 uint8_t wildcount;
258 uint8_t pst_sp; /* parsing stack head */
259 uint8_t outer_array;
260};
261
262LWS_VISIBLE LWS_EXTERN void
263lejp_construct(struct lejp_ctx *ctx,
264 signed char (*callback)(struct lejp_ctx *ctx, char reason),
265 void *user, const char * const *paths, unsigned char paths_count);
266
267LWS_VISIBLE LWS_EXTERN void
268lejp_destruct(struct lejp_ctx *ctx);
269
270LWS_VISIBLE LWS_EXTERN int
271lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len);
272
273LWS_VISIBLE LWS_EXTERN void
274lejp_change_callback(struct lejp_ctx *ctx,
275 signed char (*callback)(struct lejp_ctx *ctx, char reason));
276
277/*
278 * push the current paths / paths_count and lejp_cb to a stack in the ctx, and
279 * start using the new ones
280 */
281LWS_VISIBLE LWS_EXTERN int
282lejp_parser_push(struct lejp_ctx *ctx, void *user, const char * const *paths,
283 unsigned char paths_count, lejp_callback lejp_cb);
284
285/*
286 * pop the previously used paths / paths_count and lejp_cb, and continue
287 * parsing using those as before
288 */
289LWS_VISIBLE LWS_EXTERN int
290lejp_parser_pop(struct lejp_ctx *ctx);
291
292/* exported for use when reevaluating a path for use with a subcontext */
293LWS_VISIBLE LWS_EXTERN void
294lejp_check_path_match(struct lejp_ctx *ctx);
295
296LWS_VISIBLE LWS_EXTERN int
297lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len);
298
299LWS_VISIBLE LWS_EXTERN const char *
300lejp_error_to_string(int e);
Definition lws-lejp.h:209
Definition lws-lejp.h:202
Definition lws-lejp.h:218