json.h 11.1 KB
Newer Older
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 7
/*                                                                     */
/*  This file contains the JSON classes declares.                      */
/***********************************************************************/
8
#pragma once
9
#include <mysql_com.h>
10
#include "value.h"
11
#include "xobject.h"
12 13 14 15 16 17 18

#if defined(_DEBUG)
#define X  assert(false);
#else
#define X
#endif

19
enum JTYP {
Olivier Bertrand's avatar
Olivier Bertrand committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
	TYPE_NULL = TYPE_VOID,
	TYPE_STRG = TYPE_STRING,
	TYPE_DBL = TYPE_DOUBLE,
	TYPE_BOOL = TYPE_TINY,
	TYPE_BINT = TYPE_BIGINT,
	TYPE_INTG = TYPE_INT,
	TYPE_DTM = TYPE_DATE,
	TYPE_FLOAT,
	TYPE_JAR,
	TYPE_JOB,
	TYPE_JVAL,
	TYPE_JSON,
	TYPE_DEL,
	TYPE_UNKNOWN
};
35

36
class JDOC;
37 38 39 40 41 42
class JOUT;
class JSON;
class JVALUE;
class JOBJECT;
class JARRAY;

43
typedef class JDOC    *PJDOC;
44 45 46 47 48
typedef class JSON    *PJSON;
typedef class JVALUE  *PJVAL;
typedef class JOBJECT *PJOB;
typedef class JARRAY  *PJAR;

49
typedef struct JPAIR *PJPR;
50
//typedef struct VAL   *PVL;
51 52 53 54 55 56 57 58 59 60

/***********************************************************************/
/* Structure JPAIR. The pairs of a json Object.                        */
/***********************************************************************/
struct JPAIR {
	PCSZ  Key;      // This pair key name
	PJVAL Val;      // To the value of the pair
	PJPR  Next;     // To the next pair
}; // end of struct JPAIR

61
//PVL   AllocVal(PGLOBAL g, JTYP type);
62 63
char *NextChr(PSZ s, char sep);
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);
Olivier Bertrand's avatar
Olivier Bertrand committed
68
DllExport bool IsNum(PSZ s);
69 70

/***********************************************************************/
71
/* Class JDOC. The class for parsing and serializing json documents.   */
72
/***********************************************************************/
73 74 75 76 77
class JDOC: public BLOCK {
	friend PJSON ParseJson(PGLOBAL, char*, size_t, int*, bool*);
	friend PSZ Serialize(PGLOBAL, PJSON, char*, int);
public:
	JDOC(void) : js(NULL), s(NULL), len(0), pty(NULL) {}
78

79
	void  SetJp(JOUT* jp) { js = jp; }
80 81

 protected:
82 83 84 85
	PJAR  ParseArray(PGLOBAL g, int& i);
	PJOB  ParseObject(PGLOBAL g, int& i);
	PJVAL ParseValue(PGLOBAL g, int& i);
	char *ParseString(PGLOBAL g, int& i);
86
	void  ParseNumeric(PGLOBAL g, int& i, PJVAL jvp);
87 88 89 90 91 92 93 94 95 96 97 98
	PJAR  ParseAsArray(PGLOBAL g, int& i, int pretty, int *ptyp);
	bool  SerializeArray(PJAR jarp, bool b);
	bool  SerializeObject(PJOB jobp);
	bool  SerializeValue(PJVAL jvp);

	// Members used when parsing and serializing
 private:
	JOUT* js;
	char *s;
	int   len;
	bool *pty;
}; // end of class JDOC
99 100 101 102 103

/***********************************************************************/
/* Class JSON. The base class for all other json classes.              */
/***********************************************************************/
class JSON : public BLOCK {
104 105 106 107 108 109 110 111 112 113 114 115 116
public:
	// Constructor
	JSON(void) { Type = TYPE_JSON; }
	JSON(int) {}

	// Implementation
	inline  JTYP   GetType(void) { return Type; }

	// Methods
	virtual int    size(void) { return 1; }
	virtual void   Clear(void) { X }
	virtual PJOB   GetObject(void) { return NULL; }
	virtual PJAR   GetArray(void) { return NULL; }
117
	virtual PJVAL  GetArrayValue(int i) { X return NULL; }
118
	virtual int    GetSize(bool b) { X return 0; }
119
	virtual PJSON  GetJsp(void) { X return NULL; }
120
	virtual PJPR   GetFirst(void) { X return NULL; }
121
	virtual PSZ    GetText(PGLOBAL g, PSTRG text) { X return NULL; }
122
	virtual bool   Merge(PGLOBAL g, PJSON jsp) { X return true; }
123 124 125
	virtual void   SetValue(PJSON jsp) { X }
	virtual bool   DeleteValue(int i) { X return true; }
	virtual bool   IsNull(void) { X return true; }
126 127

