From 477b5256ddca1431b94aad7bc78e339ee399e5bb Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 21 Nov 2020 21:52:48 +0100 Subject: Fix some test failure --- storage/connect/bson.cpp | 1601 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1601 insertions(+) create mode 100644 storage/connect/bson.cpp (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp new file mode 100644 index 00000000000..86825f5808e --- /dev/null +++ b/storage/connect/bson.cpp @@ -0,0 +1,1601 @@ +/*************** json CPP Declares Source Code File (.H) ***************/ +/* Name: json.cpp Version 1.5 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2020 */ +/* */ +/* This file contains the JSON classes functions. */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include relevant sections of the MariaDB header file. */ +/***********************************************************************/ +#include + +/***********************************************************************/ +/* 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 "bson.h" + +#define ARGS MY_MIN(24,(int)len-i),s+MY_MAX(i-3,0) + +#if defined(__WIN__) +#define EL "\r\n" +#else +#define EL "\n" +#undef SE_CATCH // Does not work for Linux +#endif + +#if defined(SE_CATCH) +/**************************************************************************/ +/* This is the support of catching C interrupts to prevent crashes. */ +/**************************************************************************/ +#include + +class SE_Exception { +public: + SE_Exception(unsigned int n, PEXCEPTION_RECORD p) : nSE(n), eRec(p) {} + ~SE_Exception() {} + + 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); +} // end of trans_func + +char* GetExceptionDesc(PGLOBAL g, unsigned int e); +#endif // SE_CATCH + +#if 0 +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; + + return true; +} // end of IsNum + +/***********************************************************************/ +/* 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; + else if (p1) + return MY_MIN(p1, p2); + + return p2; +} // end of NextChr +#endif // 0 + +/* --------------------------- Class BDOC ---------------------------- */ + +/***********************************************************************/ +/* BDOC constructor. */ +/***********************************************************************/ +BDOC::BDOC(void) : jp(NULL), base(NULL), s(NULL), len(0) +{ + pty[0] = pty[1] = pty[2] = true; +} // end of BDOC constructor + +/***********************************************************************/ +/* Program for sub-allocating Bson structures. */ +/***********************************************************************/ +void* BDOC::BsonSubAlloc(PGLOBAL g, size_t size) { + PPOOLHEADER pph; /* Points on area header. */ + void* memp = g->Sarea; + + size = ((size + 3) / 4) * 4; /* Round up size to multiple of 4 */ + pph = (PPOOLHEADER)memp; + + xtrc(16, "SubAlloc in %p size=%zd used=%zd free=%zd\n", + memp, size, pph->To_Free, pph->FreeBlk); + + if (size > pph->FreeBlk) { /* Not enough memory left in pool */ + sprintf(g->Message, + "Not enough memory for request of %zd (used=%zd free=%zd)", + size, pph->To_Free, pph->FreeBlk); + xtrc(1, "BsonSubAlloc: %s\n", g->Message); + throw(1234); + } /* endif size OS32 code */ + + // Do the suballocation the simplest way + memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */ + pph->To_Free += size; /* New offset of pool free block */ + pph->FreeBlk -= size; /* New size of pool free block */ + xtrc(16, "Done memp=%p used=%zd free=%zd\n", + memp, pph->To_Free, pph->FreeBlk); + return memp; +} /* end of BsonSubAlloc */ + + + +/***********************************************************************/ +/* Parse a json string. */ +/* Note: when pretty is not known, the caller set pretty to 3. */ +/***********************************************************************/ +PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { + int i, pretty = (ptyp) ? *ptyp : 3; + bool b = false; + PBVAL bvp = NULL; + + xtrc(1, "ParseJson: s=%.10s len=%zd\n", s, len); + + if (!s || !len) { + strcpy(g->Message, "Void JSON object"); + return NULL; + } 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; + + s = js; + len = lng; + + try { + bvp = (PBVAL)PlugSubAlloc(g, NULL, sizeof(BVAL)); + bvp->Type = TYPE_UNKNOWN; + base = bvp; + + for (i = 0; i < len; i++) + switch (s[i]) { + case '[': + if (bvp->Type != TYPE_UNKNOWN) + bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + else + bvp->To_Val = ParseArray(g, ++i); + + bvp->Type = TYPE_JAR; + break; + case '{': + if (bvp->Type != TYPE_UNKNOWN) { + bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + bvp->Type = TYPE_JAR; + } else if ((bvp->To_Val = ParseObject(g, ++i))) + bvp->Type = TYPE_JOB; + else + throw 2; + + break; + case ' ': + case '\t': + case '\n': + case '\r': + break; + case ',': + if (bvp->Type != TYPE_UNKNOWN && (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 (bvp->Type != TYPE_UNKNOWN) { + bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + bvp->Type = TYPE_JAR; + } else if ((bvp->To_Val = MakeOff(base, ParseValue(g, i)))) + bvp->Type = TYPE_JVAL; + else + throw 4; + + break; + }; // endswitch s[i] + + if (bvp->Type == TYPE_UNKNOWN) + 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); + bvp = NULL; + } catch (const char* msg) { + strcpy(g->Message, msg); + bvp = NULL; + } // end catch + + return bvp; +} // end of ParseJson + +/***********************************************************************/ +/* Parse several items as being in an array. */ +/***********************************************************************/ +OFFSET BDOC::ParseAsArray(PGLOBAL g, int& i, int pretty, int* ptyp) { + if (pty[0] && (!pretty || pretty > 2)) { + OFFSET jsp; + + 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 0; +} // end of ParseAsArray + +/***********************************************************************/ +/* Parse a JSON Array. */ +/***********************************************************************/ +OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { + int level = 0; + bool b = (!i); + PBVAL vlp, firstvlp, lastvlp; + + vlp = firstvlp = lastvlp = NULL; + + for (; i < len; i++) + switch (s[i]) { + case ',': + if (level < 2) { + sprintf(g->Message, "Unexpected ',' near %.*s", ARGS); + throw 1; + } else + level = 1; + + break; + case ']': + if (level == 1) { + sprintf(g->Message, "Unexpected ',]' near %.*s", ARGS); + throw 1; + } // endif level + + return MakeOff(base, vlp); + case '\n': + if (!b) + pty[0] = pty[1] = false; + case '\r': + case ' ': + case '\t': + break; + default: + if (level == 2) { + sprintf(g->Message, "Unexpected value near %.*s", ARGS); + throw 1; + } else if (lastvlp) { + vlp = ParseValue(g, i); + lastvlp->Next = MakeOff(base, vlp); + lastvlp = vlp; + } else + firstvlp = lastvlp = ParseValue(g, i); + + level = (b) ? 1 : 2; + break; + }; // endswitch s[i] + + if (b) { + // Case of Pretty == 0 + return MakeOff(base, vlp); + } // endif b + + throw ("Unexpected EOF in array"); +} // end of ParseArray + +/***********************************************************************/ +/* Sub-allocate and initialize a BPAIR. */ +/***********************************************************************/ +PBPR BDOC::SubAllocPair(PGLOBAL g, OFFSET key) +{ + PBPR bpp = (PBPR)BsonSubAlloc(g, sizeof(BPAIR)); + + bpp->Key = key; + bpp->Vlp = 0; + bpp->Next = 0; + return bpp; +} // end of SubAllocPair + +/***********************************************************************/ +/* Parse a JSON Object. */ +/***********************************************************************/ +OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { + OFFSET key; + int level = 0; + PBPR bpp, firstbpp, lastbpp; + + bpp = firstbpp = lastbpp = NULL; + + for (; i < len; i++) + switch (s[i]) { + case '"': + if (level < 2) { + key = ParseString(g, ++i); + bpp = SubAllocPair(g, key); + + if (lastbpp) { + lastbpp->Next = MakeOff(base, bpp); + lastbpp = bpp; + } else + firstbpp = lastbpp = bpp; + + level = 1; + } else { + sprintf(g->Message, "misplaced string near %.*s", ARGS); + throw 2; + } // endif level + + break; + case ':': + if (level == 1) { + lastbpp->Vlp = MakeOff(base, ParseValue(g, ++i)); + level = 2; + } else { + sprintf(g->Message, "Unexpected ':' near %.*s", ARGS); + throw 2; + } // endif level + + break; + case ',': + if (level < 2) { + sprintf(g->Message, "Unexpected ',' near %.*s", ARGS); + throw 2; + } else + level = 0; + + break; + case '}': + if (level < 2) { + sprintf(g->Message, "Unexpected '}' near %.*s", ARGS); + throw 2; + } // endif level + + return MakeOff(base, firstbpp); + case '\n': + pty[0] = pty[1] = false; + case '\r': + case ' ': + case '\t': + break; + default: + sprintf(g->Message, "Unexpected character '%c' near %.*s", + s[i], ARGS); + throw 2; + }; // endswitch s[i] + + strcpy(g->Message, "Unexpected EOF in Object"); + throw 2; +} // end of ParseObject + +/***********************************************************************/ +/* Sub-allocate and initialize a BVAL. */ +/***********************************************************************/ +PBVAL BDOC::SubAllocVal(PGLOBAL g) +{ + PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); + + bvp->To_Val = 0; + bvp->Nd = 0; + bvp->Type = TYPE_UNKNOWN; + bvp->Next = 0; + return bvp; +} // end of SubAllocVal + +/***********************************************************************/ +/* Parse a JSON Value. */ +/***********************************************************************/ +PBVAL BDOC::ParseValue(PGLOBAL g, int& i) { + PBVAL bvp = SubAllocVal(g); + + for (; i < len; i++) + 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 '[': + bvp->To_Val = ParseArray(g, ++i); + bvp->Type = TYPE_JAR; + break; + case '{': + bvp->To_Val = ParseObject(g, ++i); + bvp->Type = TYPE_JOB; + break; + case '"': + // jvp->Val = AllocVal(g, TYPE_STRG); + bvp->To_Val = ParseString(g, ++i); + bvp->Type = TYPE_STRG; + break; + case 't': + if (!strncmp(s + i, "true", 4)) { + // jvp->Val = AllocVal(g, TYPE_BOOL); + bvp->B = true; + bvp->Type = TYPE_BOOL; + i += 3; + } else + goto err; + + break; + case 'f': + if (!strncmp(s + i, "false", 5)) { + // jvp->Val = AllocVal(g, TYPE_BOOL); + bvp->B = false; + bvp->Type = TYPE_BOOL; + i += 4; + } else + goto err; + + break; + case 'n': + if (!strncmp(s + i, "null", 4)) { + bvp->Type = TYPE_NULL; + i += 3; + } else + goto err; + + break; + case '-': + default: + if (s[i] == '-' || isdigit(s[i])) + ParseNumeric(g, i, bvp); + else + goto err; + + }; // endswitch s[i] + + return bvp; + +err: + sprintf(g->Message, "Unexpected character '%c' near %.*s", s[i], ARGS); + throw 3; +} // end of ParseValue + +/***********************************************************************/ +/* Unescape and parse a JSON string. */ +/***********************************************************************/ +OFFSET BDOC::ParseString(PGLOBAL g, int& i) { + uchar* p; + int n = 0; + + // Be sure of memory availability + if (((size_t)len + 1 - i) > ((PPOOLHEADER)g->Sarea)->FreeBlk) + throw("ParseString: Out of memory"); + + // The size to allocate is not known yet + p = (uchar*)PlugSubAlloc(g, NULL, 0); + + for (; i < len; i++) + switch (s[i]) { + case '"': + p[n++] = 0; + PlugSubAlloc(g, NULL, n); + return MakeOff(base, p); + case '\\': + if (++i < len) { + if (s[i] == 'u') { + if (len - i > 5) { + // if (charset == utf8) { + char xs[5]; + uint hex; + + xs[0] = s[++i]; + xs[1] = s[++i]; + xs[2] = s[++i]; + xs[3] = s[++i]; + xs[4] = 0; + hex = strtoul(xs, NULL, 16); + + if (hex < 0x80) { + p[n] = (uchar)hex; + } else if (hex < 0x800) { + p[n++] = (uchar)(0xC0 | (hex >> 6)); + p[n] = (uchar)(0x80 | (hex & 0x3F)); + } else if (hex < 0x10000) { + p[n++] = (uchar)(0xE0 | (hex >> 12)); + p[n++] = (uchar)(0x80 | ((hex >> 6) & 0x3f)); + p[n] = (uchar)(0x80 | (hex & 0x3f)); + } else + p[n] = '?'; + +#if 0 + } else { + char xs[3]; + UINT hex; + + i += 2; + xs[0] = s[++i]; + xs[1] = s[++i]; + xs[2] = 0; + hex = strtoul(xs, NULL, 16); + p[n] = (char)hex; + } // endif charset +#endif // 0 + } else + goto err; + + } else switch (s[i]) { + case 't': p[n] = '\t'; break; + case 'n': p[n] = '\n'; break; + case 'r': p[n] = '\r'; break; + case 'b': p[n] = '\b'; break; + case 'f': p[n] = '\f'; break; + default: p[n] = s[i]; break; + } // endswitch + + n++; + } else + goto err; + + break; + default: + p[n++] = s[i]; + break; +}; // endswitch s[i] + +err: +throw("Unexpected EOF in String"); +} // end of ParseString + +/***********************************************************************/ +/* Parse a JSON numeric value. */ +/***********************************************************************/ +void BDOC::ParseNumeric(PGLOBAL g, int& i, PBVAL vlp) { + char buf[50]; + int n = 0; + short nd = 0; + bool has_dot = false; + bool has_e = false; + bool found_digit = false; + + for (; i < len; i++) { + switch (s[i]) { + case '.': + if (!found_digit || has_dot || has_e) + goto err; + + has_dot = true; + break; + case 'e': + case 'E': + if (!found_digit || has_e) + goto err; + + has_e = true; + found_digit = false; + break; + case '+': + if (!has_e) + goto err; + + // fall through + case '-': + if (found_digit) + goto err; + + break; + default: + if (isdigit(s[i])) { + if (has_dot && !has_e) + nd++; // Number of decimals + + found_digit = true; + } else + goto fin; + + }; // endswitch s[i] + + buf[n++] = s[i]; + } // endfor i + +fin: + if (found_digit) { + buf[n] = 0; + + if (has_dot || has_e) { + double dv = strtod(buf, NULL); + + if (nd > 6) { + double* dvp = (double*)PlugSubAlloc(g, NULL, sizeof(double)); + + *dvp = dv; + vlp->To_Val = MakeOff(base, dvp); + vlp->Type = TYPE_DBL; + } else { + vlp->F = (float)dv; + vlp->Type = TYPE_FLOAT; + } // endif nd + + vlp->Nd = nd; + } else { + long long iv = strtoll(buf, NULL, 10); + + if (iv > INT_MAX32 || iv < INT_MIN32) { + long long *llp = (long long*)PlugSubAlloc(g, NULL, sizeof(long long)); + + *llp = iv; + vlp->To_Val = MakeOff(base, llp); + vlp->Type = TYPE_BINT; + } else { + vlp->N = (int)iv; + vlp->Type = TYPE_INTG; + } // endif iv + + } // endif has + + i--; // Unstack following character + return; + } else + throw("No digit found"); + +err: + throw("Unexpected EOF in number"); +} // end of ParseNumeric + +/***********************************************************************/ +/* Serialize a JSON document tree: */ +/***********************************************************************/ +PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { + PSZ str = NULL; + bool b = false, err = true; + JOUT* jp; + FILE* fs = NULL; + + g->Message[0] = 0; + + try { + if (!bvp) { + 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 (bvp->Type) { + case TYPE_JAR: + err = SerializeArray(bvp->To_Val, b); + break; + case TYPE_JOB: + err = ((b && jp->Prty()) && jp->WriteChr('\t')); + err |= SerializeObject(bvp->To_Val); + break; + case TYPE_JVAL: + err = SerializeValue((PBVAL)MakePtr(base, bvp->To_Val)); + 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 BDOC::SerializeArray(OFFSET arp, bool b) { + bool first = true; + PBVAL vp = (PBVAL)MakePtr(base, arp); + + if (b) { + if (jp->Prty()) { + if (jp->WriteChr('[')) + return true; + else if (jp->Prty() == 1 && (jp->WriteStr(EL) || jp->WriteChr('\t'))) + return true; + + } // endif Prty + + } else if (jp->WriteChr('[')) + return true; + + for (vp; vp; vp = (PBVAL)MakePtr(base, vp->Next)) { + if (first) + first = false; + else if ((!b || jp->Prty()) && jp->WriteChr(',')) + return true; + else if (b) { + if (jp->Prty() < 2 && jp->WriteStr(EL)) + return true; + else if (jp->Prty() == 1 && jp->WriteChr('\t')) + return true; + + } // endif b + + if (SerializeValue(vp)) + return true; + + } // endfor i + + if (b && jp->Prty() == 1 && jp->WriteStr(EL)) + return true; + + return ((!b || jp->Prty()) && jp->WriteChr(']')); +} // end of SerializeArray + +/***********************************************************************/ +/* Serialize a JSON Object. */ +/***********************************************************************/ +bool BDOC::SerializeObject(OFFSET obp) { + bool first = true; + PBPR prp = (PBPR)MakePtr(base, obp); + + if (jp->WriteChr('{')) + return true; + + for (prp; prp; prp = (PBPR)MakePtr(base, prp->Next)) { + if (first) + first = false; + else if (jp->WriteChr(',')) + return true; + + if (jp->WriteChr('"') || + jp->WriteStr((const char*)MakePtr(base, prp->Key)) || + jp->WriteChr('"') || + jp->WriteChr(':') || + SerializeValue((PBVAL)MakePtr(base, prp->Vlp))) + return true; + + } // endfor i + + return jp->WriteChr('}'); +} // end of SerializeObject + +/***********************************************************************/ +/* Serialize a JSON Value. */ +/***********************************************************************/ +bool BDOC::SerializeValue(PBVAL jvp) { + char buf[64]; + + switch (jvp->Type) { + case TYPE_JAR: + return SerializeArray(jvp->To_Val, false); + case TYPE_JOB: + return SerializeObject(jvp->To_Val); + case TYPE_BOOL: + return jp->WriteStr(jvp->B ? "true" : "false"); + case TYPE_STRG: + case TYPE_DTM: + return jp->Escape((const char*)MakePtr(base, jvp->To_Val)); + case TYPE_INTG: + sprintf(buf, "%d", jvp->N); + return jp->WriteStr(buf); + case TYPE_BINT: + sprintf(buf, "%lld", *(long long*)MakePtr(base, jvp->To_Val)); + return jp->WriteStr(buf); + case TYPE_FLOAT: + sprintf(buf, "%.*f", jvp->Nd, jvp->F); + return jp->WriteStr(buf); + case TYPE_DBL: + sprintf(buf, "%.*lf", jvp->Nd, *(double*)MakePtr(base, jvp->To_Val)); + return jp->WriteStr(buf); + case TYPE_NULL: + return jp->WriteStr("null"); + default: + return jp->WriteStr("???"); // TODO + } // endswitch Type + + strcpy(jp->g->Message, "Unrecognized value"); + return true; +} // end of SerializeValue + +#if 0 +/* -------------------------- 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)); + + jpp->Key = key; + jpp->Next = NULL; + jpp->Val = NULL; + + if (Last) + Last->Next = jpp; + else + First = jpp; + + Last = jpp; + return jpp; +} // end of AddPair + +/***********************************************************************/ +/* Return all keys as an array. */ +/***********************************************************************/ +PJAR JOBJECT::GetKeyList(PGLOBAL g) { + PJAR jarp = new(g) JARRAY(); + + for (PJPR jpp = First; jpp; jpp = jpp->Next) + jarp->AddArrayValue(g, new(g) JVALUE(g, jpp->Key)); + + jarp->InitArray(g); + return jarp; +} // end of GetKeyList + +/***********************************************************************/ +/* Return all values as an array. */ +/***********************************************************************/ +PJAR JOBJECT::GetValList(PGLOBAL g) { + PJAR jarp = new(g) JARRAY(); + + for (PJPR jpp = First; jpp; jpp = jpp->Next) + jarp->AddArrayValue(g, jpp->Val); + + jarp->InitArray(g); + return jarp; +} // end of GetValList + +/***********************************************************************/ +/* Get the value corresponding to the given key. */ +/***********************************************************************/ +PJVAL JOBJECT::GetKeyValue(const char* 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"); + + } // endif text + + } else for (PJPR jp = First; jp; jp = jp->Next) { + jp->Val->GetText(g, text); + + if (jp->Next) + text->Append(' '); + + } // endfor jp + + if (b) { + text->Trim(); + return text->GetStr(); + } // endif b + + } // endif First + + return NULL; +} // end of GetText; + +/***********************************************************************/ +/* Merge two objects. */ +/***********************************************************************/ +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 + + PJOB jobp = (PJOB)jsp; + + for (PJPR jpp = jobp->First; jpp; jpp = jpp->Next) + SetKeyValue(g, jpp->Val, jpp->Key); + + return false; +} // end of Marge; + +/***********************************************************************/ +/* 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 + + if (!jp) { + jp = AddPair(g, key); + jp->Val = jvp; + } // endif jp + +} // end of SetValue + +/***********************************************************************/ +/* Delete a value corresponding to the given key. */ +/***********************************************************************/ +void JOBJECT::DeleteKey(PCSZ key) { + PJPR jp, * pjp = &First; + + for (jp = First; jp; jp = jp->Next) + if (!strcmp(jp->Key, key)) { + *pjp = jp->Next; + break; + } else + pjp = &jp->Next; + +} // end of DeleteKey + +/***********************************************************************/ +/* 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()) + return false; + + return true; +} // 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]; + 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; + else if (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) { + strcpy(g->Message, "Second argument is not an array"); + return true; + } // endif Type + + PJAR arp = (PJAR)jsp; + + for (int i = 0; i < arp->size(); i++) + AddArrayValue(g, arp->GetArrayValue(i)); + + InitArray(g); + return false; +} // end of Merge + +/***********************************************************************/ +/* Set the nth Value of the Array Value list. */ +/***********************************************************************/ +bool 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); + return false; +} // 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('('); + + b = false; + } + + for (jp = First; jp; jp = jp->Next) { + jp->GetText(g, text); + + if (jp->Next) + text->Append(", "); + else if (!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; + return false; + } else + return true; + +} // 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()) + return false; + + return true; +} // end of IsNull + +/* -------------------------- Class JVALUE- -------------------------- */ + +/***********************************************************************/ +/* Constructor for a JVALUE. */ +/***********************************************************************/ +JVALUE::JVALUE(PJSON jsp) : JSON() { + 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; + Type = TYPE_JVAL; +} // end of JVALUE constructor + +#if 0 +/***********************************************************************/ +/* 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; + +} // end of GetValType + +/***********************************************************************/ +/* Return the Value's Object value. */ +/***********************************************************************/ +PJOB JVALUE::GetObject(void) { + if (DataType == TYPE_JSON && Jsp->GetType() == TYPE_JOB) + return (PJOB)Jsp; + + return NULL; +} // end of GetObject + +/***********************************************************************/ +/* Return the Value's Array value. */ +/***********************************************************************/ +PJAR JVALUE::GetArray(void) { + if (DataType == TYPE_JSON && Jsp->GetType() == TYPE_JAR) + return (PJAR)Jsp; + + return NULL; +} // end of GetArray + +/***********************************************************************/ +/* Return the Value's as a Value class. */ +/***********************************************************************/ +PVAL JVALUE::GetValue(PGLOBAL g) { + 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 + +/***********************************************************************/ +/* Return the Value's Big integer value. */ +/***********************************************************************/ +long long JVALUE::GetBigint(void) { + 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 + +/***********************************************************************/ +/* Return the Value's Double value. */ +/***********************************************************************/ +double JVALUE::GetFloat(void) { + 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, char* buff) { + 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, PSTRG text) { + if (DataType == TYPE_JSON) + return Jsp->GetText(g, text); + + char buff[32]; + PSZ s = (DataType == TYPE_NULL) ? NULL : GetString(g, buff); + + if (s) + text->Append(s); + else if (GetJsonNull()) + text->Append(GetJsonNull()); + + return NULL; +} // end of GetText + +void JVALUE::SetValue(PJSON jsp) { + 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 = valp->GetCharValue(); + else { + char buf[32]; + + Strp = PlugDup(g, valp->GetCharString(buf)); + } // endif Formatted + + DataType = TYPE_DTM; + break; + case TYPE_STRING: + Strp = 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 + +/***********************************************************************/ +/* 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, long long 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 = 6; + 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 +#endif // 0 -- cgit v1.2.1 From dc8f914c383366d11b6a995ba184b99d5ec663cf Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Wed, 25 Nov 2020 12:56:45 +0100 Subject: Remove based enum not accepted by most gcc compilers --- storage/connect/bson.cpp | 1016 ++++++++++++++++++++++++++-------------------- 1 file changed, 586 insertions(+), 430 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 86825f5808e..2f380752c0d 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -21,8 +21,6 @@ #include "plgdbsem.h" #include "bson.h" -#define ARGS MY_MIN(24,(int)len-i),s+MY_MAX(i-3,0) - #if defined(__WIN__) #define EL "\r\n" #else @@ -89,43 +87,14 @@ char* NextChr(PSZ s, char sep) { /***********************************************************************/ /* BDOC constructor. */ /***********************************************************************/ -BDOC::BDOC(void) : jp(NULL), base(NULL), s(NULL), len(0) +BDOC::BDOC(void *base) : BJSON(base, NULL) { + jp = NULL; + s = NULL; + len = 0; pty[0] = pty[1] = pty[2] = true; } // end of BDOC constructor -/***********************************************************************/ -/* Program for sub-allocating Bson structures. */ -/***********************************************************************/ -void* BDOC::BsonSubAlloc(PGLOBAL g, size_t size) { - PPOOLHEADER pph; /* Points on area header. */ - void* memp = g->Sarea; - - size = ((size + 3) / 4) * 4; /* Round up size to multiple of 4 */ - pph = (PPOOLHEADER)memp; - - xtrc(16, "SubAlloc in %p size=%zd used=%zd free=%zd\n", - memp, size, pph->To_Free, pph->FreeBlk); - - if (size > pph->FreeBlk) { /* Not enough memory left in pool */ - sprintf(g->Message, - "Not enough memory for request of %zd (used=%zd free=%zd)", - size, pph->To_Free, pph->FreeBlk); - xtrc(1, "BsonSubAlloc: %s\n", g->Message); - throw(1234); - } /* endif size OS32 code */ - - // Do the suballocation the simplest way - memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */ - pph->To_Free += size; /* New offset of pool free block */ - pph->FreeBlk -= size; /* New size of pool free block */ - xtrc(16, "Done memp=%p used=%zd free=%zd\n", - memp, pph->To_Free, pph->FreeBlk); - return memp; -} /* end of BsonSubAlloc */ - - - /***********************************************************************/ /* Parse a json string. */ /* Note: when pretty is not known, the caller set pretty to 3. */ @@ -133,9 +102,10 @@ void* BDOC::BsonSubAlloc(PGLOBAL g, size_t size) { PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { int i, pretty = (ptyp) ? *ptyp : 3; bool b = false; - PBVAL bvp = NULL; - xtrc(1, "ParseJson: s=%.10s len=%zd\n", s, len); + s = js; + len = lng; + xtrc(1, "BDOC::ParseJson: s=%.10s len=%zd\n", s, len); if (!s || !len) { strcpy(g->Message, "Void JSON object"); @@ -147,30 +117,26 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n'))) pty[0] = false; - s = js; - len = lng; - try { - bvp = (PBVAL)PlugSubAlloc(g, NULL, sizeof(BVAL)); - bvp->Type = TYPE_UNKNOWN; - base = bvp; + Bvp = SubAllocVal(g); + Bvp->Type = TYPE_UNKNOWN; for (i = 0; i < len; i++) switch (s[i]) { case '[': - if (bvp->Type != TYPE_UNKNOWN) - bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + if (Bvp->Type != TYPE_UNKNOWN) + Bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); else - bvp->To_Val = ParseArray(g, ++i); + Bvp->To_Val = ParseArray(g, ++i); - bvp->Type = TYPE_JAR; + Bvp->Type = TYPE_JAR; break; case '{': - if (bvp->Type != TYPE_UNKNOWN) { - bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); - bvp->Type = TYPE_JAR; - } else if ((bvp->To_Val = ParseObject(g, ++i))) - bvp->Type = TYPE_JOB; + if (Bvp->Type != TYPE_UNKNOWN) { + Bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + Bvp->Type = TYPE_JAR; + } else if ((Bvp->To_Val = ParseObject(g, ++i))) + Bvp->Type = TYPE_JOB; else throw 2; @@ -181,7 +147,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { case '\r': break; case ',': - if (bvp->Type != TYPE_UNKNOWN && (pretty == 1 || pretty == 3)) { + if (Bvp->Type != TYPE_UNKNOWN && (pretty == 1 || pretty == 3)) { if (comma) *comma = true; @@ -201,18 +167,18 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { } // endif b default: - if (bvp->Type != TYPE_UNKNOWN) { - bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); - bvp->Type = TYPE_JAR; - } else if ((bvp->To_Val = MakeOff(base, ParseValue(g, i)))) - bvp->Type = TYPE_JVAL; + if (Bvp->Type != TYPE_UNKNOWN) { + Bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + Bvp->Type = TYPE_JAR; + } else if ((Bvp->To_Val = MOF(ParseValue(g, i)))) + Bvp->Type = TYPE_JVAL; else throw 4; break; }; // endswitch s[i] - if (bvp->Type == TYPE_UNKNOWN) + if (Bvp->Type == TYPE_UNKNOWN) sprintf(g->Message, "Invalid Json string '%.*s'", MY_MIN((int)len, 50), s); else if (ptyp && pretty == 3) { *ptyp = 3; // Not recognized pretty @@ -228,13 +194,13 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { } catch (int n) { if (trace(1)) htrc("Exception %d: %s\n", n, g->Message); - bvp = NULL; + Bvp = NULL; } catch (const char* msg) { strcpy(g->Message, msg); - bvp = NULL; + Bvp = NULL; } // end catch - return bvp; + return Bvp; } // end of ParseJson /***********************************************************************/ @@ -280,7 +246,7 @@ OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { throw 1; } // endif level - return MakeOff(base, vlp); + return MOF(firstvlp); case '\n': if (!b) pty[0] = pty[1] = false; @@ -294,7 +260,7 @@ OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { throw 1; } else if (lastvlp) { vlp = ParseValue(g, i); - lastvlp->Next = MakeOff(base, vlp); + lastvlp->Next = MOF(vlp); lastvlp = vlp; } else firstvlp = lastvlp = ParseValue(g, i); @@ -305,25 +271,12 @@ OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { if (b) { // Case of Pretty == 0 - return MakeOff(base, vlp); + return MOF(firstvlp); } // endif b throw ("Unexpected EOF in array"); } // end of ParseArray -/***********************************************************************/ -/* Sub-allocate and initialize a BPAIR. */ -/***********************************************************************/ -PBPR BDOC::SubAllocPair(PGLOBAL g, OFFSET key) -{ - PBPR bpp = (PBPR)BsonSubAlloc(g, sizeof(BPAIR)); - - bpp->Key = key; - bpp->Vlp = 0; - bpp->Next = 0; - return bpp; -} // end of SubAllocPair - /***********************************************************************/ /* Parse a JSON Object. */ /***********************************************************************/ @@ -342,7 +295,7 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { bpp = SubAllocPair(g, key); if (lastbpp) { - lastbpp->Next = MakeOff(base, bpp); + lastbpp->Next = MOF(bpp); lastbpp = bpp; } else firstbpp = lastbpp = bpp; @@ -356,7 +309,7 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { break; case ':': if (level == 1) { - lastbpp->Vlp = MakeOff(base, ParseValue(g, ++i)); + lastbpp->Vlp = MOF(ParseValue(g, ++i)); level = 2; } else { sprintf(g->Message, "Unexpected ':' near %.*s", ARGS); @@ -378,7 +331,7 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { throw 2; } // endif level - return MakeOff(base, firstbpp); + return MOF(firstbpp); case '\n': pty[0] = pty[1] = false; case '\r': @@ -395,20 +348,6 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { throw 2; } // end of ParseObject -/***********************************************************************/ -/* Sub-allocate and initialize a BVAL. */ -/***********************************************************************/ -PBVAL BDOC::SubAllocVal(PGLOBAL g) -{ - PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); - - bvp->To_Val = 0; - bvp->Nd = 0; - bvp->Type = TYPE_UNKNOWN; - bvp->Next = 0; - return bvp; -} // end of SubAllocVal - /***********************************************************************/ /* Parse a JSON Value. */ /***********************************************************************/ @@ -505,7 +444,7 @@ OFFSET BDOC::ParseString(PGLOBAL g, int& i) { case '"': p[n++] = 0; PlugSubAlloc(g, NULL, n); - return MakeOff(base, p); + return MOF(p); case '\\': if (++i < len) { if (s[i] == 'u') { @@ -634,7 +573,7 @@ fin: double* dvp = (double*)PlugSubAlloc(g, NULL, sizeof(double)); *dvp = dv; - vlp->To_Val = MakeOff(base, dvp); + vlp->To_Val = MOF(dvp); vlp->Type = TYPE_DBL; } else { vlp->F = (float)dv; @@ -643,13 +582,13 @@ fin: vlp->Nd = nd; } else { - long long iv = strtoll(buf, NULL, 10); + longlong iv = strtoll(buf, NULL, 10); if (iv > INT_MAX32 || iv < INT_MIN32) { - long long *llp = (long long*)PlugSubAlloc(g, NULL, sizeof(long long)); + longlong *llp = (longlong*)PlugSubAlloc(g, NULL, sizeof(longlong)); *llp = iv; - vlp->To_Val = MakeOff(base, llp); + vlp->To_Val = MOF(llp); vlp->Type = TYPE_BINT; } else { vlp->N = (int)iv; @@ -668,12 +607,11 @@ err: } // end of ParseNumeric /***********************************************************************/ -/* Serialize a JSON document tree: */ +/* Serialize a BJSON document tree: */ /***********************************************************************/ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { PSZ str = NULL; bool b = false, err = true; - JOUT* jp; FILE* fs = NULL; g->Message[0] = 0; @@ -712,7 +650,7 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { err |= SerializeObject(bvp->To_Val); break; case TYPE_JVAL: - err = SerializeValue((PBVAL)MakePtr(base, bvp->To_Val)); + err = SerializeValue(MVP(bvp->To_Val)); break; default: strcpy(g->Message, "Invalid json tree"); @@ -750,7 +688,7 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { /***********************************************************************/ bool BDOC::SerializeArray(OFFSET arp, bool b) { bool first = true; - PBVAL vp = (PBVAL)MakePtr(base, arp); + PBVAL vp = MVP(arp); if (b) { if (jp->Prty()) { @@ -764,7 +702,7 @@ bool BDOC::SerializeArray(OFFSET arp, bool b) { } else if (jp->WriteChr('[')) return true; - for (vp; vp; vp = (PBVAL)MakePtr(base, vp->Next)) { + for (vp; vp; vp = MVP(vp->Next)) { if (first) first = false; else if ((!b || jp->Prty()) && jp->WriteChr(',')) @@ -780,7 +718,7 @@ bool BDOC::SerializeArray(OFFSET arp, bool b) { if (SerializeValue(vp)) return true; - } // endfor i + } // endfor vp if (b && jp->Prty() == 1 && jp->WriteStr(EL)) return true; @@ -793,22 +731,22 @@ bool BDOC::SerializeArray(OFFSET arp, bool b) { /***********************************************************************/ bool BDOC::SerializeObject(OFFSET obp) { bool first = true; - PBPR prp = (PBPR)MakePtr(base, obp); + PBPR prp = MPP(obp); if (jp->WriteChr('{')) return true; - for (prp; prp; prp = (PBPR)MakePtr(base, prp->Next)) { + for (prp; prp; prp = MPP(prp->Next)) { if (first) first = false; else if (jp->WriteChr(',')) return true; if (jp->WriteChr('"') || - jp->WriteStr((const char*)MakePtr(base, prp->Key)) || + jp->WriteStr(MZP(prp->Key)) || jp->WriteChr('"') || jp->WriteChr(':') || - SerializeValue((PBVAL)MakePtr(base, prp->Vlp))) + SerializeValue(MVP(prp->Vlp))) return true; } // endfor i @@ -831,18 +769,18 @@ bool BDOC::SerializeValue(PBVAL jvp) { return jp->WriteStr(jvp->B ? "true" : "false"); case TYPE_STRG: case TYPE_DTM: - return jp->Escape((const char*)MakePtr(base, jvp->To_Val)); + return jp->Escape(MZP(jvp->To_Val)); case TYPE_INTG: sprintf(buf, "%d", jvp->N); return jp->WriteStr(buf); case TYPE_BINT: - sprintf(buf, "%lld", *(long long*)MakePtr(base, jvp->To_Val)); + sprintf(buf, "%lld", *(longlong*)MakePtr(Base, jvp->To_Val)); return jp->WriteStr(buf); case TYPE_FLOAT: sprintf(buf, "%.*f", jvp->Nd, jvp->F); return jp->WriteStr(buf); case TYPE_DBL: - sprintf(buf, "%.*lf", jvp->Nd, *(double*)MakePtr(base, jvp->To_Val)); + sprintf(buf, "%.*lf", jvp->Nd, *(double*)MakePtr(Base, jvp->To_Val)); return jp->WriteStr(buf); case TYPE_NULL: return jp->WriteStr("null"); @@ -854,84 +792,139 @@ bool BDOC::SerializeValue(PBVAL jvp) { return true; } // end of SerializeValue -#if 0 -/* -------------------------- Class JOBJECT -------------------------- */ +/* --------------------------- Class BJSON --------------------------- */ + +/***********************************************************************/ +/* Program for sub-allocating Bjson structures. */ +/***********************************************************************/ +void* BJSON::BsonSubAlloc(PGLOBAL g, size_t size) +{ + PPOOLHEADER pph; /* Points on area header. */ + void* memp = g->Sarea; + + size = ((size + 3) / 4) * 4; /* Round up size to multiple of 4 */ + pph = (PPOOLHEADER)memp; + + xtrc(16, "SubAlloc in %p size=%zd used=%zd free=%zd\n", + memp, size, pph->To_Free, pph->FreeBlk); + + if (size > pph->FreeBlk) { /* Not enough memory left in pool */ + sprintf(g->Message, + "Not enough memory for request of %zd (used=%zd free=%zd)", + size, pph->To_Free, pph->FreeBlk); + xtrc(1, "BsonSubAlloc: %s\n", g->Message); + throw(1234); + } /* endif size OS32 code */ + + // Do the suballocation the simplest way + memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */ + pph->To_Free += size; /* New offset of pool free block */ + pph->FreeBlk -= size; /* New size of pool free block */ + xtrc(16, "Done memp=%p used=%zd free=%zd\n", + memp, pph->To_Free, pph->FreeBlk); + return memp; +} /* end of BsonSubAlloc */ + +/* ------------------------ Bobject functions ------------------------ */ + +/***********************************************************************/ +/* Sub-allocate and initialize a BPAIR. */ +/***********************************************************************/ +PBPR BJSON::SubAllocPair(PGLOBAL g, OFFSET key, OFFSET val) +{ + PBPR bpp = (PBPR)BsonSubAlloc(g, sizeof(BPAIR)); + + bpp->Key = key; + bpp->Vlp = val; + bpp->Next = 0; + return bpp; +} // end of SubAllocPair /***********************************************************************/ /* Return the number of pairs in this object. */ /***********************************************************************/ -int JOBJECT::GetSize(bool b) { +int BJSON::GetObjectSize(PBPR bop, bool b) +{ int n = 0; - for (PJPR jpp = First; jpp; jpp = jpp->Next) + for (PBPR brp = bop; brp; brp = MPP(brp->Next)) // If b return only non null pairs - if (!b || jpp->Val && !jpp->Val->IsNull()) + if (!b || (brp->Vlp && (MVP(brp->Vlp))->Type != TYPE_NULL)) n++; return n; -} // end of GetSize +} // end of GetObjectSize /***********************************************************************/ -/* Add a new pair to an Object. */ +/* Add a new pair to an Object and return it. */ /***********************************************************************/ -PJPR JOBJECT::AddPair(PGLOBAL g, PCSZ key) { - PJPR jpp = (PJPR)PlugSubAlloc(g, NULL, sizeof(JPAIR)); +PBPR BJSON::AddPair(PGLOBAL g, PBPR bop, PSZ key, OFFSET val) +{ + PBPR brp, nrp = SubAllocPair(g, MOF(key), val); - jpp->Key = key; - jpp->Next = NULL; - jpp->Val = NULL; + if (bop) { + for (brp = bop; brp->Next; brp = MPP(brp->Next)); - if (Last) - Last->Next = jpp; - else - First = jpp; + brp->Next = MOF(nrp); + } else + bop = nrp; - Last = jpp; - return jpp; + return bop; } // end of AddPair /***********************************************************************/ -/* Return all keys as an array. */ +/* Return all object keys as an array. */ /***********************************************************************/ -PJAR JOBJECT::GetKeyList(PGLOBAL g) { - PJAR jarp = new(g) JARRAY(); +PBVAL BJSON::GetKeyList(PGLOBAL g, PBPR bop) +{ + PBVAL bvp, lvp, fvp = NULL; - for (PJPR jpp = First; jpp; jpp = jpp->Next) - jarp->AddArrayValue(g, new(g) JVALUE(g, jpp->Key)); + for (PBPR brp = bop; brp; brp = MPP(brp->Next)) + if (fvp) { + bvp = SubAllocVal(g, brp->Key, TYPE_STRG); + lvp->Next = MOF(bvp); + lvp = bvp; + } else + lvp = fvp = SubAllocVal(g, brp->Key, TYPE_STRG); - jarp->InitArray(g); - return jarp; + return fvp; } // end of GetKeyList /***********************************************************************/ -/* Return all values as an array. */ +/* Return all object values as an array. */ /***********************************************************************/ -PJAR JOBJECT::GetValList(PGLOBAL g) { - PJAR jarp = new(g) JARRAY(); +PBVAL BJSON::GetObjectValList(PGLOBAL g, PBPR bop) +{ + PBVAL bvp, lvp, fvp = NULL; - for (PJPR jpp = First; jpp; jpp = jpp->Next) - jarp->AddArrayValue(g, jpp->Val); + for (PBPR brp = bop; brp; brp = MPP(brp->Next)) + if (fvp) { + bvp = DupVal(g, MVP(brp->Vlp)); + lvp->Next = MOF(bvp); + lvp = bvp; + } else + lvp = fvp = DupVal(g, MVP(brp->Vlp)); - jarp->InitArray(g); - return jarp; -} // end of GetValList + return fvp; +} // end of GetObjectValList /***********************************************************************/ /* Get the value corresponding to the given key. */ /***********************************************************************/ -PJVAL JOBJECT::GetKeyValue(const char* key) { - for (PJPR jp = First; jp; jp = jp->Next) - if (!strcmp(jp->Key, key)) - return jp->Val; +PBVAL BJSON::GetKeyValue(PBPR bop, PSZ key) +{ + for (PBPR brp = bop; brp; brp = MPP(brp->Next)) + if (!strcmp(MZP(brp->Key), key)) + return MVP(brp->Vlp); return NULL; -} // end of GetValue; +} // end of GetKeyValue; /***********************************************************************/ /* Return the text corresponding to all keys (XML like). */ /***********************************************************************/ -PSZ JOBJECT::GetText(PGLOBAL g, PSTRG text) { - if (First) { +PSZ BJSON::GetObjectText(PGLOBAL g, PBPR bop, PSTRG text) { + if (bop) { bool b; if (!text) { @@ -944,7 +937,8 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSTRG text) { b = false; } // endif text - if (b && !First->Next && !strcmp(First->Key, "$date")) { +#if 0 + if (b && !bop->Next && !strcmp(MZP(bop->Key), "$date")) { int i; PSZ s; @@ -964,228 +958,211 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSTRG text) { } // endif text - } else for (PJPR jp = First; jp; jp = jp->Next) { - jp->Val->GetText(g, text); + } else +#endif // 0 - if (jp->Next) + for (PBPR brp = bop; brp; brp = MPP(brp->Next)) { + GetValueText(g, MVP(brp->Vlp), text); + + if (brp->Next) text->Append(' '); - } // endfor jp + } // endfor brp if (b) { text->Trim(); return text->GetStr(); } // endif b - } // endif First + } // endif bop return NULL; -} // end of GetText; +} // end of GetObjectText; /***********************************************************************/ -/* Merge two objects. */ +/* Set or add a value corresponding to the given key. */ /***********************************************************************/ -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 +PBPR BJSON::SetKeyValue(PGLOBAL g, PBPR bop, OFFSET bvp, PSZ key) +{ + PBPR brp = bop, prp = NULL; + + if (brp) { + for (brp = bop; brp; brp = MPP(brp->Next)) + if (!strcmp(MZP(brp->Key), key)) { + brp->Vlp = bvp; + break; + } else + prp = brp; - PJOB jobp = (PJOB)jsp; + if (!brp) + prp->Vlp = MOF(SubAllocPair(g, MOF(key), bvp)); - for (PJPR jpp = jobp->First; jpp; jpp = jpp->Next) - SetKeyValue(g, jpp->Val, jpp->Key); + } else + bop = SubAllocPair(g, MOF(key), bvp); - return false; -} // end of Marge; + // Return the first pair of this object + return bop; +} // end of SetKeyValue /***********************************************************************/ -/* Set or add a value corresponding to the given key. */ +/* Merge two objects. */ /***********************************************************************/ -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 +PBPR BJSON::MergeObject(PGLOBAL g, PBPR bop1, PBPR bop2) +{ + if (bop1) + for (PBPR brp = bop2; brp; brp = MPP(brp->Next)) + SetKeyValue(g, bop1, brp->Vlp, MZP(brp->Key)); - if (!jp) { - jp = AddPair(g, key); - jp->Val = jvp; - } // endif jp + else + bop1 = bop2; -} // end of SetValue + return bop1; +} // end of MergeObject; /***********************************************************************/ /* Delete a value corresponding to the given key. */ /***********************************************************************/ -void JOBJECT::DeleteKey(PCSZ key) { - PJPR jp, * pjp = &First; +PBPR BJSON::DeleteKey(PBPR bop, PCSZ key) +{ + PBPR brp, pbrp = NULL; + + for (brp = bop; brp; brp = MPP(brp->Next)) + if (!strcmp(MZP(brp->Key), key)) { + if (pbrp) { + pbrp->Next = brp->Next; + return bop; + } else + return MPP(brp->Next); - for (jp = First; jp; jp = jp->Next) - if (!strcmp(jp->Key, key)) { - *pjp = jp->Next; - break; } else - pjp = &jp->Next; + pbrp = brp; + return bop; } // end of DeleteKey /***********************************************************************/ /* 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()) +bool BJSON::IsObjectNull(PBPR bop) +{ + for (PBPR brp = bop; brp; brp = MPP(brp->Next)) + if (brp->Vlp && (MVP(brp->Vlp))->Type != TYPE_NULL) return false; return true; -} // end of IsNull +} // end of IsObjectNull -/* -------------------------- Class JARRAY --------------------------- */ - -/***********************************************************************/ -/* JARRAY constructor. */ -/***********************************************************************/ -JARRAY::JARRAY(void) : JSON() { - Type = TYPE_JAR; - Size = 0; - Alloc = 0; - First = Last = NULL; - Mvals = NULL; -} // end of JARRAY constructor +/* ------------------------- Barray functions ------------------------ */ /***********************************************************************/ /* 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++; +int BJSON::GetArraySize(PBVAL bap, bool b) +{ + int n = 0; - return n; - } else - return Size; + for (PBVAL bvp = bap; bvp; bvp = MVP(bvp->Next)) + // If b, return only non null values + if (!b || bvp->Type != TYPE_NULL) + n++; -} // end of GetSize + return n; +} // end of GetArraySize /***********************************************************************/ -/* Make the array of values from the values list. */ +/* Get the Nth value of an Array. */ /***********************************************************************/ -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; +PBVAL BJSON::GetArrayValue(PBVAL bap, int n) +{ + int i = 0; -} // end of InitArray + for (PBVAL bvp = bap; bvp; bvp = MVP(bvp->Next)) + if (i == n) + return bvp; + else + i++; -/***********************************************************************/ -/* Get the Nth value of an Array. */ -/***********************************************************************/ -PJVAL JARRAY::GetArrayValue(int i) { - if (Mvals && i >= 0 && i < Size) - return Mvals[i]; - else - return NULL; -} // end of GetValue + return NULL; +} // end of GetArrayValue /***********************************************************************/ /* Add a Value to the Array Value list. */ /***********************************************************************/ -PJVAL JARRAY::AddArrayValue(PGLOBAL g, PJVAL jvp, int* x) { - if (!jvp) - jvp = new(g) JVALUE; +PBVAL BJSON::AddArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int* x) +{ + if (!nvp) + nvp = SubAllocVal(g); - if (x) { + if (bap) { int i = 0, n = *x; - PJVAL jp, * jpp = &First; + PBVAL bvp; - for (jp = First; jp && i < n; i++, jp = *(jpp = &jp->Next)); - - (*jpp) = jvp; - - if (!(jvp->Next = jp)) - Last = jvp; - - } else { - if (!First) - First = jvp; - else if (Last == First) - First->Next = Last = jvp; - else - Last->Next = jvp; + for (bvp = bap; bvp; bvp = MVP(bvp->Next), i++) + if (!bvp->Next || (x && i == n)) { + nvp->Next = bvp->Next; + bvp->Next = MOF(nvp); + break; + } // endif Next - Last = jvp; - Last->Next = NULL; - } // endif x + } else + bap = nvp; - return jvp; -} // end of AddValue + return bap; +} // end of AddArrayValue /***********************************************************************/ /* Merge two arrays. */ /***********************************************************************/ -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 - - PJAR arp = (PJAR)jsp; +PBVAL BJSON::MergeArray(PGLOBAL g, PBVAL bap1, PBVAL bap2) +{ + if (bap1) { + for (PBVAL bvp = bap2; bvp; bvp = MVP(bvp->Next)) + AddArrayValue(g, bap1, bvp); - for (int i = 0; i < arp->size(); i++) - AddArrayValue(g, arp->GetArrayValue(i)); + return bap1; + } else + return bap2; - InitArray(g); - return false; -} // end of Merge +} // end of MergeArray /***********************************************************************/ -/* Set the nth Value of the Array Value list. */ +/* Set the nth Value of the Array Value list or add it. */ /***********************************************************************/ -bool JARRAY::SetArrayValue(PGLOBAL g, PJVAL jvp, int n) { - int i = 0; - PJVAL jp, * jpp = &First; +PBVAL BJSON::SetArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int n) +{ + PBVAL bvp = bap, pvp = NULL; + + if (bvp) { + for (int i = 0; bvp; i++, bvp = MVP(bvp->Next)) + if (i == n) { + bvp->To_Val = nvp->To_Val; + bvp->Nd = nvp->Nd; + bvp->Type = nvp->Type; + return bap; + } else + pvp = bvp; + + } // endif bap + + if (!bvp) { + bvp = DupVal(g, nvp); - for (jp = First; i < n; i++, jp = *(jpp = &jp->Next)) - if (!jp) - *jpp = jp = new(g) JVALUE; + if (pvp) + pvp->Next = MOF(bvp); + else + bap = bvp; + + } // endif bvp - *jpp = jvp; - jvp->Next = (jp ? jp->Next : NULL); - return false; + return bap; } // end of SetValue /***********************************************************************/ /* Return the text corresponding to all values. */ /***********************************************************************/ -PSZ JARRAY::GetText(PGLOBAL g, PSTRG text) { - if (First) { +PSZ BJSON::GetArrayText(PGLOBAL g, PBVAL bap, PSTRG text) { + if (bap) { bool b; - PJVAL jp; if (!text) { text = new(g) STRING(g, 256); @@ -1197,12 +1174,12 @@ PSZ JARRAY::GetText(PGLOBAL g, PSTRG text) { text->Append('('); b = false; - } + } // endif text - for (jp = First; jp; jp = jp->Next) { - jp->GetText(g, text); + for (PBVAL bvp = bap; bvp; bvp = MVP(bvp->Next)) { + GetValueText(g, bvp, text); - if (jp->Next) + if (bvp->Next) text->Append(", "); else if (!b) text->Append(')'); @@ -1222,30 +1199,89 @@ PSZ JARRAY::GetText(PGLOBAL g, PSTRG text) { /***********************************************************************/ /* Delete a Value from the Arrays Value list. */ /***********************************************************************/ -bool JARRAY::DeleteValue(int n) { - PJVAL jvp = GetArrayValue(n); +PBVAL BJSON::DeleteValue(PBVAL bap, int n) +{ + PBVAL bvp = bap, pvp = NULL; - if (jvp) { - jvp->Del = true; - return false; - } else - return true; + if (bvp) + for (int i = 0; bvp; i++, bvp = MVP(bvp->Next)) + if (i == n) { + if (pvp) + pvp->Next = bvp->Next; + else + bap = bvp; + + break; + } // endif i + return bap; } // 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()) +bool BJSON::IsArrayNull(PBVAL bap) +{ + for (PBVAL bvp = bap; bvp; bvp = MVP(bvp->Next)) + if (bvp->Type != TYPE_NULL) return false; return true; } // end of IsNull -/* -------------------------- Class JVALUE- -------------------------- */ +/* ------------------------- Bvalue functions ------------------------ */ + +/***********************************************************************/ +/* Sub-allocate and clear a BVAL. */ +/***********************************************************************/ +PBVAL BJSON::SubAllocVal(PGLOBAL g) +{ + PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); + + bvp->To_Val = 0; + bvp->Nd = 0; + bvp->Type = TYPE_UNKNOWN; + bvp->Next = 0; + return bvp; +} // end of SubAllocVal + +/***********************************************************************/ +/* Sub-allocate and initialize a BVAL as string. */ +/***********************************************************************/ +PBVAL BJSON::SubAllocVal(PGLOBAL g, OFFSET toval, JTYP type, short nd) +{ + PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); + + bvp->To_Val = toval; + bvp->Nd = nd; + bvp->Type = type; + bvp->Next = 0; + return bvp; +} // end of SubAllocVal +/***********************************************************************/ +/* Allocate a BVALUE with a given string or numeric value. */ +/***********************************************************************/ +PBVAL BJSON::SubAllocVal(PGLOBAL g, PVAL valp) +{ + PBVAL vlp = SubAllocVal(g); + SetValue(g, vlp, valp); + vlp->Next = NULL; + return vlp; +} // end of SubAllocVal + +/***********************************************************************/ +/* Sub-allocate and initialize a BVAL from another BVAL. */ +/***********************************************************************/ +PBVAL BJSON::DupVal(PGLOBAL g, PBVAL bvlp) { + PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); + + *bvp = *bvlp; + bvp->Next = 0; + return bvp; +} // end of DupVal + +#if 0 /***********************************************************************/ /* Constructor for a JVALUE. */ /***********************************************************************/ @@ -1276,7 +1312,6 @@ JVALUE::JVALUE(PJSON jsp) : JSON() { Type = TYPE_JVAL; } // end of JVALUE constructor -#if 0 /***********************************************************************/ /* Constructor for a JVALUE with a given string or numeric value. */ /***********************************************************************/ @@ -1289,18 +1324,7 @@ JVALUE::JVALUE(PGLOBAL g, PVL vlp) : JSON() { } // 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 - +#if 0 /***********************************************************************/ /* Constructor for a given string. */ /***********************************************************************/ @@ -1339,13 +1363,31 @@ JTYP JVALUE::GetValType(void) { return DataType; } // end of GetValType +#endif // 0 + +/***********************************************************************/ +/* Return the size of value's value. */ +/***********************************************************************/ +int BJSON::GetSize(PBVAL vlp, bool b) +{ + switch (vlp->Type) { + case TYPE_JAR: + return GetArraySize(MVP(vlp->To_Val)); + case TYPE_JOB: + return GetObjectSize(MPP(vlp->To_Val)); + default: + return 1; + } // enswitch Type + +} // end of GetSize /***********************************************************************/ /* Return the Value's Object value. */ /***********************************************************************/ -PJOB JVALUE::GetObject(void) { - if (DataType == TYPE_JSON && Jsp->GetType() == TYPE_JOB) - return (PJOB)Jsp; +PBPR BJSON::GetObject(PBVAL vlp) +{ + if (vlp->Type == TYPE_JOB) + return MPP(vlp->To_Val); return NULL; } // end of GetObject @@ -1353,24 +1395,41 @@ PJOB JVALUE::GetObject(void) { /***********************************************************************/ /* Return the Value's Array value. */ /***********************************************************************/ -PJAR JVALUE::GetArray(void) { - if (DataType == TYPE_JSON && Jsp->GetType() == TYPE_JAR) - return (PJAR)Jsp; +PBVAL BJSON::GetArray(PBVAL vlp) +{ + if (vlp->Type == TYPE_JAR) + return MVP(vlp->To_Val); return NULL; } // end of GetArray /***********************************************************************/ -/* Return the Value's as a Value class. */ +/* Return the Value's as a Value struct. */ /***********************************************************************/ -PVAL JVALUE::GetValue(PGLOBAL g) { - PVAL valp = NULL; +PVAL BJSON::GetValue(PGLOBAL g, PBVAL vp) +{ + double d; + PVAL valp; + PBVAL vlp = vp->Type == TYPE_JVAL ? MVP(vp->To_Val) : vp; - if (DataType != TYPE_JSON) - if (DataType == TYPE_STRG) - valp = AllocateValue(g, Strp, DataType, Nd); - else - valp = AllocateValue(g, &LLn, DataType, Nd); + switch (vlp->Type) { + case TYPE_STRG: + case TYPE_DBL: + case TYPE_BINT: + valp = AllocateValue(g, MP(vlp->To_Val), vlp->Type, vlp->Nd); + break; + case TYPE_INTG: + case TYPE_BOOL: + valp = AllocateValue(g, vlp, vlp->Type); + break; + case TYPE_FLOAT: + d = (double)vlp->F; + valp = AllocateValue(g, &d, TYPE_DOUBLE, vlp->Nd); + break; + default: + valp = NULL; + break; + } // endswitch Type return valp; } // end of GetValue @@ -1378,16 +1437,30 @@ PVAL JVALUE::GetValue(PGLOBAL g) { /***********************************************************************/ /* Return the Value's Integer value. */ /***********************************************************************/ -int JVALUE::GetInteger(void) { - int n; +int BJSON::GetInteger(PBVAL vp) { + int n; + PBVAL vlp = (vp->Type == TYPE_JVAL) ? MVP(vp->To_Val) : vp; - switch (DataType) { - case TYPE_INTG: n = N; break; - case TYPE_DBL: n = (int)F; break; + switch (vlp->Type) { + case TYPE_INTG: + n = vlp->N; + break; + case TYPE_FLOAT: + n = (int)vlp->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; + case TYPE_STRG: + n = atoi(MZP(vlp->To_Val)); + break; + case TYPE_BOOL: + n = (vlp->B) ? 1 : 0; + break; + case TYPE_BINT: + n = (int)*(longlong*)MP(vlp->To_Val); + break; + case TYPE_DBL: + n = (int)*(double*)MP(vlp->To_Val); + break; default: n = 0; } // endswitch Type @@ -1398,16 +1471,30 @@ int JVALUE::GetInteger(void) { /***********************************************************************/ /* Return the Value's Big integer value. */ /***********************************************************************/ -long long JVALUE::GetBigint(void) { - long long lln; +longlong BJSON::GetBigint(PBVAL vp) { + longlong lln; + PBVAL vlp = (vp->Type == TYPE_JVAL) ? MVP(vp->To_Val) : vp; - switch (DataType) { - case TYPE_BINT: lln = LLn; break; - case TYPE_INTG: lln = (long long)N; break; - case TYPE_DBL: lln = (long long)F; break; + switch (vlp->Type) { + case TYPE_BINT: + lln = *(longlong*)MP(vlp->To_Val); + break; + case TYPE_INTG: + lln = (longlong)vlp->N; + break; + case TYPE_FLOAT: + lln = (longlong)vlp->F; + break; + case TYPE_DBL: + lln = (longlong)*(double*)MP(vlp->To_Val); + break; case TYPE_DTM: - case TYPE_STRG: lln = atoll(Strp); break; - case TYPE_BOOL: lln = (B) ? 1 : 0; break; + case TYPE_STRG: + lln = atoll(MZP(vlp->To_Val)); + break; + case TYPE_BOOL: + lln = (vlp->B) ? 1 : 0; + break; default: lln = 0; } // endswitch Type @@ -1418,16 +1505,31 @@ long long JVALUE::GetBigint(void) { /***********************************************************************/ /* Return the Value's Double value. */ /***********************************************************************/ -double JVALUE::GetFloat(void) { +double BJSON::GetDouble(PBVAL vp) +{ double d; + PBVAL vlp = (vp->Type == TYPE_JVAL) ? MVP(vp->To_Val) : vp; - switch (DataType) { - case TYPE_DBL: d = F; break; - case TYPE_BINT: d = (double)LLn; break; - case TYPE_INTG: d = (double)N; break; + switch (vlp->Type) { + case TYPE_DBL: + d = *(double*)MP(vlp->To_Val); + break; + case TYPE_BINT: + d = (double)*(longlong*)MP(vlp->To_Val); + break; + case TYPE_INTG: + d = (double)vlp->N; + break; + case TYPE_FLOAT: + d = (double)vlp->F; + break; case TYPE_DTM: - case TYPE_STRG: d = atof(Strp); break; - case TYPE_BOOL: d = (B) ? 1.0 : 0.0; break; + case TYPE_STRG: + d = atof(MZP(vlp->To_Val)); + break; + case TYPE_BOOL: + d = (vlp->B) ? 1.0 : 0.0; + break; default: d = 0.0; } // endswitch Type @@ -1438,47 +1540,53 @@ double JVALUE::GetFloat(void) { /***********************************************************************/ /* Return the Value's String value. */ /***********************************************************************/ -PSZ JVALUE::GetString(PGLOBAL g, char* buff) { +PSZ BJSON::GetString(PGLOBAL g, PBVAL vp, char* buff) +{ char buf[32]; char* p = (buff) ? buff : buf; + PBVAL vlp = (vp->Type == TYPE_JVAL) ? MVP(vp->To_Val) : vp; - switch (DataType) { + switch (vlp->Type) { case TYPE_DTM: case TYPE_STRG: - p = Strp; + p = MZP(vlp->To_Val); break; case TYPE_INTG: - sprintf(p, "%d", N); + sprintf(p, "%d", vlp->N); + break; + case TYPE_FLOAT: + sprintf(p, "%.*f", vlp->Nd, vlp->F); break; case TYPE_BINT: - sprintf(p, "%lld", LLn); + sprintf(p, "%lld", *(longlong*)MP(vlp->To_Val)); break; case TYPE_DBL: - sprintf(p, "%.*lf", Nd, F); + sprintf(p, "%.*lf", vlp->Nd, *(double*)MP(vlp->To_Val)); break; case TYPE_BOOL: - p = (char*)((B) ? "true" : "false"); + p = (PSZ)((vlp->B) ? "true" : "false"); break; case TYPE_NULL: - p = (char*)"null"; + p = (PSZ)"null"; break; default: p = NULL; } // endswitch Type - - return (p == buf) ? (char*)PlugDup(g, buf) : p; + return (p == buf) ? (PSZ)PlugDup(g, buf) : p; } // end of GetString /***********************************************************************/ /* Return the Value's String value. */ /***********************************************************************/ -PSZ JVALUE::GetText(PGLOBAL g, PSTRG text) { - if (DataType == TYPE_JSON) - return Jsp->GetText(g, text); +PSZ BJSON::GetValueText(PGLOBAL g, PBVAL vlp, PSTRG text) { + if (vlp->Type == TYPE_JOB) + return GetObjectText(g, MPP(vlp->To_Val), text); + else if (vlp->Type == TYPE_JAR) + return GetArrayText(g, MVP(vlp->To_Val), text); char buff[32]; - PSZ s = (DataType == TYPE_NULL) ? NULL : GetString(g, buff); + PSZ s = (vlp->Type == TYPE_NULL) ? NULL : GetString(g, vlp, buff); if (s) text->Append(s); @@ -1488,60 +1596,81 @@ PSZ JVALUE::GetText(PGLOBAL g, PSTRG text) { return NULL; } // end of GetText -void JVALUE::SetValue(PJSON jsp) { - 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 +void BJSON::SetValueObj(PBVAL vlp, PBPR bop) +{ + vlp->To_Val = MOF(bop); + vlp->Type = TYPE_JOB; +} // end of SetValueObj; +void BJSON::SetValueArr(PBVAL vlp, PBVAL bap) +{ + vlp->To_Val = MOF(bap); + vlp->Type = TYPE_JAR; } // end of SetValue; -void JVALUE::SetValue(PGLOBAL g, PVAL valp) { - //if (!Val) - // Val = AllocVal(g, TYPE_VAL); +void BJSON::SetValueVal(PBVAL vlp, PBVAL vp) +{ + vlp->To_Val = vp->To_Val; + vlp->Nd = vp->Nd; + vlp->Type = vp->Type; +} // end of SetValue; +void BJSON::SetValue(PGLOBAL g, PBVAL vlp, PVAL valp) +{ if (!valp || valp->IsNull()) { - DataType = TYPE_NULL; + vlp->Type = TYPE_NULL; } else switch (valp->GetType()) { case TYPE_DATE: if (((DTVAL*)valp)->IsFormatted()) - Strp = valp->GetCharValue(); + vlp->To_Val = MOF(valp->GetCharValue()); else { char buf[32]; - Strp = PlugDup(g, valp->GetCharString(buf)); + vlp->To_Val = MOF(PlugDup(g, valp->GetCharString(buf))); } // endif Formatted - DataType = TYPE_DTM; + vlp->Type = TYPE_DTM; break; case TYPE_STRING: - Strp = valp->GetCharValue(); - DataType = TYPE_STRG; + vlp->To_Val = MOF(valp->GetCharValue()); + vlp->Type = TYPE_STRG; break; case TYPE_DOUBLE: case TYPE_DECIM: - F = valp->GetFloatValue(); + vlp->Nd = (IsTypeNum(valp->GetType())) ? valp->GetValPrec() : 0; - if (IsTypeNum(valp->GetType())) - Nd = valp->GetValPrec(); + if (vlp->Nd <= 6) { + vlp->F = (float)valp->GetFloatValue(); + vlp->Type = TYPE_FLOAT; + } else { + double *dp = (double*)PlugSubAlloc(g, NULL, sizeof(double)); + + *dp = valp->GetFloatValue(); + vlp->To_Val = MOF(dp); + vlp->Type = TYPE_DBL; + } // endif Nd - DataType = TYPE_DBL; break; case TYPE_TINY: - B = valp->GetTinyValue() != 0; - DataType = TYPE_BOOL; + vlp->B = valp->GetTinyValue() != 0; + vlp->Type = TYPE_BOOL; case TYPE_INT: - N = valp->GetIntValue(); - DataType = TYPE_INTG; + vlp->N = valp->GetIntValue(); + vlp->Type = TYPE_INTG; break; case TYPE_BIGINT: - LLn = valp->GetBigintValue(); - DataType = TYPE_BINT; + if (valp->GetBigintValue() >= INT_MIN32 && + valp->GetBigintValue() <= INT_MAX32) { + vlp->N = valp->GetIntValue(); + vlp->Type = TYPE_INTG; + } else { + longlong* llp = (longlong*)PlugSubAlloc(g, NULL, sizeof(longlong)); + + *llp = valp->GetBigintValue(); + vlp->To_Val = MOF(llp); + vlp->Type = TYPE_BINT; + } // endif BigintValue + break; default: sprintf(g->Message, "Unsupported typ %d\n", valp->GetType()); @@ -1553,49 +1682,76 @@ void JVALUE::SetValue(PGLOBAL g, PVAL valp) { /***********************************************************************/ /* Set the Value's value as the given integer. */ /***********************************************************************/ -void JVALUE::SetInteger(PGLOBAL g, int n) { - N = n; - DataType = TYPE_INTG; +void BJSON::SetInteger(PBVAL vlp, int n) +{ + vlp->N = n; + vlp->Type = 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; +void BJSON::SetBool(PBVAL vlp, bool b) +{ + vlp->B = b; + vlp->Type = TYPE_BOOL; } // end of SetTiny /***********************************************************************/ /* Set the Value's value as the given big integer. */ /***********************************************************************/ -void JVALUE::SetBigint(PGLOBAL g, long long ll) { - LLn = ll; - DataType = TYPE_BINT; +void BJSON::SetBigint(PGLOBAL g, PBVAL vlp, longlong ll) +{ + if (ll >= INT_MIN32 && ll <= INT_MAX32) { + vlp->N = (int)ll; + vlp->Type = TYPE_INTG; + } else { + longlong* llp = (longlong*)PlugSubAlloc(g, NULL, sizeof(longlong)); + + *llp = ll; + vlp->To_Val = MOF(llp); + vlp->Type = TYPE_BINT; + } // endif ll + } // end of SetBigint /***********************************************************************/ /* Set the Value's value as the given DOUBLE. */ /***********************************************************************/ -void JVALUE::SetFloat(PGLOBAL g, double f) { - F = f; - Nd = 6; - DataType = TYPE_DBL; +void BJSON::SetFloat(PBVAL vlp, double f) { + vlp->F = (float)f; + vlp->Nd = 6; + vlp->Type = TYPE_FLOAT; } // 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; +void BJSON::SetString(PBVAL vlp, PSZ s, int ci) { + vlp->To_Val = MOF(s); + vlp->Nd = ci; + vlp->Type = 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 -#endif // 0 +bool BJSON::IsValueNull(PBVAL vlp) { + bool b; + + switch (vlp->Type) { + case TYPE_NULL: + b = true; + break; + case TYPE_JOB: + b = IsObjectNull(MPP(vlp->To_Val)); + break; + case TYPE_JAR: + b = IsArrayNull(MVP(vlp->To_Val)); + break; + default: + b = false; + } // endswitch Type + + return b; + } // end of IsNull -- cgit v1.2.1 From b656d3d333f6d8a28407e5e4b636cd142d757595 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Wed, 25 Nov 2020 17:42:01 +0100 Subject: Desesperatly trying to stop compiling failures --- storage/connect/bson.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 2f380752c0d..61e5eb9fe16 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -135,10 +135,10 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { if (Bvp->Type != TYPE_UNKNOWN) { Bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); Bvp->Type = TYPE_JAR; - } else if ((Bvp->To_Val = ParseObject(g, ++i))) + } else { + Bvp->To_Val = ParseObject(g, ++i); Bvp->Type = TYPE_JOB; - else - throw 2; + } // endif Type break; case ' ': @@ -300,7 +300,7 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { } else firstbpp = lastbpp = bpp; - level = 1; + level = 2; } else { sprintf(g->Message, "misplaced string near %.*s", ARGS); throw 2; @@ -308,9 +308,9 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { break; case ':': - if (level == 1) { + if (level == 2) { lastbpp->Vlp = MOF(ParseValue(g, ++i)); - level = 2; + level = 3; } else { sprintf(g->Message, "Unexpected ':' near %.*s", ARGS); throw 2; @@ -318,15 +318,15 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { break; case ',': - if (level < 2) { + if (level < 3) { sprintf(g->Message, "Unexpected ',' near %.*s", ARGS); throw 2; } else - level = 0; + level = 1; break; case '}': - if (level < 2) { + if (!(level == 0 || level == 3)) { sprintf(g->Message, "Unexpected '}' near %.*s", ARGS); throw 2; } // endif level @@ -1248,7 +1248,7 @@ PBVAL BJSON::SubAllocVal(PGLOBAL g) /***********************************************************************/ /* Sub-allocate and initialize a BVAL as string. */ /***********************************************************************/ -PBVAL BJSON::SubAllocVal(PGLOBAL g, OFFSET toval, JTYP type, short nd) +PBVAL BJSON::SubAllocVal(PGLOBAL g, OFFSET toval, int type, short nd) { PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); -- cgit v1.2.1 From 950bf6ab53d7b6d5db0e7d986b81fbd5709e98f6 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 27 Nov 2020 10:25:47 +0100 Subject: - Begin implementation of BSON modified: storage/connect/bson.cpp modified: storage/connect/bson.h modified: storage/connect/bsonudf.cpp modified: storage/connect/bsonudf.h modified: storage/connect/jsonudf.cpp --- storage/connect/bson.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 61e5eb9fe16..4725b67c06b 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -653,7 +653,7 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { err = SerializeValue(MVP(bvp->To_Val)); break; default: - strcpy(g->Message, "Invalid json tree"); + err = SerializeValue(bvp); } // endswitch Type if (fs) { @@ -760,7 +760,7 @@ bool BDOC::SerializeObject(OFFSET obp) { bool BDOC::SerializeValue(PBVAL jvp) { char buf[64]; - switch (jvp->Type) { + if (jvp) switch (jvp->Type) { case TYPE_JAR: return SerializeArray(jvp->To_Val, false); case TYPE_JOB: @@ -788,8 +788,7 @@ bool BDOC::SerializeValue(PBVAL jvp) { return jp->WriteStr("???"); // TODO } // endswitch Type - strcpy(jp->g->Message, "Unrecognized value"); - return true; + return jp->WriteStr("null"); } // end of SerializeValue /* --------------------------- Class BJSON --------------------------- */ @@ -860,7 +859,7 @@ int BJSON::GetObjectSize(PBPR bop, bool b) /***********************************************************************/ PBPR BJSON::AddPair(PGLOBAL g, PBPR bop, PSZ key, OFFSET val) { - PBPR brp, nrp = SubAllocPair(g, MOF(key), val); + PBPR brp, nrp = SubAllocPair(g, key, val); if (bop) { for (brp = bop; brp->Next; brp = MPP(brp->Next)); @@ -995,10 +994,10 @@ PBPR BJSON::SetKeyValue(PGLOBAL g, PBPR bop, OFFSET bvp, PSZ key) prp = brp; if (!brp) - prp->Vlp = MOF(SubAllocPair(g, MOF(key), bvp)); + prp->Vlp = MOF(SubAllocPair(g, key, bvp)); } else - bop = SubAllocPair(g, MOF(key), bvp); + bop = SubAllocPair(g, key, bvp); // Return the first pair of this object return bop; @@ -1094,7 +1093,7 @@ PBVAL BJSON::AddArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int* x) nvp = SubAllocVal(g); if (bap) { - int i = 0, n = *x; + int i = 0, n = (x) ? *x : INT_MAX32; PBVAL bvp; for (bvp = bap; bvp; bvp = MVP(bvp->Next), i++) @@ -1240,7 +1239,7 @@ PBVAL BJSON::SubAllocVal(PGLOBAL g) bvp->To_Val = 0; bvp->Nd = 0; - bvp->Type = TYPE_UNKNOWN; + bvp->Type = TYPE_NULL; bvp->Next = 0; return bvp; } // end of SubAllocVal -- cgit v1.2.1 From 4e8af8a6645136be34649abacb5b31ef64264584 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 1 Dec 2020 19:30:56 +0100 Subject: - Fix memory leak for the JSON table type (and continue BSON implementatio) modified: storage/connect/bson.cpp modified: storage/connect/bson.h modified: storage/connect/bsonudf.cpp modified: storage/connect/connect.cc modified: storage/connect/global.h modified: storage/connect/ha_connect.cc modified: storage/connect/jsonudf.cpp modified: storage/connect/mycat.cc modified: storage/connect/plgdbsem.h modified: storage/connect/plugutil.cpp modified: storage/connect/tabjson.cpp modified: storage/connect/tabjson.h modified: storage/connect/user_connect.cc - Desesperatly trying to fix xml.test failure modified: storage/connect/mysql-test/connect/r/xml.result --- storage/connect/bson.cpp | 218 ++++++++++++++++++++++++++--------------------- 1 file changed, 122 insertions(+), 96 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 4725b67c06b..e395bd8988d 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -87,7 +87,7 @@ char* NextChr(PSZ s, char sep) { /***********************************************************************/ /* BDOC constructor. */ /***********************************************************************/ -BDOC::BDOC(void *base) : BJSON(base, NULL) +BDOC::BDOC(PGLOBAL G) : BJSON(G, NULL) { jp = NULL; s = NULL; @@ -118,25 +118,25 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { pty[0] = false; try { - Bvp = SubAllocVal(g); + Bvp = NewVal(); Bvp->Type = TYPE_UNKNOWN; for (i = 0; i < len; i++) switch (s[i]) { case '[': if (Bvp->Type != TYPE_UNKNOWN) - Bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + Bvp->To_Val = ParseAsArray(i, pretty, ptyp); else - Bvp->To_Val = ParseArray(g, ++i); + Bvp->To_Val = ParseArray(++i); Bvp->Type = TYPE_JAR; break; case '{': if (Bvp->Type != TYPE_UNKNOWN) { - Bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + Bvp->To_Val = ParseAsArray(i, pretty, ptyp); Bvp->Type = TYPE_JAR; } else { - Bvp->To_Val = ParseObject(g, ++i); + Bvp->To_Val = ParseObject(++i); Bvp->Type = TYPE_JOB; } // endif Type @@ -168,9 +168,9 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { default: if (Bvp->Type != TYPE_UNKNOWN) { - Bvp->To_Val = ParseAsArray(g, i, pretty, ptyp); + Bvp->To_Val = ParseAsArray(i, pretty, ptyp); Bvp->Type = TYPE_JAR; - } else if ((Bvp->To_Val = MOF(ParseValue(g, i)))) + } else if ((Bvp->To_Val = MOF(ParseValue(i)))) Bvp->Type = TYPE_JVAL; else throw 4; @@ -193,7 +193,8 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { } catch (int n) { if (trace(1)) - htrc("Exception %d: %s\n", n, g->Message); + htrc("Exception %d: %s\n", n, G->Message); + GetMsg(g); Bvp = NULL; } catch (const char* msg) { strcpy(g->Message, msg); @@ -206,16 +207,16 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { /***********************************************************************/ /* Parse several items as being in an array. */ /***********************************************************************/ -OFFSET BDOC::ParseAsArray(PGLOBAL g, int& i, int pretty, int* ptyp) { +OFFSET BDOC::ParseAsArray(int& i, int pretty, int* ptyp) { if (pty[0] && (!pretty || pretty > 2)) { OFFSET jsp; - if ((jsp = ParseArray(g, (i = 0))) && ptyp && pretty == 3) + if ((jsp = ParseArray((i = 0))) && ptyp && pretty == 3) *ptyp = (pty[0]) ? 0 : 3; return jsp; } else - strcpy(g->Message, "More than one item in file"); + strcpy(G->Message, "More than one item in file"); return 0; } // end of ParseAsArray @@ -223,7 +224,7 @@ OFFSET BDOC::ParseAsArray(PGLOBAL g, int& i, int pretty, int* ptyp) { /***********************************************************************/ /* Parse a JSON Array. */ /***********************************************************************/ -OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { +OFFSET BDOC::ParseArray(int& i) { int level = 0; bool b = (!i); PBVAL vlp, firstvlp, lastvlp; @@ -234,7 +235,7 @@ OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { switch (s[i]) { case ',': if (level < 2) { - sprintf(g->Message, "Unexpected ',' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',' near %.*s", ARGS); throw 1; } else level = 1; @@ -242,7 +243,7 @@ OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { break; case ']': if (level == 1) { - sprintf(g->Message, "Unexpected ',]' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',]' near %.*s", ARGS); throw 1; } // endif level @@ -256,14 +257,14 @@ OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { break; default: if (level == 2) { - sprintf(g->Message, "Unexpected value near %.*s", ARGS); + sprintf(G->Message, "Unexpected value near %.*s", ARGS); throw 1; } else if (lastvlp) { - vlp = ParseValue(g, i); + vlp = ParseValue(i); lastvlp->Next = MOF(vlp); lastvlp = vlp; } else - firstvlp = lastvlp = ParseValue(g, i); + firstvlp = lastvlp = ParseValue(i); level = (b) ? 1 : 2; break; @@ -280,7 +281,7 @@ OFFSET BDOC::ParseArray(PGLOBAL g, int& i) { /***********************************************************************/ /* Parse a JSON Object. */ /***********************************************************************/ -OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { +OFFSET BDOC::ParseObject(int& i) { OFFSET key; int level = 0; PBPR bpp, firstbpp, lastbpp; @@ -291,8 +292,8 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { switch (s[i]) { case '"': if (level < 2) { - key = ParseString(g, ++i); - bpp = SubAllocPair(g, key); + key = ParseString(++i); + bpp = SubAllocPair(key); if (lastbpp) { lastbpp->Next = MOF(bpp); @@ -302,24 +303,24 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { level = 2; } else { - sprintf(g->Message, "misplaced string near %.*s", ARGS); + sprintf(G->Message, "misplaced string near %.*s", ARGS); throw 2; } // endif level break; case ':': if (level == 2) { - lastbpp->Vlp = MOF(ParseValue(g, ++i)); + lastbpp->Vlp = MOF(ParseValue(++i)); level = 3; } else { - sprintf(g->Message, "Unexpected ':' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ':' near %.*s", ARGS); throw 2; } // endif level break; case ',': if (level < 3) { - sprintf(g->Message, "Unexpected ',' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',' near %.*s", ARGS); throw 2; } else level = 1; @@ -327,7 +328,7 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { break; case '}': if (!(level == 0 || level == 3)) { - sprintf(g->Message, "Unexpected '}' near %.*s", ARGS); + sprintf(G->Message, "Unexpected '}' near %.*s", ARGS); throw 2; } // endif level @@ -339,20 +340,21 @@ OFFSET BDOC::ParseObject(PGLOBAL g, int& i) { case '\t': break; default: - sprintf(g->Message, "Unexpected character '%c' near %.*s", + sprintf(G->Message, "Unexpected character '%c' near %.*s", s[i], ARGS); throw 2; }; // endswitch s[i] - strcpy(g->Message, "Unexpected EOF in Object"); + strcpy(G->Message, "Unexpected EOF in Object"); throw 2; } // end of ParseObject /***********************************************************************/ /* Parse a JSON Value. */ /***********************************************************************/ -PBVAL BDOC::ParseValue(PGLOBAL g, int& i) { - PBVAL bvp = SubAllocVal(g); +PBVAL BDOC::ParseValue(int& i) +{ + PBVAL bvp = NewVal(); for (; i < len; i++) switch (s[i]) { @@ -369,16 +371,16 @@ PBVAL BDOC::ParseValue(PGLOBAL g, int& i) { suite: switch (s[i]) { case '[': - bvp->To_Val = ParseArray(g, ++i); + bvp->To_Val = ParseArray(++i); bvp->Type = TYPE_JAR; break; case '{': - bvp->To_Val = ParseObject(g, ++i); + bvp->To_Val = ParseObject(++i); bvp->Type = TYPE_JOB; break; case '"': // jvp->Val = AllocVal(g, TYPE_STRG); - bvp->To_Val = ParseString(g, ++i); + bvp->To_Val = ParseString(++i); bvp->Type = TYPE_STRG; break; case 't': @@ -412,7 +414,7 @@ suite: case '-': default: if (s[i] == '-' || isdigit(s[i])) - ParseNumeric(g, i, bvp); + ParseNumeric(i, bvp); else goto err; @@ -421,29 +423,29 @@ suite: return bvp; err: - sprintf(g->Message, "Unexpected character '%c' near %.*s", s[i], ARGS); + sprintf(G->Message, "Unexpected character '%c' near %.*s", s[i], ARGS); throw 3; } // end of ParseValue /***********************************************************************/ /* Unescape and parse a JSON string. */ /***********************************************************************/ -OFFSET BDOC::ParseString(PGLOBAL g, int& i) { +OFFSET BDOC::ParseString(int& i) { uchar* p; int n = 0; // Be sure of memory availability - if (((size_t)len + 1 - i) > ((PPOOLHEADER)g->Sarea)->FreeBlk) + if (((size_t)len + 1 - i) > ((PPOOLHEADER)G->Sarea)->FreeBlk) throw("ParseString: Out of memory"); // The size to allocate is not known yet - p = (uchar*)PlugSubAlloc(g, NULL, 0); + p = (uchar*)PlugSubAlloc(G, NULL, 0); for (; i < len; i++) switch (s[i]) { case '"': p[n++] = 0; - PlugSubAlloc(g, NULL, n); + PlugSubAlloc(G, NULL, n); return MOF(p); case '\\': if (++i < len) { @@ -514,7 +516,7 @@ throw("Unexpected EOF in String"); /***********************************************************************/ /* Parse a JSON numeric value. */ /***********************************************************************/ -void BDOC::ParseNumeric(PGLOBAL g, int& i, PBVAL vlp) { +void BDOC::ParseNumeric(int& i, PBVAL vlp) { char buf[50]; int n = 0; short nd = 0; @@ -570,7 +572,7 @@ fin: double dv = strtod(buf, NULL); if (nd > 6) { - double* dvp = (double*)PlugSubAlloc(g, NULL, sizeof(double)); + double* dvp = (double*)PlugSubAlloc(G, NULL, sizeof(double)); *dvp = dv; vlp->To_Val = MOF(dvp); @@ -585,7 +587,7 @@ fin: longlong iv = strtoll(buf, NULL, 10); if (iv > INT_MAX32 || iv < INT_MIN32) { - longlong *llp = (longlong*)PlugSubAlloc(g, NULL, sizeof(longlong)); + longlong *llp = (longlong*)PlugSubAlloc(G, NULL, sizeof(longlong)); *llp = iv; vlp->To_Val = MOF(llp); @@ -614,7 +616,7 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { bool b = false, err = true; FILE* fs = NULL; - g->Message[0] = 0; + G->Message[0] = 0; try { if (!bvp) { @@ -664,15 +666,15 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { str = ((JOUTSTR*)jp)->Strp; jp->WriteChr('\0'); PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N); - } else { - if (!g->Message[0]) + } else if (G->Message[0]) strcpy(g->Message, "Error in Serialize"); - - } // endif's + else + GetMsg(g); } catch (int n) { if (trace(1)) - htrc("Exception %d: %s\n", n, g->Message); + htrc("Exception %d: %s\n", n, G->Message); + GetMsg(g); str = NULL; } catch (const char* msg) { strcpy(g->Message, msg); @@ -796,10 +798,10 @@ bool BDOC::SerializeValue(PBVAL jvp) { /***********************************************************************/ /* Program for sub-allocating Bjson structures. */ /***********************************************************************/ -void* BJSON::BsonSubAlloc(PGLOBAL g, size_t size) +void* BJSON::BsonSubAlloc(size_t size) { PPOOLHEADER pph; /* Points on area header. */ - void* memp = g->Sarea; + void* memp = G->Sarea; size = ((size + 3) / 4) * 4; /* Round up size to multiple of 4 */ pph = (PPOOLHEADER)memp; @@ -808,10 +810,10 @@ void* BJSON::BsonSubAlloc(PGLOBAL g, size_t size) memp, size, pph->To_Free, pph->FreeBlk); if (size > pph->FreeBlk) { /* Not enough memory left in pool */ - sprintf(g->Message, + sprintf(G->Message, "Not enough memory for request of %zd (used=%zd free=%zd)", size, pph->To_Free, pph->FreeBlk); - xtrc(1, "BsonSubAlloc: %s\n", g->Message); + xtrc(1, "BsonSubAlloc: %s\n", G->Message); throw(1234); } /* endif size OS32 code */ @@ -824,14 +826,29 @@ void* BJSON::BsonSubAlloc(PGLOBAL g, size_t size) return memp; } /* end of BsonSubAlloc */ +/*********************************************************************************/ +/* Program for SubSet re-initialization of the memory pool. */ +/*********************************************************************************/ +void BJSON::SubSet(bool b) +{ + PPOOLHEADER pph = (PPOOLHEADER)G->Sarea; + + pph->To_Free = (G->Saved_Size) ? G->Saved_Size : sizeof(POOLHEADER); + pph->FreeBlk = G->Sarea_Size - pph->To_Free; + + if (b) + G->Saved_Size = 0; + +} /* end of JsonSubSet */ + /* ------------------------ Bobject functions ------------------------ */ /***********************************************************************/ /* Sub-allocate and initialize a BPAIR. */ /***********************************************************************/ -PBPR BJSON::SubAllocPair(PGLOBAL g, OFFSET key, OFFSET val) +PBPR BJSON::SubAllocPair(OFFSET key, OFFSET val) { - PBPR bpp = (PBPR)BsonSubAlloc(g, sizeof(BPAIR)); + PBPR bpp = (PBPR)BsonSubAlloc(sizeof(BPAIR)); bpp->Key = key; bpp->Vlp = val; @@ -857,9 +874,9 @@ int BJSON::GetObjectSize(PBPR bop, bool b) /***********************************************************************/ /* Add a new pair to an Object and return it. */ /***********************************************************************/ -PBPR BJSON::AddPair(PGLOBAL g, PBPR bop, PSZ key, OFFSET val) +PBPR BJSON::AddPair(PBPR bop, PSZ key, OFFSET val) { - PBPR brp, nrp = SubAllocPair(g, key, val); + PBPR brp, nrp = SubAllocPair(key, val); if (bop) { for (brp = bop; brp->Next; brp = MPP(brp->Next)); @@ -874,17 +891,17 @@ PBPR BJSON::AddPair(PGLOBAL g, PBPR bop, PSZ key, OFFSET val) /***********************************************************************/ /* Return all object keys as an array. */ /***********************************************************************/ -PBVAL BJSON::GetKeyList(PGLOBAL g, PBPR bop) +PBVAL BJSON::GetKeyList(PBPR bop) { PBVAL bvp, lvp, fvp = NULL; for (PBPR brp = bop; brp; brp = MPP(brp->Next)) if (fvp) { - bvp = SubAllocVal(g, brp->Key, TYPE_STRG); + bvp = SubAllocVal(brp->Key, TYPE_STRG); lvp->Next = MOF(bvp); lvp = bvp; } else - lvp = fvp = SubAllocVal(g, brp->Key, TYPE_STRG); + lvp = fvp = SubAllocVal(brp->Key, TYPE_STRG); return fvp; } // end of GetKeyList @@ -892,17 +909,17 @@ PBVAL BJSON::GetKeyList(PGLOBAL g, PBPR bop) /***********************************************************************/ /* Return all object values as an array. */ /***********************************************************************/ -PBVAL BJSON::GetObjectValList(PGLOBAL g, PBPR bop) +PBVAL BJSON::GetObjectValList(PBPR bop) { PBVAL bvp, lvp, fvp = NULL; for (PBPR brp = bop; brp; brp = MPP(brp->Next)) if (fvp) { - bvp = DupVal(g, MVP(brp->Vlp)); + bvp = DupVal(MVP(brp->Vlp)); lvp->Next = MOF(bvp); lvp = bvp; } else - lvp = fvp = DupVal(g, MVP(brp->Vlp)); + lvp = fvp = DupVal(MVP(brp->Vlp)); return fvp; } // end of GetObjectValList @@ -981,7 +998,7 @@ PSZ BJSON::GetObjectText(PGLOBAL g, PBPR bop, PSTRG text) { /***********************************************************************/ /* Set or add a value corresponding to the given key. */ /***********************************************************************/ -PBPR BJSON::SetKeyValue(PGLOBAL g, PBPR bop, OFFSET bvp, PSZ key) +PBPR BJSON::SetKeyValue(PBPR bop, OFFSET bvp, PSZ key) { PBPR brp = bop, prp = NULL; @@ -994,10 +1011,10 @@ PBPR BJSON::SetKeyValue(PGLOBAL g, PBPR bop, OFFSET bvp, PSZ key) prp = brp; if (!brp) - prp->Vlp = MOF(SubAllocPair(g, key, bvp)); + prp->Vlp = MOF(SubAllocPair(key, bvp)); } else - bop = SubAllocPair(g, key, bvp); + bop = SubAllocPair(key, bvp); // Return the first pair of this object return bop; @@ -1006,11 +1023,11 @@ PBPR BJSON::SetKeyValue(PGLOBAL g, PBPR bop, OFFSET bvp, PSZ key) /***********************************************************************/ /* Merge two objects. */ /***********************************************************************/ -PBPR BJSON::MergeObject(PGLOBAL g, PBPR bop1, PBPR bop2) +PBPR BJSON::MergeObject(PBPR bop1, PBPR bop2) { if (bop1) for (PBPR brp = bop2; brp; brp = MPP(brp->Next)) - SetKeyValue(g, bop1, brp->Vlp, MZP(brp->Key)); + SetKeyValue(bop1, brp->Vlp, MZP(brp->Key)); else bop1 = bop2; @@ -1087,10 +1104,10 @@ PBVAL BJSON::GetArrayValue(PBVAL bap, int n) /***********************************************************************/ /* Add a Value to the Array Value list. */ /***********************************************************************/ -PBVAL BJSON::AddArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int* x) +PBVAL BJSON::AddArrayValue(PBVAL bap, PBVAL nvp, int* x) { if (!nvp) - nvp = SubAllocVal(g); + nvp = NewVal(); if (bap) { int i = 0, n = (x) ? *x : INT_MAX32; @@ -1112,11 +1129,11 @@ PBVAL BJSON::AddArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int* x) /***********************************************************************/ /* Merge two arrays. */ /***********************************************************************/ -PBVAL BJSON::MergeArray(PGLOBAL g, PBVAL bap1, PBVAL bap2) +PBVAL BJSON::MergeArray(PBVAL bap1, PBVAL bap2) { if (bap1) { for (PBVAL bvp = bap2; bvp; bvp = MVP(bvp->Next)) - AddArrayValue(g, bap1, bvp); + AddArrayValue(bap1, bvp); return bap1; } else @@ -1127,7 +1144,7 @@ PBVAL BJSON::MergeArray(PGLOBAL g, PBVAL bap1, PBVAL bap2) /***********************************************************************/ /* Set the nth Value of the Array Value list or add it. */ /***********************************************************************/ -PBVAL BJSON::SetArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int n) +PBVAL BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n) { PBVAL bvp = bap, pvp = NULL; @@ -1144,7 +1161,7 @@ PBVAL BJSON::SetArrayValue(PGLOBAL g, PBVAL bap, PBVAL nvp, int n) } // endif bap if (!bvp) { - bvp = DupVal(g, nvp); + bvp = DupVal(nvp); if (pvp) pvp->Next = MOF(bvp); @@ -1233,47 +1250,56 @@ bool BJSON::IsArrayNull(PBVAL bap) /***********************************************************************/ /* Sub-allocate and clear a BVAL. */ /***********************************************************************/ -PBVAL BJSON::SubAllocVal(PGLOBAL g) +PBVAL BJSON::NewVal(int type) { - PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); + PBVAL bvp = (PBVAL)BsonSubAlloc(sizeof(BVAL)); bvp->To_Val = 0; bvp->Nd = 0; - bvp->Type = TYPE_NULL; + bvp->Type = type; bvp->Next = 0; return bvp; } // end of SubAllocVal +/***********************************************************************/ +/* Sub-allocate and initialize a BVAL as type. */ +/***********************************************************************/ +PBVAL BJSON::SubAllocVal(OFFSET toval, int type, short nd) +{ + PBVAL bvp = NewVal(type); + + bvp->To_Val = toval; + bvp->Nd = nd; + return bvp; +} // end of SubAllocVal + /***********************************************************************/ /* Sub-allocate and initialize a BVAL as string. */ /***********************************************************************/ -PBVAL BJSON::SubAllocVal(PGLOBAL g, OFFSET toval, int type, short nd) +PBVAL BJSON::SubAllocStr(OFFSET toval, short nd) { - PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); + PBVAL bvp = NewVal(TYPE_STRG); bvp->To_Val = toval; bvp->Nd = nd; - bvp->Type = type; - bvp->Next = 0; return bvp; } // end of SubAllocVal /***********************************************************************/ /* Allocate a BVALUE with a given string or numeric value. */ /***********************************************************************/ -PBVAL BJSON::SubAllocVal(PGLOBAL g, PVAL valp) +PBVAL BJSON::SubAllocVal(PVAL valp) { - PBVAL vlp = SubAllocVal(g); - SetValue(g, vlp, valp); - vlp->Next = NULL; + PBVAL vlp = NewVal(); + SetValue(vlp, valp); return vlp; } // end of SubAllocVal /***********************************************************************/ /* Sub-allocate and initialize a BVAL from another BVAL. */ /***********************************************************************/ -PBVAL BJSON::DupVal(PGLOBAL g, PBVAL bvlp) { - PBVAL bvp = (PBVAL)BsonSubAlloc(g, sizeof(BVAL)); +PBVAL BJSON::DupVal(PBVAL bvlp) { + PBVAL bvp = NewVal(); *bvp = *bvlp; bvp->Next = 0; @@ -1539,7 +1565,7 @@ double BJSON::GetDouble(PBVAL vp) /***********************************************************************/ /* Return the Value's String value. */ /***********************************************************************/ -PSZ BJSON::GetString(PGLOBAL g, PBVAL vp, char* buff) +PSZ BJSON::GetString(PBVAL vp, char* buff) { char buf[32]; char* p = (buff) ? buff : buf; @@ -1572,7 +1598,7 @@ PSZ BJSON::GetString(PGLOBAL g, PBVAL vp, char* buff) p = NULL; } // endswitch Type - return (p == buf) ? (PSZ)PlugDup(g, buf) : p; + return (p == buf) ? (PSZ)PlugDup(G, buf) : p; } // end of GetString /***********************************************************************/ @@ -1585,7 +1611,7 @@ PSZ BJSON::GetValueText(PGLOBAL g, PBVAL vlp, PSTRG text) { return GetArrayText(g, MVP(vlp->To_Val), text); char buff[32]; - PSZ s = (vlp->Type == TYPE_NULL) ? NULL : GetString(g, vlp, buff); + PSZ s = (vlp->Type == TYPE_NULL) ? NULL : GetString(vlp, buff); if (s) text->Append(s); @@ -1614,7 +1640,7 @@ void BJSON::SetValueVal(PBVAL vlp, PBVAL vp) vlp->Type = vp->Type; } // end of SetValue; -void BJSON::SetValue(PGLOBAL g, PBVAL vlp, PVAL valp) +void BJSON::SetValue(PBVAL vlp, PVAL valp) { if (!valp || valp->IsNull()) { vlp->Type = TYPE_NULL; @@ -1625,7 +1651,7 @@ void BJSON::SetValue(PGLOBAL g, PBVAL vlp, PVAL valp) else { char buf[32]; - vlp->To_Val = MOF(PlugDup(g, valp->GetCharString(buf))); + vlp->To_Val = MOF(PlugDup(G, valp->GetCharString(buf))); } // endif Formatted vlp->Type = TYPE_DTM; @@ -1642,7 +1668,7 @@ void BJSON::SetValue(PGLOBAL g, PBVAL vlp, PVAL valp) vlp->F = (float)valp->GetFloatValue(); vlp->Type = TYPE_FLOAT; } else { - double *dp = (double*)PlugSubAlloc(g, NULL, sizeof(double)); + double *dp = (double*)PlugSubAlloc(G, NULL, sizeof(double)); *dp = valp->GetFloatValue(); vlp->To_Val = MOF(dp); @@ -1663,7 +1689,7 @@ void BJSON::SetValue(PGLOBAL g, PBVAL vlp, PVAL valp) vlp->N = valp->GetIntValue(); vlp->Type = TYPE_INTG; } else { - longlong* llp = (longlong*)PlugSubAlloc(g, NULL, sizeof(longlong)); + longlong* llp = (longlong*)PlugSubAlloc(G, NULL, sizeof(longlong)); *llp = valp->GetBigintValue(); vlp->To_Val = MOF(llp); @@ -1672,7 +1698,7 @@ void BJSON::SetValue(PGLOBAL g, PBVAL vlp, PVAL valp) break; default: - sprintf(g->Message, "Unsupported typ %d\n", valp->GetType()); + sprintf(G->Message, "Unsupported typ %d\n", valp->GetType()); throw(777); } // endswitch Type @@ -1699,13 +1725,13 @@ void BJSON::SetBool(PBVAL vlp, bool b) /***********************************************************************/ /* Set the Value's value as the given big integer. */ /***********************************************************************/ -void BJSON::SetBigint(PGLOBAL g, PBVAL vlp, longlong ll) +void BJSON::SetBigint(PBVAL vlp, longlong ll) { if (ll >= INT_MIN32 && ll <= INT_MAX32) { vlp->N = (int)ll; vlp->Type = TYPE_INTG; } else { - longlong* llp = (longlong*)PlugSubAlloc(g, NULL, sizeof(longlong)); + longlong* llp = (longlong*)PlugSubAlloc(G, NULL, sizeof(longlong)); *llp = ll; vlp->To_Val = MOF(llp); -- cgit v1.2.1 From c05b1288fd86c98d9b13724d6b115b35c77ca15a Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 4 Dec 2020 23:21:59 +0100 Subject: Remove a push warning causing failing assert. Modified storage/connect/filamap.cpp --- storage/connect/bson.cpp | 386 +++++++++++++++++++---------------------------- 1 file changed, 154 insertions(+), 232 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index e395bd8988d..b4ce7ec1505 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -21,6 +21,15 @@ #include "plgdbsem.h" #include "bson.h" +/***********************************************************************/ +/* Check macro. */ +/***********************************************************************/ +#if defined(_DEBUG) +#define CheckType(X,Y) if (!X || X ->Type != Y) throw MSG(VALTYPE_NOMATCH); +#else +#define CheckType(V) +#endif + #if defined(__WIN__) #define EL "\r\n" #else @@ -859,13 +868,14 @@ PBPR BJSON::SubAllocPair(OFFSET key, OFFSET val) /***********************************************************************/ /* Return the number of pairs in this object. */ /***********************************************************************/ -int BJSON::GetObjectSize(PBPR bop, bool b) +int BJSON::GetObjectSize(PBVAL bop, bool b) { + CheckType(bop, TYPE_JOB); int n = 0; - for (PBPR brp = bop; brp; brp = MPP(brp->Next)) + for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) // If b return only non null pairs - if (!b || (brp->Vlp && (MVP(brp->Vlp))->Type != TYPE_NULL)) + if (!b || (brp->Vlp && GetVal(brp)->Type != TYPE_NULL)) n++; return n; @@ -874,64 +884,60 @@ int BJSON::GetObjectSize(PBPR bop, bool b) /***********************************************************************/ /* Add a new pair to an Object and return it. */ /***********************************************************************/ -PBPR BJSON::AddPair(PBPR bop, PSZ key, OFFSET val) +void BJSON::AddPair(PBVAL bop, PSZ key, OFFSET val) { - PBPR brp, nrp = SubAllocPair(key, val); + CheckType(bop, TYPE_JOB); + PBPR brp; + OFFSET nrp = MOF(SubAllocPair(key, val)); - if (bop) { - for (brp = bop; brp->Next; brp = MPP(brp->Next)); + if (bop->To_Val) { + for (brp = GetObject(bop); brp->Next; brp = GetNext(brp)); - brp->Next = MOF(nrp); + brp->Next = nrp; } else - bop = nrp; + bop->To_Val = nrp; - return bop; + bop->Nd++; } // end of AddPair /***********************************************************************/ /* Return all object keys as an array. */ /***********************************************************************/ -PBVAL BJSON::GetKeyList(PBPR bop) +PBVAL BJSON::GetKeyList(PBVAL bop) { - PBVAL bvp, lvp, fvp = NULL; + CheckType(bop, TYPE_JOB); + PBVAL arp = NewVal(TYPE_JAR); - for (PBPR brp = bop; brp; brp = MPP(brp->Next)) - if (fvp) { - bvp = SubAllocVal(brp->Key, TYPE_STRG); - lvp->Next = MOF(bvp); - lvp = bvp; - } else - lvp = fvp = SubAllocVal(brp->Key, TYPE_STRG); + for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) + AddArrayValue(arp, MOF(SubAllocVal(brp->Key, TYPE_STRG))); - return fvp; + return arp; } // end of GetKeyList /***********************************************************************/ /* Return all object values as an array. */ /***********************************************************************/ -PBVAL BJSON::GetObjectValList(PBPR bop) +PBVAL BJSON::GetObjectValList(PBVAL bop) { - PBVAL bvp, lvp, fvp = NULL; + CheckType(bop, TYPE_JOB); + PBVAL arp = NewVal(TYPE_JAR); - for (PBPR brp = bop; brp; brp = MPP(brp->Next)) - if (fvp) { - bvp = DupVal(MVP(brp->Vlp)); - lvp->Next = MOF(bvp); - lvp = bvp; - } else - lvp = fvp = DupVal(MVP(brp->Vlp)); + for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) + AddArrayValue(arp, brp->Vlp); - return fvp; + return arp; } // end of GetObjectValList /***********************************************************************/ /* Get the value corresponding to the given key. */ /***********************************************************************/ -PBVAL BJSON::GetKeyValue(PBPR bop, PSZ key) +PBVAL BJSON::GetKeyValue(PBVAL bop, PSZ key) { - for (PBPR brp = bop; brp; brp = MPP(brp->Next)) - if (!strcmp(MZP(brp->Key), key)) - return MVP(brp->Vlp); + CheckType(bop, TYPE_JOB); + + for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) + if (!strcmp(GetKey(brp), key)) + return GetVal(brp); return NULL; } // end of GetKeyValue; @@ -939,8 +945,11 @@ PBVAL BJSON::GetKeyValue(PBPR bop, PSZ key) /***********************************************************************/ /* Return the text corresponding to all keys (XML like). */ /***********************************************************************/ -PSZ BJSON::GetObjectText(PGLOBAL g, PBPR bop, PSTRG text) { - if (bop) { +PSZ BJSON::GetObjectText(PGLOBAL g, PBVAL bop, PSTRG text) +{ + CheckType(bop, TYPE_JOB); + + if (bop->To_Val) { bool b; if (!text) { @@ -977,8 +986,8 @@ PSZ BJSON::GetObjectText(PGLOBAL g, PBPR bop, PSTRG text) { } else #endif // 0 - for (PBPR brp = bop; brp; brp = MPP(brp->Next)) { - GetValueText(g, MVP(brp->Vlp), text); + for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) { + GetValueText(g, GetVal(brp), text); if (brp->Next) text->Append(' '); @@ -998,39 +1007,44 @@ PSZ BJSON::GetObjectText(PGLOBAL g, PBPR bop, PSTRG text) { /***********************************************************************/ /* Set or add a value corresponding to the given key. */ /***********************************************************************/ -PBPR BJSON::SetKeyValue(PBPR bop, OFFSET bvp, PSZ key) +void BJSON::SetKeyValue(PBVAL bop, OFFSET bvp, PSZ key) { - PBPR brp = bop, prp = NULL; + CheckType(bop, TYPE_JOB); + PBPR brp, prp = NULL; - if (brp) { - for (brp = bop; brp; brp = MPP(brp->Next)) - if (!strcmp(MZP(brp->Key), key)) { + if (bop->To_Val) { + for (brp = GetObject(bop); brp; brp = GetNext(brp)) + if (!strcmp(GetKey(brp), key)) { brp->Vlp = bvp; - break; + return; } else prp = brp; if (!brp) - prp->Vlp = MOF(SubAllocPair(key, bvp)); + prp->Next = MOF(SubAllocPair(key, bvp)); } else - bop = SubAllocPair(key, bvp); + bop->To_Val = MOF(SubAllocPair(key, bvp)); - // Return the first pair of this object - return bop; + bop->Nd++; } // end of SetKeyValue /***********************************************************************/ /* Merge two objects. */ /***********************************************************************/ -PBPR BJSON::MergeObject(PBPR bop1, PBPR bop2) +PBVAL BJSON::MergeObject(PBVAL bop1, PBVAL bop2) { - if (bop1) - for (PBPR brp = bop2; brp; brp = MPP(brp->Next)) - SetKeyValue(bop1, brp->Vlp, MZP(brp->Key)); + CheckType(bop1, TYPE_JOB); + CheckType(bop2, TYPE_JOB); + + if (bop1->To_Val) + for (PBPR brp = GetObject(bop2); brp; brp = GetNext(brp)) + SetKeyValue(bop1, brp->Vlp, GetKey(brp)); - else - bop1 = bop2; + else { + bop1->To_Val = bop2->To_Val; + bop1->Nd = bop2->Nd; + } // endelse To_Val return bop1; } // end of MergeObject; @@ -1038,30 +1052,33 @@ PBPR BJSON::MergeObject(PBPR bop1, PBPR bop2) /***********************************************************************/ /* Delete a value corresponding to the given key. */ /***********************************************************************/ -PBPR BJSON::DeleteKey(PBPR bop, PCSZ key) +void BJSON::DeleteKey(PBVAL bop, PCSZ key) { + CheckType(bop, TYPE_JOB); PBPR brp, pbrp = NULL; - for (brp = bop; brp; brp = MPP(brp->Next)) + for (brp = GetObject(bop); brp; brp = GetNext(brp)) if (!strcmp(MZP(brp->Key), key)) { if (pbrp) { pbrp->Next = brp->Next; - return bop; } else - return MPP(brp->Next); + bop->To_Val = brp->Next; + bop->Nd--; + break; } else pbrp = brp; - return bop; } // end of DeleteKey /***********************************************************************/ /* True if void or if all members are nulls. */ /***********************************************************************/ -bool BJSON::IsObjectNull(PBPR bop) +bool BJSON::IsObjectNull(PBVAL bop) { - for (PBPR brp = bop; brp; brp = MPP(brp->Next)) + CheckType(bop, TYPE_JOB); + + for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) if (brp->Vlp && (MVP(brp->Vlp))->Type != TYPE_NULL) return false; @@ -1075,9 +1092,10 @@ bool BJSON::IsObjectNull(PBPR bop) /***********************************************************************/ int BJSON::GetArraySize(PBVAL bap, bool b) { + CheckType(bap, TYPE_JAR); int n = 0; - for (PBVAL bvp = bap; bvp; bvp = MVP(bvp->Next)) + for (PBVAL bvp = GetArray(bap); bvp; bvp = GetNext(bvp)) // If b, return only non null values if (!b || bvp->Type != TYPE_NULL) n++; @@ -1090,13 +1108,12 @@ int BJSON::GetArraySize(PBVAL bap, bool b) /***********************************************************************/ PBVAL BJSON::GetArrayValue(PBVAL bap, int n) { + CheckType(bap, TYPE_JAR); int i = 0; - for (PBVAL bvp = bap; bvp; bvp = MVP(bvp->Next)) + for (PBVAL bvp = GetArray(bap); bvp; bvp = GetNext(bvp), i++) if (i == n) return bvp; - else - i++; return NULL; } // end of GetArrayValue @@ -1104,80 +1121,78 @@ PBVAL BJSON::GetArrayValue(PBVAL bap, int n) /***********************************************************************/ /* Add a Value to the Array Value list. */ /***********************************************************************/ -PBVAL BJSON::AddArrayValue(PBVAL bap, PBVAL nvp, int* x) +void BJSON::AddArrayValue(PBVAL bap, OFFSET nvp, int* x) { + CheckType(bap, TYPE_JAR); if (!nvp) - nvp = NewVal(); + nvp = MOF(NewVal()); - if (bap) { + if (bap->To_Val) { int i = 0, n = (x) ? *x : INT_MAX32; - PBVAL bvp; - for (bvp = bap; bvp; bvp = MVP(bvp->Next), i++) + for (PBVAL bvp = GetArray(bap); bvp; bvp = GetNext(bvp), i++) if (!bvp->Next || (x && i == n)) { - nvp->Next = bvp->Next; - bvp->Next = MOF(nvp); + MVP(nvp)->Next = bvp->Next; + bvp->Next = nvp; break; } // endif Next } else - bap = nvp; + bap->To_Val = nvp; - return bap; + bap->Nd++; } // end of AddArrayValue /***********************************************************************/ /* Merge two arrays. */ /***********************************************************************/ -PBVAL BJSON::MergeArray(PBVAL bap1, PBVAL bap2) +void BJSON::MergeArray(PBVAL bap1, PBVAL bap2) { - if (bap1) { - for (PBVAL bvp = bap2; bvp; bvp = MVP(bvp->Next)) - AddArrayValue(bap1, bvp); + CheckType(bap1, TYPE_JAR); + CheckType(bap2, TYPE_JAR); - return bap1; - } else - return bap2; + if (bap1->To_Val) { + for (PBVAL bvp = GetArray(bap2); bvp; bvp = GetNext(bvp)) + AddArrayValue(bap1, MOF(DupVal(bvp))); + + } else { + bap1->To_Val = bap2->To_Val; + bap1->Nd = bap2->Nd; + } // endif To_Val } // end of MergeArray /***********************************************************************/ -/* Set the nth Value of the Array Value list or add it. */ +/* Set the nth Value of the Array Value list or add it. */ /***********************************************************************/ -PBVAL BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n) +void BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n) { - PBVAL bvp = bap, pvp = NULL; + CheckType(bap, TYPE_JAR); + PBVAL bvp = NULL, pvp = NULL; - if (bvp) { - for (int i = 0; bvp; i++, bvp = MVP(bvp->Next)) + if (bap->To_Val) { + for (int i = 0; bvp = GetArray(bap); i++, bvp = GetNext(bvp)) if (i == n) { - bvp->To_Val = nvp->To_Val; - bvp->Nd = nvp->Nd; - bvp->Type = nvp->Type; - return bap; + SetValueVal(bvp, nvp); + return; } else pvp = bvp; } // endif bap - if (!bvp) { - bvp = DupVal(nvp); - - if (pvp) - pvp->Next = MOF(bvp); - else - bap = bvp; - - } // endif bvp + if (!bvp) + AddArrayValue(bap, MOF(nvp)); - return bap; } // end of SetValue /***********************************************************************/ /* Return the text corresponding to all values. */ /***********************************************************************/ -PSZ BJSON::GetArrayText(PGLOBAL g, PBVAL bap, PSTRG text) { - if (bap) { +PSZ BJSON::GetArrayText(PGLOBAL g, PBVAL bap, PSTRG text) +{ + CheckType(bap, TYPE_JAR); + + if (bap->To_Val) { bool b; if (!text) { @@ -1192,7 +1207,7 @@ PSZ BJSON::GetArrayText(PGLOBAL g, PBVAL bap, PSTRG text) { b = false; } // endif text - for (PBVAL bvp = bap; bvp; bvp = MVP(bvp->Next)) { + for (PBVAL bvp = GetArray(bap); bvp; bvp = GetNext(bvp)) { GetValueText(g, bvp, text); if (bvp->Next) @@ -1200,14 +1215,14 @@ PSZ BJSON::GetArrayText(PGLOBAL g, PBVAL bap, PSTRG text) { else if (!b) text->Append(')'); - } // endfor jp + } // endfor bvp if (b) { text->Trim(); return text->GetStr(); } // endif b - } // endif First + } // endif To_Val return NULL; } // end of GetText; @@ -1215,22 +1230,23 @@ PSZ BJSON::GetArrayText(PGLOBAL g, PBVAL bap, PSTRG text) { /***********************************************************************/ /* Delete a Value from the Arrays Value list. */ /***********************************************************************/ -PBVAL BJSON::DeleteValue(PBVAL bap, int n) +void BJSON::DeleteValue(PBVAL bap, int n) { - PBVAL bvp = bap, pvp = NULL; + CheckType(bap, TYPE_JAR); + int i = 0; + PBVAL bvp, pvp = NULL; - if (bvp) - for (int i = 0; bvp; i++, bvp = MVP(bvp->Next)) + for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp)) if (i == n) { if (pvp) pvp->Next = bvp->Next; else - bap = bvp; + bap->To_Val = bvp->Next; + bap->Nd--; break; } // endif i - return bap; } // end of DeleteValue /***********************************************************************/ @@ -1238,7 +1254,9 @@ PBVAL BJSON::DeleteValue(PBVAL bap, int n) /***********************************************************************/ bool BJSON::IsArrayNull(PBVAL bap) { - for (PBVAL bvp = bap; bvp; bvp = MVP(bvp->Next)) + CheckType(bap, TYPE_JAR); + + for (PBVAL bvp = GetArray(bap); bvp; bvp = GetNext(bvp)) if (bvp->Type != TYPE_NULL) return false; @@ -1288,9 +1306,10 @@ PBVAL BJSON::SubAllocStr(OFFSET toval, short nd) /***********************************************************************/ /* Allocate a BVALUE with a given string or numeric value. */ /***********************************************************************/ -PBVAL BJSON::SubAllocVal(PVAL valp) +PBVAL BJSON::NewVal(PVAL valp) { PBVAL vlp = NewVal(); + SetValue(vlp, valp); return vlp; } // end of SubAllocVal @@ -1306,90 +1325,6 @@ PBVAL BJSON::DupVal(PBVAL bvlp) { return bvp; } // end of DupVal -#if 0 -/***********************************************************************/ -/* Constructor for a JVALUE. */ -/***********************************************************************/ -JVALUE::JVALUE(PJSON jsp) : JSON() { - 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; - Type = TYPE_JVAL; -} // end of JVALUE constructor - -/***********************************************************************/ -/* 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 - -#if 0 -/***********************************************************************/ -/* 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; - -} // end of GetValType -#endif // 0 - /***********************************************************************/ /* Return the size of value's value. */ /***********************************************************************/ @@ -1397,37 +1332,15 @@ int BJSON::GetSize(PBVAL vlp, bool b) { switch (vlp->Type) { case TYPE_JAR: - return GetArraySize(MVP(vlp->To_Val)); + return GetArraySize(vlp); case TYPE_JOB: - return GetObjectSize(MPP(vlp->To_Val)); + return GetObjectSize(vlp); default: return 1; } // enswitch Type } // end of GetSize -/***********************************************************************/ -/* Return the Value's Object value. */ -/***********************************************************************/ -PBPR BJSON::GetObject(PBVAL vlp) -{ - if (vlp->Type == TYPE_JOB) - return MPP(vlp->To_Val); - - return NULL; -} // end of GetObject - -/***********************************************************************/ -/* Return the Value's Array value. */ -/***********************************************************************/ -PBVAL BJSON::GetArray(PBVAL vlp) -{ - if (vlp->Type == TYPE_JAR) - return MVP(vlp->To_Val); - - return NULL; -} // end of GetArray - /***********************************************************************/ /* Return the Value's as a Value struct. */ /***********************************************************************/ @@ -1604,11 +1517,12 @@ PSZ BJSON::GetString(PBVAL vp, char* buff) /***********************************************************************/ /* Return the Value's String value. */ /***********************************************************************/ -PSZ BJSON::GetValueText(PGLOBAL g, PBVAL vlp, PSTRG text) { +PSZ BJSON::GetValueText(PGLOBAL g, PBVAL vlp, PSTRG text) +{ if (vlp->Type == TYPE_JOB) - return GetObjectText(g, MPP(vlp->To_Val), text); + return GetObjectText(g, vlp, text); else if (vlp->Type == TYPE_JAR) - return GetArrayText(g, MVP(vlp->To_Val), text); + return GetArrayText(g, vlp, text); char buff[32]; PSZ s = (vlp->Type == TYPE_NULL) ? NULL : GetString(vlp, buff); @@ -1621,15 +1535,19 @@ PSZ BJSON::GetValueText(PGLOBAL g, PBVAL vlp, PSTRG text) { return NULL; } // end of GetText -void BJSON::SetValueObj(PBVAL vlp, PBPR bop) +void BJSON::SetValueObj(PBVAL vlp, PBVAL bop) { - vlp->To_Val = MOF(bop); + CheckType(bop, TYPE_JOB); + vlp->To_Val = bop->To_Val; + vlp->Nd = bop->Nd; vlp->Type = TYPE_JOB; } // end of SetValueObj; void BJSON::SetValueArr(PBVAL vlp, PBVAL bap) { - vlp->To_Val = MOF(bap); + CheckType(bap, TYPE_JAR); + vlp->To_Val = bap->To_Val; + vlp->Nd = bap->Nd; vlp->Type = TYPE_JAR; } // end of SetValue; @@ -1640,14 +1558,17 @@ void BJSON::SetValueVal(PBVAL vlp, PBVAL vp) vlp->Type = vp->Type; } // end of SetValue; -void BJSON::SetValue(PBVAL vlp, PVAL valp) +PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp) { + if (!vlp) + vlp = NewVal(); + if (!valp || valp->IsNull()) { vlp->Type = TYPE_NULL; } else switch (valp->GetType()) { case TYPE_DATE: if (((DTVAL*)valp)->IsFormatted()) - vlp->To_Val = MOF(valp->GetCharValue()); + vlp->To_Val = MOF(PlugDup(G, valp->GetCharValue())); else { char buf[32]; @@ -1657,7 +1578,7 @@ void BJSON::SetValue(PBVAL vlp, PVAL valp) vlp->Type = TYPE_DTM; break; case TYPE_STRING: - vlp->To_Val = MOF(valp->GetCharValue()); + vlp->To_Val = MOF(PlugDup(G, valp->GetCharValue())); vlp->Type = TYPE_STRG; break; case TYPE_DOUBLE: @@ -1702,6 +1623,7 @@ void BJSON::SetValue(PBVAL vlp, PVAL valp) throw(777); } // endswitch Type + return vlp; } // end of SetValue /***********************************************************************/ @@ -1769,10 +1691,10 @@ bool BJSON::IsValueNull(PBVAL vlp) { b = true; break; case TYPE_JOB: - b = IsObjectNull(MPP(vlp->To_Val)); + b = IsObjectNull(vlp); break; case TYPE_JAR: - b = IsArrayNull(MVP(vlp->To_Val)); + b = IsArrayNull(vlp); break; default: b = false; -- cgit v1.2.1 From 871532c3b9155fa00f7de61ef02f0c2d0f862d57 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 8 Dec 2020 01:15:40 +0100 Subject: - Continue BSON implementation modified: storage/connect/bson.cpp modified: storage/connect/bson.h modified: storage/connect/bsonudf.cpp modified: storage/connect/cmgfam.cpp modified: storage/connect/cmgfam.h modified: storage/connect/ha_connect.cc modified: storage/connect/jmgfam.cpp modified: storage/connect/jmgfam.h modified: storage/connect/jmgoconn.cpp modified: storage/connect/mycat.cc modified: storage/connect/tabbson.cpp modified: storage/connect/tabjson.cpp --- storage/connect/bson.cpp | 71 +++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 25 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index b4ce7ec1505..bf0755d4eae 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -108,7 +108,8 @@ BDOC::BDOC(PGLOBAL G) : BJSON(G, NULL) /* Parse a json string. */ /* Note: when pretty is not known, the caller set pretty to 3. */ /***********************************************************************/ -PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { +PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) +{ int i, pretty = (ptyp) ? *ptyp : 3; bool b = false; @@ -233,7 +234,8 @@ OFFSET BDOC::ParseAsArray(int& i, int pretty, int* ptyp) { /***********************************************************************/ /* Parse a JSON Array. */ /***********************************************************************/ -OFFSET BDOC::ParseArray(int& i) { +OFFSET BDOC::ParseArray(int& i) +{ int level = 0; bool b = (!i); PBVAL vlp, firstvlp, lastvlp; @@ -290,7 +292,8 @@ OFFSET BDOC::ParseArray(int& i) { /***********************************************************************/ /* Parse a JSON Object. */ /***********************************************************************/ -OFFSET BDOC::ParseObject(int& i) { +OFFSET BDOC::ParseObject(int& i) +{ OFFSET key; int level = 0; PBPR bpp, firstbpp, lastbpp; @@ -439,7 +442,8 @@ err: /***********************************************************************/ /* Unescape and parse a JSON string. */ /***********************************************************************/ -OFFSET BDOC::ParseString(int& i) { +OFFSET BDOC::ParseString(int& i) +{ uchar* p; int n = 0; @@ -448,13 +452,13 @@ OFFSET BDOC::ParseString(int& i) { throw("ParseString: Out of memory"); // The size to allocate is not known yet - p = (uchar*)PlugSubAlloc(G, NULL, 0); + p = (uchar*)BsonSubAlloc(0); for (; i < len; i++) switch (s[i]) { case '"': p[n++] = 0; - PlugSubAlloc(G, NULL, n); + BsonSubAlloc(n); return MOF(p); case '\\': if (++i < len) { @@ -525,7 +529,8 @@ throw("Unexpected EOF in String"); /***********************************************************************/ /* Parse a JSON numeric value. */ /***********************************************************************/ -void BDOC::ParseNumeric(int& i, PBVAL vlp) { +void BDOC::ParseNumeric(int& i, PBVAL vlp) +{ char buf[50]; int n = 0; short nd = 0; @@ -580,7 +585,7 @@ fin: if (has_dot || has_e) { double dv = strtod(buf, NULL); - if (nd > 6) { + if (nd > 5 || dv > FLT_MAX || dv < FLT_MIN) { double* dvp = (double*)PlugSubAlloc(G, NULL, sizeof(double)); *dvp = dv; @@ -620,7 +625,8 @@ err: /***********************************************************************/ /* Serialize a BJSON document tree: */ /***********************************************************************/ -PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { +PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) +{ PSZ str = NULL; bool b = false, err = true; FILE* fs = NULL; @@ -697,7 +703,8 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) { /***********************************************************************/ /* Serialize a JSON Array. */ /***********************************************************************/ -bool BDOC::SerializeArray(OFFSET arp, bool b) { +bool BDOC::SerializeArray(OFFSET arp, bool b) +{ bool first = true; PBVAL vp = MVP(arp); @@ -740,7 +747,8 @@ bool BDOC::SerializeArray(OFFSET arp, bool b) { /***********************************************************************/ /* Serialize a JSON Object. */ /***********************************************************************/ -bool BDOC::SerializeObject(OFFSET obp) { +bool BDOC::SerializeObject(OFFSET obp) +{ bool first = true; PBPR prp = MPP(obp); @@ -768,7 +776,8 @@ bool BDOC::SerializeObject(OFFSET obp) { /***********************************************************************/ /* Serialize a JSON Value. */ /***********************************************************************/ -bool BDOC::SerializeValue(PBVAL jvp) { +bool BDOC::SerializeValue(PBVAL jvp) +{ char buf[64]; if (jvp) switch (jvp->Type) { @@ -833,7 +842,22 @@ void* BJSON::BsonSubAlloc(size_t size) xtrc(16, "Done memp=%p used=%zd free=%zd\n", memp, pph->To_Free, pph->FreeBlk); return memp; -} /* end of BsonSubAlloc */ +} // end of BsonSubAlloc + +/*********************************************************************************/ +/* Program for SubSet re-initialization of the memory pool. */ +/*********************************************************************************/ +OFFSET BJSON::DupStr(PSZ str) +{ + if (str) { + PSZ sm = (PSZ)BsonSubAlloc(strlen(str) + 1); + + strcpy(sm, str); + return MOF(sm); + } else + return NULL; + +} // end of DupStr /*********************************************************************************/ /* Program for SubSet re-initialization of the memory pool. */ @@ -888,7 +912,7 @@ void BJSON::AddPair(PBVAL bop, PSZ key, OFFSET val) { CheckType(bop, TYPE_JOB); PBPR brp; - OFFSET nrp = MOF(SubAllocPair(key, val)); + OFFSET nrp = NewPair(key, val); if (bop->To_Val) { for (brp = GetObject(bop); brp->Next; brp = GetNext(brp)); @@ -948,8 +972,9 @@ PBVAL BJSON::GetKeyValue(PBVAL bop, PSZ key) PSZ BJSON::GetObjectText(PGLOBAL g, PBVAL bop, PSTRG text) { CheckType(bop, TYPE_JOB); + PBPR brp = GetObject(bop); - if (bop->To_Val) { + if (brp) { bool b; if (!text) { @@ -962,12 +987,11 @@ PSZ BJSON::GetObjectText(PGLOBAL g, PBVAL bop, PSTRG text) b = false; } // endif text -#if 0 - if (b && !bop->Next && !strcmp(MZP(bop->Key), "$date")) { + if (b && !brp->Next && !strcmp(MZP(brp->Key), "$date")) { int i; PSZ s; - First->Val->GetText(g, text); + GetValueText(g, MVP(brp->Vlp), text); s = text->GetStr(); i = (s[1] == '-' ? 2 : 1); @@ -983,10 +1007,7 @@ PSZ BJSON::GetObjectText(PGLOBAL g, PBVAL bop, PSTRG text) } // endif text - } else -#endif // 0 - - for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) { + } else for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) { GetValueText(g, GetVal(brp), text); if (brp->Next) @@ -1021,10 +1042,10 @@ void BJSON::SetKeyValue(PBVAL bop, OFFSET bvp, PSZ key) prp = brp; if (!brp) - prp->Next = MOF(SubAllocPair(key, bvp)); + prp->Next = NewPair(key, bvp); } else - bop->To_Val = MOF(SubAllocPair(key, bvp)); + bop->To_Val = NewPair(key, bvp); bop->Nd++; } // end of SetKeyValue @@ -1301,7 +1322,7 @@ PBVAL BJSON::SubAllocStr(OFFSET toval, short nd) bvp->To_Val = toval; bvp->Nd = nd; return bvp; -} // end of SubAllocVal +} // end of SubAllocStr /***********************************************************************/ /* Allocate a BVALUE with a given string or numeric value. */ -- cgit v1.2.1 From 4eeadedc77018da781eb7ea008fd3474f1a354d5 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Wed, 9 Dec 2020 00:55:06 +0100 Subject: - Fix json_bjson (s was erase by Json_Subset) modified: storage/connect/jsonudf.cpp modified: storage/connect/jsonudf.h - Fix compile error (Force_Bson was not conditional by BSON_SUPPORT) modified: storage/connect/ha_connect.cc - Continue Bjson implementation modified: storage/connect/block.h modified: storage/connect/bson.cpp modified: storage/connect/bson.h modified: storage/connect/bsonudf.cpp modified: storage/connect/bsonudf.h modified: storage/connect/plugutil.cpp modified: storage/connect/tabbson.cpp modified: storage/connect/tabjson.cpp - Typo deleted: storage/connect/Header.h --- storage/connect/bson.cpp | 58 +++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index bf0755d4eae..a291dd69df6 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -1,9 +1,9 @@ -/*************** json CPP Declares Source Code File (.H) ***************/ -/* Name: json.cpp Version 1.5 */ +/*************** bson CPP Declares Source Code File (.H) ***************/ +/* Name: bson.cpp Version 1.0 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2020 */ +/* (C) Copyright to the author Olivier BERTRAND 2020 */ /* */ -/* This file contains the JSON classes functions. */ +/* This file contains the BJSON classes functions. */ /***********************************************************************/ /***********************************************************************/ @@ -15,7 +15,7 @@ /* 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. */ +/* bson.h is header containing the BSON classes declarations. */ /***********************************************************************/ #include "global.h" #include "plgdbsem.h" @@ -112,6 +112,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) { int i, pretty = (ptyp) ? *ptyp : 3; bool b = false; + PBVAL bvp = NULL; s = js; len = lng; @@ -128,26 +129,26 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) pty[0] = false; try { - Bvp = NewVal(); - Bvp->Type = TYPE_UNKNOWN; + bvp = NewVal(); + bvp->Type = TYPE_UNKNOWN; for (i = 0; i < len; i++) switch (s[i]) { case '[': - if (Bvp->Type != TYPE_UNKNOWN) - Bvp->To_Val = ParseAsArray(i, pretty, ptyp); + if (bvp->Type != TYPE_UNKNOWN) + bvp->To_Val = ParseAsArray(i, pretty, ptyp); else - Bvp->To_Val = ParseArray(++i); + bvp->To_Val = ParseArray(++i); - Bvp->Type = TYPE_JAR; + bvp->Type = TYPE_JAR; break; case '{': - if (Bvp->Type != TYPE_UNKNOWN) { - Bvp->To_Val = ParseAsArray(i, pretty, ptyp); - Bvp->Type = TYPE_JAR; + if (bvp->Type != TYPE_UNKNOWN) { + bvp->To_Val = ParseAsArray(i, pretty, ptyp); + bvp->Type = TYPE_JAR; } else { - Bvp->To_Val = ParseObject(++i); - Bvp->Type = TYPE_JOB; + bvp->To_Val = ParseObject(++i); + bvp->Type = TYPE_JOB; } // endif Type break; @@ -157,7 +158,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) case '\r': break; case ',': - if (Bvp->Type != TYPE_UNKNOWN && (pretty == 1 || pretty == 3)) { + if (bvp->Type != TYPE_UNKNOWN && (pretty == 1 || pretty == 3)) { if (comma) *comma = true; @@ -177,18 +178,18 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) } // endif b default: - if (Bvp->Type != TYPE_UNKNOWN) { - Bvp->To_Val = ParseAsArray(i, pretty, ptyp); - Bvp->Type = TYPE_JAR; - } else if ((Bvp->To_Val = MOF(ParseValue(i)))) - Bvp->Type = TYPE_JVAL; + if (bvp->Type != TYPE_UNKNOWN) { + bvp->To_Val = ParseAsArray(i, pretty, ptyp); + bvp->Type = TYPE_JAR; + } else if ((bvp->To_Val = MOF(ParseValue(i)))) + bvp->Type = TYPE_JVAL; else throw 4; break; }; // endswitch s[i] - if (Bvp->Type == TYPE_UNKNOWN) + if (bvp->Type == TYPE_UNKNOWN) sprintf(g->Message, "Invalid Json string '%.*s'", MY_MIN((int)len, 50), s); else if (ptyp && pretty == 3) { *ptyp = 3; // Not recognized pretty @@ -205,13 +206,13 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) if (trace(1)) htrc("Exception %d: %s\n", n, G->Message); GetMsg(g); - Bvp = NULL; + bvp = NULL; } catch (const char* msg) { strcpy(g->Message, msg); - Bvp = NULL; + bvp = NULL; } // end catch - return Bvp; + return bvp; } // end of ParseJson /***********************************************************************/ @@ -391,13 +392,11 @@ suite: bvp->Type = TYPE_JOB; break; case '"': - // jvp->Val = AllocVal(g, TYPE_STRG); bvp->To_Val = ParseString(++i); bvp->Type = TYPE_STRG; break; case 't': if (!strncmp(s + i, "true", 4)) { - // jvp->Val = AllocVal(g, TYPE_BOOL); bvp->B = true; bvp->Type = TYPE_BOOL; i += 3; @@ -407,7 +406,6 @@ suite: break; case 'f': if (!strncmp(s + i, "false", 5)) { - // jvp->Val = AllocVal(g, TYPE_BOOL); bvp->B = false; bvp->Type = TYPE_BOOL; i += 4; @@ -872,7 +870,7 @@ void BJSON::SubSet(bool b) if (b) G->Saved_Size = 0; -} /* end of JsonSubSet */ +} // end of SubSet /* ------------------------ Bobject functions ------------------------ */ -- cgit v1.2.1 From ceacffbb3b9504c88d0649d472396fa42397a62c Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 15 Dec 2020 12:28:03 +0100 Subject: - Fix pretty=2 Tabjson bug on INSERT. Occuring when inserting more than one line in one statement. modified: storage/connect/json.cpp - Fix a wrong if statement modified: storage/connect/tabjson.cpp - Continue BSON implementation modified: storage/connect/bson.cpp modified: storage/connect/bson.h modified: storage/connect/filamtxt.cpp modified: storage/connect/filamtxt.h modified: storage/connect/tabbson.cpp modified: storage/connect/tabbson.h - No need anymore deleted: storage/connect/mysql-test/connect/r/bson.result deleted: storage/connect/mysql-test/connect/t/bson.test --- storage/connect/bson.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index a291dd69df6..08f4dca46f2 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -872,7 +872,18 @@ void BJSON::SubSet(bool b) } // end of SubSet -/* ------------------------ Bobject functions ------------------------ */ +/*********************************************************************************/ +/* Set the beginning of suballocations. */ +/*********************************************************************************/ +void BJSON::MemSet(size_t size) +{ + PPOOLHEADER pph = (PPOOLHEADER)G->Sarea; + + pph->To_Free = size + sizeof(POOLHEADER); + pph->FreeBlk = G->Sarea_Size - pph->To_Free; +} // end of MemSet + + /* ------------------------ Bobject functions ------------------------ */ /***********************************************************************/ /* Sub-allocate and initialize a BPAIR. */ @@ -1187,18 +1198,17 @@ void BJSON::MergeArray(PBVAL bap1, PBVAL bap2) void BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n) { CheckType(bap, TYPE_JAR); + int i = 0; PBVAL bvp = NULL, pvp = NULL; - if (bap->To_Val) { - for (int i = 0; bvp = GetArray(bap); i++, bvp = GetNext(bvp)) + if (bap->To_Val) + for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp)) if (i == n) { SetValueVal(bvp, nvp); return; } else pvp = bvp; - } // endif bap - if (!bvp) AddArrayValue(bap, MOF(nvp)); @@ -1264,7 +1274,8 @@ void BJSON::DeleteValue(PBVAL bap, int n) bap->Nd--; break; - } // endif i + } else + pvp = bvp; } // end of DeleteValue @@ -1587,17 +1598,17 @@ PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp) } else switch (valp->GetType()) { case TYPE_DATE: if (((DTVAL*)valp)->IsFormatted()) - vlp->To_Val = MOF(PlugDup(G, valp->GetCharValue())); + vlp->To_Val = DupStr(valp->GetCharValue()); else { char buf[32]; - vlp->To_Val = MOF(PlugDup(G, valp->GetCharString(buf))); + vlp->To_Val = DupStr(valp->GetCharString(buf)); } // endif Formatted vlp->Type = TYPE_DTM; break; case TYPE_STRING: - vlp->To_Val = MOF(PlugDup(G, valp->GetCharValue())); + vlp->To_Val = DupStr(valp->GetCharValue()); vlp->Type = TYPE_STRG; break; case TYPE_DOUBLE: @@ -1608,7 +1619,7 @@ PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp) vlp->F = (float)valp->GetFloatValue(); vlp->Type = TYPE_FLOAT; } else { - double *dp = (double*)PlugSubAlloc(G, NULL, sizeof(double)); + double *dp = (double*)BsonSubAlloc(sizeof(double)); *dp = valp->GetFloatValue(); vlp->To_Val = MOF(dp); @@ -1629,7 +1640,7 @@ PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp) vlp->N = valp->GetIntValue(); vlp->Type = TYPE_INTG; } else { - longlong* llp = (longlong*)PlugSubAlloc(G, NULL, sizeof(longlong)); + longlong* llp = (longlong*)BsonSubAlloc(sizeof(longlong)); *llp = valp->GetBigintValue(); vlp->To_Val = MOF(llp); -- cgit v1.2.1 From a7867410009ce91e3e710ace0b0d97261170d44a Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 17 Dec 2020 13:58:13 +0100 Subject: - Fix crash with JsonContains UDF + BSON development --- storage/connect/bson.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 08f4dca46f2..f7d4e5731c5 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -27,7 +27,7 @@ #if defined(_DEBUG) #define CheckType(X,Y) if (!X || X ->Type != Y) throw MSG(VALTYPE_NOMATCH); #else -#define CheckType(V) +#define CheckType(X,Y) #endif #if defined(__WIN__) -- cgit v1.2.1 From 2113cab7ec808721d3492870f094d681842e7274 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 22 Dec 2020 22:50:12 +0100 Subject: Make REST tables default file name. Commit before continuing BSON development --- storage/connect/bson.cpp | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index f7d4e5731c5..df95bd4c9c8 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -101,17 +101,19 @@ BDOC::BDOC(PGLOBAL G) : BJSON(G, NULL) jp = NULL; s = NULL; len = 0; + pretty = 3; pty[0] = pty[1] = pty[2] = true; + comma = false; } // end of BDOC constructor /***********************************************************************/ /* Parse a json string. */ /* Note: when pretty is not known, the caller set pretty to 3. */ /***********************************************************************/ -PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) +PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng) { - int i, pretty = (ptyp) ? *ptyp : 3; - bool b = false; + int i; + bool b = false, ptyp = (bool *)pty; PBVAL bvp = NULL; s = js; @@ -121,8 +123,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) if (!s || !len) { strcpy(g->Message, "Void JSON object"); return NULL; - } else if (comma) - *comma = false; + } // endif s // Trying to guess the pretty format if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n'))) @@ -136,7 +137,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) switch (s[i]) { case '[': if (bvp->Type != TYPE_UNKNOWN) - bvp->To_Val = ParseAsArray(i, pretty, ptyp); + bvp->To_Val = ParseAsArray(i); else bvp->To_Val = ParseArray(++i); @@ -144,7 +145,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) break; case '{': if (bvp->Type != TYPE_UNKNOWN) { - bvp->To_Val = ParseAsArray(i, pretty, ptyp); + bvp->To_Val = ParseAsArray(i); bvp->Type = TYPE_JAR; } else { bvp->To_Val = ParseObject(++i); @@ -159,9 +160,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) break; case ',': if (bvp->Type != TYPE_UNKNOWN && (pretty == 1 || pretty == 3)) { - if (comma) - *comma = true; - + comma = true; pty[0] = pty[2] = false; break; } // endif pretty @@ -179,7 +178,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) default: if (bvp->Type != TYPE_UNKNOWN) { - bvp->To_Val = ParseAsArray(i, pretty, ptyp); + bvp->To_Val = ParseAsArray(i); bvp->Type = TYPE_JAR; } else if ((bvp->To_Val = MOF(ParseValue(i)))) bvp->Type = TYPE_JVAL; @@ -191,12 +190,10 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) if (bvp->Type == TYPE_UNKNOWN) sprintf(g->Message, "Invalid Json string '%.*s'", MY_MIN((int)len, 50), s); - else if (ptyp && pretty == 3) { - *ptyp = 3; // Not recognized pretty - + else if (pretty == 3) { for (i = 0; i < 3; i++) if (pty[i]) { - *ptyp = i; + pretty = i; break; } // endif pty @@ -218,12 +215,12 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng, int* ptyp, bool* comma) /***********************************************************************/ /* Parse several items as being in an array. */ /***********************************************************************/ -OFFSET BDOC::ParseAsArray(int& i, int pretty, int* ptyp) { +OFFSET BDOC::ParseAsArray(int& i) { if (pty[0] && (!pretty || pretty > 2)) { OFFSET jsp; - if ((jsp = ParseArray((i = 0))) && ptyp && pretty == 3) - *ptyp = (pty[0]) ? 0 : 3; + if ((jsp = ParseArray((i = 0))) && pretty == 3) + pretty = (pty[0]) ? 0 : 3; return jsp; } else -- cgit v1.2.1 From a35424829a4534ad63a80f30a73adb0ce74f742e Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 26 Dec 2020 19:44:38 +0100 Subject: - Continue BSON implementation + fix create modified ha_connect.cc --- storage/connect/bson.cpp | 174 ++++++++++++++++++++++++----------------------- 1 file changed, 90 insertions(+), 84 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index df95bd4c9c8..cdb619d07ca 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -59,38 +59,6 @@ void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp) { char* GetExceptionDesc(PGLOBAL g, unsigned int e); #endif // SE_CATCH -#if 0 -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; - - return true; -} // end of IsNum - -/***********************************************************************/ -/* 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; - else if (p1) - return MY_MIN(p1, p2); - - return p2; -} // end of NextChr -#endif // 0 - /* --------------------------- Class BDOC ---------------------------- */ /***********************************************************************/ @@ -180,7 +148,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng) if (bvp->Type != TYPE_UNKNOWN) { bvp->To_Val = ParseAsArray(i); bvp->Type = TYPE_JAR; - } else if ((bvp->To_Val = MOF(ParseValue(i)))) + } else if ((bvp->To_Val = MOF(ParseValue(i, NewVal())))) bvp->Type = TYPE_JVAL; else throw 4; @@ -269,11 +237,11 @@ OFFSET BDOC::ParseArray(int& i) sprintf(G->Message, "Unexpected value near %.*s", ARGS); throw 1; } else if (lastvlp) { - vlp = ParseValue(i); + vlp = ParseValue(i, NewVal()); lastvlp->Next = MOF(vlp); lastvlp = vlp; } else - firstvlp = lastvlp = ParseValue(i); + firstvlp = lastvlp = ParseValue(i, NewVal()); level = (b) ? 1 : 2; break; @@ -303,10 +271,10 @@ OFFSET BDOC::ParseObject(int& i) case '"': if (level < 2) { key = ParseString(++i); - bpp = SubAllocPair(key); + bpp = NewPair(key); if (lastbpp) { - lastbpp->Next = MOF(bpp); + lastbpp->Vlp.Next = MOF(bpp); lastbpp = bpp; } else firstbpp = lastbpp = bpp; @@ -320,7 +288,7 @@ OFFSET BDOC::ParseObject(int& i) break; case ':': if (level == 2) { - lastbpp->Vlp = MOF(ParseValue(++i)); + ParseValue(++i, GetVlp(lastbpp)); level = 3; } else { sprintf(G->Message, "Unexpected ':' near %.*s", ARGS); @@ -362,10 +330,8 @@ OFFSET BDOC::ParseObject(int& i) /***********************************************************************/ /* Parse a JSON Value. */ /***********************************************************************/ -PBVAL BDOC::ParseValue(int& i) +PBVAL BDOC::ParseValue(int& i, PBVAL bvp) { - PBVAL bvp = NewVal(); - for (; i < len; i++) switch (s[i]) { case '\n': @@ -750,7 +716,7 @@ bool BDOC::SerializeObject(OFFSET obp) if (jp->WriteChr('{')) return true; - for (prp; prp; prp = MPP(prp->Next)) { + for (prp; prp; prp = GetNext(prp)) { if (first) first = false; else if (jp->WriteChr(',')) @@ -760,7 +726,7 @@ bool BDOC::SerializeObject(OFFSET obp) jp->WriteStr(MZP(prp->Key)) || jp->WriteChr('"') || jp->WriteChr(':') || - SerializeValue(MVP(prp->Vlp))) + SerializeValue(GetVlp(prp))) return true; } // endfor i @@ -883,15 +849,35 @@ void BJSON::MemSet(size_t size) /* ------------------------ Bobject functions ------------------------ */ /***********************************************************************/ +/* Set a pair vlp to some PVAL values. */ +/***********************************************************************/ +void BJSON::SetPairValue(PBPR brp, PBVAL bvp) +{ + if (bvp) { + brp->Vlp.To_Val = bvp->To_Val; + brp->Vlp.Nd = bvp->Nd; + brp->Vlp.Type = bvp->Type; + } else { + brp->Vlp.To_Val = 0; + brp->Vlp.Nd = 0; + brp->Vlp.Type = TYPE_NULL; + } // endif bvp + +} // end of SetPairValue + + /***********************************************************************/ /* Sub-allocate and initialize a BPAIR. */ /***********************************************************************/ -PBPR BJSON::SubAllocPair(OFFSET key, OFFSET val) +PBPR BJSON::NewPair(OFFSET key, int type) { PBPR bpp = (PBPR)BsonSubAlloc(sizeof(BPAIR)); bpp->Key = key; - bpp->Vlp = val; - bpp->Next = 0; + bpp->Vlp.Ktp = TYPE_STRG; + bpp->Vlp.Type = type; + bpp->Vlp.To_Val = 0; + bpp->Vlp.Nd = 0; + bpp->Vlp.Next = 0; return bpp; } // end of SubAllocPair @@ -905,7 +891,7 @@ int BJSON::GetObjectSize(PBVAL bop, bool b) for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) // If b return only non null pairs - if (!b || (brp->Vlp && GetVal(brp)->Type != TYPE_NULL)) + if (!b || (brp->Vlp.To_Val && brp->Vlp.Type != TYPE_NULL)) n++; return n; @@ -914,20 +900,21 @@ int BJSON::GetObjectSize(PBVAL bop, bool b) /***********************************************************************/ /* Add a new pair to an Object and return it. */ /***********************************************************************/ -void BJSON::AddPair(PBVAL bop, PSZ key, OFFSET val) +PBVAL BJSON::AddPair(PBVAL bop, PSZ key, int type) { CheckType(bop, TYPE_JOB); PBPR brp; - OFFSET nrp = NewPair(key, val); + OFFSET nrp = NewPair(key, type); if (bop->To_Val) { - for (brp = GetObject(bop); brp->Next; brp = GetNext(brp)); + for (brp = GetObject(bop); brp->Vlp.Next; brp = GetNext(brp)); - brp->Next = nrp; + brp->Vlp.Next = nrp; } else bop->To_Val = nrp; bop->Nd++; + return GetVlp(MPP(nrp)); } // end of AddPair /***********************************************************************/ @@ -953,7 +940,7 @@ PBVAL BJSON::GetObjectValList(PBVAL bop) PBVAL arp = NewVal(TYPE_JAR); for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) - AddArrayValue(arp, brp->Vlp); + AddArrayValue(arp, GetVlp(brp)); return arp; } // end of GetObjectValList @@ -967,7 +954,7 @@ PBVAL BJSON::GetKeyValue(PBVAL bop, PSZ key) for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) if (!strcmp(GetKey(brp), key)) - return GetVal(brp); + return GetVlp(brp); return NULL; } // end of GetKeyValue; @@ -993,11 +980,11 @@ PSZ BJSON::GetObjectText(PGLOBAL g, PBVAL bop, PSTRG text) b = false; } // endif text - if (b && !brp->Next && !strcmp(MZP(brp->Key), "$date")) { + if (b && !brp->Vlp.Next && !strcmp(MZP(brp->Key), "$date")) { int i; PSZ s; - GetValueText(g, MVP(brp->Vlp), text); + GetValueText(g, GetVlp(brp), text); s = text->GetStr(); i = (s[1] == '-' ? 2 : 1); @@ -1013,10 +1000,10 @@ PSZ BJSON::GetObjectText(PGLOBAL g, PBVAL bop, PSTRG text) } // endif text - } else for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) { - GetValueText(g, GetVal(brp), text); + } else for (; brp; brp = GetNext(brp)) { + GetValueText(g, GetVlp(brp), text); - if (brp->Next) + if (brp->Vlp.Next) text->Append(' '); } // endfor brp @@ -1041,18 +1028,18 @@ void BJSON::SetKeyValue(PBVAL bop, OFFSET bvp, PSZ key) if (bop->To_Val) { for (brp = GetObject(bop); brp; brp = GetNext(brp)) - if (!strcmp(GetKey(brp), key)) { - brp->Vlp = bvp; - return; - } else + if (!strcmp(GetKey(brp), key)) + break; + else prp = brp; if (!brp) - prp->Next = NewPair(key, bvp); + brp = MPP(prp->Vlp.Next = NewPair(key)); } else - bop->To_Val = NewPair(key, bvp); + brp = MPP(bop->To_Val = NewPair(key)); + SetPairValue(brp, MVP(bvp)); bop->Nd++; } // end of SetKeyValue @@ -1066,7 +1053,7 @@ PBVAL BJSON::MergeObject(PBVAL bop1, PBVAL bop2) if (bop1->To_Val) for (PBPR brp = GetObject(bop2); brp; brp = GetNext(brp)) - SetKeyValue(bop1, brp->Vlp, GetKey(brp)); + SetKeyValue(bop1, GetVlp(brp), GetKey(brp)); else { bop1->To_Val = bop2->To_Val; @@ -1087,9 +1074,9 @@ void BJSON::DeleteKey(PBVAL bop, PCSZ key) for (brp = GetObject(bop); brp; brp = GetNext(brp)) if (!strcmp(MZP(brp->Key), key)) { if (pbrp) { - pbrp->Next = brp->Next; + pbrp->Vlp.Next = brp->Vlp.Next; } else - bop->To_Val = brp->Next; + bop->To_Val = brp->Vlp.Next; bop->Nd--; break; @@ -1106,7 +1093,7 @@ bool BJSON::IsObjectNull(PBVAL bop) CheckType(bop, TYPE_JOB); for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) - if (brp->Vlp && (MVP(brp->Vlp))->Type != TYPE_NULL) + if (brp->Vlp.To_Val && brp->Vlp.Type != TYPE_NULL) return false; return true; @@ -1368,6 +1355,25 @@ int BJSON::GetSize(PBVAL vlp, bool b) } // end of GetSize +PBVAL BJSON::GetBson(PBVAL bvp) +{ + PBVAL bp = NULL; + + switch (bvp->Type) { + case TYPE_JAR: + bp = MVP(bvp->To_Val); + break; + case TYPE_JOB: + bp = GetVlp(MPP(bvp->To_Val)); + break; + default: + bp = bvp; + break; + } // endswitch Type + + return bp; +} // end of GetBson + /***********************************************************************/ /* Return the Value's as a Value struct. */ /***********************************************************************/ @@ -1378,22 +1384,22 @@ PVAL BJSON::GetValue(PGLOBAL g, PBVAL vp) PBVAL vlp = vp->Type == TYPE_JVAL ? MVP(vp->To_Val) : vp; switch (vlp->Type) { - case TYPE_STRG: - case TYPE_DBL: - case TYPE_BINT: - valp = AllocateValue(g, MP(vlp->To_Val), vlp->Type, vlp->Nd); - break; - case TYPE_INTG: - case TYPE_BOOL: - valp = AllocateValue(g, vlp, vlp->Type); - break; - case TYPE_FLOAT: - d = (double)vlp->F; - valp = AllocateValue(g, &d, TYPE_DOUBLE, vlp->Nd); - break; - default: - valp = NULL; - break; + case TYPE_STRG: + case TYPE_DBL: + case TYPE_BINT: + valp = AllocateValue(g, MP(vlp->To_Val), vlp->Type, vlp->Nd); + break; + case TYPE_INTG: + case TYPE_BOOL: + valp = AllocateValue(g, vlp, vlp->Type); + break; + case TYPE_FLOAT: + d = (double)vlp->F; + valp = AllocateValue(g, &d, TYPE_DOUBLE, vlp->Nd); + break; + default: + valp = NULL; + break; } // endswitch Type return valp; -- cgit v1.2.1 From cba46c9912b2bcd062ecc6b53082ba5eb5109e41 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 31 Dec 2020 15:43:52 +0100 Subject: - Fix jfile_convert crash on error. modified: jsonudf.cpp (plus BSON UDF's) --- storage/connect/bson.cpp | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index cdb619d07ca..2588657089f 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -808,17 +808,17 @@ void* BJSON::BsonSubAlloc(size_t size) /*********************************************************************************/ /* Program for SubSet re-initialization of the memory pool. */ /*********************************************************************************/ -OFFSET BJSON::DupStr(PSZ str) +PSZ BJSON::NewStr(PSZ str) { if (str) { PSZ sm = (PSZ)BsonSubAlloc(strlen(str) + 1); strcpy(sm, str); - return MOF(sm); + return sm; } else return NULL; -} // end of DupStr +} // end of NewStr /*********************************************************************************/ /* Program for SubSet re-initialization of the memory pool. */ @@ -940,7 +940,7 @@ PBVAL BJSON::GetObjectValList(PBVAL bop) PBVAL arp = NewVal(TYPE_JAR); for (PBPR brp = GetObject(bop); brp; brp = GetNext(brp)) - AddArrayValue(arp, GetVlp(brp)); + AddArrayValue(arp, DupVal(GetVlp(brp))); return arp; } // end of GetObjectValList @@ -1135,24 +1135,28 @@ PBVAL BJSON::GetArrayValue(PBVAL bap, int n) /***********************************************************************/ /* Add a Value to the Array Value list. */ /***********************************************************************/ -void BJSON::AddArrayValue(PBVAL bap, OFFSET nvp, int* x) +void BJSON::AddArrayValue(PBVAL bap, OFFSET nbv, int* x) { CheckType(bap, TYPE_JAR); - if (!nvp) - nvp = MOF(NewVal()); + int i = 0; + PBVAL bvp, lbp = NULL; - if (bap->To_Val) { - int i = 0, n = (x) ? *x : INT_MAX32; + if (!nbv) + nbv = MOF(NewVal()); - for (PBVAL bvp = GetArray(bap); bvp; bvp = GetNext(bvp), i++) - if (!bvp->Next || (x && i == n)) { - MVP(nvp)->Next = bvp->Next; - bvp->Next = nvp; - break; - } // endif Next + for (bvp = GetArray(bap); bvp; bvp = GetNext(bvp), i++) + if (x && i == *x) + break; + else + lbp = bvp; - } else - bap->To_Val = nvp; + if (lbp) { + MVP(nbv)->Next = lbp->Next; + lbp->Next = nbv; + } else { + MVP(nbv)->Next = bap->To_Val; + bap->To_Val = nbv; + } // endif lbp bap->Nd++; } // end of AddArrayValue -- cgit v1.2.1 From 8f34d45404817a4fe63251ac2ab74da96b6849fa Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 8 Jan 2021 22:18:52 +0100 Subject: - Add the new BSON temporary type for testing modified: storage/connect/CMakeLists.txt modified: storage/connect/bson.cpp modified: storage/connect/bson.h modified: storage/connect/bsonudf.cpp modified: storage/connect/bsonudf.h modified: storage/connect/global.h modified: storage/connect/json.cpp modified: storage/connect/jsonudf.cpp modified: storage/connect/mysql-test/connect/disabled.def modified: storage/connect/mysql-test/connect/t/mongo_test.inc modified: storage/connect/plugutil.cpp modified: storage/connect/tabbson.cpp modified: storage/connect/tabjson.cpp --- storage/connect/bson.cpp | 181 +++++++++++++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 70 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 2588657089f..f3ad919993f 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -544,9 +544,9 @@ fin: buf[n] = 0; if (has_dot || has_e) { - double dv = strtod(buf, NULL); + double dv = atof(buf); - if (nd > 5 || dv > FLT_MAX || dv < FLT_MIN) { + if (nd >= 6 || dv > FLT_MAX || dv < FLT_MIN) { double* dvp = (double*)PlugSubAlloc(G, NULL, sizeof(double)); *dvp = dv; @@ -557,7 +557,7 @@ fin: vlp->Type = TYPE_FLOAT; } // endif nd - vlp->Nd = nd; + vlp->Nd = MY_MIN(nd, 16); } else { longlong iv = strtoll(buf, NULL, 10); @@ -765,6 +765,8 @@ bool BDOC::SerializeValue(PBVAL jvp) return jp->WriteStr(buf); case TYPE_NULL: return jp->WriteStr("null"); + case TYPE_JVAL: + return SerializeValue(MVP(jvp->To_Val)); default: return jp->WriteStr("???"); // TODO } // endswitch Type @@ -793,7 +795,12 @@ void* BJSON::BsonSubAlloc(size_t size) "Not enough memory for request of %zd (used=%zd free=%zd)", size, pph->To_Free, pph->FreeBlk); xtrc(1, "BsonSubAlloc: %s\n", G->Message); - throw(1234); + + if (Throw) + throw(1234); + else + return NULL; + } /* endif size OS32 code */ // Do the suballocation the simplest way @@ -1066,7 +1073,7 @@ PBVAL BJSON::MergeObject(PBVAL bop1, PBVAL bop2) /***********************************************************************/ /* Delete a value corresponding to the given key. */ /***********************************************************************/ -void BJSON::DeleteKey(PBVAL bop, PCSZ key) +bool BJSON::DeleteKey(PBVAL bop, PCSZ key) { CheckType(bop, TYPE_JOB); PBPR brp, pbrp = NULL; @@ -1079,10 +1086,11 @@ void BJSON::DeleteKey(PBVAL bop, PCSZ key) bop->To_Val = brp->Vlp.Next; bop->Nd--; - break; + return true;; } else pbrp = brp; + return false; } // end of DeleteKey /***********************************************************************/ @@ -1247,24 +1255,25 @@ PSZ BJSON::GetArrayText(PGLOBAL g, PBVAL bap, PSTRG text) /***********************************************************************/ /* Delete a Value from the Arrays Value list. */ /***********************************************************************/ -void BJSON::DeleteValue(PBVAL bap, int n) +bool BJSON::DeleteValue(PBVAL bap, int n) { CheckType(bap, TYPE_JAR); int i = 0; PBVAL bvp, pvp = NULL; - for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp)) - if (i == n) { - if (pvp) - pvp->Next = bvp->Next; - else - bap->To_Val = bvp->Next; + for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp)) + if (i == n) { + if (pvp) + pvp->Next = bvp->Next; + else + bap->To_Val = bvp->Next; - bap->Nd--; - break; - } else - pvp = bvp; + bap->Nd--; + return true;; + } else + pvp = bvp; + return false; } // end of DeleteValue /***********************************************************************/ @@ -1510,7 +1519,7 @@ double BJSON::GetDouble(PBVAL vp) } // endswitch Type return d; -} // end of GetFloat +} // end of GetDouble /***********************************************************************/ /* Return the Value's String value. */ @@ -1603,61 +1612,64 @@ PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp) if (!valp || valp->IsNull()) { vlp->Type = TYPE_NULL; } else switch (valp->GetType()) { - case TYPE_DATE: - if (((DTVAL*)valp)->IsFormatted()) - vlp->To_Val = DupStr(valp->GetCharValue()); - else { - char buf[32]; + case TYPE_DATE: + if (((DTVAL*)valp)->IsFormatted()) + vlp->To_Val = DupStr(valp->GetCharValue()); + else { + char buf[32]; - vlp->To_Val = DupStr(valp->GetCharString(buf)); - } // endif Formatted + vlp->To_Val = DupStr(valp->GetCharString(buf)); + } // endif Formatted - vlp->Type = TYPE_DTM; - break; - case TYPE_STRING: - vlp->To_Val = DupStr(valp->GetCharValue()); - vlp->Type = TYPE_STRG; - break; - case TYPE_DOUBLE: - case TYPE_DECIM: - vlp->Nd = (IsTypeNum(valp->GetType())) ? valp->GetValPrec() : 0; + vlp->Type = TYPE_DTM; + break; + case TYPE_STRING: + vlp->To_Val = DupStr(valp->GetCharValue()); + vlp->Type = TYPE_STRG; + break; + case TYPE_DOUBLE: + case TYPE_DECIM: + { double d = valp->GetFloatValue(); + int nd = (IsTypeNum(valp->GetType())) ? valp->GetValPrec() : 0; - if (vlp->Nd <= 6) { - vlp->F = (float)valp->GetFloatValue(); - vlp->Type = TYPE_FLOAT; - } else { - double *dp = (double*)BsonSubAlloc(sizeof(double)); + if (nd <= 6 && d >= FLT_MIN && d <= FLT_MAX) { + vlp->F = (float)valp->GetFloatValue(); + vlp->Type = TYPE_FLOAT; + } else { + double* dp = (double*)BsonSubAlloc(sizeof(double)); - *dp = valp->GetFloatValue(); - vlp->To_Val = MOF(dp); - vlp->Type = TYPE_DBL; - } // endif Nd + *dp = d; + vlp->To_Val = MOF(dp); + vlp->Type = TYPE_DBL; + } // endif Nd - break; - case TYPE_TINY: - vlp->B = valp->GetTinyValue() != 0; - vlp->Type = TYPE_BOOL; - case TYPE_INT: - vlp->N = valp->GetIntValue(); - vlp->Type = TYPE_INTG; - break; - case TYPE_BIGINT: - if (valp->GetBigintValue() >= INT_MIN32 && - valp->GetBigintValue() <= INT_MAX32) { + vlp->Nd = MY_MIN(nd, 16); + } break; + case TYPE_TINY: + vlp->B = valp->GetTinyValue() != 0; + vlp->Type = TYPE_BOOL; + break; + case TYPE_INT: vlp->N = valp->GetIntValue(); vlp->Type = TYPE_INTG; - } else { - longlong* llp = (longlong*)BsonSubAlloc(sizeof(longlong)); + break; + case TYPE_BIGINT: + if (valp->GetBigintValue() >= INT_MIN32 && + valp->GetBigintValue() <= INT_MAX32) { + vlp->N = valp->GetIntValue(); + vlp->Type = TYPE_INTG; + } else { + longlong* llp = (longlong*)BsonSubAlloc(sizeof(longlong)); - *llp = valp->GetBigintValue(); - vlp->To_Val = MOF(llp); - vlp->Type = TYPE_BINT; - } // endif BigintValue + *llp = valp->GetBigintValue(); + vlp->To_Val = MOF(llp); + vlp->Type = TYPE_BINT; + } // endif BigintValue - break; - default: - sprintf(G->Message, "Unsupported typ %d\n", valp->GetType()); - throw(777); + break; + default: + sprintf(G->Message, "Unsupported typ %d\n", valp->GetType()); + throw(777); } // endswitch Type return vlp; @@ -1702,16 +1714,44 @@ void BJSON::SetBigint(PBVAL vlp, longlong ll) /***********************************************************************/ /* Set the Value's value as the given DOUBLE. */ /***********************************************************************/ -void BJSON::SetFloat(PBVAL vlp, double f) { - vlp->F = (float)f; - vlp->Nd = 6; - vlp->Type = TYPE_FLOAT; +void BJSON::SetFloat(PBVAL vlp, double d, int nd) +{ + double* dp = (double*)BsonSubAlloc(sizeof(double)); + + *dp = d; + vlp->To_Val = MOF(dp); + vlp->Nd = MY_MIN(nd, 16); + vlp->Type = TYPE_DBL; } // end of SetFloat /***********************************************************************/ +/* Set the Value's value as the given DOUBLE representation. */ +/***********************************************************************/ +void BJSON::SetFloat(PBVAL vlp, PSZ s) +{ + char *p = strchr(s, '.'); + int nd = 0; + double d = atof(s); + + if (p) { + for (++p; isdigit(*p); nd++, p++); + for (--p; *p == '0'; nd--, p--); + } // endif p + + if (nd < 6 && d >= FLT_MIN && d <= FLT_MAX) { + vlp->F = (float)d; + vlp->Nd = nd; + vlp->Type = TYPE_FLOAT; + } else + SetFloat(vlp, d, nd); + +} // end of SetFloat + + /***********************************************************************/ /* Set the Value's value as the given string. */ /***********************************************************************/ -void BJSON::SetString(PBVAL vlp, PSZ s, int ci) { +void BJSON::SetString(PBVAL vlp, PSZ s, int ci) +{ vlp->To_Val = MOF(s); vlp->Nd = ci; vlp->Type = TYPE_STRG; @@ -1720,7 +1760,8 @@ void BJSON::SetString(PBVAL vlp, PSZ s, int ci) { /***********************************************************************/ /* True when its JSON or normal value is null. */ /***********************************************************************/ -bool BJSON::IsValueNull(PBVAL vlp) { +bool BJSON::IsValueNull(PBVAL vlp) +{ bool b; switch (vlp->Type) { -- cgit v1.2.1 From 347bce0201076d3a01ec6554bd0c8147a501af44 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 12 Jan 2021 18:25:41 +0100 Subject: - Remove static linkage to cpprestsdk when it is installed modified: storage/connect/CMakeLists.txt - Continue BSON development modified: storage/connect/bson.cpp modified: storage/connect/bson.h modified: storage/connect/bsonudf.cpp modified: storage/connect/bsonudf.h added: storage/connect/mysql-test/connect/r/bson_udf.result added: storage/connect/mysql-test/connect/t/bson_udf.inc added: storage/connect/mysql-test/connect/t/bson_udf.test added: storage/connect/mysql-test/connect/t/bson_udf2.inc --- storage/connect/bson.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index f3ad919993f..fc58303a73f 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -631,7 +631,7 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty) err = SerializeValue(MVP(bvp->To_Val)); break; default: - err = SerializeValue(bvp); + err = SerializeValue(bvp, true); } // endswitch Type if (fs) { @@ -737,7 +737,7 @@ bool BDOC::SerializeObject(OFFSET obp) /***********************************************************************/ /* Serialize a JSON Value. */ /***********************************************************************/ -bool BDOC::SerializeValue(PBVAL jvp) +bool BDOC::SerializeValue(PBVAL jvp, bool b) { char buf[64]; @@ -750,7 +750,11 @@ bool BDOC::SerializeValue(PBVAL jvp) return jp->WriteStr(jvp->B ? "true" : "false"); case TYPE_STRG: case TYPE_DTM: - return jp->Escape(MZP(jvp->To_Val)); + if (b) { + return jp->WriteStr(MZP(jvp->To_Val)); + } else + return jp->Escape(MZP(jvp->To_Val)); + case TYPE_INTG: sprintf(buf, "%d", jvp->N); return jp->WriteStr(buf); @@ -1505,8 +1509,12 @@ double BJSON::GetDouble(PBVAL vp) d = (double)vlp->N; break; case TYPE_FLOAT: - d = (double)vlp->F; - break; + { char buf[32]; + int n = (vlp->Nd) ? vlp->Nd : 5; + + sprintf(buf, "%.*f", n, vlp->F); + d = atof(buf); + } break; case TYPE_DTM: case TYPE_STRG: d = atof(MZP(vlp->To_Val)); @@ -1632,7 +1640,7 @@ PBVAL BJSON::SetValue(PBVAL vlp, PVAL valp) { double d = valp->GetFloatValue(); int nd = (IsTypeNum(valp->GetType())) ? valp->GetValPrec() : 0; - if (nd <= 6 && d >= FLT_MIN && d <= FLT_MAX) { + if (nd > 0 && nd <= 6 && d >= FLT_MIN && d <= FLT_MAX) { vlp->F = (float)valp->GetFloatValue(); vlp->Type = TYPE_FLOAT; } else { -- cgit v1.2.1 From 7edd4294be4e59c19539167620ff140e3f5e7f58 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 28 Jan 2021 01:02:29 +0100 Subject: - Continue BSON development modified: storage/connect/bson.cpp modified: storage/connect/bson.h modified: storage/connect/bsonudf.cpp modified: storage/connect/bsonudf.h modified: storage/connect/ha_connect.cc modified: storage/connect/jsonudf.cpp modified: storage/connect/mysql-test/connect/r/bson.result modified: storage/connect/mysql-test/connect/r/bson_udf.result modified: storage/connect/mysql-test/connect/t/bson_udf.inc modified: storage/connect/mysql-test/connect/t/bson_udf.test modified: storage/connect/mysql-test/connect/t/bson_udf2.inc modified: storage/connect/tabbson.cpp modified: storage/connect/tabbson.h --- storage/connect/bson.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index fc58303a73f..5731ce9eac5 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -37,6 +37,8 @@ #undef SE_CATCH // Does not work for Linux #endif +int GetJsonDefPrec(void); + #if defined(SE_CATCH) /**************************************************************************/ /* This is the support of catching C interrupts to prevent crashes. */ @@ -1722,14 +1724,22 @@ void BJSON::SetBigint(PBVAL vlp, longlong ll) /***********************************************************************/ /* Set the Value's value as the given DOUBLE. */ /***********************************************************************/ -void BJSON::SetFloat(PBVAL vlp, double d, int nd) +void BJSON::SetFloat(PBVAL vlp, double d, int prec) { - double* dp = (double*)BsonSubAlloc(sizeof(double)); + int nd = MY_MIN((prec < 0) ? GetJsonDefPrec() : prec, 16); + + if (nd < 6 && d >= FLT_MIN && d <= FLT_MAX) { + vlp->F = (float)d; + vlp->Type = TYPE_FLOAT; + } else { + double* dp = (double*)BsonSubAlloc(sizeof(double)); - *dp = d; - vlp->To_Val = MOF(dp); - vlp->Nd = MY_MIN(nd, 16); - vlp->Type = TYPE_DBL; + *dp = d; + vlp->To_Val = MOF(dp); + vlp->Type = TYPE_DBL; + } // endif nd + + vlp->Nd = nd; } // end of SetFloat /***********************************************************************/ @@ -1746,13 +1756,7 @@ void BJSON::SetFloat(PBVAL vlp, PSZ s) for (--p; *p == '0'; nd--, p--); } // endif p - if (nd < 6 && d >= FLT_MIN && d <= FLT_MAX) { - vlp->F = (float)d; - vlp->Nd = nd; - vlp->Type = TYPE_FLOAT; - } else - SetFloat(vlp, d, nd); - + SetFloat(vlp, d, nd); } // end of SetFloat /***********************************************************************/ -- cgit v1.2.1 From 848a1a613c103209e4f2fb5d02572237d46832a1 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 28 Jan 2021 19:54:24 +0100 Subject: Fix decimal problems in bson udf's --- storage/connect/bson.cpp | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 5731ce9eac5..6c979498286 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -1501,31 +1501,27 @@ double BJSON::GetDouble(PBVAL vp) PBVAL vlp = (vp->Type == TYPE_JVAL) ? MVP(vp->To_Val) : vp; switch (vlp->Type) { - case TYPE_DBL: - d = *(double*)MP(vlp->To_Val); - break; - case TYPE_BINT: - d = (double)*(longlong*)MP(vlp->To_Val); - break; - case TYPE_INTG: - d = (double)vlp->N; - break; - case TYPE_FLOAT: - { char buf[32]; - int n = (vlp->Nd) ? vlp->Nd : 5; - - sprintf(buf, "%.*f", n, vlp->F); - d = atof(buf); - } break; - case TYPE_DTM: - case TYPE_STRG: - d = atof(MZP(vlp->To_Val)); - break; - case TYPE_BOOL: - d = (vlp->B) ? 1.0 : 0.0; - break; - default: - d = 0.0; + case TYPE_DBL: + d = *(double*)MP(vlp->To_Val); + break; + case TYPE_BINT: + d = (double)*(longlong*)MP(vlp->To_Val); + break; + case TYPE_INTG: + d = (double)vlp->N; + break; + case TYPE_FLOAT: + d = (double)vlp->F; + break; + case TYPE_DTM: + case TYPE_STRG: + d = atof(MZP(vlp->To_Val)); + break; + case TYPE_BOOL: + d = (vlp->B) ? 1.0 : 0.0; + break; + default: + d = 0.0; } // endswitch Type return d; -- cgit v1.2.1 From 40868c4765383549d1fe5650e6bce1ca5078b875 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 28 Jan 2021 18:30:32 +0100 Subject: fix warnings returned by gcc v10.0 --- storage/connect/bson.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index fc58303a73f..7728d488a00 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -1199,15 +1199,14 @@ void BJSON::SetArrayValue(PBVAL bap, PBVAL nvp, int n) { CheckType(bap, TYPE_JAR); int i = 0; - PBVAL bvp = NULL, pvp = NULL; + PBVAL bvp = NULL; if (bap->To_Val) for (bvp = GetArray(bap); bvp; i++, bvp = GetNext(bvp)) if (i == n) { SetValueVal(bvp, nvp); return; - } else - pvp = bvp; + } if (!bvp) AddArrayValue(bap, MOF(nvp)); -- cgit v1.2.1 From 496f7090a825ac7ee54a6b5f9700e5f261e4bce0 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 29 Jan 2021 12:35:17 +0100 Subject: Fix of warnings on aarch64 like: bson.cpp:1775:3: error: case label value is less than minimum value for type [-Werror] case TYPE_NULL: bson.cpp:1776:7: error: statement will never be executed [-Werror=switch-unreachable] b = true; --- storage/connect/bson.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 7728d488a00..f6a8db67d42 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -767,7 +767,7 @@ bool BDOC::SerializeValue(PBVAL jvp, bool b) case TYPE_DBL: sprintf(buf, "%.*lf", jvp->Nd, *(double*)MakePtr(Base, jvp->To_Val)); return jp->WriteStr(buf); - case TYPE_NULL: + case (char)TYPE_NULL: return jp->WriteStr("null"); case TYPE_JVAL: return SerializeValue(MVP(jvp->To_Val)); @@ -1557,7 +1557,7 @@ PSZ BJSON::GetString(PBVAL vp, char* buff) case TYPE_BOOL: p = (PSZ)((vlp->B) ? "true" : "false"); break; - case TYPE_NULL: + case (char)TYPE_NULL: p = (PSZ)"null"; break; default: @@ -1772,7 +1772,7 @@ bool BJSON::IsValueNull(PBVAL vlp) bool b; switch (vlp->Type) { - case TYPE_NULL: + case (char)TYPE_NULL: b = true; break; case TYPE_JOB: -- cgit v1.2.1 From c2aecb05751ee7319722cbe4c65b974e1f10fbbb Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 30 Jan 2021 12:07:37 +0100 Subject: Fix failed test bson and xml --- storage/connect/bson.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 6c979498286..a494cf3166b 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -886,7 +886,6 @@ PBPR BJSON::NewPair(OFFSET key, int type) PBPR bpp = (PBPR)BsonSubAlloc(sizeof(BPAIR)); bpp->Key = key; - bpp->Vlp.Ktp = TYPE_STRG; bpp->Vlp.Type = type; bpp->Vlp.To_Val = 0; bpp->Vlp.Nd = 0; -- cgit v1.2.1 From b3cecb7bfc88a72661e61b3c8ce3e6101ac4e9b5 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 2 Feb 2021 10:37:54 +0100 Subject: Revert "Fix of warnings on aarch64 like:" Fixed by the author in other way (char -> short) This reverts commit 496f7090a825ac7ee54a6b5f9700e5f261e4bce0. --- storage/connect/bson.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index fa24300f91f..7665d8520ab 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -769,7 +769,7 @@ bool BDOC::SerializeValue(PBVAL jvp, bool b) case TYPE_DBL: sprintf(buf, "%.*lf", jvp->Nd, *(double*)MakePtr(Base, jvp->To_Val)); return jp->WriteStr(buf); - case (char)TYPE_NULL: + case TYPE_NULL: return jp->WriteStr("null"); case TYPE_JVAL: return SerializeValue(MVP(jvp->To_Val)); @@ -1554,7 +1554,7 @@ PSZ BJSON::GetString(PBVAL vp, char* buff) case TYPE_BOOL: p = (PSZ)((vlp->B) ? "true" : "false"); break; - case (char)TYPE_NULL: + case TYPE_NULL: p = (PSZ)"null"; break; default: @@ -1771,7 +1771,7 @@ bool BJSON::IsValueNull(PBVAL vlp) bool b; switch (vlp->Type) { - case (char)TYPE_NULL: + case TYPE_NULL: b = true; break; case TYPE_JOB: -- cgit v1.2.1 From c04ae0d365f4e65bf6c0ccc01c25d597e269d47e Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 3 Feb 2021 15:35:32 +0100 Subject: Fix of crashes of connect engine. Use size_t everywhere and remove suspicious expression. --- storage/connect/bson.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'storage/connect/bson.cpp') diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp index 7665d8520ab..3c33551cb68 100644 --- a/storage/connect/bson.cpp +++ b/storage/connect/bson.cpp @@ -82,7 +82,7 @@ BDOC::BDOC(PGLOBAL G) : BJSON(G, NULL) /***********************************************************************/ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng) { - int i; + size_t i; bool b = false, ptyp = (bool *)pty; PBVAL bvp = NULL; @@ -185,7 +185,7 @@ PBVAL BDOC::ParseJson(PGLOBAL g, char* js, size_t lng) /***********************************************************************/ /* Parse several items as being in an array. */ /***********************************************************************/ -OFFSET BDOC::ParseAsArray(int& i) { +OFFSET BDOC::ParseAsArray(size_t& i) { if (pty[0] && (!pretty || pretty > 2)) { OFFSET jsp; @@ -202,7 +202,7 @@ OFFSET BDOC::ParseAsArray(int& i) { /***********************************************************************/ /* Parse a JSON Array. */ /***********************************************************************/ -OFFSET BDOC::ParseArray(int& i) +OFFSET BDOC::ParseArray(size_t& i) { int level = 0; bool b = (!i); @@ -214,7 +214,7 @@ OFFSET BDOC::ParseArray(int& i) switch (s[i]) { case ',': if (level < 2) { - sprintf(G->Message, "Unexpected ',' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',' near %.*s", (int) ARGS); throw 1; } else level = 1; @@ -222,7 +222,7 @@ OFFSET BDOC::ParseArray(int& i) break; case ']': if (level == 1) { - sprintf(G->Message, "Unexpected ',]' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',]' near %.*s", (int) ARGS); throw 1; } // endif level @@ -236,7 +236,7 @@ OFFSET BDOC::ParseArray(int& i) break; default: if (level == 2) { - sprintf(G->Message, "Unexpected value near %.*s", ARGS); + sprintf(G->Message, "Unexpected value near %.*s", (int) ARGS); throw 1; } else if (lastvlp) { vlp = ParseValue(i, NewVal()); @@ -260,7 +260,7 @@ OFFSET BDOC::ParseArray(int& i) /***********************************************************************/ /* Parse a JSON Object. */ /***********************************************************************/ -OFFSET BDOC::ParseObject(int& i) +OFFSET BDOC::ParseObject(size_t& i) { OFFSET key; int level = 0; @@ -283,7 +283,7 @@ OFFSET BDOC::ParseObject(int& i) level = 2; } else { - sprintf(G->Message, "misplaced string near %.*s", ARGS); + sprintf(G->Message, "misplaced string near %.*s", (int) ARGS); throw 2; } // endif level @@ -293,14 +293,14 @@ OFFSET BDOC::ParseObject(int& i) ParseValue(++i, GetVlp(lastbpp)); level = 3; } else { - sprintf(G->Message, "Unexpected ':' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ':' near %.*s", (int) ARGS); throw 2; } // endif level break; case ',': if (level < 3) { - sprintf(G->Message, "Unexpected ',' near %.*s", ARGS); + sprintf(G->Message, "Unexpected ',' near %.*s", (int) ARGS); throw 2; } else level = 1; @@ -308,7 +308,7 @@ OFFSET BDOC::ParseObject(int& i) break; case '}': if (!(level == 0 || level == 3)) { - sprintf(G->Message, "Unexpected '}' near %.*s", ARGS); + sprintf(G->Message, "Unexpected '}' near %.*s", (int) ARGS); throw 2; } // endif level @@ -321,7 +321,7 @@ OFFSET BDOC::ParseObject(int& i) break; default: sprintf(G->Message, "Unexpected character '%c' near %.*s", - s[i], ARGS); + s[i], (int) ARGS); throw 2; }; // endswitch s[i] @@ -332,7 +332,7 @@ OFFSET BDOC::ParseObject(int& i) /***********************************************************************/ /* Parse a JSON Value. */ /***********************************************************************/ -PBVAL BDOC::ParseValue(int& i, PBVAL bvp) +PBVAL BDOC::ParseValue(size_t& i, PBVAL bvp) { for (; i < len; i++) switch (s[i]) { @@ -398,14 +398,14 @@ suite: return bvp; err: - sprintf(G->Message, "Unexpected character '%c' near %.*s", s[i], ARGS); + sprintf(G->Message, "Unexpected character '%c' near %.*s", s[i], (int) ARGS); throw 3; } // end of ParseValue /***********************************************************************/ /* Unescape and parse a JSON string. */ /***********************************************************************/ -OFFSET BDOC::ParseString(int& i) +OFFSET BDOC::ParseString(size_t& i) { uchar* p; int n = 0; @@ -492,7 +492,7 @@ throw("Unexpected EOF in String"); /***********************************************************************/ /* Parse a JSON numeric value. */ /***********************************************************************/ -void BDOC::ParseNumeric(int& i, PBVAL vlp) +void BDOC::ParseNumeric(size_t& i, PBVAL vlp) { char buf[50]; int n = 0; -- cgit v1.2.1