/*************** json CPP Declares Source Code File (.H) ***************/ /* Name: json.cpp Version 1.6 */ /* */ /* (C) Copyright to the author Olivier BERTRAND 2014 - 2021 */ /* */ /* This file contains the JSON classes functions. */ /***********************************************************************/
/***********************************************************************/ /* Include relevant sections of the MariaDB header file. */ /***********************************************************************/ #include <my_global.h> #include <m_string.h>
/***********************************************************************/ /* Include application header files: */ /* global.h is header containing all global declarations. */ /* plgdbsem.h is header containing the DB application declarations. */ /* xjson.h is header containing the JSON classes declarations. */ /***********************************************************************/ #include"global.h" #include"plgdbsem.h" #include"json.h"
#define EL "\n" #if !defined(_WIN32) #undef SE_CATCH // Does not work for Linux #endif
#ifdefined(SE_CATCH) /**************************************************************************/ /* This is the support of catching C interrupts to prevent crashes. */ /**************************************************************************/ #include <eh.h>
class SE_Exception { public:
SE_Exception(unsignedint n, PEXCEPTION_RECORD p) : nSE(n), eRec(p) {}
~SE_Exception() {}
unsignedint nSE;
PEXCEPTION_RECORD eRec;
}; // end of class SE_Exception
void trans_func(unsignedint u, _EXCEPTION_POINTERS* pExp)
{ throw SE_Exception(u, pExp->ExceptionRecord);
} // end of trans_func
char *GetJsonNull(void); int GetDefaultPrec(void); int PrepareColist(char*);
/***********************************************************************/ /* IsNum: check whether this string is all digits. */ /***********************************************************************/ bool IsNum(PSZ s)
{ char* p = s;
if (*p == '-')
p++;
if (*p == ']') returnfalse; elsefor (; *p; p++) if (*p == ']') break; elseif (!isdigit(*p)) returnfalse;
returntrue;
} // end of IsNum
/***********************************************************************/ /* IsArray: check whether this is a Mongo array path. */ /***********************************************************************/ bool IsArray(PSZ s)
{ char* p = s;
if (!p || !*p) returnfalse; elsefor (; *p; p++) if (*p == '.') break; elseif (!isdigit(*p)) returnfalse;
returntrue;
} // end of IsArray
/***********************************************************************/ /* NextChr: return the first found '[' or Sep pointer. */ /***********************************************************************/ char* NextChr(PSZ s, char sep)
{ char* p1 = strchr(s, '['); char* p2 = strchr(s, sep);
if (!p2) return p1; elseif (p1) return MY_MIN(p1, p2);
return p2;
} // end of NextChr
/***********************************************************************/ /* Stringified: check that this column is in the stringified list. */ /***********************************************************************/ bool Stringified(PCSZ strfy, char *colname)
{ if (strfy) { char *p, colist[512]; int n;
strncpy(colist, strfy, sizeof(colist) - 1);
n = PrepareColist(colist);
for (p = colist; n && p; p += (strlen(p) + 1), n--) if (!stricmp(p, colname)) returntrue;
} // endif strfy
returnfalse;
} // end of Stringified
#if0 /***********************************************************************/ /* 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, size_t len, int* ptyp, bool* comma)
{ 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=%zd\n", s, len);
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(constchar* s) { if (s) {
size_t len = strlen(s);
if (N + len > Max) returntrue;
memcpy(Strp + N, s, len);
N += len; returnfalse;
} else returntrue;
} // end of WriteStr
/***********************************************************************/ /* Concatenate a character to the Serialize string. */ /***********************************************************************/ bool JOUTSTR::WriteChr(constchar c) { if (N + 1 > Max) returntrue;
Strp[N++] = c; returnfalse;
} // end of WriteChr
/***********************************************************************/ /* Escape and Concatenate a string to the Serialize string. */ /***********************************************************************/ bool JOUTSTR::Escape(constchar* s)
{ if (s) {
WriteChr('"');
for (unsignedint 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");
returnfalse;
} // end of Escape
/* ------------------------- Class JOUTFILE -------------------------- */
/***********************************************************************/ /* Write a string to the Serialize file. */ /***********************************************************************/ bool JOUTFILE::WriteStr(constchar* s)
{ // This is temporary
fputs(s, Stream); returnfalse;
} // end of WriteStr
/***********************************************************************/ /* Write a character to the Serialize file. */ /***********************************************************************/ bool JOUTFILE::WriteChr(constchar c)
{ // This is temporary
fputc(c, Stream); returnfalse;
} // end of WriteChr
/***********************************************************************/ /* Escape and Concatenate a string to the Serialize string. */ /***********************************************************************/ bool JOUTFILE::Escape(constchar* s)
{ // This is temporary if (s) {
fputc('"', Stream);
/* ------------------------- Class JOUTPRT --------------------------- */
/***********************************************************************/ /* Write a string to the Serialize pretty file. */ /***********************************************************************/ bool JOUTPRT::WriteStr(constchar* 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); returnfalse;
} // end of WriteStr
/***********************************************************************/ /* Write a character to the Serialize pretty file. */ /***********************************************************************/ bool JOUTPRT::WriteChr(constchar c)
{ switch (c) { case':':
fputs(": ", Stream); break; case'{': case'[': #if0 if (M)
fputs(EL, Stream);
for (int i = 0; i < M; i++)
fputc('\t', Stream); #endif// 0
B = false; break; default:
fputc(c, Stream);
} // endswitch c
returnfalse;
} // end of WriteChr
/* --------------------------- Class JDOC ---------------------------- */
/***********************************************************************/ /* Parse several items as being in an array. */ /***********************************************************************/
PJAR JDOC::ParseAsArray(PGLOBAL g, int& i, int pretty, int *ptyp)
{ if (pty[0] && (!pretty || pretty > 2)) {
PJAR jsp;
if ((jsp = ParseArray(g, (i = 0))) && ptyp && pretty == 3)
*ptyp = (pty[0]) ? 0 : 3;
return jsp;
} else
snprintf(g->Message, sizeof(g->Message), "More than one item in file");
return NULL;
} // end of ParseAsArray
/***********************************************************************/ /* Parse a JSON Array. */ /***********************************************************************/
PJAR JDOC::ParseArray(PGLOBAL g, int& i)
{ int level = 0; bool b = (!i);
PJAR jarp = new(g) JARRAY;
for (; i < len; i++) switch (s[i]) { case',': if (level < 2) {
snprintf(g->Message, sizeof(g->Message), "Unexpected ',' near %.*s",ARGS); throw1;
} else
level = 1;
break; case']': if (level == 1) {
snprintf(g->Message, sizeof(g->Message), "Unexpected ',]' near %.*s", ARGS); throw1;
} // endif level
jarp->InitArray(g); return jarp; case'\n': if (!b)
pty[0] = pty[1] = false; case'\r': case' ': case'\t': break; default: if (level == 2) {
snprintf(g->Message, sizeof(g->Message), "Unexpected value near %.*s", ARGS); throw1;
} else
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
throw ("Unexpected EOF in array");
} // end of ParseArray
if ((jap = jvp->GetArray())) return SerializeArray(jap, false); elseif ((jop = jvp->GetObject())) return SerializeObject(jop); //else if (!(vlp = jvp->Val)) // return js->WriteStr("null"); elseswitch (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:
snprintf(buf, sizeof(buf), "%d", jvp->N); return js->WriteStr(buf); case TYPE_BINT:
snprintf(buf, sizeof(buf), "%lld", jvp->LLn); return js->WriteStr(buf); case TYPE_DBL: // dfp to limit to the default number of decimals
snprintf(buf, sizeof(buf), "%.*f", MY_MIN(jvp->Nd, dfp), jvp->F); return js->WriteStr(buf); case TYPE_NULL: return js->WriteStr("null"); default: return js->WriteStr("???"); // TODO
} // endswitch Type
strcpy(js->g->Message, "Unrecognized value"); returntrue;
} // end of SerializeValue
/* -------------------------- Class JOBJECT -------------------------- */
/***********************************************************************/ /* Return the number of pairs in this object. */ /***********************************************************************/ int JOBJECT::GetSize(bool b) { int n = 0;
for (PJPR jpp = First; jpp; jpp = jpp->Next) // If b return only non null pairs if (!b || (jpp->Val && !jpp->Val->IsNull()))
n++;
return n;
} // end of GetSize
/***********************************************************************/ /* Add a new pair to an Object. */ /***********************************************************************/
PJPR JOBJECT::AddPair(PGLOBAL g, PCSZ key)
{
PJPR jpp = (PJPR)PlugSubAlloc(g, NULL, sizeof(JPAIR));
jarp->InitArray(g); return jarp;
} // end of GetValList
/***********************************************************************/ /* Get the value corresponding to the given key. */ /***********************************************************************/
PJVAL JOBJECT::GetKeyValue(constchar* key)
{ for (PJPR jp = First; jp; jp = jp->Next) if (!strcmp(jp->Key, key)) return jp->Val;
return NULL;
} // end of GetValue;
/***********************************************************************/ /* Return the text corresponding to all keys (XML like). */ /***********************************************************************/
PSZ JOBJECT::GetText(PGLOBAL g, PSTRG text)
{ if (First) { bool b;
if (!text) {
text = new(g) STRING(g, 256);
b = true;
} else { if (text->GetLastChar() != ' ')
text->Append(' ');
b = false;
} // endif text
if (b && !First->Next && !strcmp(First->Key, "$date")) { int i;
PSZ s;
First->Val->GetText(g, text);
s = text->GetStr();
i = (s[1] == '-' ? 2 : 1);
if (IsNum(s + i)) { // Date is in milliseconds int j = text->GetLength();
if (j >= 4 + i) {
s[j - 3] = 0; // Change it to seconds
text->SetLength((uint)strlen(s));
} else
text->Set(" 0");
/***********************************************************************/ /* Set or add a value corresponding to the given key. */ /***********************************************************************/ void JOBJECT::SetKeyValue(PGLOBAL g, PJVAL jvp, PCSZ key)
{
PJPR jp;
for (jp = First; jp; jp = jp->Next) if (!strcmp(jp->Key, key)) {
jp->Val = jvp; break;
} // endif key
/***********************************************************************/ /* Delete a value corresponding to the given key. */ /***********************************************************************/ void JOBJECT::DeleteKey(PCSZ key)
{
PJPR jp, *pjp = &First;
/***********************************************************************/ /* True if void or if all members are nulls. */ /***********************************************************************/ bool JOBJECT::IsNull(void)
{ for (PJPR jp = First; jp; jp = jp->Next) if (!jp->Val->IsNull()) returnfalse;
returntrue;
} // end of IsNull
/* -------------------------- 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;
for (PJVAL jvp = First; jvp; jvp = jvp->Next) if (!jvp->IsNull())
n++;
return n;
} else return Size;
} // end of GetSize
/***********************************************************************/ /* Make the array of values from the values list. */ /***********************************************************************/ void JARRAY::InitArray(PGLOBAL g)
{ int i;
PJVAL jvp, *pjvp = &First;
for (Size = 0, jvp = First; jvp; jvp = jvp->Next) if (!jvp->Del)
Size++;
if (Size > Alloc) { // No need to realloc after deleting values
Mvals = (PJVAL*)PlugSubAlloc(g, NULL, Size * sizeof(PJVAL));
Alloc = Size;
} // 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;
} // end of InitArray
/***********************************************************************/ /* Get the Nth value of an Array. */ /***********************************************************************/
PJVAL JARRAY::GetArrayValue(int i)
{ if (Mvals && i >= 0 && i < Size) return Mvals[i]; elseif (Mvals && i < 0 && i >= -Size) return Mvals[Size + i]; else return NULL;
} // end of GetValue
/***********************************************************************/ /* Add a Value to the Array Value list. */ /***********************************************************************/
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;
for (jp = First; jp && i < n; i++, jp = *(jpp = &jp->Next));
(*jpp) = jvp;
if (!(jvp->Next = jp))
Last = jvp;
} else { if (!First)
First = jvp; elseif (Last == First)
First->Next = Last = jvp; else
Last->Next = jvp;
Last = jvp;
Last->Next = NULL;
} // endif x
return jvp;
} // end of AddValue
/***********************************************************************/ /* Merge two arrays. */ /***********************************************************************/ bool JARRAY::Merge(PGLOBAL g, PJSON jsp)
{ if (jsp->GetType() != TYPE_JAR) {
snprintf(g->Message, sizeof(g->Message), "Second argument is not an array"); returntrue;
} // endif Type
PJAR arp = (PJAR)jsp;
for (int i = 0; i < arp->size(); i++)
AddArrayValue(g, arp->GetArrayValue(i));
InitArray(g); returnfalse;
} // end of Merge
/***********************************************************************/ /* Set the nth Value of the Array Value list or add it. */ /***********************************************************************/ void JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n)
{ int i = 0;
PJVAL jp, *jpp = &First;
for (jp = First; i < n; i++, jp = *(jpp = &jp->Next)) if (!jp)
*jpp = jp = new(g) JVALUE;
*jpp = jvp;
jvp->Next = (jp ? jp->Next : NULL);
} // end of SetValue
/***********************************************************************/ /* Return the text corresponding to all values. */ /***********************************************************************/
PSZ JARRAY::GetText(PGLOBAL g, PSTRG text)
{ 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('(');
if (jp->Next)
text->Append(", "); elseif (!b)
text->Append(')');
} // endfor jp
if (b) {
text->Trim(); return text->GetStr();
} // endif b
} // endif First
return NULL;
} // end of GetText;
/***********************************************************************/ /* Delete a Value from the Arrays Value list. */ /***********************************************************************/ bool JARRAY::DeleteValue(int n)
{
PJVAL jvp = GetArrayValue(n);
if (jvp) {
jvp->Del = true; returnfalse;
} else returntrue;
} // end of DeleteValue
/***********************************************************************/ /* True if void or if all members are nulls. */ /***********************************************************************/ bool JARRAY::IsNull(void)
{ for (int i = 0; i < Size; i++) if (!Mvals[i]->IsNull()) returnfalse;
returntrue;
} // end of IsNull
/* -------------------------- Class JVALUE- -------------------------- */
/***********************************************************************/ /* Constructor for a JVALUE. */ /***********************************************************************/
JVALUE::JVALUE(PJSON jsp) : JSON()
{ if (jsp && 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
Next = NULL;
Del = false;
Type = TYPE_JVAL;
} // end of JVALUE constructor
#if0 /***********************************************************************/ /* Constructor for a JVALUE with a given string or numeric value. */ /***********************************************************************/
JVALUE::JVALUE(PGLOBAL g, PVL vlp) : JSON()
{
Jsp = NULL;
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
/***********************************************************************/ /* Constructor for a given string. */ /***********************************************************************/
JVALUE::JVALUE(PGLOBAL g, PCSZ strp) : JSON()
{
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 (DataType == TYPE_JSON) return Jsp->GetType(); //else if (Val) // return Val->Type; else return DataType;
/***********************************************************************/ /* Return the Value's as a Value class. */ /***********************************************************************/
PVAL JVALUE::GetValue(PGLOBAL g)
{
PVAL valp = NULL;
/***********************************************************************/ /* 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
/***********************************************************************/ /* Return the Value's Big integer value. */ /***********************************************************************/ longlong JVALUE::GetBigint(void)
{ longlong lln;
switch (DataType) { case TYPE_BINT: lln = LLn; break; case TYPE_INTG: lln = (longlong)N; break; case TYPE_DBL: lln = (longlong)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
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
switch (DataType) { case TYPE_DTM: case TYPE_STRG:
p = Strp; break; case TYPE_INTG:
snprintf(p, 32, "%d", N); break; case TYPE_BINT:
snprintf(p, 32, "%lld", LLn); break; case TYPE_DBL:
snprintf(p, 32, "%.*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
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; break; case TYPE_INT:
N = valp->GetIntValue();
DataType = TYPE_INTG; break; case TYPE_BIGINT:
LLn = valp->GetBigintValue();
DataType = TYPE_BINT; break; default:
snprintf(g->Message, sizeof(g->Message), "Unsupported typ %d", valp->GetType()); throw(777);
} // endswitch Type
} // end of SetValue
/***********************************************************************/ /* Set the Value's value as the given integer. */ /***********************************************************************/ void JVALUE::SetInteger(PGLOBAL g, int n)
{
N = n;
DataType = TYPE_INTG;
} // end of SetInteger
/***********************************************************************/ /* Set the Value's Boolean value as a tiny integer. */ /***********************************************************************/ void JVALUE::SetBool(PGLOBAL g, bool b)
{
B = b;
DataType = TYPE_BOOL;
} // end of SetTiny
/***********************************************************************/ /* Set the Value's value as the given big integer. */ /***********************************************************************/ void JVALUE::SetBigint(PGLOBAL g, longlong ll)
{
LLn = ll;
DataType = TYPE_BINT;
} // end of SetBigint
/***********************************************************************/ /* Set the Value's value as the given DOUBLE. */ /***********************************************************************/ void JVALUE::SetFloat(PGLOBAL g, double f)
{
F = f;
Nd = GetDefaultPrec();
DataType = TYPE_DBL;
} // end of SetFloat
/***********************************************************************/ /* Set the Value's value as the given string. */ /***********************************************************************/ void JVALUE::SetString(PGLOBAL g, PSZ s, int ci)
{
Strp = s;
Nd = ci;
DataType = TYPE_STRG;
} // end of SetString
/***********************************************************************/ /* True when its JSON or normal value is null. */ /***********************************************************************/ bool JVALUE::IsNull(void)
{ 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]);
/***********************************************************************/ /* Replace all object offsets by pointers. */ /***********************************************************************/
PJOB SWAP::MptrObject(PJOB ojob) {
PJOB jobp = (PJOB)MakePtr(Base, (size_t)ojob);
jobp = (PJOB)new((longlong)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((longlong)jvp) JVALUE(0);
if (!jvp->Del) { if (jvp->DataType == TYPE_JSON)
jvp->Jsp = (PJSON)MptrJson(jvp->Jsp); elseif (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
#if0 /***********************************************************************/ /* 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
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.29Bemerkung:
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.