test-server-libev: disable Werror just on server-libev.c to workaround libev dirt
[platform/upstream/libwebsockets.git] / lib / lejp.h
1 #include "libwebsockets.h"
2 struct lejp_ctx;
3
4 #ifndef ARRAY_SIZE
5 #define ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0]))
6 #endif
7 #define LEJP_FLAG_WS_KEEP 64
8 #define LEJP_FLAG_WS_COMMENTLINE 32
9
10 enum lejp_states {
11         LEJP_IDLE = 0,
12         LEJP_MEMBERS = 1,
13         LEJP_M_P = 2,
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,
20         LEJP_MP_DELIM = 9,
21         LEJP_MP_VALUE = 10,
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,
27 };
28
29 enum lejp_reasons {
30         LEJP_CONTINUE = -1,
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
53 };
54
55 #define LEJP_FLAG_CB_IS_VALUE 64
56
57 enum lejp_callbacks {
58         LEJPCB_CONSTRUCTED      = 0,
59         LEJPCB_DESTRUCTED       = 1,
60
61         LEJPCB_START            = 2,
62         LEJPCB_COMPLETE         = 3,
63         LEJPCB_FAILED           = 4,
64
65         LEJPCB_PAIR_NAME        = 5,
66
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,
75
76         LEJPCB_ARRAY_START      = 14,
77         LEJPCB_ARRAY_END        = 15,
78
79         LEJPCB_OBJECT_START     = 16,
80         LEJPCB_OBJECT_END       = 17
81 };
82
83 /**
84  * _lejp_callback() - User parser actions
85  * \param ctx:  LEJP context
86  * \param reason:       Callback reason
87  *
88  *      Your user callback is associated with the context at construction time,
89  *      and receives calls as the parsing progresses.
90  *
91  *      All of the callbacks may be ignored and just return 0.
92  *
93  *      The reasons it might get called, found in @reason, are:
94  *
95  *  LEJPCB_CONSTRUCTED:  The context was just constructed... you might want to
96  *              perform one-time allocation for the life of the context.
97  *
98  *  LEJPCB_DESTRUCTED:  The context is being destructed... if you made any
99  *              allocations at construction-time, you can free them now
100  *
101  *  LEJPCB_START:       Parsing is beginning at the first byte of input
102  *
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
106  *
107  *  LEJPCB_FAILED:      Parsing failed.  You'll get a negative error code
108  *                      returned from lejp_parse
109  *
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[]
113  *
114  *  LEJPCB_VAL_TRUE:    The "true" value appeared
115  *
116  *  LEJPCB_VAL_FALSE:   The "false" value appeared
117  *
118  *  LEJPCB_VAL_NULL:    The "null" value appeared
119  *
120  *  LEJPCB_VAL_NUM_INT: A string representing an integer is in ctx->buf
121  *
122  *  LEJPCB_VAL_NUM_FLOAT: A string representing a float is in ctx->buf
123  *
124  *  LEJPCB_VAL_STR_START: We are starting to parse a string, no data yet
125  *
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
130  *                      callback.
131  *
132  *  LEJPCB_VAL_STR_END: String parsing has completed, the last chunk of the
133  *                      string is in ctx->buf.
134  *
135  *  LEJPCB_ARRAY_START: An array started
136  *
137  *  LEJPCB_ARRAY_END:   An array ended
138  *
139  *  LEJPCB_OBJECT_START: An object started
140  *
141  *  LEJPCB_OBJECT_END:  An object ended
142  */
143 LWS_EXTERN char _lejp_callback(struct lejp_ctx *ctx, char reason);
144
145 typedef char (*lejp_callback)(struct lejp_ctx *ctx, char reason);
146
147 #ifndef LEJP_MAX_DEPTH
148 #define LEJP_MAX_DEPTH 12
149 #endif
150 #ifndef LEJP_MAX_INDEX_DEPTH
151 #define LEJP_MAX_INDEX_DEPTH 5
152 #endif
153 #ifndef LEJP_MAX_PATH
154 #define LEJP_MAX_PATH 128
155 #endif
156 #ifndef LEJP_STRING_CHUNK
157 /* must be >= 30 to assemble floats */
158 #define LEJP_STRING_CHUNK 255
159 #endif
160
161 enum num_flags {
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)
166 };
167
168 struct _lejp_stack {
169         char s; /* lejp_state stack*/
170         char p; /* path length */
171         char i; /* index array length */
172         char b; /* user bitfield */
173 };
174
175 struct lejp_ctx {
176
177         /* sorted by type for most compact alignment
178          *
179          * pointers
180          */
181
182         char (*callback)(struct lejp_ctx *ctx, char reason);
183         void *user;
184         const char * const *paths;
185
186         /* arrays */
187
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];
193
194         /* int */
195
196         unsigned int line;
197
198         /* short */
199
200         unsigned short uni;
201
202         /* char */
203
204         unsigned char npos;
205         unsigned char dcount;
206         unsigned char f;
207         unsigned char sp; /* stack head */
208         unsigned char ipos; /* index stack depth */
209         unsigned char ppos;
210         unsigned char count_paths;
211         unsigned char path_match;
212         unsigned char path_match_len;
213         unsigned char wildcount;
214 };
215
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);
220
221 LWS_VISIBLE LWS_EXTERN void
222 lejp_destruct(struct lejp_ctx *ctx);
223
224 LWS_VISIBLE LWS_EXTERN int
225 lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len);
226
227 LWS_VISIBLE LWS_EXTERN void
228 lejp_change_callback(struct lejp_ctx *ctx,
229                        char (*callback)(struct lejp_ctx *ctx, char reason));
230
231 LWS_VISIBLE LWS_EXTERN int
232 lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len);