Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/BdbUtil/BdbTString.cc

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: BdbTString.cc,v 1.4 2001/11/20 01:57:02 becla Exp $
00004 //
00005 // Description:
00006 //      "BdbTString" extends the Objectivity "ooVString" by adding some
00007 //      of the usual features of a string class, like the concatenation
00008 //      operators and soon...
00009 //
00010 // Nature:
00011 //      Transient class;
00012 //
00013 // Environment:
00014 //      Software developed for the BaBar Detector at the SLAC B-Factory.
00015 //
00016 // Author List:
00017 //      Jean-Noel Albert    LAL/SLAC    Nov 1997        Original Author
00018 //------------------------------------------------------------------------
00019 
00020 //----------------
00021 // Class Header --
00022 //----------------
00023 // Note: Must be the first header loaded by the class implementation
00024 
00025 #include "BdbUtil/BdbTString.hh"
00026 
00027 //-------------
00028 // C Headers --
00029 //-------------
00030 
00031 extern "C" {
00032 #include <stdlib.h>
00033 #include <string.h>
00034 }
00035 
00036 //-----------------
00037 // BaBar headers --
00038 //-----------------
00039 #include "BdbUtil/BdbUtilErrors.hh"
00040 
00041 //----------------
00042 // Constructors --
00043 //----------------
00044 
00045 // Default constructor - used for the BdbStringArray
00046 BdbTString::BdbTString()
00047 {
00048     _string = "";
00049 }
00050 
00051 // Copy constructor - build a new string from an existing one
00052 BdbTString::BdbTString(const BdbTString& value)
00053 {
00054     _string = value;
00055 }
00056 
00057 // Conversion constructors - build a string from an existing
00058 // persistent string (d_String) or a C string.
00059 BdbTString::BdbTString(const d_String& value)
00060 {
00061     if (value.head() == 0)
00062         _string = "";
00063     else
00064         _string = value;
00065 }
00066 
00067 BdbTString::BdbTString(const char* value)
00068 {
00069     if (value == NULL)
00070         _string = "";           // CAUTION: NULL is not 0 !!
00071     else
00072         _string = value;
00073 }
00074 
00075 // Conversion constructor - build a string from an integer
00076 // CAUTION: *0* is not *NULL* !
00077 //          affecting *0* to a string creates a string "O";
00078 //          affecting *NULL* creates an empty string ("").
00079 BdbTString::BdbTString(int value)
00080 {
00081     if (value == 0)
00082         _string = "0";          // CAUTION: 0 is not NULL !!
00083     else {
00084         char svalue[32];
00085         sprintf(svalue, "%d", value);
00086         _string = svalue;
00087     }
00088 }
00089 
00090 // Concatenation constructor - allow to build a string
00091 // from a lot of partial strings. Principally useful
00092 // to supply the concatenation operator (+) for C strings
00093 // and integers.
00094 // Example: 
00095 //          char* home = getenv("HOME")
00096 //          BdbString test = BdbString(home, "/test.log");
00097 //  (you can write: test = home + "/test.log" because
00098 //   "+" can't be defined for 2 C strings.)
00099 BdbTString::BdbTString(const BdbTString& s0, const BdbTString& s1,
00100                        const BdbTString& s2, const BdbTString& s3, 
00101                        const BdbTString& s4, const BdbTString& s5,
00102                        const BdbTString& s6, const BdbTString& s7,
00103                        const BdbTString& s8, const BdbTString& s9,
00104                        const BdbTString& s10, const BdbTString& s11)
00105 {
00106     (*this) = s0;
00107     (*this) += s1;
00108     (*this) += s2;
00109     (*this) += s3;
00110     (*this) += s4;
00111     (*this) += s5;
00112     (*this) += s6;
00113     (*this) += s7;
00114     (*this) += s8;
00115     (*this) += s9;
00116     (*this) += s10;
00117     (*this) += s11;
00118 }
00119 
00120 // Destructor
00121 BdbTString::~BdbTString()
00122 {}
00123 
00124 // Affectations
00125 BdbTString& BdbTString::operator= (const BdbTString& value)
00126 {
00127     _string = value._string;
00128     return *this;
00129 }
00130 
00131 BdbTString& BdbTString::operator= (const d_String& value)
00132 {
00133     if (value.head() == 0)
00134         _string = "";
00135     else
00136         _string = value;
00137     return *this;
00138 }
00139 
00140 BdbTString& BdbTString::operator= (const char* value)
00141 {
00142     if (value == NULL)
00143         _string = "";                   // CAUTION: NULL is not 0 !!
00144     else
00145         _string = value;
00146     return *this;
00147 }
00148 
00149 BdbTString& BdbTString::operator= (int value)
00150 {
00151     _string = BdbTString(value);
00152     return *this;
00153 }
00154 
00155 // Auto-concatenations
00156 BdbTString& BdbTString::operator+= (const BdbTString& value)
00157 {
00158     _string += value._string;
00159     return *this;
00160 }
00161 
00162 BdbTString& BdbTString::operator+= (const d_String& value)
00163 {
00164     if (value.head() != 0)
00165         _string += value;
00166     return *this;
00167 }
00168 
00169 BdbTString& BdbTString::operator+= (const char* value)
00170 {
00171     if (value != NULL)
00172         _string += value;
00173     return *this;
00174 }
00175 
00176 // Modifiers: some developers prefer to avoid the "operator="
00177 void BdbTString::set(const BdbTString& value)
00178 {
00179     _string = value;
00180 }
00181 
00182 void BdbTString::set(const d_String& value)
00183 {
00184     _string = value;
00185 }
00186 
00187 void BdbTString::set(const char* value)
00188 {
00189     _string = value;
00190 }
00191 
00192 void BdbTString::set(int value)
00193 {
00194     _string = BdbTString(value);
00195 }
00196 
00197 // Length of the string
00198 int BdbTString::length() const
00199 {
00200     return _string.length();
00201 }
00202 
00203 // Converters - automatically called to convert a string
00204 //  to the specified type
00205 BdbTString::operator const char*() const
00206 {
00207     return _string.head();
00208 }
00209 
00210 BdbTString::operator int() const
00211 {
00212     return atoi(data());
00213 }
00214 
00215 // Accessors: return the value of the string.
00216 // Principally used to force the conversion of a string
00217 // to a "const char*". Useful with some older C++ compilers.
00218 // "chars" is GNU-compatible, "data" is STL-compatible.
00219 const char* BdbTString::chars() const
00220 {
00221     return _string.head();
00222 }
00223 
00224 const char* BdbTString::data() const
00225 {
00226     return _string.head();
00227 }
00228 
00229 // Locators: returns the index of the first character
00230 //          of the substring in the string.
00231 //
00232 // Note on the indexes: 
00233 //  * 0 means the first character of the string (C convention;
00234 //  * 1 is the second character;
00235 //  * -1 means the *last* character of the string !
00236 //  * -2 is the previous one...
00237 int BdbTString::position(char c, int index) const
00238 {
00239     if (abs(index) > length())
00240         return -1;
00241 
00242     int position;
00243     const char* str;
00244 
00245     if (index >= 0) {
00246         position = index;
00247         str = data() + position;
00248         int len = length();
00249         while ((position < len) && (*str != c)) {
00250             str++; position++;
00251         }
00252     }
00253     else {
00254         position = length() + index;
00255         str = data() + position;
00256         while ((position >= 0) && (*str != c)) {
00257             str--; position--;
00258         }
00259     }
00260 
00261     if (*str != c)
00262         return -1;
00263 
00264     return position;
00265 }
00266 
00267 int BdbTString::position(const BdbTString& s, int index) const
00268 {
00269     if (abs(index) > length())
00270         return -1;
00271 
00272     const char* ps = s.data();
00273     int slen = s.length();
00274     int position;
00275     const char* str;
00276 
00277     if (index > 0) {
00278         position = index;
00279         str = data() + position;
00280         int len = length();
00281 
00282         for (; position < len; str++, position++)
00283             if ((*str == *ps) && (strncmp(str, ps, slen) == 0))
00284                 return position;
00285     }
00286     else {
00287         position = length() + index;
00288         str = data() + position;
00289 
00290         for (; position >= 0; str--, position--)
00291             if ((*str == *ps) && (strncmp(str, ps, slen) == 0))
00292                 return position;
00293     }
00294 
00295     return -1;
00296 }
00297 
00298 // Indexed accessors: 2 operators are defined,
00299 // one for the `lhs' (affectation) and one for the `rhs'
00300 // (const). Most of the compilers are now able to understand
00301 // the differences...
00302 char BdbTString::operator[] (int index) const
00303 {
00304     if (abs(index) > length())
00305         return '\0';
00306 
00307     if (index < 0)
00308         index = length() + index;
00309 
00310     return *(data() + index);
00311 }
00312 
00313 char BdbTString::operator[] (int index)
00314 {
00315     // The only way to recover an invalid access to a string
00316     // is to throw an exception...
00317     // (sorry)
00318     if (abs(index) > length())
00319         BdbSignal(BdbcFatalError, BdbUtilErrBadIndex, 0,
00320                   "BdbTString::operator[]", index, length());
00321 
00322     if (index < 0)
00323         index = length() + index;
00324 
00325     return *((char*)(data()) + index);
00326 }
00327 
00328 // Return the substring starting at the "index" position,
00329 //  up to the specified length. By default, return all the
00330 //  end of the string.
00331 BdbTString BdbTString::at(int index, int len) const
00332 {
00333     if (abs(index) > length())
00334         return "";
00335 
00336     if (index < 0)
00337         index = length() + index;
00338 
00339     if ((len < 0) || (len + index) > length())
00340         len = length() - index;
00341 
00342     char* str = new char[len];
00343     memcpy(str, (data() + index), len);
00344     str[len] = '\0';
00345 
00346     BdbTString bs = str;
00347     delete[] str;
00348 
00349     return bs;
00350 }
00351 
00352 // Return the substring starting at the position specified,
00353 //  to the end of the string. If the position is specified
00354 //  by a substring the copy starts after the last character
00355 //  of this substring.
00356 // If the substring does not exist, an empty string ("")
00357 // is returned.
00358 BdbTString BdbTString::after (int index) const
00359 {
00360     if (index < 0)
00361         index = length() + index;
00362     return at(index + 1);
00363 }
00364 
00365 BdbTString BdbTString::after (char c, int index) const
00366 {
00367     int pos = position(c, index);
00368     if (pos < 0)
00369         return "";
00370     else
00371         return after(pos);
00372 }
00373 
00374 BdbTString BdbTString::after (const BdbTString& s, int index) const
00375 {
00376     int pos = position(s, index) + s.length();
00377     if (pos < 0)
00378         return "";
00379     else
00380         return after(pos);
00381 }
00382 
00383 // Return the substring starting of the beginning of the string
00384 //  to the position specified by the index or the substring.
00385 // If the substring does not exist, return an empty string ("").
00386 BdbTString BdbTString::before (int index) const
00387 {
00388     if (index < 0)
00389         index = length() + index;
00390     return at(0, index);
00391 }
00392 
00393 BdbTString BdbTString::before (char c, int index) const
00394 {
00395     int pos = position(c, index);
00396     if (pos < 0)
00397         return "";
00398     else
00399         return before(pos);
00400 }
00401 
00402 BdbTString BdbTString::before (const BdbTString& s, int index) const
00403 {
00404     int pos = position(s, index);
00405     if (pos < 0)
00406         return "";
00407     else
00408         return before(pos);
00409 }
00410 
00411 // Comparison between string and values
00412 int BdbTString::strcmp(const BdbTString& s1, const BdbTString& s2)
00413 {
00414     const char* h1 = s1._string.head();
00415     const char* h2 = s2._string.head();
00416     if (((h1 == 0) || (*h1 == '\0')) && ((h2 == 0) || (*h2 == '\0')))
00417         return 0;
00418     else if ((h1 == 0) || (*h1 == '\0'))
00419         return 1;
00420     else if ((h2 == 0) || (*h2 == '\0'))
00421         return -1;
00422     else
00423         return ::strcmp(h1, h2);
00424 }
00425 
00426 int BdbTString::strcmp(const BdbTString& str, const char* txt)
00427 {
00428     const char* hd = str._string.head();
00429     if (((hd == 0) || (*hd == '\0')) && ((txt == 0) || (*txt == '\0')))
00430         return 0;
00431     else if ((hd == 0) || (*hd == '\0'))
00432         return 1;
00433     else if ((txt == 0) || (*txt == '\0'))
00434         return -1;
00435     else
00436         return ::strcmp(hd, txt);
00437 }
00438 
00439 int BdbTString::strcmp(const char* txt, const BdbTString& str)
00440 {
00441     const char* hd = str._string.head();
00442     if (((txt == 0) || (*txt == '\0')) && ((hd == 0) || (*hd == '\0')))
00443         return 0;
00444     else if ((txt == 0) || (*txt == '\0'))
00445         return 1;
00446     else if ((hd == 0) || (*hd == '\0'))
00447         return -1;
00448     else
00449         return ::strcmp(txt, hd);
00450 }
00451 
00452 ostream& operator<< (ostream& s, const BdbTString& str)
00453 {
00454     s << str._string.head();
00455     return s;
00456 }
00457 
00458 istream& operator>> (istream& s, const BdbTString& str)
00459 {
00460     s >> str._string;
00461     return s;
00462 }
00463 
00464 //////////////////////////////////////////////////////////////
00465 
00466 //-----------------
00467 // Concatenation --
00468 //-----------------
00469 
00470 BdbTString operator + (const BdbTString& s1, const BdbTString& s2)
00471 {
00472     BdbTString temp = s1;
00473     temp += s2;
00474     return temp;
00475 }
00476 
00477 BdbTString operator + (const BdbTString& str, const char* txt)
00478 {
00479     BdbTString temp = str;
00480     temp += txt;
00481     return temp;
00482 }
00483 
00484 BdbTString operator + (const char* txt, const BdbTString& str)
00485 {
00486     BdbTString temp = txt;
00487     temp += str;
00488     return temp;
00489 }
00490 
00491 //--------------
00492 // Comparison --
00493 //--------------
00494 
00495 int operator == (const BdbTString& s1, const BdbTString& s2)
00496 {
00497     return BdbTString::strcmp(s1, s2) == 0;
00498 }
00499 
00500 int operator != (const BdbTString& s1, const BdbTString& s2)
00501 {
00502     return BdbTString::strcmp(s1, s2) != 0;
00503 }
00504 
00505 int operator >  (const BdbTString& s1, const BdbTString& s2)
00506 {
00507     return BdbTString::strcmp(s1, s2) > 0;
00508 }
00509 
00510 int operator >= (const BdbTString& s1, const BdbTString& s2)
00511 {
00512     return BdbTString::strcmp(s1, s2) >= 0;
00513 }
00514 
00515 int operator <  (const BdbTString& s1, const BdbTString& s2)
00516 {
00517     return BdbTString::strcmp(s1, s2) < 0;
00518 }
00519 
00520 int operator <= (const BdbTString& s1, const BdbTString& s2)
00521 {
00522     return BdbTString::strcmp(s1, s2) <= 0;
00523 }
00524 
00525 int operator == (const BdbTString& str, const char* txt)
00526 {
00527     return BdbTString::strcmp(str, txt) == 0;
00528 }
00529 
00530 int operator != (const BdbTString& str, const char* txt)
00531 {
00532     return BdbTString::strcmp(str, txt) != 0;
00533 }
00534 
00535 int operator >  (const BdbTString& str, const char* txt)
00536 {
00537     return BdbTString::strcmp(str, txt) > 0;
00538 }
00539 
00540 int operator >= (const BdbTString& str, const char* txt)
00541 {
00542     return BdbTString::strcmp(str, txt) >= 0;
00543 }
00544 
00545 int operator <  (const BdbTString& str, const char* txt)
00546 {
00547     return BdbTString::strcmp(str, txt) < 0;
00548 }
00549 
00550 int operator <= (const BdbTString& str, const char* txt)
00551 {
00552     return BdbTString::strcmp(str, txt) <= 0;
00553 }
00554 
00555 int operator == (const char* txt, const BdbTString& str)
00556 {
00557     return BdbTString::strcmp(txt, str) == 0;
00558 }
00559 
00560 int operator != (const char* txt, const BdbTString& str)
00561 {
00562     return BdbTString::strcmp(txt, str) != 0;
00563 }
00564 
00565 int operator >  (const char* txt, const BdbTString& str)
00566 {
00567     return BdbTString::strcmp(txt, str) > 0;
00568 }
00569 
00570 int operator >= (const char* txt, const BdbTString& str)
00571 {
00572     return BdbTString::strcmp(txt, str) >= 0;
00573 }
00574 
00575 int operator <  (const char* txt, const BdbTString& str)
00576 {
00577     return BdbTString::strcmp(txt, str) < 0;
00578 }
00579 
00580 int operator <= (const char* txt, const BdbTString& str)
00581 {
00582     return BdbTString::strcmp(txt, str) <= 0;
00583 }

 


BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us

Page Owner: Jacek Becla
Last Update: October 04, 2002