changed copyright years in source files
[fegdk.git] / core / code / system / f_wstr.h
blobb202600a2c3801bb910febf2512a9b4a389caf94
1 /*
2 fegdk: FE Game Development Kit
3 Copyright (C) 2001-2008 Alexey "waker" Yakovenko
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 Alexey Yakovenko
20 waker@users.sourceforge.net
23 #ifndef __F_WSTR_H
24 #define __F_WSTR_H
26 #include "wchar.h"
27 #ifndef _WIN32
28 #include "wctype.h"
29 #endif
31 #ifndef _wcsinc
32 #define _wcsinc(_pc) ((_pc)+1)
33 #endif
35 #ifndef _wclen
36 #define _wclen(lpsz) (1)
37 #endif
39 namespace fe
42 class wStr
44 protected:
45 wchar_t* _Ptr;
46 size_t _Len;
47 size_t _Res;
49 public:
51 static const size_t npos = 0xffffffff;
53 wStr( const wchar_t *s )
55 _Ptr = NULL;
56 _Len = 0;
57 _Res = 0;
58 assign( s );
60 wStr( const char *s )
62 _Ptr = NULL;
63 _Len = 0;
64 _Res = 0;
65 assign( s );
68 wStr()
70 _Ptr = NULL;
71 _Len = 0;
72 _Res = 0;
75 wStr( const wStr& _X )
77 _Ptr = NULL;
78 _Len = 0;
79 _Res = 0;
80 assign(_X, 0, npos);
83 wStr( const wStr& _X, size_t _P, size_t _M )
85 _Ptr = NULL;
86 _Len = 0;
87 _Res = 0;
88 assign(_X, _P, _M);
91 ~wStr()
93 if ( _Ptr )
94 delete[] _Ptr;
97 void clear( void )
99 if ( _Len )
101 _Len = 0;
102 *_Ptr = 0;
106 wStr &assign( const wchar_t *s )
108 resize( wcslen( s ) );
109 if ( _Len )
110 wcscpy( _Ptr, s );
111 else if ( _Ptr )
112 *_Ptr = 0;
113 return *this;
115 wStr& assign( const char *s )
117 resize( strlen( s ) );
118 if ( _Ptr )
120 size_t i;
121 for ( i = 0; i < _Len; i++ )
122 _Ptr[i] = *s++;
123 if ( _Len )
124 _Ptr[i] = 0;
126 return *this;
129 void printf( wchar_t *fmt, ... )
131 // try {
132 int n;
133 char *p, *np;
134 va_list ap;
136 if (_Len == 0)
137 resize (wcslen (fmt));
139 while (1) {
140 /* Try to print in the allocated space. */
141 va_start(ap, fmt);
142 n = vswprintf (_Ptr, _Len, fmt, ap);
143 va_end(ap);
144 /* If that worked, return the string. */
145 if (n > -1 && n < _Len)
146 break;
147 /* Else try again with more space. */
148 if (n > -1) /* glibc 2.1 */
149 resize (_Len + 1); /* precisely what is needed */
150 else /* glibc 2.0 */
151 resize (_Len * 2); /* twice the old size */
153 // }
154 // catch ( ... )
155 // {
156 // seems like too big line. terminate.
157 // throw genericError ("cStr::printf failed!\n");
158 // }
161 void trim_left( wchar_t *targets )
163 wchar_t *c = _Ptr;
165 while ( *c != '\0' )
167 if ( wcschr( targets, *c ) == NULL )
168 break;
169 c++;
172 if ( c != _Ptr )
174 // fix up data and length
175 size_t l = _Len - ( c - _Ptr );
176 memmove( _Ptr, c, ( l + 1 ) * sizeof( wchar_t ) );
177 _Len = l;
181 void trim_left( wchar_t target )
183 wchar_t *c = _Ptr;
185 while ( target == *c )
186 c++;
188 if ( c != _Ptr )
190 // fix up data and length
191 size_t l = _Len - ( c - _Ptr );
192 memmove( _Ptr, c, ( l + 1 ) * sizeof( wchar_t ) );
193 _Len = l;
197 void trim_left( void )
199 wchar_t *c = _Ptr;
201 while ( iswspace( *c ) )
202 c++;
204 if ( c != _Ptr )
206 // fix up data and length
207 size_t l = _Len - ( c - _Ptr );
208 memmove( _Ptr, c, ( l + 1 ) * sizeof( wchar_t ) );
209 _Len = l;
213 void trim_right( wchar_t *targets )
215 // find beginning of trailing matches
216 // by starting at beginning (DBCS aware)
218 wchar_t *c = _Ptr;
219 wchar_t *last = NULL;
221 while ( *c != '\0' )
223 if ( wcschr( targets, *c ) != NULL )
225 if ( last == NULL)
226 last = c;
228 else
229 last = NULL;
230 c++;
233 if ( last != NULL )
235 // truncate at left-most matching character
236 *last = '\0';
237 _Len = last - _Ptr;
241 void trim_right( wchar_t target )
243 wchar_t *c = _Ptr;
244 wchar_t *last = NULL;
246 while ( *c != '\0' )
248 if ( *c == target )
250 if ( last == NULL )
251 last = c;
253 else
254 last = NULL;
255 c++;
258 if ( last != NULL )
260 // truncate at left-most matching character
261 *last = '\0';
262 _Len = last - c;
266 void trim_right( void )
268 wchar_t *c = _Ptr;
269 wchar_t *last = NULL;
271 while ( *c != '\0' )
273 if ( iswspace( *c ) )
275 if ( last == NULL )
276 last = c;
278 else
279 last = NULL;
280 c++;
283 if ( last != NULL )
285 // truncate at trailing space start
286 *last = '\0';
287 _Len = last - _Ptr;
291 void reserve( size_t s )
293 if ( _Res < s )
294 grow( s );
297 void resize( size_t s )
299 if ( s <= _Len )
300 erase( s );
301 else
302 append( s - _Len, wchar_t( 0 ) );
305 void erase( size_t s )
307 if ( s )
308 memset( _Ptr + s, 0, sizeof( wchar_t ) * ( _Len - s ) );
309 _Len = s;
312 size_t size( void ) const
314 return _Len;
317 size_t length( void ) const
319 return _Len;
322 size_t capacity( void ) const
324 return _Res;
327 const wchar_t *c_str( void ) const
329 return _Ptr ? _Ptr : L"";
332 const wchar_t *data( void ) const
334 return c_str();
337 void grow( size_t s )
339 _Res = s;
340 wchar_t *buf = new wchar_t[ _Res + 1 ];
341 assert( buf );
342 if ( _Ptr )
344 wcscpy( buf, _Ptr );
345 delete[] _Ptr;
347 else
348 memset( buf, 0, sizeof( wchar_t ) * ( _Res + 1 ) );
349 _Ptr = buf;
352 wStr& assign( const wStr &s )
354 resize( s.size() );
355 if ( _Len )
356 wcscpy( _Ptr, s.c_str() );
357 return *this;
360 wStr& assign( size_t s, wchar_t c )
362 resize( s );
364 wchar_t *p;
365 for ( p = _Ptr; p < _Ptr + s; p++ )
366 *p = c;
367 *p = wchar_t( 0 );
369 return *this;
372 wStr& assign( const wStr& _X, size_t _P, size_t _M )
374 size_t _N = _X.size() - _P;
375 if (_M < _N)
376 _N = _M;
379 resize( _N );
380 if ( _Len )
381 wcsncpy( _Ptr, &_X.c_str()[_P], _N );
382 if ( _Ptr )
383 _Ptr[_N] = wchar_t( 0 );
385 return *this;
388 wStr& append( size_t s, wchar_t c )
390 if ( _Len + s > _Res )
391 grow( _Len + s );
392 for ( wchar_t *p = _Ptr + _Len; p < _Ptr + _Len + s; p++ )
393 *p = c;
394 _Len += s;
395 return *this;
398 wStr& append( const wchar_t *s )
400 size_t l = _Len;
401 resize( l + wcslen( s ) );
402 wcscpy( _Ptr + l, s );
403 return *this;
406 wStr& append( const wStr &s )
408 size_t l = _Len;
409 resize( l + s.size() );
410 wcscpy( _Ptr + l, s.c_str() );
411 return *this;
414 size_t find( wchar_t s ) const
416 for ( wchar_t *p = _Ptr; p < _Ptr + _Len; p++ )
418 if ( *p == s )
419 return p - _Ptr;
421 return npos;
424 wStr substr( size_t p, size_t m ) const
426 return wStr( *this, p, m );
429 int compare( const wStr &s ) const
431 const wchar_t *p1, *p2;
433 p1 = empty() ? L"" : _Ptr;
434 p2 = s.empty() ? L"" : s.c_str();
436 return wcscmp( p1, p2 );
439 bool empty( void ) const
441 return _Len == 0;
444 void insert( size_t offs, const wStr& val )
446 assert( offs <= size() );
447 if ( val.empty() )
448 return;
449 size_t sz = size();
450 resize( size() + val.size() );
451 if ( offs < sz )
452 memmove( _Ptr + offs + val.size(), _Ptr + offs, ( sz - offs + 1 ) * sizeof( wchar_t ) );
453 memcpy( _Ptr + offs, val.c_str(), val.size() * sizeof( wchar_t ) );
454 *(_Ptr + _Len) = 0;
457 void erase( size_t offs, size_t amount )
459 assert( offs < size() );
460 assert( offs + amount <= size() );
462 memmove( _Ptr + offs, _Ptr + offs + amount, ( size() - offs - amount ) * sizeof( wchar_t ) );
463 resize( size() - amount );
466 operator const wchar_t *() const
468 return c_str();
471 wStr& operator = ( const wStr& _X )
473 return assign( _X );
476 wStr& operator = ( const wchar_t* _X )
478 return assign( _X );
481 wStr& operator = ( wchar_t _X )
483 return assign( 1, _X );
486 wStr& operator += ( const wStr& _X )
488 return append( _X );
491 wStr& operator += ( const wchar_t* _X )
493 return append( _X );
496 wStr& operator += ( wchar_t _X )
498 return append( 1, _X );
501 void tolower( void )
503 for ( size_t i = 0; i < size(); i++ )
505 #ifdef _WIN32
506 *(_Ptr + i) = towlower( *( _Ptr + i ) );
507 #else
508 *(_Ptr + i) = towlower( *( _Ptr + i ) );
509 #endif
515 inline wStr operator + ( const wStr &s1, const wStr &s2 )
517 return wStr( s1 ) += s2;
520 inline bool operator < ( const wStr &_L, const wStr &_R )
522 return _L.compare(_R) < 0;
525 inline bool operator > ( const wStr &_L, const wStr &_R )
527 return _R < _L;
530 inline bool operator <= ( const wStr &_L, const wStr &_R )
532 return !( _R < _L );
535 inline bool operator >= ( const wStr &_L, const wStr &_R )
537 return !( _L < _R );
540 inline bool operator == ( const wStr &_L, const wStr &_R )
542 return _L.compare( _R ) ? false : true;
545 inline bool operator == ( const wStr &_L, const wchar_t *_R )
547 return _L.compare( _R ) ? false : true;
550 inline bool operator == ( const wchar_t *_L, const wStr &_R )
552 return _R.compare( _L ) ? false : true;
555 inline bool operator != ( const wStr &_L, const wStr &_R )
557 return _L.compare( _R ) ? true : false;
560 inline bool operator != ( const wStr &_L, const wchar_t *_R )
562 return _L.compare( _R ) ? true : false;
565 inline bool operator != ( const wchar_t *_L, const wStr &_R )
567 return _R.compare( _L ) ? true : false;
572 #endif // __F_WSTR_H