SqlStringTestAscii.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calctest/SqlStringTestAscii.cpp#2 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2004-2009 The Eigenbase Project
00005 // Copyright (C) 2004-2009 SQLstream, Inc.
00006 // Copyright (C) 2009-2009 LucidEra, Inc.
00007 //
00008 // This program is free software; you can redistribute it and/or modify it
00009 // under the terms of the GNU General Public License as published by the Free
00010 // Software Foundation; either version 2 of the License, or (at your option)
00011 // any later version approved by The Eigenbase Project.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #include "fennel/common/CommonPreamble.h"
00024 #include "fennel/test/TestBase.h"
00025 #include "fennel/calc/SqlString.h"
00026 #include "fennel/common/TraceSource.h"
00027 
00028 #include <boost/test/test_tools.hpp>
00029 #include <boost/scoped_array.hpp>
00030 #include <string>
00031 #include <limits>
00032 
00033 using namespace fennel;
00034 using namespace std;
00035 
00036 
00037 const int MAXLEN = 8;   // Must not be less than 5. Best >=7.
00038 const int MAXRANDOM = 5;
00039 const int MAXCMPLEN = 8;  // Must not be less than 3.
00040 const int BUMPERLEN = 3;
00041 const char BUMPERCH = '@';
00042 
00043 
00044 // must support 0 length strings
00045 class SqlStringTestGen
00046 {
00047 public:
00048     SqlStringTestGen(
00049         int storage,            // maximum size (column width) of string
00050         int size,             // size of text, excluding padding
00051         int leftpad = 0,      // pad left with this many chars
00052         int rightpad = 0,     // pad right with this many chars
00053         char text = 'x',     // fill text w/this
00054         char pad = ' ',      // pad w/this
00055         int leftBumper = BUMPERLEN,  // try to pick something unaligned...
00056         int rightBumper = BUMPERLEN)
00057         : mStorage(storage),
00058           mSize(size),
00059           mLeftPad(leftpad),
00060           mRightPad(rightpad),
00061           mLeftBump(leftBumper),
00062           mRightBump(rightBumper),
00063           mTotal(storage + leftBumper + rightBumper),
00064           mS(mTotal, BUMPERCH)
00065     {
00066         assert(leftBumper > 0);
00067         assert(rightBumper > 0);
00068         assert(storage == size + leftpad + rightpad);
00069 
00070         mLeftP = const_cast<char *>(mS.c_str()); // Too abusive of string()?
00071         mStr = mLeftP + mLeftBump;
00072         mRightP = mStr + mStorage;
00073 
00074         string padS(mStorage, pad);
00075         string textS(size, text);
00076 
00077         mS.replace(mLeftBump, mStorage, padS, 0, mStorage); // pad all first
00078         mS.replace(mLeftBump + mLeftPad, mSize, textS, 0, mSize);
00079     }
00080 
00081     bool
00082     verify()
00083     {
00084         string verS(mTotal, BUMPERCH);
00085         if (mS.compare(0, mLeftBump, verS, 0, mLeftBump)) {
00086             return false;
00087         }
00088         if (mS.compare(
00089             mLeftBump + mLeftPad + mSize + mRightPad,
00090             mRightBump, verS, 0, mRightBump))
00091         {
00092             return false;
00093         }
00094         return true;
00095     }
00096 
00097     void
00098     randomize(
00099         unsigned char start = 'A',
00100         unsigned char lower = ' ',
00101         unsigned char upper = '~')
00102     {
00103         patternfill(start, lower, upper);
00104         string r(mStr, mSize);
00105         random_shuffle(r.begin(), r.end());
00106         mS.replace(mLeftBump + mLeftPad, mSize, r);
00107     }
00108 
00109     void
00110     patternfill(
00111         unsigned char start = 'A',
00112         unsigned char lower = ' ',
00113         unsigned char upper = '~')
00114     {
00115         uint c; // deal with overflow easier than char
00116         int toGen = mSize;
00117 
00118         string r;
00119 
00120         c = start;
00121         while (toGen) {
00122             r.push_back(static_cast<unsigned char>(c));
00123             toGen--;
00124             if (++c > upper) {
00125                 c = lower;
00126             }
00127         }
00128         mS.replace(mLeftBump + mLeftPad, mSize, r);
00129     }
00130 
00131 
00132     char * mStr;           // valid string start. (includes left padding)
00133     char * mRightP;   // right bumper start. valid string ends 1 before here
00134     char * mLeftP;         // left bumper start.
00135     const int mStorage;    // maximum size (column width) of string
00136     const int mSize;       // size of string
00137     const int mLeftPad;    // length of left padding
00138     const int mRightPad;   // length of right padding
00139     const int mLeftBump;   // length of left bumper
00140     const int mRightBump;  // length of right bumper
00141     const int mTotal;      // size of string + bumpers
00142     string mS;
00143 
00144 private:
00145 
00146     string
00147     vectortostring(vector<char> &v)
00148     {
00149         string s;
00150         vector<char>::iterator i = v.begin();
00151         while (i != v.end()) {
00152             s.push_back(*i);
00153             i++;
00154         }
00155         return s;
00156     }
00157 };
00158 
00159 
00160 class SqlStringTest : virtual public TestBase, public TraceSource
00161 {
00162     void testSqlStringClass();
00163 
00164     void testSqlStringAsciiCatF();
00165     void testSqlStringAsciiCatV();
00166     void testSqlStringAsciiCatV2();
00167     void testSqlStringAsciiCmpFDiffLen();
00168     void testSqlStringAsciiCmpFEqLen();
00169     void testSqlStringAsciiCmpVDiffLen();
00170     void testSqlStringAsciiCmpVEqLen();
00171     void testSqlStringAsciiLenBit();
00172     void testSqlStringAsciiLenChar();
00173     void testSqlStringAsciiLenOct();
00174     void testSqlStringAsciiOverlay();
00175     void testSqlStringAsciiPos();
00176     void testSqlStringAsciiSubStr();
00177     void testSqlStringAsciiToLower();
00178     void testSqlStringAsciiToUpper();
00179     void testSqlStringAsciiTrim();
00180 
00181     void testSqlStringAsciiCmpVHelper(
00182         SqlStringTestGen &src1,
00183         int src1_len,
00184         SqlStringTestGen &src2,
00185         int src2_len);
00186     void testSqlStringAsciiCmpFHelper(
00187         SqlStringTestGen &src1,
00188         int src1_storage,
00189         int src1_len,
00190         SqlStringTestGen &src2,
00191         int src2_storage,
00192         int src2_len);
00193     int testSqlStringNormalizeLexicalCmp(int v);
00194 
00195 public:
00196     explicit SqlStringTest()
00197         : TraceSource(shared_from_this(),"SqlStringTest")
00198     {
00199         srand(time(NULL));
00200         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringClass);
00201         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiCatF);
00202         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiCatV2);
00203         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiCatV);
00204         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiCmpFDiffLen);
00205         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiCmpFEqLen);
00206         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiCmpVDiffLen);
00207         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiCmpVEqLen);
00208         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiLenBit);
00209         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiLenChar);
00210         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiLenOct);
00211         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiOverlay);
00212         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiPos);
00213         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiSubStr);
00214         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiToLower);
00215         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiToUpper);
00216         FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAsciiTrim);
00217     }
00218 
00219     virtual ~SqlStringTest()
00220     {
00221     }
00222 };
00223 
00224 void
00225 SqlStringTest::testSqlStringClass()
00226 {
00227     int storage, size, leftpad, rightpad;
00228     int leftbump = 2;
00229     int rightbump = 2;
00230     int k;
00231 
00232     for (storage = 0; storage <= 5; storage++) {
00233         for (size = 0; size <= storage; size++) {
00234             for (leftpad = 0; leftpad <= storage - size; leftpad++) {
00235                 rightpad = (storage - size) - leftpad;
00236 
00237                 SqlStringTestGen t(
00238                     storage, size,
00239                     leftpad, rightpad,
00240                     'x', ' ',
00241                     leftbump, rightbump);
00242 
00243                 BOOST_CHECK_EQUAL(t.mStorage, storage);
00244                 BOOST_CHECK_EQUAL(t.mSize, size);
00245                 BOOST_CHECK_EQUAL(t.mLeftPad, leftpad);
00246                 BOOST_CHECK_EQUAL(t.mRightPad, rightpad);
00247                 BOOST_CHECK_EQUAL(
00248                     static_cast<int>(t.mS.size()),
00249                     storage + leftbump + rightbump);
00250 
00251                 BOOST_CHECK(t.verify());
00252 
00253                 char *p = t.mLeftP;
00254                 // left bumper
00255                 for (k = 0; k < leftbump; k++) {
00256                     BOOST_CHECK_EQUAL(*(p++), BUMPERCH);
00257                 }
00258                 BOOST_CHECK(p == t.mStr);
00259                 // left padding
00260                 for (k = 0; k < leftpad; k++) {
00261                     BOOST_CHECK_EQUAL(*(p++), ' ');
00262                 }
00263                 // text
00264                 for (k = 0; k < size; k++) {
00265                     BOOST_CHECK_EQUAL(*(p++), 'x');
00266                 }
00267                 // right padding
00268                 for (k = 0; k < rightpad; k++) {
00269                     BOOST_CHECK_EQUAL(*(p++), ' ');
00270                 }
00271                 BOOST_CHECK(p == t.mRightP);
00272                 // right bumper
00273                 for (k = 0; k < rightbump; k++) {
00274                     BOOST_CHECK_EQUAL(*(p++), BUMPERCH);
00275                 }
00276                 BOOST_CHECK_EQUAL(
00277                     static_cast<int>(p - t.mLeftP),
00278                     storage + leftbump + rightbump);
00279 
00280                 BOOST_CHECK(t.verify());
00281 
00282                 for (k = 0; k < size; k++) {
00283                     *(t.mStr + k) = '0' + (k % 10);
00284                 }
00285                 BOOST_CHECK(t.verify());
00286 
00287                 *(t.mLeftP) = 'X';
00288                 BOOST_CHECK(!t.verify());
00289                 *(t.mLeftP) = BUMPERCH;
00290                 BOOST_CHECK(t.verify());
00291 
00292                 *(t.mStr - 1) = 'X';
00293                 BOOST_CHECK(!t.verify());
00294                 *(t.mStr - 1) = BUMPERCH;
00295                 BOOST_CHECK(t.verify());
00296 
00297                 *(t.mRightP) = 'X';
00298                 BOOST_CHECK(!t.verify());
00299                 *(t.mRightP) = BUMPERCH;
00300                 BOOST_CHECK(t.verify());
00301 
00302                 *(t.mRightP + t.mRightBump - 1) = 'X';
00303                 BOOST_CHECK(!t.verify());
00304                 *(t.mRightP + t.mRightBump - 1) = BUMPERCH;
00305                 BOOST_CHECK(t.verify());
00306 
00307                 t.randomize();
00308                 BOOST_CHECK(t.verify());
00309             }
00310         }
00311     }
00312 }
00313 
00314 
00315 // Test catting 3 fixed width strings together as proof-of-concept
00316 void
00317 SqlStringTest::testSqlStringAsciiCatF()
00318 {
00319     int src1_storage, src2_storage, src3_storage, dst_storage;
00320     int src1_len, src2_len, src3_len;
00321     bool caught;
00322     int newlen;
00323 
00324     for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00325         for (src1_storage = 0; src1_storage < MAXLEN; src1_storage++) {
00326             for (src1_len = 0; src1_len <= src1_storage; src1_len++) {
00327                 for (src2_storage = 0; src2_storage < MAXLEN; src2_storage++) {
00328                     for (src2_len = 0; src2_len <= src2_storage; src2_len++) {
00329                         for (src3_storage = 0; src3_storage < MAXLEN;
00330                              src3_storage++)
00331                         {
00332                             for (src3_len = 0; src3_len <= src3_storage;
00333                                  src3_len++)
00334                             {
00335                                 SqlStringTestGen dst(
00336                                     dst_storage, 0,
00337                                     0, dst_storage,
00338                                     'd', ' ');
00339                                 SqlStringTestGen src1(
00340                                     src1_storage, src1_len,
00341                                     0, src1_storage - src1_len,
00342                                     '1', ' ');
00343                                 SqlStringTestGen src2(
00344                                     src2_storage, src2_len,
00345                                     0, src2_storage - src2_len,
00346                                     '2', ' ');
00347                                 SqlStringTestGen src3(
00348                                     src3_storage, src3_len,
00349                                     0, src3_storage - src3_len,
00350                                     '3', ' ');
00351 
00352                                 caught = false;
00353                                 try {
00354                                     newlen = SqlStrAsciiCat(
00355                                         dst.mStr, dst_storage,
00356                                         src1.mStr, src1_storage,
00357                                         src2.mStr, src2_storage);
00358                                 } catch (const char *str) {
00359                                     caught = true;
00360                                     BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00361                                     BOOST_CHECK(
00362                                         src1_storage + src2_storage
00363                                         > dst_storage);
00364                                     BOOST_CHECK(dst.verify());
00365                                     BOOST_CHECK(src1.verify());
00366                                     BOOST_CHECK(src2.verify());
00367                                 } catch (...) {
00368                                     BOOST_CHECK(false);
00369                                 }
00370                                 if (!caught) {
00371                                     BOOST_CHECK(
00372                                         src1_storage + src2_storage
00373                                         <= dst_storage);
00374                                     BOOST_CHECK(dst.verify());
00375                                     BOOST_CHECK(src1.verify());
00376                                     BOOST_CHECK(src2.verify());
00377 
00378                                     caught = false;
00379                                     try {
00380                                         newlen = SqlStrAsciiCat(
00381                                             dst.mStr,
00382                                             dst_storage,
00383                                             newlen,
00384                                             src3.mStr,
00385                                             src3_storage);
00386                                     } catch (const char *str) {
00387                                         caught = true;
00388                                         BOOST_CHECK_EQUAL(
00389                                             strcmp(str, "22001"),
00390                                             0);
00391                                         BOOST_CHECK(
00392                                             (src1_storage +
00393                                              src2_storage +
00394                                              src3_storage)
00395                                             > dst_storage);
00396                                         BOOST_CHECK(dst.verify());
00397                                         BOOST_CHECK(src1.verify());
00398                                         BOOST_CHECK(src2.verify());
00399                                         BOOST_CHECK(src3.verify());
00400                                     } catch (...) {
00401                                         BOOST_CHECK(false);
00402                                     }
00403                                     if (!caught) {
00404                                         BOOST_CHECK(dst.verify());
00405                                         BOOST_CHECK(src1.verify());
00406                                         BOOST_CHECK(src2.verify());
00407                                         BOOST_CHECK(src3.verify());
00408                                         BOOST_CHECK_EQUAL(
00409                                             newlen,
00410                                             (src1_storage +
00411                                              src2_storage +
00412                                              src3_storage));
00413 
00414                                         string result(dst.mStr, newlen);
00415                                         string expect(src1.mStr, src1_storage);
00416                                         expect.append(src2.mStr, src2_storage);
00417                                         expect.append(src3.mStr, src3_storage);
00418 
00419                                         BOOST_CHECK(!result.compare(expect));
00420                                     }
00421                                 }
00422                             }
00423                         }
00424                     }
00425                 }
00426             }
00427         }
00428     }
00429 
00430 }
00431 
00432 
00433 void
00434 SqlStringTest::testSqlStringAsciiCatV2()
00435 {
00436     int src1_storage, src2_storage, dst_storage, src1_len, src2_len;
00437     int newlen;
00438     bool caught;
00439 
00440     for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00441         for (src1_storage = 0; src1_storage < MAXLEN; src1_storage++) {
00442             for (src1_len = 0; src1_len <= src1_storage; src1_len++) {
00443                 for (src2_storage = 0; src2_storage < MAXLEN; src2_storage++) {
00444                     for (src2_len = 0; src2_len <= src2_storage; src2_len++) {
00445                         SqlStringTestGen dst(
00446                             dst_storage, 0,
00447                             0, dst_storage,
00448                             'd', ' ');
00449                         SqlStringTestGen src1(
00450                             src1_storage, src1_len,
00451                             0, src1_storage - src1_len,
00452                             's', ' ');
00453                         SqlStringTestGen src2(
00454                             src2_storage, src2_len,
00455                             0, src2_storage - src2_len,
00456                             'S', ' ');
00457 
00458                         caught = false;
00459                         try {
00460                             newlen = SqlStrAsciiCat(
00461                                 dst.mStr,
00462                                 dst_storage,
00463                                 src1.mStr,
00464                                 src1_len,
00465                                 src2.mStr,
00466                                 src2_len);
00467                         } catch (const char *str) {
00468                             caught = true;
00469                             BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00470                             BOOST_CHECK(src1_len + src2_len > dst_storage);
00471                         } catch (...) {
00472                             BOOST_CHECK(false);
00473                         }
00474                         if (!caught) {
00475                             BOOST_CHECK(src1_len + src2_len <= dst_storage);
00476                             BOOST_CHECK_EQUAL(newlen, src1_len + src2_len);
00477 
00478                             string expect;
00479                             expect.append(src1_len, 's');
00480                             expect.append(src2_len, 'S');
00481 
00482                             string result(dst.mStr, newlen);
00483 
00484                             BOOST_CHECK(!result.compare(expect));
00485                             BOOST_CHECK(!expect.compare(result));
00486                         }
00487                         BOOST_CHECK(dst.verify());
00488                         BOOST_CHECK(src1.verify());
00489                         BOOST_CHECK(src2.verify());
00490                     }
00491                 }
00492             }
00493         }
00494     }
00495 }
00496 
00497 
00498 void
00499 SqlStringTest::testSqlStringAsciiCatV()
00500 {
00501     int src_storage, dst_storage, src_len, dst_len;
00502     int newlen;
00503     bool caught;
00504 
00505     for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00506         for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
00507             for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
00508                 for (src_len = 0; src_len <= src_storage; src_len++) {
00509                     SqlStringTestGen dst(
00510                         dst_storage, dst_len,
00511                         0, dst_storage - dst_len,
00512                         'd', ' ');
00513                     SqlStringTestGen src(
00514                         src_storage, src_len,
00515                         0, src_storage - src_len,
00516                         's', ' ');
00517                     caught = false;
00518                     try {
00519                         newlen = SqlStrAsciiCat(
00520                             dst.mStr,
00521                             dst_storage,
00522                             dst_len,
00523                             src.mStr,
00524                             src_len);
00525                     } catch (const char *str) {
00526                         caught = true;
00527                         BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00528                         BOOST_CHECK(src_len + dst_len > dst_storage);
00529                     } catch (...) {
00530                         BOOST_CHECK(false);
00531                     }
00532                     if (!caught) {
00533                         BOOST_CHECK(src_len + dst_len <= dst_storage);
00534                         BOOST_CHECK_EQUAL(newlen, src_len + dst_len);
00535 
00536                         string expect;
00537                         expect.append(dst_len, 'd');
00538                         expect.append(src_len, 's');
00539 
00540                         string result(dst.mStr, newlen);
00541 
00542                         BOOST_CHECK(!result.compare(expect));
00543                         BOOST_CHECK(!expect.compare(result));
00544                     }
00545                     BOOST_CHECK(dst.verify());
00546                     BOOST_CHECK(src.verify());
00547                 }
00548             }
00549         }
00550     }
00551 }
00552 
00553 int
00554 SqlStringTest::testSqlStringNormalizeLexicalCmp(int v)
00555 {
00556     if (v < 0) {
00557         return -1;
00558     }
00559     if (v > 0) {
00560         return 1;
00561     }
00562     return 0;
00563 }
00564 
00565 
00566 
00567 void
00568 SqlStringTest::testSqlStringAsciiCmpFHelper(
00569     SqlStringTestGen &src1,
00570     int src1_storage,
00571     int src1_len,
00572     SqlStringTestGen &src2,
00573     int src2_storage,
00574     int src2_len)
00575 {
00576     int result;
00577 
00578     string s1(src1.mStr, src1_len);
00579     string s2(src2.mStr, src2_len);
00580 
00581     // It is possible that test string ends with a space. Remove it.
00582     s1.erase(s1.find_last_not_of(" ") + 1);
00583     s2.erase(s2.find_last_not_of(" ") + 1);
00584 
00585     int expected = testSqlStringNormalizeLexicalCmp(s1.compare(s2));
00586     char const * const s1p = s1.c_str();
00587     char const * const s2p = s2.c_str();
00588     int expected2 = testSqlStringNormalizeLexicalCmp(strcmp(s1p, s2p));
00589     BOOST_CHECK_EQUAL(expected, expected2);
00590 
00591     result = SqlStrAsciiCmpF(
00592         src1.mStr, src1_storage,
00593         src2.mStr, src2_storage);
00594     BOOST_CHECK(src1.verify());
00595     BOOST_CHECK(src2.verify());
00596 
00597 #if 0
00598     BOOST_MESSAGE(" src1=|" << s1 << "|" <<
00599                   " src2=|" << s2 << "|" <<
00600                   " expect=" << expected <<
00601                   " expect2=" << expected2 <<
00602                   " result=" << result);
00603 #endif
00604     BOOST_CHECK_EQUAL(result, expected);
00605 
00606     // check the exact opposite, even if equal
00607     int result2 = SqlStrAsciiCmpF(
00608         src2.mStr, src2_storage,
00609         src1.mStr, src1_storage);
00610     BOOST_CHECK(src1.verify());
00611     BOOST_CHECK(src2.verify());
00612     BOOST_CHECK_EQUAL(result2 * -1, result);
00613 
00614     // force check of equal strings
00615     result = SqlStrAsciiCmpF(
00616         src1.mStr, src1_storage,
00617         src1.mStr, src1_storage);
00618     BOOST_CHECK(src1.verify());
00619     BOOST_CHECK_EQUAL(result, 0);
00620 
00621 }
00622 
00623 
00624 void
00625 SqlStringTest::testSqlStringAsciiCmpFDiffLen()
00626 {
00627     int src1_storage, src2_storage, src1_len, src2_len;
00628     unsigned char startchar;
00629 
00630     for (src1_storage = 0; src1_storage <= MAXLEN; src1_storage++) {
00631         for (src1_len = 0; src1_len < src1_storage; src1_len++) {
00632             for (src2_storage = 0; src2_storage <= MAXLEN; src2_storage++) {
00633                 for (src2_len = 0; src2_len < src2_storage; src2_len++) {
00634                     // can't test w/ 0, confuses strcmp and/or std:string
00635                     for (startchar = 1; startchar < 255; startchar++) {
00636                         SqlStringTestGen src1(
00637                             src1_storage, src1_len,
00638                             0, src1_storage - src1_len,
00639                             'd', ' ');
00640                         SqlStringTestGen src2(
00641                             src2_storage, src2_len,
00642                             0, src2_storage - src2_len,
00643                             's', ' ');
00644 
00645                         src1.patternfill(startchar, 1, 255);
00646                         src2.patternfill(startchar, 1, 255);
00647 
00648                         testSqlStringAsciiCmpFHelper(
00649                             src1, src1_storage, src1_len,
00650                             src2, src2_storage, src2_len);
00651                     }
00652                 }
00653             }
00654         }
00655     }
00656 }
00657 
00658 
00659 void
00660 SqlStringTest::testSqlStringAsciiCmpFEqLen()
00661 {
00662     int src1_storage, src2_storage, src1_len, src2_len, randX;
00663 
00664     // not much point large length, chances of 2 random strings being equal
00665     // are very low. test forces an equality check anyway.
00666     src1_storage = MAXCMPLEN;
00667     src2_storage = MAXCMPLEN;
00668     for (src1_len = 0; src1_len < src1_storage; src1_len++) {
00669         src2_len = src1_len;
00670         for (randX = 0; randX <= 65536; randX++) {
00671             SqlStringTestGen src1(
00672                 src1_storage, src1_len,
00673                 0, src1_storage - src1_len,
00674                 'd', ' ');
00675             SqlStringTestGen src2(
00676                 src2_storage, src2_len,
00677                 0, src2_storage - src2_len,
00678                 's', ' ');
00679 
00680             // can't test w/ 0, confuses strcmp and/or std:string
00681             src1.randomize(1, 1, 255);
00682             src2.randomize(1, 1, 255);
00683 
00684             testSqlStringAsciiCmpFHelper(
00685                 src1, src1_storage, src1_len,
00686                 src2, src2_storage, src2_len);
00687         }
00688     }
00689 }
00690 
00691 
00692 void
00693 SqlStringTest::testSqlStringAsciiCmpVHelper(
00694     SqlStringTestGen &src1,
00695     int src1_len,
00696     SqlStringTestGen &src2,
00697     int src2_len)
00698 {
00699     int result;
00700 
00701     string s1(src1.mStr, src1_len);
00702     string s2(src2.mStr, src2_len);
00703 
00704     int expected = testSqlStringNormalizeLexicalCmp(s1.compare(s2));
00705     char const * const s1p = s1.c_str();
00706     char const * const s2p = s2.c_str();
00707     int expected2 = testSqlStringNormalizeLexicalCmp(strcmp(s1p, s2p));
00708     BOOST_CHECK_EQUAL(expected, expected2);
00709 
00710 
00711     result = SqlStrAsciiCmpV(
00712         src1.mStr, src1_len,
00713         src2.mStr, src2_len);
00714     BOOST_CHECK(src1.verify());
00715     BOOST_CHECK(src2.verify());
00716 
00717 #if 0
00718     BOOST_MESSAGE(" src1=|" << s1 << "|" <<
00719                   " src2=|" << s2 << "|" <<
00720                   " expect=" << expected <<
00721                   " expect2=" << expected2 <<
00722                   " result=" << result);
00723 #endif
00724     BOOST_CHECK_EQUAL(result, expected);
00725 
00726     // check the exact opposite, even if equal
00727     int result2 = SqlStrAsciiCmpV(
00728         src2.mStr, src2_len,
00729         src1.mStr, src1_len);
00730     BOOST_CHECK(src1.verify());
00731     BOOST_CHECK(src2.verify());
00732     BOOST_CHECK_EQUAL(result2 * -1, result);
00733 
00734     // force check of equal strings
00735     result = SqlStrAsciiCmpV(
00736         src1.mStr, src1_len,
00737         src1.mStr, src1_len);
00738     BOOST_CHECK(src1.verify());
00739     BOOST_CHECK_EQUAL(result, 0);
00740 
00741 }
00742 
00743 
00744 void
00745 SqlStringTest::testSqlStringAsciiCmpVDiffLen()
00746 {
00747     int src1_storage, src2_storage, src1_len, src2_len;
00748     unsigned char startchar;
00749 
00750     for (src1_storage = 0; src1_storage <= MAXLEN; src1_storage++) {
00751         src1_len = src1_storage;
00752         for (src2_storage = 0; src2_storage <= MAXLEN; src2_storage++) {
00753             src2_len = src2_storage;
00754             // can't test w/ 0, confuses strcmp and/or std:string
00755             for (startchar = 1; startchar < 255; startchar++) {
00756                 SqlStringTestGen src1(
00757                     src1_storage, src1_len,
00758                     0, src1_storage - src1_len,
00759                     'd', ' ');
00760                 SqlStringTestGen src2(
00761                     src2_storage, src2_len,
00762                     0, src2_storage - src2_len,
00763                     's', ' ');
00764 
00765                 src1.patternfill(startchar, 1, 255);
00766                 src2.patternfill(startchar, 1, 255);
00767 
00768                 testSqlStringAsciiCmpVHelper(
00769                     src1, src1_len,
00770                     src2, src2_len);
00771             }
00772         }
00773     }
00774 }
00775 
00776 
00777 void
00778 SqlStringTest::testSqlStringAsciiCmpVEqLen()
00779 {
00780     int src1_storage, src2_storage, src1_len, src2_len, randX;
00781 
00782     // not much point large length, chances of 2 random strings being equal
00783     // are very low. test forces an equality check anyway.
00784     src1_storage = MAXCMPLEN;
00785     src1_len = src1_storage;
00786     src2_storage = src1_storage;
00787     src2_len = src1_storage;
00788     for (randX = 0; randX <= 65536; randX++) {
00789         SqlStringTestGen src1(
00790             src1_storage, src1_len,
00791             0, src1_storage - src1_len,
00792             'd', ' ');
00793         SqlStringTestGen src2(
00794             src2_storage, src2_len,
00795             0, src2_storage - src2_len,
00796             's', ' ');
00797 
00798         // can't test w/ 0, confuses strcmp and/or std:string
00799         src1.randomize(1, 1, 255);
00800         src2.randomize(1, 1, 255);
00801 
00802         testSqlStringAsciiCmpVHelper(
00803             src1, src1_len,
00804             src2, src2_len);
00805     }
00806 }
00807 
00808 
00809 void
00810 SqlStringTest::testSqlStringAsciiLenBit()
00811 {
00812     int src_storage, src_len;
00813     int newlen;
00814 
00815     src_storage = MAXLEN;
00816     for (src_storage = 0; src_storage <= MAXLEN; src_storage++) {
00817         for (src_len = 0; src_len <= src_storage; src_len++) {
00818             SqlStringTestGen src(
00819                 src_storage, src_len,
00820                 0, src_storage - src_len,
00821                 's', ' ');
00822 
00823             newlen = SqlStrAsciiLenBit(
00824                 src.mStr,
00825                 src_len);
00826             BOOST_CHECK_EQUAL(newlen, src_len * 8);
00827             BOOST_CHECK(src.verify());
00828 
00829             newlen = SqlStrAsciiLenBit(
00830                 src.mStr,
00831                 src_storage);
00832             BOOST_CHECK_EQUAL(newlen, src_storage * 8);
00833             BOOST_CHECK(src.verify());
00834         }
00835     }
00836 }
00837 
00838 
00839 void
00840 SqlStringTest::testSqlStringAsciiLenChar()
00841 {
00842     int src_storage, src_len;
00843     int newlen;
00844 
00845     src_storage = MAXLEN;
00846     for (src_storage = 0; src_storage <= MAXLEN; src_storage++) {
00847         for (src_len = 0; src_len <= src_storage; src_len++) {
00848             SqlStringTestGen src(
00849                 src_storage, src_len,
00850                 0, src_storage - src_len,
00851                 's', ' ');
00852 
00853             newlen = SqlStrAsciiLenChar(
00854                 src.mStr,
00855                 src_len);
00856             BOOST_CHECK_EQUAL(newlen, src_len);
00857             BOOST_CHECK(src.verify());
00858 
00859             newlen = SqlStrAsciiLenChar(
00860                 src.mStr,
00861                 src_storage);
00862             BOOST_CHECK_EQUAL(newlen, src_storage);
00863             BOOST_CHECK(src.verify());
00864         }
00865     }
00866 }
00867 
00868 
00869 void
00870 SqlStringTest::testSqlStringAsciiLenOct()
00871 {
00872     int src_storage, src_len;
00873     int newlen;
00874 
00875     src_storage = MAXLEN;
00876     for (src_storage = 0; src_storage <= MAXLEN; src_storage++) {
00877         for (src_len = 0; src_len <= src_storage; src_len++) {
00878             SqlStringTestGen src(
00879                 src_storage, src_len,
00880                 0, src_storage - src_len,
00881                 's', ' ');
00882 
00883             newlen = SqlStrAsciiLenOct(
00884                 src.mStr,
00885                 src_len);
00886             BOOST_CHECK_EQUAL(newlen, src_len);
00887             BOOST_CHECK(src.verify());
00888 
00889             newlen = SqlStrAsciiLenOct(
00890                 src.mStr,
00891                 src_storage);
00892             BOOST_CHECK_EQUAL(newlen, src_storage);
00893             BOOST_CHECK(src.verify());
00894         }
00895     }
00896 }
00897 
00898 
00899 void
00900 SqlStringTest::testSqlStringAsciiOverlay()
00901 {
00902     int dst_storage, src_storage, src_len, over_storage, over_len;
00903     int position, length, lengthI;
00904     int exLeftLen, exMidLen, exRightLen;
00905     char *exLeftP, *exMidP, *exRightP;
00906     bool lenSpecified;
00907     bool caught;
00908     int newlen;
00909 
00910     for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00911         for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
00912             src_len = src_storage;
00913             for (over_storage = 0; over_storage < MAXLEN; over_storage++) {
00914                 over_len = over_storage;
00915                 for (position = 0; position < MAXLEN; position++) {
00916                     for (lengthI = -1; lengthI < MAXLEN; lengthI++) {
00917                         if (lengthI == -1) {
00918                             lenSpecified = false;
00919                             length = over_len;
00920                         } else {
00921                             lenSpecified = true;
00922                             length = lengthI;
00923                         }
00924 #if 0
00925                         BOOST_MESSAGE(" dst_storage=" << dst_storage <<
00926                                       " src_storage=" << src_storage <<
00927                                       " over_storage=" << over_storage <<
00928                                       " pos=" << position <<
00929                                       " length=" << length <<
00930                                       " spec=" << lenSpecified);
00931 #endif
00932                         SqlStringTestGen dst(
00933                             dst_storage, dst_storage,
00934                             0, 0,
00935                             'd', ' ');
00936                         SqlStringTestGen src(
00937                             src_storage, src_len,
00938                             0, src_storage - src_len,
00939                             's', ' ');
00940                         SqlStringTestGen over(
00941                             over_storage, over_len,
00942                             0, over_storage - over_len,
00943                             'o', ' ');
00944 
00945                         src.patternfill('a', 'a', 'z');
00946                         over.patternfill('A', 'A', 'Z');
00947 
00948                         // ex* vars are 0-indexed. for loops are 1-indexed
00949                         exLeftP = src.mStr;
00950                         if (position >= 1 && src_len >= 1) {
00951                             exLeftLen = position - 1;  // 1-idx -> 0-idx
00952                             if (exLeftLen > src_len) {
00953                                 exLeftLen = src_len;
00954                             }
00955                         } else {
00956                             exLeftLen = 0;
00957                         }
00958 
00959                         exMidP = over.mStr;
00960                         exMidLen = over_len;
00961 
00962                         exRightLen = src_len - (exLeftLen + length);
00963                         if (exRightLen < 0) {
00964                             exRightLen = 0;
00965                         }
00966                         exRightP = exLeftP + (src_len - exRightLen);
00967 
00968                         string expect(exLeftP, exLeftLen);
00969                         expect.append(exMidP, exMidLen);
00970                         expect.append(exRightP, exRightLen);
00971 
00972                         caught = false;
00973                         try {
00974                             newlen = SqlStrAsciiOverlay(
00975                                 dst.mStr,
00976                                 dst_storage,
00977                                 src.mStr,
00978                                 src_len,
00979                                 over.mStr,
00980                                 over_len,
00981                                 position,
00982                                 length,
00983                                 lenSpecified);
00984                         } catch (const char *str) {
00985                             caught = true;
00986                             if (!strcmp(str, "22011")) {
00987                                 BOOST_CHECK(
00988                                     position < 1
00989                                     || (lenSpecified && length < 1));
00990                             } else if (!strcmp(str, "22001")) {
00991                                 BOOST_CHECK(src_len + over_len > dst_storage);
00992                             } else {
00993                                 BOOST_CHECK(false);
00994                             }
00995                         }
00996                         if (!caught) {
00997                             BOOST_CHECK(position > 0);
00998                             if (lenSpecified) {
00999                                 BOOST_CHECK(length >= 0);
01000                             }
01001 
01002                             BOOST_CHECK(dst.verify());
01003                             BOOST_CHECK(src.verify());
01004                             BOOST_CHECK(over.verify());
01005 
01006                             string result(dst.mStr, newlen);
01007 
01008                             BOOST_CHECK(!result.compare(expect));
01009                             BOOST_CHECK(!expect.compare(result));
01010                         }
01011                     }
01012                 }
01013             }
01014         }
01015     }
01016 }
01017 
01018 void
01019 SqlStringTest::testSqlStringAsciiPos()
01020 {
01021     int src_storage, find_start, find_len, randX;
01022     int alter_char;
01023 
01024     int foundpos;
01025 
01026     for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
01027         for (randX = 0; randX < MAXRANDOM; randX++) {
01028             SqlStringTestGen src(
01029                 src_storage, src_storage,
01030                 0, 0,
01031                 's', ' ');
01032             src.randomize('a', 'a', 'z');
01033 
01034             // find all possible valid substrings
01035             for (find_start = 0; find_start <= src_storage; find_start++) {
01036                 for (find_len = 0; find_len <= src_storage - find_start;
01037                      find_len++)
01038                 {
01039                     string validsubstr(src.mStr + find_start, find_len);
01040                     SqlStringTestGen find(
01041                         find_len, find_len,
01042                         0, 0,
01043                         'X', ' ');
01044                     memcpy(find.mStr, validsubstr.c_str(), find_len);
01045 
01046                     foundpos  = SqlStrAsciiPos(
01047                         src.mStr,
01048                         src_storage,
01049                         find.mStr,
01050                         find_len);
01051                     BOOST_CHECK(src.verify());
01052                     BOOST_CHECK(find.verify());
01053 
01054                     if (find_len) {
01055                         // foundpos is 1-indexed. find_start is 0-indexed.
01056                         BOOST_CHECK_EQUAL(foundpos, find_start + 1);
01057                     } else {
01058                         BOOST_CHECK_EQUAL(
01059                             foundpos, static_cast<int>(1));  // Case A.
01060                     }
01061 
01062                     // alter valid substring to prevent match
01063                     for (alter_char = 0; alter_char < find_len; alter_char++) {
01064                         char save = *(find.mStr + alter_char);
01065                         // 'X' not between 'a' and 'z'
01066                         *(find.mStr + alter_char) = 'X';
01067 
01068                         foundpos  = SqlStrAsciiPos(
01069                             src.mStr,
01070                             src_storage,
01071                             find.mStr,
01072                             find_len);
01073                         BOOST_CHECK(src.verify());
01074                         BOOST_CHECK(find.verify());
01075 
01076                         BOOST_CHECK_EQUAL(foundpos, static_cast<int>(0));
01077 
01078                         *(find.mStr + alter_char) = save;
01079                     }
01080                 }
01081             }
01082         }
01083     }
01084 }
01085 
01086 void
01087 SqlStringTest::testSqlStringAsciiSubStr()
01088 {
01089     int src_storage, src_len, dst_storage, newlen;
01090     int sub_start, sub_len;
01091     bool caught;
01092     char const * resultP;
01093 
01094     // must test where substart and/or sublen larger than src_storage and
01095     // less than 0
01096 
01097     for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
01098         for (src_storage = 0; src_storage <= dst_storage; src_storage++) {
01099             for (src_len = 0; src_len <= src_storage; src_len++) {
01100                 for (sub_start = -3; sub_start <= 3 + src_storage;
01101                      sub_start++)
01102                 {
01103                     for (sub_len = -3; sub_len <= 3 + src_storage; sub_len++) {
01104                         SqlStringTestGen dst(
01105                             dst_storage, dst_storage,
01106                             0, 0,
01107                             'd', ' ');
01108                         SqlStringTestGen src(
01109                             src_storage, src_len,
01110                             0, src_storage - src_len,
01111                             's', ' ');
01112                         src.randomize();
01113 #if 0
01114                         BOOST_MESSAGE(
01115                             "src =|" << src.mLeftP <<
01116                             "| dest_storage=" << dst_storage <<
01117                             " src_storage=" << src_storage <<
01118                             " src_len=" << src_len <<
01119                             " sub_start=" << sub_start <<
01120                             " sub_len=" << sub_len);
01121 #endif
01122                         int exsubstart = sub_start;
01123                         int exlen = sub_len;
01124                         if (exsubstart < 1) {
01125                             // will grab fewer characters
01126                             exlen += (exsubstart - 1);
01127                         }
01128                         exsubstart--;                       // convert index
01129                         if (exsubstart < 0) {
01130                             exsubstart = 0; // clean up for std::string
01131                         }
01132                         if (exlen < 0) {
01133                             exlen = 0;           // clean up for std::string
01134                         }
01135 
01136                         if (exsubstart + exlen > src_storage) {
01137                             if (exsubstart > src_storage) {
01138                                 exlen = 0;
01139                             } else {
01140                                 exlen = src_storage - exsubstart;
01141                             }
01142                         }
01143                         if (exsubstart < 0) {
01144                             exsubstart = 0; // clean up for std::string
01145                         }
01146                         if (exlen < 0) {
01147                             exlen = 0;           // clean up for std::string
01148                         }
01149 
01150                         string expect(src.mStr + exsubstart, exlen);
01151 
01152                         caught = false;
01153                         try {
01154                             newlen = SqlStrAsciiSubStr(
01155                                 &resultP, dst_storage,
01156                                 src.mStr, src_storage,
01157                                 sub_start, sub_len, true);
01158                         } catch (const char *str) {
01159                             caught = true;
01160                             if (!strcmp(str, "22011")) {
01161                                 BOOST_CHECK(sub_len < 0);
01162                             } else if (!strcmp(str, "22001")) {
01163                                 BOOST_CHECK(sub_len > dst_storage);
01164                                 BOOST_CHECK(sub_len >= 0);
01165                             } else {
01166                                 BOOST_CHECK(false);
01167                             }
01168                         }
01169                         if (!caught) {
01170                             BOOST_CHECK(sub_len >= 0);
01171                             string result(resultP, newlen);
01172 #if 0
01173                             BOOST_MESSAGE("expect |" << expect << "|");
01174                             BOOST_MESSAGE("result |" << result << "|");
01175 #endif
01176                             BOOST_CHECK(!result.compare(expect));
01177                             BOOST_CHECK(!expect.compare(result));
01178                         }
01179                         BOOST_CHECK(dst.verify());
01180                         BOOST_CHECK(src.verify());
01181 
01182                         // length unspecified mode
01183                         // test when length is at or past the storage
01184                         if (sub_start > 0 && sub_len > 0 &&
01185                             sub_start + sub_len - 1 > src_storage) {
01186                             caught = false;
01187                             try {
01188                                 newlen = SqlStrAsciiSubStr(
01189                                     &resultP, dst_storage,
01190                                     src.mStr, src_storage,
01191                                     sub_start, 0, false);
01192                             } catch (const char *str) {
01193                                 caught = true;
01194                                 if (!strcmp(str, "22011")) {
01195                                     BOOST_CHECK(sub_len < 0);
01196                                 } else if (!strcmp(str, "22001")) {
01197                                     BOOST_CHECK(sub_len > dst_storage);
01198                                 } else {
01199                                     BOOST_CHECK(false);
01200                                 }
01201                             }
01202                             if (!caught) {
01203                                 // BOOST_MESSAGE(
01204                                 //     " len=" << sub_len
01205                                 //     << " start=" << sub_start);
01206 
01207                                 string result(resultP, newlen);
01208 #if 0
01209                                 BOOST_MESSAGE("expect |" << expect << "|");
01210                                 BOOST_MESSAGE("result |" << result << "|");
01211 #endif
01212                                 BOOST_CHECK(!result.compare(expect));
01213                                 BOOST_CHECK(!expect.compare(result));
01214                             }
01215                             BOOST_CHECK(dst.verify());
01216                             BOOST_CHECK(src.verify());
01217                         }
01218                     }
01219                 }
01220             }
01221         }
01222     }
01223 }
01224 
01225 void
01226 SqlStringTest::testSqlStringAsciiToLower()
01227 {
01228     int dest_storage, dest_len, src_storage, src_len, randX;
01229     int newlen;
01230     bool caught;
01231 
01232     for (dest_storage = 0; dest_storage < MAXLEN; dest_storage++) {
01233         dest_len = dest_storage;
01234         for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
01235             src_len = src_storage;
01236             for (randX = 0; randX < MAXRANDOM; randX++) {
01237                 SqlStringTestGen dest(
01238                     dest_storage, dest_len,
01239                     0, 0,
01240                     'd', ' ');
01241                 SqlStringTestGen src(
01242                     src_storage, src_len,
01243                     0, src_storage - src_len,
01244                     's', ' ');
01245                 src.randomize('A');
01246 
01247                 string save(src.mStr, src_len);
01248                 string::iterator itr;
01249                 char const *s;
01250                 int count;
01251 
01252                 // copy
01253                 caught = false;
01254                 try {
01255                     newlen = SqlStrAsciiToLower(
01256                         dest.mStr, dest_storage, src.mStr, src_len);
01257                 } catch (const char *str) {
01258                     caught = true;
01259                     BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
01260                     BOOST_CHECK(src_len > dest_storage);
01261                 } catch (...) {
01262                     BOOST_CHECK(false);
01263                 }
01264                 if (!caught) {
01265                     BOOST_CHECK(src_len <= dest_storage);
01266                     BOOST_CHECK(src.verify());
01267                     BOOST_CHECK(dest.verify());
01268                     BOOST_CHECK_EQUAL(newlen, src_len);
01269 
01270                     itr = save.begin();
01271                     s = dest.mStr;
01272                     count = 0;
01273                     while (itr != save.end()) {
01274                         if (*itr >= 'A' && *itr <= 'Z') {
01275                             BOOST_CHECK_EQUAL(*s, (*itr + ('a' - 'A')));
01276                         } else {
01277                             BOOST_CHECK_EQUAL(*itr, *s);
01278                         }
01279                         s++;
01280                         itr++;
01281                         count++;
01282                     }
01283                     BOOST_CHECK_EQUAL(count, src_len);
01284                 }
01285             }
01286         }
01287     }
01288 }
01289 
01290 
01291 void
01292 SqlStringTest::testSqlStringAsciiToUpper()
01293 {
01294     int dest_storage, dest_len, src_storage, src_len, randX;
01295     int newlen;
01296     bool caught;
01297 
01298 
01299     for (dest_storage = 0; dest_storage < MAXLEN; dest_storage++) {
01300         dest_len = dest_storage;
01301         for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
01302             src_len = src_storage;
01303             for (randX = 0; randX < MAXRANDOM; randX++) {
01304                 SqlStringTestGen dest(
01305                     dest_storage, dest_len,
01306                     0, 0,
01307                     'd', ' ');
01308                 SqlStringTestGen src(
01309                     src_storage, src_len,
01310                     0, src_storage - src_len,
01311                     's', ' ');
01312                 src.randomize('a');
01313 
01314                 string save(src.mStr, src_len);
01315                 string::iterator itr;
01316                 char const *s;
01317                 int count;
01318 
01319                 // copy
01320                 caught = false;
01321                 try {
01322                     newlen = SqlStrAsciiToUpper(
01323                         dest.mStr, dest_storage, src.mStr, src_len);
01324                 } catch (const char *str) {
01325                     caught = true;
01326                     BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
01327                     BOOST_CHECK(src_len > dest_storage);
01328                 } catch (...) {
01329                     BOOST_CHECK(false);
01330                 }
01331                 if (!caught) {
01332                     BOOST_CHECK(src_len <= dest_storage);
01333                     BOOST_CHECK(src.verify());
01334                     BOOST_CHECK(dest.verify());
01335                     BOOST_CHECK_EQUAL(newlen, src_len);
01336 
01337                     itr = save.begin();
01338                     s = dest.mStr;
01339                     count = 0;
01340 
01341                     while (itr != save.end()) {
01342                         if (*itr >= 'a' && *itr <= 'z') {
01343                             BOOST_CHECK_EQUAL(*s, (*itr - ('a' - 'A')));
01344                         } else {
01345                             BOOST_CHECK_EQUAL(*itr, *s);
01346                         }
01347                         s++;
01348                         itr++;
01349                         count++;
01350                     }
01351                     BOOST_CHECK_EQUAL(count, src_len);
01352                 }
01353             }
01354         }
01355     }
01356 }
01357 
01358 void
01359 SqlStringTest::testSqlStringAsciiTrim()
01360 {
01361     int dst_storage, src_storage, src_len, leftpad, rightpad, randX, i;
01362     char padchar = ' ';
01363     char textchar = 's';
01364     bool caught;
01365 
01366     BOOST_REQUIRE(MAXLEN >= 5); // 2 pad + 1 text + 2 pad
01367 
01368     for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
01369         for (src_storage = 0; src_storage < dst_storage + 5; src_storage++) {
01370             for (src_len = 0; src_len <= src_storage; src_len++) {
01371                 for (leftpad = 0; leftpad <= src_storage - src_len; leftpad++) {
01372                     rightpad = src_storage - (src_len + leftpad);
01373                     for (randX = 0; randX < MAXRANDOM; randX++) {
01374                         BOOST_REQUIRE(
01375                             leftpad + rightpad + src_len == src_storage);
01376                         for (i = 0; i < 4; i++) {
01377                             int newsize;
01378                             int expectsize;
01379                             string resultByReference;
01380                             string resultCopy;
01381                             string expect;
01382                             SqlStringTestGen src(
01383                                 src_storage, src_len,
01384                                 leftpad, rightpad,
01385                                 textchar, padchar);
01386                             SqlStringTestGen dst(
01387                                 dst_storage, dst_storage,
01388                                 0, 0,
01389                                 textchar, padchar);
01390 
01391                             int lefttrim, righttrim;
01392                             switch (i) {
01393                             case 0:
01394                                 lefttrim = true;
01395                                 righttrim = true;
01396                                 expect.append(src_len, textchar);
01397                                 expectsize = src_len;
01398                                 break;
01399                             case 1:
01400                                 lefttrim = true;
01401                                 righttrim = false;
01402                                 expect.append(src_len, textchar);
01403                                 // if no text, everything is trimmed
01404                                 if (src_len) {
01405                                     expect.append(rightpad, padchar);
01406                                 }
01407                                 expectsize = src_len + (src_len ? rightpad : 0);
01408                                 break;
01409                             case 2:
01410                                 lefttrim = false;
01411                                 righttrim = true;
01412                                 // if no text, everything is trimmed
01413                                 if (src_len) {
01414                                     expect.append(leftpad, padchar);
01415                                 }
01416                                 expect.append(src_len, textchar);
01417                                 expectsize = src_len + (src_len ? leftpad : 0);
01418                                 break;
01419                             case 3:
01420                                 lefttrim = false;
01421                                 righttrim = false;
01422                                 expect.append(leftpad, padchar);
01423                                 expect.append(src_len, textchar);
01424                                 expect.append(rightpad, padchar);
01425                                 expectsize = src_len + leftpad + rightpad;
01426                                 break;
01427                             }
01428 
01429                             // test copy implementation
01430                             caught = false;
01431                             try {
01432                                 newsize =
01433                                     SqlStrAsciiTrim(
01434                                         dst.mStr,
01435                                         dst_storage,
01436                                         src.mStr,
01437                                         src_len + leftpad + rightpad,
01438                                         lefttrim,
01439                                         righttrim);
01440                             } catch (const char *str) {
01441                                 caught = true;
01442                                 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
01443                                 BOOST_CHECK(expectsize > dst_storage);
01444                             } catch (...) {
01445                                 BOOST_CHECK(false);
01446                             }
01447 
01448                             if (!caught) {
01449                                 BOOST_CHECK(expectsize <= dst_storage);
01450 
01451                                 BOOST_CHECK(src.verify());
01452                                 BOOST_CHECK(dst.verify());
01453                                 BOOST_CHECK_EQUAL(newsize, expectsize);
01454                                 resultCopy = string(dst.mStr, newsize);
01455 
01456                                 BOOST_CHECK(!resultCopy.compare(expect));
01457                                 BOOST_CHECK(!expect.compare(resultCopy));
01458                             }
01459 
01460 
01461                             // test by reference
01462                             char const * start;
01463                             newsize = SqlStrAsciiTrim(
01464                                 &start,
01465                                 src.mStr,
01466                                 src_len + leftpad + rightpad,
01467                                 lefttrim,
01468                                 righttrim);
01469 
01470                             BOOST_CHECK(start >= src.mStr);
01471                             BOOST_CHECK(start <= src.mStr + src_storage);
01472                             BOOST_CHECK(src.verify());
01473                             BOOST_CHECK(dst.verify());
01474                             BOOST_CHECK_EQUAL(newsize, expectsize);
01475                             resultByReference = string(start, newsize);
01476 
01477                             BOOST_CHECK(!resultByReference.compare(expect));
01478                             BOOST_CHECK(!expect.compare(resultByReference));
01479                         }
01480                     }
01481                 }
01482             }
01483         }
01484     }
01485 }
01486 
01487 
01488 FENNEL_UNIT_TEST_SUITE(SqlStringTest);
01489 
01490 // End SqlStringTestAscii.cpp

Generated on Mon Jun 22 04:00:14 2009 for Fennel by  doxygen 1.5.1