• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/String.h

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #ifndef _tstring_h
00018 #define _tstring_h
00019 
00020 #include <string.h>
00021 #include <stdlib.h>
00022 
00023 #ifndef __cplusplus
00024 #error not cpp
00025 #endif
00026 
00027 #include <spl/types.h>
00028 #include <spl/Debug.h>
00029 
00030 #ifdef _WINDOWS
00031 #include <spl/configwin32.h>
00032 #else
00033 #include <spl/autoconf/config.h>
00034 char *ltoa( long i, char *buf, const int buflen );
00035 #endif
00036 
00037 #include <stdarg.h>
00038 
00039 #include <spl/collection/Array.h>
00040 #include <spl/Memory.h>
00041 #include <spl/RefCountPtr.h>
00042 #include <spl/collection/Vector.h>
00043 #include <spl/WeakReference.h>
00044 
00051 #define STRING_MAJIC 0x0001             //< Majic number for ASSERT's in Compare and Convert
00052 
00053 #ifdef StrCmp
00054 #undef StrCmp
00055 #endif
00056 
00057 namespace spl
00058 {
00059         extern int StrCpyLen( char *strto, const char *strfrom, const int maxlen );
00060         extern int StrCpy( char *strto, const char *strfrom );
00061         extern int StrCmp( const char *str1, const char *str2, int maxlen );
00062         extern int StrCmpNoCase( const char *str1, int str1len, const char *str2 );
00063         extern int IndexofchfromWithLen( const char *str, const char ch, int start, const int len );
00064 #define IndexOfCh(s,c) spl::IndexofchfromWithLen(s,c,0,(int)strlen(s))
00065 };
00066 
00067 class String;
00068 typedef RefCountPtr<String> StringPtr;
00069 typedef WeakReference<String, StringPtr> StringRef;
00070 
00071 REGISTER_TYPEOF( 572, StringPtr );
00072 REGISTER_TYPEOF( 574, StringRef );
00073 
00077 class String : public IComparable, public IMemoryValidate
00078 {
00079 private:
00080         static char m_empty[2];
00081 
00082 protected:
00083         const char *m_cstr;
00084         bool m_isintern;
00085         int m_len;
00086 
00087         void InitWith(const char *cp, const int offset, const int len);
00088 
00089 public:
00090         String();
00091         
00092         inline String( const char *cp, const int offset, const int len )
00093         {
00094                 InitWith(cp, offset, len);
00095         }
00096 
00097         inline String( const Array<byte>& cp, const int offset, const int len )
00098         {
00099                 InitWith((const char *)cp.Data(), offset, len);
00100         }
00101 
00102         inline String( const Array<char>& cp, const int offset, const int len )
00103         {
00104                 InitWith((const char *)cp.Data(), offset, len);
00105         }
00106 
00107         inline String( const char *cp, const int len )
00108         {
00109                 InitWith(cp, 0, len);
00110         }
00111 
00112         inline String( const char *cp )
00113         {
00114                 InitWith(cp, 0, (int)strlen(cp));
00115         }
00116 
00117         String( const String& str );
00118 
00119         ~String();
00120 
00121         void Set( const String& cp );
00122 
00123         inline String& operator =(const String& str)
00124         {
00125                 if ( Equals(str) )
00126                 {
00127                         return *this;
00128                 }
00129                 Set(str);
00130                 return *this;
00131         }
00132 
00133         inline String& operator =(const char *str)
00134         {
00135                 if ( Equals(str) )
00136                 {
00137                         return *this;
00138                 }
00139                 Set(str);
00140                 return *this;
00141         }
00142 
00143         inline bool operator ==(const String& str) const
00144         {
00145                 return Equals(str);
00146         }
00147 
00148         inline bool operator ==(const char *cp) const
00149         {
00150                 return Equals(cp);
00151         }
00152 
00153         inline bool operator !=(const String& str) const
00154         {
00155                 return !Equals(str);
00156         }
00157 
00158         inline bool operator <(const String& str) const
00159         {
00160                 return Compare(str) < 0;
00161         }
00162 
00163         inline bool operator >(const String& str) const
00164         {
00165                 return Compare(str) > 0;
00166         }
00167 
00168         inline bool operator <=(const String& str) const
00169         {
00170                 return Compare(str) <= 0;
00171         }
00172 
00173         inline bool operator >=(const String& str) const
00174         {
00175                 return Compare(str) >= 0;
00176         }
00177 
00178         StringPtr Substring( int start, int len ) const;
00179         inline StringPtr Substring( int start ) const { return Substring(start, m_len - start); }
00180 
00181         StringPtr Cat( const String& cp, const int len ) const;
00182         inline StringPtr Cat( const String& arg ) const { return Cat(arg.GetChars(), arg.Length()); }
00183 
00184         inline String operator +( const String& arg ) const { return *Cat(arg); }
00185 
00186         StringPtr Right( int len ) const;
00187         StringPtr Left( int len ) const;
00188         StringPtr Mid( int start, int stop ) const;
00189 
00190         RefCountPtr<Vector<StringPtr> > Split( const String& cp ) const;
00191         
00192         StringPtr PadRight( char ch, int count );
00193 
00194         virtual int Compare( const IComparable *str ) const;
00195         virtual bool Equals( const IComparable *str ) const;
00196         virtual bool Equals( const IComparable& a ) const;
00197         virtual int Compare( const IComparable& a ) const;
00198         virtual int32 MajicNumber() const;
00199 
00200         inline int Compare( const String& str ) const
00201         {
00202                 return Compare( str.m_cstr );
00203         }
00204 
00205         inline int Compare( const char *cp ) const
00206         {
00207                 return spl::StrCmp( m_cstr, cp, (int)strlen(cp) );
00208         }
00209 
00210         inline int CompareNoCase( const char *cp ) const
00211         {
00212                 return spl::StrCmpNoCase( m_cstr, m_len, cp );
00213         }
00214 
00215         inline int CompareNoCase( const String& sp ) const
00216         {
00217                 return spl::StrCmpNoCase( m_cstr, m_len, sp.m_cstr );
00218         }
00219 
00220         inline int IndexOf( const String& str ) const
00221         {
00222                 return IndexOf( str, 0 );
00223         }
00224 
00225         int IndexOf( const String& cp, const int start ) const;
00226 
00227         inline int IndexOf( const char ch ) const
00228         {
00229                 return IndexOf( ch, 0 );
00230         }
00231         
00232         inline int IndexOf( const char ch, const int start ) const
00233         {
00234                 return spl::IndexofchfromWithLen(m_cstr, ch, start, m_len);
00235         }
00236 
00237         int IndexOfAny( const String& str ) const;
00238 
00239         int LastIndexOf( const char ch ) const;
00240 
00241         inline bool StartsWith( char ch ) { char buf[2]; buf[0] = ch; buf[1] = '\0'; return StartsWith(buf); }
00242         bool StartsWith( const String& str ) const;
00243 
00244         bool EndsWith( const String& str ) const;
00245 
00246         inline bool EndsWith( char cp ) const
00247         {
00248                 char buf[2];
00249                 buf[0] = cp;
00250                 buf[1] = '\0';
00251                 return EndsWith( buf );
00252         }
00253 
00254         inline bool EqualsIgnoreCase( const String& cp ) const
00255         {
00256                 return 0 == CompareNoCase(cp);
00257         }
00258 
00259         inline bool Equals( const String& cp ) const
00260         {
00261                 return 0 == spl::StrCmp(m_cstr, cp.m_cstr, m_len);
00262         }
00263 
00264         inline bool Equals( const char ch ) const
00265         {
00266                 return 1 == m_len && ch == m_cstr[0];
00267         }
00268 
00269         inline int CountChar( const char ch ) const
00270         {
00271                 return CountChar( m_cstr, m_len, ch );
00272         }
00273 
00274         virtual int32 HashCode() const;
00275 
00276         inline const char *GetChars() const
00277         {
00278                 return m_cstr;
00279         }
00280 
00281         inline int Length() const
00282         {
00283                 ASSERT( (int)strlen(m_cstr) == m_len );
00284                 return m_len;
00285         }
00286 
00287         char CharAt( const int idx ) const;
00288 
00289         char operator[] (const int idx) const;
00290         
00291         StringPtr Replace(const char from, const char to) const;
00292         StringPtr Replace(const char *from, const char *to) const;
00293 
00294         StringPtr ToUpper() const;
00295 
00296         StringPtr ToLower() const;
00297 
00298         StringPtr StripQuotes();
00299 
00301         StringPtr RTrim(char ch) const;
00302         inline StringPtr RTrim() { return RTrim(' '); }
00303 
00304         StringPtr LTrim(char ch) const;
00305         inline StringPtr LTrim() { return LTrim(' '); }
00306 
00308         StringPtr Trim() const;
00309 
00310         inline operator const char *()
00311         {
00312                 return GetChars();
00313         }
00314 
00315         inline StringPtr Clone() const
00316         {
00317                 return StringPtr(new String(*this));
00318         }
00319 
00320         RefCountPtr<Array<byte> > ToByteArray() const;
00321         
00322         inline StringPtr ToString() const
00323         {
00324                 return StringPtr(new String(*this));
00325         }
00326 
00327         static StringPtr Fill( char ch, int length );
00328 
00329         static int CountChar( const char *str, const int len, const char ch );
00330 
00331         static StringPtr Base64Encode( RefCountPtr<Array<byte> > cp );
00332         static StringPtr Base64Encode( const char* cp, int len );
00333         static RefCountPtr<Array<byte> > Base64Decode( const String& cp );
00334 
00336         static StringPtr Intern( const char *str );
00337 
00339         void UnIntern();
00340 
00341         static StringPtr Format(const String fmt, ...);
00342         static StringPtr FormatVA(const String fmt, va_list args);
00343 
00344         friend String operator +(const char *cp, const String& str);
00345 
00346 #if defined(DEBUG) || defined(_DEBUG)
00347         void CheckMem() const;
00348         void ValidateMem() const;
00349 #endif
00350 };
00351 
00352 inline void ValidateType( const String &s ) 
00353 {
00354         s.ValidateMem();
00355         s.CheckMem();
00356 }
00357 
00358 inline void ValidateType( StringPtr s ) 
00359 {
00360         if ( NULL != s.Get() )
00361         {
00362                 ASSERT_MEM(s.Get(), sizeof(String));
00363                 DEBUG_NOTE_MEM(s.Get());
00364                 s.ValidateMem();
00365                 s.CheckMem();
00366         }
00367 }
00368 
00369 String operator +(const char *cp, const String& str);
00370 
00371 inline bool operator ==(const char *cp, const String& str)
00372 {
00373         return str == cp;
00374 }
00375 
00376 REGISTER_TYPEOF( 570, String );
00377 REGISTER_TYPEOF( 588, Vector<String> );
00378 REGISTER_TYPEOF( 589, Array<String> );
00379 
00382 #endif