1 // Copyright 2009 The Archiveopteryx Developers <info@aox.org> 2 3 #ifndef ESTRING_H 4 #define ESTRING_H 5 6 #include "global.h" 7 8 9 class EStringData 10 : public Garbage 11 { 12 private: EStringData()13 EStringData(): str( 0 ), len( 0 ), max( 0 ) { 14 setFirstNonPointer( &len ); 15 } 16 EStringData( int ); 17 18 friend class EString; 19 friend bool operator==( const class EString &, const class EString & ); 20 friend bool operator==( const class EString &, const char * ); 21 void * operator new( size_t, uint ); new(size_t s)22 void * operator new( size_t s ) { return Garbage::operator new( s); } 23 24 char * str; 25 uint len; 26 uint max; 27 }; 28 29 30 class EString 31 : public Garbage 32 { 33 public: 34 EString(); 35 EString( const char * ); 36 EString( const char *, uint ); 37 EString( const EString & ); 38 ~EString(); 39 40 EString & operator=( const EString & ); 41 EString & operator=( const char * ); 42 EString & operator+=( const EString & str ) { append( str ); return *this; } 43 44 void operator delete( void * ); 45 46 // const, returns zero when used beyond the end 47 inline char operator[]( uint i ) const { 48 if ( !d ) 49 return 0; 50 if ( i >= d->len ) 51 return 0; 52 return d->str[i]; 53 } 54 at(uint i)55 inline char at( uint i ) const { return (*this)[i]; } 56 isEmpty()57 inline bool isEmpty() const { return !d || !d->len; } length()58 inline uint length() const { return d ? d->len : 0; } capacity()59 inline uint capacity() const { return d ? d->max : 0; } data()60 inline const char * data() const { return d ? (const char*)d->str : 0; } 61 const char * cstr(); 62 const char * cstr() const; 63 64 EString lower() const; 65 EString upper() const; 66 EString headerCased() const; 67 EString mid( uint, uint = UINT_MAX ) const; 68 EString simplified() const; 69 EString trimmed() const; 70 EString stripCRLF() const; 71 EString hex() const; 72 bool isQuoted( char = '"', char = '\\' ) const; 73 EString unquoted( char = '"', char = '\\' ) const; 74 EString quoted( char = '"', char = '\\' ) const; forlog()75 EString forlog() const { return !d || !d->len ? "<>" : *this ; }; 76 77 enum Boring { Totally, IMAP, MIME }; 78 bool boring( Boring = Totally ) const; 79 80 bool startsWith( const EString & ) const; 81 bool startsWith( const char * ) const; 82 bool endsWith( const EString & ) const; 83 bool endsWith( const char * ) const; 84 uint number( bool *, uint = 10 ) const; 85 static EString fromNumber( int64, uint = 10 ); 86 void appendNumber( int64, uint = 10 ); 87 static EString humanNumber( int64 ); 88 89 int find( char, int=0 ) const; 90 int find( const EString &, int=0 ) const; 91 bool contains( const EString & ) const; 92 bool contains( const char ) const; 93 bool containsWord( const EString & ) const; 94 EString section( const EString &, uint ) const; 95 96 void replace( const EString &, const EString & ); 97 98 void append( char ); 99 void appendNumber( int, int = 10 ); 100 void appendNumber( uint, int = 10 ); 101 void append( const EString & ); 102 void append( const char *, uint ); 103 void append( const char * ); 104 105 void prepend( const EString & ); 106 107 void reserve( uint ); 108 void reserve2( uint ); 109 void truncate( uint = 0 ); 110 void setLength( uint ); 111 112 enum Encoding { Binary, Base64, QP, Uuencode }; 113 EString encoded( Encoding, uint = 0 ) const; 114 EString decoded( Encoding ) const; 115 116 EString eURI() const; 117 EString deURI() const; 118 EString de64() const; 119 EString deUue() const; 120 EString e64( uint = 0 ) const; 121 EString deQP( bool = false ) const; 122 EString eQP( bool = false, bool = false ) const; 123 bool needsQP() const; 124 125 friend inline bool operator==( const EString &, const EString & ); 126 friend bool operator==( const EString &, const char * ); 127 128 bool operator<( const EString & ) const; 129 bool operator>( const EString & ) const; 130 bool operator<=( const EString & ) const; 131 bool operator>=( const EString & ) const; 132 133 bool operator<( const char * ) const; 134 135 int compare( const EString & ) const; 136 detach()137 inline void detach() { if ( !modifiable() ) reserve( length() ); } 138 modifiable()139 bool modifiable() const { return d && d->max > 0; } 140 141 void print() const; 142 143 EString anonymised() const; 144 145 EString crlf() const; 146 147 EString wrapped( uint linelength, 148 const EString & firstPrefix, const EString & otherPrefix, 149 bool spaceAtEOL ) const; 150 151 private: 152 EStringData * d; 153 }; 154 155 156 // since operator== is called so often, we provide fastish inlines 157 inline bool operator==( const EString & a, const EString & b ) { 158 uint al = a.length(); 159 uint bl = b.length(); 160 if ( !al && !bl ) 161 return true; 162 if ( !al || !bl || al != bl ) 163 return false; 164 if ( a.d == b.d ) 165 return true; 166 uint i = 0; 167 while ( i < al && i < bl && a.d->str[i] == b.d->str[i] ) 168 i++; 169 if ( i < al ) 170 return false; 171 return true; 172 } 173 174 175 inline bool operator==( const EString & a, const char * b ) { 176 uint al = a.length(); 177 if ( !b || !*b ) { 178 if ( al == 0 ) 179 return true; 180 return false; 181 } 182 uint i = 0; 183 while ( i < al && a.d->str[i] == b[i] && b[i] != '\0' ) 184 i++; 185 if ( i < al ) 186 return false; 187 if ( b[i] != '\0' ) 188 return false; 189 return true; 190 } 191 192 193 inline bool operator==( const char * a, const EString & b ) { 194 return b == a; 195 } 196 197 198 inline bool operator!=( const EString & a, const char * b ) { 199 return !( a == b ); 200 } 201 202 203 inline bool operator!=( const char * a, const EString & b ) { 204 return !( b == a ); 205 } 206 207 208 inline bool operator!=( const EString & a, const EString & b ) { 209 return !( a == b ); 210 } 211 212 213 extern const EString operator+( const EString & a, const EString & b ); 214 extern const EString operator+=( const EString & a, const EString & b ); 215 216 217 inline EString fn( int64 n, uint b = 10 ) 218 { 219 return EString::fromNumber( n, b ); 220 } 221 222 223 #endif 224