summaryrefslogtreecommitdiffstats
path: root/storage/connect/xobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect/xobject.cpp')
-rw-r--r--storage/connect/xobject.cpp441
1 files changed, 441 insertions, 0 deletions
diff --git a/storage/connect/xobject.cpp b/storage/connect/xobject.cpp
new file mode 100644
index 00000000..21a91653
--- /dev/null
+++ b/storage/connect/xobject.cpp
@@ -0,0 +1,441 @@
+/************ Xobject C++ Functions Source Code File (.CPP) ************/
+/* Name: XOBJECT.CPP Version 2.5 */
+/* */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
+/* */
+/* This file contains base XOBJECT class functions. */
+/* Also here is the implementation of the CONSTANT class. */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Include mariaDB header file. */
+/***********************************************************************/
+#include "my_global.h"
+#include "m_string.h"
+
+/***********************************************************************/
+/* Include required application header files */
+/* global.h is header containing all global Plug declarations. */
+/* plgdbsem.h is header containing the DB applic. declarations. */
+/***********************************************************************/
+#include "global.h"
+#include "plgdbsem.h"
+#include "xobject.h"
+
+/***********************************************************************/
+/* Macro definitions. */
+/***********************************************************************/
+#if defined(_DEBUG) || defined(DEBTRACE)
+#define ASSERT(B) assert(B);
+#else
+#define ASSERT(B)
+#endif
+
+/***********************************************************************/
+/* The one and only needed void object. */
+/***********************************************************************/
+XVOID Xvoid;
+PXOB const pXVOID = &Xvoid; // Pointer used by other classes
+
+/* ------------------------- Class XOBJECT --------------------------- */
+
+/***********************************************************************/
+/* GetCharValue: returns the Result value as a char string. */
+/* Using GetCharValue provides no conversion from numeric types. */
+/***********************************************************************/
+PSZ XOBJECT::GetCharValue(void)
+ {
+ ASSERT(Value)
+ return Value->GetCharValue();
+ } // end of GetCharValue()
+
+/***********************************************************************/
+/* GetShortValue: returns the Result value as a short integer. */
+/***********************************************************************/
+short XOBJECT::GetShortValue(void)
+ {
+ ASSERT(Value)
+ return Value->GetShortValue();
+ } // end of GetShortValue
+
+/***********************************************************************/
+/* GetIntValue: returns the Result value as a int integer. */
+/***********************************************************************/
+int XOBJECT::GetIntValue(void)
+ {
+ ASSERT(Value)
+ return Value->GetIntValue();
+ } // end of GetIntValue
+
+/***********************************************************************/
+/* GetFloatValue: returns the Result value as a double float. */
+/***********************************************************************/
+double XOBJECT::GetFloatValue(void)
+ {
+ ASSERT(Value)
+ return Value->GetFloatValue();
+ } // end of GetFloatValue
+
+/* ------------------------- Class CONSTANT -------------------------- */
+
+/***********************************************************************/
+/* CONSTANT public constructor. */
+/***********************************************************************/
+CONSTANT::CONSTANT(PGLOBAL g, void *value, short type)
+ {
+ if (!(Value = AllocateValue(g, value, (int)type)))
+ throw (int)TYPE_CONST;
+
+ Constant = true;
+ } // end of CONSTANT constructor
+
+/***********************************************************************/
+/* CONSTANT public constructor. */
+/***********************************************************************/
+CONSTANT::CONSTANT(PGLOBAL g, int n)
+ {
+ if (!(Value = AllocateValue(g, &n, TYPE_INT)))
+ throw (int)TYPE_CONST;
+
+ Constant = true;
+ } // end of CONSTANT constructor
+
+/***********************************************************************/
+/* GetLengthEx: returns an evaluation of the constant string length. */
+/* Note: When converting from token to string, length has to be */
+/* specified but we need the domain length, not the value length. */
+/***********************************************************************/
+int CONSTANT::GetLengthEx(void)
+ {
+ return Value->GetValLen();
+ } // end of GetLengthEx
+
+/***********************************************************************/
+/* Convert a constant to the given type. */
+/***********************************************************************/
+void CONSTANT::Convert(PGLOBAL g, int newtype)
+ {
+ if (Value->GetType() != newtype)
+ if (!(Value = AllocateValue(g, Value, newtype)))
+ throw (int)TYPE_CONST;
+
+ } // end of Convert
+
+/***********************************************************************/
+/* Compare: returns true if this object is equivalent to xp. */
+/***********************************************************************/
+bool CONSTANT::Compare(PXOB xp)
+ {
+ if (this == xp)
+ return true;
+ else if (xp->GetType() != TYPE_CONST)
+ return false;
+ else
+ return Value->IsEqual(xp->GetValue(), true);
+
+ } // end of Compare
+
+#if 0
+/***********************************************************************/
+/* Rephrase: temporary implementation used by PlugRephraseSQL. */
+/***********************************************************************/
+bool CONSTANT::Rephrase(PGLOBAL g, PSZ work)
+ {
+ switch (Value->GetType()) {
+ case TYPE_STRING:
+ sprintf(work + strlen(work), "'%s'", Value->GetCharValue());
+ break;
+ case TYPE_SHORT:
+ sprintf(work + strlen(work), "%hd", Value->GetShortValue());
+ break;
+ case TYPE_INT:
+ case TYPE_DATE:
+ sprintf(work + strlen(work), "%d", Value->GetIntValue());
+ break;
+ case TYPE_DOUBLE:
+ sprintf(work + strlen(work), "%lf", Value->GetFloatValue());
+ break;
+ case TYPE_BIGINT:
+ sprintf(work + strlen(work), "%lld", Value->GetBigintValue());
+ break;
+ case TYPE_TINY:
+ sprintf(work + strlen(work), "%d", Value->GetTinyValue());
+ break;
+ default:
+ snprintf(g->Message, sizeof(g->Message), MSG(BAD_CONST_TYPE), Value->GetType());
+ return false;
+ } // endswitch
+
+ return false;
+ } // end of Rephrase
+#endif // 0
+
+/***********************************************************************/
+/* Make file output of a constant object. */
+/***********************************************************************/
+void CONSTANT::Printf(PGLOBAL g, FILE *f, uint n)
+ {
+ Value->Printf(g, f, n);
+ } /* end of Printf */
+
+/***********************************************************************/
+/* Make string output of a constant object. */
+/***********************************************************************/
+void CONSTANT::Prints(PGLOBAL g, char *ps, uint z)
+ {
+ Value->Prints(g, ps, z);
+ } /* end of Prints */
+
+/* -------------------------- Class STRING --------------------------- */
+
+/***********************************************************************/
+/* STRING public constructor for new char values. Alloc Size must be */
+/* calculated because PlugSubAlloc rounds up size to multiple of 8. */
+/***********************************************************************/
+STRING::STRING(PGLOBAL g, uint n, PCSZ str)
+{
+ G = g;
+ Length = (str) ? strlen(str) : 0;
+
+ if ((Strp = (PSZ)PlgDBSubAlloc(g, NULL, MY_MAX(n, Length) + 1))) {
+ if (str)
+ strcpy(Strp, str);
+ else
+ *Strp = 0;
+
+ Next = GetNext();
+ Size = (int)(Next - Strp);
+ Trc = false;
+ } else {
+ // This should normally never happen
+ Next = NULL;
+ Size = 0;
+ Trc = true;
+ } // endif Strp
+
+} // end of STRING constructor
+
+/***********************************************************************/
+/* Reallocate the string memory and return the (new) position. */
+/* If Next is equal to GetNext() this means that no new suballocation */
+/* has been done. Then we can just increase the size of the current */
+/* allocation and the Strp will remain pointing to the same memory. */
+/***********************************************************************/
+char *STRING::Realloc(uint len)
+{
+ char *p;
+ bool b = (Next == GetNext());
+
+ p = (char*)PlgDBSubAlloc(G, NULL, b ? len - Size : len);
+
+ if (!p) {
+ // No more room in Sarea; this is very unlikely
+ strcpy(G->Message, "No more room in work area");
+ Trc = true;
+ return NULL;
+ } // endif p
+
+ if (b)
+ p = Strp;
+
+ Next = GetNext();
+ Size = (int)(Next - p);
+ return p;
+} // end of Realloc
+
+/***********************************************************************/
+/* Set a STRING new PSZ value. */
+/***********************************************************************/
+bool STRING::Set(PCSZ s)
+{
+ if (!s)
+ return false;
+
+ uint len = strlen(s) + 1;
+
+ if (len > Size) {
+ char *p = Realloc(len);
+
+ if (!p)
+ return true;
+ else
+ Strp = p;
+
+ } // endif n
+
+ strcpy(Strp, s);
+ Length = len - 1;
+ return false;
+} // end of Set
+
+/***********************************************************************/
+/* Set a STRING new PSZ value. */
+/***********************************************************************/
+bool STRING::Set(char *s, uint n)
+{
+ if (!s)
+ return false;
+
+ uint len = strnlen(s, n) + 1;
+
+ if (len > Size) {
+ char *p = Realloc(len);
+
+ if (!p)
+ return true;
+ else
+ Strp = p;
+
+ } // endif n
+
+ strncpy(Strp, s, n);
+ Length = len - 1;
+ return false;
+} // end of Set
+
+/***********************************************************************/
+/* Append a char* to a STRING. */
+/***********************************************************************/
+bool STRING::Append(const char *s, uint ln, bool nq)
+{
+ if (!s)
+ return false;
+
+ uint i, len = Length + ln + 1;
+
+ if (len > Size) {
+ char *p = Realloc(len);
+
+ if (!p)
+ return true;
+ else if (p != Strp) {
+ strcpy(p, Strp);
+ Strp = p;
+ } // endif p
+
+ } // endif n
+
+ if (nq) {
+ for (i = 0; i < ln; i++)
+ switch (s[i]) {
+ case '\\': Strp[Length++] = '\\'; Strp[Length++] = '\\'; break;
+ case '\0': Strp[Length++] = '\\'; Strp[Length++] = '0'; break;
+ case '\'': Strp[Length++] = '\\'; Strp[Length++] = '\''; break;
+ case '\n': Strp[Length++] = '\\'; Strp[Length++] = 'n'; break;
+ case '\r': Strp[Length++] = '\\'; Strp[Length++] = 'r'; break;
+ case '\032': Strp[Length++] = '\\'; Strp[Length++] = 'Z'; break;
+ default: Strp[Length++] = s[i];
+ } // endswitch s[i]
+
+ } else
+ for (i = 0; i < ln && s[i]; i++)
+ Strp[Length++] = s[i];
+
+ Strp[Length] = 0;
+ return false;
+} // end of Append
+
+/***********************************************************************/
+/* Append a PCSZ to a STRING. */
+/***********************************************************************/
+bool STRING::Append(PCSZ s)
+{
+ if (!s)
+ return false;
+
+ uint len = Length + strlen(s) + 1;
+
+ if (len > Size) {
+ char *p = Realloc(len);
+
+ if (!p)
+ return true;
+ else if (p != Strp) {
+ strcpy(p, Strp);
+ Strp = p;
+ } // endif p
+
+ } // endif n
+
+ strcpy(Strp + Length, s);
+ Length = len - 1;
+ return false;
+} // end of Append
+
+/***********************************************************************/
+/* Append a STRING to a STRING. */
+/***********************************************************************/
+bool STRING::Append(STRING &str)
+{
+ return Append(str.GetStr());
+} // end of Append
+
+/***********************************************************************/
+/* Append a char to a STRING. */
+/***********************************************************************/
+bool STRING::Append(char c)
+{
+ if (Length + 2 > Size) {
+ char *p = Realloc(Length + 2);
+
+ if (!p)
+ return true;
+ else if (p != Strp) {
+ strcpy(p, Strp);
+ Strp = p;
+ } // endif p
+
+ } // endif n
+
+ Strp[Length++] = c;
+ Strp[Length] = 0;
+ return false;
+} // end of Append
+
+/***********************************************************************/
+/* Append a quoted PSZ to a STRING. */
+/***********************************************************************/
+bool STRING::Append_quoted(PCSZ s)
+{
+ bool b = Append('\'');
+
+ if (s) for (const char *p = s; !b && *p; p++)
+ switch (*p) {
+ case '\'':
+ case '\\':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\b':
+ case '\f': b |= Append('\\');
+ // fall through
+ default:
+ b |= Append(*p);
+ break;
+ } // endswitch *p
+
+ return (b |= Append('\''));
+} // end of Append_quoted
+
+/***********************************************************************/
+/* Resize to given length but only when last suballocated. */
+/* New size should be greater than string length. */
+/***********************************************************************/
+bool STRING::Resize(uint newsize)
+{
+ if (Next == GetNext() && newsize > Length) {
+ uint nsz = (((signed)newsize + 7) / 8) * 8;
+ int diff = (signed)Size - (signed)nsz;
+ PPOOLHEADER pp = (PPOOLHEADER)G->Sarea;
+
+ if ((signed)pp->FreeBlk + diff < 0)
+ return true; // Out of memory
+
+ pp->To_Free -= diff;
+ pp->FreeBlk += diff;
+ Size = nsz;
+ return false;
+ } else
+ return newsize > Size;
+
+} // end of Resize