	// Members
128
	JTYP Type;
129 130 131 132 133 134
}; // end of class JSON

/***********************************************************************/
/* Class JOBJECT: contains a list of value pairs.                      */
/***********************************************************************/
class JOBJECT : public JSON {
135
  friend class JDOC;
136
	friend class JSNX;
137 138 139 140 141
	friend class SWAP;
public:
	JOBJECT(void) : JSON() { Type = TYPE_JOB; First = Last = NULL; }
	JOBJECT(int i) : JSON(i) {}

142
	// Methods
143 144
	virtual void  Clear(void) {First = Last = NULL;}
//virtual JTYP  GetValType(void) {return TYPE_JOB;}
145
  virtual PJPR  GetFirst(void) {return First;}
146
	virtual int   GetSize(bool b);
147
  virtual PJOB  GetObject(void) {return this;}
148
	virtual PSZ   GetText(PGLOBAL g, PSTRG text);
149
	virtual bool  Merge(PGLOBAL g, PJSON jsp);
150
	virtual bool  IsNull(void);
151

152 153
	// Specific
	PJPR  AddPair(PGLOBAL g, PCSZ key);
154
	PJVAL GetKeyValue(const char* key);
155 156
	PJAR  GetKeyList(PGLOBAL g);
	PJAR  GetValList(PGLOBAL g);
157
	void  SetKeyValue(PGLOBAL g, PJVAL jvp, PCSZ key);
158 159
	void  DeleteKey(PCSZ k);

160 161 162 163 164 165 166 167 168
 protected:
  PJPR First;
  PJPR Last;
}; // end of class JOBJECT

/***********************************************************************/
/* Class JARRAY.                                                       */
/***********************************************************************/
class JARRAY : public JSON {
169
	friend class SWAP;
170
 public:
171
	JARRAY(void);
172
	JARRAY(int i) : JSON(i) {}
173

174
	// Methods
175
  virtual void  Clear(void) {First = Last = NULL; Size = 0;}
176
	virtual int   size(void) { return Size; }
177
  virtual PJAR  GetArray(void) {return this;}
178
	virtual int   GetSize(bool b);
179
  virtual PJVAL GetArrayValue(int i);
180
	virtual PSZ   GetText(PGLOBAL g, PSTRG text);
181
	virtual bool  Merge(PGLOBAL g, PJSON jsp);
182 183 184
  virtual bool  DeleteValue(int n);
  virtual bool  IsNull(void);

185
	// Specific
186 187
	PJVAL AddArrayValue(PGLOBAL g, PJVAL jvp = NULL, int* x = NULL);
	bool  SetArrayValue(PGLOBAL g, PJVAL jvp, int i);
188 189
	void  InitArray(PGLOBAL g);

190 191
 protected:
  // Members
192
	int    Size;		 // The number of items in the array
193 194 195 196 197 198 199 200 201 202 203
  int    Alloc;    // The Mvals allocated size
  PJVAL  First;    // Used when constructing
  PJVAL  Last;     // Last constructed value
  PJVAL *Mvals;    // Allocated when finished
}; // end of class JARRAY

/***********************************************************************/
/* Class JVALUE.                                                       */
/***********************************************************************/
class JVALUE : public JSON {
  friend class JARRAY;
204
	friend class JSNX;
205
	friend class JSONDISC;
206
	friend class JSONCOL;
207
  friend class JSON;
208 209 210 211
	friend class JDOC;
	friend class SWAP;
public:
	JVALUE(void) : JSON() { Type = TYPE_JVAL; Clear(); }
212
	JVALUE(PJSON jsp);
213
//JVALUE(PGLOBAL g, PVL vlp);
214
	JVALUE(PGLOBAL g, PVAL valp);
215
	JVALUE(PGLOBAL g, PCSZ strp);
216
	JVALUE(int i) : JSON(i) {}
217

218 219
  //using JSON::GetVal;
  //using JSON::SetVal;
220 221

