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