diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2015-05-13 19:58:21 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2015-05-13 19:58:21 +0200 |
commit | e6b60ee5af76a574a9c87733143e608a2bc648bb (patch) | |
tree | 0a1644fa7112ab32e447fba28ae97a5a1735489e /storage/connect/tabfix.cpp | |
parent | 3810fefc65dfaecfac0b0f4c2210126b1e0bc8fa (diff) | |
download | mariadb-git-e6b60ee5af76a574a9c87733143e608a2bc648bb.tar.gz |
Make BIN table files more flexible with new column format.
In particular enable to set length and endian setting.
This should solve all problems on IBM390s machines.
modified: storage/connect/ha_connect.cc
modified: storage/connect/tabfix.cpp
modified: storage/connect/tabfix.h
Make DBF tables to be usable in big-endian machines (test version)
modified: storage/connect/filamdbf.cpp
Ignore git files on storage/connect
modified: .gitignore
Diffstat (limited to 'storage/connect/tabfix.cpp')
-rw-r--r-- | storage/connect/tabfix.cpp | 104 |
1 files changed, 94 insertions, 10 deletions
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp index 5cfd5a726ef..724d8cfde75 100644 --- a/storage/connect/tabfix.cpp +++ b/storage/connect/tabfix.cpp @@ -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. */ @@ -373,19 +374,89 @@ 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 *fmt = cdp->GetFmt(); + + Buff = NULL; + M = GetTypeSize(Buf_Type, Long); + Lim = M; + + if (fmt) { + Fmt = 'H'; + + for (N = 0, i = 0; fmt[i]; i++) + if (isdigit(fmt[i])) + N = (N * 10 + (fmt[i] - 48)); + else + Fmt = toupper(fmt[i]); + + if (N == GetTypeSize(Buf_Type, -1) && (Fmt == 'H' || Fmt == Endian)) { + // New format is a no op + N = 0; + Fmt = 'X'; + } else if (Fmt == 'L' || Fmt == 'B' || Fmt == 'H') { + // This is a new format + if (!N) + N = GetTypeSize(Buf_Type, 0); + + if (Fmt == 'H') + Fmt = Endian; + + Buff = (char*)PlugSubAlloc(g, NULL, M); + memset(Buff, 0, M); + Lim = MY_MIN(N, M); + } // endif Fmt + + } else { + N = 0; + Fmt = 'X'; + } // endif fmt + } // 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) { 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 + +/***********************************************************************/ +/* Copy according to Endian settings and sizes. */ +/***********************************************************************/ +void BINCOL::NumCpy(char *from, char *to) + { + for (int i = 0; i < Lim; i++) + if (Fmt == 'B' && Endian == 'L') + to[i] = from[N - i - 1]; + else if (Fmt == 'L' && Endian == 'B') + to[N - i - 1] = from[i]; + else if (Endian == 'B') + to[M - i - 1] = from[N - i - 1]; + else + to[i] = from[i]; + + } // end of NumCpy + +/***********************************************************************/ /* 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,19 +487,22 @@ void BINCOL::ReadColumn(PGLOBAL g) /*********************************************************************/ /* Set Value from the line field. */ /*********************************************************************/ - switch (Fmt) { + if (N) { + NumCpy(p, Buff); + Value->SetBinValue(Buff); + } else switch (Fmt) { case 'X': // Standard not converted values 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 '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; @@ -490,14 +564,24 @@ void BINCOL::WriteColumn(PGLOBAL g) /* Updating will be done only during the second pass (Status=true) */ /* Conversion occurs if the external format Fmt is specified. */ /*********************************************************************/ - switch (Fmt) { + if (N) { + if (Value->GetBinValue(Buff, M, Status)) { + sprintf(g->Message, MSG(BIN_F_TOO_LONG), + Name, Value->GetSize(), M); + longjmp(g->jumper[g->jump_level], 31); + } // endif Buff + + if (Status) + NumCpy(Buff, p); + + } else switch (Fmt) { case 'X': // Standard not converted values 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 |