OpenBarnyard
 
Loading...
Searching...
No Matches
TString16.cpp
Go to the documentation of this file.
1#include "ToshiPCH.h"
2#include "TString16.h"
3
4#include "Toshi/TSystem.h"
5
6//-----------------------------------------------------------------------------
7// Enables memory debugging.
8// Note: Should be the last include!
9//-----------------------------------------------------------------------------
10#include "Core/TMemoryDebugOn.h"
11
13
15{
16 Reset();
17 m_pAllocator = GetAllocator();
18}
19
21{
22 Reset();
23 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
24}
25
27{
28 TString16::m_pAllocator = src.m_pAllocator;
29 TString16::m_iExcessLen = src.m_iExcessLen;
30 TString16::m_iStrLen = src.m_iStrLen;
31 TString16::m_pBuffer = src.m_pBuffer;
32 src.Reset();
33}
34
36{
37 Reset();
38 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
39 Copy( src, -1 );
40}
41
43{
44 Reset();
45 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
46 AllocBuffer( size );
47}
48
49TString16::TString16( const TWCHAR* src, T2Allocator* allocator )
50{
51 Reset();
52 m_pAllocator = allocator == TNULL ? GetAllocator() : allocator;
53 Copy( src );
54}
55
56void TString16::Copy( const TWCHAR* src, TINT size )
57{
58 if ( src != m_pBuffer )
59 {
60 TINT srcLen = src ? (TINT)TStringManager::String16Length( src ) : 0;
61 TASSERT( srcLen <= 0xFFFFFF, "Too big string" );
62
63 if ( srcLen < size || size == -1 )
64 {
65 size = srcLen;
66 }
67
68 AllocBuffer( size, TTRUE );
69 TUtil::MemCopy( m_pBuffer, src, size * sizeof( TWCHAR ) );
70
71 m_pBuffer[ size ] = 0;
72 }
73}
74
75TINT TString16::Find( TWCHAR character, TINT pos ) const
76{
77 if ( !IsIndexValid( pos ) ) return -1;
78
79 const TWCHAR* foundAt = wcschr( &m_pBuffer[ pos ], character );
80 if ( foundAt == TNULL ) return -1;
81
82 return (TINT)( foundAt - m_pBuffer );
83}
84
85TINT TString16::Find( const TWCHAR* substr, TINT pos ) const
86{
87 if ( !IsIndexValid( pos ) ) return -1;
88
89 const TWCHAR* foundAt = wcsstr( GetString( pos ), substr );
90 if ( foundAt == TNULL ) return -1;
91
92 return (TINT)( foundAt - m_pBuffer );
93}
94
95TBOOL TString16::AllocBuffer( TINT a_iLength, TBOOL freeMemory )
96{
97 TBOOL hasChanged = TFALSE;
98 TINT currentLength = Length();
99
100 TASSERT( a_iLength >= 0, "Length can't be less than 0" );
101 TASSERT( a_iLength <= 0xFFFFFF, "Too big string" );
102
103 if ( a_iLength != currentLength )
104 {
105 if ( a_iLength == 0 )
106 {
107 if ( freeMemory ) m_pAllocator->Free( m_pBuffer );
108
109 m_pBuffer = NullWString;
110 m_iExcessLen = 0;
111
112 hasChanged = TTRUE;
113 }
114 else
115 {
116 TINT newExcessLen = ( currentLength - a_iLength ) + m_iExcessLen;
117
118 if ( newExcessLen < 0 || newExcessLen > 0xFF )
119 {
120 if ( currentLength != 0 && freeMemory )
121 {
122 m_pAllocator->Free( m_pBuffer );
123 }
124
125 m_pBuffer = (TWCHAR*)m_pAllocator->Malloc( ( a_iLength + 1 ) * sizeof( TWCHAR ) );
126 m_iExcessLen = 0;
127
128 hasChanged = TTRUE;
129 }
130 else
131 {
132 m_iExcessLen = newExcessLen;
133 hasChanged = TFALSE;
134 }
135 }
136
137 m_iStrLen = a_iLength;
138 }
139
140 if ( freeMemory ) m_pBuffer[ 0 ] = L'\0';
141 return hasChanged;
142}
143
144TString16 TString16::Format( const TWCHAR* a_pcFormat, ... )
145{
146 TWCHAR buffer[ 0x400 ];
147 TString16 buffer2;
148 va_list args;
149
150 va_start( args, a_pcFormat );
151
152 TINT iResult = _vsnwprintf( buffer, sizeof( buffer ), a_pcFormat, args );
153 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" );
154 buffer2.Copy( buffer, -1 );
155
156 return buffer2;
157}
158
159TString16& TString16::VFormat( const TWCHAR* a_pcFormat, va_list a_vargs )
160{
161 TWCHAR buffer[ 0x400 ];
162
163 TINT iResult = _vsnwprintf( buffer, sizeof( buffer ), a_pcFormat, a_vargs );
164 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" );
165 Copy( buffer, -1 );
166
167 return *this;
168}
169
170void TString16::ForceSetData( TWCHAR* a_cString, TINT a_iLength )
171{
172 m_pBuffer = a_cString;
173
174 if ( a_iLength < 0 )
175 {
176 m_iStrLen = TStringManager::String16Length( a_cString );
177 }
178 else
179 {
180 m_iStrLen = a_iLength;
181 }
182
183 m_iExcessLen = 0;
184}
185
186TINT TString16::FindReverse( TWCHAR a_findChar, TINT pos ) const
187{
188 if ( pos == -1 )
189 {
190 pos = m_iStrLen;
191 }
192 else
193 {
194 if ( !IsIndexValid( pos ) ) return -1;
195 }
196
197
198 for ( ; pos > -1; pos-- )
199 {
200 if ( a_findChar == m_pBuffer[ pos ] )
201 {
202 return pos;
203 }
204 }
205
206 return -1;
207}
208
210{
211 if ( Length() < length )
212 {
213 length = Length();
214 }
215
216 TWCHAR* oldBuffer = m_pBuffer;
217
218 TBOOL allocated = AllocBuffer( length, TFALSE );
219 if ( allocated )
220 {
221 TStringManager::String16Copy( m_pBuffer, oldBuffer, length );
222 }
223
224 m_pBuffer[ length ] = 0;
225
226 if ( allocated && Length() != 0 )
227 {
228 m_pAllocator->Free( oldBuffer );
229 }
230}
231
233{
234 if ( Length() != 0 ) m_pAllocator->Free( m_pBuffer );
235 Reset();
236}
237
238const TWCHAR* TString16::GetString( TINT a_iIndex ) const
239{
240 TASSERT( a_iIndex >= 0 && a_iIndex <= m_iStrLen );
241 if ( IsIndexValid( a_iIndex ) ) { return &m_pBuffer[ a_iIndex ]; }
242 return TNULL;
243}
244
246{
247 TASSERT( a_iIndex >= 0 && a_iIndex <= m_iStrLen );
248 if ( IsIndexValid( a_iIndex ) ) { return &m_pBuffer[ a_iIndex ]; }
249 return TNULL;
250}
251
253{
255
256 if ( ( len < size ) || ( size == -1 ) )
257 {
258 size = len;
259 }
260
261 TINT oldLength = m_iStrLen;
262 TWCHAR* oldString = m_pBuffer;
263
264 TBOOL allocated = AllocBuffer( m_iStrLen + size, TFALSE );
265
266 if ( allocated )
267 {
268 // since it has made a new buffer
269 // it need to copy the old string
270 // to the new buffer
271
272 TStringManager::String16Copy( m_pBuffer, oldString, -1 );
273 }
274
275 TStringManager::String16Copy( m_pBuffer + oldLength, str, size );
276 m_pBuffer[ m_iStrLen ] = 0;
277
278 if ( allocated && oldLength != 0 )
279 {
280 m_pAllocator->Free( oldString );
281 }
282
283 return *this;
284}
285
286TINT TString16::Compare( const TWCHAR* a_pcString, TINT param_2 ) const
287{
288 TASSERT( a_pcString != TNULL, "TCString::CompareNoCase - Passed string cannot be TNULL" );
289 TASSERT( IsIndexValid( 0 ), "TCString::CompareNoCase - Index 0 is not valid" );
290 TASSERT( GetString() != TNULL, "TCString::CompareNoCase - String cannot be TNULL" );
291
292 if ( param_2 != -1 )
293 {
294 return wcsncmp( GetString(), a_pcString, param_2 );
295 }
296
297 const TWCHAR* str = GetString();
298 TWCHAR bVar1 = 0;
299 TWCHAR bVar4 = 0;
300 while ( TTRUE )
301 {
302 bVar1 = *str;
303 bVar4 = bVar1 < *a_pcString;
304
305 if ( bVar1 != *a_pcString ) break;
306 if ( bVar1 == 0 ) return 0;
307
308 bVar1 = str[ 1 ];
309 bVar4 = bVar1 < a_pcString[ 1 ];
310
311 if ( bVar1 != a_pcString[ 1 ] ) break;
312 if ( bVar1 == 0 ) return 0;
313
314 str += 2;
315 a_pcString += 2;
316 }
317 return bVar4 | 1;
318}
319
321{
322 if ( size > Length() + TINT( ExcessLength() ) )
323 {
324 TINT iOldLength = m_iStrLen;
325 TWCHAR* pOldString = m_pBuffer;
326 TINT iCopySize = TMath::Min( iOldLength, size );
327
328 TBOOL bAllocated = AllocBuffer( size, TFALSE );
329
330 if ( bAllocated )
331 {
332 TStringManager::String16Copy( m_pBuffer, pOldString, iCopySize );
333 m_pBuffer[ iCopySize ] = 0;
334 }
335
336 if ( bAllocated && iOldLength != 0 )
337 m_pAllocator->Free( pOldString );
338 }
339
340 return *this;
341}
342
343TINT TString16::CompareNoCase( const TWCHAR* a_pcString, TINT param_2 ) const
344{
345 TASSERT( a_pcString != TNULL, "TWString::CompareNoCase - Passed string cannot be TNULL" );
346 TASSERT( IsIndexValid( 0 ), "TWString::CompareNoCase - Index 0 is not valid" );
347 TASSERT( GetString() != TNULL, "TWString::CompareNoCase - String cannot be TNULL" );
348
349 if ( param_2 == -1 )
350 {
351 return _wcsicmp( GetString(), a_pcString );
352 }
353
354 TASSERT( IsIndexValid( 0 ), "TWString::CompareNoCase - Index 0 is not valid" );
355
356 return _wcsnicmp( GetString(), a_pcString, param_2 );
357}
358
359TString16 TString16::Mid( TINT a_iFirst, TINT a_iCount ) const
360{
361 if ( a_iFirst < 0 )
362 {
363 a_iFirst = 0;
364 }
365 else if ( Length() <= a_iFirst )
366 {
367 // Can't return string bigger that the original
368 return TString16();
369 }
370
371 if ( a_iCount < 0 || Length() < a_iFirst + a_iCount )
372 {
373 a_iCount = Length() - a_iFirst;
374 }
375
376 TString16 strResult( a_iCount, TNULL );
377 TUtil::MemCopy( strResult.GetStringUnsafe(), GetString( a_iFirst ), a_iCount * 2 );
378 strResult[ a_iCount ] = '\0';
379
380 return strResult;
381}
382
384{
385 return Mid( a_iFrom, Length() - a_iFrom );
386}
387
389{
390 if ( m_iStrLen != 0 )
391 {
392 TWCHAR* iter = m_pBuffer;
393 TWCHAR* endStr = m_pBuffer + m_iStrLen;
394
395 do
396 {
397 TWCHAR currentC = *iter++;
398 if ( !iswlower( currentC ) ) return TFALSE;
399 } while ( iter < endStr );
400 }
401
402 return TTRUE;
403}
404
406{
407 if ( m_iStrLen != 0 )
408 {
409 TWCHAR* iter = m_pBuffer;
410 TWCHAR* endStr = m_pBuffer + m_iStrLen;
411
412 do
413 {
414 TWCHAR currentC = *iter++;
415 if ( !iswupper( currentC ) ) return TFALSE;
416 } while ( iter < endStr );
417 }
418
419 return TTRUE;
420}
421
#define TASSERT(X,...)
Definition Defines.h:138
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
wchar_t TWCHAR
Definition Typedefs.h:21
#define TNULL
Definition Typedefs.h:23
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)
TString16 & Concat(const TString16 &str, TINT size=-1)
Definition TString16.h:48
void Copy(const TString16 &src, TINT size=-1)
Definition TString16.h:18
TString16 Mid(TINT a_iFirst, TINT a_iCount) const
TBOOL AllocBuffer(TINT size, TBOOL freeMemory=true)
Definition TString16.cpp:95
TString16 Right(TINT a_iFrom) const
TINT Find(TWCHAR character, TINT pos=0) const
Definition TString16.cpp:75
TString16 & Reserve(TINT size)
TBOOL IsAllLowerCase() const
TUINT16 ExcessLength() const
Definition TString16.h:74
TWCHAR * GetStringUnsafe(TINT a_iIndex=0)
TINT CompareNoCase(const TWCHAR *a_wszString, TINT a_iLength=-1) const
void ForceSetData(TWCHAR *a_cString, TINT a_ilength)
TString16 & VFormat(const TWCHAR *a_pcFormat, va_list a_vargs)
TINT Length() const
Definition TString16.h:73
const TWCHAR * GetString(TINT index=0) const
TINT Compare(const TWCHAR *a_wszString, TINT a_iLength=-1) const
static TString16 Format(const TWCHAR *a_pcFormat,...)
void Truncate(TINT length)
TBOOL IsIndexValid(TINT index) const
Definition TString16.h:78
void FreeBuffer()
TBOOL IsAllUpperCase() const
TINT FindReverse(TWCHAR a_findChar, TINT pos=-1) const
static TWCHAR * String16Copy(TWCHAR *dst, const TWCHAR *src, TSIZE size=-1)
static TSIZE String16Length(const TWCHAR *str)
static void * MemCopy(void *dst, const void *src, TSIZE size)
Definition TUtil.h:90