00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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