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_DEPTH
177 #define LEJP_MAX_DEPTH 12
178 #endif
179 #ifndef LEJP_MAX_INDEX_DEPTH
180 #define LEJP_MAX_INDEX_DEPTH 5
181 #endif
182 #ifndef LEJP_MAX_PATH
183 #define LEJP_MAX_PATH 128
184 #endif
185 #ifndef LEJP_STRING_CHUNK
186 /* must be >= 30 to assemble floats */
187 #define LEJP_STRING_CHUNK 254
188 #endif
189 
190 enum num_flags {
191  LEJP_SEEN_MINUS = (1 << 0),
192  LEJP_SEEN_POINT = (1 << 1),
193  LEJP_SEEN_POST_POINT = (1 << 2),
194  LEJP_SEEN_EXP = (1 << 3)
195 };
196 
197 struct _lejp_stack {
198  char s; /* lejp_state stack*/
199  char p; /* path length */
200  char i; /* index array length */
201  char b; /* user bitfield */
202 };
203 
204 struct lejp_ctx {
205 
206  /* sorted by type for most compact alignment
207  *
208  * pointers
209  */
210 
211  signed char (*callback)(struct lejp_ctx *ctx, char reason);
212  void *user;
213  const char * const *paths;
214 
215  /* arrays */
216 
217  struct _lejp_stack st[LEJP_MAX_DEPTH];
218  uint16_t i[LEJP_MAX_INDEX_DEPTH]; /* index array */
219  uint16_t wild[LEJP_MAX_INDEX_DEPTH]; /* index array */
220  char path[LEJP_MAX_PATH];
221  char buf[LEJP_STRING_CHUNK + 1];
222 
223  /* int */
224 
225  uint32_t line;
226 
227  /* short */
228 
229  uint16_t uni;
230 
231  /* char */
232 
233  uint8_t npos;
234  uint8_t dcount;
235  uint8_t f;
236  uint8_t sp; /* stack head */
237  uint8_t ipos; /* index stack depth */
238  uint8_t ppos;
239  uint8_t count_paths;
240  uint8_t path_match;
241  uint8_t path_match_len;
242  uint8_t wildcount;
243 };
244 
245 LWS_VISIBLE LWS_EXTERN void
246 lejp_construct(struct lejp_ctx *ctx,
247  signed char (*callback)(struct lejp_ctx *ctx, char reason),
248  void *user, const char * const *paths, unsigned char paths_count);
249 
250 LWS_VISIBLE LWS_EXTERN void
251 lejp_destruct(struct lejp_ctx *ctx);
252 
253 LWS_VISIBLE LWS_EXTERN int
254 lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len);
255 
256 LWS_VISIBLE LWS_EXTERN void
257 lejp_change_callback(struct lejp_ctx *ctx,
258  signed char (*callback)(struct lejp_ctx *ctx, char reason));
259 
260 LWS_VISIBLE LWS_EXTERN int
261 lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len);
lejp_ctx
Definition: lws-lejp.h:204
_lejp_stack
Definition: lws-lejp.h:197