1 #include "libwebsockets.h"
5 #define ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0]))
7 #define LEJP_FLAG_WS_KEEP 64
8 #define LEJP_FLAG_WS_COMMENTLINE 32
14 LEJP_MP_STRING = LEJP_FLAG_WS_KEEP | 3,
15 LEJP_MP_STRING_ESC = LEJP_FLAG_WS_KEEP | 4,
16 LEJP_MP_STRING_ESC_U1 = LEJP_FLAG_WS_KEEP | 5,
17 LEJP_MP_STRING_ESC_U2 = LEJP_FLAG_WS_KEEP | 6,
18 LEJP_MP_STRING_ESC_U3 = LEJP_FLAG_WS_KEEP | 7,
19 LEJP_MP_STRING_ESC_U4 = LEJP_FLAG_WS_KEEP | 8,
22 LEJP_MP_VALUE_NUM_INT = LEJP_FLAG_WS_KEEP | 11,
23 LEJP_MP_VALUE_NUM_EXP = LEJP_FLAG_WS_KEEP | 12,
24 LEJP_MP_VALUE_TOK = LEJP_FLAG_WS_KEEP | 13,
25 LEJP_MP_COMMA_OR_END = 14,
26 LEJP_MP_ARRAY_END = 15,
31 LEJP_REJECT_IDLE_NO_BRACE = -2,
32 LEJP_REJECT_MEMBERS_NO_CLOSE = -3,
33 LEJP_REJECT_MP_NO_OPEN_QUOTE = -4,
34 LEJP_REJECT_MP_STRING_UNDERRUN = -5,
35 LEJP_REJECT_MP_ILLEGAL_CTRL = -6,
36 LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC = -7,
37 LEJP_REJECT_ILLEGAL_HEX = -8,
38 LEJP_REJECT_MP_DELIM_MISSING_COLON = -9,
39 LEJP_REJECT_MP_DELIM_BAD_VALUE_START = -10,
40 LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC = -11,
41 LEJP_REJECT_MP_VAL_NUM_FORMAT = -12,
42 LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP = -13,
43 LEJP_REJECT_MP_VAL_TOK_UNKNOWN = -14,
44 LEJP_REJECT_MP_C_OR_E_UNDERF = -15,
45 LEJP_REJECT_MP_C_OR_E_NOTARRAY = -16,
46 LEJP_REJECT_MP_ARRAY_END_MISSING = -17,
47 LEJP_REJECT_STACK_OVERFLOW = -18,
48 LEJP_REJECT_MP_DELIM_ISTACK = -19,
49 LEJP_REJECT_NUM_TOO_LONG = -20,
50 LEJP_REJECT_MP_C_OR_E_NEITHER = -21,
51 LEJP_REJECT_UNKNOWN = -22,
52 LEJP_REJECT_CALLBACK = -23
55 #define LEJP_FLAG_CB_IS_VALUE 64
58 LEJPCB_CONSTRUCTED = 0,
59 LEJPCB_DESTRUCTED = 1,
67 LEJPCB_VAL_TRUE = LEJP_FLAG_CB_IS_VALUE | 6,
68 LEJPCB_VAL_FALSE = LEJP_FLAG_CB_IS_VALUE | 7,
69 LEJPCB_VAL_NULL = LEJP_FLAG_CB_IS_VALUE | 8,
70 LEJPCB_VAL_NUM_INT = LEJP_FLAG_CB_IS_VALUE | 9,
71 LEJPCB_VAL_NUM_FLOAT = LEJP_FLAG_CB_IS_VALUE | 10,
72 LEJPCB_VAL_STR_START = 11, /* notice handle separately */
73 LEJPCB_VAL_STR_CHUNK = LEJP_FLAG_CB_IS_VALUE | 12,
74 LEJPCB_VAL_STR_END = LEJP_FLAG_CB_IS_VALUE | 13,
76 LEJPCB_ARRAY_START = 14,
77 LEJPCB_ARRAY_END = 15,
79 LEJPCB_OBJECT_START = 16,
80 LEJPCB_OBJECT_END = 17
84 * _lejp_callback() - User parser actions
85 * \param ctx: LEJP context
86 * \param reason: Callback reason
88 * Your user callback is associated with the context at construction time,
89 * and receives calls as the parsing progresses.
91 * All of the callbacks may be ignored and just return 0.
93 * The reasons it might get called, found in @reason, are:
95 * LEJPCB_CONSTRUCTED: The context was just constructed... you might want to
96 * perform one-time allocation for the life of the context.
98 * LEJPCB_DESTRUCTED: The context is being destructed... if you made any
99 * allocations at construction-time, you can free them now
101 * LEJPCB_START: Parsing is beginning at the first byte of input
103 * LEJPCB_COMPLETE: Parsing has completed successfully. You'll get a 0 or
104 * positive return code from lejp_parse indicating the
105 * amount of unused bytes left in the input buffer
107 * LEJPCB_FAILED: Parsing failed. You'll get a negative error code
108 * returned from lejp_parse
110 * LEJPCB_PAIR_NAME: When a "name":"value" pair has had the name parsed,
111 * this callback occurs. You can find the new name at
112 * the end of ctx->path[]
114 * LEJPCB_VAL_TRUE: The "true" value appeared
116 * LEJPCB_VAL_FALSE: The "false" value appeared
118 * LEJPCB_VAL_NULL: The "null" value appeared
120 * LEJPCB_VAL_NUM_INT: A string representing an integer is in ctx->buf
122 * LEJPCB_VAL_NUM_FLOAT: A string representing a float is in ctx->buf
124 * LEJPCB_VAL_STR_START: We are starting to parse a string, no data yet
126 * LEJPCB_VAL_STR_CHUNK: We parsed LEJP_STRING_CHUNK -1 bytes of string data in
127 * ctx->buf, which is as much as we can buffer, so we are
128 * spilling it. If all your strings are less than
129 * LEJP_STRING_CHUNK - 1 bytes, you will never see this
132 * LEJPCB_VAL_STR_END: String parsing has completed, the last chunk of the
133 * string is in ctx->buf.
135 * LEJPCB_ARRAY_START: An array started
137 * LEJPCB_ARRAY_END: An array ended
139 * LEJPCB_OBJECT_START: An object started
141 * LEJPCB_OBJECT_END: An object ended
143 LWS_EXTERN char _lejp_callback(struct lejp_ctx *ctx, char reason);
145 typedef char (*lejp_callback)(struct lejp_ctx *ctx, char reason);
147 #ifndef LEJP_MAX_DEPTH
148 #define LEJP_MAX_DEPTH 12
150 #ifndef LEJP_MAX_INDEX_DEPTH
151 #define LEJP_MAX_INDEX_DEPTH 5
153 #ifndef LEJP_MAX_PATH
154 #define LEJP_MAX_PATH 128
156 #ifndef LEJP_STRING_CHUNK
157 /* must be >= 30 to assemble floats */
158 #define LEJP_STRING_CHUNK 255
162 LEJP_SEEN_MINUS = (1 << 0),
163 LEJP_SEEN_POINT = (1 << 1),
164 LEJP_SEEN_POST_POINT = (1 << 2),
165 LEJP_SEEN_EXP = (1 << 3)
169 char s; /* lejp_state stack*/
170 char p; /* path length */
171 char i; /* index array length */
172 char b; /* user bitfield */
177 /* sorted by type for most compact alignment
182 char (*callback)(struct lejp_ctx *ctx, char reason);
184 const char * const *paths;
188 struct _lejp_stack st[LEJP_MAX_DEPTH];
189 unsigned short i[LEJP_MAX_INDEX_DEPTH]; /* index array */
190 unsigned short wild[LEJP_MAX_INDEX_DEPTH]; /* index array */
191 char path[LEJP_MAX_PATH];
192 char buf[LEJP_STRING_CHUNK];
205 unsigned char dcount;
207 unsigned char sp; /* stack head */
208 unsigned char ipos; /* index stack depth */
210 unsigned char count_paths;
211 unsigned char path_match;
212 unsigned char path_match_len;
213 unsigned char wildcount;
216 LWS_VISIBLE LWS_EXTERN void
217 lejp_construct(struct lejp_ctx *ctx,
218 char (*callback)(struct lejp_ctx *ctx, char reason), void *user,
219 const char * const *paths, unsigned char paths_count);
221 LWS_VISIBLE LWS_EXTERN void
222 lejp_destruct(struct lejp_ctx *ctx);
224 LWS_VISIBLE LWS_EXTERN int
225 lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len);
227 LWS_VISIBLE LWS_EXTERN void
228 lejp_change_callback(struct lejp_ctx *ctx,
229 char (*callback)(struct lejp_ctx *ctx, char reason));
231 LWS_VISIBLE LWS_EXTERN int
232 lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len);