NetBurner 3.1
json_lexer.h
1 /*NB_REVISION*/
2 
3 /*NB_COPYRIGHT*/
4 
5 #ifndef _JSON_LEXER_H
6 #define _JSON_LEXER_H
7 
8 #include <buffers.h>
9 #include <math.h>
10 #include <nettypes.h>
11 #include <webclient/web_buffers.h>
12 
13 enum json_primative_type
14 {
15  UNDEFINED,
16  BEGIN_ARRAY, //[
17  BEGIN_OBJECT, //{
18  END_ARRAY, //]
19  END_OBJECT, //}
20  NAME, //"xxx":
21  STRING, //"xxx"
22  VALUE_SEPERATOR, //,
23  NUMBER, // A number
24  FALSE_EL, // false
25  TRUE_EL, // true
26  NULL_EL, // null
27  STRING_TOO_BIG, // Error we got a sting, but it was too big to fit in the storage scheme (1500 bytes)
28  ALLOC_STRING, // We allocated a large string
29  NOTFOUND, // Return value when we don't find what w are lookign for
30  EOF_EL // Last token in the data set
31 };
32 
33 /* Helper function type def for print functions */
34 typedef void(CharOutputFn)(const char *chars, int len, void *blob);
35 
36 struct JsonAlocString
37 {
38 JsonAlocString * pNext;
39 char data[];
40 };
41 
42 // A class to hold a JSON object
43 class ParsedJsonDataSet : public buffer_object
44 {
45  PoolPtr m_pStorage_List_Head;
46  PoolPtr m_pCurrent_Pool;
47  JsonAlocString * pStringList;
48  int m_nCurrent_Position;
49  int m_nMax_Position;
50  int m_nPool_Count;
51  bool bEnableLargeStrings;
52 
53  // Parser state vars used when recieving text data
54  int m_state; // Parser state flag
55  unsigned char m_sep; // Current string seperator
56  unsigned short m_tv;
57  unsigned char *m_pPrevStringStart;
58  int m_nStrLen;
59  bool bNeedComma;
60 
61  unsigned char *PutChar(unsigned char c); // Used to proces incomming text
62  void CheckForAndFixBrokenString();
63  void ProcessChar(unsigned char c);
64  void ZeroNextString();
65  void ZeroNextNumber(char c);
66  void AddStringChar(char c);
67  void AddNumberChar(char c);
68  void EmitNumberBuffer();
69  bool CheckStringEmit(json_primative_type t);
70  void Emit(json_primative_type t);
71  void ChangeString(json_primative_type t);
72  bool IncPosition();
73  bool JumpPosition(int siz);
74  bool Built();
75 
76  virtual void Error(const char *err); // Error handler
77 
78 
79 
80  // Web byffer stuff so it can recieve stuff friom get post etc....
81 
82  // Used to print objects
83  void printhelper(CharOutputFn *pf, void *p, bool pretty, bool from_here=false);
84 
85  void ResetPosition();
86 
87  public:
88 
89  //Enable allocated strings larger than 1500 bytes
90  void EnableLargeStrings(bool b) {bEnableLargeStrings=b; };
91 
92 
93 
94  virtual int WriteData(const unsigned char *pCopyFrom, int num_bytes);
95 
96  /*********************SCANNING Functions *******************/
97  // Functions to scan through elements
98  // returns UNDEFINED if parsing is not complete
99  // returns EOF_EL on last element;
100  json_primative_type GetFirst(); // First element
101  json_primative_type GetNext(); // Move up one element
102  json_primative_type GetCurrent(); // Get current position element
103  json_primative_type GetRawCurrent(); // Get current position element including non public types
104 
105  // Retrieve only name elements
106  // returns NOTFOUND if its not there
107  json_primative_type GetNextName();
108  json_primative_type GetNextNameInCurrentObject(); // Retrieve only name elements inside current object
109  json_primative_type GetNextNameInCurrentArray();
110 
111  /***********************FIND Functions ************************/
112  // All of these can return NOTFOUND
113 
114  /*This function works with doted string to find sub elements
115  For instance...
116 
117  {
118  "SUCCESS": true,
119  "ACTION": null,
120  "JDATA": {
121  "foo": 7,
122  "bar": {
123  "b1": "Sb1",
124  "b2": {
125  "s1": "Sub1",
126  "s2": "Sub2",
127  "s3": "Sub3",
128  "s4": {
129  "Sub4a": "Test4a",
130  "Sub4b": "Test4b" <---------------------
131  },
132  "s5": "Sub5",
133  "s6": "Sub6"
134  },
135  "b3": true,
136  "b4": null
137  },
138  "bogus": "Bstring",
139  "nubog": 1234.57,
140  "av": [
141  1,
142  2,
143  3,
144  4,
145  5,
146  6,
147  7,
148  8,
149  9,
150  10
151  ],
152  "aftaav": true
153  }
154  }
155  You could get the elment pointed to with the <-----------------
156  by
157  FindFullName("JDATA.bar.b2.s4.Sub4b");
158  In this example the current element would be the "Test4b" string
159  */
160  json_primative_type FindFullName(const char *name);
161 
162  json_primative_type FindFullAtName(const char *name);
163 
164  // Finds name in current object points at element after name
165  // Only supports simple names, not dotted names
166  // Finds from current postion to end..
167  json_primative_type FindElementAfterName(const char *name);
168 
169  // Finds from current position to end
170  // if that fails starts over at the beginning
171  json_primative_type FindGlobalElementAfterName(const char *name);
172 
173  // Only finds names on the current object indent level, does not find elements inside sub objects
174  json_primative_type FindElementAfterNameInCurrentObject(const char *name);
175 
176  json_primative_type FindElementAfterNameInCurrentArray(const char *name);
177 
178  /********************Variable conversion functions *******************************************
179  These conver the element at the current position
180  */
181 
182  bool CurrentBool(); // Only returns true for true element
183  bool PermissiveCurrentBool(); // returns true for true element,"True","true", non zero number
184  double CurrentNumber();
185  const char *CurrentString();
186  const char *CurrentName();
187 
188  /********************************Find and conver ***************************************/
189 
190  // If element is not found returns false;
191  bool FindFullNameBoolean(const char *name)
192  {
193  if (FindFullName(name) == TRUE_EL) return true;
194  return false;
195  };
196  bool FindGlobalBoolean(const char *name)
197  {
198  if (FindGlobalElementAfterName(name) == TRUE_EL) return true;
199  return false;
200  };
201  bool FindBoolean(const char *name)
202  {
203  if (FindElementAfterName(name) == TRUE_EL) return true;
204  return false;
205  };
206  bool FindBooleanInCurentObject(const char *name)
207  {
208  if (FindElementAfterNameInCurrentObject(name) == TRUE_EL) return true;
209  return false;
210  };
211 
212  // If element is not found returns false;
213  bool FindFullNamePermissiveBoolean(const char *name)
214  {
215  if (FindFullName(name) != NOTFOUND) return PermissiveCurrentBool();
216  return false;
217  };
218  bool FindGlobalPermissiveBoolean(const char *name)
219  {
220  if (FindGlobalElementAfterName(name) != NOTFOUND) return PermissiveCurrentBool();
221  return false;
222  };
223  bool FindPermissiveBoolean(const char *name)
224  {
225  if (FindElementAfterName(name) != NOTFOUND) return PermissiveCurrentBool();
226  return false;
227  };
228  bool FindPermissiveBooleanInCurentObject(const char *name)
229  {
230  if (FindElementAfterNameInCurrentObject(name) != NOTFOUND) return PermissiveCurrentBool();
231  return false;
232  };
233 
234  // If item not found returns null
235  const char *FindFullNameString(const char *name)
236  {
237  if (FindFullName(name) == STRING) return CurrentString();
238  return 0;
239  };
240  const char *FindGlobalString(const char *name)
241  {
242  if (FindGlobalElementAfterName(name) == STRING) return CurrentString();
243  return 0;
244  };
245  const char *FindString(const char *name)
246  {
247  if (FindElementAfterName(name) == STRING) return CurrentString();
248  return 0;
249  };
250  const char *FindStringInCurentObject(const char *name)
251  {
252  if (FindElementAfterNameInCurrentObject(name) == STRING) return CurrentString();
253  return 0;
254  };
255 
256  // if item is not found returns nan
257  double FindFullNameNumber(const char *name)
258  {
259  if (FindFullName(name) == NUMBER) return CurrentNumber();
260  return nan("quiet");
261  };
262  double FindGlobalNumber(const char *name)
263  {
264  if (FindGlobalElementAfterName(name) == NUMBER) return CurrentNumber();
265  return nan("quiet");
266  };
267  double FindNumber(const char *name)
268  {
269  if (FindElementAfterName(name) == NUMBER) return CurrentNumber();
270  return nan("quiet");
271  };
272  double FindNumberInCurentObject(const char *name)
273  {
274  if (FindElementAfterNameInCurrentObject(name) == NUMBER) return CurrentNumber();
275  return nan("quiet");
276  };
277 
278  // If item is not found returns false
279  bool FindGlobalObject(const char *name)
280  {
281  if (FindGlobalElementAfterName(name) == BEGIN_OBJECT) return true;
282  return false;
283  };
284  bool FindObject(const char *name)
285  {
286  if (FindElementAfterName(name) == BEGIN_OBJECT) return true;
287  return false;
288  };
289  bool FindObjectInCurentObject(const char *name)
290  {
291  if (FindElementAfterNameInCurrentObject(name) == BEGIN_OBJECT) return true;
292  return false;
293  };
294 
295  // Constructors
296  // Build emty
297  ParsedJsonDataSet();
298  ParsedJsonDataSet(const char *pData, int len = 0, bool bBigStrings=false); // 0 len mean use strlen
299  // Destructor
300  ~ParsedJsonDataSet();
301 
302  bool CopyObject(ParsedJsonDataSet & src_set);
303 
304 
305  // Clear out the ojbject reset to virgin state
306  void ClearObject();
307 
308  // Diagnostic Show whats in the parse tree
309  void DumpState();
310 
311  // prints the json, with pretty has \r\n and nice indent
312  // without the pretty its minimal space
313 
314  // Print to stdio
315  void PrintObject(bool pretty = false);
316 
317  // Print to a char buffer, returns chars written
318  int PrintObjectToBuffer(char *buffer, int maxlen, bool pretty = false);
319 
320  // print to an FD
321  void PrintObjectToFd(int fd, bool pretty = false);
322 
323  // Doesnt really print just calculates how many chars it would print
324  int GetPrintSize(bool pretty = false);
325 
326  private:
327  void InsertName(const char *name);
328  void InsertString(const char *s);
329  void Insert(short i);
330  void Insert(int i);
331  void Insert(long i);
332  void Insert(unsigned short i);
333  void Insert(unsigned int i);
334  void Insert(unsigned long i);
335  void Insert(bool b);
336  void Insert(double d);
337  void Insert(const IPADDR &ip);
338 
339  public:
340  /* Used for building new json objects */
341  void StartBuilding();
342  void AddObjectStart(const char *name);
343  void AddMyMac(const char *name);
344  void Add(const char *name, int i);
345  void Add(const char *name, short i);
346  void Add(const char *name, long i);
347  void Add(const char *name, unsigned int i);
348  void Add(const char *name, unsigned short i);
349  void Add(const char *name, unsigned long i);
350  void Add(const char *name, double d);
351  void Add(const char *name, const char *str);
352  void Add(const char *name, bool b);
353  void Add(const char *name, IPADDR4 i4);
354  void Add(const char *name, const IPADDR &i);
355  void Add(const char *name, const MACADR &ma);
356  void AddNull(const char *name);
357  void AddArrayStart(const char *name);
358  void EndArray();
359 
360  void AddArrayElement(int i);
361  void AddArrayElement(short i);
362  void AddArrayElement(long i);
363  void AddArrayElement(unsigned int i);
364  void AddArrayElement(unsigned short i);
365  void AddArrayElement(unsigned long i);
366  void AddArrayElement(double d);
367  void AddArrayElement(const char *str);
368  void AddArrayElement(bool b);
369  void AddArrayElement(const IPADDR &i);
370  void AddArrayElementArray();
371  void AddArrayObjectStart();
372  void AddNullArrayElement();
373 
374  void EndObject();
375  void DoneBuilding();
376 };
377 
378 const char *GetTypeName(json_primative_type t);
379 
380 #endif
Used to hold and manipulate IPv4 and IPv6 addresses in dual stack mode.
Definition: ipv6_addr.h:28
NetBurner Buffers API.
void WriteData(int fd, const char *c, int siz)
Definition: gifCompress.cpp:142