SqlStringBuffer.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calctest/SqlStringBuffer.cpp#3 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-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/calctest/SqlStringBuffer.h"
00025 
00026 using namespace fennel;
00027 using namespace std;
00028 
00029 #if !(defined LITTLEENDIAN || defined BIGENDIAN)
00030 #error "endian not defined"
00031 #endif
00032 
00033 const uint SqlStringBuffer::mBumperChar = '@';
00034 // use unaligned bumperlen for 1-byte-per-character strings
00035 // to ensure generality
00036 const int SqlStringBuffer::mBumperLen = 3;
00037 
00038 SqlStringBuffer::
00039 SqlStringBuffer(
00040     int storage,    // maximum size of string in characters
00041     int size,       // size of text, in characters, excluding padding
00042     int leftpad,    // pad left with this many characters
00043     int rightpad,   // pad right with this many chararacters
00044     uint text,      // fill text w/this
00045     uint pad,       // pad w/this
00046     int leftBumper, // In characters
00047     int rightBumper)
00048     : mStorage(storage),
00049       mSize(size),
00050       mLeftPad(leftpad),
00051       mRightPad(rightpad),
00052       mLeftBump(leftBumper),
00053       mRightBump(rightBumper),
00054       mTotal(storage + leftBumper + rightBumper),
00055       mS(mTotal, mBumperChar)
00056 {
00057     assert(leftBumper > 0);
00058     assert(rightBumper > 0);
00059     assert(storage == size + leftpad + rightpad);
00060 
00061     mLeftP = const_cast<char *>(mS.c_str()); // Too abusive of string()?
00062     mStr = mLeftP + mLeftBump;
00063     mRightP = mStr + mStorage;
00064 
00065     string padS(mStorage, pad);
00066     string textS(size, text);
00067 
00068     mS.replace(mLeftBump, mStorage, padS, 0, mStorage); // pad all first
00069     mS.replace(mLeftBump + mLeftPad, mSize, textS, 0, mSize);
00070 }
00071 
00072 
00073 bool
00074 SqlStringBuffer::verify()
00075 {
00076     string verS(mTotal, mBumperChar);
00077     if (mS.compare(0, mLeftBump, verS, 0, mLeftBump)) {
00078         return false;
00079     }
00080     if (mS.compare(
00081         mLeftBump + mLeftPad + mSize + mRightPad,
00082         mRightBump, verS, 0, mRightBump))
00083     {
00084         return false;
00085     }
00086     return true;
00087 }
00088 
00089 void
00090 SqlStringBuffer::randomize(
00091     uint start,
00092     uint lower,
00093     uint upper)
00094 {
00095     patternfill(start, lower, upper);
00096     string r(mStr, mSize);
00097     random_shuffle(r.begin(), r.end());
00098     mS.replace(mLeftBump + mLeftPad, mSize, r);
00099 }
00100 
00101 void
00102 SqlStringBuffer::patternfill(
00103     uint start,
00104     uint lower,
00105     uint upper)
00106 {
00107     uint c = start; // deal with overflow easier than char
00108     int toGen = mSize;
00109 
00110     string r;
00111 
00112     while (toGen) {
00113         r.push_back(static_cast<unsigned char>(c));
00114         toGen--;
00115         if (++c > upper) {
00116             c = lower;
00117         }
00118     }
00119     mS.replace(mLeftBump + mLeftPad, mSize, r);
00120 }
00121 
00122 
00123 const uint SqlStringBufferUCS2::mBumperChar = '@';
00124 // multi-byte strings will be aligned by tuple mechanism to
00125 // at least short-word (2-byte) alignment.
00126 const int SqlStringBufferUCS2::mBumperLen = 2;
00127 
00128 SqlStringBufferUCS2::SqlStringBufferUCS2(SqlStringBuffer const &src)
00129     : mStorage(src.mStorage *2),
00130       mSize(src.mSize * 2),
00131       mLeftPad(src.mLeftPad * 2),
00132       mRightPad(src.mRightPad * 2),
00133       // force alignment when copying from potentially unaligned
00134       mLeftBump(src.mLeftBump & 1 ? src.mLeftBump + 1 : src.mLeftBump),
00135       mRightBump(src.mRightBump & 1 ? src.mRightBump + 1 : src.mRightBump),
00136       mTotal(src.mStorage * 2 + mLeftBump + mRightBump)
00137 {
00138     mS.assign(mTotal, mBumperChar);
00139 
00140     init();
00141 
00142     char *srcP = src.mStr;
00143     char *dstP = mStr;
00144     int i = src.mStorage;
00145     while (i > 0) {
00146 #ifdef LITTLEENDIAN
00147         *(dstP++) = *(srcP++);
00148         *(dstP++) = 0x00;
00149 #else
00150         *(dstP++) = 0x00;
00151         *(dstP++) = *(srcP++);
00152 #endif
00153         i--;
00154     }
00155 }
00156 
00157 SqlStringBufferUCS2::SqlStringBufferUCS2(
00158     SqlStringBuffer const &src,
00159     int leftBumper,
00160     int rightBumper)
00161     : mStorage(src.mStorage *2),
00162       mSize(src.mSize * 2),
00163       mLeftPad(src.mLeftPad * 2),
00164       mRightPad(src.mRightPad * 2),
00165       mLeftBump(leftBumper),
00166       mRightBump(rightBumper),
00167       mTotal(src.mStorage * 2 + leftBumper + rightBumper)
00168 {
00169     // force alignment
00170     assert(!(mLeftBump & 1));
00171     assert(!(mRightBump & 1));
00172 
00173     mS.assign(mTotal, mBumperChar);
00174 
00175     init();
00176 
00177     char *srcP = src.mStr;
00178     char *dstP = mStr;
00179     int i = src.mStorage;
00180     while (i > 0) {
00181 #ifdef LITTLEENDIAN
00182         *(dstP++) = *(srcP++);
00183         *(dstP++) = 0x00;
00184 #else
00185         *(dstP++) = 0x00;
00186         *(dstP++) = *(srcP++);
00187 #endif
00188         i--;
00189     }
00190 }
00191 
00192 
00193 void
00194 SqlStringBufferUCS2::init()
00195 {
00196     assert(mLeftBump > 0);
00197     assert(mRightBump > 0);
00198     assert(mStorage == mSize + mLeftPad + mRightPad);
00199 
00200     mLeftP = const_cast<char *>(mS.c_str()); // Too abusive of string()?
00201     mStr = mLeftP + mLeftBump;
00202     mStrPostPad = mStr + mLeftPad;
00203     mRightP = mStr + mStorage;
00204 }
00205 
00206 
00207 bool
00208 SqlStringBufferUCS2::verify()
00209 {
00210     string verS(mTotal, mBumperChar);
00211     if (mS.compare(0, mLeftBump, verS, 0, mLeftBump)) {
00212         return false;
00213     }
00214     if (mS.compare(
00215         mLeftBump + mLeftPad + mSize + mRightPad,
00216         mRightBump, verS, 0, mRightBump))
00217     {
00218         return false;
00219     }
00220     return true;
00221 }
00222 
00223 void
00224 SqlStringBufferUCS2::randomize(
00225     uint start,
00226     uint lower,
00227     uint upper)
00228 {
00229     patternfill(start, lower, upper);
00230 
00231     vector <uint16_t> r;
00232     uint16_t tmp;
00233     int i = 0;
00234     while (i < mSize) {
00235 #ifdef LITTLEENDIAN
00236         tmp = mStrPostPad[i + 1] << 8 | mStrPostPad[i];
00237 #else
00238         tmp = mStrPostPad[i] << 8 | mStrPostPad[i + 1];
00239 #endif
00240         r.push_back(tmp);
00241         i += 2;
00242     }
00243 
00244 
00245     random_shuffle(r.begin(), r.end());
00246     i = 0;
00247     vector<uint16_t>::iterator iter = r.begin();
00248     while (i < mSize) {
00249         tmp = *(iter++);
00250 #ifdef LITTLEENDIAN
00251         mStrPostPad[i++] = tmp & 0xff;
00252         mStrPostPad[i++] = (tmp >> 8) & 0xff;
00253 #else
00254         mStrPostPad[i++] = (tmp >> 8) & 0xff;
00255         mStrPostPad[i++] = tmp & 0xff;
00256 #endif
00257     }
00258 }
00259 
00260 void
00261 SqlStringBufferUCS2::patternfill(
00262     uint start,
00263     uint lower,
00264     uint upper)
00265 {
00266     uint c = start;
00267     int i = 0;
00268 
00269     while (i < mSize) {
00270 #ifdef LITTLEENDIAN
00271         mStrPostPad[i++] = c & 0xff;
00272         mStrPostPad[i++] = (c >> 8) & 0xff;
00273 #else
00274         mStrPostPad[i++] = (c >> 8) & 0xff;
00275         mStrPostPad[i++] = c & 0xff;
00276 #endif
00277         if (++c > upper) {
00278             c = lower;
00279         }
00280     }
00281 }
00282 
00283 string
00284 SqlStringBufferUCS2::dump()
00285 {
00286     int i = 0;
00287     string ret;
00288     char buf[100];
00289 
00290     sprintf(
00291         buf, "DUMP: Storage=%d LeftBump=%d Size=%d RightBump=%d LP=%p Str=%p\n",
00292         mStorage, mLeftBump, mSize, mRightBump,
00293         mLeftP, mStr);
00294     ret += buf;
00295 
00296     i = 0;
00297     while (i < mTotal) {
00298         sprintf(
00299             buf,
00300             " %d:%x(%c)",
00301             i,
00302             mLeftP[i],
00303             (mLeftP[i] >= ' ' ? mLeftP[i] : '_'));
00304         ret += buf;
00305         i++;
00306     }
00307 
00308     ret += "\nLeft Bumper:\n";
00309     i = 0;
00310     while (i < mLeftBump) {
00311         sprintf(buf, "%d: 0x%x (%c)\n", i, mLeftP[i], mLeftP[i]);
00312         ret += buf;
00313         i++;
00314     }
00315 
00316     ret += "\nText:\n";
00317     i = 0;
00318     while (i < mStorage) {
00319         sprintf(
00320             buf, "%d: 0x%x (%c) 0x%x (%c)\n", i,
00321             mStr[i], (mStr[i] >= ' ' ? mStr[i] : '_'),
00322             mStr[i + 1], (mStr[i + 1] >= ' ' ? mStr[i + 1] : '_'));
00323         ret += buf;
00324         i += 2;
00325     }
00326 
00327     ret += "\nRight Bumper:\n";
00328     i = 0;
00329     while (i < mRightBump) {
00330         sprintf(
00331             buf, "%d: 0x%x (%c)\n", i, mStr[i + mStorage], mStr[i + mStorage]);
00332         ret += buf;
00333         i++;
00334     }
00335 
00336     return ret;
00337 }
00338 
00339 bool
00340 SqlStringBufferUCS2::equal(SqlStringBufferUCS2 const &other)
00341 {
00342     if (other.mTotal != mTotal) {
00343         return false;
00344     }
00345     if (memcmp(other.mLeftP, mLeftP, mTotal)) {
00346         return false;
00347     }
00348     return true;
00349 }
00350 
00351 // End SqlStringBuffer.cpp

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