1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-09 22:24:09 +03:00
Files
mariadb/storage/connect/valblk.cpp
2013-01-23 22:45:25 +01:00

1414 lines
48 KiB
C++

/************ Valblk C++ Functions Source Code File (.CPP) *************/
/* Name: VALBLK.CPP Version 1.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2005-2012 */
/* */
/* This file contains the VALBLK and derived classes functions. */
/* Second family is VALBLK, representing simple suballocated arrays */
/* of values treated sequentially by FIX, BIN and VCT tables and */
/* columns, as well for min/max blocks as for VCT column blocks. */
/* Q&A: why not using only one family ? Simple values are arrays that */
/* have only one element and arrays could have functions for all kind */
/* of processing. The answer is a-because historically it was simpler */
/* to do that way, b-because of performance on single values, and c- */
/* to avoid too complicated classes and unuseful duplication of many */
/* functions used on one family only. The drawback is that for new */
/* types of objects, we shall have more classes to update. */
/* Currently the only implemented types are STRING, int and DOUBLE. */
/* Shortly we should add at least int VARCHAR and DATE. */
/***********************************************************************/
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
#if defined(WIN32)
//#include <windows.h>
#else
#include "osutil.h"
#include "string.h"
#endif
/***********************************************************************/
/* Include required application header files */
/* global.h is header containing all global Plug declarations. */
/* plgdbsem.h is header containing the DB applic. declarations. */
/* valblk.h is header containing VALBLK derived classes declares. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "valblk.h"
/***********************************************************************/
/* Check macro's. */
/***********************************************************************/
#if defined(_DEBUG) || defined(DEBTRACE)
#define CheckIndex(N) ChkIndx(N);
void VALBLK::ChkIndx(int n) {
if (n >= Nval) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BAD_VALBLK_INDX));
longjmp(g->jumper[g->jump_level], Type);
} // endif N
} // end of ChkIndx
#define CheckParms(V,N) ChkPrm(V,N);
void VALBLK::ChkPrm(PVAL v, int n) {
ChkIndx(n);
if (Check && Type != v->GetType()) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(VALTYPE_NOMATCH));
longjmp(g->jumper[g->jump_level], Type);
} // endif Check
} // end of ChkPrm
#define CheckBlanks assert(!Blanks);
#define CheckType(V) ChkTyp(V);
void VALBLK::ChkTyp(PVAL v) {
if (Type != v->GetType()) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(VALTYPE_NOMATCH));
longjmp(g->jumper[g->jump_level], Type);
} // endif Type
} // end of ChkTyp
void VALBLK::ChkTyp(PVBLK vb) {
if (Type != vb->GetType()) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(VALTYPE_NOMATCH));
longjmp(g->jumper[g->jump_level], Type);
} // endif Type
} // end of ChkTyp
#else
#define CheckIndex(N)
#define CheckParms(V,N)
#define CheckBlanks
#define CheckType(V)
#endif
/***********************************************************************/
/* AllocValBlock: allocate a VALBLK according to type. */
/***********************************************************************/
PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
int prec, bool check, bool blank)
{
PVBLK blkp;
#ifdef DEBTRACE
htrc("AVB: mp=%p type=%d nval=%d len=%d check=%u blank=%u\n",
mp, type, nval, len, check, blank);
#endif
switch (type) {
case TYPE_STRING:
if (len)
blkp = new(g) CHRBLK(mp, nval, len, prec, blank);
else
blkp = new(g) STRBLK(g, mp, nval);
break;
case TYPE_SHORT:
blkp = new(g) SHRBLK(mp, nval);
break;
case TYPE_INT:
blkp = new(g) LNGBLK(mp, nval);
break;
case TYPE_DATE: // ?????
blkp = new(g) DATBLK(mp, nval);
break;
case TYPE_BIGINT:
blkp = new(g) BIGBLK(mp, nval);
break;
case TYPE_FLOAT:
blkp = new(g) DBLBLK(mp, nval, prec);
break;
default:
sprintf(g->Message, MSG(BAD_VALBLK_TYPE), type);
return NULL;
} // endswitch Type
blkp->Init(g, check);
return blkp;
} // end of AllocValBlock
/* -------------------------- Class VALBLK --------------------------- */
/***********************************************************************/
/* Raise error for numeric types. */
/***********************************************************************/
PSZ VALBLK::GetCharValue(int n)
{
PGLOBAL& g = Global;
assert(g);
sprintf(g->Message, MSG(NO_CHAR_FROM), Type);
longjmp(g->jumper[g->jump_level], Type);
return NULL;
} // end of GetCharValue
/***********************************************************************/
/* Set format so formatted dates can be converted on input. */
/***********************************************************************/
bool VALBLK::SetFormat(PGLOBAL g, PSZ fmt, int len, int year)
{
sprintf(g->Message, MSG(NO_DATE_FMT), Type);
return true;
} // end of SetFormat
/***********************************************************************/
/* Set the index of the location of value and return true if found. */
/* To be used on ascending sorted arrays only. */
/* Currently used by some BLKFIL classes only. */
/***********************************************************************/
bool VALBLK::Locate(PVAL vp, int& i)
{
CheckType(vp)
int n = 1;
for (i = 0; i < Nval; i++)
if ((n = CompVal(vp, i)) <= 0)
break;
return (!n);
} // end of Locate
/* -------------------------- Class CHRBLK --------------------------- */
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank)
: VALBLK(mp, TYPE_STRING, nval), Chrp((char*&)Blkp)
{
Valp = NULL;
Blanks = blank;
Ci = (prec != 0);
Long = len;
} // end of CHRBLK constructor
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void CHRBLK::Init(PGLOBAL g, bool check)
{
Valp = (char*)PlugSubAlloc(g, NULL, Long + 1);
Valp[Long] = '\0';
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * Long);
Check = check;
Global = g;
} // end of Init
/***********************************************************************/
/* Reset nth element to a null string. */
/***********************************************************************/
void CHRBLK::Reset(int n)
{
if (Blanks)
memset(Chrp + n * Long, ' ', Long);
else
*(Chrp + n * Long) = '\0';
} // end of Reset
/***********************************************************************/
/* Return the zero ending value of the nth element. */
/***********************************************************************/
char *CHRBLK::GetCharValue(int n)
{
return (char *)GetValPtrEx(n);
} // end of GetCharValue
/***********************************************************************/
/* Return the value of the nth element converted to short. */
/***********************************************************************/
short CHRBLK::GetShortValue(int n)
{
return (short)atoi((char *)GetValPtrEx(n));
} // end of GetIntValue
/***********************************************************************/
/* Return the value of the nth element converted to int. */
/***********************************************************************/
int CHRBLK::GetIntValue(int n)
{
return atol((char *)GetValPtrEx(n));
} // end of GetIntValue
/***********************************************************************/
/* Return the value of the nth element converted to big int. */
/***********************************************************************/
longlong CHRBLK::GetBigintValue(int n)
{
return atoll((char *)GetValPtrEx(n));
} // end of GetIntValue
/***********************************************************************/
/* Return the value of the nth element converted to double. */
/***********************************************************************/
double CHRBLK::GetFloatValue(int n)
{
return atof((char *)GetValPtrEx(n));
} // end of GetFloatValue
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void CHRBLK::SetValue(PVAL valp, int n)
{
CheckParms(valp, n)
SetValue((PSZ)valp->GetCharValue(), n);
} // end of SetValue
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void CHRBLK::SetValue(PSZ sp, int n)
{
size_t len = (sp) ? strlen(sp) : 0;
char *p = Chrp + n * Long;
#if defined(_DEBUG) || defined(DEBTRACE)
if (Check && (signed)len > Long) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(SET_STR_TRUNC));
longjmp(g->jumper[g->jump_level], Type);
} // endif Check
#endif
if (sp)
strncpy(p, sp, Long);
else
*p = '\0';
if (Blanks)
// Suppress eventual ending zero and right fill with blanks
for (register int i = len; i < Long; i++)
p[i] = ' ';
} // end of SetValue
/***********************************************************************/
/* Set one value in a block from a value in another block. */
/***********************************************************************/
void CHRBLK::SetValue(PVBLK pv, int n1, int n2)
{
#if defined(_DEBUG) || defined(DEBTRACE)
if (Type != pv->GetType() || Long != ((CHRBLK*)pv)->Long) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BLKTYPLEN_MISM));
longjmp(g->jumper[g->jump_level], Type);
} // endif Type
#endif
memcpy(Chrp + n1 * Long, ((CHRBLK*)pv)->Chrp + n2 * Long, Long);
} // end of SetValue
/***********************************************************************/
/* Set many values in a block from values in another block. */
/***********************************************************************/
void CHRBLK::SetValues(PVBLK pv, int k, int n)
{
#if defined(_DEBUG) || defined(DEBTRACE)
if (Type != pv->GetType() || Long != ((CHRBLK*)pv)->Long) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BLKTYPLEN_MISM));
longjmp(g->jumper[g->jump_level], Type);
} // endif Type
#endif
char *p = ((CHRBLK*)pv)->Chrp;
if (!k)
memcpy(Chrp, p, Long * n);
else
memcpy(Chrp + k * Long, p + k * Long, Long * (n - k));
} // end of SetValues
/***********************************************************************/
/* Set one value in a block if val is less than the current value. */
/***********************************************************************/
void CHRBLK::SetMin(PVAL valp, int n)
{
CheckParms(valp, n)
CheckBlanks
char *vp = valp->GetCharValue();
char *bp = Chrp + n * Long;
if (((Ci) ? strnicmp(vp, bp, Long) : strncmp(vp, bp, Long)) < 0)
memcpy(bp, vp, Long);
} // end of SetMin
/***********************************************************************/
/* Set one value in a block if val is greater than the current value. */
/***********************************************************************/
void CHRBLK::SetMax(PVAL valp, int n)
{
CheckParms(valp, n)
CheckBlanks
char *vp = valp->GetCharValue();
char *bp = Chrp + n * Long;
if (((Ci) ? strnicmp(vp, bp, Long) : strncmp(vp, bp, Long)) > 0)
memcpy(bp, vp, Long);
} // end of SetMax
/***********************************************************************/
/* Move one value from i to j. */
/***********************************************************************/
void CHRBLK::Move(int i, int j)
{
memcpy(Chrp + j * Long, Chrp + i * Long, Long);
} // end of Move
/***********************************************************************/
/* Compare a Value object with the nth value of the block. */
/***********************************************************************/
int CHRBLK::CompVal(PVAL vp, int n)
{
CheckParms(vp, n)
char *xvp = vp->GetCharValue(); // Get Value zero ended string
bool ci = Ci || vp->IsCi(); // true if is case insensitive
GetValPtrEx(n); // Get a zero ended string in Valp
return (ci) ? stricmp(xvp, Valp) : strcmp(xvp, Valp);
} // end of CompVal
/***********************************************************************/
/* Compare two values of the block. */
/***********************************************************************/
int CHRBLK::CompVal(int i1, int i2)
{
return (Ci) ? strnicmp(Chrp + i1 * Long, Chrp + i2 * Long, Long)
: strncmp(Chrp + i1 * Long, Chrp + i2 * Long, Long);
} // end of CompVal
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *CHRBLK::GetValPtr(int n)
{
CheckIndex(n)
return Chrp + n * Long;
} // end of GetValPtr
/***********************************************************************/
/* Get a pointer on a zero ended string equal to nth value. */
/***********************************************************************/
void *CHRBLK::GetValPtrEx(int n)
{
CheckIndex(n)
memcpy(Valp, Chrp + n * Long, Long);
if (Blanks) {
// The (fast) way this is done works only for blocks such
// as Min and Max where strings are stored with the ending 0
// except for those whose length is equal to Len.
// For VCT blocks we must remove rightmost blanks.
char *p = Valp + Long;
for (p--; *p == ' ' && p >= Valp; p--) ;
*(++p) = '\0';
} // endif Blanks
return Valp;
} // end of GetValPtrEx
/***********************************************************************/
/* Returns index of matching value in block or -1. */
/***********************************************************************/
int CHRBLK::Find(PVAL vp)
{
CheckType(vp)
int i;
bool ci = Ci || vp->IsCi();
PSZ s = vp->GetCharValue();
for (i = 0; i < Nval; i++) {
GetValPtrEx(i); // Get a zero ended string in Valp
if (!((ci) ? strnicmp(s, Valp, Long) : strncmp(s, Valp, Long)))
break;
} // endfor i
return (i < Nval) ? i : (-1);
} // end of GetValPtr
/***********************************************************************/
/* Returns the length of the longest string in the block. */
/***********************************************************************/
int CHRBLK::GetMaxLength(void)
{
int i, n;
for (i = n = 0; i < Nval; i++) {
GetValPtrEx(i);
n = max(n, (signed)strlen(Valp));
} // endfor i
return n;
} // end of GetMaxLength
/* -------------------------- Class STRBLK --------------------------- */
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
STRBLK::STRBLK(PGLOBAL g, void *mp, int nval)
: VALBLK(mp, TYPE_STRING, nval), Strp((PSZ*&)Blkp)
{
Global = g;
} // end of STRBLK constructor
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void STRBLK::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(PSZ));
Check = check;
Global = g;
} // end of Init
/***********************************************************************/
/* Set one value in a block from a value in another block. */
/***********************************************************************/
void STRBLK::SetValue(PVBLK pv, int n1, int n2)
{
CheckType(pv)
Strp[n1] = ((STRBLK*)pv)->Strp[n2];
} // end of SetValue
/***********************************************************************/
/* Set many values in a block from values in another block. */
/***********************************************************************/
void STRBLK::SetValues(PVBLK pv, int k, int n)
{
CheckType(pv)
PSZ *sp = ((STRBLK*)pv)->Strp;
for (register int i = k; i < n; i++)
Strp[i] = sp[i];
} // end of SetValues
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void STRBLK::SetValue(PVAL valp, int n)
{
CheckParms(valp, n)
SetValue((PSZ)valp->GetCharValue(), n);
} // end of SetValue
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void STRBLK::SetValue(PSZ p, int n)
{
Strp[n] = (PSZ)PlugSubAlloc(Global, NULL, strlen(p) + 1);
strcpy(Strp[n], p);
} // end of SetValue
/***********************************************************************/
/* Set one value in a block if val is less than the current value. */
/***********************************************************************/
void STRBLK::SetMin(PVAL valp, int n)
{
CheckParms(valp, n)
char *vp = valp->GetCharValue();
char *bp = Strp[n];
if (strcmp(vp, bp) < 0)
SetValue(valp, n);
} // end of SetMin
/***********************************************************************/
/* Set one value in a block if val is greater than the current value. */
/***********************************************************************/
void STRBLK::SetMax(PVAL valp, int n)
{
CheckParms(valp, n)
char *vp = valp->GetCharValue();
char *bp = Strp[n];
if (strcmp(vp, bp) > 0)
SetValue(valp, n);
} // end of SetMax
/***********************************************************************/
/* Move one value from i to j. */
/***********************************************************************/
void STRBLK::Move(int i, int j)
{
Strp[j] = Strp[i];
} // end of Move
/***********************************************************************/
/* Compare a Value object with the nth value of the block. */
/***********************************************************************/
int STRBLK::CompVal(PVAL vp, int n)
{
CheckParms(vp, n)
return strcmp(vp->GetCharValue(), Strp[n]);
} // end of CompVal
/***********************************************************************/
/* Compare two values of the block. */
/***********************************************************************/
int STRBLK::CompVal(int i1, int i2)
{
return (strcmp(Strp[i1], Strp[i2]));
} // end of CompVal
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *STRBLK::GetValPtr(int n)
{
CheckIndex(n)
return Strp + n;
} // end of GetValPtr
/***********************************************************************/
/* Get a pointer on a zero ended string equal to nth value. */
/***********************************************************************/
void *STRBLK::GetValPtrEx(int n)
{
CheckIndex(n)
return Strp[n];
} // end of GetValPtrEx
/***********************************************************************/
/* Returns index of matching value in block or -1. */
/***********************************************************************/
int STRBLK::Find(PVAL vp)
{
CheckType(vp)
int i;
PSZ s = vp->GetCharValue();
for (i = 0; i < Nval; i++)
if (!strcmp(s, Strp[i]))
break;
return (i < Nval) ? i : (-1);
} // end of Find
/***********************************************************************/
/* Returns the length of the longest string in the block. */
/***********************************************************************/
int STRBLK::GetMaxLength(void)
{
int i, n;
for (i = n = 0; i < Nval; i++)
n = max(n, (signed)strlen(Strp[i]));
return n;
} // end of GetMaxLength
/* -------------------------- Class SHRBLK --------------------------- */
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
SHRBLK::SHRBLK(void *mp, int nval)
: VALBLK(mp, TYPE_SHORT, nval), Shrp((short*&)Blkp)
{
} // end of SHRBLK constructor
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void SHRBLK::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(short));
Check = check;
Global = g;
} // end of Init
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void SHRBLK::SetValue(PVAL valp, int n)
{
CheckParms(valp, n)
Shrp[n] = valp->GetShortValue();
} // end of SetValue
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void SHRBLK::SetValue(PSZ p, int n)
{
#if defined(_DEBUG) || defined(DEBTRACE)
if (Check) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BAD_SET_STRING));
longjmp(g->jumper[g->jump_level], Type);
} // endif Check
#endif
Shrp[n] = (short)atoi(p);
} // end of SetValue
/***********************************************************************/
/* Set one value in a block if val is less than the current value. */
/***********************************************************************/
void SHRBLK::SetMin(PVAL valp, int n)
{
CheckParms(valp, n)
short sval = valp->GetShortValue();
short& smin = Shrp[n];
if (sval < smin)
smin = sval;
} // end of SetMin
/***********************************************************************/
/* Set one value in a block if val is greater than the current value. */
/***********************************************************************/
void SHRBLK::SetMax(PVAL valp, int n)
{
CheckParms(valp, n)
short sval = valp->GetShortValue();
short& smin = Shrp[n];
if (sval > smin)
smin = sval;
} // end of SetMax
/***********************************************************************/
/* Set one value in a block from a value in another block. */
/***********************************************************************/
void SHRBLK::SetValue(PVBLK pv, int n1, int n2)
{
CheckType(pv)
Shrp[n1] = ((SHRBLK*)pv)->Shrp[n2];
} // end of SetValue
/***********************************************************************/
/* Set many values in a block from values in another block. */
/***********************************************************************/
void SHRBLK::SetValues(PVBLK pv, int k, int n)
{
CheckType(pv)
short *sp = ((SHRBLK*)pv)->Shrp;
for (register int i = k; i < n; i++)
Shrp[i] = sp[i];
} // end of SetValues
/***********************************************************************/
/* This function is used by class RESCOL when calculating COUNT. */
/***********************************************************************/
void SHRBLK::AddMinus1(PVBLK pv, int n1, int n2)
{
assert(Type == pv->GetType());
Shrp[n1] += (((SHRBLK*)pv)->Shrp[n2] - 1);
} // end of AddMinus1
/***********************************************************************/
/* Move one value from i to j. */
/***********************************************************************/
void SHRBLK::Move(int i, int j)
{
Shrp[j] = Shrp[i];
} // end of Move
/***********************************************************************/
/* Compare a Value object with the nth value of the block. */
/***********************************************************************/
int SHRBLK::CompVal(PVAL vp, int n)
{
CheckParms(vp, n)
short msv = Shrp[n];
short vsv = vp->GetShortValue();
return (vsv > msv) ? 1 : (vsv < msv) ? (-1) : 0;
} // end of CompVal
/***********************************************************************/
/* Compare two values of the block. */
/***********************************************************************/
int SHRBLK::CompVal(int i1, int i2)
{
short sv1 = Shrp[i1];
short sv2 = Shrp[i2];
return (sv1 > sv2) ? 1 : (sv1 < sv2) ? (-1) : 0;
} // end of CompVal
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *SHRBLK::GetValPtr(int n)
{
CheckIndex(n)
return Shrp + n;
} // end of GetValPtr
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *SHRBLK::GetValPtrEx(int n)
{
CheckIndex(n)
return Shrp + n;
} // end of GetValPtrEx
/***********************************************************************/
/* Returns index of matching value in block or -1. */
/***********************************************************************/
int SHRBLK::Find(PVAL vp)
{
CheckType(vp)
int i;
short n = vp->GetShortValue();
for (i = 0; i < Nval; i++)
if (n == Shrp[i])
break;
return (i < Nval) ? i : (-1);
} // end of Find
/***********************************************************************/
/* Returns the length of the longest string in the block. */
/***********************************************************************/
int SHRBLK::GetMaxLength(void)
{
char buf[12];
int i, n;
for (i = n = 0; i < Nval; i++) {
sprintf(buf, "%hd", Shrp[i]);
n = max(n, (signed)strlen(buf));
} // endfor i
return n;
} // end of GetMaxLength
/* -------------------------- Class LNGBLK --------------------------- */
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
LNGBLK::LNGBLK(void *mp, int nval)
: VALBLK(mp, TYPE_INT, nval), Lngp((int*&)Blkp)
{
} // end of LNGBLK constructor
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void LNGBLK::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(int));
Check = check;
Global = g;
} // end of Init
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void LNGBLK::SetValue(PVAL valp, int n)
{
CheckParms(valp, n)
Lngp[n] = valp->GetIntValue();
} // end of SetValue
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void LNGBLK::SetValue(PSZ p, int n)
{
#if defined(_DEBUG) || defined(DEBTRACE)
if (Check) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BAD_SET_STRING));
longjmp(g->jumper[g->jump_level], Type);
} // endif Check
#endif
Lngp[n] = atol(p);
} // end of SetValue
/***********************************************************************/
/* Set one value in a block if val is less than the current value. */
/***********************************************************************/
void LNGBLK::SetMin(PVAL valp, int n)
{
CheckParms(valp, n)
int lval = valp->GetIntValue();
int& lmin = Lngp[n];
if (lval < lmin)
lmin = lval;
} // end of SetMin
/***********************************************************************/
/* Set one value in a block if val is greater than the current value. */
/***********************************************************************/
void LNGBLK::SetMax(PVAL valp, int n)
{
CheckParms(valp, n)
int lval = valp->GetIntValue();
int& lmax = Lngp[n];
if (lval > lmax)
lmax = lval;
} // end of SetMax
/***********************************************************************/
/* Set one value in a block from a value in another block. */
/***********************************************************************/
void LNGBLK::SetValue(PVBLK pv, int n1, int n2)
{
CheckType(pv)
Lngp[n1] = ((LNGBLK*)pv)->Lngp[n2];
} // end of SetValue
/***********************************************************************/
/* Set many values in a block from values in another block. */
/***********************************************************************/
void LNGBLK::SetValues(PVBLK pv, int k, int n)
{
CheckType(pv)
int *lp = ((LNGBLK*)pv)->Lngp;
for (register int i = k; i < n; i++)
Lngp[i] = lp[i];
} // end of SetValues
/***********************************************************************/
/* This function is used by class RESCOL when calculating COUNT. */
/***********************************************************************/
void LNGBLK::AddMinus1(PVBLK pv, int n1, int n2)
{
assert(Type == pv->GetType());
Lngp[n1] += (((LNGBLK*)pv)->Lngp[n2] - 1);
} // end of AddMinus1
/***********************************************************************/
/* Move one value from i to j. */
/***********************************************************************/
void LNGBLK::Move(int i, int j)
{
Lngp[j] = Lngp[i];
} // end of Move
/***********************************************************************/
/* Compare a Value object with the nth value of the block. */
/***********************************************************************/
int LNGBLK::CompVal(PVAL vp, int n)
{
CheckParms(vp, n)
register int mlv = Lngp[n];
register int vlv = vp->GetIntValue();
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
} // end of CompVal
/***********************************************************************/
/* Compare two values of the block. */
/***********************************************************************/
int LNGBLK::CompVal(int i1, int i2)
{
register int lv1 = Lngp[i1];
register int lv2 = Lngp[i2];
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
} // end of CompVal
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *LNGBLK::GetValPtr(int n)
{
CheckIndex(n)
return Lngp + n;
} // end of GetValPtr
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *LNGBLK::GetValPtrEx(int n)
{
CheckIndex(n)
return Lngp + n;
} // end of GetValPtrEx
/***********************************************************************/
/* Returns index of matching value in block or -1. */
/***********************************************************************/
int LNGBLK::Find(PVAL vp)
{
CheckType(vp)
int i;
int n = vp->GetIntValue();
for (i = 0; i < Nval; i++)
if (n == Lngp[i])
break;
return (i < Nval) ? i : (-1);
} // end of Find
/***********************************************************************/
/* Returns the length of the longest string in the block. */
/***********************************************************************/
int LNGBLK::GetMaxLength(void)
{
char buf[12];
int i, n;
for (i = n = 0; i < Nval; i++) {
sprintf(buf, "%d", Lngp[i]);
n = max(n, (signed)strlen(buf));
} // endfor i
return n;
} // end of GetMaxLength
/* -------------------------- Class DATBLK --------------------------- */
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
DATBLK::DATBLK(void *mp, int nval) : LNGBLK(mp, nval)
{
Type = TYPE_DATE;
Dvalp = NULL;
} // end of DATBLK constructor
/***********************************************************************/
/* Set format so formatted dates can be converted on input. */
/***********************************************************************/
bool DATBLK::SetFormat(PGLOBAL g, PSZ fmt, int len, int year)
{
if (!(Dvalp = AllocateValue(g, TYPE_DATE, len, year, fmt)))
return true;
return false;
} // end of SetFormat
/***********************************************************************/
/* Set one value in a block from a char string. */
/***********************************************************************/
void DATBLK::SetValue(PSZ p, int n)
{
if (Dvalp) {
// Decode the string according to format
Dvalp->SetValue_psz(p);
Lngp[n] = Dvalp->GetIntValue();
} else
LNGBLK::SetValue(p, n);
} // end of SetValue
/* -------------------------- Class BIGBLK --------------------------- */
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
BIGBLK::BIGBLK(void *mp, int nval)
: VALBLK(mp, TYPE_BIGINT, nval), Lngp((longlong*&)Blkp)
{
} // end of BIGBLK constructor
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void BIGBLK::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(longlong));
Check = check;
Global = g;
} // end of Init
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void BIGBLK::SetValue(PVAL valp, int n)
{
CheckParms(valp, n)
Lngp[n] = valp->GetBigintValue();
} // end of SetValue
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void BIGBLK::SetValue(PSZ p, int n)
{
#if defined(_DEBUG) || defined(DEBTRACE)
if (Check) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BAD_SET_STRING));
longjmp(g->jumper[g->jump_level], Type);
} // endif Check
#endif
Lngp[n] = atoll(p);
} // end of SetValue
/***********************************************************************/
/* Set one value in a block if val is less than the current value. */
/***********************************************************************/
void BIGBLK::SetMin(PVAL valp, int n)
{
CheckParms(valp, n)
longlong lval = valp->GetIntValue();
longlong& lmin = Lngp[n];
if (lval < lmin)
lmin = lval;
} // end of SetMin
/***********************************************************************/
/* Set one value in a block if val is greater than the current value. */
/***********************************************************************/
void BIGBLK::SetMax(PVAL valp, int n)
{
CheckParms(valp, n)
longlong lval = valp->GetIntValue();
longlong& lmax = Lngp[n];
if (lval > lmax)
lmax = lval;
} // end of SetMax
/***********************************************************************/
/* Set one value in a block from a value in another block. */
/***********************************************************************/
void BIGBLK::SetValue(PVBLK pv, int n1, int n2)
{
CheckType(pv)
Lngp[n1] = ((BIGBLK*)pv)->Lngp[n2];
} // end of SetValue
/***********************************************************************/
/* Set many values in a block from values in another block. */
/***********************************************************************/
void BIGBLK::SetValues(PVBLK pv, int k, int n)
{
CheckType(pv)
longlong *lp = ((BIGBLK*)pv)->Lngp;
for (register int i = k; i < n; i++)
Lngp[i] = lp[i];
} // end of SetValues
/***********************************************************************/
/* This function is used by class RESCOL when calculating COUNT. */
/***********************************************************************/
void BIGBLK::AddMinus1(PVBLK pv, int n1, int n2)
{
assert(Type == pv->GetType());
Lngp[n1] += (((BIGBLK*)pv)->Lngp[n2] - 1);
} // end of AddMinus1
/***********************************************************************/
/* Move one value from i to j. */
/***********************************************************************/
void BIGBLK::Move(int i, int j)
{
Lngp[j] = Lngp[i];
} // end of Move
/***********************************************************************/
/* Compare a Value object with the nth value of the block. */
/***********************************************************************/
int BIGBLK::CompVal(PVAL vp, int n)
{
CheckParms(vp, n)
longlong mlv = Lngp[n];
longlong vlv = vp->GetBigintValue();
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
} // end of CompVal
/***********************************************************************/
/* Compare two values of the block. */
/***********************************************************************/
int BIGBLK::CompVal(int i1, int i2)
{
longlong lv1 = Lngp[i1];
longlong lv2 = Lngp[i2];
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
} // end of CompVal
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *BIGBLK::GetValPtr(int n)
{
CheckIndex(n)
return Lngp + n;
} // end of GetValPtr
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *BIGBLK::GetValPtrEx(int n)
{
CheckIndex(n)
return Lngp + n;
} // end of GetValPtrEx
/***********************************************************************/
/* Returns index of matching value in block or -1. */
/***********************************************************************/
int BIGBLK::Find(PVAL vp)
{
CheckType(vp)
int i;
longlong n = vp->GetBigintValue();
for (i = 0; i < Nval; i++)
if (n == Lngp[i])
break;
return (i < Nval) ? i : (-1);
} // end of Find
/***********************************************************************/
/* Returns the length of the longest string in the block. */
/***********************************************************************/
int BIGBLK::GetMaxLength(void)
{
char buf[24];
int i, n;
for (i = n = 0; i < Nval; i++) {
sprintf(buf, "%lld", Lngp[i]);
n = max(n, (signed)strlen(buf));
} // endfor i
return n;
} // end of GetMaxLength
/* -------------------------- Class DBLBLK --------------------------- */
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
DBLBLK::DBLBLK(void *mp, int nval, int prec)
: VALBLK(mp, TYPE_FLOAT, nval), Dblp((double*&)Blkp)
{
Prec = prec;
} // end of DBLBLK constructor
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void DBLBLK::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(double));
Check = check;
Global = g;
} // end of Init
/***********************************************************************/
/* Set one value in a block from a value in another block. */
/***********************************************************************/
void DBLBLK::SetValue(PVBLK pv, int n1, int n2)
{
CheckType(pv)
Dblp[n1] = ((DBLBLK*)pv)->Dblp[n2];
} // end of SetValue
/***********************************************************************/
/* Set many values in a block from values in another block. */
/***********************************************************************/
void DBLBLK::SetValues(PVBLK pv, int k, int n)
{
CheckType(pv)
double *dp = ((DBLBLK*)pv)->Dblp;
for (register int i = k; i < n; i++)
Dblp[i] = dp[i];
} // end of SetValues
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void DBLBLK::SetValue(PVAL valp, int n)
{
CheckParms(valp, n)
Dblp[n] = valp->GetFloatValue();
} // end of SetValue
/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void DBLBLK::SetValue(PSZ p, int n)
{
#if defined(_DEBUG) || defined(DEBTRACE)
if (Check) {
PGLOBAL& g = Global;
strcpy(g->Message, MSG(BAD_SET_STRING));
longjmp(g->jumper[g->jump_level], Type);
} // endif Check
#endif
Dblp[n] = atof(p);
} // end of SetValue
/***********************************************************************/
/* Set one value in a block if val is less than the current value. */
/***********************************************************************/
void DBLBLK::SetMin(PVAL valp, int n)
{
CheckParms(valp, n)
double fval = valp->GetFloatValue();
double& fmin = Dblp[n];
if (fval < fmin)
fmin = fval;
} // end of SetMin
/***********************************************************************/
/* Set one value in a block if val is greater than the current value. */
/***********************************************************************/
void DBLBLK::SetMax(PVAL valp, int n)
{
CheckParms(valp, n)
double fval = valp->GetFloatValue();
double& fmax = Dblp[n];
if (fval > fmax)
fmax = fval;
} // end of SetMax
/***********************************************************************/
/* Move one value from i to j. */
/***********************************************************************/
void DBLBLK::Move(int i, int j)
{
Dblp[j] = Dblp[i];
} // end of Move
/***********************************************************************/
/* Compare a Value object with the nth value of the block. */
/***********************************************************************/
int DBLBLK::CompVal(PVAL vp, int n)
{
CheckParms(vp, n)
double mfv = Dblp[n];
double vfv = vp->GetFloatValue();
return (vfv > mfv) ? 1 : (vfv < mfv) ? (-1) : 0;
} // end of CompVal
/***********************************************************************/
/* Compare two values of the block. */
/***********************************************************************/
int DBLBLK::CompVal(int i1, int i2)
{
register double dv1 = Dblp[i1];
register double dv2 = Dblp[i2];
return (dv1 > dv2) ? 1 : (dv1 < dv2) ? (-1) : 0;
} // end of CompVal
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *DBLBLK::GetValPtr(int n)
{
CheckIndex(n)
return Dblp + n;
} // end of GetValPtr
/***********************************************************************/
/* Get a pointer on the nth value of the block. */
/***********************************************************************/
void *DBLBLK::GetValPtrEx(int n)
{
CheckIndex(n)
return Dblp + n;
} // end of GetValPtrEx
/***********************************************************************/
/* Returns index of matching value in block or -1. */
/***********************************************************************/
int DBLBLK::Find(PVAL vp)
{
CheckType(vp)
int i;
double d = vp->GetFloatValue();
for (i = 0; i < Nval; i++)
if (d == Dblp[i])
break;
return (i < Nval) ? i : (-1);
} // end of Find
/***********************************************************************/
/* Returns the length of the longest string in the block. */
/***********************************************************************/
int DBLBLK::GetMaxLength(void)
{
char buf[32];
int i, n;
for (i = n = 0; i < Nval; i++) {
sprintf(buf, "%lf", Dblp[i]);
n = max(n, (signed)strlen(buf));
} // endfor i
return n;
} // end of GetMaxLength
/* ------------------------- End of Valblk --------------------------- */