summaryrefslogtreecommitdiff
path: root/storage/connect/tabfix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect/tabfix.cpp')
-rw-r--r--storage/connect/tabfix.cpp152
1 files changed, 131 insertions, 21 deletions
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index 77e47e6f8dd..acd548c86ab 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -5,7 +5,7 @@
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2015 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -17,7 +17,7 @@
/* Include relevant section of system dependant header files. */
/***********************************************************************/
#include "my_global.h"
-#if defined(WIN32)
+#if defined(__WIN__)
#include <io.h>
#include <fcntl.h>
#include <errno.h>
@@ -25,7 +25,7 @@
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
-#else // !WIN32
+#else // !__WIN__
#if defined(UNIX)
#include <sys/types.h>
#include <sys/stat.h>
@@ -35,7 +35,7 @@
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
-#endif // !WIN32
+#endif // !__WIN__
/***********************************************************************/
/* Include application header files: */
@@ -54,6 +54,7 @@
extern int num_read, num_there, num_eq[2]; // Statistics
static const longlong M2G = 0x80000000;
static const longlong M4G = (longlong)2 * M2G;
+char BINCOL::Endian = 'H';
/***********************************************************************/
/* External function. */
@@ -67,10 +68,12 @@ USETEMP UseTemp(void);
/***********************************************************************/
TDBFIX::TDBFIX(PDOSDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
{
+ Teds = tdp->Teds; // For BIN tables
} // end of TDBFIX standard constructor
TDBFIX::TDBFIX(PGLOBAL g, PTDBFIX tdbp) : TDBDOS(g, tdbp)
{
+ Teds = tdbp->Teds;
} // end of TDBFIX copy constructor
// Method
@@ -271,7 +274,7 @@ int TDBFIX::RowNumber(PGLOBAL g, bool b)
/***********************************************************************/
/* FIX tables don't use temporary files except if specified as do it. */
/***********************************************************************/
-bool TDBFIX::IsUsingTemp(PGLOBAL g)
+bool TDBFIX::IsUsingTemp(PGLOBAL)
{
// Not ready yet to handle using a temporary file with mapping
// or while deleting from DBF files.
@@ -373,19 +376,94 @@ int TDBFIX::WriteDB(PGLOBAL g)
BINCOL::BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
: DOSCOL(g, cdp, tp, cp, i, am)
{
- Fmt = (cdp->GetFmt()) ? toupper(*cdp->GetFmt()) : 'X';
+ char c, *fmt = cdp->GetFmt();
+
+ Fmt = GetDomain() ? 'C' : 'X';
+ Buff = NULL;
+ Eds = ((PTDBFIX)tp)->Teds;
+ N = 0;
+ M = GetTypeSize(Buf_Type, sizeof(longlong));
+ Lim = 0;
+
+ if (fmt) {
+ for (N = 0, i = 0; fmt[i]; i++) {
+ c = toupper(fmt[i]);
+
+ if (isdigit(c))
+ N = (N * 10 + (c - '0'));
+ else if (c == 'L' || c == 'B' || c == 'H')
+ Eds = c;
+ else
+ Fmt = c;
+
+ } // endfor i
+
+ // M is the size of the source value
+ switch (Fmt) {
+ case 'C': Eds = 0; break;
+ case 'X': break;
+ case 'S': M = sizeof(short); break;
+ case 'T': M = sizeof(char); break;
+ case 'I': M = sizeof(int); break;
+ case 'G': M = sizeof(longlong); break;
+ case 'R': // Real
+ case 'F': M = sizeof(float); break;
+ case 'D': M = sizeof(double); break;
+ default:
+ sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name);
+ longjmp(g->jumper[g->jump_level], 11);
+ } // endswitch Fmt
+
+ } else if (IsTypeChar(Buf_Type))
+ Eds = 0;
+
+ if (Eds) {
+ // This is a byte order specification
+ if (!N)
+ N = M;
+
+ if (Eds != 'L' && Eds != 'B')
+ Eds = Endian;
+
+ if (N != M || Eds != Endian || IsTypeChar(Buf_Type)) {
+ Buff = (char*)PlugSubAlloc(g, NULL, M);
+ memset(Buff, 0, M);
+ Lim = MY_MIN(N, M);
+ } else
+ Eds = 0; // New format is a no op
+
+ } // endif Eds
+
} // end of BINCOL constructor
/***********************************************************************/
-/* FIXCOL constructor used for copying columns. */
+/* BINCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
BINCOL::BINCOL(BINCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
{
+ Eds = col1->Eds;
Fmt = col1->Fmt;
+ N = col1->N;
+ M = col1->M;
+ Lim = col1->Lim;
} // end of BINCOL copy constructor
/***********************************************************************/
+/* Set Endian according to the host setting. */
+/***********************************************************************/
+void BINCOL::SetEndian(void)
+ {
+ union {
+ short S;
+ char C[sizeof(short)];
+ };
+
+ S = 1;
+ Endian = (C[0] == 1) ? 'L' : 'B';
+ } // end of SetEndian
+
+/***********************************************************************/
/* ReadColumn: what this routine does is to access the last line */
/* read from the corresponding table and extract from it the field */
/* corresponding to this column. */
@@ -416,22 +494,40 @@ void BINCOL::ReadColumn(PGLOBAL g)
/*********************************************************************/
/* Set Value from the line field. */
/*********************************************************************/
+ if (Eds) {
+ for (int i = 0; i < Lim; i++)
+ if (Eds == 'B' && Endian == 'L')
+ Buff[i] = p[N - i - 1];
+ else if (Eds == 'L' && Endian == 'B')
+ Buff[M - i - 1] = p[i];
+ else if (Endian == 'B')
+ Buff[M - i - 1] = p[N - i - 1];
+ else
+ Buff[i] = p[i];
+
+ p = Buff;
+ } // endif Eds
+
switch (Fmt) {
case 'X': // Standard not converted values
- Value->SetBinValue(p);
+ if (Eds && IsTypeChar(Buf_Type))
+ Value->SetValue(*(longlong*)p);
+ else
+ Value->SetBinValue(p);
+
break;
case 'S': // Short integer
- Value->SetValue((int)*(short*)p);
+ Value->SetValue(*(short*)p);
break;
case 'T': // Tiny integer
- Value->SetValue((int)*p);
+ Value->SetValue(*p);
break;
- case 'L': // Long Integer
- strcpy(g->Message, "Format L is deprecated, use I");
- longjmp(g->jumper[g->jump_level], 11);
case 'I': // Integer
Value->SetValue(*(int*)p);
break;
+ case 'G': // Large (great) integer
+ Value->SetValue(*(longlong*)p);
+ break;
case 'F': // Float
case 'R': // Real
Value->SetValue((double)*(float*)p);
@@ -483,7 +579,7 @@ void BINCOL::WriteColumn(PGLOBAL g)
if (Value != To_Val)
Value->SetValue_pval(To_Val, false); // Convert the updated value
- p = tdbp->To_Line + Deplac;
+ p = (Eds) ? Buff : tdbp->To_Line + Deplac;
/*********************************************************************/
/* Check whether updating is Ok, meaning col value is not too long. */
@@ -493,11 +589,13 @@ void BINCOL::WriteColumn(PGLOBAL g)
switch (Fmt) {
case 'X':
// Standard not converted values
- if (Value->GetBinValue(p, Long, Status)) {
+ if (Eds && IsTypeChar(Buf_Type))
+ *(longlong *)p = Value->GetBigintValue();
+ else if (Value->GetBinValue(p, Long, Status)) {
sprintf(g->Message, MSG(BIN_F_TOO_LONG),
Name, Value->GetSize(), Long);
longjmp(g->jumper[g->jump_level], 31);
- } // endif Fmt
+ } // endif p
break;
case 'S': // Short integer
@@ -520,9 +618,6 @@ void BINCOL::WriteColumn(PGLOBAL g)
*p = (char)n;
break;
- case 'L': // Long Integer
- strcpy(g->Message, "Format L is deprecated, use I");
- longjmp(g->jumper[g->jump_level], 11);
case 'I': // Integer
n = Value->GetBigintValue();
@@ -533,9 +628,9 @@ void BINCOL::WriteColumn(PGLOBAL g)
*(int *)p = Value->GetIntValue();
break;
- case 'B': // Large (big) integer
+ case 'G': // Large (great) integer
if (Status)
- *(longlong *)p = (longlong)Value->GetBigintValue();
+ *(longlong *)p = Value->GetBigintValue();
break;
case 'F': // Float
@@ -567,6 +662,21 @@ void BINCOL::WriteColumn(PGLOBAL g)
longjmp(g->jumper[g->jump_level], 11);
} // endswitch Fmt
+ if (Eds && Status) {
+ p = tdbp->To_Line + Deplac;
+
+ for (int i = 0; i < Lim; i++)
+ if (Eds == 'B' && Endian == 'L')
+ p[N - i - 1] = Buff[i];
+ else if (Eds == 'L' && Endian == 'B')
+ p[i] = Buff[M - i - 1];
+ else if (Endian == 'B')
+ p[N - i - 1] = Buff[M - i - 1];
+ else
+ p[i] = Buff[i];
+
+ } // endif Eds
+
} // end of WriteColumn
/* ------------------------ End of TabFix ---------------------------- */