OpenBarnyard
 
Loading...
Searching...
No Matches
TString8.cpp
Go to the documentation of this file.
1#include "ToshiPCH.h"
2#include "TString8.h"
3#include "TString16.h"
4
5#include "Toshi/TSystem.h"
6
7//-----------------------------------------------------------------------------
8// Enables memory debugging.
9// Note: Should be the last include!
10//-----------------------------------------------------------------------------
11#include "Core/TMemoryDebugOn.h"
12
14
16{
17 Reset();
18 m_pAllocator = GetAllocator();
19}
20
22{
23 Reset();
24 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
25}
26
27TString8::TString8( const TString8& src, T2Allocator* allocator )
28{
29 Reset();
30 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
31 Copy( src, -1 );
32}
33
35{
36 Reset();
37 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
38 AllocBuffer( size );
39}
40
41TString8::TString8( const TString16& src, T2Allocator* allocator )
42{
43 Reset();
44 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
45 Copy( src );
46}
47
48TString8::TString8( const TCHAR* src, T2Allocator* allocator )
49{
50 Reset();
51 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
52 Copy( src );
53}
54
56{
57 TString8::m_pAllocator = src.m_pAllocator;
58 TString8::m_iExcessLen = src.m_iExcessLen;
59 TString8::m_iStrLen = src.m_iStrLen;
60 TString8::m_pBuffer = src.m_pBuffer;
61 src.Reset();
62}
63
64void TString8::Copy( const TString16& src, TINT size )
65{
66 TINT srcLen = src.Length();
67 TASSERT( srcLen <= 0xFFFFFF, "Too big string" );
68
69 if ( srcLen < size || size == -1 ) { size = srcLen; }
70
71 AllocBuffer( size, TTRUE );
72 TStringManager::StringUnicodeToChar( m_pBuffer, src, size );
73 m_pBuffer[ size ] = 0;
74}
75
76void TString8::Copy( const TCHAR* src, TINT size )
77{
78 if ( src != m_pBuffer )
79 {
80 TINT srcLen = src ? TINT( TStringManager::String8Length( src ) ) : 0;
81 TASSERT( srcLen <= 0xFFFFFF, "Too big string" );
82
83 if ( srcLen < size || size == -1 )
84 {
85 size = srcLen;
86 }
87
88 AllocBuffer( size, TTRUE );
89 TUtil::MemCopy( m_pBuffer, src, size );
90
91 m_pBuffer[ size ] = 0;
92 }
93}
94
95void TString8::Copy( const TWCHAR* src, TINT size )
96{
97 TINT srcLen = TINT( TStringManager::String16Length( src ) );
98 TASSERT( srcLen <= 0xFFFFFF, "Too big string" );
99
100 if ( srcLen < size || size == -1 ) { size = srcLen; }
101
102 AllocBuffer( size, TTRUE );
103 TStringManager::StringUnicodeToChar( m_pBuffer, src, size );
104 m_pBuffer[ size ] = 0;
105}
106
107TINT TString8::Find( TCHAR character, TINT pos ) const
108{
109 if ( !IsIndexValid( pos ) ) return -1;
110
111 const TCHAR* foundAt = strchr( &m_pBuffer[ pos ], character );
112 if ( foundAt == TNULL ) return -1;
113
114 return (TINT)( foundAt - m_pBuffer );
115}
116
117TINT TString8::Find( const TCHAR* substr, TINT pos ) const
118{
119 if ( !IsIndexValid( pos ) ) return -1;
120
121 const TCHAR* foundAt = strstr( GetString( pos ), substr );
122 if ( foundAt == TNULL ) return -1;
123
124 return (TINT)( foundAt - m_pBuffer );
125}
126
127TBOOL TString8::AllocBuffer( TINT a_iLength, TBOOL a_bFreeMemory )
128{
129 TBOOL hasChanged = TFALSE;
130 TUINT32 currentLength = Length();
131
132 TASSERT( a_iLength >= 0, "Length can't be less than 0" );
133 TASSERT( a_iLength <= 0xFFFFFF, "Too big string" );
134
135 if ( a_iLength != currentLength )
136 {
137 if ( a_iLength == 0 )
138 {
139 if ( a_bFreeMemory ) m_pAllocator->Free( m_pBuffer );
140
141 m_pBuffer = NullString;
142 m_iExcessLen = 0;
143
144 hasChanged = TTRUE;
145 }
146 else
147 {
148 TINT newExcessLen = ( currentLength - a_iLength ) + m_iExcessLen;
149
150 if ( newExcessLen < 0 || newExcessLen > 0xFF )
151 {
152 if ( currentLength != 0 && a_bFreeMemory )
153 {
154 m_pAllocator->Free( m_pBuffer );
155 }
156
157 m_pBuffer = (TCHAR*)m_pAllocator->Malloc( a_iLength + 1 );
158 m_iExcessLen = 0;
159
160 hasChanged = TTRUE;
161 }
162 else
163 {
164 m_iExcessLen = newExcessLen;
165 hasChanged = TFALSE;
166 }
167 }
168
169 m_iStrLen = a_iLength;
170 }
171
172 if ( a_bFreeMemory ) m_pBuffer[ 0 ] = '\0';
173 return hasChanged;
174}
175
176TString8& TString8::Format( const TCHAR* a_pcFormat, ... )
177{
178 va_list args;
179 va_start( args, a_pcFormat );
180 // TASSERT is only in T2String8
181
182 TCHAR buffer[ 1024 ];
183 TINT iResult = _vsnprintf( buffer, sizeof( buffer ), a_pcFormat, args );
184 TASSERT( iResult != -1, "PS2/GC/X360 do not correctly support _vsnprintf, this code will cause memory to be clobbered on those platforms! Increase the size of the destination string to avoid this problem" );
185 Copy( buffer, -1 );
186
187 return *this;
188}
189
190TString8& TString8::VFormat( const TCHAR* a_pcFormat, va_list a_vargs )
191{
192 TCHAR buffer[ 0x400 ];
193
194 // TASSERT is only in T2String8
195 TINT iResult = _vsnprintf( buffer, sizeof( buffer ), a_pcFormat, a_vargs );
196 TASSERT( iResult != -1, "PS2/GC/X360 do not correctly support _vsnprintf, this code will cause memory to be clobbered on those platforms! Increase the size of the destination string to avoid this problem" );
197 Copy( buffer, -1 );
198
199 return *this;
200}
201
202TString8 TString8::VarArgs( const TCHAR* a_pcFormat, ... )
203{
204 TCHAR buffer[ 0x400 ];
205 TString8 buffer2;
206 va_list args;
207
208 va_start( args, a_pcFormat );
209
210 // TASSERT is only in T2String8
211 TINT iResult = _vsnprintf( buffer, sizeof( buffer ), a_pcFormat, args );
212 TASSERT( iResult != -1, "PS2/GC/X360 do not correctly support _vsnprintf, this code will cause memory to be clobbered on those platforms! Increase the size of the destination string to avoid this problem" );
213 buffer2.Copy( buffer, -1 );
214
215 return buffer2;
216}
217
218void TString8::ForceSetData( TCHAR* a_cString, TINT a_iLength )
219{
220 m_pBuffer = a_cString;
221
222 if ( a_iLength < 0 )
223 {
224 m_iStrLen = TINT( TStringManager::String8Length( a_cString ) );
225 }
226 else
227 {
228 m_iStrLen = a_iLength;
229 }
230
231 m_iExcessLen = 0;
232}
233
234TINT TString8::FindReverse( TCHAR a_findChar, TINT pos ) const
235{
236 if ( pos == -1 )
237 {
238 pos = m_iStrLen;
239 }
240 else
241 {
242 if ( !IsIndexValid( pos ) ) return -1;
243 }
244
245
246 for ( ; pos > -1; pos-- )
247 {
248 if ( a_findChar == m_pBuffer[ pos ] )
249 {
250 return pos;
251 }
252 }
253
254 return -1;
255}
256
258{
259 if ( Length() < length )
260 {
261 length = Length();
262 }
263
264 TCHAR* oldBuffer = m_pBuffer;
265
266 TBOOL allocated = AllocBuffer( length, TFALSE );
267 if ( allocated )
268 {
269 TStringManager::String8Copy( m_pBuffer, oldBuffer, length );
270 }
271
272 m_pBuffer[ length ] = 0;
273
274 if ( allocated && Length() != 0 )
275 {
276 m_pAllocator->Free( oldBuffer );
277 }
278}
279
281{
282 if ( Length() != 0 ) m_pAllocator->Free( m_pBuffer );
283 Reset();
284}
285
286const TCHAR* TString8::GetString( TINT a_iIndex ) const
287{
288 TASSERT( a_iIndex >= 0 && a_iIndex <= (TINT)m_iStrLen );
289 if ( IsIndexValid( a_iIndex ) ) { return &m_pBuffer[ a_iIndex ]; }
290 return TNULL;
291}
292
294{
295 TASSERT( a_iIndex >= 0 && a_iIndex <= (TINT)m_iStrLen );
296 if ( IsIndexValid( a_iIndex ) ) { return &m_pBuffer[ a_iIndex ]; }
297 return TNULL;
298}
299
301{
303
304 if ( ( len < size ) || ( size == -1 ) )
305 {
306 size = len;
307 }
308
309 TINT oldLength = m_iStrLen;
310 TCHAR* oldString = m_pBuffer;
311
312 TBOOL allocated = AllocBuffer( m_iStrLen + size, TFALSE );
313
314 if ( allocated )
315 {
316 // since it has made a new buffer
317 // it needs to copy the old string
318 // to the new buffer
319
320 TStringManager::String8Copy( m_pBuffer, oldString, -1 );
321 }
322
323 TStringManager::String8Copy( m_pBuffer + oldLength, str, size );
324 m_pBuffer[ m_iStrLen ] = 0;
325
326 if ( allocated && oldLength != 0 )
327 {
328 m_pAllocator->Free( oldString );
329 }
330
331 return *this;
332}
333
335{
336 if ( size > Length() + TINT( ExcessLength() ) )
337 {
338 TINT iOldLength = m_iStrLen;
339 TCHAR* pOldString = m_pBuffer;
340 TINT iCopySize = TMath::Min( iOldLength, size );
341
342 // Reallocate buffer if necessary
343 TBOOL bAllocated = AllocBuffer( size, TFALSE );
344
345 // Update excess length
346 TASSERT( iCopySize <= size );
347 AllocBuffer( iCopySize, TFALSE );
348
349 if ( bAllocated )
350 {
351 TStringManager::String8Copy( m_pBuffer, pOldString, iCopySize );
352 m_pBuffer[ iCopySize ] = 0;
353 }
354
355 if ( bAllocated && iOldLength != 0 )
356 m_pAllocator->Free( pOldString );
357 }
358
359 return *this;
360}
361
362TINT TString8::Compare( const TCHAR* a_pcString, TINT a_iLength ) const
363{
364 TASSERT( a_pcString != TNULL, "TCString::Compare - Passed string cannot be TNULL" );
365 TASSERT( IsIndexValid( 0 ), "TCString::Compare - Index 0 is not valid" );
366 TASSERT( GetString() != TNULL, "TCString::Compare - String cannot be TNULL" );
367
368 if ( a_iLength != -1 )
369 return strncmp( GetString(), a_pcString, a_iLength );
370
371 return strcmp( GetString(), a_pcString );
372}
373
374TINT TString8::CompareNoCase( const TCHAR* a_pcString, TINT a_iLength ) const
375{
376 TASSERT( a_pcString != TNULL, "TCString::CompareNoCase - Passed string cannot be TNULL" );
377 TASSERT( IsIndexValid( 0 ), "TCString::CompareNoCase - Index 0 is not valid" );
378 TASSERT( GetString() != TNULL, "TCString::CompareNoCase - String cannot be TNULL" );
379
380 if ( a_iLength == -1 )
381 return _stricmp( GetString(), a_pcString );
382
383 return _strnicmp( GetString(), a_pcString, a_iLength );
384}
385
386TString8 TString8::Mid( TINT a_iFirst, TINT a_iCount ) const
387{
388 if ( a_iFirst < 0 )
389 {
390 a_iFirst = 0;
391 }
392 else if ( Length() <= a_iFirst )
393 {
394 // Can't return string bigger that the original
395 return TString8();
396 }
397
398 if ( a_iCount < 0 || Length() < a_iFirst + a_iCount )
399 {
400 a_iCount = Length() - a_iFirst;
401 }
402
403 TString8 strResult( a_iCount, TNULL );
404 TUtil::MemCopy( strResult.GetStringUnsafe(), GetString( a_iFirst ), a_iCount );
405 strResult[ a_iCount ] = '\0';
406
407 return strResult;
408}
409
411{
412 return Mid( a_iFrom, Length() - a_iFrom );
413}
414
416{
417 TINT len = str.Length();
418
419 if ( ( len < size ) || ( size == -1 ) )
420 {
421 size = len;
422 }
423
424 TUINT32 oldLength = m_iStrLen;
425 TCHAR* oldString = m_pBuffer;
426
427 TBOOL allocated = AllocBuffer( m_iStrLen + size, TFALSE );
428
429 if ( allocated )
430 {
431 // since it has made a new buffer
432 // it needs to copy the old string
433 // to the new buffer
434
435 TStringManager::String8Copy( m_pBuffer, oldString, -1 );
436 }
437
438 TStringManager::StringUnicodeToChar( m_pBuffer + oldLength, str.GetString(), size );
439 m_pBuffer[ m_iStrLen ] = 0;
440
441 if ( allocated && m_iStrLen != 0 )
442 {
443 m_pAllocator->Free( oldString );
444 }
445
446 return *this;
447}
448
450{
451 TCHAR* pChar = m_pBuffer;
452
453 while ( pChar < m_pBuffer + m_iStrLen )
454 {
455 TCHAR cChar = *pChar++;
456 if ( cChar >= 'A' && cChar <= 'Z' ) return TFALSE;
457 }
458
459 return TTRUE;
460}
461
463{
464 TCHAR* pChar = m_pBuffer;
465
466 while ( pChar < m_pBuffer + m_iStrLen )
467 {
468 TCHAR cChar = *pChar++;
469 if ( cChar >= 'a' && cChar <= 'z' ) return TFALSE;
470 }
471
472 return TTRUE;
473}
474
475TBOOL TString8::StartsWith( const TCHAR* a_szString, TINT a_iLength /*= -1 */ ) const
476{
477 TINT iStringLength = ( a_iLength != -1 ) ? a_iLength : T2String8::Length( a_szString );
478
479 if ( Length() < iStringLength )
480 return TFALSE;
481
482 return Compare( a_szString, iStringLength ) == 0;
483}
484
485TBOOL TString8::EndsWith( const TCHAR* a_szString, TINT a_iLength /*= -1 */ ) const
486{
487 TINT iStringLength = ( a_iLength != -1 ) ? a_iLength : T2String8::Length( a_szString );
488
489 if ( Length() < iStringLength )
490 return TFALSE;
491
492 return strncmp( GetString( Length() - iStringLength ), a_szString, iStringLength ) == 0;
493}
494
495TBOOL TString8::StartsWithNoCase( const TCHAR* a_szString, TINT a_iLength /*= -1 */ ) const
496{
497 TINT iStringLength = ( a_iLength != -1 ) ? a_iLength : T2String8::Length( a_szString );
498
499 if ( Length() < iStringLength )
500 return TFALSE;
501
502 return CompareNoCase( a_szString, iStringLength ) == 0;
503}
504
505TBOOL TString8::EndsWithNoCase( const TCHAR* a_szString, TINT a_iLength /*= -1 */ ) const
506{
507 TINT iStringLength = ( a_iLength != -1 ) ? a_iLength : T2String8::Length( a_szString );
508
509 if ( Length() < iStringLength )
510 return TFALSE;
511
512 return strnicmp( GetString( Length() - iStringLength ), a_szString, iStringLength ) == 0;
513}
514
#define TASSERT(X,...)
Definition Defines.h:138
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
Char string implementation for the Toshi engine.
wchar_t TWCHAR
Definition Typedefs.h:21
char TCHAR
Definition Typedefs.h:20
#define TNULL
Definition Typedefs.h:23
uint32_t TUINT32
Definition Typedefs.h:13
int TINT
Definition Typedefs.h:7
#define TFALSE
Definition Typedefs.h:24
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
TFORCEINLINE const T & Min(const T &a, const T &b)
static TSIZE Length(const TCHAR *str)
TINT Length() const
Definition TString16.h:73
const TWCHAR * GetString(TINT index=0) const
TString8 Mid(TINT a_iFirst, TINT a_iCount) const
Definition TString8.cpp:386
TBOOL EndsWithNoCase(const TCHAR *a_szString, TINT a_iLength=-1) const
Definition TString8.cpp:505
TString8 & Format(const TCHAR *a_pcFormat,...)
Definition TString8.cpp:176
TBOOL EndsWith(const TCHAR *a_szString, TINT a_iLength=-1) const
Definition TString8.cpp:485
TString8 & Concat(const TString8 &str, TINT size=-1)
Definition TString8.h:66
TINT Compare(const TCHAR *a_szString, TINT a_iLength=-1) const
Definition TString8.cpp:362
TCHAR * GetStringUnsafe(TINT a_iIndex=0)
Definition TString8.cpp:293
TINT Find(TCHAR character, TINT pos=0) const
Definition TString8.cpp:107
TBOOL IsAllLowerCase() const
Definition TString8.cpp:449
TBOOL AllocBuffer(TINT a_iLength, TBOOL a_bFreeMemory=true)
Definition TString8.cpp:127
TBOOL IsAllUpperCase() const
Definition TString8.cpp:462
TINT CompareNoCase(const TCHAR *a_szString, TINT a_iLength=-1) const
Definition TString8.cpp:374
TINT FindReverse(TCHAR a_findChar, TINT pos=-1) const
Definition TString8.cpp:234
static TString8 VarArgs(const TCHAR *a_pcFormat,...)
Definition TString8.cpp:202
TBOOL IsIndexValid(TINT a_iIndex) const
Definition TString8.h:103
TBOOL StartsWith(const TCHAR *a_szString, TINT a_iLength=-1) const
Definition TString8.cpp:475
TBOOL StartsWithNoCase(const TCHAR *a_szString, TINT a_iLength=-1) const
Definition TString8.cpp:495
TString8 & VFormat(const TCHAR *a_pcFormat, va_list a_vargs)
Definition TString8.cpp:190
void ForceSetData(TCHAR *a_pchString, TINT a_iLength)
Definition TString8.cpp:218
void Truncate(TINT length)
Definition TString8.cpp:257
void FreeBuffer()
Definition TString8.cpp:280
TINT Length() const
Definition TString8.h:93
void Copy(const TString8 &src, TINT size=-1)
Definition TString8.h:32
TUINT16 ExcessLength() const
Definition TString8.h:94
TString8 & Reserve(TINT size)
Definition TString8.cpp:334
const TCHAR * GetString(TINT a_iIndex=0) const
Definition TString8.cpp:286
TString8 Right(TINT a_iFrom) const
Definition TString8.cpp:410
static TSIZE String8Length(const TCHAR *str)
static TSIZE String16Length(const TWCHAR *str)
static TCHAR * String8Copy(TCHAR *dst, const TCHAR *src, TSIZE size=-1)
static TCHAR * StringUnicodeToChar(TCHAR *a_CharString, const TWCHAR *const &a_UnicodeString, TUINT32 a_iLength)
static void * MemCopy(void *dst, const void *src, TSIZE size)
Definition TUtil.h:90