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