Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Search  

C:/temp/src/j2k/Beta/GString.h

Go to the documentation of this file.
00001 /*
00002 http://www.cygnus.com/~manfredh/libgxx/libg++-2.8.1.3.tar.gz
00003 http://www.europe.redhat.com/documentation/HOWTO/C++Programming-HOWTO-15.php3
00004 http://www.mike95.com/c_plusplus/classes/JString/
00005 
00006 This new version of JString 
00007 is an enhanced and more optimized version 
00008 based on libg++ 2.8.1.3 string algorithm
00009 which is also LGPL licensed.
00010 
00011 Copyright (C) 1988 Free Software Foundation - LGPL licensed.
00012 written by Doug Lea (dl@rocky.oswego.edu)
00013 
00014 Refer to license.txt for the complete LGPL license documentation.
00015 */
00016 
00017 #include <j2k/Fred/fast_alloc.c>
00018 
00019  /* Internal String representations */
00020 typedef struct _JString_t   
00021 {
00022   size_t   bufferSize;   /* Allocated Buffer Space                         */
00023   size_t   length;       /* The Actual String Length                       */
00024   short    nbRefs;       /* Reference Counter                              */
00025   char     lock;         /* Lock, if direct access (CString compatibility) */
00026 
00027   char     data[1];      /* The string is at least '\0', so one null byte  */
00028                          /* It must be allocated/expanded via realloc()    */
00029 } JString_t;
00030 
00031 
00032 typedef struct _JSubString_t
00033 {
00034   size_t         pos;    /* Starting position of the string in rep         */
00035   size_t         len;    /* Length of the substring                        */
00036   JString_t*     str;    /* The String I'm a substring of                  */
00037  _JSubString_t*  next;   /* For a link-list of JString parts...            */
00038 
00039 } JSubString_t;
00040 
00041 #define JSTRING_SIZE     ( sizeof( JString_t    ) )
00042 #define JSUBSTRING_SIZE  ( sizeof( JSubString_t ) )
00043 
00044 #define JSTRING_INIT     { 0, 0, 1, 0, { 0 } }
00045 #define JSUBSTRING_INIT  { 0, 0, 0, 0 }
00046 
00047 
00048 /* Primitive operations on JString_t -- nearly all JString functions use those. */
00049 
00050 JString_t* JString_malloc( register size_t  buffer_size )
00051 {
00052   buffer_size += sizeof( JString_t );
00053   return (JString_t*)fast_malloc( buffer_size );
00054 }
00055 
00056 JString_t* JString_calloc( register size_t  buffer_size )
00057 {
00058   buffer_size += sizeof( JString_t );
00059   JString_t* s = (JString_t*)fast_malloc( buffer_size );
00060   memset( s, 0, buffer_size );
00061   s->nbRefs = 1;
00062   return s;
00063 }
00064 
00065 void JString_free( JString_t* this )
00066 {
00067   /* delete if not used and unlock */
00068   if( --this->nbRefs <= 0  &&  this->lock == 0 )
00069   {
00070     free( this );
00071   }
00072 }
00073 
00074 /* GOTCHA: We assume length is passed as: strlen( str ) if unknown */
00075 JString_t* JString_create( const char* str, register size_t length, register size_t  buffer_size )
00076 {
00077   /* Make sure the buffer size is at least the length */
00078   if ( buffer_size < length ) 
00079   {
00080     buffer_size = length;
00081   }
00082 
00083   JString_t* s = JString_calloc( buffer_size );
00084 
00085   if ( str != NULL )
00086   {
00087     memcpy( s->data, str, length );
00088   }
00089 
00090   return s;
00091 }
00092 
00093 JString_t* JString_safe_create( const char* str )
00094 {
00095   return JString_create( str, strlen( str ), 80 ); 
00096 }
00097 
00098 
00099 const char* str, size_t length, 
00100 
00101 JString_t*, const char*, int, int);
00102 JString_t*     JString_copy(       JString_t*, const JString_t* );
00103 JString_t*     JString_cat(        JString_t*, const char*, int, const char*, int);
00104 JString_t*     JString_cat(        JString_t*, const char*, int, const char*, int, const char*, int );
00105 JString_t*     JString_prepend(    JString_t*, const char*, int );
00106 JString_t*     JString_reverse(    const JString_t*, JString_t* );
00107 JString_t*     JString_upcase(     const JString_t*, JString_t* );
00108 JString_t*     JString_downcase(   const JString_t*, JString_t* );
00109 JString_t*     JString_capitalize( const JString_t*, JString_t* );
00110 
00111 // These classes need to be defined in the order given
00112 
00113 class String;
00114 class SubString;
00115 
00116 class SubString
00117 {
00118   friend class      String;
00119 protected:
00120 
00121   String&           S;        // The String I'm a substring of
00122   unsigned short    pos;      // starting position in S's rep
00123   unsigned short    len;      // length of substring
00124 
00125   void              assign(const JString_t*, const char*, int = -1);
00126                     SubString(String& x, int p, int l);
00127                     SubString(const SubString& x);
00128 
00129 public:
00130 
00131 // Note there are no public constructors. SubStrings are always
00132 // created via String operations
00133 
00134                    ~SubString();
00135 
00136   SubString&        operator =  (const String&     y);
00137   SubString&        operator =  (const SubString&  y);
00138   SubString&        operator =  (const char* t);
00139   SubString&        operator =  (char        c);
00140 
00141 // return 1 if target appears anywhere in SubString; else 0
00142 
00143   int               contains(char        c) const;
00144   int               contains(const String&     y) const;
00145   int               contains(const SubString&  y) const;
00146   int               contains(const char* t) const;
00147   int               contains(const Regex&       r) const;
00148 
00149 // return 1 if target matches entire SubString
00150 
00151   int               matches(const Regex&  r) const;
00152 
00153 // IO 
00154 
00155   friend ostream&   operator<<(ostream& s, const SubString& x);
00156 
00157 // status
00158 
00159   unsigned int      length() const;
00160   int               empty() const;
00161   const char*       chars() const;
00162 
00163   int               OK() const; 
00164 
00165 };
00166 
00167 
00168 class String
00169 {
00170   friend class      SubString;
00171 
00172 protected:
00173   JString_t*           rep;   // Strings are pointers to their representations
00174 
00175 // some helper functions
00176 
00177   int               search(int, int, const char*, int = -1) const;
00178   int               search(int, int, char) const;
00179   int               match(int, int, int, const char*, int = -1) const;
00180   int               _gsub(const char*, int, const char* ,int);
00181   int               _gsub(const Regex&, const char*, int);
00182   SubString         _substr(int, int);
00183 
00184 public:
00185 
00186 // constructors & assignment
00187 
00188                     String();
00189                     String(const String& x);
00190                     String(const SubString&  x);
00191                     String(const char* t);
00192                     String(const char* t, int len);
00193                     String(char c);
00194 
00195                     ~String();
00196 
00197   String&           operator =  (const String&     y);
00198   String&           operator =  (const char* y);
00199   String&           operator =  (char        c);
00200   String&           operator =  (const SubString&  y);
00201 
00202 // concatenation
00203 
00204   String&           operator += (const String&     y); 
00205   String&           operator += (const SubString&  y);
00206   String&           operator += (const char* t);
00207   String&           operator += (char        c);
00208 
00209   void              prepend(const String&     y); 
00210   void              prepend(const SubString&  y);
00211   void              prepend(const char* t);
00212   void              prepend(char        c);
00213 
00214 
00215 // procedural versions:
00216 // concatenate first 2 args, store result in last arg
00217 
00218   friend inline void     cat(const String&, const String&, String&);
00219   friend inline void     cat(const String&, const SubString&, String&);
00220   friend inline void     cat(const String&, const char*, String&);
00221   friend inline void     cat(const String&, char, String&);
00222 
00223   friend inline void     cat(const SubString&, const String&, String&);
00224   friend inline void     cat(const SubString&, const SubString&, String&);
00225   friend inline void     cat(const SubString&, const char*, String&);
00226   friend inline void     cat(const SubString&, char, String&);
00227 
00228   friend inline void     cat(const char*, const String&, String&);
00229   friend inline void     cat(const char*, const SubString&, String&);
00230   friend inline void     cat(const char*, const char*, String&);
00231   friend inline void     cat(const char*, char, String&);
00232 
00233 // double concatenation, by request. (yes, there are too many versions, 
00234 // but if one is supported, then the others should be too...)
00235 // Concatenate first 3 args, store in last arg
00236 
00237   friend inline void     cat(const String&,const String&, const String&,String&);
00238   friend inline void     cat(const String&,const String&,const SubString&,String&);
00239   friend inline void     cat(const String&,const String&, const char*, String&);
00240   friend inline void     cat(const String&,const String&, char, String&);
00241   friend inline void     cat(const String&,const SubString&,const String&,String&);
00242   inline friend void     cat(const String&,const SubString&,const SubString&,String&);
00243   friend inline void     cat(const String&,const SubString&, const char*, String&);
00244   friend inline void     cat(const String&,const SubString&, char, String&);
00245   friend inline void     cat(const String&,const char*, const String&,    String&);
00246   friend inline void     cat(const String&,const char*, const SubString&, String&);
00247   friend inline void     cat(const String&,const char*, const char*, String&);
00248   friend inline void     cat(const String&,const char*, char, String&);
00249 
00250   friend inline void     cat(const char*, const String&, const String&,String&);
00251   friend inline void     cat(const char*,const String&,const SubString&,String&);
00252   friend inline void     cat(const char*,const String&, const char*, String&);
00253   friend inline void     cat(const char*,const String&, char, String&);
00254   friend inline void     cat(const char*,const SubString&,const String&,String&);
00255   friend inline void     cat(const char*,const SubString&,const SubString&,String&);
00256   friend inline void     cat(const char*,const SubString&, const char*, String&);
00257   friend inline void     cat(const char*,const SubString&, char, String&);
00258   friend inline void     cat(const char*,const char*, const String&,    String&);
00259   friend inline void     cat(const char*,const char*, const SubString&, String&);
00260   friend inline void     cat(const char*,const char*, const char*, String&);
00261   friend inline void     cat(const char*,const char*, char, String&);
00262 
00263 
00264 // searching & matching
00265 
00266 // return position of target in string or -1 for failure
00267 
00268   int               index(char        c, int startpos = 0) const;      
00269   int               index(const String&     y, int startpos = 0) const;      
00270   int               index(const SubString&  y, int startpos = 0) const;      
00271   int               index(const char* t, int startpos = 0) const;  
00272   int               index(const Regex&      r, int startpos = 0) const;       
00273 
00274 // return 1 if target appears anyhere in String; else 0
00275 
00276   int               contains(char        c) const;
00277   int               contains(const String&     y) const;
00278   int               contains(const SubString&  y) const;
00279   int               contains(const char* t) const;
00280   int               contains(const Regex&      r) const;
00281 
00282 // return 1 if target appears anywhere after position pos 
00283 // (or before, if pos is negative) in String; else 0
00284 
00285   int               contains(char        c, int pos) const;
00286   int               contains(const String&     y, int pos) const;
00287   int               contains(const SubString&  y, int pos) const;
00288   int               contains(const char* t, int pos) const;
00289   int               contains(const Regex&      r, int pos) const;
00290 
00291 // return 1 if target appears at position pos in String; else 0
00292 
00293   int               matches(char        c, int pos = 0) const;
00294   int               matches(const String&     y, int pos = 0) const;
00295   int               matches(const SubString&  y, int pos = 0) const;
00296   int               matches(const char* t, int pos = 0) const;
00297   int               matches(const Regex&      r, int pos = 0) const;
00298 
00299 //  return number of occurences of target in String
00300 
00301   int               freq(char        c) const; 
00302   int               freq(const String&     y) const;
00303   int               freq(const SubString&  y) const;
00304   int               freq(const char* t) const;
00305 
00306 // SubString extraction
00307 
00308 // Note that you can't take a substring of a const String, since
00309 // this leaves open the possiblility of indirectly modifying the
00310 // String through the SubString
00311 
00312   SubString         at(int         pos, int len);
00313   SubString         operator () (int         pos, int len); // synonym for at
00314 
00315   SubString         at(const String&     x, int startpos = 0); 
00316   SubString         at(const SubString&  x, int startpos = 0); 
00317   SubString         at(const char* t, int startpos = 0);
00318   SubString         at(char        c, int startpos = 0);
00319   SubString         at(const Regex&      r, int startpos = 0); 
00320 
00321   SubString         before(int          pos);
00322   SubString         before(const String&      x, int startpos = 0);
00323   SubString         before(const SubString&   x, int startpos = 0);
00324   SubString         before(const char*  t, int startpos = 0);
00325   SubString         before(char         c, int startpos = 0);
00326   SubString         before(const Regex&       r, int startpos = 0);
00327 
00328   SubString         through(int          pos);
00329   SubString         through(const String&      x, int startpos = 0);
00330   SubString         through(const SubString&   x, int startpos = 0);
00331   SubString         through(const char*  t, int startpos = 0);
00332   SubString         through(char         c, int startpos = 0);
00333   SubString         through(const Regex&       r, int startpos = 0);
00334 
00335   SubString         from(int          pos);
00336   SubString         from(const String&      x, int startpos = 0);
00337   SubString         from(const SubString&   x, int startpos = 0);
00338   SubString         from(const char*  t, int startpos = 0);
00339   SubString         from(char         c, int startpos = 0);
00340   SubString         from(const Regex&       r, int startpos = 0);
00341 
00342   SubString         after(int         pos);
00343   SubString         after(const String&     x, int startpos = 0);
00344   SubString         after(const SubString&  x, int startpos = 0);
00345   SubString         after(const char* t, int startpos = 0);
00346   SubString         after(char        c, int startpos = 0);
00347   SubString         after(const Regex&      r, int startpos = 0);
00348 
00349 
00350 // deletion
00351 
00352 // delete len chars starting at pos
00353   void              del(int         pos, int len);
00354 
00355 // delete the first occurrence of target after startpos
00356 
00357   void              del(const String&     y, int startpos = 0);
00358   void              del(const SubString&  y, int startpos = 0);
00359   void              del(const char* t, int startpos = 0);
00360   void              del(char        c, int startpos = 0);
00361   void              del(const Regex&      r, int startpos = 0);
00362 
00363 // global substitution: substitute all occurrences of pat with repl
00364 
00365   int               gsub(const String&     pat, const String&     repl);
00366   int               gsub(const SubString&  pat, const String&     repl);
00367   int               gsub(const char* pat, const String&     repl);
00368   int               gsub(const char* pat, const char* repl);
00369   int               gsub(const Regex&      pat, const String&     repl);
00370 
00371 // friends & utilities
00372 
00373 // split string into array res at separators; return number of elements
00374 
00375   friend int        split(const String& x, String res[], int maxn, 
00376                           const String& sep);
00377   friend int        split(const String& x, String res[], int maxn, 
00378                           const Regex&  sep);
00379 
00380   friend String     common_prefix(const String& x, const String& y, 
00381                                   int startpos = 0);
00382   friend String     common_suffix(const String& x, const String& y, 
00383                                   int startpos = -1);
00384   friend String     replicate(char        c, int n);
00385   friend String     replicate(const String&     y, int n);
00386   friend String     join(String src[], int n, const String& sep);
00387 
00388 // simple builtin transformations
00389 
00390   friend inline String     reverse(const String& x);
00391   friend inline String     upcase(const String& x);
00392   friend inline String     downcase(const String& x);
00393   friend inline String     capitalize(const String& x);
00394 
00395 // in-place versions of above
00396 
00397   void              reverse();
00398   void              upcase();
00399   void              downcase();
00400   void              capitalize();
00401 
00402 // element extraction
00403 
00404   char&             operator [] (int i);
00405   const char&       operator [] (int i) const;
00406   char              elem(int i) const;
00407   char              firstchar() const;
00408   char              lastchar() const;
00409 
00410 // conversion
00411 
00412                     operator const char*() const;
00413   const char*       chars() const;
00414 
00415 
00416 // IO
00417 
00418   friend inline ostream&   operator<<(ostream& s, const String& x);
00419   friend ostream&   operator<<(ostream& s, const SubString& x);
00420   friend istream&   operator>>(istream& s, String& x);
00421 
00422   friend int        readline(istream& s, String& x, 
00423                              char terminator = '\n',
00424                              int discard_terminator = 1);
00425 
00426 // status
00427 
00428   unsigned int      length() const;
00429   int               empty() const;
00430 
00431 // preallocate some space for String
00432   void              alloc(int newsize);
00433 
00434 // report current allocation (not length!)
00435 
00436   int               allocation() const;
00437 
00438 
00439   void     error(const char* msg) const;
00440 
00441   int               OK() const;
00442 };
00443 
00444 typedef String StrTmp; // for backward compatibility
00445 
00446 // other externs
00447 
00448 int        compare(const String&    x, const String&     y);
00449 int        compare(const String&    x, const SubString&  y);
00450 int        compare(const String&    x, const char* y);
00451 int        compare(const SubString& x, const String&     y);
00452 int        compare(const SubString& x, const SubString&  y);
00453 int        compare(const SubString& x, const char* y);
00454 int        fcompare(const String&   x, const String&     y); // ignore case
00455 
00456 extern StrRep  _nilStrRep;
00457 extern String _nilString;
00458 
00459 // status reports, needed before defining other things
00460 
00461 inline unsigned int String::length() const {  return rep->len; }
00462 inline int         String::empty() const { return rep->len == 0; }
00463 inline const char* String::chars() const { return &(rep->s[0]); }
00464 inline int         String::allocation() const { return rep->sz; }
00465 
00466 inline unsigned int SubString::length() const { return len; }
00467 inline int         SubString::empty() const { return len == 0; }
00468 inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
00469 
00470 
00471 // constructors
00472 
00473 inline String::String() 
00474   : rep(&_nilStrRep) {}
00475 inline String::String(const String& x) 
00476   : rep(Scopy(0, x.rep)) {}
00477 inline String::String(const char* t) 
00478   : rep(Salloc(0, t, -1, -1)) {}
00479 inline String::String(const char* t, int tlen)
00480   : rep(Salloc(0, t, tlen, tlen)) {}
00481 inline String::String(const SubString& y)
00482   : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
00483 inline String::String(char c) 
00484   : rep(Salloc(0, &c, 1, 1)) {}
00485 
00486 inline String::~String() { if (rep != &_nilStrRep) delete rep; }
00487 
00488 inline SubString::SubString(const SubString& x)
00489   :S(x.S), pos(x.pos), len(x.len) {}
00490 inline SubString::SubString(String& x, int first, int l)
00491   :S(x), pos(first), len(l) {}
00492 
00493 inline SubString::~SubString() {}
00494 
00495 // assignment
00496 
00497 inline String& String::operator =  (const String& y)
00498 { 
00499   rep = Scopy(rep, y.rep);
00500   return *this;
00501 }
00502 
00503 inline String& String::operator=(const char* t)
00504 {
00505   rep = Salloc(rep, t, -1, -1);
00506   return *this;
00507 }
00508 
00509 inline String& String::operator=(const SubString&  y)
00510 {
00511   rep = Salloc(rep, y.chars(), y.length(), y.length());
00512   return *this;
00513 }
00514 
00515 inline String& String::operator=(char c)
00516 {
00517   rep = Salloc(rep, &c, 1, 1);
00518   return *this;
00519 }
00520 
00521 
00522 inline SubString& SubString::operator = (const char* ys)
00523 {
00524   assign(0, ys);
00525   return *this;
00526 }
00527 
00528 inline SubString& SubString::operator = (char ch)
00529 {
00530   assign(0, &ch, 1);
00531   return *this;
00532 }
00533 
00534 inline SubString& SubString::operator = (const String& y)
00535 {
00536   assign(y.rep, y.chars(), y.length());
00537   return *this;
00538 }
00539 
00540 inline SubString& SubString::operator = (const SubString& y)
00541 {
00542   assign(y.S.rep, y.chars(), y.length());
00543   return *this;
00544 }
00545 
00546 // Zillions of cats...
00547 
00548 inline void cat(const String& x, const String& y, String& r)
00549 {
00550   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
00551 }
00552 
00553 inline void cat(const String& x, const SubString& y, String& r)
00554 {
00555   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
00556 }
00557 
00558 inline void cat(const String& x, const char* y, String& r)
00559 {
00560   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
00561 }
00562 
00563 inline void cat(const String& x, char y, String& r)
00564 {
00565   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
00566 }
00567 
00568 inline void cat(const SubString& x, const String& y, String& r)
00569 {
00570   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
00571 }
00572 
00573 inline void cat(const SubString& x, const SubString& y, String& r)
00574 {
00575   r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
00576 }
00577 
00578 inline void cat(const SubString& x, const char* y, String& r)
00579 {
00580   r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
00581 }
00582 
00583 inline void cat(const SubString& x, char y, String& r)
00584 {
00585   r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
00586 }
00587 
00588 inline void cat(const char* x, const String& y, String& r)
00589 {
00590   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
00591 }
00592 
00593 inline void cat(const char* x, const SubString& y, String& r)
00594 {
00595   r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
00596 }
00597 
00598 inline void cat(const char* x, const char* y, String& r)
00599 {
00600   r.rep = Scat(r.rep, x, -1, y, -1);
00601 }
00602 
00603 inline void cat(const char* x, char y, String& r)
00604 {
00605   r.rep = Scat(r.rep, x, -1, &y, 1);
00606 }
00607 
00608 inline void cat(const String& a, const String& x, const String& y, String& r)
00609 {
00610   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
00611 }
00612 
00613 inline void cat(const String& a, const String& x, const SubString& y, String& r)
00614 {
00615   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
00616 }
00617 
00618 inline void cat(const String& a, const String& x, const char* y, String& r)
00619 {
00620   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
00621 }
00622 
00623 inline void cat(const String& a, const String& x, char y, String& r)
00624 {
00625   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
00626 }
00627 
00628 inline void cat(const String& a, const SubString& x, const String& y, String& r)
00629 {
00630   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
00631 }
00632 
00633 inline void cat(const String& a, const SubString& x, const SubString& y, String& r)
00634 {
00635   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
00636 }
00637 
00638 inline void cat(const String& a, const SubString& x, const char* y, String& r)
00639 {
00640   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
00641 }
00642 
00643 inline void cat(const String& a, const SubString& x, char y, String& r)
00644 {
00645   r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
00646 }
00647 
00648 inline void cat(const String& a, const char* x, const String& y, String& r)
00649 {
00650   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
00651 }
00652 
00653 inline void cat(const String& a, const char* x, const SubString& y, String& r)
00654 {
00655   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
00656 }
00657 
00658 inline void cat(const String& a, const char* x, const char* y, String& r)
00659 {
00660   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y, -1);
00661 }
00662 
00663 inline void cat(const String& a, const char* x, char y, String& r)
00664 {
00665   r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, &y, 1);
00666 }
00667 
00668 
00669 inline void cat(const char* a, const String& x, const String& y, String& r)
00670 {
00671   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
00672 }
00673 
00674 inline void cat(const char* a, const String& x, const SubString& y, String& r)
00675 {
00676   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
00677 }
00678 
00679 inline void cat(const char* a, const String& x, const char* y, String& r)
00680 {
00681   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
00682 }
00683 
00684 inline void cat(const char* a, const String& x, char y, String& r)
00685 {
00686   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
00687 }
00688 
00689 inline void cat(const char* a, const SubString& x, const String& y, String& r)
00690 {
00691   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
00692 }
00693 
00694 inline void cat(const char* a, const SubString& x, const SubString& y, String& r)
00695 {
00696   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
00697 }
00698 
00699 inline void cat(const char* a, const SubString& x, const char* y, String& r)
00700 {
00701   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
00702 }
00703 
00704 inline void cat(const char* a, const SubString& x, char y, String& r)
00705 {
00706   r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
00707 }
00708 
00709 inline void cat(const char* a, const char* x, const String& y, String& r)
00710 {
00711   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
00712 }
00713 
00714 inline void cat(const char* a, const char* x, const SubString& y, String& r)
00715 {
00716   r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
00717 }
00718 
00719 inline void cat(const char* a, const char* x, const char* y, String& r)
00720 {
00721   r.rep = Scat(r.rep, a, -1, x, -1, y, -1);
00722 }
00723 
00724 inline void cat(const char* a, const char* x, char y, String& r)
00725 {
00726   r.rep = Scat(r.rep, a, -1, x, -1, &y, 1);
00727 }
00728 
00729 
00730 // operator versions
00731 
00732 inline String& String::operator +=(const String& y)
00733 {
00734   cat(*this, y, *this);
00735   return *this;
00736 }
00737 
00738 inline String& String::operator +=(const SubString& y)
00739 {
00740   cat(*this, y, *this);
00741   return *this;
00742 }
00743 
00744 inline String& String::operator += (const char* y)
00745 {
00746   cat(*this, y, *this);
00747   return *this;
00748 }
00749 
00750 inline String& String:: operator +=(char y)
00751 {
00752   cat(*this, y, *this);
00753   return *this;
00754 }
00755 
00756 // constructive concatenation
00757 
00758 #if defined(__GNUG__) && !defined(_G_NO_NRV)
00759 
00760 inline String operator + (const String& x, const String& y) return r;
00761 {
00762   cat(x, y, r);
00763 }
00764 
00765 inline String operator + (const String& x, const SubString& y) return r;
00766 {
00767   cat(x, y, r);
00768 }
00769 
00770 inline String operator + (const String& x, const char* y) return r;
00771 {
00772   cat(x, y, r);
00773 }
00774 
00775 inline String operator + (const String& x, char y) return r;
00776 {
00777   cat(x, y, r);
00778 }
00779 
00780 inline String operator + (const SubString& x, const String& y) return r;
00781 {
00782   cat(x, y, r);
00783 }
00784 
00785 inline String operator + (const SubString& x, const SubString& y) return r;
00786 {
00787   cat(x, y, r);
00788 }
00789 
00790 inline String operator + (const SubString& x, const char* y) return r;
00791 {
00792   cat(x, y, r);
00793 }
00794 
00795 inline String operator + (const SubString& x, char y) return r;
00796 {
00797   cat(x, y, r);
00798 }
00799 
00800 inline String operator + (const char* x, const String& y) return r;
00801 {
00802   cat(x, y, r);
00803 }
00804 
00805 inline String operator + (const char* x, const SubString& y) return r;
00806 {
00807   cat(x, y, r);
00808 }
00809 
00810 inline String reverse(const String& x) return r;
00811 {
00812   r.rep = Sreverse(x.rep, r.rep);
00813 }
00814 
00815 inline String upcase(const String& x) return r;
00816 {
00817   r.rep = Supcase(x.rep, r.rep);
00818 }
00819 
00820 inline String downcase(const String& x) return r;
00821 {
00822   r.rep = Sdowncase(x.rep, r.rep);
00823 }
00824 
00825 inline String capitalize(const String& x) return r;
00826 {
00827   r.rep = Scapitalize(x.rep, r.rep);
00828 }
00829 
00830 #else /* NO_NRV */
00831 
00832 inline String operator + (const String& x, const String& y)
00833 {
00834   String r;  cat(x, y, r);  return r;
00835 }
00836 
00837 inline String operator + (const String& x, const SubString& y) 
00838 {
00839   String r; cat(x, y, r); return r;
00840 }
00841 
00842 inline String operator + (const String& x, const char* y) 
00843 {
00844   String r; cat(x, y, r); return r;
00845 }
00846 
00847 inline String operator + (const String& x, char y) 
00848 {
00849   String r; cat(x, y, r); return r;
00850 }
00851 
00852 inline String operator + (const SubString& x, const String& y) 
00853 {
00854   String r; cat(x, y, r); return r;
00855 }
00856 
00857 inline String operator + (const SubString& x, const SubString& y) 
00858 {
00859   String r; cat(x, y, r); return r;
00860 }
00861 
00862 inline String operator + (const SubString& x, const char* y) 
00863 {
00864   String r; cat(x, y, r); return r;
00865 }
00866 
00867 inline String operator + (const SubString& x, char y) 
00868 {
00869   String r; cat(x, y, r); return r;
00870 }
00871 
00872 inline String operator + (const char* x, const String& y) 
00873 {
00874   String r; cat(x, y, r); return r;
00875 }
00876 
00877 inline String operator + (const char* x, const SubString& y) 
00878 {
00879   String r; cat(x, y, r); return r;
00880 }
00881 
00882 inline String reverse(const String& x) 
00883 {
00884   String r; r.rep = Sreverse(x.rep, r.rep); return r;
00885 }
00886 
00887 inline String upcase(const String& x) 
00888 {
00889   String r; r.rep = Supcase(x.rep, r.rep); return r;
00890 }
00891 
00892 inline String downcase(const String& x) 
00893 {
00894   String r; r.rep = Sdowncase(x.rep, r.rep); return r;
00895 }
00896 
00897 inline String capitalize(const String& x) 
00898 {
00899   String r; r.rep = Scapitalize(x.rep, r.rep); return r;
00900 }
00901 
00902 #endif
00903 
00904 // prepend
00905 
00906 inline void String::prepend(const String& y)
00907 {
00908   rep = Sprepend(rep, y.chars(), y.length());
00909 }
00910 
00911 inline void String::prepend(const char* y)
00912 {
00913   rep = Sprepend(rep, y, -1); 
00914 }
00915 
00916 inline void String::prepend(char y)
00917 {
00918   rep = Sprepend(rep, &y, 1); 
00919 }
00920 
00921 inline void String::prepend(const SubString& y)
00922 {
00923   rep = Sprepend(rep, y.chars(), y.length());
00924 }
00925 
00926 // misc transformations
00927 
00928 
00929 inline void String::reverse()
00930 {
00931   rep = Sreverse(rep, rep);
00932 }
00933 
00934 
00935 inline void String::upcase()
00936 {
00937   rep = Supcase(rep, rep);
00938 }
00939 
00940 
00941 inline void String::downcase()
00942 {
00943   rep = Sdowncase(rep, rep);
00944 }
00945 
00946 
00947 inline void String::capitalize()
00948 {
00949   rep = Scapitalize(rep, rep);
00950 }
00951 
00952 // element extraction
00953 
00954 inline char&  String::operator [] (int i) 
00955 { 
00956   if (((unsigned)i) >= length()) error("invalid index");
00957   return rep->s[i];
00958 }
00959 
00960 inline const char&  String::operator [] (int i) const
00961 { 
00962   if (((unsigned)i) >= length()) error("invalid index");
00963   return rep->s[i];
00964 }
00965 
00966 inline char  String::elem (int i) const
00967 { 
00968   if (((unsigned)i) >= length()) error("invalid index");
00969   return rep->s[i];
00970 }
00971 
00972 inline char  String::firstchar() const
00973 { 
00974   return elem(0);
00975 }
00976 
00977 inline char  String::lastchar() const
00978 { 
00979   return elem(length() - 1);
00980 }
00981 
00982 // searching
00983 
00984 inline int String::index(char c, int startpos) const
00985 {
00986   return search(startpos, length(), c);
00987 }
00988 
00989 inline int String::index(const char* t, int startpos) const
00990 {   
00991   return search(startpos, length(), t);
00992 }
00993 
00994 inline int String::index(const String& y, int startpos) const
00995 {   
00996   return search(startpos, length(), y.chars(), y.length());
00997 }
00998 
00999 inline int String::index(const SubString& y, int startpos) const
01000 {   
01001   return search(startpos, length(), y.chars(), y.length());
01002 }
01003 
01004 inline int String::index(const Regex& r, int startpos) const
01005 {
01006   int unused;  return r.search(chars(), length(), unused, startpos);
01007 }
01008 
01009 inline int String::contains(char c) const
01010 {
01011   return search(0, length(), c) >= 0;
01012 }
01013 
01014 inline int String::contains(const char* t) const
01015 {   
01016   return search(0, length(), t) >= 0;
01017 }
01018 
01019 inline int String::contains(const String& y) const
01020 {   
01021   return search(0, length(), y.chars(), y.length()) >= 0;
01022 }
01023 
01024 inline int String::contains(const SubString& y) const
01025 {   
01026   return search(0, length(), y.chars(), y.length()) >= 0;
01027 }
01028 
01029 inline int String::contains(char c, int p) const
01030 {
01031   return match(p, length(), 0, &c, 1) >= 0;
01032 }
01033 
01034 inline int String::contains(const char* t, int p) const
01035 {
01036   return match(p, length(), 0, t) >= 0;
01037 }
01038 
01039 inline int String::contains(const String& y, int p) const
01040 {
01041   return match(p, length(), 0, y.chars(), y.length()) >= 0;
01042 }
01043 
01044 inline int String::contains(const SubString& y, int p) const
01045 {
01046   return match(p, length(), 0, y.chars(), y.length()) >= 0;
01047 }
01048 
01049 inline int String::contains(const Regex& r) const
01050 {
01051   int unused;  return r.search(chars(), length(), unused, 0) >= 0;
01052 }
01053 
01054 inline int String::contains(const Regex& r, int p) const
01055 {
01056   return r.match(chars(), length(), p) >= 0;
01057 }
01058 
01059 
01060 inline int String::matches(const SubString& y, int p) const
01061 {
01062   return match(p, length(), 1, y.chars(), y.length()) >= 0;
01063 }
01064 
01065 inline int String::matches(const String& y, int p) const
01066 {
01067   return match(p, length(), 1, y.chars(), y.length()) >= 0;
01068 }
01069 
01070 inline int String::matches(const char* t, int p) const
01071 {
01072   return match(p, length(), 1, t) >= 0;
01073 }
01074 
01075 inline int String::matches(char c, int p) const
01076 {
01077   return match(p, length(), 1, &c, 1) >= 0;
01078 }
01079 
01080 inline int String::matches(const Regex& r, int p) const
01081 {
01082   int l = (p < 0)? -p : length() - p;
01083   return r.match(chars(), length(), p) == l;
01084 }
01085 
01086 
01087 inline int SubString::contains(const char* t) const
01088 {   
01089   return S.search(pos, pos+len, t) >= 0;
01090 }
01091 
01092 inline int SubString::contains(const String& y) const
01093 {   
01094   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
01095 }
01096 
01097 inline int SubString::contains(const SubString&  y) const
01098 {   
01099   return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
01100 }
01101 
01102 inline int SubString::contains(char c) const
01103 {
01104   return S.search(pos, pos+len, c) >= 0;
01105 }
01106 
01107 inline int SubString::contains(const Regex& r) const
01108 {
01109   int unused;  return r.search(chars(), len, unused, 0) >= 0;
01110 }
01111 
01112 inline int SubString::matches(const Regex& r) const
01113 {
01114   return r.match(chars(), len, 0) == len;
01115 }
01116 
01117 
01118 inline int String::gsub(const String& pat, const String& r)
01119 {
01120   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
01121 }
01122 
01123 inline int String::gsub(const SubString&  pat, const String& r)
01124 {
01125   return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
01126 }
01127 
01128 inline int String::gsub(const Regex& pat, const String& r)
01129 {
01130   return _gsub(pat, r.chars(), r.length());
01131 }
01132 
01133 inline int String::gsub(const char* pat, const String& r)
01134 {
01135   return _gsub(pat, -1, r.chars(), r.length());
01136 }
01137 
01138 inline int String::gsub(const char* pat, const char* r)
01139 {
01140   return _gsub(pat, -1, r, -1);
01141 }
01142 
01143 
01144 
01145 inline  ostream& operator<<(ostream& s, const String& x)
01146 {
01147    s << x.chars(); return s;
01148 }
01149 
01150 // a zillion comparison operators
01151 
01152 inline int operator==(const String& x, const String& y) 
01153 {
01154   return compare(x, y) == 0; 
01155 }
01156 
01157 inline int operator!=(const String& x, const String& y)
01158 {
01159   return compare(x, y) != 0; 
01160 }
01161 
01162 inline int operator>(const String& x, const String& y)
01163 {
01164   return compare(x, y) > 0; 
01165 }
01166 
01167 inline int operator>=(const String& x, const String& y)
01168 {
01169   return compare(x, y) >= 0; 
01170 }
01171 
01172 inline int operator<(const String& x, const String& y)
01173 {
01174   return compare(x, y) < 0; 
01175 }
01176 
01177 inline int operator<=(const String& x, const String& y)
01178 {
01179   return compare(x, y) <= 0; 
01180 }
01181 
01182 inline int operator==(const String& x, const SubString&  y) 
01183 {
01184   return compare(x, y) == 0; 
01185 }
01186 
01187 inline int operator!=(const String& x, const SubString&  y)
01188 {
01189   return compare(x, y) != 0; 
01190 }
01191 
01192 inline int operator>(const String& x, const SubString&  y)      
01193 {
01194   return compare(x, y) > 0; 
01195 }
01196 
01197 inline int operator>=(const String& x, const SubString&  y)
01198 {
01199   return compare(x, y) >= 0; 
01200 }
01201 
01202 inline int operator<(const String& x, const SubString&  y) 
01203 {
01204   return compare(x, y) < 0; 
01205 }
01206 
01207 inline int operator<=(const String& x, const SubString&  y)
01208 {
01209   return compare(x, y) <= 0; 
01210 }
01211 
01212 inline int operator==(const String& x, const char* t) 
01213 {
01214   return compare(x, t) == 0; 
01215 }
01216 
01217 inline int operator!=(const String& x, const char* t) 
01218 {
01219   return compare(x, t) != 0; 
01220 }
01221 
01222 inline int operator>(const String& x, const char* t)  
01223 {
01224   return compare(x, t) > 0; 
01225 }
01226 
01227 inline int operator>=(const String& x, const char* t) 
01228 {
01229   return compare(x, t) >= 0; 
01230 }
01231 
01232 inline int operator<(const String& x, const char* t)  
01233 {
01234   return compare(x, t) < 0; 
01235 }
01236 
01237 inline int operator<=(const String& x, const char* t) 
01238 {
01239   return compare(x, t) <= 0; 
01240 }
01241 
01242 inline int operator==(const SubString& x, const String& y) 
01243 {
01244   return compare(y, x) == 0; 
01245 }
01246 
01247 inline int operator!=(const SubString& x, const String& y)
01248 {
01249   return compare(y, x) != 0;
01250 }
01251 
01252 inline int operator>(const SubString& x, const String& y)      
01253 {
01254   return compare(y, x) < 0;
01255 }
01256 
01257 inline int operator>=(const SubString& x, const String& y)     
01258 {
01259   return compare(y, x) <= 0;
01260 }
01261 
01262 inline int operator<(const SubString& x, const String& y)      
01263 {
01264   return compare(y, x) > 0;
01265 }
01266 
01267 inline int operator<=(const SubString& x, const String& y)     
01268 {
01269   return compare(y, x) >= 0;
01270 }
01271 
01272 inline int operator==(const SubString& x, const SubString&  y) 
01273 {
01274   return compare(x, y) == 0; 
01275 }
01276 
01277 inline int operator!=(const SubString& x, const SubString&  y)
01278 {
01279   return compare(x, y) != 0;
01280 }
01281 
01282 inline int operator>(const SubString& x, const SubString&  y)      
01283 {
01284   return compare(x, y) > 0;
01285 }
01286 
01287 inline int operator>=(const SubString& x, const SubString&  y)
01288 {
01289   return compare(x, y) >= 0;
01290 }
01291 
01292 inline int operator<(const SubString& x, const SubString&  y) 
01293 {
01294   return compare(x, y) < 0;
01295 }
01296 
01297 inline int operator<=(const SubString& x, const SubString&  y)
01298 {
01299   return compare(x, y) <= 0;
01300 }
01301 
01302 inline int operator==(const SubString& x, const char* t) 
01303 {
01304   return compare(x, t) == 0; 
01305 }
01306 
01307 inline int operator!=(const SubString& x, const char* t) 
01308 {
01309   return compare(x, t) != 0;
01310 }
01311 
01312 inline int operator>(const SubString& x, const char* t)  
01313 {
01314   return compare(x, t) > 0; 
01315 }
01316 
01317 inline int operator>=(const SubString& x, const char* t) 
01318 {
01319   return compare(x, t) >= 0; 
01320 }
01321 
01322 inline int operator<(const SubString& x, const char* t)  
01323 {
01324   return compare(x, t) < 0; 
01325 }
01326 
01327 inline int operator<=(const SubString& x, const char* t) 
01328 {
01329   return compare(x, t) <= 0; 
01330 }
01331 
01332 
01333 // a helper needed by at, before, etc.
01334 
01335 inline SubString String::_substr(int first, int l)
01336 {
01337   if (first < 0 || (unsigned)(first + l) > length() )
01338     return SubString(_nilString, 0, 0) ;
01339   else 
01340     return SubString(*this, first, l);
01341 }
01342 
01343 #endif

Generated on Sun Oct 14 18:46:11 2001 for Standard J2K Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001