Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members

SubString.C

Go to the documentation of this file.
00001 
00026 #include <string.h>
00027 
00028 #include "String.h"
00029 #include "SubString.h"
00030 
00043 SubString::operator String() const
00044 { 
00045   return this->string(); 
00046 }
00047 
00048 
00053 void SubString::rangeCheck(String &s, const size_t start, const size_t len)
00054      throw(std::out_of_range)
00055 {
00056   char *errMsg = 0;
00057   bool rangeError = false;
00058   size_t sLen = s.strlen();
00059   if (start >= sLen) {
00060     errMsg = "SubString: start >= String length";
00061     rangeError = true;
00062   }
00063   else if (start + len > sLen) {
00064     errMsg = "SubString: start + len >= String length";
00065     rangeError = true;
00066   }
00067 
00068   if (rangeError) {
00069     throw std::out_of_range( errMsg );
00070   }
00071 } // rangeCheck
00072 
00073 
00132 SubString::SubString( String &s, const size_t start, const size_t len )
00133           throw(std::out_of_range)
00134           : value( new SharedData() )
00135 {
00136   try {
00137     rangeCheck(s, start, len);
00138     size_t sLen = s.strlen();
00139     value->pStr( &s );
00140     value->start( start );
00141     value->subStrLen(len);
00142   }
00143   catch (std::out_of_range e) {
00144     throw e;
00145   }
00146 } // SubString constructor
00147 
00148 
00149 
00172 void SubString::createCopySpace(size_t start, size_t charsToCopy)
00173 {
00174     size_t subStrLen = value->subStrLen();
00175 
00176     if (charsToCopy != subStrLen) {
00177       size_t strlen = value->pStr()->strlen();
00178       if (charsToCopy < subStrLen) {
00179         // The end of the copy region will be start+charsToCopy
00180         // The end of the SubString section is start+subStrLen
00181         size_t dest = start+charsToCopy;
00182         for (size_t i = start+subStrLen; i < strlen; i++, dest++) {
00183           char ch = value->pStr()->read(i);
00184           value->pStr()->write(dest, ch );
00185         }
00186         size_t shrink = subStrLen - charsToCopy;
00187         size_t newLen = strlen - shrink;
00188         value->pStr()->resize( newLen );
00189       }
00190       else if (charsToCopy > subStrLen) {
00191         size_t expand = charsToCopy - subStrLen;
00192         size_t newLen = strlen + expand;
00193         value->pStr()->resize( newLen );
00194 
00195         size_t dest = newLen-1;
00196         for (int i = strlen-1; i >= (int)start; i--, dest--) {
00197           char ch = value->pStr()->read(i);
00198           value->pStr()->write(dest, ch );
00199         }
00200       }
00201     }
00202 } // createCopySpace
00203 
00207 String SubString::operator +(const char *Cstr)
00208 {
00209   String result = *this;
00210   if (Cstr != 0) {
00211     result += Cstr;
00212   }
00213   return result;
00214 }
00215 
00216 
00220 String SubString::operator +(const SubString& sub)
00221 {
00222   String s1 = *this;
00223   String s2 = sub;
00224   String result = s1 + s2;
00225   return result;
00226 }
00227 
00228 
00232 String SubString::operator +(const String &str)
00233 {
00234   String s1 = *this;
00235   String result = s1 + str;
00236   return result;
00237 }
00238 
00239 
00323 String SubString::operator =( const char *Cstr )
00324 {
00325   size_t charsToCopy;
00326 
00327   if (Cstr && (charsToCopy = ::strlen( Cstr)) > 0) {
00328     size_t start = value->start();
00329 
00330     // create a copy region that is the correct size
00331     createCopySpace( start, charsToCopy );
00332 
00333     size_t cnt = 0;
00334     for (size_t i = start; i < start + charsToCopy; i++, cnt++) {
00335       value->pStr()->write(i, Cstr[ cnt ] );
00336     }
00337   }
00338 
00339   //
00340   // C/C++ allows chained assignment, so one can do something like
00341   //
00342   //    String a = b(2,4) = "abcd";
00343   //
00344   // So the string that results from the substring assignment should
00345   // be returned.
00346   //
00347   String retStr( *(value->pStr()) );
00348 
00349   return retStr;
00350 } // operator = (Cstr)
00351 
00352 
00353 
00369 String SubString::operator =( String& str )
00370 {
00371   size_t charsToCopy;
00372 
00373   if ((charsToCopy = str.strlen()) > 0) {
00374     size_t start = value->start();
00375 
00376     // create a copy region that is the correct size
00377     createCopySpace(start, charsToCopy );
00378 
00379     if (value->pStr()) {
00380       size_t i, cnt;
00381       for (i = start, cnt = 0; i < start + charsToCopy; i++,cnt++) {
00382         value->pStr()->write(i, str[cnt]);
00383       }
00384     }
00385   }
00386 
00387   if (value->pStr())
00388     return *(value->pStr());
00389   else {
00390     String empty;
00391 
00392     return empty;
00393   }
00394 } // operator = (String)
00395 
00396 
00407 String SubString::operator =(const SubString& str )
00408 {
00409   // convert to a SubStr = String
00410   *this = str.string();
00411   return (*this).string();
00412 } // operator=
00413 
00414 
00415 
00430 String SubString::string() const
00431 {
00432   String retVal;
00433 
00434   if (value->pStr()) {
00435     size_t sLen = value->pStr()->strlen();
00436     size_t start = value->start();
00437     size_t subStrLen = value->subStrLen();
00438     size_t subStrEnd = start + subStrLen;
00439 
00440     for (size_t i = start; i < subStrEnd; i++) {
00441       retVal += (*(value->pStr()))[i];
00442     }
00443 
00444   }
00445   return retVal;
00446 } // SubString::string
00447 
00448 
00483 int SubString::compareTo( const char *CStr )
00484 {
00485   int result;
00486   const char *pThisCStr = *(value->pStr());
00487   if (pThisCStr == 0 && CStr == 0) {
00488     result = 0;
00489   } else if (pThisCStr == 0 && CStr != 0) {
00490     result = -1;
00491   } else if (pThisCStr != 0 && CStr == 0) {
00492     result = 1;
00493   } else { // both pThisCStr and CStr are non-NULL
00494     size_t subStrLen = value->subStrLen();
00495     size_t start = value->start();
00496     result = strncmp((pThisCStr + start), CStr, subStrLen);
00497     if (result == 0) {
00498       size_t CStrLen = strlen( CStr );
00499       if (CStrLen > subStrLen) {
00500         result = -1; // ThisCStr < CStr
00501       }
00502     }
00503   }
00504   return result;
00505 } // compareTo for const char *
00506 
00507 
00524 int SubString::compareTo( String &s )
00525 {
00526   const char *pCStr = s;
00527   return compareTo( pCStr );
00528 } // compareTo for String
00529 
00530 
00531 
00541 int SubString::compareTo( SubString &subStr)
00542 {
00543   int result;
00544   const char *pThisCStr = *(value->pStr());
00545   const char *pRhsCStr = *(subStr.value->pStr());
00546 
00547   // The Strings in both SubStrings are NULL
00548   if (pThisCStr == 0 && pRhsCStr == 0) {
00549     result = 0;
00550   }
00551   else if (pThisCStr != 0 && pRhsCStr == 0) {
00552     result = 1;
00553   }
00554   else if (pThisCStr == 0 && pRhsCStr != 0) {
00555     result = -1;
00556   }
00557   else {
00558     size_t thisLen = value->subStrLen();
00559     size_t rhsLen = subStr.value->subStrLen();
00560     size_t compareLen = thisLen;
00561     if (compareLen > rhsLen) {
00562       compareLen = rhsLen;
00563     }
00564     size_t thisStart = value->start();
00565     size_t rhsStart = subStr.value->start();
00566 
00567     result = strncmp( pThisCStr+thisStart,
00568                       pRhsCStr+rhsStart,
00569                       compareLen );
00570     if (result == 0) {
00571       if (thisLen < rhsLen) {
00572         result = -1;
00573       }
00574       else if (thisLen > rhsLen) {
00575         result = 1;
00576       }
00577     }
00578   }
00579   return result;
00580 } // compareTo for SubString
00581 
00582 
00583 //
00584 // Global Operators
00585 //
00586 
00587 bool operator ==(const char *Cstr, SubString s)
00588 {
00589   return (s == Cstr);
00590 } // global operator ==
00591 
00592  
00593 bool operator !=(const char *Cstr, SubString s)
00594 {
00595   return (s != Cstr);
00596 } // global operator !=
00597 
00598 
00599 bool operator <=(const char *Cstr, SubString s)
00600 {
00601   return (s >= Cstr);
00602 } // global operator <=
00603 
00604 
00605 bool operator >=(const char *Cstr, SubString s)
00606 {
00607   return (s <= Cstr);
00608 } // global operator >=
00609 
00610 bool operator <(const char *Cstr, SubString s)
00611 {
00612   return (s > Cstr);
00613 } // global operator <
00614 
00615 bool operator >(const char *Cstr, SubString s)
00616 {
00617   return (s < Cstr);
00618 } // global operator >

Generated on Mon Sep 22 20:22:58 2003 by doxygen 1.3.3