00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "fennel/common/CommonPreamble.h"
00024 #include "fennel/test/TestBase.h"
00025 #include "fennel/calculator/SqlString.h"
00026 #include "fennel/common/TraceSource.h"
00027 #include "fennel/calctest/SqlStringBuffer.h"
00028
00029 #include <boost/test/test_tools.hpp>
00030 #include <boost/scoped_array.hpp>
00031 #include <string>
00032 #include <limits>
00033 #include <iostream>
00034 #include <math.h>
00035
00036 #ifdef HAVE_ICU
00037 #include <unicode/unistr.h>
00038 #include <unicode/uloc.h>
00039 #endif
00040
00041 using namespace fennel;
00042 using namespace std;
00043
00044 #ifdef COMPLETE_REGRESSION_TEST_SETTINGS
00045
00046 const int MAXLEN = 8;
00047 const int MAXRANDOM = 5;
00048 const int MAXCMPRANDOM = 65536;
00049 const int MAXCMPLEN = 8;
00050 #else
00051
00052 const int MAXLEN = 5;
00053 const int MAXRANDOM = 1;
00054 const int MAXCMPRANDOM = 256;
00055 const int MAXCMPLEN = 3;
00056 #endif
00057
00058 class SqlStringTest : virtual public TestBase, public TraceSource
00059 {
00060 void testSqlStringBuffer_Ascii();
00061 void testSqlStringBuffer_UCS2();
00062
00063 void testSqlStringCat_Fix();
00064 void testSqlStringCat_Var();
00065 void testSqlStringCat_Var2();
00066 void testSqlStringCpy_Fix();
00067 void testSqlStringCpy_Var();
00068 void testSqlStringCmp();
00069 void testSqlStringCmp_Bin();
00070 void testSqlStringLenBit();
00071 void testSqlStringLenChar();
00072 void testSqlStringLenOct();
00073 void testSqlStringOverlay();
00074 void testSqlStringPos();
00075 void testSqlStringSubStr();
00076 void testSqlStringAlterCase();
00077 void testSqlStringTrim();
00078 void testSqlStringCastToExact();
00079 void testSqlStringCastToDecimal();
00080 void testSqlStringCastToApprox();
00081 void testSqlStringCastFromExact();
00082 void testSqlStringCastFromDecimal();
00083 void testSqlStringCastFromApprox();
00084 void testSqlStringCastToVarChar();
00085 void testSqlStringCastToChar();
00086
00087 void appendCharsToUCS2LikeString(
00088 string& str,
00089 int number,
00090 char character);
00091
00092 void testSqlStringCmp_Helper(
00093 SqlStringBuffer &src1,
00094 int src1_storage,
00095 int src1_len,
00096 SqlStringBuffer &src2,
00097 int src2_storage,
00098 int src2_len);
00099
00100 void testSqlStringCmp_Bin_Helper(
00101 SqlStringBuffer &src1,
00102 int src1_storage,
00103 int src1_len,
00104 SqlStringBuffer &src2,
00105 int src2_storage,
00106 int src2_len);
00107
00108 void testSqlStringCmp_Bin_Helper2(
00109 int &lower,
00110 int &upper);
00111
00112 int testSqlStringNormalizeLexicalCmp(int v);
00113
00114 void testSqlStringAlterCase_Ascii(
00115 int dst_storage,
00116 int src_len,
00117 SqlStringBuffer& dest,
00118 SqlStringBuffer& src,
00119 const string& expect,
00120 SqlStrAlterCaseAction action);
00121
00122 void testSqlStringAlterCase_UCS2(
00123 int dst_storage,
00124 int src_len,
00125 SqlStringBufferUCS2& destU2,
00126 SqlStringBufferUCS2& srcU2,
00127 const string& expect,
00128 SqlStrAlterCaseAction action);
00129
00130 void testSqlStringAlterCase_Case(
00131 SqlStrAlterCaseAction action,
00132 int dst_storage,
00133 int dest_len,
00134 int src_storage,
00135 int src_len);
00136
00137 void testSqlStringTrim_Helper(
00138 int dst_storage,
00139 int src_storage,
00140 int src_len,
00141 int leftpad,
00142 int rightpad,
00143 int action);
00144
00145 void testSqlStringCastToExact_Helper(
00146 uint64_t value,
00147 char const * const buf,
00148 int src_storage,
00149 int src_len,
00150 bool exceptionExpected);
00151
00152 void testSqlStringCastToDecimal_Helper(
00153 uint64_t value,
00154 int precision,
00155 int scale,
00156 char const * const buf,
00157 int src_storage,
00158 int src_len,
00159 bool outOfRangeExpected,
00160 bool invalidCharExpected);
00161
00162 void testSqlStringCastToApprox_Helper(
00163 double value,
00164 char const * const buf,
00165 int src_storage,
00166 int src_len,
00167 bool exceptionExpected);
00168 #ifdef HAVE_ICU
00169 string UnicodeToPrintable(const UnicodeString &s);
00170 #endif
00171
00172
00173 public:
00174 explicit SqlStringTest()
00175 : TraceSource(shared_from_this(),"SqlStringTest")
00176 {
00177 srand(time(NULL));
00178 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringBuffer_Ascii);
00179 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringBuffer_UCS2);
00180 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCat_Fix);
00181 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCat_Var2);
00182 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCat_Var);
00183 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCpy_Fix);
00184 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCpy_Var);
00185 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCmp);
00186 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCmp_Bin);
00187 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringLenBit);
00188 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringLenChar);
00189 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringLenOct);
00190 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringOverlay);
00191 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringPos);
00192 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringSubStr);
00193 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringAlterCase);
00194 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringTrim);
00195 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCastToExact);
00196 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCastToDecimal);
00197 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCastToApprox);
00198 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCastFromExact);
00199 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCastFromDecimal);
00200 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCastFromApprox);
00201 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCastToVarChar);
00202 FENNEL_UNIT_TEST_CASE(SqlStringTest, testSqlStringCastToChar);
00203 }
00204
00205 virtual ~SqlStringTest()
00206 {
00207 }
00208 };
00209
00210 #ifdef HAVE_ICU
00211
00212 string
00213 SqlStringTest::UnicodeToPrintable(const UnicodeString &s) {
00214 ostringstream o;
00215 int32_t i, length;
00216 char tmp;
00217
00218
00219 length = s.length();
00220 for (i = 0; i < length; ++i) {
00221 tmp = s.charAt(i) & 0xff;
00222 o << i << "=" << tmp << " | ";
00223 }
00224 return o.str();
00225 }
00226 #endif
00227
00228
00229
00230 void
00231 SqlStringTest::appendCharsToUCS2LikeString(
00232 string& str,
00233 int number,
00234 char character)
00235 {
00236 int i;
00237 for (i = 0; i < number; i++) {
00238 #ifdef LITTLEENDIAN
00239 str.push_back(character);
00240 str.push_back(0);
00241 #else
00242 str.push_back(0);
00243 str.push_back(character);
00244 #endif
00245 }
00246 }
00247
00248
00249 void
00250 SqlStringTest::testSqlStringBuffer_Ascii()
00251 {
00252 int storage, size, leftpad, rightpad;
00253 int leftbump = 2;
00254 int rightbump = 2;
00255 int k;
00256
00257 for (storage = 0; storage <= 5; storage++) {
00258 for (size = 0; size <= storage; size++) {
00259 for (leftpad = 0; leftpad <= storage - size; leftpad++) {
00260 rightpad = (storage - size) - leftpad;
00261
00262 SqlStringBuffer t(
00263 storage, size,
00264 leftpad, rightpad,
00265 'x', ' ',
00266 leftbump, rightbump);
00267
00268 BOOST_CHECK_EQUAL(t.mStorage, storage);
00269 BOOST_CHECK_EQUAL(t.mSize, size);
00270 BOOST_CHECK_EQUAL(t.mLeftPad, leftpad);
00271 BOOST_CHECK_EQUAL(t.mRightPad, rightpad);
00272 BOOST_CHECK_EQUAL(
00273 static_cast<int>(t.mS.size()),
00274 storage + leftbump + rightbump);
00275
00276 BOOST_CHECK(t.verify());
00277
00278 char *p = t.mLeftP;
00279
00280 for (k = 0; k < leftbump; k++) {
00281 BOOST_CHECK_EQUAL(*(p++), SqlStringBuffer::mBumperChar);
00282 }
00283 BOOST_CHECK(p == t.mStr);
00284
00285 for (k = 0; k < leftpad; k++) {
00286 BOOST_CHECK_EQUAL(*(p++), ' ');
00287 }
00288
00289 for (k = 0; k < size; k++) {
00290 BOOST_CHECK_EQUAL(*(p++), 'x');
00291 }
00292
00293 for (k = 0; k < rightpad; k++) {
00294 BOOST_CHECK_EQUAL(*(p++), ' ');
00295 }
00296 BOOST_CHECK(p == t.mRightP);
00297
00298 for (k = 0; k < rightbump; k++) {
00299 BOOST_CHECK_EQUAL(*(p++), SqlStringBuffer::mBumperChar);
00300 }
00301 BOOST_CHECK_EQUAL(
00302 static_cast<int>(p - t.mLeftP),
00303 storage + leftbump + rightbump);
00304
00305 BOOST_CHECK(t.verify());
00306
00307 for (k = 0; k < size; k++) {
00308 *(t.mStr + k) = '0' + (k % 10);
00309 }
00310 BOOST_CHECK(t.verify());
00311
00312 *(t.mLeftP) = 'X';
00313 BOOST_CHECK(!t.verify());
00314 *(t.mLeftP) = SqlStringBuffer::mBumperChar;
00315 BOOST_CHECK(t.verify());
00316
00317 *(t.mStr - 1) = 'X';
00318 BOOST_CHECK(!t.verify());
00319 *(t.mStr - 1) = SqlStringBuffer::mBumperChar;
00320 BOOST_CHECK(t.verify());
00321
00322 *(t.mRightP) = 'X';
00323 BOOST_CHECK(!t.verify());
00324 *(t.mRightP) = SqlStringBuffer::mBumperChar;
00325 BOOST_CHECK(t.verify());
00326
00327 *(t.mRightP + t.mRightBump - 1) = 'X';
00328 BOOST_CHECK(!t.verify());
00329 *(t.mRightP + t.mRightBump - 1) = SqlStringBuffer::mBumperChar;
00330 BOOST_CHECK(t.verify());
00331
00332 t.randomize();
00333 BOOST_CHECK(t.verify());
00334 }
00335 }
00336 }
00337 }
00338
00339 void
00340 SqlStringTest::testSqlStringBuffer_UCS2()
00341 {
00342 int storage, size, leftpad, rightpad;
00343 int leftbump = 2;
00344 int rightbump = 2;
00345 int k;
00346
00347 int textChar = 'x';
00348 int spaceChar = ' ';
00349 char textChar1, textChar2, spaceChar1, spaceChar2;
00350 #ifdef LITTLEENDIAN
00351 textChar2 = (textChar >> 8) & 0xff;
00352 textChar1 = textChar & 0xff;
00353 spaceChar2 = (spaceChar >> 8) & 0xff;
00354 spaceChar1 = spaceChar & 0xff;
00355 #elif BIGENDIAN
00356 textChar1 = (textChar >> 8) & 0xff;
00357 textChar2 = textChar & 0xff;
00358 spaceChar1 = (spaceChar >> 8) & 0xff;
00359 spaceChar2 = spaceChar & 0xff;
00360 #else
00361 #error "unknown endian"
00362 #endif
00363
00364 for (storage = 0; storage <= 5; storage++) {
00365 for (size = 0; size <= storage; size++) {
00366 for (leftpad = 0; leftpad <= storage - size; leftpad++) {
00367 rightpad = (storage - size) - leftpad;
00368
00369 SqlStringBuffer a(
00370 storage, size,
00371 leftpad, rightpad,
00372 textChar, spaceChar,
00373 leftbump, rightbump);
00374 SqlStringBufferUCS2 b(a);
00375
00376 BOOST_CHECK_EQUAL(b.mStorage, storage * 2);
00377 BOOST_CHECK_EQUAL(b.mSize, size * 2);
00378 BOOST_CHECK_EQUAL(b.mLeftPad, leftpad * 2);
00379 BOOST_CHECK_EQUAL(b.mRightPad, rightpad * 2);
00380 BOOST_CHECK_EQUAL(
00381 static_cast<int>(b.mS.size()),
00382 (storage*2)+leftbump+rightbump);
00383
00384 BOOST_CHECK(a.verify());
00385 BOOST_CHECK(b.verify());
00386
00387 char *p = b.mLeftP;
00388
00389 for (k = 0; k < leftbump; k++) {
00390 BOOST_CHECK_EQUAL(*(p++), SqlStringBuffer::mBumperChar);
00391 }
00392 BOOST_CHECK(p == b.mStr);
00393
00394 for (k = 0; k < leftpad; k++) {
00395 BOOST_CHECK_EQUAL(*(p++), spaceChar1);
00396 BOOST_CHECK_EQUAL(*(p++), spaceChar2);
00397 }
00398
00399 for (k = 0; k < size; k++) {
00400 BOOST_CHECK_EQUAL(*(p++), textChar1);
00401 BOOST_CHECK_EQUAL(*(p++), textChar2);
00402 }
00403
00404 for (k = 0; k < rightpad; k++) {
00405 BOOST_CHECK_EQUAL(*(p++), spaceChar1);
00406 BOOST_CHECK_EQUAL(*(p++), spaceChar2);
00407 }
00408 BOOST_CHECK(p == b.mRightP);
00409
00410 for (k = 0; k < rightbump; k++) {
00411 BOOST_CHECK_EQUAL(*(p++), SqlStringBuffer::mBumperChar);
00412 }
00413 BOOST_CHECK_EQUAL(
00414 static_cast<int>(p - b.mLeftP),
00415 storage*2+leftbump+rightbump);
00416
00417 BOOST_CHECK(b.verify());
00418
00419 p = b.mStr;
00420 for (k = 0; k < size; k++) {
00421 *(p++) = 0x00;
00422 *(p++) = '0' + (k % 10);
00423 }
00424 BOOST_CHECK(b.verify());
00425
00426 b.randomize();
00427 BOOST_CHECK(b.verify());
00428 }
00429 }
00430 }
00431 }
00432
00433
00434 void
00435 SqlStringTest::testSqlStringCat_Fix()
00436 {
00437 int src1_storage, src2_storage, src3_storage, dst_storage;
00438 int src1_len, src2_len, src3_len;
00439 bool caught;
00440 int newlen;
00441
00442 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00443 for (src1_storage = 0; src1_storage < MAXLEN; src1_storage++) {
00444 for (src1_len = 0; src1_len <= src1_storage; src1_len++) {
00445 for (src2_storage = 0; src2_storage < MAXLEN; src2_storage++) {
00446 for (src2_len = 0; src2_len <= src2_storage; src2_len++) {
00447 for (src3_storage = 0; src3_storage < MAXLEN;
00448 src3_storage++)
00449 {
00450 for (src3_len = 0; src3_len <= src3_storage;
00451 src3_len++)
00452 {
00453 SqlStringBuffer dst(
00454 dst_storage, 0,
00455 0, dst_storage,
00456 'd', ' ');
00457 SqlStringBuffer src1(
00458 src1_storage, src1_len,
00459 0, src1_storage - src1_len,
00460 '1', ' ');
00461 SqlStringBuffer src2(
00462 src2_storage, src2_len,
00463 0, src2_storage - src2_len,
00464 '2', ' ');
00465 SqlStringBuffer src3(
00466 src3_storage, src3_len,
00467 0, src3_storage - src3_len,
00468 '3', ' ');
00469
00470 caught = false;
00471 try {
00472 newlen = SqlStrCat(
00473 dst.mStr, dst_storage,
00474 src1.mStr, src1_storage,
00475 src2.mStr, src2_storage);
00476 } catch (const char *str) {
00477 caught = true;
00478 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00479 BOOST_CHECK(
00480 src1_storage + src2_storage
00481 > dst_storage);
00482 BOOST_CHECK(dst.verify());
00483 BOOST_CHECK(src1.verify());
00484 BOOST_CHECK(src2.verify());
00485 } catch (...) {
00486
00487 BOOST_CHECK(false);
00488 }
00489 if (!caught) {
00490 BOOST_CHECK(
00491 src1_storage + src2_storage
00492 <= dst_storage);
00493 BOOST_CHECK(dst.verify());
00494 BOOST_CHECK(src1.verify());
00495 BOOST_CHECK(src2.verify());
00496
00497 caught = false;
00498 try {
00499 newlen = SqlStrCat(
00500 dst.mStr,
00501 dst_storage,
00502 newlen,
00503 src3.mStr,
00504 src3_storage);
00505 } catch (const char *str) {
00506 caught = true;
00507 BOOST_CHECK_EQUAL(
00508 strcmp(str, "22001"), 0);
00509 BOOST_CHECK(
00510 (src1_storage +
00511 src2_storage +
00512 src3_storage)
00513 > dst_storage);
00514 BOOST_CHECK(dst.verify());
00515 BOOST_CHECK(src1.verify());
00516 BOOST_CHECK(src2.verify());
00517 BOOST_CHECK(src3.verify());
00518 } catch (...) {
00519
00520 BOOST_CHECK(false);
00521 }
00522 if (!caught) {
00523 BOOST_CHECK(dst.verify());
00524 BOOST_CHECK(src1.verify());
00525 BOOST_CHECK(src2.verify());
00526 BOOST_CHECK(src3.verify());
00527 BOOST_CHECK_EQUAL(
00528 newlen,
00529 (src1_storage +
00530 src2_storage +
00531 src3_storage));
00532
00533 string result(dst.mStr, newlen);
00534 string expect(src1.mStr, src1_storage);
00535 expect.append(src2.mStr, src2_storage);
00536 expect.append(src3.mStr, src3_storage);
00537
00538 BOOST_CHECK(!result.compare(expect));
00539 }
00540 }
00541 }
00542 }
00543 }
00544 }
00545 }
00546 }
00547 }
00548
00549 }
00550
00551
00552 void
00553 SqlStringTest::testSqlStringCat_Var2()
00554 {
00555 int src1_storage, src2_storage, dst_storage, src1_len, src2_len;
00556 int newlen;
00557 bool caught;
00558
00559 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00560 for (src1_storage = 0; src1_storage < MAXLEN; src1_storage++) {
00561 for (src1_len = 0; src1_len <= src1_storage; src1_len++) {
00562 for (src2_storage = 0; src2_storage < MAXLEN; src2_storage++) {
00563 for (src2_len = 0; src2_len <= src2_storage; src2_len++) {
00564 SqlStringBuffer dst(
00565 dst_storage, 0,
00566 0, dst_storage,
00567 'd', ' ');
00568 SqlStringBuffer src1(
00569 src1_storage, src1_len,
00570 0, src1_storage - src1_len,
00571 's', ' ');
00572 SqlStringBuffer src2(
00573 src2_storage, src2_len,
00574 0, src2_storage - src2_len,
00575 'S', ' ');
00576
00577 caught = false;
00578 try {
00579 newlen = SqlStrCat(
00580 dst.mStr,
00581 dst_storage,
00582 src1.mStr,
00583 src1_len,
00584 src2.mStr,
00585 src2_len);
00586 } catch (const char *str) {
00587 caught = true;
00588 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00589 BOOST_CHECK(src1_len + src2_len > dst_storage);
00590 } catch (...) {
00591
00592 BOOST_CHECK(false);
00593 }
00594 if (!caught) {
00595 BOOST_CHECK(src1_len + src2_len <= dst_storage);
00596 BOOST_CHECK_EQUAL(newlen, src1_len + src2_len);
00597
00598 string expect;
00599 expect.append(src1_len, 's');
00600 expect.append(src2_len, 'S');
00601
00602 string result(dst.mStr, newlen);
00603
00604 BOOST_CHECK(!result.compare(expect));
00605 BOOST_CHECK(!expect.compare(result));
00606 }
00607 BOOST_CHECK(dst.verify());
00608 BOOST_CHECK(src1.verify());
00609 BOOST_CHECK(src2.verify());
00610 }
00611 }
00612 }
00613 }
00614 }
00615 }
00616
00617
00618 void
00619 SqlStringTest::testSqlStringCat_Var()
00620 {
00621 int src_storage, dst_storage, src_len, dst_len;
00622 int newlen;
00623 bool caught;
00624
00625 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00626 for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
00627 for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
00628 for (src_len = 0; src_len <= src_storage; src_len++) {
00629 SqlStringBuffer dst(
00630 dst_storage, dst_len,
00631 0, dst_storage - dst_len,
00632 'd', ' ');
00633 SqlStringBuffer src(
00634 src_storage, src_len,
00635 0, src_storage - src_len,
00636 's', ' ');
00637 caught = false;
00638 try {
00639 newlen = SqlStrCat(
00640 dst.mStr,
00641 dst_storage,
00642 dst_len,
00643 src.mStr,
00644 src_len);
00645 } catch (const char *str) {
00646 caught = true;
00647 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00648 BOOST_CHECK(src_len + dst_len > dst_storage);
00649 } catch (...) {
00650
00651 BOOST_CHECK(false);
00652 }
00653 if (!caught) {
00654 BOOST_CHECK(src_len + dst_len <= dst_storage);
00655 BOOST_CHECK_EQUAL(newlen, src_len + dst_len);
00656
00657 string expect;
00658 expect.append(dst_len, 'd');
00659 expect.append(src_len, 's');
00660
00661 string result(dst.mStr, newlen);
00662
00663 BOOST_CHECK(!result.compare(expect));
00664 BOOST_CHECK(!expect.compare(result));
00665 }
00666 BOOST_CHECK(dst.verify());
00667 BOOST_CHECK(src.verify());
00668 }
00669 }
00670 }
00671 }
00672 }
00673 void
00674 SqlStringTest::testSqlStringCpy_Fix()
00675 {
00676 int src_storage, dst_storage, src_len, dst_len;
00677 bool caught;
00678
00679 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00680 for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
00681 for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
00682 for (src_len = 0; src_len <= src_storage; src_len++) {
00683
00684 SqlStringBuffer dst(
00685 dst_storage, dst_len,
00686 0, dst_storage - dst_len,
00687 'd', ' ');
00688 SqlStringBuffer src(
00689 src_storage, src_len,
00690 0, src_storage - src_len,
00691 's', ' ');
00692 caught = false;
00693 try {
00694 SqlStrCpy_Fix<1, 1>(
00695 dst.mStr,
00696 dst_storage,
00697 src.mStr,
00698 src_len);
00699 } catch (const char *str) {
00700 caught = true;
00701 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00702 BOOST_CHECK(src_len > dst_storage);
00703 } catch (...) {
00704
00705 BOOST_CHECK(false);
00706 }
00707 if (!caught) {
00708 BOOST_CHECK(src_len <= dst_storage);
00709 string expect;
00710 expect.append(src_len, 's');
00711 expect.append(dst_storage - src_len, ' ');
00712
00713
00714 string result(dst.mStr, dst_storage);
00715 #if 0
00716 BOOST_MESSAGE(" dst_storage=" << dst_storage <<
00717 " dst_len=" << dst_len <<
00718 " src_storage=" << src_storage <<
00719 " src_len=" << src_len);
00720 BOOST_MESSAGE("src =|" << src.mLeftP << "|");
00721 BOOST_MESSAGE("expect |" << expect << "|");
00722 BOOST_MESSAGE("result |" << result << "|");
00723 #endif
00724 BOOST_CHECK(!result.compare(expect));
00725 }
00726 BOOST_CHECK(dst.verify());
00727 BOOST_CHECK(src.verify());
00728
00729
00730 SqlStringBufferUCS2 srcU2(src);
00731 SqlStringBufferUCS2 dstU2(dst);
00732
00733 caught = false;
00734 try {
00735 SqlStrCpy_Fix<2,1>(
00736 dstU2.mStr,
00737 dstU2.mStorage,
00738 srcU2.mStr,
00739 srcU2.mSize);
00740 } catch (const char *str) {
00741 caught = true;
00742 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00743 BOOST_CHECK(srcU2.mSize > dstU2.mStorage);
00744 } catch (...) {
00745
00746 BOOST_CHECK(false);
00747 }
00748 if (!caught) {
00749 BOOST_CHECK(srcU2.mSize <= dstU2.mStorage);
00750 string expect;
00751 BOOST_REQUIRE(!(srcU2.mSize & 1));
00752 BOOST_REQUIRE(!(dstU2.mStorage & 1));
00753 appendCharsToUCS2LikeString(
00754 expect,
00755 srcU2.mSize >> 1,
00756 's');
00757 appendCharsToUCS2LikeString(
00758 expect,
00759 (dstU2.mStorage -
00760 srcU2.mSize) >> 1,
00761 ' ');
00762 string result(dstU2.mStr, dstU2.mStorage);
00763 #if 0
00764 BOOST_MESSAGE(" dstU2.mStorage=" << dstU2.mStorage <<
00765 " dstU2.mSize=" << dstU2.mSize <<
00766 " srcU2.mStorage=" << srcU2.mStorage <<
00767 " srcU2.mSize=" << srcU2.mSize);
00768 BOOST_MESSAGE("srcU2 =|" << srcU2.mLeftP << "|");
00769 BOOST_MESSAGE("expectU2 |" << expect << "|");
00770 BOOST_MESSAGE("resultU2 |" << result << "|");
00771 #endif
00772 BOOST_CHECK(!result.compare(expect));
00773 }
00774 BOOST_CHECK(dstU2.verify());
00775 BOOST_CHECK(srcU2.verify());
00776 }
00777 }
00778 }
00779 }
00780 }
00781
00782 void
00783 SqlStringTest::testSqlStringCpy_Var()
00784 {
00785 int src_storage, dst_storage, src_len, dst_len;
00786 int newlen;
00787 bool caught;
00788
00789 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
00790 for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
00791 for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
00792 for (src_len = 0; src_len <= src_storage; src_len++) {
00793
00794 SqlStringBuffer dst(
00795 dst_storage, dst_len,
00796 0, dst_storage - dst_len,
00797 'd', ' ');
00798 SqlStringBuffer src(
00799 src_storage, src_len,
00800 0, src_storage - src_len,
00801 's', ' ');
00802 caught = false;
00803 try {
00804 newlen = SqlStrCpy_Var(
00805 dst.mStr,
00806 dst_storage,
00807 src.mStr,
00808 src_len);
00809 } catch (const char *str) {
00810 caught = true;
00811 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00812 BOOST_CHECK(src_len > dst_storage);
00813 } catch (...) {
00814
00815 BOOST_CHECK(false);
00816 }
00817 if (!caught) {
00818 BOOST_CHECK(src_len <= dst_storage);
00819 BOOST_CHECK_EQUAL(newlen, src_len);
00820
00821 string expect;
00822 expect.append(src_len, 's');
00823
00824 string result(dst.mStr, newlen);
00825
00826 BOOST_CHECK(!result.compare(expect));
00827 BOOST_CHECK(!expect.compare(result));
00828 }
00829 BOOST_CHECK(dst.verify());
00830 BOOST_CHECK(src.verify());
00831
00832
00833 SqlStringBufferUCS2 srcU2(src);
00834 SqlStringBufferUCS2 dstU2(dst);
00835 caught = false;
00836 try {
00837 newlen = SqlStrCpy_Var(
00838 dstU2.mStr,
00839 dstU2.mStorage,
00840 srcU2.mStr,
00841 srcU2.mSize);
00842 } catch (const char *str) {
00843 caught = true;
00844 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
00845 BOOST_CHECK(srcU2.mSize > dstU2.mStorage);
00846 } catch (...) {
00847
00848 BOOST_CHECK(false);
00849 }
00850 if (!caught) {
00851 BOOST_CHECK(srcU2.mSize <= dstU2.mStorage);
00852 BOOST_CHECK_EQUAL(newlen, srcU2.mSize);
00853
00854 string expect;
00855 appendCharsToUCS2LikeString(
00856 expect,
00857 src_len,
00858 's');
00859 string result(dstU2.mStr, newlen);
00860
00861 BOOST_CHECK(!result.compare(expect));
00862 BOOST_CHECK(!expect.compare(result));
00863 }
00864 BOOST_CHECK(dstU2.verify());
00865 BOOST_CHECK(srcU2.verify());
00866 }
00867 }
00868 }
00869 }
00870 }
00871
00872
00873 int
00874 SqlStringTest::testSqlStringNormalizeLexicalCmp(int v)
00875 {
00876 if (v < 0) {
00877 return -1;
00878 }
00879 if (v > 0) {
00880 return 1;
00881 }
00882 return 0;
00883 }
00884
00885 void
00886 SqlStringTest::testSqlStringCmp_Helper(
00887 SqlStringBuffer &src1,
00888 int src1_storage,
00889 int src1_len,
00890 SqlStringBuffer &src2,
00891 int src2_storage,
00892 int src2_len)
00893 {
00894 int result, resultflip;
00895
00896 string s1(src1.mStr, src1_len);
00897 string s2(src2.mStr, src2_len);
00898 string s1F(src1.mStr, src1_storage);
00899 string s2F(src2.mStr, src2_storage);
00900
00901
00902 s1.erase(s1.find_last_not_of(" ") + 1);
00903 s2.erase(s2.find_last_not_of(" ") + 1);
00904
00905 int expected = testSqlStringNormalizeLexicalCmp(s1.compare(s2));
00906 char const * const s1p = s1.c_str();
00907 char const * const s2p = s2.c_str();
00908 int expected2 = testSqlStringNormalizeLexicalCmp(strcmp(s1p, s2p));
00909 BOOST_CHECK_EQUAL(expected, expected2);
00910
00911 #if 0
00912 BOOST_MESSAGE("src1=|" << s1 << "|" <<
00913 " src2=|" << s2 << "|" <<
00914 " src1F=|" << s1F << "|" <<
00915 " src2F=|" << s2F << "|" <<
00916 " expect=" << expected <<
00917 " expect2=" << expected2);
00918 #endif
00919
00920
00921 result = SqlStrCmp<1,1>(
00922 src1.mStr, src1_storage,
00923 src2.mStr, src2_storage);
00924 BOOST_CHECK(src1.verify());
00925 BOOST_CHECK(src2.verify());
00926 BOOST_CHECK_EQUAL(result, expected);
00927
00928
00929 resultflip = SqlStrCmp<1,1>(
00930 src2.mStr, src2_storage,
00931 src1.mStr, src1_storage);
00932 BOOST_CHECK(src1.verify());
00933 BOOST_CHECK(src2.verify());
00934 BOOST_CHECK_EQUAL(resultflip * -1, result);
00935
00936
00937 result = SqlStrCmp<1,1>(
00938 src1.mStr, src1_len,
00939 src2.mStr, src2_len);
00940 BOOST_CHECK(src1.verify());
00941 BOOST_CHECK(src2.verify());
00942 BOOST_CHECK_EQUAL(result, expected);
00943
00944
00945 resultflip = SqlStrCmp<1,1>(
00946 src2.mStr, src2_len,
00947 src1.mStr, src1_len);
00948 BOOST_CHECK(src1.verify());
00949 BOOST_CHECK(src2.verify());
00950 BOOST_CHECK_EQUAL(resultflip * -1, result);
00951
00952
00953 result = SqlStrCmp<1,1>(
00954 src1.mStr, src1_len,
00955 src2.mStr, src2_storage);
00956 BOOST_CHECK(src1.verify());
00957 BOOST_CHECK(src2.verify());
00958 BOOST_CHECK_EQUAL(result, expected);
00959
00960
00961 resultflip = SqlStrCmp<1,1>(
00962 src2.mStr, src2_storage,
00963 src1.mStr, src1_len);
00964 BOOST_CHECK(src1.verify());
00965 BOOST_CHECK(src2.verify());
00966 BOOST_CHECK_EQUAL(resultflip * -1, result);
00967
00968
00969 result = SqlStrCmp<1,1>(
00970 src1.mStr, src1_storage,
00971 src2.mStr, src2_len);
00972 BOOST_CHECK(src1.verify());
00973 BOOST_CHECK(src2.verify());
00974 BOOST_CHECK_EQUAL(result, expected);
00975
00976
00977 resultflip = SqlStrCmp<1,1>(
00978 src2.mStr, src2_len,
00979 src1.mStr, src1_storage);
00980 BOOST_CHECK(src1.verify());
00981 BOOST_CHECK(src2.verify());
00982 BOOST_CHECK_EQUAL(resultflip * -1, result);
00983
00984
00985
00986 result = SqlStrCmp<1,1>(
00987 src1.mStr, src1_storage,
00988 src1.mStr, src1_storage);
00989 BOOST_CHECK(src1.verify());
00990 BOOST_CHECK_EQUAL(result, 0);
00991
00992 result = SqlStrCmp<1,1>(
00993 src1.mStr, src1_len,
00994 src1.mStr, src1_len);
00995 BOOST_CHECK(src1.verify());
00996 BOOST_CHECK_EQUAL(result, 0);
00997
00998 result = SqlStrCmp<1,1>(
00999 src1.mStr, src1_storage,
01000 src1.mStr, src1_len);
01001 BOOST_CHECK(src1.verify());
01002 BOOST_CHECK_EQUAL(result, 0);
01003
01004 result = SqlStrCmp<1,1>(
01005 src1.mStr, src1_len,
01006 src1.mStr, src1_storage);
01007 BOOST_CHECK(src1.verify());
01008 BOOST_CHECK_EQUAL(result, 0);
01009
01010 result = SqlStrCmp<1,1>(
01011 src2.mStr, src2_storage,
01012 src2.mStr, src2_storage);
01013 BOOST_CHECK(src2.verify());
01014 BOOST_CHECK_EQUAL(result, 0);
01015
01016 result = SqlStrCmp<1,1>(
01017 src2.mStr, src2_len,
01018 src2.mStr, src2_len);
01019 BOOST_CHECK(src2.verify());
01020 BOOST_CHECK_EQUAL(result, 0);
01021 }
01022
01023
01024 void
01025 SqlStringTest::testSqlStringCmp()
01026 {
01027 int src1_storage, src2_storage, src1_len, src2_len;
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 int startc = ' ' + 1;
01042 int range = 255 - startc;
01043
01044 for (src1_storage = 0; src1_storage <= MAXLEN; src1_storage++) {
01045 for (src1_len = 0; src1_len < src1_storage; src1_len++) {
01046 for (src2_storage = 0; src2_storage <= MAXLEN; src2_storage++) {
01047 for (src2_len = 0; src2_len < src2_storage; src2_len++) {
01048 for (int startchar1 = startc; startchar1 < 255;
01049 startchar1 += 30)
01050 {
01051 for (int startchar2 = startc; startchar2 < 255;
01052 startchar2 += 30)
01053 {
01054 SqlStringBuffer src1(
01055 src1_storage, src1_len,
01056 0, src1_storage - src1_len,
01057 'd', ' ');
01058 SqlStringBuffer src2(
01059 src2_storage, src2_len,
01060 0, src2_storage - src2_len,
01061 's', ' ');
01062
01063 src1.patternfill(startchar1, startc, 255);
01064 src2.patternfill(startchar2, startc, 255);
01065
01066 testSqlStringCmp_Helper(
01067 src1, src1_storage,
01068 src1_len,
01069 src2, src2_storage,
01070 src2_len);
01071 }
01072 }
01073 }
01074
01075
01076 for (int randX = 0; randX < 5; randX++) {
01077 SqlStringBuffer src1(
01078 src1_storage, src1_len,
01079 0, src1_storage - src1_len,
01080 'd', ' ');
01081 SqlStringBuffer src2(
01082 src2_storage, src2_len,
01083 0, src2_storage - src2_len,
01084 's', ' ');
01085
01086 src1.randomize(startc + (rand() % range), startc, 255);
01087 src2.randomize(startc + (rand() % range), startc, 255);
01088
01089 testSqlStringCmp_Helper(
01090 src1, src1_storage, src1_len,
01091 src2, src2_storage, src2_len);
01092 }
01093 }
01094 }
01095 }
01096 }
01097
01098
01099 void
01100 SqlStringTest::testSqlStringCmp_Bin_Helper(
01101 SqlStringBuffer &src1,
01102 int src1_storage,
01103 int src1_len,
01104 SqlStringBuffer &src2,
01105 int src2_storage,
01106 int src2_len)
01107 {
01108 int result;
01109 string s1(src1.mStr, src1_len);
01110 string s2(src2.mStr, src2_len);
01111 #if 0
01112 BOOST_MESSAGE("src1=|" << s1 << "| " << src1_len << " " << src1_storage <<
01113 " src2=|" << s2 << "| " << src2_len << " " << src2_storage);
01114 #endif
01115
01116 int expected = testSqlStringNormalizeLexicalCmp(s1.compare(s2));
01117
01118
01119 result = SqlStrCmp_Bin(
01120 src1.mStr, src1_len,
01121 src2.mStr, src2_len);
01122 BOOST_CHECK(src1.verify());
01123 BOOST_CHECK(src2.verify());
01124 BOOST_CHECK_EQUAL(expected, result);
01125
01126
01127 result = SqlStrCmp_Bin(
01128 src2.mStr, src2_len,
01129 src1.mStr, src1_len);
01130 BOOST_CHECK(src1.verify());
01131 BOOST_CHECK(src2.verify());
01132 BOOST_CHECK_EQUAL(expected * -1, result);
01133
01134
01135 result = SqlStrCmp_Bin(
01136 src1.mStr, src1_len,
01137 src1.mStr, src1_len);
01138 BOOST_CHECK(src1.verify());
01139 BOOST_CHECK_EQUAL(0, result);
01140
01141
01142 result = SqlStrCmp_Bin(
01143 src2.mStr, src2_len,
01144 src2.mStr, src2_len);
01145 BOOST_CHECK(src2.verify());
01146 BOOST_CHECK_EQUAL(0, result);
01147 }
01148
01149
01150 void
01151 SqlStringTest::testSqlStringCmp_Bin_Helper2(int &lower, int &upper)
01152 {
01153 lower = (rand() % 254) + 1;
01154 upper = lower + (rand() % (255 - lower));
01155 assert(lower > 0 && lower < 256);
01156 assert(upper > 0 && upper < 256);
01157 assert(lower <= upper);
01158 }
01159
01160 void
01161 SqlStringTest::testSqlStringCmp_Bin()
01162 {
01163
01164
01165
01166
01167 int src1_storage, src2_storage, src1_len, src2_len;
01168
01169 for (src1_storage = 0; src1_storage <= MAXCMPLEN; src1_storage++) {
01170 src1_len = src1_storage;
01171 for (src2_storage = 0; src2_storage <= MAXCMPLEN; src2_storage++) {
01172 src2_len = src2_storage;
01173 SqlStringBuffer src1(
01174 src1_storage, src1_len,
01175 0, src1_storage - src1_len,
01176 'd', ' ');
01177 SqlStringBuffer src2(
01178 src2_storage, src2_len,
01179 0, src2_storage - src2_len,
01180 's', ' ');
01181 testSqlStringCmp_Bin_Helper(
01182 src1, src1_storage, src1_len,
01183 src2, src2_storage, src2_len);
01184
01185 if (src1_len == 0 || src2_len == 0) {
01186 continue;
01187 }
01188 int lower, upper;
01189 int maxcmp = MAXCMPRANDOM >> 2;
01190 if (maxcmp < 16) {
01191 maxcmp = 16;
01192 }
01193 for (int randX = 0; randX < maxcmp; randX++) {
01194 testSqlStringCmp_Bin_Helper2(lower, upper);
01195 src1.randomize(lower, lower, upper);
01196
01197 int count = 100;
01198 do {
01199 testSqlStringCmp_Bin_Helper2(lower, upper);
01200 src2.randomize(lower, lower, upper);
01201 } while (src1_len > 0 && count-- > 0 &&
01202 !memcmp(src1.mStr, src2.mStr, src1_len));
01203 if (count < 1) {
01204
01205 BOOST_MESSAGE("giving up on impossible random string gen");
01206 break;
01207 }
01208 testSqlStringCmp_Bin_Helper(
01209 src1, src1_storage, src1_len,
01210 src2, src2_storage, src2_len);
01211 }
01212 }
01213 }
01214 }
01215
01216 void
01217 SqlStringTest::testSqlStringLenBit()
01218 {
01219 int src_storage, src_len;
01220 int newlen;
01221
01222 src_storage = MAXLEN;
01223 for (src_storage = 0; src_storage <= MAXLEN; src_storage++) {
01224 for (src_len = 0; src_len <= src_storage; src_len++) {
01225 SqlStringBuffer src(
01226 src_storage, src_len,
01227 0, src_storage - src_len,
01228 's', ' ');
01229
01230
01231 newlen = SqlStrLenBit(src_len);
01232 BOOST_CHECK_EQUAL(newlen, src_len * 8);
01233 BOOST_CHECK(src.verify());
01234
01235
01236 newlen = SqlStrLenBit(src_storage);
01237 BOOST_CHECK_EQUAL(newlen, src_storage * 8);
01238 BOOST_CHECK(src.verify());
01239
01240 SqlStringBufferUCS2 srcU2(src);
01241
01242
01243 newlen = SqlStrLenBit(srcU2.mSize);
01244 BOOST_CHECK_EQUAL(newlen, srcU2.mSize * 8);
01245 BOOST_CHECK(src.verify());
01246
01247
01248 newlen = SqlStrLenBit(srcU2.mStorage);
01249 BOOST_CHECK_EQUAL(newlen, srcU2.mStorage * 8);
01250 BOOST_CHECK(src.verify());
01251 }
01252 }
01253 }
01254
01255 void
01256 SqlStringTest::testSqlStringLenChar()
01257 {
01258 int src_storage, src_len;
01259 int newlen;
01260
01261 src_storage = MAXLEN;
01262 for (src_storage = 0; src_storage <= MAXLEN; src_storage++) {
01263 for (src_len = 0; src_len <= src_storage; src_len++) {
01264 SqlStringBuffer src(
01265 src_storage, src_len,
01266 0, src_storage - src_len,
01267 's', ' ');
01268
01269
01270 newlen = SqlStrLenChar<1, 1>(
01271 src.mStr,
01272 src_len);
01273 BOOST_CHECK_EQUAL(newlen, src_len);
01274 BOOST_CHECK(src.verify());
01275
01276
01277 newlen = SqlStrLenChar<1, 1>(
01278 src.mStr,
01279 src_storage);
01280 BOOST_CHECK_EQUAL(newlen, src_storage);
01281 BOOST_CHECK(src.verify());
01282
01283 SqlStringBufferUCS2 srcU2(src);
01284
01285
01286 newlen = SqlStrLenChar<2,1>(
01287 srcU2.mStr,
01288 srcU2.mSize);
01289
01290 BOOST_CHECK_EQUAL(newlen, src_len);
01291 BOOST_CHECK(src.verify());
01292
01293
01294 newlen = SqlStrLenChar<2,1>(
01295 srcU2.mStr,
01296 srcU2.mStorage);
01297
01298 BOOST_CHECK_EQUAL(newlen, src_storage);
01299 BOOST_CHECK(src.verify());
01300 }
01301 }
01302 }
01303
01304
01305 void
01306 SqlStringTest::testSqlStringLenOct()
01307 {
01308 int src_storage, src_len;
01309 int newlen;
01310
01311 src_storage = MAXLEN;
01312 for (src_storage = 0; src_storage <= MAXLEN; src_storage++) {
01313 for (src_len = 0; src_len <= src_storage; src_len++) {
01314 SqlStringBuffer src(
01315 src_storage, src_len,
01316 0, src_storage - src_len,
01317 's', ' ');
01318
01319
01320 newlen = SqlStrLenOct(src_len);
01321 BOOST_CHECK_EQUAL(newlen, src_len);
01322 BOOST_CHECK(src.verify());
01323
01324
01325 newlen = SqlStrLenOct(src_storage);
01326 BOOST_CHECK_EQUAL(newlen, src_storage);
01327 BOOST_CHECK(src.verify());
01328
01329 SqlStringBufferUCS2 srcU2(src);
01330
01331
01332 newlen = SqlStrLenOct(srcU2.mSize);
01333 BOOST_CHECK_EQUAL(newlen, srcU2.mSize);
01334 BOOST_CHECK(srcU2.verify());
01335
01336
01337 newlen = SqlStrLenOct(srcU2.mStorage);
01338 BOOST_CHECK_EQUAL(newlen, srcU2.mStorage);
01339 BOOST_CHECK(srcU2.verify());
01340 }
01341 }
01342 }
01343
01344
01345 void
01346 SqlStringTest::testSqlStringOverlay()
01347 {
01348 int dst_storage, src_storage, src_len, over_storage, over_len;
01349 int position, length, lengthI;
01350 int exLeftLen, exMidLen, exRightLen;
01351 char *exLeftP, *exMidP, *exRightP;
01352 bool lenSpecified;
01353 bool caught = false;
01354 int newlen = 0;
01355
01356 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
01357 for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
01358 src_len = src_storage;
01359 for (over_storage = 0; over_storage < MAXLEN; over_storage++) {
01360 over_len = over_storage;
01361 for (position = 0; position < MAXLEN; position++) {
01362 for (lengthI = -1; lengthI < MAXLEN; lengthI++) {
01363 if (lengthI == -1) {
01364 lenSpecified = false;
01365 length = over_len;
01366 } else {
01367 lenSpecified = true;
01368 length = lengthI;
01369 }
01370 #if 0
01371 BOOST_MESSAGE(
01372 " dst_storage=" << dst_storage <<
01373 " src_storage=" << src_storage <<
01374 " over_storage=" << over_storage <<
01375 " pos=" << position <<
01376 " length=" << length <<
01377 " spec=" << lenSpecified);
01378 #endif
01379 SqlStringBuffer dst(
01380 dst_storage, dst_storage,
01381 0, 0,
01382 'd', ' ');
01383 SqlStringBuffer src(
01384 src_storage, src_len,
01385 0, src_storage - src_len,
01386 's', ' ');
01387 SqlStringBuffer over(
01388 over_storage, over_len,
01389 0, over_storage - over_len,
01390 'o', ' ');
01391
01392 src.patternfill('a', 'a', 'z');
01393 over.patternfill('A', 'A', 'Z');
01394
01395
01396 exLeftP = src.mStr;
01397 if (position >= 1 && src_len >= 1) {
01398 exLeftLen = position - 1;
01399 if (exLeftLen > src_len) {
01400 exLeftLen = src_len;
01401 }
01402 } else {
01403 exLeftLen = 0;
01404 }
01405
01406 exMidP = over.mStr;
01407 exMidLen = over_len;
01408
01409 exRightLen = src_len - (exLeftLen + length);
01410 if (exRightLen < 0) {
01411 exRightLen = 0;
01412 }
01413 exRightP = exLeftP + (src_len - exRightLen);
01414
01415 string expect(exLeftP, exLeftLen);
01416 expect.append(exMidP, exMidLen);
01417 expect.append(exRightP, exRightLen);
01418
01419 caught = false;
01420 try {
01421 newlen = SqlStrOverlay<1,1>(
01422 dst.mStr,
01423 dst_storage,
01424 src.mStr,
01425 src_len,
01426 over.mStr,
01427 over_len,
01428 position,
01429 length,
01430 lenSpecified);
01431 } catch (const char *str) {
01432 caught = true;
01433 if (!strcmp(str, "22011")) {
01434 BOOST_CHECK(
01435 position < 1
01436 || (lenSpecified && length < 1));
01437 } else if (!strcmp(str, "22001")) {
01438 BOOST_CHECK(src_len + over_len > dst_storage);
01439 } else {
01440 BOOST_CHECK(false);
01441 }
01442 }
01443 if (!caught) {
01444 BOOST_CHECK(position > 0);
01445 if (lenSpecified) {
01446 BOOST_CHECK(length >= 0);
01447 }
01448
01449 BOOST_CHECK(dst.verify());
01450 BOOST_CHECK(src.verify());
01451 BOOST_CHECK(over.verify());
01452
01453 string result(dst.mStr, newlen);
01454
01455 BOOST_CHECK(!result.compare(expect));
01456 BOOST_CHECK(!expect.compare(result));
01457 }
01458 }
01459 }
01460 }
01461 }
01462 }
01463 }
01464
01465 void
01466 SqlStringTest::testSqlStringPos()
01467 {
01468 int src_storage, find_start, find_len, randX;
01469 int alter_char;
01470
01471 int foundpos;
01472
01473 for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
01474 for (randX = 0; randX < MAXRANDOM; randX++) {
01475 SqlStringBuffer src(
01476 src_storage, src_storage,
01477 0, 0,
01478 's', ' ');
01479 src.randomize('a', 'a', 'z');
01480
01481
01482 for (find_start = 0; find_start <= src_storage; find_start++) {
01483 for (find_len = 0; find_len <= src_storage - find_start;
01484 find_len++)
01485 {
01486 string validsubstr(src.mStr + find_start, find_len);
01487 SqlStringBuffer find(
01488 find_len, find_len,
01489 0, 0,
01490 'X', ' ');
01491 memcpy(find.mStr, validsubstr.c_str(), find_len);
01492
01493 foundpos = SqlStrPos<1,1>(
01494 src.mStr,
01495 src_storage,
01496 find.mStr,
01497 find_len);
01498 BOOST_CHECK(src.verify());
01499 BOOST_CHECK(find.verify());
01500
01501 if (find_len) {
01502
01503 BOOST_CHECK_EQUAL(foundpos, find_start + 1);
01504 } else {
01505 BOOST_CHECK_EQUAL(
01506 foundpos, static_cast<int>(1));
01507 }
01508
01509
01510 for (alter_char = 0; alter_char < find_len; alter_char++) {
01511 char save = *(find.mStr + alter_char);
01512
01513 *(find.mStr + alter_char) = 'X';
01514
01515 foundpos = SqlStrPos<1,1>(
01516 src.mStr,
01517 src_storage,
01518 find.mStr,
01519 find_len);
01520 BOOST_CHECK(src.verify());
01521 BOOST_CHECK(find.verify());
01522
01523 BOOST_CHECK_EQUAL(foundpos, static_cast<int>(0));
01524
01525 *(find.mStr + alter_char) = save;
01526 }
01527 }
01528 }
01529 }
01530 }
01531 }
01532
01533 void
01534 SqlStringTest::testSqlStringSubStr()
01535 {
01536 int src_storage, src_len, dst_storage, newlen = 0;
01537 int sub_start, sub_len;
01538 bool caught;
01539 char const * resultP;
01540
01541
01542
01543
01544 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
01545 for (src_storage = 0; src_storage <= dst_storage; src_storage++) {
01546 for (src_len = 0; src_len <= src_storage; src_len++) {
01547 for (sub_start = -3; sub_start <= 3 + src_storage;
01548 sub_start++)
01549 {
01550 for (sub_len = -3; sub_len <= 3 + src_storage; sub_len++) {
01551 SqlStringBuffer dst(
01552 dst_storage, dst_storage,
01553 0, 0,
01554 'd', ' ');
01555 SqlStringBuffer src(
01556 src_storage, src_len,
01557 0, src_storage - src_len,
01558 's', ' ');
01559 src.randomize();
01560 #if 0
01561 BOOST_MESSAGE("src =|" << src.mLeftP <<
01562 "| dst_storage=" << dst_storage <<
01563 " src_storage=" << src_storage <<
01564 " src_len=" << src_len <<
01565 " sub_start=" << sub_start <<
01566 " sub_len=" << sub_len);
01567 #endif
01568 int exsubstart = sub_start;
01569 int exlen = sub_len;
01570 if (exsubstart < 1) {
01571
01572 exlen += (exsubstart - 1);
01573 }
01574 exsubstart--;
01575 if (exsubstart < 0) {
01576 exsubstart = 0;
01577 }
01578 if (exlen < 0) {
01579 exlen = 0;
01580 }
01581
01582 if (exsubstart + exlen > src_storage) {
01583 if (exsubstart > src_storage) {
01584 exlen = 0;
01585 } else {
01586 exlen = src_storage - exsubstart;
01587 }
01588 }
01589 if (exsubstart < 0) {
01590 exsubstart = 0;
01591 }
01592 if (exlen < 0) {
01593 exlen = 0;
01594 }
01595
01596 string expect(src.mStr + exsubstart, exlen);
01597
01598 caught = false;
01599 try {
01600 newlen = SqlStrSubStr<1,1>(
01601 &resultP, dst_storage,
01602 src.mStr, src_storage,
01603 sub_start, sub_len, true);
01604 } catch (const char *str) {
01605 caught = true;
01606 if (!strcmp(str, "22011")) {
01607 BOOST_CHECK(sub_len < 0);
01608 } else if (!strcmp(str, "22001")) {
01609 BOOST_CHECK(sub_len > dst_storage);
01610 BOOST_CHECK(sub_len >= 0);
01611 } else {
01612 BOOST_CHECK(false);
01613 }
01614 }
01615 if (!caught) {
01616 BOOST_CHECK(sub_len >= 0);
01617 string result(resultP, newlen);
01618 #if 0
01619 BOOST_MESSAGE("expect |" << expect << "|");
01620 BOOST_MESSAGE("result |" << result << "|");
01621 #endif
01622 BOOST_CHECK(!result.compare(expect));
01623 BOOST_CHECK(!expect.compare(result));
01624 }
01625 BOOST_CHECK(dst.verify());
01626 BOOST_CHECK(src.verify());
01627
01628
01629
01630 if (sub_start > 0 && sub_len > 0 &&
01631 sub_start + sub_len - 1 > src_storage) {
01632 caught = false;
01633 try {
01634 newlen = SqlStrSubStr<1,1>(
01635 &resultP, dst_storage,
01636 src.mStr, src_storage,
01637 sub_start, 0, false);
01638 } catch (const char *str) {
01639 caught = true;
01640 if (!strcmp(str, "22011")) {
01641 BOOST_CHECK(sub_len < 0);
01642 } else if (!strcmp(str, "22001")) {
01643 BOOST_CHECK(sub_len > dst_storage);
01644 } else {
01645 BOOST_CHECK(false);
01646 }
01647 }
01648 if (!caught) {
01649
01650
01651
01652
01653 string result(resultP, newlen);
01654 #if 0
01655 BOOST_MESSAGE("expect |" << expect << "|");
01656 BOOST_MESSAGE("result |" << result << "|");
01657 #endif
01658 BOOST_CHECK(!result.compare(expect));
01659 BOOST_CHECK(!expect.compare(result));
01660 }
01661 BOOST_CHECK(dst.verify());
01662 BOOST_CHECK(src.verify());
01663 }
01664 }
01665 }
01666 }
01667 }
01668 }
01669 }
01670
01671
01672 void
01673 SqlStringTest::testSqlStringAlterCase_Ascii(
01674 int dst_storage,
01675 int src_len,
01676 SqlStringBuffer& dest,
01677 SqlStringBuffer& src,
01678 const string& expect,
01679 SqlStrAlterCaseAction action)
01680 {
01681 int newlen = 0;
01682 bool caught = false;
01683
01684 try {
01685 switch (action) {
01686 case AlterCaseUpper:
01687 newlen = SqlStrAlterCase<1,1,AlterCaseUpper>(
01688 dest.mStr,
01689 dest.mStorage,
01690 src.mStr,
01691 src.mSize);
01692 break;
01693 case AlterCaseLower:
01694 newlen = SqlStrAlterCase<1,1,AlterCaseLower>(
01695 dest.mStr,
01696 dest.mStorage,
01697 src.mStr,
01698 src.mSize);
01699 break;
01700 default:
01701 BOOST_REQUIRE(0);
01702 break;
01703 }
01704 } catch (const char *str) {
01705 caught = true;
01706 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
01707 BOOST_CHECK(src_len > dst_storage);
01708 } catch (...) {
01709
01710 BOOST_CHECK(false);
01711 }
01712 if (!caught) {
01713 BOOST_CHECK(src_len <= dst_storage);
01714 BOOST_CHECK(src.verify());
01715 BOOST_CHECK(dest.verify());
01716 BOOST_CHECK_EQUAL(newlen, src_len);
01717
01718 string result(dest.mStr, newlen);
01719 #if 0
01720 BOOST_MESSAGE(" action=" << action <<
01721 " newlen="<< newlen <<
01722 " result=|" << result << "|" <<
01723 " expect=|" << expect << "|");
01724 #endif
01725 BOOST_CHECK(!expect.compare(result));
01726 }
01727 }
01728
01729
01730 void
01731 SqlStringTest::testSqlStringAlterCase_UCS2(
01732 int dst_storage,
01733 int src_len,
01734 SqlStringBufferUCS2& destU2,
01735 SqlStringBufferUCS2& srcU2,
01736 const string& expect,
01737 SqlStrAlterCaseAction action)
01738 {
01739 #ifdef HAVE_ICU
01740 UnicodeString expectU2(expect.c_str(), "iso-8859-1");
01741 BOOST_REQUIRE(!expectU2.isBogus());
01742
01743 BOOST_CHECK(srcU2.verify());
01744 BOOST_CHECK(destU2.verify());
01745
01746 BOOST_REQUIRE(srcU2.mSize == src_len * 2);
01747 BOOST_REQUIRE(destU2.mStorage == dst_storage * 2);
01748
01749 int newlen;
01750 bool caught = false;
01751 try {
01752 switch (action) {
01753 case AlterCaseUpper:
01754 newlen = SqlStrAlterCase<2,1,AlterCaseUpper>(
01755 destU2.mStr,
01756 destU2.mStorage,
01757 srcU2.mStr,
01758 srcU2.mSize,
01759 ULOC_US);
01760 break;
01761 case AlterCaseLower:
01762 newlen = SqlStrAlterCase<2,1,AlterCaseLower>(
01763 destU2.mStr,
01764 destU2.mStorage,
01765 srcU2.mStr,
01766 srcU2.mSize,
01767 ULOC_US);
01768 break;
01769 default:
01770 BOOST_REQUIRE(0);
01771 break;
01772 }
01773 } catch (const char *str) {
01774 caught = true;
01775 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
01776 BOOST_CHECK(src_len > dst_storage);
01777 } catch (...) {
01778
01779 BOOST_CHECK(false);
01780 }
01781 if (!caught) {
01782 BOOST_CHECK(src_len <= dst_storage);
01783 BOOST_CHECK(srcU2.verify());
01784 BOOST_CHECK(destU2.verify());
01785 BOOST_CHECK_EQUAL(newlen, srcU2.mSize);
01786
01787 UnicodeString resultU2(
01788 reinterpret_cast<UChar *>(destU2.mStr),
01789 newlen >> 1);
01790
01791 BOOST_REQUIRE(!resultU2.isBogus());
01792 #if 0
01793 BOOST_MESSAGE("newlen=" << newlen);
01794 BOOST_MESSAGE("srcU2= |" << srcU2.dump());
01795 BOOST_MESSAGE("destU2= |" << destU2.dump());
01796 BOOST_MESSAGE("expect=|" << UnicodeToPrintable(expectU2) << "|");
01797 BOOST_MESSAGE("result=|" << UnicodeToPrintable(resultU2) << "|");
01798 #endif
01799 BOOST_CHECK(!expectU2.compare(resultU2));
01800 }
01801 #endif
01802 }
01803
01804
01805 void
01806 SqlStringTest::testSqlStringAlterCase_Case(
01807 SqlStrAlterCaseAction action,
01808 int dst_storage,
01809 int dest_len,
01810 int src_storage,
01811 int src_len)
01812 {
01813 BOOST_REQUIRE(action == AlterCaseUpper || action == AlterCaseLower);
01814
01815 SqlStringBuffer dest(
01816 dst_storage, dest_len,
01817 0, 0,
01818 'd', ' ');
01819 SqlStringBuffer src(
01820 src_storage, src_len,
01821 0, src_storage - src_len,
01822 's', ' ');
01823 string expect;
01824
01825 switch (action) {
01826 case AlterCaseUpper:
01827 src.randomize('a');
01828 expect.assign(src.mStr, src_len);
01829 std::transform(
01830 expect.begin(), expect.end(),
01831 expect.begin(), (int(*)(int)) std::toupper);
01832 break;
01833 case AlterCaseLower:
01834 src.randomize('A');
01835 expect.assign(src.mStr, src_len);
01836 std::transform(
01837 expect.begin(), expect.end(),
01838 expect.begin(), (int(*)(int)) std::tolower);
01839 break;
01840 default:
01841 BOOST_REQUIRE(0);
01842 break;
01843 }
01844
01845
01846 testSqlStringAlterCase_Ascii(
01847 dst_storage, src_len,
01848 dest,
01849 src,
01850 expect,
01851 action);
01852
01853
01854
01855
01856 SqlStringBufferUCS2 srcU2LongAligned(src, 4, 4);
01857 SqlStringBufferUCS2 destU2LongAligned(dest, 4, 4);
01858
01859 testSqlStringAlterCase_UCS2(
01860 dst_storage,
01861 src_len,
01862 destU2LongAligned,
01863 srcU2LongAligned,
01864 expect,
01865 action);
01866
01867
01868 SqlStringBufferUCS2 srcU2ShortAligned(src);
01869 SqlStringBufferUCS2 destU2ShortAligned(dest);
01870
01871 testSqlStringAlterCase_UCS2(
01872 dst_storage,
01873 src_len,
01874 destU2ShortAligned,
01875 srcU2ShortAligned,
01876 expect,
01877 action);
01878
01879 }
01880
01881
01882 void
01883 SqlStringTest::testSqlStringAlterCase()
01884 {
01885 int dst_storage, dest_len, src_storage, src_len, randX;
01886
01887 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
01888 dest_len = dst_storage;
01889 for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
01890 src_len = src_storage;
01891 for (randX = 0; randX < MAXRANDOM; randX++) {
01892 testSqlStringAlterCase_Case(
01893 AlterCaseUpper,
01894 dst_storage,
01895 dest_len,
01896 src_storage,
01897 src_len);
01898 testSqlStringAlterCase_Case(
01899 AlterCaseLower,
01900 dst_storage,
01901 dest_len,
01902 src_storage,
01903 src_len);
01904 }
01905 }
01906 }
01907 }
01908
01909 void
01910 SqlStringTest::testSqlStringTrim_Helper(
01911 int dst_storage,
01912 int src_storage,
01913 int src_len,
01914 int leftpad,
01915 int rightpad,
01916 int action)
01917 {
01918 int expectsize, expectsizeU2;
01919 string expect, expectU2;
01920 int lefttrim = 0, righttrim = 0;
01921 char padchar = ' ';
01922 char textchar = 's';
01923 bool caught;
01924
01925 switch (action) {
01926 case 0:
01927 lefttrim = 1;
01928 righttrim = 1;
01929 expect.append(src_len, textchar);
01930 expectsize = src_len;
01931 appendCharsToUCS2LikeString(
01932 expectU2,
01933 src_len,
01934 textchar);
01935 break;
01936 case 1:
01937 lefttrim = 1;
01938 righttrim = 0;
01939 expect.append(src_len, textchar);
01940 appendCharsToUCS2LikeString(
01941 expectU2,
01942 src_len,
01943 textchar);
01944
01945 if (src_len) {
01946 expect.append(rightpad, padchar);
01947 appendCharsToUCS2LikeString(
01948 expectU2,
01949 rightpad,
01950 padchar);
01951 }
01952 expectsize = src_len + (src_len ? rightpad : 0);
01953 break;
01954 case 2:
01955 lefttrim = 0;
01956 righttrim = 1;
01957
01958 if (src_len) {
01959 expect.append(leftpad, padchar);
01960 appendCharsToUCS2LikeString(
01961 expectU2,
01962 leftpad,
01963 padchar);
01964 }
01965 expect.append(src_len, textchar);
01966 appendCharsToUCS2LikeString(
01967 expectU2,
01968 src_len,
01969 textchar);
01970 expectsize = src_len + (src_len ? leftpad : 0);
01971 break;
01972 case 3:
01973 lefttrim = 0;
01974 righttrim = 0;
01975 expect.append(leftpad, padchar);
01976 expect.append(src_len, textchar);
01977 expect.append(rightpad, padchar);
01978 appendCharsToUCS2LikeString(
01979 expectU2,
01980 leftpad,
01981 padchar);
01982 appendCharsToUCS2LikeString(
01983 expectU2,
01984 src_len,
01985 textchar);
01986 appendCharsToUCS2LikeString(
01987 expectU2,
01988 rightpad,
01989 padchar);
01990 expectsize = src_len + leftpad + rightpad;
01991 break;
01992 }
01993 expectsizeU2 = expectsize * 2;
01994 BOOST_REQUIRE(expect.length() == expectsize);
01995 BOOST_REQUIRE(expectU2.length() == expectsizeU2);
01996
01997 string resultByReference;
01998 string resultCopy;
01999 int newsize;
02000 SqlStringBuffer src(
02001 src_storage, src_len,
02002 leftpad, rightpad,
02003 textchar, padchar);
02004 SqlStringBuffer dst(
02005 dst_storage, dst_storage,
02006 0, 0,
02007 textchar, padchar);
02008
02009
02010 caught = false;
02011 try {
02012 newsize =
02013 SqlStrTrim<1,1>(
02014 dst.mStr,
02015 dst_storage,
02016 src.mStr,
02017 src_len + leftpad + rightpad,
02018 lefttrim,
02019 righttrim);
02020 } catch (const char *str) {
02021 caught = true;
02022 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
02023 BOOST_CHECK(expectsize > dst_storage);
02024 } catch (...) {
02025
02026 BOOST_CHECK(false);
02027 }
02028
02029 if (!caught) {
02030 BOOST_CHECK(expectsize <= dst_storage);
02031
02032 BOOST_CHECK(src.verify());
02033 BOOST_CHECK(dst.verify());
02034 BOOST_CHECK_EQUAL(newsize, expectsize);
02035 resultCopy = string(dst.mStr, newsize);
02036
02037 BOOST_CHECK(!resultCopy.compare(expect));
02038 }
02039
02040
02041 SqlStringBufferUCS2 srcU2(src);
02042 SqlStringBufferUCS2 dstU2(dst);
02043 caught = false;
02044 try {
02045 newsize =
02046 SqlStrTrim<2,1>(
02047 dstU2.mStr,
02048 dstU2.mStorage,
02049 srcU2.mStr,
02050 (srcU2.mSize +
02051 srcU2.mLeftPad +
02052 srcU2.mRightPad),
02053 lefttrim,
02054 righttrim);
02055 } catch (const char *str) {
02056 caught = true;
02057 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
02058 BOOST_CHECK(expectsize > dst_storage);
02059 } catch (...) {
02060
02061 BOOST_CHECK(false);
02062 }
02063
02064 if (!caught) {
02065 BOOST_CHECK(expectsize <= dst_storage);
02066
02067 BOOST_CHECK(srcU2.verify());
02068 BOOST_CHECK(dstU2.verify());
02069 BOOST_CHECK_EQUAL(newsize, expectsizeU2);
02070 resultCopy = string(dstU2.mStr, newsize);
02071
02072 BOOST_CHECK(!resultCopy.compare(expectU2));
02073 }
02074
02075
02076
02077
02078 char const * start;
02079 newsize = SqlStrTrim<1,1>(
02080 &start,
02081 src.mStr,
02082 src_len + leftpad + rightpad,
02083 lefttrim,
02084 righttrim);
02085
02086 BOOST_CHECK(start >= src.mStr);
02087 BOOST_CHECK(start <= src.mStr + src_storage);
02088 BOOST_CHECK(src.verify());
02089 BOOST_CHECK(dst.verify());
02090 BOOST_CHECK_EQUAL(newsize, expectsize);
02091 resultByReference = string(start, newsize);
02092
02093 BOOST_CHECK(!resultByReference.compare(expect));
02094 BOOST_CHECK(!expect.compare(resultByReference));
02095
02096
02097 newsize = SqlStrTrim<2,1>(
02098 &start,
02099 srcU2.mStr,
02100 (srcU2.mSize +
02101 srcU2.mLeftPad +
02102 srcU2.mRightPad),
02103 lefttrim,
02104 righttrim);
02105
02106 BOOST_CHECK(start >= srcU2.mStr);
02107 BOOST_CHECK(start <= srcU2.mStr + srcU2.mStorage);
02108 BOOST_CHECK(srcU2.verify());
02109 BOOST_CHECK(dstU2.verify());
02110 BOOST_CHECK_EQUAL(newsize, expectsizeU2);
02111 resultByReference = string(start, newsize);
02112
02113 BOOST_CHECK(!resultByReference.compare(expectU2));
02114 }
02115
02116
02117 void
02118 SqlStringTest::testSqlStringTrim()
02119 {
02120 int dst_storage, src_storage, src_len, leftpad, rightpad, randX, action;
02121
02122 BOOST_REQUIRE(MAXLEN >= 5);
02123
02124 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
02125 for (src_storage = 0; src_storage < dst_storage + 5; src_storage++) {
02126 for (src_len = 0; src_len <= src_storage; src_len++) {
02127 for (leftpad = 0; leftpad <= src_storage - src_len; leftpad++) {
02128 rightpad = src_storage - (src_len + leftpad);
02129 for (randX = 0; randX < MAXRANDOM; randX++) {
02130 BOOST_REQUIRE(
02131 leftpad + rightpad + src_len
02132 == src_storage);
02133 for (action = 0; action < 4; action++) {
02134 testSqlStringTrim_Helper(
02135 dst_storage,
02136 src_storage,
02137 src_len,
02138 leftpad,
02139 rightpad,
02140 action);
02141 }
02142 }
02143 }
02144 }
02145 }
02146 }
02147 }
02148
02149 void
02150 SqlStringTest::testSqlStringCastToExact_Helper(
02151 uint64_t value,
02152 char const * const buf,
02153 int src_storage,
02154 int src_len,
02155 bool exceptionExpected)
02156 {
02157 bool caught = false;
02158 int64_t newvalue = 0;
02159 SqlStringBuffer src(
02160 src_storage, src_len,
02161 0, src_storage - src_len,
02162 's', ' ');
02163
02164 #if 0
02165 BOOST_MESSAGE("buf = |" << buf << "|");
02166 #endif
02167 if (strlen(buf) > src_len) {
02168
02169 return;
02170 }
02171
02172
02173 memcpy(src.mStr, buf, strlen(buf));
02174
02175
02176 memset(src.mStr + strlen(buf), ' ', src_len - strlen(buf));
02177 #if 0
02178 BOOST_MESSAGE("str = |" << src.mLeftP << "|");
02179 #endif
02180
02181 try {
02182 newvalue = SqlStrCastToExact<1,1>(
02183 src.mStr,
02184 src_len);
02185 } catch (const char *str) {
02186 caught = true;
02187 BOOST_CHECK_EQUAL(strcmp(str, "22018"), 0);
02188 }
02189 BOOST_CHECK_EQUAL(caught, exceptionExpected);
02190 if (!caught) {
02191 BOOST_CHECK_EQUAL(value, newvalue);
02192 BOOST_CHECK(src.verify());
02193 }
02194 }
02195
02196
02197 void
02198 SqlStringTest::testSqlStringCastToExact()
02199 {
02200 int src_storage, src_len;
02201 int rand_idx;
02202 int64_t power, poweridx;
02203 int64_t value, valuer1, valuer2, valuer3;
02204 char buf[256];
02205
02206 src_storage = MAXLEN;
02207
02208 for (src_storage = 1; src_storage <= 20; src_storage++) {
02209 for (src_len = 1; src_len <= src_storage; src_len++) {
02210 power = 1;
02211 for (poweridx = 0; poweridx < src_len; poweridx++) {
02212 power *= 10;
02213 }
02214
02215
02216
02217 for (rand_idx = 0; rand_idx < 5 * MAXRANDOM; rand_idx++) {
02218
02219 valuer1 = rand();
02220 valuer2 = rand();
02221 valuer3 = rand();
02222 value = (valuer1 * valuer2 * valuer3) % power;
02223
02224 if (value < 0) {
02225 value *= -1;
02226 }
02227 if (src_len > 1 && rand() % 2) {
02228
02229
02230
02231 value /= -10;
02232 }
02233
02234
02235 #if 0
02236 BOOST_MESSAGE("src_storage = " << src_storage);
02237 BOOST_MESSAGE("src_len = " << src_len);
02238 BOOST_MESSAGE("power = " << power);
02239 BOOST_MESSAGE("value = " << value);
02240 #endif
02241
02242
02243 sprintf(buf, "%" FMT_INT64, value);
02244 BOOST_REQUIRE(strlen(buf) <= src_len);
02245 testSqlStringCastToExact_Helper(
02246 value,
02247 buf,
02248 src_storage,
02249 src_len,
02250 false);
02251
02252
02253 if (src_len >= 2 && value >= 0) {
02254 sprintf(buf, "+%" FMT_INT64, value / 10);
02255 BOOST_REQUIRE(strlen(buf) <= src_len);
02256 testSqlStringCastToExact_Helper(
02257 value / 10,
02258 buf,
02259 src_storage,
02260 src_len,
02261 false);
02262 }
02263
02264
02265
02266 sprintf(buf, "%5" FMT_INT64, value);
02267 testSqlStringCastToExact_Helper(
02268 value,
02269 buf,
02270 src_storage,
02271 src_len,
02272 false);
02273
02274
02275 sprintf(buf, "%20" FMT_INT64, value);
02276 testSqlStringCastToExact_Helper(
02277 value,
02278 buf,
02279 src_storage,
02280 src_len,
02281 false);
02282
02283
02284 sprintf(buf, "%020" FMT_INT64, value);
02285 testSqlStringCastToExact_Helper(
02286 value,
02287 buf,
02288 src_storage,
02289 src_len,
02290 false);
02291
02292
02293 sprintf(buf, "%07" FMT_INT64, value);
02294 testSqlStringCastToExact_Helper(
02295 value,
02296 buf,
02297 src_storage,
02298 src_len,
02299 false);
02300
02301
02302 sprintf(buf, "%" FMT_INT64, value);
02303 buf[0] = 'a';
02304 testSqlStringCastToExact_Helper(
02305 value,
02306 buf,
02307 src_storage,
02308 src_len,
02309 true);
02310
02311
02312 if (src_len > 2) {
02313 sprintf(buf, "%" FMT_INT64, value);
02314 buf[1] = 'a';
02315 testSqlStringCastToExact_Helper(
02316 value,
02317 buf,
02318 src_storage,
02319 src_len,
02320 true);
02321 }
02322
02323
02324 if (src_len > 3 && value >= 100) {
02325 sprintf(buf, "%" FMT_INT64, value);
02326 buf[1] = ' ';
02327 testSqlStringCastToExact_Helper(
02328 value,
02329 buf,
02330 src_storage,
02331 src_len,
02332 true);
02333 }
02334
02335
02336 memset(buf, ' ', src_len);
02337 testSqlStringCastToExact_Helper(
02338 value,
02339 buf,
02340 src_storage,
02341 src_len,
02342 true);
02343
02344
02345 if (src_len > 3) {
02346 sprintf(buf, "%" FMT_INT64, value);
02347 buf[0] = '-';
02348 buf[1] = ' ';
02349 testSqlStringCastToExact_Helper(
02350 value,
02351 buf,
02352 src_storage,
02353 src_len,
02354 true);
02355 }
02356
02357
02358 if (src_len > 3) {
02359 sprintf(buf, "%" FMT_INT64, value);
02360 buf[0] = '-';
02361 buf[1] = ' ';
02362 testSqlStringCastToExact_Helper(
02363 value,
02364 buf,
02365 src_storage,
02366 src_len,
02367 true);
02368 }
02369
02370
02371 memset(buf, ' ', src_len);
02372 buf[0] = '-';
02373 testSqlStringCastToExact_Helper(
02374 value,
02375 buf,
02376 src_storage,
02377 src_len,
02378 true);
02379
02380 memset(buf, ' ', src_len);
02381 buf[0] = '+';
02382 testSqlStringCastToExact_Helper(
02383 value,
02384 buf,
02385 src_storage,
02386 src_len,
02387 true);
02388 }
02389 }
02390 }
02391 }
02392
02393 void
02394 SqlStringTest::testSqlStringCastToDecimal_Helper(
02395 uint64_t value,
02396 int precision,
02397 int scale,
02398 char const * const buf,
02399 int src_storage,
02400 int src_len,
02401 bool outOfRangeExpected,
02402 bool invalidCharExpected)
02403 {
02404 bool caught = false;
02405 int64_t newvalue = 0;
02406 SqlStringBuffer src(
02407 src_storage, src_len,
02408 0, src_storage - src_len,
02409 's', ' ');
02410
02411 #if 0
02412 BOOST_MESSAGE("buf = |" << buf << "|");
02413 #endif
02414
02415 if (strlen(buf) > src_len) {
02416
02417 return;
02418 }
02419
02420
02421 memcpy(src.mStr, buf, strlen(buf));
02422
02423
02424 memset(src.mStr + strlen(buf), ' ', src_len - strlen(buf));
02425 #if 0
02426 BOOST_MESSAGE("str = |" << src.mLeftP << "|");
02427 #endif
02428
02429 try {
02430 newvalue = SqlStrCastToExact<1,1>(
02431 src.mStr,
02432 src_len,
02433 precision,
02434 scale);
02435 } catch (const char *str) {
02436 caught = true;
02437 if (outOfRangeExpected) {
02438 BOOST_CHECK_EQUAL(strcmp(str, "22003"), 0);
02439 } else if (invalidCharExpected) {
02440 BOOST_CHECK_EQUAL(strcmp(str, "22018"), 0);
02441 } else {
02442
02443 BOOST_CHECK(false);
02444 }
02445 }
02446 BOOST_CHECK_EQUAL(caught, (invalidCharExpected || outOfRangeExpected));
02447 if (!caught) {
02448 BOOST_CHECK_EQUAL(value, newvalue);
02449 BOOST_CHECK(src.verify());
02450 }
02451 }
02452
02453
02454
02455 void
02456 SqlStringTest::testSqlStringCastToDecimal()
02457 {
02458 int src_storage, src_len;
02459 int rand_idx;
02460 int precision, scale;
02461 int64_t power, poweridx;
02462 int64_t value, valuer1, valuer2, valuer3;
02463 char buf[256];
02464
02465 src_storage = MAXLEN;
02466
02467 for (src_storage = 1; src_storage <= 20; src_storage++) {
02468 for (src_len = 1; src_len <= src_storage; src_len++) {
02469 power = 1;
02470 for (poweridx = 0; poweridx < src_len; poweridx++) {
02471 power *= 10;
02472 }
02473
02474
02475
02476 for (rand_idx = 0; rand_idx < 5 * MAXRANDOM; rand_idx++) {
02477
02478 valuer1 = rand();
02479 valuer2 = rand();
02480 valuer3 = rand();
02481 value = (valuer1 * valuer2 * valuer3) % power;
02482
02483 if (value < 0) {
02484 value *= -1;
02485 }
02486 if (src_len > 1 && rand() % 2) {
02487
02488
02489
02490 value /= -10;
02491 }
02492
02493 #if 0
02494 BOOST_MESSAGE("src_storage = " << src_storage);
02495 BOOST_MESSAGE("src_len = " << src_len);
02496 BOOST_MESSAGE("power = " << power);
02497 BOOST_MESSAGE("value = " << value);
02498 #endif
02499
02500 scale = 0;
02501
02502
02503 sprintf(buf, "%" FMT_INT64, value);
02504 precision = (value < 0) ? strlen(buf) - 1 : strlen(buf);
02505 BOOST_REQUIRE(strlen(buf) <= src_len);
02506 testSqlStringCastToDecimal_Helper(
02507 value,
02508 precision,
02509 scale,
02510 buf,
02511 src_storage,
02512 src_len,
02513 false,
02514 false);
02515
02516
02517 if (src_len >= 2 && value >= 0) {
02518 sprintf(buf, "+%" FMT_INT64, value / 10);
02519 BOOST_REQUIRE(strlen(buf) <= src_len);
02520 testSqlStringCastToDecimal_Helper(
02521 value / 10,
02522 precision,
02523 scale,
02524 buf,
02525 src_storage,
02526 src_len,
02527 false,
02528 false);
02529 }
02530
02531
02532
02533 sprintf(buf, "%5" FMT_INT64, value);
02534 testSqlStringCastToDecimal_Helper(
02535 value,
02536 precision,
02537 scale,
02538 buf,
02539 src_storage,
02540 src_len,
02541 false,
02542 false);
02543
02544
02545 sprintf(buf, "%20" FMT_INT64, value);
02546 testSqlStringCastToDecimal_Helper(
02547 value,
02548 precision,
02549 scale,
02550 buf,
02551 src_storage,
02552 src_len,
02553 false,
02554 false);
02555
02556
02557 sprintf(buf, "%020" FMT_INT64, value);
02558 testSqlStringCastToDecimal_Helper(
02559 value,
02560 precision,
02561 scale,
02562 buf,
02563 src_storage,
02564 src_len,
02565 false,
02566 false);
02567
02568
02569
02570 sprintf(buf, "%07" FMT_INT64, value);
02571 testSqlStringCastToDecimal_Helper(
02572 value,
02573 precision,
02574 scale,
02575 buf,
02576 src_storage,
02577 src_len,
02578 false,
02579 false);
02580
02581
02582 sprintf(buf, ".%" FMT_INT64, value);
02583 if (value < 0) {
02584 buf[0] = '-';
02585 buf[1] = '.';
02586 }
02587 testSqlStringCastToDecimal_Helper(
02588 value,
02589 precision,
02590 precision,
02591 buf,
02592 src_storage + 1,
02593 src_len + 1,
02594 false,
02595 false);
02596
02597
02598 sprintf(buf, ".%" FMT_INT64 "e3", value);
02599 if (value < 0) {
02600 buf[0] = '-';
02601 buf[1] = '.';
02602 }
02603 testSqlStringCastToDecimal_Helper(
02604 value,
02605 precision,
02606 precision - 3,
02607 buf,
02608 src_storage + 3,
02609 src_len + 3,
02610 false,
02611 false);
02612
02613 if (value != 0) {
02614
02615 testSqlStringCastToDecimal_Helper(
02616 value,
02617 precision,
02618 precision,
02619 buf,
02620 src_storage + 3,
02621 src_len + 3,
02622 true,
02623 false);
02624 }
02625
02626
02627 uint64_t tmp;
02628 sprintf(buf, "%" FMT_INT64 "e-3", value);
02629
02630 testSqlStringCastToDecimal_Helper(
02631 value,
02632 precision,
02633 3,
02634 buf,
02635 src_storage,
02636 src_len,
02637 false,
02638 false);
02639
02640
02641 if (value < 0) {
02642 tmp = -((-value + 5) /10);
02643 } else {
02644 tmp = (value + 5) / 10;
02645 }
02646 testSqlStringCastToDecimal_Helper(
02647 tmp,
02648 precision,
02649 2,
02650 buf,
02651 src_storage+3,
02652 src_len + 3,
02653 false,
02654 false);
02655
02656 if (value != 0) {
02657
02658 testSqlStringCastToDecimal_Helper(
02659 value,
02660 precision,
02661 4,
02662 buf,
02663 src_storage + 3,
02664 src_len + 3,
02665 true,
02666 false);
02667 }
02668
02669
02670
02671 if (abs(value) >= 10) {
02672 sprintf(buf, "%" FMT_INT64, value);
02673 testSqlStringCastToDecimal_Helper(
02674 value,
02675 precision - 1,
02676 scale,
02677 buf,
02678 src_storage,
02679 src_len,
02680 true,
02681 false);
02682 }
02683
02684
02685 sprintf(buf, "%" FMT_INT64 "e", value);
02686 testSqlStringCastToDecimal_Helper(
02687 value,
02688 precision,
02689 scale,
02690 buf,
02691 src_storage + 1,
02692 src_len + 1,
02693 false,
02694 true);
02695
02696
02697 sprintf(buf, "%" FMT_INT64, value);
02698 buf[0] = 'a';
02699 testSqlStringCastToDecimal_Helper(
02700 value,
02701 precision,
02702 scale,
02703 buf,
02704 src_storage,
02705 src_len,
02706 false,
02707 true);
02708
02709
02710 if (src_len > 2) {
02711 sprintf(buf, "%" FMT_INT64, value);
02712 buf[1] = 'a';
02713 testSqlStringCastToDecimal_Helper(
02714 value,
02715 precision,
02716 scale,
02717 buf,
02718 src_storage,
02719 src_len,
02720 false,
02721 true);
02722 }
02723
02724
02725 if (src_len > 3 && value >= 100) {
02726 sprintf(buf, "%" FMT_INT64, value);
02727 buf[1] = ' ';
02728 testSqlStringCastToDecimal_Helper(
02729 value,
02730 precision,
02731 scale,
02732 buf,
02733 src_storage,
02734 src_len,
02735 false,
02736 true);
02737 }
02738
02739
02740 memset(buf, ' ', src_len);
02741 testSqlStringCastToDecimal_Helper(
02742 value,
02743 precision,
02744 scale,
02745 buf,
02746 src_storage,
02747 src_len,
02748 false,
02749 true);
02750
02751
02752 if (src_len > 3) {
02753 sprintf(buf, "%" FMT_INT64, value);
02754 buf[0] = '-';
02755 buf[1] = ' ';
02756 testSqlStringCastToDecimal_Helper(
02757 value,
02758 precision,
02759 scale,
02760 buf,
02761 src_storage,
02762 src_len,
02763 false,
02764 true);
02765 }
02766
02767
02768 if (src_len > 3) {
02769 sprintf(buf, "%" FMT_INT64, value);
02770 buf[0] = '-';
02771 buf[1] = ' ';
02772 testSqlStringCastToDecimal_Helper(
02773 value,
02774 precision,
02775 scale,
02776 buf,
02777 src_storage,
02778 src_len,
02779 false,
02780 true);
02781 }
02782
02783
02784 memset(buf, ' ', src_len);
02785 buf[0] = '-';
02786 testSqlStringCastToDecimal_Helper(
02787 value,
02788 precision,
02789 scale,
02790 buf,
02791 src_storage,
02792 src_len,
02793 false,
02794 true);
02795
02796 memset(buf, ' ', src_len);
02797 buf[0] = '+';
02798 testSqlStringCastToDecimal_Helper(
02799 value,
02800 precision,
02801 scale,
02802 buf,
02803 src_storage,
02804 src_len,
02805 false,
02806 true);
02807 }
02808 }
02809 }
02810 }
02811
02812 void
02813 SqlStringTest::testSqlStringCastToApprox_Helper(
02814 double value,
02815 char const * const buf,
02816 int src_storage,
02817 int src_len,
02818 bool exceptionExpected)
02819 {
02820 bool caught = false;
02821 double newvalue = 0;
02822 SqlStringBuffer src(
02823 src_storage, src_len,
02824 0, src_storage - src_len,
02825 's', ' ');
02826
02827 #if 0
02828 BOOST_MESSAGE("buf = |" << buf << "|");
02829 {
02830 char foo[256];
02831 sprintf(foo, "%.8lf", value);
02832 BOOST_MESSAGE("expected value = " << value << " " << foo);
02833 }
02834 #endif
02835 if (strlen(buf) > src_len) {
02836
02837 return;
02838 }
02839
02840
02841 memcpy(src.mStr, buf, strlen(buf));
02842
02843
02844 memset(src.mStr + strlen(buf), ' ', src_len - strlen(buf));
02845 #if 0
02846 BOOST_MESSAGE("str = |" << src.mLeftP << "|");
02847 #endif
02848
02849 try {
02850 newvalue = SqlStrCastToApprox<1,1>(
02851 src.mStr,
02852 src_len);
02853 } catch (const char *str) {
02854 caught = true;
02855 BOOST_CHECK_EQUAL(strcmp(str, "22018"), 0);
02856 }
02857 BOOST_CHECK_EQUAL(caught, exceptionExpected);
02858 if (!caught) {
02859
02860
02861
02862
02863 double epsilon = fabs(value / 10000);
02864 if (epsilon < 0.0001) {
02865
02866 epsilon = 0.0001;
02867 }
02868 BOOST_CHECK(fabs(value - newvalue) < epsilon);
02869 BOOST_CHECK(src.verify());
02870 }
02871 }
02872
02873
02874 void
02875 SqlStringTest::testSqlStringCastToApprox()
02876 {
02877 int src_storage, src_len;
02878 char exponent_buf[256];
02879 char decimal_buf[256];
02880 char neg_buf[256];
02881 double orig_value, dec_value, exp_value;
02882 double small_idx;
02883 int leading;
02884 int leadingplus;
02885 int leadingminus;
02886 int beforedec;
02887 int afterdec;
02888 int src_len_left;
02889 int buildlen;
02890 int idx;
02891 int rnd;
02892 int neg_idx;
02893
02894 src_storage = MAXLEN;
02895
02896
02897 for (src_storage = 2; src_storage <= 10; src_storage++) {
02898 for (src_len = 2; src_len <= src_storage; src_len++) {
02899 for (leading = 0; leading <= 2; leading++) {
02900 leadingplus = leadingminus = 0;
02901 if (leading == 1 && src_len > 2) {
02902 leadingplus = 1;
02903 }
02904 if (leading == 2 && src_len > 2) {
02905 leadingminus = 1;
02906 }
02907 src_len_left = src_len;
02908 if (leadingplus || leadingminus) {
02909 src_len_left--;
02910 }
02911 for (beforedec = 0; beforedec <= src_len_left; beforedec++) {
02912 afterdec = src_len_left - beforedec;
02913
02914 #if 0
02915 BOOST_MESSAGE("src_storage = " << src_storage);
02916 BOOST_MESSAGE("src_len = " << src_len);
02917 BOOST_MESSAGE("leadingplus = " << leadingplus);
02918 BOOST_MESSAGE("leadingminus = " << leadingminus);
02919 BOOST_MESSAGE("beforedec = " << beforedec);
02920 BOOST_MESSAGE("afterdec = " << afterdec);
02921 #endif
02922
02923 buildlen = leadingplus + leadingminus + beforedec +
02924 afterdec;
02925 BOOST_REQUIRE(buildlen == src_len);
02926
02927 string s;
02928 if (leadingplus) {
02929 s.append("+");
02930 }
02931 if (leadingminus) {
02932 s.append("-");
02933 }
02934 idx = beforedec;
02935 while (idx-- > 0) {
02936 rnd = rand() % 10;
02937 s.append(1, '0' + rnd);
02938 }
02939 if (afterdec) {
02940 s.append(".");
02941 idx = afterdec - 1;
02942 while (idx-- > 0) {
02943 rnd = rand() % 10;
02944 s.append(1, '0' + rnd);
02945 }
02946 }
02947 sscanf(s.c_str(), "%lf", &orig_value);
02948
02949 for (small_idx = 1E+10;
02950 small_idx > 1E-10;
02951 small_idx *= 0.01) {
02952 dec_value = orig_value * small_idx;
02953
02954 sprintf(decimal_buf, "%.8lf", orig_value * small_idx);
02955 sscanf(decimal_buf, "%lf", &dec_value);
02956 sprintf(exponent_buf, "%.8E", orig_value * small_idx);
02957 sscanf(exponent_buf, "%lf", &exp_value);
02958
02959 #if 0
02960 BOOST_MESSAGE("s = |" << s << "|");
02961 BOOST_MESSAGE("exponent_buf = |"<< exponent_buf<< "|");
02962 BOOST_MESSAGE("dec_value = " << dec_value);
02963 BOOST_MESSAGE("exp_value = " << exp_value);
02964 #endif
02965
02966
02967
02968 testSqlStringCastToApprox_Helper(
02969 exp_value,
02970 exponent_buf,
02971 src_storage,
02972 src_len,
02973 false);
02974
02975 testSqlStringCastToApprox_Helper(
02976 dec_value,
02977 decimal_buf,
02978 src_storage,
02979 src_len,
02980 false);
02981
02982
02983 sprintf(
02984 exponent_buf, "%10.8E",
02985 orig_value * small_idx);
02986 sscanf(exponent_buf, "%lf", &exp_value);
02987 testSqlStringCastToApprox_Helper(
02988 exp_value,
02989 exponent_buf,
02990 src_storage,
02991 src_len,
02992 false);
02993
02994
02995 sprintf(
02996 decimal_buf, "%10.8lf",
02997 orig_value * small_idx);
02998 sscanf(decimal_buf, "%lf", &dec_value);
02999 testSqlStringCastToApprox_Helper(
03000 dec_value,
03001 decimal_buf,
03002 src_storage,
03003 src_len,
03004 false);
03005
03006
03007 sprintf(
03008 exponent_buf, "%010.8E",
03009 orig_value * small_idx);
03010 sscanf(exponent_buf, "%lf", &exp_value);
03011 testSqlStringCastToApprox_Helper(
03012 exp_value,
03013 exponent_buf,
03014 src_storage,
03015 src_len,
03016 false);
03017
03018
03019 sprintf(
03020 decimal_buf, "%010.8lf",
03021 orig_value * small_idx);
03022 sscanf(decimal_buf, "%lf", &dec_value);
03023 testSqlStringCastToApprox_Helper(
03024 dec_value,
03025 decimal_buf,
03026 src_storage,
03027 src_len,
03028 false);
03029
03030
03031
03032
03033 if (src_storage < 4 || !(rand() % 10)) {
03034
03035 sprintf(
03036 decimal_buf, "%.8lf",
03037 orig_value * small_idx);
03038 sscanf(
03039 decimal_buf, "%lf",
03040 &dec_value);
03041 sprintf(
03042 exponent_buf, "%.8E",
03043 orig_value * small_idx);
03044 sscanf(exponent_buf, "%lf", &exp_value);
03045 int exp_len = strlen(exponent_buf);
03046 int dec_len = strlen(decimal_buf);
03047
03048 for (neg_idx = 0;
03049 neg_idx < dec_len;
03050 neg_idx++)
03051 {
03052 strcpy(neg_buf, decimal_buf);
03053 neg_buf[neg_idx] = 'a';
03054 testSqlStringCastToApprox_Helper(
03055 dec_value,
03056 neg_buf,
03057 src_storage,
03058 src_len,
03059 true);
03060 if (neg_idx > 1 && neg_idx < dec_len - 1) {
03061
03062 neg_buf[neg_idx] = ' ';
03063 testSqlStringCastToApprox_Helper(
03064 dec_value,
03065 neg_buf,
03066 src_storage,
03067 src_len,
03068 true);
03069 }
03070 }
03071
03072 for (neg_idx = 0;
03073 neg_idx < exp_len;
03074 neg_idx++)
03075 {
03076 strcpy(neg_buf, exponent_buf);
03077 neg_buf[neg_idx] = 'a';
03078 testSqlStringCastToApprox_Helper(
03079 exp_value,
03080 neg_buf,
03081 src_storage,
03082 src_len,
03083 true);
03084 if (neg_idx > 1 && neg_idx < exp_len - 1) {
03085
03086 neg_buf[neg_idx] = ' ';
03087 testSqlStringCastToApprox_Helper(
03088 exp_value,
03089 neg_buf,
03090 src_storage,
03091 src_len,
03092 true);
03093 }
03094 }
03095
03096
03097 memset(neg_buf, ' ', src_len);
03098 testSqlStringCastToApprox_Helper(
03099 exp_value,
03100 neg_buf,
03101 src_storage,
03102 src_len,
03103 true);
03104 }
03105 }
03106 }
03107 }
03108 }
03109 }
03110 }
03111
03112 void
03113 SqlStringTest::testSqlStringCastFromExact()
03114 {
03115 int src_len;
03116 int dst_storage, dst_len, newlen = 0;
03117 int rand_idx, power_idx;
03118 int negative;
03119 int64_t value, newones;
03120 bool caught;
03121
03122
03123 for (dst_storage = 0; dst_storage <= 22; dst_storage++) {
03124 for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
03125 for (src_len = 0; src_len < 19; src_len++) {
03126 for (rand_idx = 0; rand_idx < 1; rand_idx++) {
03127 for (negative = 0; negative <= 1; negative++) {
03128 value = 0;
03129 for (power_idx = 0;
03130 power_idx < src_len - negative;
03131 power_idx++) {
03132 if (!value) {
03133
03134 newones = rand() % 9 + 1;
03135 } else {
03136 newones = rand() % 10;
03137 }
03138 value = value*10 + newones;
03139 }
03140 if (!(rand() % 10)) {
03141 value = 0;
03142 }
03143 if (negative) {
03144 value *= -1;
03145 }
03146
03147 ostringstream ostr("");
03148 ostr << value;
03149 string expect = ostr.str();
03150 string expect_fix(expect);
03151 if (expect_fix.length() < dst_storage) {
03152 expect_fix.append(
03153 dst_storage -
03154 expect_fix.length(),
03155 ' ');
03156 }
03157
03158 SqlStringBuffer dst(
03159 dst_storage, dst_len,
03160 0, dst_storage - dst_len,
03161 's', ' ');
03162
03163 caught = false;
03164 try {
03165 newlen = SqlStrCastFromExact<1,1>(
03166 dst.mStr,
03167 dst_storage,
03168 value,
03169 false);
03170 } catch (const char *str) {
03171 caught = true;
03172 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
03173 BOOST_CHECK(expect.length() > dst_storage);
03174 BOOST_CHECK(dst.verify());
03175 }
03176 if (!caught) {
03177 string result(dst.mStr, newlen);
03178 BOOST_CHECK(dst.verify());
03179 BOOST_CHECK(expect.length() <= dst_storage);
03180 BOOST_CHECK(!expect.compare(result));
03181 }
03182
03183 SqlStringBuffer dst_fix(
03184 dst_storage, dst_len,
03185 0, dst_storage - dst_len,
03186 's', ' ');
03187
03188 caught = false;
03189 try {
03190 newlen = SqlStrCastFromExact<1,1>(
03191 dst_fix.mStr,
03192 dst_storage,
03193 value,
03194 true);
03195 } catch (const char *str) {
03196 caught = true;
03197 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
03198 BOOST_CHECK(expect_fix.length() > dst_storage);
03199 BOOST_CHECK(dst_fix.verify());
03200 }
03201 if (!caught) {
03202 string result_fix(dst_fix.mStr, newlen);
03203 BOOST_CHECK(dst_fix.verify());
03204 BOOST_CHECK(expect_fix.length() <= dst_storage);
03205 BOOST_CHECK(!expect_fix.compare(result_fix));
03206 }
03207 }
03208 }
03209 }
03210 }
03211 }
03212 }
03213
03214 void
03215 SqlStringTest::testSqlStringCastFromDecimal()
03216 {
03217 int precision, scale;
03218 int src_len;
03219 int dst_storage, dst_len, newlen = 0;
03220 int rand_idx, power_idx;
03221 int negative;
03222 int64_t value, newones, whole, decimal;
03223 char expected_buf[256];
03224 char digits[] = "0123456789";
03225 bool caught;
03226
03227
03228 for (dst_storage = 0; dst_storage <= 22; dst_storage++) {
03229 for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
03230 for (src_len = 0; src_len < 19; src_len++) {
03231 for (rand_idx = 0; rand_idx < 1; rand_idx++) {
03232 for (negative = 0; negative <= 1; negative++) {
03233 precision = src_len;
03234 value = 0;
03235 for (power_idx = 0;
03236 power_idx < src_len - negative;
03237 power_idx++) {
03238 if (!value) {
03239
03240 newones = rand() % 9 + 1;
03241 } else {
03242 newones = rand() % 10;
03243 }
03244 value = value*10 + newones;
03245 }
03246 if (!(rand() % 10)) {
03247 value = 0;
03248 }
03249 if (negative) {
03250 value *= -1;
03251 }
03252 scale = rand() % 25 - 5;
03253
03254 if (scale == 0) {
03255 sprintf(expected_buf, "%" FMT_INT64, value);
03256 } else if (scale > 0) {
03257 whole = value;
03258 for (int i = 0; i < scale; i++) {
03259 whole /= 10;
03260 }
03261
03262 if (whole != 0) {
03263 sprintf(expected_buf, "%" FMT_INT64, whole);
03264 } else {
03265 if (value < 0) {
03266 expected_buf[0] = '-';
03267 expected_buf[1] = '\0';
03268 } else {
03269 expected_buf[0] = '\0';
03270 }
03271 }
03272
03273 for (int i = 0; i < scale; i++) {
03274 whole *= 10;
03275 }
03276 decimal = abs(value - whole);
03277
03278 int len = strlen(expected_buf);
03279 expected_buf[len] = '.';
03280 for (int i = scale-1; i >= 0; i--) {
03281 expected_buf[len + i + 1] =
03282 digits[decimal % 10];
03283 decimal /= 10;
03284 }
03285 expected_buf[len+scale+1] = '\0';
03286 } else if (scale < 0) {
03287 sprintf(expected_buf, "%" FMT_INT64, value);
03288 if (value != 0) {
03289 int len = strlen(expected_buf);
03290 memset(expected_buf + len, '0', -scale);
03291 expected_buf[len - scale] = '\0';
03292 }
03293 }
03294
03295 string expect(expected_buf);
03296 string expect_fix(expect);
03297 if (expect_fix.length() < dst_storage) {
03298 expect_fix.append(
03299 dst_storage -
03300 expect_fix.length(),
03301 ' ');
03302 }
03303
03304 SqlStringBuffer dst(
03305 dst_storage, dst_len,
03306 0, dst_storage - dst_len,
03307 's', ' ');
03308
03309 caught = false;
03310 try {
03311 newlen = SqlStrCastFromExact<1,1>(
03312 dst.mStr,
03313 dst_storage,
03314 value,
03315 precision,
03316 scale,
03317 false);
03318 } catch (const char *str) {
03319 caught = true;
03320 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
03321 BOOST_CHECK(expect.length() > dst_storage);
03322 BOOST_CHECK(dst.verify());
03323 }
03324 if (!caught) {
03325 string result(dst.mStr, newlen);
03326 BOOST_CHECK(dst.verify());
03327 BOOST_CHECK(expect.length() <= dst_storage);
03328 BOOST_CHECK(!expect.compare(result));
03329 }
03330
03331 SqlStringBuffer dst_fix(
03332 dst_storage, dst_len,
03333 0, dst_storage - dst_len,
03334 's', ' ');
03335
03336 caught = false;
03337 try {
03338 newlen = SqlStrCastFromExact<1,1>(
03339 dst_fix.mStr,
03340 dst_storage,
03341 value,
03342 precision,
03343 scale,
03344 true);
03345 } catch (const char *str) {
03346 caught = true;
03347 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
03348 BOOST_CHECK(expect_fix.length() > dst_storage);
03349 BOOST_CHECK(dst_fix.verify());
03350 }
03351 if (!caught) {
03352 string result_fix(dst_fix.mStr, newlen);
03353 BOOST_CHECK(dst_fix.verify());
03354 BOOST_CHECK(expect_fix.length() <= dst_storage);
03355 BOOST_CHECK(!expect_fix.compare(result_fix));
03356 }
03357 }
03358 }
03359 }
03360 }
03361 }
03362 }
03363
03364 void
03365 SqlStringTest::testSqlStringCastFromApprox()
03366 {
03367 int src_len;
03368 int dst_storage, dst_len, newlen = 0;
03369 int rand_idx, power_idx;
03370 int negative;
03371 int isFloat;
03372 int max_precision;
03373 double value, newones, exponent;
03374 char expected_buf[256];
03375 bool caught;
03376
03377
03378 for (dst_storage = 0; dst_storage <= 24; dst_storage++) {
03379 for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
03380
03381 for (src_len = 0; src_len < 16; src_len++) {
03382 for (rand_idx = 0; rand_idx < 1; rand_idx++) {
03383 for (negative = 0; negative <= 1; negative++) {
03384 value = 0;
03385 for (power_idx = 0;
03386
03387 power_idx < src_len - (negative + 5);
03388 power_idx++) {
03389 if (!value) {
03390
03391 newones = rand() % 9 + 1;
03392 } else {
03393 newones = rand() % 10;
03394 }
03395 value = value*10 + newones;
03396 }
03397 if (!(rand() % 10)) {
03398 value = 0;
03399 }
03400 if (negative) {
03401 value *= -1;
03402 }
03403
03404 exponent = 1 + rand() % 30;
03405 if (!(rand() % 2)) {
03406 exponent *= -1;
03407 }
03408 value = pow(value, 1 + rand() % 80);
03409
03410 isFloat = rand() % 2;
03411 if (isFloat) {
03412 value = (float) value;
03413 }
03414 max_precision = (isFloat) ? 7 : 16;
03415
03416 if (value > std::numeric_limits<double>::max()) {
03417 strcpy(expected_buf, "INF");
03418 } else if (value
03419 < -std::numeric_limits<double>::max())
03420 {
03421 strcpy(expected_buf, "-INF");
03422 } else if (value) {
03423 int i, epos = -1, prec = 0, buflen, exp;
03424 int neg = (value < 0) ? 1 : 0;
03425 char last_digit = 0;
03426 sprintf(expected_buf, "%.*E", max_precision, value);
03427 buflen = strlen(expected_buf);
03428 epos = neg + max_precision + 2;
03429 if (buflen > epos && expected_buf[epos] == 'E') {
03430 sscanf(expected_buf + epos + 1, "%d", &exp);
03431
03432
03433 if ((expected_buf[epos - 1] >= '5') &&
03434 (expected_buf[epos - 1] <= '9'))
03435 {
03436 expected_buf[epos - 1] = '0';
03437 for (int i = epos - 2; i >= neg; i--) {
03438 if (expected_buf[i] == '9') {
03439 expected_buf[i] = '0';
03440 } else if (expected_buf[i] != '.') {
03441 expected_buf[i]++;
03442 break;
03443 }
03444 }
03445
03446
03447 if (expected_buf[neg] == '0') {
03448 expected_buf[neg] = '1';
03449 for (int i = epos - 1; i > neg + 2;
03450 i--)
03451 {
03452 expected_buf[i] =
03453 expected_buf[i - 1];
03454 }
03455 expected_buf[neg + 2] = '0';
03456
03457
03458 exp++;
03459 }
03460 }
03461
03462 for (i = epos - 2; i >= 0; i--) {
03463 if (expected_buf[i] != '0') {
03464 if (expected_buf[i] == '.') {
03465 BOOST_CHECK_EQUAL(i, 1 + neg);
03466 last_digit = expected_buf[i - 1];
03467 } else {
03468 last_digit = expected_buf[i];
03469 }
03470 prec = i - 1 - neg;
03471 break;
03472 }
03473 }
03474 sprintf(expected_buf, "%.*E", prec, value);
03475 buflen = strlen(expected_buf);
03476 epos =
03477 (prec > 0) ? (neg + prec + 2) : (neg + 1);
03478 BOOST_CHECK(buflen > epos);
03479 BOOST_CHECK(expected_buf[epos] == 'E');
03480 expected_buf[epos - 1] = last_digit;
03481 sprintf(expected_buf + epos + 1, "%d", exp);
03482 }
03483 } else {
03484
03485 strcpy(expected_buf, "0E0");
03486 }
03487
03488 string expect(expected_buf);
03489 string expect_fix(expect);
03490 if (expect_fix.length() < dst_storage) {
03491 expect_fix.append(
03492 dst_storage -
03493 expect_fix.length(),
03494 ' ');
03495 }
03496
03497 #if 0
03498 BOOST_MESSAGE("value = " << value);
03499 BOOST_MESSAGE("storage = " << dst_storage <<
03500 " len = " << dst_len <<
03501 " src_len = " << src_len);
03502 BOOST_MESSAGE("expect = |" << expect << "|");
03503 BOOST_MESSAGE("expect_fix = |" << expect_fix << "|");
03504 #endif
03505
03506 SqlStringBuffer dst(
03507 dst_storage, dst_len,
03508 0, dst_storage - dst_len,
03509 's', ' ');
03510
03511 caught = false;
03512 try {
03513 newlen = SqlStrCastFromApprox<1,1>(
03514 dst.mStr,
03515 dst_storage,
03516 value,
03517 isFloat,
03518 false);
03519 } catch (const char *str) {
03520 caught = true;
03521 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
03522 BOOST_CHECK(expect.length() > dst_storage);
03523 BOOST_CHECK(dst.verify());
03524 }
03525 if (!caught) {
03526 string result(dst.mStr, newlen);
03527
03528 BOOST_CHECK(dst.verify());
03529 BOOST_CHECK(expect.length() <= dst_storage);
03530 BOOST_CHECK(!expect.compare(result));
03531 if (expect.compare(result)) {
03532 BOOST_MESSAGE("Got " << result <<
03533 ", expected " << expect <<
03534 ", value " << value);
03535 }
03536 }
03537
03538 SqlStringBuffer dst_fix(
03539 dst_storage, dst_len,
03540 0, dst_storage - dst_len,
03541 's', ' ');
03542
03543 caught = false;
03544 try {
03545 newlen = SqlStrCastFromApprox<1,1>(
03546 dst_fix.mStr,
03547 dst_storage,
03548 value,
03549 isFloat,
03550 true);
03551 } catch (const char *str) {
03552 caught = true;
03553 BOOST_CHECK_EQUAL(strcmp(str, "22001"), 0);
03554 BOOST_CHECK(expect_fix.length() > dst_storage);
03555 BOOST_CHECK(dst_fix.verify());
03556 }
03557 if (!caught) {
03558 string result_fix(dst_fix.mStr, newlen);
03559 BOOST_CHECK(dst_fix.verify());
03560 BOOST_CHECK(expect_fix.length() <= dst_storage);
03561 BOOST_CHECK(!expect_fix.compare(result_fix));
03562 }
03563 }
03564 }
03565 }
03566 }
03567 }
03568 }
03569
03570
03571 void
03572 SqlStringTest::testSqlStringCastToVarChar()
03573 {
03574 int src_storage, dst_storage, src_len, dst_len;
03575
03576 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
03577 for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
03578 for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
03579 for (src_len = 0; src_len <= src_storage; src_len++) {
03580
03581
03582 SqlStringBuffer dst(
03583 dst_storage, dst_len,
03584 0, dst_storage - dst_len,
03585 'd', ' ');
03586
03587 SqlStringBuffer src(
03588 src_storage, src_len,
03589 0, src_storage - src_len,
03590 's', ' ');
03591
03592 int rightTruncWarning = 0;
03593 try {
03594 SqlStrCastToVarChar<1,1>(
03595 dst.mStr,
03596 dst_storage,
03597 src.mStr,
03598 src_len,
03599 &rightTruncWarning);
03600 } catch (...) {
03601 BOOST_CHECK(false);
03602 }
03603
03604 BOOST_CHECK(
03605 (src_len <= dst_storage && !rightTruncWarning)
03606 || (src_len > dst_storage && rightTruncWarning));
03607
03608 string expect;
03609 expect.append(min(src_len, dst_storage), 's');
03610
03611 if (dst_storage > src_len) {
03612 expect.append(dst_storage - src_len, ' ');
03613 }
03614
03615 string result(dst.mStr, dst_storage);
03616
03617 #if 0
03618 BOOST_MESSAGE(" dst_storage=" << dst_storage <<
03619 " dst_len=" << dst_len <<
03620 " src_storage=" << src_storage <<
03621 " src_len=" << src_len);
03622 BOOST_MESSAGE("src =|" << src.mLeftP << "|");
03623 BOOST_MESSAGE("expect |" << expect << "|");
03624 BOOST_MESSAGE("result |" << result << "|");
03625 #endif
03626
03627 BOOST_CHECK(!result.compare(expect));
03628
03629 BOOST_CHECK(dst.verify());
03630 BOOST_CHECK(src.verify());
03631
03632
03633
03634 }
03635 }
03636 }
03637 }
03638 }
03639
03640
03641 void
03642 SqlStringTest::testSqlStringCastToChar()
03643 {
03644 int src_storage, dst_storage, src_len, dst_len, new_len = 0;
03645
03646
03647
03648
03649
03650
03651
03652 for (dst_storage = 0; dst_storage < MAXLEN; dst_storage++) {
03653 for (dst_len = 0; dst_len <= dst_storage; dst_len++) {
03654 for (src_storage = 0; src_storage < MAXLEN; src_storage++) {
03655 for (src_len = 0; src_len <= src_storage; src_len++) {
03656
03657
03658 SqlStringBuffer dst(
03659 dst_storage, dst_len,
03660 0, dst_storage - dst_len,
03661 'd', ' ');
03662
03663 SqlStringBuffer src(
03664 src_storage, src_len,
03665 0, src_storage - src_len,
03666 's', ' ');
03667
03668 int rightTruncWarning = 0;
03669
03670 try {
03671 new_len = SqlStrCastToChar<1,1>(
03672 dst.mStr,
03673 dst_storage,
03674 src.mStr,
03675 src_len,
03676 &rightTruncWarning);
03677 } catch (...) {
03678 BOOST_CHECK(false);
03679 }
03680
03681 BOOST_CHECK(
03682 (src_len <= dst_storage && !rightTruncWarning)
03683 || (src_len > dst_storage && rightTruncWarning));
03684 BOOST_CHECK_EQUAL(new_len, dst_storage);
03685
03686 string expect;
03687 expect.append(min(src_len, dst_storage), 's');
03688
03689 if (dst_storage > src_len) {
03690 expect.append(dst_storage - src_len, ' ');
03691 }
03692
03693 string result(dst.mStr, dst_storage);
03694
03695 #if 0
03696 BOOST_MESSAGE(" dst_storage=" << dst_storage <<
03697 " dst_len=" << dst_len <<
03698 " src_storage=" << src_storage <<
03699 " src_len=" << src_len);
03700 BOOST_MESSAGE("src =|" << src.mLeftP << "|");
03701 BOOST_MESSAGE("expect |" << expect << "|");
03702 BOOST_MESSAGE("result |" << result << "|");
03703 #endif
03704
03705 BOOST_CHECK(!result.compare(expect));
03706
03707 BOOST_CHECK(dst.verify());
03708 BOOST_CHECK(src.verify());
03709
03710
03711
03712 }
03713 }
03714 }
03715 }
03716 }
03717
03718
03719 FENNEL_UNIT_TEST_SUITE(SqlStringTest);
03720
03721