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