summaryrefslogtreecommitdiff
path: root/storage/connect/json.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect/json.cpp')
-rw-r--r--storage/connect/json.cpp1903
1 files changed, 1199 insertions, 704 deletions
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index ea3ea18da0b..0152a44fffa 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -1,7 +1,7 @@
/*************** json CPP Declares Source Code File (.H) ***************/
-/* Name: json.cpp Version 1.4 */
+/* Name: json.cpp Version 1.5 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2020 */
/* */
/* This file contains the JSON classes functions. */
/***********************************************************************/
@@ -21,7 +21,7 @@
#include "plgdbsem.h"
#include "json.h"
-#define ARGS MY_MIN(24,len-i),s+MY_MAX(i-3,0)
+#define ARGS MY_MIN(24,(int)len-i),s+MY_MAX(i-3,0)
#if defined(__WIN__)
#define EL "\r\n"
@@ -38,16 +38,16 @@
class SE_Exception {
public:
- SE_Exception(unsigned int n, PEXCEPTION_RECORD p) : nSE(n), eRec(p) {}
- ~SE_Exception() {}
+ SE_Exception(unsigned int n, PEXCEPTION_RECORD p) : nSE(n), eRec(p) {}
+ ~SE_Exception() {}
- unsigned int nSE;
- PEXCEPTION_RECORD eRec;
+ unsigned int nSE;
+ PEXCEPTION_RECORD eRec;
}; // end of class SE_Exception
void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp)
{
- throw SE_Exception(u, pExp->ExceptionRecord);
+ throw SE_Exception(u, pExp->ExceptionRecord);
} // end of trans_func
char *GetExceptionDesc(PGLOBAL g, unsigned int e);
@@ -58,46 +58,60 @@ char *GetJsonNull(void);
/***********************************************************************/
/* IsNum: check whether this string is all digits. */
/***********************************************************************/
-bool IsNum(PSZ s)
-{
- for (char *p = s; *p; p++)
- if (*p == ']')
- break;
- else if (!isdigit(*p) || *p == '-')
- return false;
+bool IsNum(PSZ s) {
+ for (char* p = s; *p; p++)
+ if (*p == ']')
+ break;
+ else if (!isdigit(*p) || *p == '-')
+ return false;
- return true;
-} // end of IsNum
+ return true;
+} // end of IsNum
/***********************************************************************/
/* NextChr: return the first found '[' or Sep pointer. */
/***********************************************************************/
-char *NextChr(PSZ s, char sep)
+char* NextChr(PSZ s, char sep)
{
- char *p1 = strchr(s, '[');
- char *p2 = strchr(s, sep);
+ char* p1 = strchr(s, '[');
+ char* p2 = strchr(s, sep);
- if (!p2)
- return p1;
- else if (p1)
- return MY_MIN(p1, p2);
+ if (!p2)
+ return p1;
+ else if (p1)
+ return MY_MIN(p1, p2);
- return p2;
-} // end of NextChr
+ return p2;
+} // end of NextChr
+#if 0
+/***********************************************************************/
+/* Allocate a VAL structure, make sure common field and Nd are zeroed. */
+/***********************************************************************/
+PVL AllocVal(PGLOBAL g, JTYP type)
+{
+ PVL vlp = (PVL)PlugSubAlloc(g, NULL, sizeof(VAL));
+
+ vlp->LLn = 0;
+ vlp->Nd = 0;
+ vlp->Type = type;
+ return vlp;
+} // end of AllocVal
+#endif // 0
/***********************************************************************/
/* Parse a json string. */
/* Note: when pretty is not known, the caller set pretty to 3. */
/***********************************************************************/
-PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
+PJSON ParseJson(PGLOBAL g, char* s, size_t len, int* ptyp, bool* comma)
{
- int i, pretty = (ptyp) ? *ptyp : 3;
- bool b = false, pty[3] = {true,true,true};
- PJSON jsp = NULL, jp = NULL;
+ int i, pretty = (ptyp) ? *ptyp : 3;
+ bool b = false, pty[3] = { true,true,true };
+ PJSON jsp = NULL;
+ PJDOC jdp = NULL;
- if (trace(1))
- htrc("ParseJson: s=%.10s len=%d\n", s, len);
+ if (trace(1))
+ htrc("ParseJson: s=%.10s len=%zd\n", s, len);
if (!s || !len) {
strcpy(g->Message, "Void JSON object");
@@ -105,116 +119,402 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
} else if (comma)
*comma = false;
- // Trying to guess the pretty format
- if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n')))
- pty[0] = false;
-
- try {
- jp = new(g) JSON();
- jp->s = s;
- jp->len = len;
- jp->pty = pty;
-
- for (i = 0; i < jp->len; i++)
- switch (s[i]) {
- case '[':
- if (jsp)
- jsp = jp->ParseAsArray(g, i, pretty, ptyp);
- else
- jsp = jp->ParseArray(g, ++i);
-
- break;
- case '{':
- if (jsp)
- jsp = jp->ParseAsArray(g, i, pretty, ptyp);
- else if (!(jsp = jp->ParseObject(g, ++i)))
- throw 2;
-
- break;
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- break;
- case ',':
- if (jsp && (pretty == 1 || pretty == 3)) {
- if (comma)
- *comma = true;
-
- pty[0] = pty[2] = false;
- break;
- } // endif pretty
-
- sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty);
- throw 3;
- case '(':
- b = true;
- break;
- case ')':
- if (b) {
- b = false;
- break;
- } // endif b
-
- default:
- if (jsp)
- jsp = jp->ParseAsArray(g, i, pretty, ptyp);
- else if (!(jsp = jp->ParseValue(g, i)))
- throw 4;
-
- break;
- }; // endswitch s[i]
-
- if (!jsp)
- sprintf(g->Message, "Invalid Json string '%.*s'", MY_MIN(len, 50), s);
- else if (ptyp && pretty == 3) {
- *ptyp = 3; // Not recognized pretty
-
- for (i = 0; i < 3; i++)
- if (pty[i]) {
- *ptyp = i;
- break;
- } // endif pty
-
- } // endif ptyp
-
- } catch (int n) {
- if (trace(1))
- htrc("Exception %d: %s\n", n, g->Message);
- jsp = NULL;
- } catch (const char *msg) {
- strcpy(g->Message, msg);
- jsp = NULL;
- } // end catch
-
- return jsp;
+ // Trying to guess the pretty format
+ if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n')))
+ pty[0] = false;
+
+ try {
+ jdp = new(g) JDOC;
+ jdp->s = s;
+ jdp->len = len;
+ jdp->pty = pty;
+
+ for (i = 0; i < jdp->len; i++)
+ switch (s[i]) {
+ case '[':
+ if (jsp)
+ jsp = jdp->ParseAsArray(g, i, pretty, ptyp);
+ else
+ jsp = jdp->ParseArray(g, ++i);
+
+ break;
+ case '{':
+ if (jsp)
+ jsp = jdp->ParseAsArray(g, i, pretty, ptyp);
+ else if (!(jsp = jdp->ParseObject(g, ++i)))
+ throw 2;
+
+ break;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ case ',':
+ if (jsp && (pretty == 1 || pretty == 3)) {
+ if (comma)
+ *comma = true;
+
+ pty[0] = pty[2] = false;
+ break;
+ } // endif pretty
+
+ sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty);
+ throw 3;
+ case '(':
+ b = true;
+ break;
+ case ')':
+ if (b) {
+ b = false;
+ break;
+ } // endif b
+
+ default:
+ if (jsp)
+ jsp = jdp->ParseAsArray(g, i, pretty, ptyp);
+ else if (!(jsp = jdp->ParseValue(g, i)))
+ throw 4;
+
+ break;
+ }; // endswitch s[i]
+
+ if (!jsp)
+ sprintf(g->Message, "Invalid Json string '%.*s'", MY_MIN((int)len, 50), s);
+ else if (ptyp && pretty == 3) {
+ *ptyp = 3; // Not recognized pretty
+
+ for (i = 0; i < 3; i++)
+ if (pty[i]) {
+ *ptyp = i;
+ break;
+ } // endif pty
+
+ } // endif ptyp
+
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
+ jsp = NULL;
+ } catch (const char* msg) {
+ strcpy(g->Message, msg);
+ jsp = NULL;
+ } // end catch
+
+ return jsp;
} // end of ParseJson
/***********************************************************************/
+/* Serialize a JSON document tree: */
+/***********************************************************************/
+PSZ Serialize(PGLOBAL g, PJSON jsp, char* fn, int pretty) {
+ PSZ str = NULL;
+ bool b = false, err = true;
+ JOUT* jp;
+ FILE* fs = NULL;
+ PJDOC jdp = NULL;
+
+ g->Message[0] = 0;
+
+ try {
+ jdp = new(g) JDOC; // MUST BE ALLOCATED BEFORE jp !!!!!
+
+ if (!jsp) {
+ strcpy(g->Message, "Null json tree");
+ throw 1;
+ } else if (!fn) {
+ // Serialize to a string
+ jp = new(g) JOUTSTR(g);
+ b = pretty == 1;
+ } else {
+ if (!(fs = fopen(fn, "wb"))) {
+ sprintf(g->Message, MSG(OPEN_MODE_ERROR),
+ "w", (int)errno, fn);
+ strcat(strcat(g->Message, ": "), strerror(errno));
+ throw 2;
+ } else if (pretty >= 2) {
+ // Serialize to a pretty file
+ jp = new(g)JOUTPRT(g, fs);
+ } else {
+ // Serialize to a flat file
+ b = true;
+ jp = new(g)JOUTFILE(g, fs, pretty);
+ } // endif's
+
+ } // endif's
+
+ jdp->SetJp(jp);
+
+ switch (jsp->GetType()) {
+ case TYPE_JAR:
+ err = jdp->SerializeArray((PJAR)jsp, b);
+ break;
+ case TYPE_JOB:
+ err = ((b && jp->Prty()) && jp->WriteChr('\t'));
+ err |= jdp->SerializeObject((PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ err = jdp->SerializeValue((PJVAL)jsp);
+ break;
+ default:
+ strcpy(g->Message, "Invalid json tree");
+ } // endswitch Type
+
+ if (fs) {
+ fputs(EL, fs);
+ fclose(fs);
+ str = (err) ? NULL : strcpy(g->Message, "Ok");
+ } else if (!err) {
+ str = ((JOUTSTR*)jp)->Strp;
+ jp->WriteChr('\0');
+ PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N);
+ } else {
+ if (!g->Message[0])
+ strcpy(g->Message, "Error in Serialize");
+
+ } // endif's
+
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
+ str = NULL;
+ } catch (const char* msg) {
+ strcpy(g->Message, msg);
+ str = NULL;
+ } // end catch
+
+ return str;
+} // end of Serialize
+
+
+/* -------------------------- Class JOUTSTR -------------------------- */
+
+/***********************************************************************/
+/* JOUTSTR constructor. */
+/***********************************************************************/
+JOUTSTR::JOUTSTR(PGLOBAL g) : JOUT(g) {
+ PPOOLHEADER pph = (PPOOLHEADER)g->Sarea;
+
+ N = 0;
+ Max = pph->FreeBlk;
+ Max = (Max > 32) ? Max - 32 : Max;
+ Strp = (char*)PlugSubAlloc(g, NULL, 0); // Size not know yet
+} // end of JOUTSTR constructor
+
+/***********************************************************************/
+/* Concatenate a string to the Serialize string. */
+/***********************************************************************/
+bool JOUTSTR::WriteStr(const char* s) {
+ if (s) {
+ size_t len = strlen(s);
+
+ if (N + len > Max)
+ return true;
+
+ memcpy(Strp + N, s, len);
+ N += len;
+ return false;
+ } else
+ return true;
+
+} // end of WriteStr
+
+/***********************************************************************/
+/* Concatenate a character to the Serialize string. */
+/***********************************************************************/
+bool JOUTSTR::WriteChr(const char c) {
+ if (N + 1 > Max)
+ return true;
+
+ Strp[N++] = c;
+ return false;
+} // end of WriteChr
+
+/***********************************************************************/
+/* Escape and Concatenate a string to the Serialize string. */
+/***********************************************************************/
+bool JOUTSTR::Escape(const char* s)
+{
+ if (s) {
+ WriteChr('"');
+
+ for (unsigned int i = 0; s[i]; i++)
+ switch (s[i]) {
+ case '"':
+ case '\\':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\b':
+ case '\f': WriteChr('\\');
+ // fall through
+ default:
+ WriteChr(s[i]);
+ break;
+ } // endswitch s[i]
+
+ WriteChr('"');
+ } else
+ WriteStr("null");
+
+ return false;
+} // end of Escape
+
+/* ------------------------- Class JOUTFILE -------------------------- */
+
+/***********************************************************************/
+/* Write a string to the Serialize file. */
+/***********************************************************************/
+bool JOUTFILE::WriteStr(const char* s)
+{
+ // This is temporary
+ fputs(s, Stream);
+ return false;
+} // end of WriteStr
+
+/***********************************************************************/
+/* Write a character to the Serialize file. */
+/***********************************************************************/
+bool JOUTFILE::WriteChr(const char c)
+{
+ // This is temporary
+ fputc(c, Stream);
+ return false;
+} // end of WriteChr
+
+/***********************************************************************/
+/* Escape and Concatenate a string to the Serialize string. */
+/***********************************************************************/
+bool JOUTFILE::Escape(const char* s)
+{
+ // This is temporary
+ if (s) {
+ fputc('"', Stream);
+
+ for (unsigned int i = 0; s[i]; i++)
+ switch (s[i]) {
+ case '"': fputs("\\\"", Stream); break;
+ case '\\': fputs("\\\\", Stream); break;
+ case '\t': fputs("\\t", Stream); break;
+ case '\n': fputs("\\n", Stream); break;
+ case '\r': fputs("\\r", Stream); break;
+ case '\b': fputs("\\b", Stream); break;
+ case '\f': fputs("\\f", Stream); break;
+ default:
+ fputc(s[i], Stream);
+ break;
+ } // endswitch s[i]
+
+ fputc('"', Stream);
+ } else
+ fputs("null", Stream);
+
+ return false;
+} // end of Escape
+
+/* ------------------------- Class JOUTPRT --------------------------- */
+
+/***********************************************************************/
+/* Write a string to the Serialize pretty file. */
+/***********************************************************************/
+bool JOUTPRT::WriteStr(const char* s)
+{
+ // This is temporary
+ if (B) {
+ fputs(EL, Stream);
+ M--;
+
+ for (int i = 0; i < M; i++)
+ fputc('\t', Stream);
+
+ B = false;
+ } // endif B
+
+ fputs(s, Stream);
+ return false;
+} // end of WriteStr
+
+/***********************************************************************/
+/* Write a character to the Serialize pretty file. */
+/***********************************************************************/
+bool JOUTPRT::WriteChr(const char c)
+{
+ switch (c) {
+ case ':':
+ fputs(": ", Stream);
+ break;
+ case '{':
+ case '[':
+#if 0
+ if (M)
+ fputs(EL, Stream);
+
+ for (int i = 0; i < M; i++)
+ fputc('\t', Stream);
+#endif // 0
+
+ fputc(c, Stream);
+ fputs(EL, Stream);
+ M++;
+
+ for (int i = 0; i < M; i++)
+ fputc('\t', Stream);
+
+ break;
+ case '}':
+ case ']':
+ M--;
+ fputs(EL, Stream);
+
+ for (int i = 0; i < M; i++)
+ fputc('\t', Stream);
+
+ fputc(c, Stream);
+ B = true;
+ break;
+ case ',':
+ fputc(c, Stream);
+ fputs(EL, Stream);
+
+ for (int i = 0; i < M; i++)
+ fputc('\t', Stream);
+
+ B = false;
+ break;
+ default:
+ fputc(c, Stream);
+ } // endswitch c
+
+ return false;
+} // end of WriteChr
+
+/* --------------------------- Class JDOC ---------------------------- */
+
+/***********************************************************************/
/* Parse several items as being in an array. */
/***********************************************************************/
-PJAR JSON::ParseAsArray(PGLOBAL g, int& i, int pretty, int *ptyp)
+PJAR JDOC::ParseAsArray(PGLOBAL g, int& i, int pretty, int *ptyp)
{
- if (pty[0] && (!pretty || pretty > 2)) {
- PJAR jsp;
+ if (pty[0] && (!pretty || pretty > 2)) {
+ PJAR jsp;
- if ((jsp = ParseArray(g, (i = 0))) && ptyp && pretty == 3)
- *ptyp = (pty[0]) ? 0 : 3;
+ if ((jsp = ParseArray(g, (i = 0))) && ptyp && pretty == 3)
+ *ptyp = (pty[0]) ? 0 : 3;
- return jsp;
- } else
- strcpy(g->Message, "More than one item in file");
+ return jsp;
+ } else
+ strcpy(g->Message, "More than one item in file");
- return NULL;
+ return NULL;
} // end of ParseAsArray
/***********************************************************************/
/* Parse a JSON Array. */
/***********************************************************************/
-PJAR JSON::ParseArray(PGLOBAL g, int& i)
+PJAR JDOC::ParseArray(PGLOBAL g, int& i)
{
- int level = 0;
- bool b = (!i);
+ int level = 0;
+ bool b = (!i);
PJAR jarp = new(g) JARRAY;
for (; i < len; i++)
@@ -235,11 +535,11 @@ PJAR JSON::ParseArray(PGLOBAL g, int& i)
jarp->InitArray(g);
return jarp;
- case '\n':
- if (!b)
- pty[0] = pty[1] = false;
- case '\r':
- case ' ':
+ case '\n':
+ if (!b)
+ pty[0] = pty[1] = false;
+ case '\r':
+ case ' ':
case '\t':
break;
default:
@@ -247,17 +547,17 @@ PJAR JSON::ParseArray(PGLOBAL g, int& i)
sprintf(g->Message, "Unexpected value near %.*s", ARGS);
throw 1;
} else
- jarp->AddValue(g, ParseValue(g, i));
+ jarp->AddArrayValue(g, ParseValue(g, i));
level = (b) ? 1 : 2;
break;
}; // endswitch s[i]
- if (b) {
- // Case of Pretty == 0
- jarp->InitArray(g);
- return jarp;
- } // endif b
+ if (b) {
+ // Case of Pretty == 0
+ jarp->InitArray(g);
+ return jarp;
+ } // endif b
throw ("Unexpected EOF in array");
} // end of ParseArray
@@ -265,10 +565,10 @@ PJAR JSON::ParseArray(PGLOBAL g, int& i)
/***********************************************************************/
/* Parse a JSON Object. */
/***********************************************************************/
-PJOB JSON::ParseObject(PGLOBAL g, int& i)
+PJOB JDOC::ParseObject(PGLOBAL g, int& i)
{
PSZ key;
- int level = 0;
+ int level = -1;
PJOB jobp = new(g) JOBJECT;
PJPR jpp = NULL;
@@ -276,7 +576,7 @@ PJOB JSON::ParseObject(PGLOBAL g, int& i)
switch (s[i]) {
case '"':
if (level < 2) {
- key = ParseString(g, ++i);
+ key = ParseString(g, ++i);
jpp = jobp->AddPair(g, key);
level = 1;
} else {
@@ -287,7 +587,7 @@ PJOB JSON::ParseObject(PGLOBAL g, int& i)
break;
case ':':
if (level == 1) {
- jpp->Val = ParseValue(g, ++i);
+ jpp->Val = ParseValue(g, ++i);
level = 2;
} else {
sprintf(g->Message, "Unexpected ':' near %.*s", ARGS);
@@ -304,16 +604,16 @@ PJOB JSON::ParseObject(PGLOBAL g, int& i)
break;
case '}':
- if (level < 2) {
+ if (level == 0 || level == 1) {
sprintf(g->Message, "Unexpected '}' near %.*s", ARGS);
throw 2;
} // endif level
return jobp;
- case '\n':
- pty[0] = pty[1] = false;
- case '\r':
- case ' ':
+ case '\n':
+ pty[0] = pty[1] = false;
+ case '\r':
+ case ' ':
case '\t':
break;
default:
@@ -329,38 +629,42 @@ PJOB JSON::ParseObject(PGLOBAL g, int& i)
/***********************************************************************/
/* Parse a JSON Value. */
/***********************************************************************/
-PJVAL JSON::ParseValue(PGLOBAL g, int& i)
+PJVAL JDOC::ParseValue(PGLOBAL g, int& i)
{
- int n;
PJVAL jvp = new(g) JVALUE;
for (; i < len; i++)
- switch (s[i]) {
- case '\n':
- pty[0] = pty[1] = false;
- case '\r':
- case ' ':
- case '\t':
- break;
- default:
- goto suite;
- } // endswitch
+ switch (s[i]) {
+ case '\n':
+ pty[0] = pty[1] = false;
+ case '\r':
+ case ' ':
+ case '\t':
+ break;
+ default:
+ goto suite;
+ } // endswitch
suite:
switch (s[i]) {
case '[':
- jvp->Jsp = ParseArray(g, ++i);
+ jvp->Jsp = ParseArray(g, ++i);
+ jvp->DataType = TYPE_JSON;
break;
case '{':
- jvp->Jsp = ParseObject(g, ++i);
+ jvp->Jsp = ParseObject(g, ++i);
+ jvp->DataType = TYPE_JSON;
break;
case '"':
- jvp->Value = AllocateValue(g, ParseString(g, ++i), TYPE_STRING);
+// jvp->Val = AllocVal(g, TYPE_STRG);
+ jvp->Strp = ParseString(g, ++i);
+ jvp->DataType = TYPE_STRG;
break;
case 't':
if (!strncmp(s + i, "true", 4)) {
- n = 1;
- jvp->Value = AllocateValue(g, &n, TYPE_TINY);
+// jvp->Val = AllocVal(g, TYPE_BOOL);
+ jvp->B = true;
+ jvp->DataType = TYPE_BOOL;
i += 3;
} else
goto err;
@@ -368,24 +672,26 @@ PJVAL JSON::ParseValue(PGLOBAL g, int& i)
break;
case 'f':
if (!strncmp(s + i, "false", 5)) {
- n = 0;
- jvp->Value = AllocateValue(g, &n, TYPE_TINY);
+// jvp->Val = AllocVal(g, TYPE_BOOL);
+ jvp->B = false;
+ jvp->DataType = TYPE_BOOL;
i += 4;
} else
goto err;
break;
case 'n':
- if (!strncmp(s + i, "null", 4))
+ if (!strncmp(s + i, "null", 4)) {
+ jvp->DataType = TYPE_NULL;
i += 3;
- else
+ } else
goto err;
break;
case '-':
default:
if (s[i] == '-' || isdigit(s[i]))
- jvp->Value = ParseNumeric(g, i);
+ ParseNumeric(g, i, jvp);
else
goto err;
@@ -401,7 +707,7 @@ err:
/***********************************************************************/
/* Unescape and parse a JSON string. */
/***********************************************************************/
-char *JSON::ParseString(PGLOBAL g, int& i)
+char *JDOC::ParseString(PGLOBAL g, int& i)
{
uchar *p;
int n = 0;
@@ -488,15 +794,15 @@ char *JSON::ParseString(PGLOBAL g, int& i)
/***********************************************************************/
/* Parse a JSON numeric value. */
/***********************************************************************/
-PVAL JSON::ParseNumeric(PGLOBAL g, int& i)
+void JDOC::ParseNumeric(PGLOBAL g, int& i, PJVAL vlp)
{
char buf[50];
int n = 0;
short nd = 0;
- bool has_dot = false;
- bool has_e = false;
- bool found_digit = false;
- PVAL valp = NULL;
+ bool has_dot = false;
+ bool has_e = false;
+ bool found_digit = false;
+//PVL vlp = NULL;
for (; i < len; i++) {
switch (s[i]) {
@@ -545,15 +851,27 @@ PVAL JSON::ParseNumeric(PGLOBAL g, int& i)
if (has_dot || has_e) {
double dv = strtod(buf, NULL);
- valp = AllocateValue(g, &dv, TYPE_DOUBLE, nd);
+// vlp = AllocVal(g, TYPE_DBL);
+ vlp->F = dv;
+ vlp->Nd = nd;
+ vlp->DataType = TYPE_DBL;
} else {
long long iv = strtoll(buf, NULL, 10);
- valp = AllocateValue(g, &iv, TYPE_BIGINT);
+ if (iv > INT_MAX32 || iv < INT_MIN32) {
+// vlp = AllocVal(g, TYPE_BINT);
+ vlp->LLn = iv;
+ vlp->DataType = TYPE_BINT;
+ } else {
+// vlp = AllocVal(g, TYPE_INTG);
+ vlp->N = (int)iv;
+ vlp->DataType = TYPE_INTG;
+ } // endif iv
+
} // endif has
i--; // Unstack following character
- return valp;
+ return;
} else
throw("No digit found");
@@ -562,137 +880,59 @@ PVAL JSON::ParseNumeric(PGLOBAL g, int& i)
} // end of ParseNumeric
/***********************************************************************/
-/* Serialize a JSON tree: */
-/***********************************************************************/
-PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty)
-{
- PSZ str = NULL;
- bool b = false, err = true;
- JOUT *jp;
- FILE *fs = NULL;
-
- g->Message[0] = 0;
-
- try {
- if (!jsp) {
- strcpy(g->Message, "Null json tree");
- throw 1;
- } else if (!fn) {
- // Serialize to a string
- jp = new(g) JOUTSTR(g);
- b = pretty == 1;
- } else {
- if (!(fs = fopen(fn, "wb"))) {
- sprintf(g->Message, MSG(OPEN_MODE_ERROR),
- "w", (int)errno, fn);
- strcat(strcat(g->Message, ": "), strerror(errno));
- throw 2;
- } else if (pretty >= 2) {
- // Serialize to a pretty file
- jp = new(g)JOUTPRT(g, fs);
- } else {
- // Serialize to a flat file
- b = true;
- jp = new(g)JOUTFILE(g, fs, pretty);
- } // endif's
-
- } // endif's
-
- switch (jsp->GetType()) {
- case TYPE_JAR:
- err = SerializeArray(jp, (PJAR)jsp, b);
- break;
- case TYPE_JOB:
- err = ((b && jp->Prty()) && jp->WriteChr('\t'));
- err |= SerializeObject(jp, (PJOB)jsp);
- break;
- case TYPE_JVAL:
- err = SerializeValue(jp, (PJVAL)jsp);
- break;
- default:
- strcpy(g->Message, "Invalid json tree");
- } // endswitch Type
-
- if (fs) {
- fputs(EL, fs);
- fclose(fs);
- str = (err) ? NULL : strcpy(g->Message, "Ok");
- } else if (!err) {
- str = ((JOUTSTR*)jp)->Strp;
- jp->WriteChr('\0');
- PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N);
- } else {
- if (!g->Message[0])
- strcpy(g->Message, "Error in Serialize");
-
- } // endif's
-
- } catch (int n) {
- if (trace(1))
- htrc("Exception %d: %s\n", n, g->Message);
- str = NULL;
- } catch (const char *msg) {
- strcpy(g->Message, msg);
- str = NULL;
- } // end catch
-
- return str;
-} // end of Serialize
-
-/***********************************************************************/
/* Serialize a JSON Array. */
/***********************************************************************/
-bool SerializeArray(JOUT *js, PJAR jarp, bool b)
+bool JDOC::SerializeArray(PJAR jarp, bool b)
{
bool first = true;
- if (b) {
- if (js->Prty()) {
- if (js->WriteChr('['))
- return true;
- else if (js->Prty() == 1 && (js->WriteStr(EL) || js->WriteChr('\t')))
- return true;
+ if (b) {
+ if (js->Prty()) {
+ if (js->WriteChr('['))
+ return true;
+ else if (js->Prty() == 1 && (js->WriteStr(EL) || js->WriteChr('\t')))
+ return true;
- } // endif Prty
+ } // endif Prty
- } else if (js->WriteChr('['))
- return true;
+ } else if (js->WriteChr('['))
+ return true;
for (int i = 0; i < jarp->size(); i++) {
if (first)
first = false;
- else if ((!b || js->Prty()) && js->WriteChr(','))
+ else if ((!b || js->Prty()) && js->WriteChr(','))
return true;
- else if (b) {
- if (js->Prty() < 2 && js->WriteStr(EL))
- return true;
- else if (js->Prty() == 1 && js->WriteChr('\t'))
- return true;
+ else if (b) {
+ if (js->Prty() < 2 && js->WriteStr(EL))
+ return true;
+ else if (js->Prty() == 1 && js->WriteChr('\t'))
+ return true;
- } // endif b
+ } // endif b
- if (SerializeValue(js, jarp->GetValue(i)))
+ if (SerializeValue(jarp->GetArrayValue(i)))
return true;
} // endfor i
- if (b && js->Prty() == 1 && js->WriteStr(EL))
+ if (b && js->Prty() == 1 && js->WriteStr(EL))
return true;
- return ((!b || js->Prty()) && js->WriteChr(']'));
+ return ((!b || js->Prty()) && js->WriteChr(']'));
} // end of SerializeArray
/***********************************************************************/
/* Serialize a JSON Object. */
/***********************************************************************/
-bool SerializeObject(JOUT *js, PJOB jobp)
+bool JDOC::SerializeObject(PJOB jobp)
{
bool first = true;
if (js->WriteChr('{'))
return true;
- for (PJPR pair = jobp->First; pair; pair = pair->Next) {
+ for (PJPR pair = jobp->GetFirst(); pair; pair = pair->Next) {
if (first)
first = false;
else if (js->WriteChr(','))
@@ -702,7 +942,7 @@ bool SerializeObject(JOUT *js, PJOB jobp)
js->WriteStr(pair->Key) ||
js->WriteChr('"') ||
js->WriteChr(':') ||
- SerializeValue(js, pair->Val))
+ SerializeValue(pair->Val))
return true;
} // endfor i
@@ -713,259 +953,70 @@ bool SerializeObject(JOUT *js, PJOB jobp)
/***********************************************************************/
/* Serialize a JSON Value. */
/***********************************************************************/
-bool SerializeValue(JOUT *js, PJVAL jvp)
+bool JDOC::SerializeValue(PJVAL jvp)
{
+ char buf[64];
PJAR jap;
PJOB jop;
- PVAL valp;
+ //PVL vlp;
if ((jap = jvp->GetArray()))
- return SerializeArray(js, jap, false);
+ return SerializeArray(jap, false);
else if ((jop = jvp->GetObject()))
- return SerializeObject(js, jop);
- else if (!(valp = jvp->Value) || valp->IsNull())
- return js->WriteStr("null");
- else switch (valp->GetType()) {
- case TYPE_TINY:
- return js->WriteStr(valp->GetTinyValue() ? "true" : "false");
- case TYPE_STRING:
- return js->Escape(valp->GetCharValue());
+ return SerializeObject(jop);
+//else if (!(vlp = jvp->Val))
+// return js->WriteStr("null");
+ else switch (jvp->DataType) {
+ case TYPE_BOOL:
+ return js->WriteStr(jvp->B ? "true" : "false");
+ case TYPE_STRG:
+ case TYPE_DTM:
+ return js->Escape(jvp->Strp);
+ case TYPE_INTG:
+ sprintf(buf, "%d", jvp->N);
+ return js->WriteStr(buf);
+ case TYPE_BINT:
+ sprintf(buf, "%lld", jvp->LLn);
+ return js->WriteStr(buf);
+ case TYPE_DBL:
+ sprintf(buf, "%.*lf", jvp->Nd, jvp->F);
+ return js->WriteStr(buf);
+ case TYPE_NULL:
+ return js->WriteStr("null");
default:
- if (valp->IsTypeNum()) {
- char buf[32];
-
- return js->WriteStr(valp->GetCharString(buf));
- } // endif valp
-
- } // endswitch Type
+ return js->WriteStr("???"); // TODO
+ } // endswitch Type
- strcpy(js->g->Message, "Unrecognized value");
- return true;
+ strcpy(js->g->Message, "Unrecognized value");
+ return true;
} // end of SerializeValue
-/* -------------------------- Class JOUTSTR -------------------------- */
-
-/***********************************************************************/
-/* JOUTSTR constructor. */
-/***********************************************************************/
-JOUTSTR::JOUTSTR(PGLOBAL g) : JOUT(g)
-{
- PPOOLHEADER pph = (PPOOLHEADER)g->Sarea;
-
- N = 0;
- Max = pph->FreeBlk;
- Max = (Max > 32) ? Max - 32 : Max;
- Strp = (char*)PlugSubAlloc(g, NULL, 0); // Size not know yet
-} // end of JOUTSTR constructor
-
-/***********************************************************************/
-/* Concatenate a string to the Serialize string. */
-/***********************************************************************/
-bool JOUTSTR::WriteStr(const char *s)
-{
- if (s) {
- size_t len = strlen(s);
-
- if (N + len > Max)
- return true;
-
- memcpy(Strp + N, s, len);
- N += len;
- return false;
- } else
- return true;
-
-} // end of WriteStr
-
-/***********************************************************************/
-/* Concatenate a character to the Serialize string. */
-/***********************************************************************/
-bool JOUTSTR::WriteChr(const char c)
-{
- if (N + 1 > Max)
- return true;
-
- Strp[N++] = c;
- return false;
-} // end of WriteChr
-
-/***********************************************************************/
-/* Escape and Concatenate a string to the Serialize string. */
-/***********************************************************************/
-bool JOUTSTR::Escape(const char *s)
-{
- WriteChr('"');
-
- for (unsigned int i = 0; s[i]; i++)
- switch (s[i]) {
- case '"':
- case '\\':
- case '\t':
- case '\n':
- case '\r':
- case '\b':
- case '\f': WriteChr('\\');
- // fall through
- default:
- WriteChr(s[i]);
- break;
- } // endswitch s[i]
-
- WriteChr('"');
- return false;
-} // end of Escape
-
-/* ------------------------- Class JOUTFILE -------------------------- */
-
-/***********************************************************************/
-/* Write a string to the Serialize file. */
-/***********************************************************************/
-bool JOUTFILE::WriteStr(const char *s)
-{
- // This is temporary
- fputs(s, Stream);
- return false;
-} // end of WriteStr
-
-/***********************************************************************/
-/* Write a character to the Serialize file. */
-/***********************************************************************/
-bool JOUTFILE::WriteChr(const char c)
-{
- // This is temporary
- fputc(c, Stream);
- return false;
-} // end of WriteChr
-
-/***********************************************************************/
-/* Escape and Concatenate a string to the Serialize string. */
-/***********************************************************************/
-bool JOUTFILE::Escape(const char *s)
-{
- // This is temporary
- fputc('"', Stream);
-
- for (unsigned int i = 0; s[i]; i++)
- switch (s[i]) {
- case '"': fputs("\\\"", Stream); break;
- case '\\': fputs("\\\\", Stream); break;
- case '\t': fputs("\\t", Stream); break;
- case '\n': fputs("\\n", Stream); break;
- case '\r': fputs("\\r", Stream); break;
- case '\b': fputs("\\b", Stream); break;
- case '\f': fputs("\\f", Stream); break;
- default:
- fputc(s[i], Stream);
- break;
- } // endswitch s[i]
-
- fputc('"', Stream);
- return false;
-} // end of Escape
-
-/* ------------------------- Class JOUTPRT --------------------------- */
-
-/***********************************************************************/
-/* Write a string to the Serialize pretty file. */
-/***********************************************************************/
-bool JOUTPRT::WriteStr(const char *s)
-{
- // This is temporary
- if (B) {
- fputs(EL, Stream);
- M--;
-
- for (int i = 0; i < M; i++)
- fputc('\t', Stream);
-
- B = false;
- } // endif B
-
- fputs(s, Stream);
- return false;
-} // end of WriteStr
-
-/***********************************************************************/
-/* Write a character to the Serialize pretty file. */
-/***********************************************************************/
-bool JOUTPRT::WriteChr(const char c)
-{
- switch (c) {
- case ':':
- fputs(": ", Stream);
- break;
- case '{':
- case '[':
-#if 0
- if (M)
- fputs(EL, Stream);
-
- for (int i = 0; i < M; i++)
- fputc('\t', Stream);
-#endif // 0
-
- fputc(c, Stream);
- fputs(EL, Stream);
- M++;
-
- for (int i = 0; i < M; i++)
- fputc('\t', Stream);
-
- break;
- case '}':
- case ']':
- M--;
- fputs(EL, Stream);
-
- for (int i = 0; i < M; i++)
- fputc('\t', Stream);
-
- fputc(c, Stream);
- B = true;
- break;
- case ',':
- fputc(c, Stream);
- fputs(EL, Stream);
-
- for (int i = 0; i < M; i++)
- fputc('\t', Stream);
-
- B = false;
- break;
- default:
- fputc(c, Stream);
- } // endswitch c
-
-return false;
-} // end of WriteChr
-
/* -------------------------- Class JOBJECT -------------------------- */
/***********************************************************************/
/* Return the number of pairs in this object. */
/***********************************************************************/
-int JOBJECT::GetSize(bool b)
-{
- if (b) {
- // Return only non null pairs
- int n = 0;
-
- for (PJPR jpp = First; jpp; jpp = jpp->Next)
- if (jpp->Val && !jpp->Val->IsNull())
- n++;
+int JOBJECT::GetSize(bool b) {
+ int n = 0;
- return n;
- } else
- return Size;
+ for (PJPR jpp = First; jpp; jpp = jpp->Next)
+ // If b return only non null pairs
+ if (!b || jpp->Val && !jpp->Val->IsNull())
+ n++;
-} // end of GetSize
+ return n;
+} // end of GetSize
/***********************************************************************/
/* Add a new pair to an Object. */
/***********************************************************************/
PJPR JOBJECT::AddPair(PGLOBAL g, PCSZ key)
{
- PJPR jpp = new(g) JPAIR(key);
+ PJPR jpp = (PJPR)PlugSubAlloc(g, NULL, sizeof(JPAIR));
+
+ jpp->Key = key;
+ jpp->Next = NULL;
+ jpp->Val = NULL;
if (Last)
Last->Next = jpp;
@@ -973,7 +1024,6 @@ PJPR JOBJECT::AddPair(PGLOBAL g, PCSZ key)
First = jpp;
Last = jpp;
- Size++;
return jpp;
} // end of AddPair
@@ -982,13 +1032,13 @@ PJPR JOBJECT::AddPair(PGLOBAL g, PCSZ key)
/***********************************************************************/
PJAR JOBJECT::GetKeyList(PGLOBAL g)
{
- PJAR jarp = new(g) JARRAY();
+ PJAR jarp = new(g) JARRAY();
- for (PJPR jpp = First; jpp; jpp = jpp->Next)
- jarp->AddValue(g, new(g) JVALUE(g, jpp->GetKey()));
+ for (PJPR jpp = First; jpp; jpp = jpp->Next)
+ jarp->AddArrayValue(g, new(g) JVALUE(g, jpp->Key));
- jarp->InitArray(g);
- return jarp;
+ jarp->InitArray(g);
+ return jarp;
} // end of GetKeyList
/***********************************************************************/
@@ -996,19 +1046,19 @@ PJAR JOBJECT::GetKeyList(PGLOBAL g)
/***********************************************************************/
PJAR JOBJECT::GetValList(PGLOBAL g)
{
- PJAR jarp = new(g) JARRAY();
+ PJAR jarp = new(g) JARRAY();
- for (PJPR jpp = First; jpp; jpp = jpp->Next)
- jarp->AddValue(g, jpp->GetVal());
+ for (PJPR jpp = First; jpp; jpp = jpp->Next)
+ jarp->AddArrayValue(g, jpp->Val);
- jarp->InitArray(g);
- return jarp;
+ jarp->InitArray(g);
+ return jarp;
} // end of GetValList
/***********************************************************************/
/* Get the value corresponding to the given key. */
/***********************************************************************/
-PJVAL JOBJECT::GetValue(const char* key)
+PJVAL JOBJECT::GetKeyValue(const char* key)
{
for (PJPR jp = First; jp; jp = jp->Next)
if (!strcmp(jp->Key, key))
@@ -1020,43 +1070,57 @@ PJVAL JOBJECT::GetValue(const char* key)
/***********************************************************************/
/* Return the text corresponding to all keys (XML like). */
/***********************************************************************/
-PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
+PSZ JOBJECT::GetText(PGLOBAL g, PSTRG text)
{
- int n;
+ if (First) {
+ bool b;
- if (!text) {
- text = (char*)PlugSubAlloc(g, NULL, 0);
- text[0] = 0;
- n = 1;
- } else
- n = 0;
+ if (!text) {
+ text = new(g) STRING(g, 256);
+ b = true;
+ } else {
+ if (text->GetLastChar() != ' ')
+ text->Append(' ');
- if (!First && n)
- return NULL;
- else if (n == 1 && Size == 1 && !strcmp(First->GetKey(), "$date")) {
- int i;
+ b = false;
+ } // endif text
- First->Val->GetText(g, text);
- i = (text[1] == '-' ? 2 : 1);
+ if (b && !First->Next && !strcmp(First->Key, "$date")) {
+ int i;
+ PSZ s;
- if (IsNum(text + i)) {
- // Date is in milliseconds
- int j = (int)strlen(text);
+ First->Val->GetText(g, text);
+ s = text->GetStr();
+ i = (s[1] == '-' ? 2 : 1);
- if (j >= 4 + i)
- text[j - 3] = 0; // Change it to seconds
- else
- strcpy(text, " 0");
+ if (IsNum(s + i)) {
+ // Date is in milliseconds
+ int j = text->GetLength();
- } // endif text
+ if (j >= 4 + i) {
+ s[j - 3] = 0; // Change it to seconds
+ text->SetLength((uint)strlen(s));
+ } else
+ text->Set(" 0");
+
+ } // endif text
+
+ } else for (PJPR jp = First; jp; jp = jp->Next) {
+ jp->Val->GetText(g, text);
- } else for (PJPR jp = First; jp; jp = jp->Next)
- jp->Val->GetText(g, text);
+ if (jp->Next)
+ text->Append(' ');
- if (n)
- PlugSubAlloc(g, NULL, strlen(text) + 1);
+ } // endfor jp
- return text + n;
+ if (b) {
+ text->Trim();
+ return text->GetStr();
+ } // endif b
+
+ } // endif First
+
+ return NULL;
} // end of GetText;
/***********************************************************************/
@@ -1064,25 +1128,25 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
/***********************************************************************/
bool JOBJECT::Merge(PGLOBAL g, PJSON jsp)
{
- if (jsp->GetType() != TYPE_JOB) {
- strcpy(g->Message, "Second argument is not an object");
- return true;
- } // endif Type
+ if (jsp->GetType() != TYPE_JOB) {
+ strcpy(g->Message, "Second argument is not an object");
+ return true;
+ } // endif Type
- PJOB jobp = (PJOB)jsp;
+ PJOB jobp = (PJOB)jsp;
- for (PJPR jpp = jobp->First; jpp; jpp = jpp->Next)
- SetValue(g, jpp->GetVal(), jpp->GetKey());
+ for (PJPR jpp = jobp->First; jpp; jpp = jpp->Next)
+ SetKeyValue(g, jpp->Val, jpp->Key);
- return false;
+ return false;
} // end of Marge;
/***********************************************************************/
/* Set or add a value corresponding to the given key. */
/***********************************************************************/
-void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PCSZ key)
+void JOBJECT::SetKeyValue(PGLOBAL g, PJVAL jvp, PCSZ key)
{
- PJPR jp;
+ PJPR jp;
for (jp = First; jp; jp = jp->Next)
if (!strcmp(jp->Key, key)) {
@@ -1102,15 +1166,14 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PCSZ key)
/***********************************************************************/
void JOBJECT::DeleteKey(PCSZ key)
{
- PJPR jp, *pjp = &First;
+ PJPR jp, *pjp = &First;
- for (jp = First; jp; jp = jp->Next)
- if (!strcmp(jp->Key, key)) {
- *pjp = jp->Next;
- Size--;
- break;
- } else
- pjp = &jp->Next;
+ for (jp = First; jp; jp = jp->Next)
+ if (!strcmp(jp->Key, key)) {
+ *pjp = jp->Next;
+ break;
+ } else
+ pjp = &jp->Next;
} // end of DeleteKey
@@ -1129,23 +1192,35 @@ bool JOBJECT::IsNull(void)
/* -------------------------- Class JARRAY --------------------------- */
/***********************************************************************/
+/* JARRAY constructor. */
+/***********************************************************************/
+JARRAY::JARRAY(void) : JSON()
+{
+ Type = TYPE_JAR;
+ Size = 0;
+ Alloc = 0;
+ First = Last = NULL;
+ Mvals = NULL;
+} // end of JARRAY constructor
+
+/***********************************************************************/
/* Return the number of values in this object. */
/***********************************************************************/
int JARRAY::GetSize(bool b)
{
- if (b) {
- // Return only non null values
- int n = 0;
+ if (b) {
+ // Return only non null values
+ int n = 0;
- for (PJVAL jvp = First; jvp; jvp = jvp->Next)
- if (!jvp->IsNull())
- n++;
+ for (PJVAL jvp = First; jvp; jvp = jvp->Next)
+ if (!jvp->IsNull())
+ n++;
- return n;
- } else
- return Size;
+ return n;
+ } else
+ return Size;
-} // end of GetSize
+} // end of GetSize
/***********************************************************************/
/* Make the array of values from the values list. */
@@ -1166,19 +1241,19 @@ void JARRAY::InitArray(PGLOBAL g)
} // endif Size
for (i = 0, jvp = First; jvp; jvp = jvp->Next)
- if (!jvp->Del) {
- Mvals[i++] = jvp;
- pjvp = &jvp->Next;
- Last = jvp;
- } else
- *pjvp = jvp->Next;
+ if (!jvp->Del) {
+ Mvals[i++] = jvp;
+ pjvp = &jvp->Next;
+ Last = jvp;
+ } else
+ *pjvp = jvp->Next;
} // end of InitArray
/***********************************************************************/
/* Get the Nth value of an Array. */
/***********************************************************************/
-PJVAL JARRAY::GetValue(int i)
+PJVAL JARRAY::GetArrayValue(int i)
{
if (Mvals && i >= 0 && i < Size)
return Mvals[i];
@@ -1189,33 +1264,33 @@ PJVAL JARRAY::GetValue(int i)
/***********************************************************************/
/* Add a Value to the Array Value list. */
/***********************************************************************/
-PJVAL JARRAY::AddValue(PGLOBAL g, PJVAL jvp, int *x)
+PJVAL JARRAY::AddArrayValue(PGLOBAL g, PJVAL jvp, int *x)
{
if (!jvp)
jvp = new(g) JVALUE;
- if (x) {
- int i = 0, n = *x;
- PJVAL jp, *jpp = &First;
+ if (x) {
+ int i = 0, n = *x;
+ PJVAL jp, *jpp = &First;
- for (jp = First; jp && i < n; i++, jp = *(jpp = &jp->Next));
+ for (jp = First; jp && i < n; i++, jp = *(jpp = &jp->Next));
- (*jpp) = jvp;
+ (*jpp) = jvp;
- if (!(jvp->Next = jp))
- Last = jvp;
+ if (!(jvp->Next = jp))
+ Last = jvp;
- } else {
- if (!First)
- First = jvp;
- else if (Last == First)
- First->Next = Last = jvp;
- else
- Last->Next = jvp;
+ } else {
+ if (!First)
+ First = jvp;
+ else if (Last == First)
+ First->Next = Last = jvp;
+ else
+ Last->Next = jvp;
- Last = jvp;
- Last->Next = NULL;
- } // endif x
+ Last = jvp;
+ Last->Next = NULL;
+ } // endif x
return jvp;
} // end of AddValue
@@ -1225,24 +1300,24 @@ PJVAL JARRAY::AddValue(PGLOBAL g, PJVAL jvp, int *x)
/***********************************************************************/
bool JARRAY::Merge(PGLOBAL g, PJSON jsp)
{
- if (jsp->GetType() != TYPE_JAR) {
- strcpy(g->Message, "Second argument is not an array");
- return true;
- } // endif Type
+ if (jsp->GetType() != TYPE_JAR) {
+ strcpy(g->Message, "Second argument is not an array");
+ return true;
+ } // endif Type
- PJAR arp = (PJAR)jsp;
+ PJAR arp = (PJAR)jsp;
- for (int i = 0; i < jsp->size(); i++)
- AddValue(g, arp->GetValue(i));
+ for (int i = 0; i < arp->size(); i++)
+ AddArrayValue(g, arp->GetArrayValue(i));
- InitArray(g);
- return false;
+ InitArray(g);
+ return false;
} // end of Merge
/***********************************************************************/
/* Set the nth Value of the Array Value list. */
/***********************************************************************/
-bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n)
+bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n)
{
int i = 0;
PJVAL jp, *jpp = &First;
@@ -1259,25 +1334,42 @@ bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n)
/***********************************************************************/
/* Return the text corresponding to all values. */
/***********************************************************************/
-PSZ JARRAY::GetText(PGLOBAL g, PSZ text)
+PSZ JARRAY::GetText(PGLOBAL g, PSTRG text)
{
- int n;
- PJVAL jp;
+ if (First) {
+ bool b;
+ PJVAL jp;
+
+ if (!text) {
+ text = new(g) STRING(g, 256);
+ b = true;
+ } else {
+ if (text->GetLastChar() != ' ')
+ text->Append(" (");
+ else
+ text->Append('(');
+
+ b = false;
+ }
+
+ for (jp = First; jp; jp = jp->Next) {
+ jp->GetText(g, text);
- if (!text) {
- text = (char*)PlugSubAlloc(g, NULL, 0);
- text[0] = 0;
- n = 1;
- } else
- n = 0;
+ if (jp->Next)
+ text->Append(", ");
+ else if (!b)
+ text->Append(')');
- for (jp = First; jp; jp = jp->Next)
- jp->GetText(g, text);
+ } // endfor jp
- if (n)
- PlugSubAlloc(g, NULL, strlen(text) + 1);
+ if (b) {
+ text->Trim();
+ return text->GetStr();
+ } // endif b
- return text + n;
+ } // endif First
+
+ return NULL;
} // end of GetText;
/***********************************************************************/
@@ -1285,13 +1377,13 @@ PSZ JARRAY::GetText(PGLOBAL g, PSZ text)
/***********************************************************************/
bool JARRAY::DeleteValue(int n)
{
- PJVAL jvp = GetValue(n);
+ PJVAL jvp = GetArrayValue(n);
- if (jvp) {
- jvp->Del = true;
- return false;
- } else
- return true;
+ if (jvp) {
+ jvp->Del = true;
+ return false;
+ } else
+ return true;
} // end of DeleteValue
@@ -1310,32 +1402,60 @@ bool JARRAY::IsNull(void)
/* -------------------------- Class JVALUE- -------------------------- */
/***********************************************************************/
-/* Constructor for a JSON. */
+/* Constructor for a JVALUE. */
/***********************************************************************/
JVALUE::JVALUE(PJSON jsp) : JSON()
{
- if (jsp->GetType() == TYPE_JVAL) {
- Jsp = jsp->GetJsp();
- Value = jsp->GetValue();
- } else {
- Jsp = jsp;
- Value = NULL;
- } // endif Type
+ if (jsp->GetType() == TYPE_JVAL) {
+ PJVAL jvp = (PJVAL)jsp;
+
+// Val = ((PJVAL)jsp)->GetVal();
+ if (jvp->DataType == TYPE_JSON) {
+ Jsp = jvp->GetJsp();
+ DataType = TYPE_JSON;
+ Nd = 0;
+ } else {
+ LLn = jvp->LLn; // Must be LLn on 32 bit machines
+ Nd = jvp->Nd;
+ DataType = jvp->DataType;
+ } // endelse Jsp
+
+ } else {
+ Jsp = jsp;
+// Val = NULL;
+ DataType = TYPE_JSON;
+ Nd = 0;
+ } // endif Type
- Next = NULL;
- Del = false;
- Size = 1;
-} // end of JVALUE constructor
+ Next = NULL;
+ Del = false;
+ Type = TYPE_JVAL;
+} // end of JVALUE constructor
+#if 0
/***********************************************************************/
-/* Constructor for a Value with a given string or numeric value. */
+/* Constructor for a JVALUE with a given string or numeric value. */
/***********************************************************************/
-JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON()
+JVALUE::JVALUE(PGLOBAL g, PVL vlp) : JSON()
{
Jsp = NULL;
- Value = AllocateValue(g, valp);
+ Val = vlp;
Next = NULL;
Del = false;
+ Type = TYPE_JVAL;
+} // end of JVALUE constructor
+#endif // 0
+
+/***********************************************************************/
+/* Constructor for a JVALUE with a given string or numeric value. */
+/***********************************************************************/
+JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON() {
+ Jsp = NULL;
+//Val = NULL;
+ SetValue(g, valp);
+ Next = NULL;
+ Del = false;
+ Type = TYPE_JVAL;
} // end of JVALUE constructor
/***********************************************************************/
@@ -1343,23 +1463,40 @@ JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON()
/***********************************************************************/
JVALUE::JVALUE(PGLOBAL g, PCSZ strp) : JSON()
{
- Jsp = NULL;
- Value = AllocateValue(g, (void*)strp, TYPE_STRING);
- Next = NULL;
- Del = false;
+ Jsp = NULL;
+//Val = AllocVal(g, TYPE_STRG);
+ Strp = (char*)strp;
+ DataType = TYPE_STRG;
+ Nd = 0;
+ Next = NULL;
+ Del = false;
+ Type = TYPE_JVAL;
} // end of JVALUE constructor
/***********************************************************************/
+/* Set or reset all Jvalue members. */
+/***********************************************************************/
+void JVALUE::Clear(void)
+{
+ Jsp = NULL;
+ Next = NULL;
+ Type = TYPE_JVAL;
+ Del = false;
+ Nd = 0;
+ DataType = TYPE_NULL;
+} // end of Clear
+
+/***********************************************************************/
/* Returns the type of the Value's value. */
/***********************************************************************/
JTYP JVALUE::GetValType(void)
{
- if (Jsp)
+ if (DataType == TYPE_JSON)
return Jsp->GetType();
- else if (Value)
- return (JTYP)Value->GetType();
+//else if (Val)
+// return Val->Type;
else
- return TYPE_NULL;
+ return DataType;
} // end of GetValType
@@ -1368,7 +1505,7 @@ JTYP JVALUE::GetValType(void)
/***********************************************************************/
PJOB JVALUE::GetObject(void)
{
- if (Jsp && Jsp->GetType() == TYPE_JOB)
+ if (DataType == TYPE_JSON && Jsp->GetType() == TYPE_JOB)
return (PJOB)Jsp;
return NULL;
@@ -1379,18 +1516,46 @@ PJOB JVALUE::GetObject(void)
/***********************************************************************/
PJAR JVALUE::GetArray(void)
{
- if (Jsp && Jsp->GetType() == TYPE_JAR)
+ if (DataType == TYPE_JSON && Jsp->GetType() == TYPE_JAR)
return (PJAR)Jsp;
return NULL;
} // end of GetArray
/***********************************************************************/
-/* Return the Value's Integer value. */
+/* Return the Value's as a Value class. */
/***********************************************************************/
-int JVALUE::GetInteger(void)
+PVAL JVALUE::GetValue(PGLOBAL g)
{
- return (Value) ? Value->GetIntValue() : 0;
+ PVAL valp = NULL;
+
+ if (DataType != TYPE_JSON)
+ if (DataType == TYPE_STRG)
+ valp = AllocateValue(g, Strp, DataType, Nd);
+ else
+ valp = AllocateValue(g, &LLn, DataType, Nd);
+
+ return valp;
+} // end of GetValue
+
+/***********************************************************************/
+/* Return the Value's Integer value. */
+/***********************************************************************/
+int JVALUE::GetInteger(void) {
+ int n;
+
+ switch (DataType) {
+ case TYPE_INTG: n = N; break;
+ case TYPE_DBL: n = (int)F; break;
+ case TYPE_DTM:
+ case TYPE_STRG: n = atoi(Strp); break;
+ case TYPE_BOOL: n = (B) ? 1 : 0; break;
+ case TYPE_BINT: n = (int)LLn; break;
+ default:
+ n = 0;
+ } // endswitch Type
+
+ return n;
} // end of GetInteger
/***********************************************************************/
@@ -1398,7 +1563,20 @@ int JVALUE::GetInteger(void)
/***********************************************************************/
long long JVALUE::GetBigint(void)
{
- return (Value) ? Value->GetBigintValue() : 0;
+ long long lln;
+
+ switch (DataType) {
+ case TYPE_BINT: lln = LLn; break;
+ case TYPE_INTG: lln = (long long)N; break;
+ case TYPE_DBL: lln = (long long)F; break;
+ case TYPE_DTM:
+ case TYPE_STRG: lln = atoll(Strp); break;
+ case TYPE_BOOL: lln = (B) ? 1 : 0; break;
+ default:
+ lln = 0;
+ } // endswitch Type
+
+ return lln;
} // end of GetBigint
/***********************************************************************/
@@ -1406,75 +1584,157 @@ long long JVALUE::GetBigint(void)
/***********************************************************************/
double JVALUE::GetFloat(void)
{
- return (Value) ? Value->GetFloatValue() : 0.0;
+ double d;
+
+ switch (DataType) {
+ case TYPE_DBL: d = F; break;
+ case TYPE_BINT: d = (double)LLn; break;
+ case TYPE_INTG: d = (double)N; break;
+ case TYPE_DTM:
+ case TYPE_STRG: d = atof(Strp); break;
+ case TYPE_BOOL: d = (B) ? 1.0 : 0.0; break;
+ default:
+ d = 0.0;
+ } // endswitch Type
+
+ return d;
} // end of GetFloat
/***********************************************************************/
/* Return the Value's String value. */
/***********************************************************************/
-PSZ JVALUE::GetString(PGLOBAL g)
+PSZ JVALUE::GetString(PGLOBAL g, char *buff)
{
- char *p;
-
- if (Value) {
- char buf[32];
-
- if ((p = Value->GetCharString(buf)) == buf)
- p = PlugDup(g, buf);
-
- } else
- p = NULL;
-
- return p;
+ char buf[32];
+ char *p = (buff) ? buff : buf;
+
+ switch (DataType) {
+ case TYPE_DTM:
+ case TYPE_STRG:
+ p = Strp;
+ break;
+ case TYPE_INTG:
+ sprintf(p, "%d", N);
+ break;
+ case TYPE_BINT:
+ sprintf(p, "%lld", LLn);
+ break;
+ case TYPE_DBL:
+ sprintf(p, "%.*lf", Nd, F);
+ break;
+ case TYPE_BOOL:
+ p = (char*)((B) ? "true" : "false");
+ break;
+ case TYPE_NULL:
+ p = (char*)"null";
+ break;
+ default:
+ p = NULL;
+ } // endswitch Type
+
+
+ return (p == buf) ? (char*)PlugDup(g, buf) : p;
} // end of GetString
/***********************************************************************/
/* Return the Value's String value. */
/***********************************************************************/
-PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
+PSZ JVALUE::GetText(PGLOBAL g, PSTRG text)
{
- if (Jsp)
+ if (DataType == TYPE_JSON)
return Jsp->GetText(g, text);
- char buf[32];
- PSZ s = (Value) ? Value->GetCharString(buf) : NULL;
+ char buff[32];
+ PSZ s = (DataType == TYPE_NULL) ? NULL : GetString(g, buff);
- if (s)
- strcat(strcat(text, " "), s);
- else if (GetJsonNull())
- strcat(strcat(text, " "), GetJsonNull());
+ if (s)
+ text->Append(s);
+ else if (GetJsonNull())
+ text->Append(GetJsonNull());
- return text;
+ return NULL;
} // end of GetText
void JVALUE::SetValue(PJSON jsp)
{
- if (jsp && jsp->GetType() == TYPE_JVAL) {
- Jsp = jsp->GetJsp();
- Value = jsp->GetValue();
- } else {
- Jsp = jsp;
- Value = NULL;
- } // endif Type
+ if (DataType == TYPE_JSON && jsp->GetType() == TYPE_JVAL) {
+ Jsp = jsp->GetJsp();
+ Nd = ((PJVAL)jsp)->Nd;
+ DataType = ((PJVAL)jsp)->DataType;
+ // Val = ((PJVAL)jsp)->GetVal();
+ } else {
+ Jsp = jsp;
+ DataType = TYPE_JSON;
+ } // endif Type
+
+} // end of SetValue;
+
+void JVALUE::SetValue(PGLOBAL g, PVAL valp)
+{
+//if (!Val)
+// Val = AllocVal(g, TYPE_VAL);
+
+ if (!valp || valp->IsNull()) {
+ DataType = TYPE_NULL;
+ } else switch (valp->GetType()) {
+ case TYPE_DATE:
+ if (((DTVAL*)valp)->IsFormatted())
+ Strp = PlugDup(g, valp->GetCharValue());
+ else {
+ char buf[32];
+
+ Strp = PlugDup(g, valp->GetCharString(buf));
+ } // endif Formatted
+
+ DataType = TYPE_DTM;
+ break;
+ case TYPE_STRING:
+ Strp = PlugDup(g, valp->GetCharValue());
+ DataType = TYPE_STRG;
+ break;
+ case TYPE_DOUBLE:
+ case TYPE_DECIM:
+ F = valp->GetFloatValue();
+
+ if (IsTypeNum(valp->GetType()))
+ Nd = valp->GetValPrec();
+
+ DataType = TYPE_DBL;
+ break;
+ case TYPE_TINY:
+ B = valp->GetTinyValue() != 0;
+ DataType = TYPE_BOOL;
+ case TYPE_INT:
+ N = valp->GetIntValue();
+ DataType = TYPE_INTG;
+ break;
+ case TYPE_BIGINT:
+ LLn = valp->GetBigintValue();
+ DataType = TYPE_BINT;
+ break;
+ default:
+ sprintf(g->Message, "Unsupported typ %d\n", valp->GetType());
+ throw(777);
+ } // endswitch Type
-} // end of SetValue;
+} // end of SetValue
/***********************************************************************/
/* Set the Value's value as the given integer. */
/***********************************************************************/
void JVALUE::SetInteger(PGLOBAL g, int n)
{
- Value = AllocateValue(g, &n, TYPE_INT);
- Jsp = NULL;
+ N = n;
+ DataType = TYPE_INTG;
} // end of SetInteger
/***********************************************************************/
/* Set the Value's Boolean value as a tiny integer. */
/***********************************************************************/
-void JVALUE::SetTiny(PGLOBAL g, char n)
+void JVALUE::SetBool(PGLOBAL g, bool b)
{
- Value = AllocateValue(g, &n, TYPE_TINY);
- Jsp = NULL;
+ B = b;
+ DataType = TYPE_BOOL;
} // end of SetTiny
/***********************************************************************/
@@ -1482,8 +1742,8 @@ void JVALUE::SetTiny(PGLOBAL g, char n)
/***********************************************************************/
void JVALUE::SetBigint(PGLOBAL g, long long ll)
{
- Value = AllocateValue(g, &ll, TYPE_BIGINT);
- Jsp = NULL;
+ LLn = ll;
+ DataType = TYPE_BINT;
} // end of SetBigint
/***********************************************************************/
@@ -1491,17 +1751,19 @@ void JVALUE::SetBigint(PGLOBAL g, long long ll)
/***********************************************************************/
void JVALUE::SetFloat(PGLOBAL g, double f)
{
- Value = AllocateValue(g, &f, TYPE_DOUBLE, 6);
- Jsp = NULL;
+ F = f;
+ Nd = 6;
+ DataType = TYPE_DBL;
} // end of SetFloat
/***********************************************************************/
/* Set the Value's value as the given string. */
/***********************************************************************/
-void JVALUE::SetString(PGLOBAL g, PSZ s, short c)
+void JVALUE::SetString(PGLOBAL g, PSZ s, int ci)
{
- Value = AllocateValue(g, s, TYPE_STRING, c);
- Jsp = NULL;
+ Strp = s;
+ Nd = ci;
+ DataType = TYPE_STRG;
} // end of SetString
/***********************************************************************/
@@ -1509,6 +1771,239 @@ void JVALUE::SetString(PGLOBAL g, PSZ s, short c)
/***********************************************************************/
bool JVALUE::IsNull(void)
{
- return (Jsp) ? Jsp->IsNull() : (Value) ? Value->IsNull() : true;
+ return (DataType == TYPE_JSON) ? Jsp->IsNull() : DataType == TYPE_NULL;
} // end of IsNull
+
+/* ---------------------------- Class SWAP --------------------------- */
+
+/***********************************************************************/
+/* Replace all pointers by offsets or the opposite. */
+/***********************************************************************/
+void SWAP::SwapJson(PJSON jsp, bool move)
+{
+ if (move)
+ MoffJson(jsp);
+ else
+ MptrJson((PJSON)MakeOff(Base, jsp));
+
+ return;
+} // end of SwapJson
+
+/***********************************************************************/
+/* Replace all pointers by offsets. */
+/***********************************************************************/
+size_t SWAP::MoffJson(PJSON jsp) {
+ size_t res = 0;
+
+ if (jsp)
+ switch (jsp->Type) {
+ case TYPE_JAR:
+ res = MoffArray((PJAR)jsp);
+ break;
+ case TYPE_JOB:
+ res = MoffObject((PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ res = MoffJValue((PJVAL)jsp);
+ break;
+ default:
+ throw "Invalid json tree";
+ } // endswitch Type
+
+ return res;
+} // end of MoffJson
+
+/***********************************************************************/
+/* Replace all array pointers by offsets. */
+/***********************************************************************/
+size_t SWAP::MoffArray(PJAR jarp)
+{
+ if (jarp->First) {
+ for (int i = 0; i < jarp->Size; i++)
+ jarp->Mvals[i] = (PJVAL)MakeOff(Base, jarp->Mvals[i]);
+
+ jarp->Mvals = (PJVAL*)MakeOff(Base, jarp->Mvals);
+ jarp->First = (PJVAL)MoffJValue(jarp->First);
+ jarp->Last = (PJVAL)MakeOff(Base, jarp->Last);
+ } // endif First
+
+ return MakeOff(Base, jarp);
+} // end of MoffArray
+
+/***********************************************************************/
+/* Replace all object pointers by offsets. */
+/***********************************************************************/
+size_t SWAP::MoffObject(PJOB jobp) {
+ if (jobp->First) {
+ jobp->First = (PJPR)MoffPair(jobp->First);
+ jobp->Last = (PJPR)MakeOff(Base, jobp->Last);
+ } // endif First
+
+ return MakeOff(Base, jobp);
+} // end of MoffObject
+
+/***********************************************************************/
+/* Replace all pair pointers by offsets. */
+/***********************************************************************/
+size_t SWAP::MoffPair(PJPR jpp) {
+ jpp->Key = (PCSZ)MakeOff(Base, (void*)jpp->Key);
+
+ if (jpp->Val)
+ jpp->Val = (PJVAL)MoffJValue(jpp->Val);
+
+ if (jpp->Next)
+ jpp->Next = (PJPR)MoffPair(jpp->Next);
+
+ return MakeOff(Base, jpp);
+} // end of MoffPair
+
+/***********************************************************************/
+/* Replace all jason value pointers by offsets. */
+/***********************************************************************/
+size_t SWAP::MoffJValue(PJVAL jvp) {
+ if (!jvp->Del) {
+ if (jvp->DataType == TYPE_JSON)
+ jvp->Jsp = (PJSON)MoffJson(jvp->Jsp);
+ else if (jvp->DataType == TYPE_STRG)
+ jvp->Strp = (PSZ)MakeOff(Base, (jvp->Strp));
+
+// if (jvp->Val)
+// jvp->Val = (PVL)MoffVal(jvp->Val);
+
+ } // endif Del
+
+ if (jvp->Next)
+ jvp->Next = (PJVAL)MoffJValue(jvp->Next);
+
+ return MakeOff(Base, jvp);
+} // end of MoffJValue
+
+#if 0
+/***********************************************************************/
+/* Replace string pointers by offset. */
+/***********************************************************************/
+size_t SWAP::MoffVal(PVL vlp) {
+ if (vlp->Type == TYPE_STRG)
+ vlp->Strp = (PSZ)MakeOff(Base, (vlp->Strp));
+
+ return MakeOff(Base, vlp);
+} // end of MoffVal
+#endif // 0
+
+/***********************************************************************/
+/* Replace all offsets by pointers. */
+/***********************************************************************/
+PJSON SWAP::MptrJson(PJSON ojp) { // ojp is an offset
+ PJSON jsp = (PJSON)MakePtr(Base, (size_t)ojp);
+
+ if (ojp)
+ switch (jsp->Type) {
+ case TYPE_JAR:
+ jsp = MptrArray((PJAR)ojp);
+ break;
+ case TYPE_JOB:
+ jsp = MptrObject((PJOB)ojp);
+ break;
+ case TYPE_JVAL:
+ jsp = MptrJValue((PJVAL)ojp);
+ break;
+ default:
+ throw "Invalid json tree";
+ } // endswitch Type
+
+ return jsp;
+} // end of MptrJson
+
+/***********************************************************************/
+/* Replace all array offsets by pointers. */
+/***********************************************************************/
+PJAR SWAP::MptrArray(PJAR ojar) {
+ PJAR jarp = (PJAR)MakePtr(Base, (size_t)ojar);
+
+ jarp = (PJAR)new((long long)jarp) JARRAY(0);
+
+ if (jarp->First) {
+ jarp->Mvals = (PJVAL*)MakePtr(Base, (size_t)jarp->Mvals);
+
+ for (int i = 0; i < jarp->Size; i++)
+ jarp->Mvals[i] = (PJVAL)MakePtr(Base, (size_t)jarp->Mvals[i]);
+
+ jarp->First = (PJVAL)MptrJValue(jarp->First);
+ jarp->Last = (PJVAL)MakePtr(Base, (size_t)jarp->Last);
+ } // endif First
+
+ return jarp;
+} // end of MptrArray
+
+/***********************************************************************/
+/* Replace all object offsets by pointers. */
+/***********************************************************************/
+PJOB SWAP::MptrObject(PJOB ojob) {
+ PJOB jobp = (PJOB)MakePtr(Base, (size_t)ojob);
+
+ jobp = (PJOB)new((long long)jobp) JOBJECT(0);
+
+ if (jobp->First) {
+ jobp->First = (PJPR)MptrPair(jobp->First);
+ jobp->Last = (PJPR)MakePtr(Base, (size_t)jobp->Last);
+ } // endif First
+
+ return jobp;
+} // end of MptrObject
+
+/***********************************************************************/
+/* Replace all pair offsets by pointers. */
+/***********************************************************************/
+PJPR SWAP::MptrPair(PJPR ojp) {
+ PJPR jpp = (PJPR)MakePtr(Base, (size_t)ojp);
+
+ jpp->Key = (PCSZ)MakePtr(Base, (size_t)jpp->Key);
+
+ if (jpp->Val)
+ jpp->Val = (PJVAL)MptrJValue(jpp->Val);
+
+ if (jpp->Next)
+ jpp->Next = (PJPR)MptrPair(jpp->Next);
+
+ return jpp;
+} // end of MptrPair
+
+/***********************************************************************/
+/* Replace all value offsets by pointers. */
+/***********************************************************************/
+PJVAL SWAP::MptrJValue(PJVAL ojv) {
+ PJVAL jvp = (PJVAL)MakePtr(Base, (size_t)ojv);
+
+ jvp = (PJVAL)new((long long)jvp) JVALUE(0);
+
+ if (!jvp->Del) {
+ if (jvp->DataType == TYPE_JSON)
+ jvp->Jsp = (PJSON)MptrJson(jvp->Jsp);
+ else if (jvp->DataType == TYPE_STRG)
+ jvp->Strp = (PSZ)MakePtr(Base, (size_t)jvp->Strp);
+
+// if (jvp->Val)
+// jvp->Val = (PVL)MptrVal(jvp->Val);
+
+ } // endif Del
+
+ if (jvp->Next)
+ jvp->Next = (PJVAL)MptrJValue(jvp->Next);
+
+ return jvp;
+} // end of MptrJValue
+
+#if 0
+/***********************************************************************/
+/* Replace string offsets by a pointer. */
+/***********************************************************************/
+PVL SWAP::MptrVal(PVL ovl) {
+ PVL vlp = (PVL)MakePtr(Base, (size_t)ovl);
+
+ if (vlp->Type == TYPE_STRG)
+ vlp->Strp = (PSZ)MakePtr(Base, (size_t)vlp->Strp);
+
+ return vlp;
+} // end of MptrValue
+#endif // 0