diff options
Diffstat (limited to 'storage/connect/xobject.cpp')
-rw-r--r-- | storage/connect/xobject.cpp | 441 |
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 |