1 /**************** json H Declares Source Code File (.H) ****************/
2 /*  Name: json.h   Version 1.2                                         */
3 /*                                                                     */
4 /*  (C) Copyright to the author Olivier BERTRAND          2014 - 2020  */
5 /*                                                                     */
6 /*  This file contains the JSON classes declares.                      */
7 /***********************************************************************/
8 #pragma once
9 #include <mysql_com.h>
10 #include "value.h"
11 #include "xobject.h"
12 
13 #if defined(_DEBUG)
14 #define X  assert(false);
15 #else
16 #define X
17 #endif
18 
19 enum JTYP {
20 	TYPE_NULL = TYPE_VOID,
21 	TYPE_STRG = TYPE_STRING,
22 	TYPE_DBL = TYPE_DOUBLE,
23 	TYPE_BOOL = TYPE_TINY,
24 	TYPE_BINT = TYPE_BIGINT,
25 	TYPE_INTG = TYPE_INT,
26 	TYPE_DTM = TYPE_DATE,
27 	TYPE_FLOAT,
28 	TYPE_JAR,
29 	TYPE_JOB,
30 	TYPE_JVAL,
31 	TYPE_JSON,
32 	TYPE_DEL,
33 	TYPE_UNKNOWN
34 };
35 
36 class JDOC;
37 class JOUT;
38 class JSON;
39 class JVALUE;
40 class JOBJECT;
41 class JARRAY;
42 
43 typedef class JDOC    *PJDOC;
44 typedef class JSON    *PJSON;
45 typedef class JVALUE  *PJVAL;
46 typedef class JOBJECT *PJOB;
47 typedef class JARRAY  *PJAR;
48 
49 typedef struct JPAIR *PJPR;
50 //typedef struct VAL   *PVL;
51 
52 /***********************************************************************/
53 /* Structure JPAIR. The pairs of a json Object.                        */
54 /***********************************************************************/
55 struct JPAIR {
56 	PCSZ  Key;      // This pair key name
57 	PJVAL Val;      // To the value of the pair
58 	PJPR  Next;     // To the next pair
59 }; // end of struct JPAIR
60 
61 //PVL   AllocVal(PGLOBAL g, JTYP type);
62 char *NextChr(PSZ s, char sep);
63 char *GetJsonNull(void);
64 const char* GetFmt(int type, bool un);
65 
66 PJSON ParseJson(PGLOBAL g, char* s, size_t n, int* prty = NULL, bool* b = NULL);
67 PSZ   Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty);
68 DllExport bool IsNum(PSZ s);
69 bool  IsArray(PSZ s);
70 bool  Stringified(PCSZ strfy, char *colname);
71 
72 /***********************************************************************/
73 /* Class JDOC. The class for parsing and serializing json documents.   */
74 /***********************************************************************/
75 class JDOC: public BLOCK {
76 	friend PJSON ParseJson(PGLOBAL, char*, size_t, int*, bool*);
77 	friend PSZ Serialize(PGLOBAL, PJSON, char*, int);
78 public:
JDOC(void)79 	JDOC(void) : js(NULL), s(NULL), len(0), dfp(0), pty(NULL) {}
80 
SetJp(JOUT * jp)81 	void  SetJp(JOUT* jp) { js = jp; }
82 
83  protected:
84 	PJAR  ParseArray(PGLOBAL g, int& i);
85 	PJOB  ParseObject(PGLOBAL g, int& i);
86 	PJVAL ParseValue(PGLOBAL g, int& i);
87 	char *ParseString(PGLOBAL g, int& i);
88 	void  ParseNumeric(PGLOBAL g, int& i, PJVAL jvp);
89 	PJAR  ParseAsArray(PGLOBAL g, int& i, int pretty, int *ptyp);
90 	bool  SerializeArray(PJAR jarp, bool b);
91 	bool  SerializeObject(PJOB jobp);
92 	bool  SerializeValue(PJVAL jvp);
93 
94 	// Members used when parsing and serializing
95  private:
96 	JOUT* js;
97 	char *s;
98 	int   len, dfp;
99 	bool *pty;
100 }; // end of class JDOC
101 
102 /***********************************************************************/
103 /* Class JSON. The base class for all other json classes.              */
104 /***********************************************************************/
105 class JSON : public BLOCK {
106 public:
107 	// Constructor
JSON(void)108 	JSON(void) { Type = TYPE_JSON; }
JSON(int)109 	JSON(int) {}
110 
111 	// Implementation
GetType(void)112 	inline  JTYP   GetType(void) { return Type; }
113 
114 	// Methods
size(void)115 	virtual int    size(void) { return 1; }
Clear(void)116 	virtual void   Clear(void) { X }
GetObject(void)117 	virtual PJOB   GetObject(void) { return NULL; }
GetArray(void)118 	virtual PJAR   GetArray(void) { return NULL; }
GetArrayValue(int i)119 	virtual PJVAL  GetArrayValue(int i) { X return NULL; }
GetSize(bool b)120 	virtual int    GetSize(bool b) { X return 0; }
GetJsp(void)121 	virtual PJSON  GetJsp(void) { X return NULL; }
GetFirst(void)122 	virtual PJPR   GetFirst(void) { X return NULL; }
GetText(PGLOBAL g,PSTRG text)123 	virtual PSZ    GetText(PGLOBAL g, PSTRG text) { X return NULL; }
Merge(PGLOBAL g,PJSON jsp)124 	virtual bool   Merge(PGLOBAL g, PJSON jsp) { X return true; }
SetValue(PJSON jsp)125 	virtual void   SetValue(PJSON jsp) { X }
DeleteValue(int i)126 	virtual bool   DeleteValue(int i) { X return true; }
IsNull(void)127 	virtual bool   IsNull(void) { X return true; }
128 
129 	// Members
130 	JTYP Type;
131 }; // end of class JSON
132 
133 /***********************************************************************/
134 /* Class JOBJECT: contains a list of value pairs.                      */
135 /***********************************************************************/
136 class JOBJECT : public JSON {
137   friend class JDOC;
138 	friend class JSNX;
139 	friend class SWAP;
140 public:
JOBJECT(void)141 	JOBJECT(void) : JSON() { Type = TYPE_JOB; First = Last = NULL; }
JOBJECT(int i)142 	JOBJECT(int i) : JSON(i) {}
143 
144 	// Methods
Clear(void)145 	virtual void  Clear(void) {First = Last = NULL;}
146 //virtual JTYP  GetValType(void) {return TYPE_JOB;}
GetFirst(void)147   virtual PJPR  GetFirst(void) {return First;}
148 	virtual int   GetSize(bool b);
GetObject(void)149   virtual PJOB  GetObject(void) {return this;}
150 	virtual PSZ   GetText(PGLOBAL g, PSTRG text);
151 	virtual bool  Merge(PGLOBAL g, PJSON jsp);
152 	virtual bool  IsNull(void);
153 
154 	// Specific
155 	PJPR  AddPair(PGLOBAL g, PCSZ key);
156 	PJVAL GetKeyValue(const char* key);
157 	PJAR  GetKeyList(PGLOBAL g);
158 	PJAR  GetValList(PGLOBAL g);
159 	void  SetKeyValue(PGLOBAL g, PJVAL jvp, PCSZ key);
160 	void  DeleteKey(PCSZ k);
161 
162  protected:
163   PJPR First;
164   PJPR Last;
165 }; // end of class JOBJECT
166 
167 /***********************************************************************/
168 /* Class JARRAY.                                                       */
169 /***********************************************************************/
170 class JARRAY : public JSON {
171 	friend class SWAP;
172  public:
173 	JARRAY(void);
JARRAY(int i)174 	JARRAY(int i) : JSON(i) {}
175 
176 	// Methods
Clear(void)177   virtual void  Clear(void) {First = Last = NULL; Size = 0;}
size(void)178 	virtual int   size(void) { return Size; }
GetArray(void)179   virtual PJAR  GetArray(void) {return this;}
180 	virtual int   GetSize(bool b);
181   virtual PJVAL GetArrayValue(int i);
182 	virtual PSZ   GetText(PGLOBAL g, PSTRG text);
183 	virtual bool  Merge(PGLOBAL g, PJSON jsp);
184   virtual bool  DeleteValue(int n);
185   virtual bool  IsNull(void);
186 
187 	// Specific
188 	PJVAL AddArrayValue(PGLOBAL g, PJVAL jvp = NULL, int* x = NULL);
189 	void  SetArrayValue(PGLOBAL g, PJVAL jvp, int i);
190 	void  InitArray(PGLOBAL g);
191 
192  protected:
193   // Members
194 	int    Size;		 // The number of items in the array
195   int    Alloc;    // The Mvals allocated size
196   PJVAL  First;    // Used when constructing
197   PJVAL  Last;     // Last constructed value
198   PJVAL *Mvals;    // Allocated when finished
199 }; // end of class JARRAY
200 
201 /***********************************************************************/
202 /* Class JVALUE.                                                       */
203 /***********************************************************************/
204 class JVALUE : public JSON {
205   friend class JARRAY;
206 	friend class JSNX;
207 	friend class JSONDISC;
208 	friend class JSONCOL;
209   friend class JSON;
210 	friend class JDOC;
211 	friend class SWAP;
212 public:
JVALUE(void)213 	JVALUE(void) : JSON() { Type = TYPE_JVAL; Clear(); }
214 	JVALUE(PJSON jsp);
215 //JVALUE(PGLOBAL g, PVL vlp);
216 	JVALUE(PGLOBAL g, PVAL valp);
217 	JVALUE(PGLOBAL g, PCSZ strp);
JVALUE(int i)218 	JVALUE(int i) : JSON(i) {}
219 
220   //using JSON::GetVal;
221   //using JSON::SetVal;
222 
223 	// Methods
224 	virtual void   Clear(void);
225 //virtual JTYP   GetType(void) {return TYPE_JVAL;}
226   virtual JTYP   GetValType(void);
227   virtual PJOB   GetObject(void);
228   virtual PJAR   GetArray(void);
GetJsp(void)229   virtual PJSON  GetJsp(void) {return (DataType == TYPE_JSON ? Jsp : NULL);}
230   virtual PSZ    GetText(PGLOBAL g, PSTRG text);
231 	virtual bool   IsNull(void);
232 
233 	// Specific
234 	//inline PVL  GetVal(void) { return Val; }
235 	//inline void SetVal(PVL vlp) { Val = vlp; }
GetJson(void)236 	inline PJSON  GetJson(void) { return (DataType == TYPE_JSON ? Jsp : this); }
237 	PSZ    GetString(PGLOBAL g, char* buff = NULL);
238 	int    GetInteger(void);
239 	long long GetBigint(void);
240 	double GetFloat(void);
241 	PVAL   GetValue(PGLOBAL g);
242 	void   SetValue(PJSON jsp);
243 	void   SetValue(PGLOBAL g, PVAL valp);
244 	void   SetString(PGLOBAL g, PSZ s, int ci = 0);
245 	void   SetInteger(PGLOBAL g, int n);
246 	void   SetBigint(PGLOBAL g, longlong ll);
247 	void   SetFloat(PGLOBAL g, double f);
248 	void   SetBool(PGLOBAL g, bool b);
249 
250  protected:
251 	 union {
252 		 PJSON  Jsp;       // To the json value
253 		 char  *Strp;      // Ptr to a string
254 		 int    N;         // An integer value
255 		 long long LLn;		 // A big integer value
256 		 double F;				 // A (double) float value
257 		 bool   B;				 // True or false
258 	 };
259 //PVL   Val;      // To the string or numeric value
260 	PJVAL Next;     // Next value in array
261 	JTYP  DataType; // The data value type
262 	int   Nd;				// Decimal number
263 	bool  Del;      // True when deleted
264 }; // end of class JVALUE
265 
266 
267 /***********************************************************************/
268 /* Class JOUT. Used by Serialize.                                      */
269 /***********************************************************************/
270 class JOUT : public BLOCK {
271 public:
JOUT(PGLOBAL gp)272 	JOUT(PGLOBAL gp) : BLOCK() { g = gp; Pretty = 3; }
273 
274 	virtual bool WriteStr(const char* s) = 0;
275 	virtual bool WriteChr(const char c) = 0;
276 	virtual bool Escape(const char* s) = 0;
Prty(void)277 	int  Prty(void) { return Pretty; }
278 
279 	// Member
280 	PGLOBAL g;
281 	int     Pretty;
282 }; // end of class JOUT
283 
284 /***********************************************************************/
285 /* Class JOUTSTR. Used to Serialize to a string.                       */
286 /***********************************************************************/
287 class JOUTSTR : public JOUT {
288 public:
289 	JOUTSTR(PGLOBAL g);
290 
291 	virtual bool WriteStr(const char* s);
292 	virtual bool WriteChr(const char c);
293 	virtual bool Escape(const char* s);
294 
295 	// Member
296 	char* Strp;                         // The serialized string
297 	size_t N;                            // Position of next char
298 	size_t Max;                          // String max size
299 }; // end of class JOUTSTR
300 
301 /***********************************************************************/
302 /* Class JOUTFILE. Used to Serialize to a file.                        */
303 /***********************************************************************/
304 class JOUTFILE : public JOUT {
305 public:
JOUTFILE(PGLOBAL g,FILE * str,int pty)306 	JOUTFILE(PGLOBAL g, FILE* str, int pty) : JOUT(g) { Stream = str; Pretty = pty; }
307 
308 	virtual bool WriteStr(const char* s);
309 	virtual bool WriteChr(const char c);
310 	virtual bool Escape(const char* s);
311 
312 	// Member
313 	FILE* Stream;
314 }; // end of class JOUTFILE
315 
316 /***********************************************************************/
317 /* Class JOUTPRT. Used to Serialize to a pretty file.                  */
318 /***********************************************************************/
319 class JOUTPRT : public JOUTFILE {
320 public:
JOUTPRT(PGLOBAL g,FILE * str)321 	JOUTPRT(PGLOBAL g, FILE* str) : JOUTFILE(g, str, 2) { M = 0; B = false; }
322 
323 	virtual bool WriteStr(const char* s);
324 	virtual bool WriteChr(const char c);
325 
326 	// Member
327 	int  M;
328 	bool B;
329 }; // end of class JOUTPRT
330 
331 
332 /***********************************************************************/
333 /* Class SWAP. Used to make or unmake a JSON tree movable.             */
334 /* This is done by making all pointers to offsets.                     */
335 /***********************************************************************/
336 class SWAP : public BLOCK {
337 public:
338 	// Constructor
SWAP(PGLOBAL g,PJSON jsp)339 	SWAP(PGLOBAL g, PJSON jsp)
340 	{
341 		G = g, Base = (char*)jsp - 8;
342 	}
343 
344 	// Methods
345 	void   SwapJson(PJSON jsp, bool move);
346 
347 protected:
348 	size_t MoffJson(PJSON jnp);
349 	size_t MoffArray(PJAR jarp);
350 	size_t MoffObject(PJOB jobp);
351 	size_t MoffJValue(PJVAL jvp);
352 	size_t MoffPair(PJPR jpp);
353 //size_t MoffVal(PVL vlp);
354 	PJSON  MptrJson(PJSON jnp);
355 	PJAR   MptrArray(PJAR jarp);
356 	PJOB   MptrObject(PJOB jobp);
357 	PJVAL  MptrJValue(PJVAL jvp);
358 	PJPR   MptrPair(PJPR jpp);
359 //PVL    MptrVal(PVL vlp);
360 
361 	// Member
362 	PGLOBAL G;
363 	void   *Base;
364 }; // end of class SWAP
365