jer_support.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
3  * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
4  * All rights reserved.
5  * Redistribution and modifications are permitted subject to BSD license.
6  */
9 
10 /* Parser states */
11 typedef enum {
21 } pstate_e;
22 
23 static const int _charclass[256] = {
24  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
25  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26  0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, /* 01234567 89
27  */
28  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* ABCDEFG HIJKLMNO */
29  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, /* PQRSTUVW XYZ */
30  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* abcdefg hijklmno */
31  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0 /* pqrstuvw xyz */
32 };
33 #define WHITESPACE(c) (_charclass[(unsigned char)(c)] == 1)
34 #define ALNUM(c) (_charclass[(unsigned char)(c)] >= 2)
35 #define ALPHA(c) (_charclass[(unsigned char)(c)] == 3)
36 
37 /* Aliases for characters, ASCII/UTF-8 */
38 #define CCOLON 0x3a /* ':' */
39 #define LCBRAC 0x7b /* '{' */
40 #define RCBRAC 0x7d /* '}' */
41 #define CQUOTE 0x22 /* '"' */
42 #define LSBRAC 0x5b /* '[' */
43 #define RSBRAC 0x5d /* ']' */
44 #define CCOMMA 0x2c /* ',' */
45 
46 /* Invoke token callback */
47 #define TOKEN_CB_CALL(type, _ns, _current_too, _final) \
48  do { \
49  int _ret; \
50  pstate_e ns = _ns; \
51  ssize_t _sz = (p - chunk_start) + _current_too; \
52  if(!_sz) { \
53  /* Shortcut */ \
54  state = _ns; \
55  break; \
56  } \
57  _ret = cb(type, chunk_start, _sz, key); \
58  if(_ret < _sz) { \
59  if(_current_too && _ret == -1) state = ns; \
60  goto finish; \
61  } \
62  chunk_start = p + _current_too; \
63  state = ns; \
64  } while(0)
65 
66 #define TOKEN_CB(_type, _ns, _current_too) \
67  TOKEN_CB_CALL(_type, _ns, _current_too, 0)
68 
69 #define PJSON_KEY_FINAL_CHUNK_TYPE PJSON_KEY_END
70 #define PJSON_VALUE_FINAL_CHUNK_TYPE PJSON_VALUE_END
71 
72 #define TOKEN_CB_FINAL(_type, _ns, _current_too) \
73  TOKEN_CB_CALL(_type##_FINAL_CHUNK_TYPE, _ns, _current_too, 1)
74 
75 /*
76  * Parser itself
77  */
78 ssize_t
79 pjson_parse(int *stateContext, const void *jsonbuf, size_t size,
80  pjson_callback_f *cb, void *key) {
81  pstate_e state = (pstate_e)*stateContext;
82  const char *chunk_start = (const char *)jsonbuf;
83  const char *p = chunk_start;
84  const char *end = p + size;
85 
86  int include = 0;
87  int in_string = 0;
88  int escaped = 0;
89 
90  for(; p < end; p++) {
91  int C = *(const unsigned char *)p;
92  switch(state) {
93  case ST_TEXT:
94  /*
95  * Initial state: we're in the middle of some text,
96  * or just have started.
97  */
98 
99  if(C == CQUOTE && !escaped) { /* " */
100  in_string = !in_string;
101  break;
102  } else {
103  if (C == '\\') {
104  escaped = !escaped;
105  break;
106  } else {
107  escaped = 0;
108  }
109  }
110 
111  if (!in_string) {
112  switch(C) {
113  case LCBRAC:
114  /* We're now in an object */
116  break;
117  case LSBRAC:
118  /* We're now in an array */
120  break;
121 
122  case RSBRAC:
123  include = !(p - chunk_start);
125  break;
126  case RCBRAC:
127  include = !(p - chunk_start);
129  break;
130  case CCOMMA:
132  break;
133  default:
134  break;
135  }
136  }
137  break;
138 
139  case ST_KEY: /* Looking for key */
140  switch(C) {
141  case RCBRAC: /* Empty object { } */
143  break;
144  case CQUOTE: /* Key start */
146  break;
147  default:
148  break;
149  }
150  break;
151 
152  case ST_KEY_BODY: /* Inside key */
153  switch(C) {
154  case CQUOTE: /* Key end */
156  break;
157  default:
158  break;
159  }
160  break;
161 
162  case ST_COLON: /* Looking for colon */
163  switch(C) {
164  case CCOLON:
165  state = ST_VALUE;
166  break;
167  default:
168  break;
169  }
170  break;
171 
172  case ST_VALUE: /* Looking for value */
173  if (WHITESPACE(C)) {
174  break;
175  } else {
176  switch(C) {
177  case CCOMMA:
179  break;
180  case RCBRAC:
182  break;
183  case RSBRAC:
185  break;
186  default:
188  break;
189  }
190  }
191  break;
192 
193  case ST_VALUE_BODY: /* Inside value */
194  switch(C) {
195  case RCBRAC:
197  break;
198  case CCOMMA:
199  include = !(p - chunk_start);
200  TOKEN_CB_FINAL(PJSON_VALUE, ST_KEY, include);
201  break;
202  default:
203  break;
204  }
205  break;
206 
207  case ST_ARRAY_VALUE: /* Looking for array value */
208  if (WHITESPACE(C)) {
209  break;
210  } else {
211  switch(C) {
212  case LCBRAC:
214  break;
215  case CCOMMA:
217  break;
218  case LSBRAC:
220  break;
221  case RSBRAC:
223  break;
224  default:
226  break;
227  }
228  }
229  break;
230 
231  case ST_ARRAY_VALUE_BODY: /* Inside array value */
232  switch(C) {
233  case RSBRAC:
234  include = !(p - chunk_start);
236  break;
237  case CCOMMA:
238  include = !(p - chunk_start);
239  if (!include) {
241  } else {
243  }
244  break;
245  default:
246  break;
247  }
248  break;
249 
250  case ST_END: /* End */
251  switch (C) {
252  case RCBRAC:
254  break;
255  default:
256  break;
257  }
258  break;
259  } /* switch(*ptr) */
260  } /* for() */
261 
262  /*
263  * Flush the partially processed chunk, state permitting.
264  */
265  if(p - chunk_start) {
266  switch (state) {
267  case ST_TEXT:
268  TOKEN_CB_FINAL(PJSON_VALUE, state, 0);
269  break;
270  default:
271  break;
272  }
273  }
274 
275 finish:
276  *stateContext = (int)state;
277  return chunk_start - (const char *)jsonbuf;
278 }
jer_support.h
PJSON_DLM
@ PJSON_DLM
Definition: jer_support.h:29
RSBRAC
#define RSBRAC
Definition: jer_support.c:43
pjson_callback_f
int() pjson_callback_f(pjson_chunk_type_e _type, const void *_chunk_data, size_t _chunk_size, void *_key)
Definition: jer_support.h:46
pstate_e
pstate_e
Definition: jer_support.c:11
PJSON_TEXT
@ PJSON_TEXT
Definition: jer_support.h:26
ST_ARRAY_VALUE_BODY
@ ST_ARRAY_VALUE_BODY
Definition: jer_support.c:19
CCOLON
#define CCOLON
Definition: jer_support.c:38
ST_VALUE_BODY
@ ST_VALUE_BODY
Definition: jer_support.c:17
RCBRAC
#define RCBRAC
Definition: jer_support.c:40
ST_KEY
@ ST_KEY
Definition: jer_support.c:13
PJSON_VALUE
@ PJSON_VALUE
Definition: jer_support.h:28
ST_VALUE
@ ST_VALUE
Definition: jer_support.c:16
_charclass
static const int _charclass[256]
Definition: jer_support.c:23
CQUOTE
#define CQUOTE
Definition: jer_support.c:41
LSBRAC
#define LSBRAC
Definition: jer_support.c:42
ST_KEY_BODY
@ ST_KEY_BODY
Definition: jer_support.c:14
PJSON_KEY
@ PJSON_KEY
Definition: jer_support.h:27
ST_TEXT
@ ST_TEXT
Definition: jer_support.c:12
asn_system.h
ST_COLON
@ ST_COLON
Definition: jer_support.c:15
key
static void ssize_t void * key
Definition: asn_internal.h:96
CCOMMA
#define CCOMMA
Definition: jer_support.c:44
ST_END
@ ST_END
Definition: jer_support.c:20
WHITESPACE
#define WHITESPACE(c)
Definition: jer_support.c:33
LCBRAC
#define LCBRAC
Definition: jer_support.c:39
pjson_parse
ssize_t pjson_parse(int *stateContext, const void *jsonbuf, size_t size, pjson_callback_f *cb, void *key)
Definition: jer_support.c:79
ST_ARRAY_VALUE
@ ST_ARRAY_VALUE
Definition: jer_support.c:18
TOKEN_CB
#define TOKEN_CB(_type, _ns, _current_too)
Definition: jer_support.c:66
TOKEN_CB_FINAL
#define TOKEN_CB_FINAL(_type, _ns, _current_too)
Definition: jer_support.c:72


etsi_its_vam_ts_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:30:55