	// Methods
222
	virtual void   Clear(void);
223
//virtual JTYP   GetType(void) {return TYPE_JVAL;}
224 225 226
  virtual JTYP   GetValType(void);
  virtual PJOB   GetObject(void);
  virtual PJAR   GetArray(void);
227
  virtual PJSON  GetJsp(void) {return (DataType == TYPE_JSON ? Jsp : NULL);}
228
  virtual PSZ    GetText(PGLOBAL g, PSTRG text);
229
	virtual bool   IsNull(void);
230

231
	// Specific
232 233 234
	//inline PVL  GetVal(void) { return Val; }
	//inline void SetVal(PVL vlp) { Val = vlp; }
	inline PJSON  GetJson(void) { return (DataType == TYPE_JSON ? Jsp : this); }
235 236 237 238 239 240 241 242 243 244 245 246 247
	PSZ    GetString(PGLOBAL g, char* buff = NULL);
	int    GetInteger(void);
	long long GetBigint(void);
	double GetFloat(void);
	PVAL   GetValue(PGLOBAL g);
	void   SetValue(PJSON jsp);
	void   SetValue(PGLOBAL g, PVAL valp);
	void   SetString(PGLOBAL g, PSZ s, int ci = 0);
	void   SetInteger(PGLOBAL g, int n);
	void   SetBigint(PGLOBAL g, longlong ll);
	void   SetFloat(PGLOBAL g, double f);
	void   SetBool(PGLOBAL g, bool b);

248
 protected:
249 250 251 252 253 254 255 256 257 258 259 260 261
	 union {
		 PJSON  Jsp;       // To the json value
		 char  *Strp;      // Ptr to a string
		 int    N;         // An integer value
		 long long LLn;		 // A big integer value
		 double F;				 // A (double) float value
		 bool   B;				 // True or false
	 };
//PVL   Val;      // To the string or numeric value
	PJVAL Next;     // Next value in array
	JTYP  DataType; // The data value type
	int   Nd;				// Decimal number
	bool  Del;      // True when deleted
262
}; // end of class JVALUE
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350


/***********************************************************************/
/* Class JOUT. Used by Serialize.                                      */
/***********************************************************************/
class JOUT : public BLOCK {
public:
	JOUT(PGLOBAL gp) : BLOCK() { g = gp; Pretty = 3; }

	virtual bool WriteStr(const char* s) = 0;
	virtual bool WriteChr(const char c) = 0;
	virtual bool Escape(const char* s) = 0;
	int  Prty(void) { return Pretty; }

	// Member
	PGLOBAL g;
	int     Pretty;
}; // end of class JOUT

/***********************************************************************/
/* Class JOUTSTR. Used to Serialize to a string.                       */
/***********************************************************************/
class JOUTSTR : public JOUT {
public:
	JOUTSTR(PGLOBAL g);

	virtual bool WriteStr(const char* s);
	virtual bool WriteChr(const char c);
	virtual bool Escape(const char* s);

	// Member
	char* Strp;                         // The serialized string
	size_t N;                            // Position of next char
	size_t Max;                          // String max size
}; // end of class JOUTSTR

/***********************************************************************/
/* Class JOUTFILE. Used to Serialize to a file.                        */
/***********************************************************************/
class JOUTFILE : public JOUT {
public:
	JOUTFILE(PGLOBAL g, FILE* str, int pty) : JOUT(g) { Stream = str; Pretty = pty; }

	virtual bool WriteStr(const char* s);
	virtual bool WriteChr(const char c);
	virtual bool Escape(const char* s);

	// Member
	FILE* Stream;
}; // end of class JOUTFILE

/***********************************************************************/
/* Class JOUTPRT. Used to Serialize to a pretty file.                  */
/***********************************************************************/
class JOUTPRT : public JOUTFILE {
public:
	JOUTPRT(PGLOBAL g, FILE* str) : JOUTFILE(g, str, 2) { M = 0; B = false; }

	virtual bool WriteStr(const char* s);
	virtual bool WriteChr(const char c);

	// Member
	int  M;
	bool B;
}; // end of class JOUTPRT


/***********************************************************************/
/* Class SWAP. Used to make or unmake a JSON tree movable.             */
/* This is done by making all pointers to offsets.                     */
/***********************************************************************/
class SWAP : public BLOCK {
public:
	// Constructor
	SWAP(PGLOBAL g, PJSON jsp) 
	{
		G = g, Base = (char*)jsp - 8;
	}

	// Methods
	void   SwapJson(PJSON jsp, bool move);

protected:
	size_t MoffJson(PJSON jnp);
	size_t MoffArray(PJAR jarp);
	size_t MoffObject(PJOB jobp);
	size_t MoffJValue(PJVAL jvp);
	size_t MoffPair(PJPR jpp);
351
//size_t MoffVal(PVL vlp);
352 353 354 355 356
	PJSON  MptrJson(PJSON jnp);
	PJAR   MptrArray(PJAR jarp);
	PJOB   MptrObject(PJOB jobp);
	PJVAL  MptrJValue(PJVAL jvp);
	PJPR   MptrPair(PJPR jpp);
357
//PVL    MptrVal(PVL vlp);
358 359

	// Member
360
	PGLOBAL G;
361 362
	void   *Base;
}; // end of class SWAP