00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00044 #ifndef _orxSTRING_H_
00045 #define _orxSTRING_H_
00046
00047
00048 #include "orxInclude.h"
00049 #include "memory/orxMemory.h"
00050 #include "math/orxVector.h"
00051
00052 #ifdef __orxMSVC__
00053
00054 #pragma warning(disable : 4996)
00055
00056 #endif
00057
00058 #include <stdio.h>
00059 #include <stdarg.h>
00060 #include <string.h>
00061 #include <stdlib.h>
00062
00063 #include "debug/orxDebug.h"
00064
00065
00066 #define orxSTRING_KC_VECTOR_START '('
00067 #define orxSTRING_KC_VECTOR_START_ALT '{'
00068 #define orxSTRING_KC_VECTOR_SEPARATOR ','
00069 #define orxSTRING_KC_VECTOR_END ')'
00070 #define orxSTRING_KC_VECTOR_END_ALT '}'
00071
00072
00073 extern orxDLLAPI const orxU32 sau32CRCTable[256];
00074
00075
00076
00077
00078
00084 static orxINLINE orxU32 orxString_ContinueCRC(const orxSTRING _zString, orxU32 _u32CRC)
00085 {
00086 orxU32 u32CRC;
00087 const orxCHAR *pc;
00088
00089
00090 orxASSERT(_zString != orxNULL);
00091
00092
00093 u32CRC = _u32CRC ^ 0xFFFFFFFFL;
00094
00095
00096 for(pc = _zString; *pc != orxCHAR_NULL; pc++)
00097 {
00098
00099 u32CRC = sau32CRCTable[(u32CRC ^ *pc) & 0xFF] ^ (u32CRC >> 8);
00100 }
00101
00102
00103 return(u32CRC ^ 0xFFFFFFFFL);
00104 }
00105
00112 static orxINLINE orxU32 orxString_NContinueCRC(const orxSTRING _zString, orxU32 _u32CRC, orxU32 _u32CharNumber)
00113 {
00114 orxU32 u32CRC;
00115 orxU32 u32Counter;
00116 const orxCHAR *pc;
00117
00118
00119 orxASSERT(_zString != orxNULL);
00120
00121
00122 u32CRC = _u32CRC ^ 0xFFFFFFFFL;
00123
00124
00125 for(pc = _zString, u32Counter = 0; (*pc != orxCHAR_NULL) && (u32Counter < _u32CharNumber); pc++, u32Counter++)
00126 {
00127
00128 u32CRC = sau32CRCTable[(u32CRC ^ *pc) & 0xFF] ^ (u32CRC >> 8);
00129 }
00130
00131
00132 return(u32CRC ^ 0xFFFFFFFFL);
00133 }
00134
00139 static orxINLINE const orxSTRING orxString_SkipWhiteSpaces(const orxSTRING _zString)
00140 {
00141 const orxSTRING zResult;
00142
00143
00144 if(_zString != orxNULL)
00145 {
00146
00147 for(zResult = _zString; (*zResult == ' ') || (*zResult == '\t'); zResult++);
00148
00149
00150 if(*zResult == orxCHAR_NULL)
00151 {
00152
00153 zResult = orxSTRING_EMPTY;
00154 }
00155 }
00156 else
00157 {
00158
00159 zResult = orxNULL;
00160 }
00161
00162
00163 return zResult;
00164 }
00165
00170 static orxINLINE const orxSTRING orxString_SkipPath(const orxSTRING _zString)
00171 {
00172 const orxSTRING zResult;
00173
00174
00175 if(_zString != orxNULL)
00176 {
00177 const orxCHAR *pc;
00178
00179
00180 zResult = _zString;
00181
00182
00183 for(pc = _zString; *pc != orxCHAR_NULL; pc++)
00184 {
00185
00186 if((*pc == orxCHAR_DIRECTORY_SEPARATOR_LINUX) || (*pc == orxCHAR_DIRECTORY_SEPARATOR_WINDOWS))
00187 {
00188 orxCHAR cNextChar = *(pc + 1);
00189
00190
00191 if((cNextChar != orxCHAR_NULL) && (cNextChar != orxCHAR_DIRECTORY_SEPARATOR_LINUX) && (cNextChar != orxCHAR_DIRECTORY_SEPARATOR_WINDOWS))
00192 {
00193
00194 zResult = pc + 1;
00195 }
00196 }
00197 }
00198 }
00199 else
00200 {
00201
00202 zResult = orxNULL;
00203 }
00204
00205
00206 return zResult;
00207 }
00208
00213 static orxINLINE orxU32 orxString_GetLength(const orxSTRING _zString)
00214 {
00215
00216 orxASSERT(_zString != orxNULL);
00217
00218
00219 return((orxU32)strlen(_zString));
00220 }
00221
00226 static orxINLINE orxBOOL orxString_IsCharacterASCII(orxU32 _u32CharacterCodePoint)
00227 {
00228 return((_u32CharacterCodePoint < 0x80) ? orxTRUE : orxFALSE);
00229 }
00230
00235 static orxINLINE orxBOOL orxString_GetUTF8CharacterLength(orxU32 _u32CharacterCodePoint)
00236 {
00237 orxU32 u32Result;
00238
00239
00240 if(_u32CharacterCodePoint < 0x80)
00241 {
00242
00243 u32Result = 1;
00244 }
00245 else if(_u32CharacterCodePoint < 0x0800)
00246 {
00247
00248 u32Result = 2;
00249 }
00250 else if(_u32CharacterCodePoint < 0x00010000)
00251 {
00252
00253 u32Result = 3;
00254 }
00255 else if(_u32CharacterCodePoint < 0x00110000)
00256 {
00257
00258 u32Result = 4;
00259 }
00260 else
00261 {
00262
00263 u32Result = orxU32_UNDEFINED;
00264 }
00265
00266
00267 return u32Result;
00268 }
00269
00276 static orxU32 orxFASTCALL orxString_PrintUTF8Character(orxSTRING _zDstString, orxU32 _u32Size, orxU32 _u32CharacterCodePoint)
00277 {
00278 orxU32 u32Result;
00279
00280
00281 u32Result = orxString_GetUTF8CharacterLength(_u32CharacterCodePoint);
00282
00283
00284 if(u32Result <= _u32Size)
00285 {
00286
00287 switch(u32Result)
00288 {
00289 case 1:
00290 {
00291
00292 *_zDstString = (orxCHAR)_u32CharacterCodePoint;
00293
00294 break;
00295 }
00296
00297 case 2:
00298 {
00299
00300 *_zDstString++ = (orxCHAR)(0xC0 | ((_u32CharacterCodePoint & 0x07C0) >> 6));
00301
00302
00303 *_zDstString = (orxCHAR)(0x80 | (_u32CharacterCodePoint & 0x3F));
00304
00305 break;
00306 }
00307
00308 case 3:
00309 {
00310
00311 *_zDstString++ = (orxCHAR)(0xE0 | ((_u32CharacterCodePoint & 0xF000) >> 12));
00312
00313
00314 *_zDstString++ = (orxCHAR)(0x80 | ((_u32CharacterCodePoint & 0x0FC0) >> 6));
00315
00316
00317 *_zDstString = (orxCHAR)(0x80 | (_u32CharacterCodePoint & 0x3F));
00318
00319 break;
00320 }
00321
00322 case 4:
00323 {
00324
00325 *_zDstString++ = (orxCHAR)(0xF0 | ((_u32CharacterCodePoint & 0x001C0000) >> 18));
00326
00327
00328 *_zDstString++ = (orxCHAR)(0x80 | ((_u32CharacterCodePoint & 0x0003F000) >> 12));
00329
00330
00331 *_zDstString++ = (orxCHAR)(0x80 | ((_u32CharacterCodePoint & 0x00000FC0) >> 6));
00332
00333
00334 *_zDstString = (orxCHAR)(0x80 | (_u32CharacterCodePoint & 0x3F));
00335
00336 break;
00337 }
00338
00339 default:
00340 {
00341
00342 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Can't print invalid unicode character <0x%X> to string.", _u32CharacterCodePoint);
00343
00344
00345 u32Result = orxU32_UNDEFINED;
00346
00347 break;
00348 }
00349 }
00350 }
00351 else
00352 {
00353
00354 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Can't print unicode character <0x%X> to string as there isn't enough space for it.", _u32CharacterCodePoint);
00355
00356
00357 u32Result = orxU32_UNDEFINED;
00358 }
00359
00360
00361 return u32Result;
00362 }
00363
00369 static orxU32 orxFASTCALL orxString_GetFirstCharacterCodePoint(const orxSTRING _zString, const orxSTRING *_pzRemaining)
00370 {
00371 orxU8 *pu8Byte;
00372 orxU32 u32Result;
00373
00374
00375 orxASSERT(_zString != orxNULL);
00376
00377
00378 pu8Byte = (orxU8 *)_zString;
00379
00380
00381 if(*pu8Byte < 0x80)
00382 {
00383
00384 u32Result = *pu8Byte;
00385 }
00386
00387 else if(*pu8Byte < 0xC0)
00388 {
00389
00390 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: multi-byte sequence non-leading byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00391
00392
00393 u32Result = orxU32_UNDEFINED;
00394 }
00395
00396 else if(*pu8Byte < 0xC2)
00397 {
00398
00399 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: overlong 2-byte sequence starting with byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00400
00401
00402 u32Result = orxU32_UNDEFINED;
00403 }
00404
00405 else if(*pu8Byte < 0xE0)
00406 {
00407
00408 u32Result = *pu8Byte++ & 0x1F;
00409
00410
00411 if((*pu8Byte & 0xC0) == 0x80)
00412 {
00413
00414 u32Result = (u32Result << 6) | (*pu8Byte & 0x3F);
00415 }
00416 else
00417 {
00418
00419 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: 2-byte sequence non-trailing byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00420
00421
00422 u32Result = orxU32_UNDEFINED;
00423 }
00424 }
00425
00426 else if(*pu8Byte < 0xF0)
00427 {
00428
00429 u32Result = *pu8Byte++ & 0x0F;
00430
00431
00432 if((*pu8Byte & 0xC0) == 0x80)
00433 {
00434
00435 u32Result = (u32Result << 6) | (*pu8Byte++ & 0x3F);
00436
00437
00438 if((*pu8Byte & 0xC0) == 0x80)
00439 {
00440
00441 u32Result = (u32Result << 6) | (*pu8Byte & 0x3F);
00442 }
00443 else
00444 {
00445
00446 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: 3-byte sequence non-trailing byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00447
00448
00449 u32Result = orxU32_UNDEFINED;
00450 }
00451 }
00452 else
00453 {
00454
00455 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: 3-byte sequence non-trailing byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00456
00457
00458 u32Result = orxU32_UNDEFINED;
00459 }
00460 }
00461
00462 else if(*pu8Byte < 0xF5)
00463 {
00464
00465 u32Result = *pu8Byte++ & 0x07;
00466
00467
00468 if((*pu8Byte & 0xC0) == 0x80)
00469 {
00470
00471 u32Result = (u32Result << 6) | (*pu8Byte++ & 0x3F);
00472
00473
00474 if((*pu8Byte & 0xC0) == 0x80)
00475 {
00476
00477 u32Result = (u32Result << 6) | (*pu8Byte++ & 0x3F);
00478
00479
00480 if((*pu8Byte & 0xC0) == 0x80)
00481 {
00482
00483 u32Result = (u32Result << 6) | (*pu8Byte & 0x3F);
00484 }
00485 else
00486 {
00487
00488 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: 4-byte sequence non-trailing byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00489
00490
00491 u32Result = orxU32_UNDEFINED;
00492 }
00493 }
00494 else
00495 {
00496
00497 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: 4-byte sequence non-trailing byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00498
00499
00500 u32Result = orxU32_UNDEFINED;
00501 }
00502 }
00503 else
00504 {
00505
00506 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: 4-byte sequence non-trailing byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00507
00508
00509 u32Result = orxU32_UNDEFINED;
00510 }
00511 }
00512 else
00513 {
00514
00515 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: invalid out-of-bound byte '%c' (0x%2X) at index %ld.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
00516
00517
00518 u32Result = orxU32_UNDEFINED;
00519 }
00520
00521
00522 if(_pzRemaining != orxNULL)
00523 {
00524
00525 *_pzRemaining = (orxSTRING)(pu8Byte + 1);
00526 }
00527
00528
00529 return u32Result;
00530 }
00531
00536 static orxINLINE orxU32 orxString_GetCharacterCounter(const orxSTRING _zString)
00537 {
00538 const orxCHAR *pc;
00539 orxU32 u32Result;
00540
00541
00542 orxASSERT(_zString != orxNULL);
00543
00544
00545 for(pc = _zString, u32Result = 0; *pc != orxCHAR_NULL; u32Result++)
00546 {
00547
00548 if(orxString_GetFirstCharacterCodePoint(pc, &pc) == orxU32_UNDEFINED)
00549 {
00550
00551 u32Result = orxU32_UNDEFINED;
00552
00553
00554 orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF8 string <%s>, can't count characters.", _zString);
00555
00556 break;
00557 }
00558 }
00559
00560
00561 return u32Result;
00562 }
00563
00570 static orxINLINE orxSTRING orxString_NCopy(orxSTRING _zDstString, const orxSTRING _zSrcString, orxU32 _u32CharNumber)
00571 {
00572
00573 orxASSERT(_zDstString != orxNULL);
00574 orxASSERT(_zSrcString != orxNULL);
00575
00576
00577 return(strncpy(_zDstString, _zSrcString, _u32CharNumber));
00578 }
00579
00585 static orxINLINE orxSTRING orxString_Copy(orxSTRING _zDstString, const orxSTRING _zSrcString)
00586 {
00587
00588 orxASSERT(_zDstString != orxNULL);
00589 orxASSERT(_zSrcString != orxNULL);
00590
00591
00592 return(strcpy(_zDstString, _zSrcString));
00593 }
00594
00599 static orxINLINE orxSTRING orxString_Duplicate(const orxSTRING _zSrcString)
00600 {
00601 orxU32 u32Size;
00602 orxSTRING zResult;
00603
00604
00605 orxASSERT(_zSrcString != orxNULL);
00606
00607
00608 u32Size = (orxString_GetLength(_zSrcString) + 1) * sizeof(orxCHAR);
00609
00610
00611 zResult = (orxSTRING)orxMemory_Allocate(u32Size, orxMEMORY_TYPE_TEXT);
00612
00613
00614 if(zResult != orxNULL)
00615 {
00616
00617 orxMemory_Copy(zResult, _zSrcString, u32Size);
00618 }
00619
00620
00621 return zResult;
00622 }
00623
00627 static orxINLINE orxSTATUS orxString_Delete(orxSTRING _zString)
00628 {
00629
00630 orxASSERT(_zString != orxNULL);
00631 orxASSERT(_zString != orxSTRING_EMPTY);
00632
00633
00634 orxMemory_Free(_zString);
00635
00636
00637 return orxSTATUS_SUCCESS;
00638 }
00639
00646 static orxINLINE orxS32 orxString_Compare(const orxSTRING _zString1, const orxSTRING _zString2)
00647 {
00648
00649 orxASSERT(_zString1 != orxNULL);
00650 orxASSERT(_zString2 != orxNULL);
00651
00652
00653 return(strcmp(_zString1, _zString2));
00654 }
00655
00664 static orxINLINE orxS32 orxString_NCompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
00665 {
00666
00667 orxASSERT(_zString1 != orxNULL);
00668 orxASSERT(_zString2 != orxNULL);
00669
00670
00671 return strncmp(_zString1, _zString2, _u32CharNumber);
00672 }
00673
00680 static orxINLINE orxS32 orxString_ICompare(const orxSTRING _zString1, const orxSTRING _zString2)
00681 {
00682
00683 orxASSERT(_zString1 != orxNULL);
00684 orxASSERT(_zString2 != orxNULL);
00685
00686 #ifdef __orxWINDOWS__
00687
00688
00689 return(stricmp(_zString1, _zString2));
00690
00691 #else
00692
00693
00694 return strcasecmp(_zString1, _zString2);
00695
00696 #endif
00697 }
00698
00707 static orxINLINE orxS32 orxString_NICompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
00708 {
00709
00710 orxASSERT(_zString1 != orxNULL);
00711 orxASSERT(_zString2 != orxNULL);
00712
00713 #ifdef __orxWINDOWS__
00714
00715
00716 return strnicmp(_zString1, _zString2, _u32CharNumber);
00717
00718 #else
00719
00720
00721 return strncasecmp(_zString1, _zString2, _u32CharNumber);
00722
00723 #endif
00724 }
00725
00733 static orxINLINE orxSTATUS orxString_ToS32Base(const orxSTRING _zString, orxU32 _u32Base, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
00734 {
00735 orxCHAR *pcEnd;
00736 orxSTATUS eResult;
00737
00738
00739 orxASSERT(_ps32OutValue != orxNULL);
00740 orxASSERT(_zString != orxNULL);
00741
00742
00743 *_ps32OutValue = strtol(_zString, &pcEnd, _u32Base);
00744
00745
00746 if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
00747 {
00748
00749 eResult = orxSTATUS_SUCCESS;
00750 }
00751 else
00752 {
00753
00754 eResult = orxSTATUS_FAILURE;
00755 }
00756
00757
00758 if(_pzRemaining != orxNULL)
00759 {
00760
00761 *_pzRemaining = pcEnd;
00762 }
00763
00764
00765 return eResult;
00766 }
00767
00774 static orxINLINE orxSTATUS orxString_ToS32(const orxSTRING _zString, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
00775 {
00776 orxSTATUS eResult;
00777
00778
00779 orxASSERT(_ps32OutValue != orxNULL);
00780 orxASSERT(_zString != orxNULL);
00781
00782
00783 if((_zString[0] != orxCHAR_EOL)
00784 && (_zString[0] == '0')
00785 && (_zString[1] != orxCHAR_EOL)
00786 && ((_zString[1] | 0x20) == 'x'))
00787 {
00788
00789 eResult = orxString_ToS32Base(_zString + 2, 16, _ps32OutValue, _pzRemaining);
00790 }
00791
00792 else if((_zString[0] != orxCHAR_EOL)
00793 && (_zString[0] == '0')
00794 && (_zString[1] != orxCHAR_EOL)
00795 && ((_zString[1] | 0x20) == 'b'))
00796 {
00797
00798 eResult = orxString_ToS32Base(_zString + 2, 2, _ps32OutValue, _pzRemaining);
00799 }
00800
00801 else if((_zString[0] != orxCHAR_EOL)
00802 && ((_zString[0] | 0x20) == '0')
00803 && ((_zString[1]) >= '0')
00804 && ((_zString[1]) <= '9'))
00805 {
00806
00807 eResult = orxString_ToS32Base(_zString + 1, 8, _ps32OutValue, _pzRemaining);
00808 }
00809
00810 else
00811 {
00812
00813 eResult = orxString_ToS32Base(_zString, 10, _ps32OutValue, _pzRemaining);
00814 }
00815
00816
00817 return eResult;
00818 }
00819
00827 static orxINLINE orxSTATUS orxString_ToU32Base(const orxSTRING _zString, orxU32 _u32Base, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
00828 {
00829 orxCHAR *pcEnd;
00830 orxSTATUS eResult;
00831
00832
00833 orxASSERT(_pu32OutValue != orxNULL);
00834 orxASSERT(_zString != orxNULL);
00835
00836
00837 *_pu32OutValue = strtoul(_zString, &pcEnd, _u32Base);
00838
00839
00840 if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
00841 {
00842
00843 eResult = orxSTATUS_SUCCESS;
00844 }
00845 else
00846 {
00847
00848 eResult = orxSTATUS_FAILURE;
00849 }
00850
00851
00852 if(_pzRemaining != orxNULL)
00853 {
00854
00855 *_pzRemaining = pcEnd;
00856 }
00857
00858
00859 return eResult;
00860 }
00861
00868 static orxINLINE orxSTATUS orxString_ToU32(const orxSTRING _zString, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
00869 {
00870 orxSTATUS eResult;
00871
00872
00873 orxASSERT(_pu32OutValue != orxNULL);
00874 orxASSERT(_zString != orxNULL);
00875
00876
00877 if((_zString[0] != orxCHAR_EOL)
00878 && (_zString[0] == '0')
00879 && (_zString[1] != orxCHAR_EOL)
00880 && ((_zString[1] | 0x20) == 'x'))
00881 {
00882
00883 eResult = orxString_ToU32Base(_zString + 2, 16, _pu32OutValue, _pzRemaining);
00884 }
00885
00886 else if((_zString[0] != orxCHAR_EOL)
00887 && (_zString[0] == '0')
00888 && (_zString[1] != orxCHAR_EOL)
00889 && ((_zString[1] | 0x20) == 'b'))
00890 {
00891
00892 eResult = orxString_ToU32Base(_zString + 2, 2, _pu32OutValue, _pzRemaining);
00893 }
00894
00895 else if((_zString[0] != orxCHAR_EOL)
00896 && ((_zString[0] | 0x20) == '0')
00897 && ((_zString[1]) >= '0')
00898 && ((_zString[1]) <= '9'))
00899 {
00900
00901 eResult = orxString_ToU32Base(_zString + 1, 8, _pu32OutValue, _pzRemaining);
00902 }
00903
00904 else
00905 {
00906
00907 eResult = orxString_ToU32Base(_zString, 10, _pu32OutValue, _pzRemaining);
00908 }
00909
00910
00911 return eResult;
00912 }
00913
00920 static orxINLINE orxSTATUS orxString_ToFloat(const orxSTRING _zString, orxFLOAT *_pfOutValue, const orxSTRING *_pzRemaining)
00921 {
00922 orxCHAR *pcEnd;
00923 orxSTATUS eResult;
00924
00925
00926 orxASSERT(_pfOutValue != orxNULL);
00927 orxASSERT(_zString != orxNULL);
00928
00929
00930 #if defined(__orxLINUX__) || defined(__orxMAC__) || defined(__orxGP2X__) || defined(__orxWII__) || defined (__orxIPHONE__) || defined(__orxMSVC__) || defined(__orxANDROID__)
00931
00932
00933 *_pfOutValue = (orxFLOAT)strtod(_zString, &pcEnd);
00934
00935 #else
00936
00937
00938 *_pfOutValue = strtof(_zString, &pcEnd);
00939
00940 #endif
00941
00942
00943 if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
00944 {
00945
00946 eResult = orxSTATUS_SUCCESS;
00947 }
00948 else
00949 {
00950
00951 eResult = orxSTATUS_FAILURE;
00952 }
00953
00954
00955 if(_pzRemaining != orxNULL)
00956 {
00957
00958 *_pzRemaining = pcEnd;
00959 }
00960
00961
00962 return eResult;
00963 }
00964
00971 static orxINLINE orxSTATUS orxString_ToVector(const orxSTRING _zString, orxVECTOR *_pvOutValue, const orxSTRING *_pzRemaining)
00972 {
00973 orxVECTOR stValue;
00974 const orxSTRING zString;
00975 orxSTATUS eResult = orxSTATUS_FAILURE;
00976
00977
00978 orxASSERT(_pvOutValue != orxNULL);
00979 orxASSERT(_zString != orxNULL);
00980
00981
00982 zString = orxString_SkipWhiteSpaces(_zString);
00983
00984
00985 if((*zString == orxSTRING_KC_VECTOR_START)
00986 || (*zString == orxSTRING_KC_VECTOR_START_ALT))
00987 {
00988
00989 zString = orxString_SkipWhiteSpaces(zString + 1);
00990
00991
00992 eResult = orxString_ToFloat(zString, &(stValue.fX), &zString);
00993
00994
00995 if(eResult != orxSTATUS_FAILURE)
00996 {
00997
00998 zString = orxString_SkipWhiteSpaces(zString);
00999
01000
01001 if(*zString == orxSTRING_KC_VECTOR_SEPARATOR)
01002 {
01003
01004 zString = orxString_SkipWhiteSpaces(zString + 1);
01005
01006
01007 eResult = orxString_ToFloat(zString, &(stValue.fY), &zString);
01008
01009
01010 if(eResult != orxSTATUS_FAILURE)
01011 {
01012
01013 zString = orxString_SkipWhiteSpaces(zString);
01014
01015
01016 if(*zString == orxSTRING_KC_VECTOR_SEPARATOR)
01017 {
01018
01019 zString = orxString_SkipWhiteSpaces(zString + 1);
01020
01021
01022 eResult = orxString_ToFloat(zString, &(stValue.fZ), &zString);
01023
01024
01025 if(eResult != orxSTATUS_FAILURE)
01026 {
01027
01028 zString = orxString_SkipWhiteSpaces(zString);
01029
01030
01031 if((*zString != orxSTRING_KC_VECTOR_END)
01032 && (*zString != orxSTRING_KC_VECTOR_END_ALT))
01033 {
01034
01035 eResult = orxSTATUS_FAILURE;
01036 }
01037 }
01038 }
01039 }
01040 }
01041 }
01042 }
01043
01044
01045 if(eResult != orxSTATUS_FAILURE)
01046 {
01047
01048 orxVector_Copy(_pvOutValue, &stValue);
01049
01050
01051 if(_pzRemaining != orxNULL)
01052 {
01053
01054 *_pzRemaining = zString + 1;
01055 }
01056 }
01057
01058
01059 return eResult;
01060 }
01061
01068 static orxINLINE orxSTATUS orxString_ToBool(const orxSTRING _zString, orxBOOL *_pbOutValue, const orxSTRING *_pzRemaining)
01069 {
01070 orxS32 s32Value;
01071 orxSTATUS eResult;
01072
01073
01074 orxASSERT(_pbOutValue != orxNULL);
01075 orxASSERT(_zString != orxNULL);
01076
01077
01078 eResult = orxString_ToS32Base(_zString, 10, &s32Value, _pzRemaining);
01079
01080
01081 if(eResult != orxSTATUS_FAILURE)
01082 {
01083
01084 *_pbOutValue = (s32Value != 0) ? orxTRUE : orxFALSE;
01085 }
01086 else
01087 {
01088 orxU32 u32Length;
01089
01090
01091 u32Length = orxString_GetLength(orxSTRING_FALSE);
01092
01093
01094 if(orxString_NICompare(_zString, orxSTRING_FALSE, u32Length) == 0)
01095 {
01096
01097 *_pbOutValue = orxFALSE;
01098
01099
01100 if(_pzRemaining != orxNULL)
01101 {
01102
01103 *_pzRemaining += u32Length;
01104 }
01105
01106
01107 eResult = orxSTATUS_SUCCESS;
01108 }
01109 else
01110 {
01111
01112 u32Length = orxString_GetLength(orxSTRING_TRUE);
01113
01114
01115 if(orxString_NICompare(_zString, orxSTRING_TRUE, u32Length) == 0)
01116 {
01117
01118 *_pbOutValue = orxTRUE;
01119
01120
01121 if(_pzRemaining != orxNULL)
01122 {
01123
01124 *_pzRemaining += u32Length;
01125 }
01126
01127
01128 eResult = orxSTATUS_SUCCESS;
01129 }
01130 }
01131 }
01132
01133
01134 return eResult;
01135 }
01136
01141 static orxINLINE orxSTRING orxString_LowerCase(orxSTRING _zString)
01142 {
01143 orxCHAR *pc;
01144
01145
01146 orxASSERT(_zString != orxNULL);
01147
01148
01149 for(pc = _zString; *pc != orxCHAR_NULL; pc++)
01150 {
01151
01152 if(*pc >= 'A' && *pc <= 'Z')
01153 {
01154
01155 *pc |= 0x20;
01156 }
01157 }
01158
01159 return _zString;
01160 }
01161
01166 static orxINLINE orxSTRING orxString_UpperCase(orxSTRING _zString)
01167 {
01168 orxCHAR *pc;
01169
01170
01171 orxASSERT(_zString != orxNULL);
01172
01173
01174 for(pc = _zString; *pc != orxCHAR_NULL; pc++)
01175 {
01176
01177 if(*pc >= 'a' && *pc <= 'z')
01178 {
01179
01180 *pc &= ~0x20;
01181 }
01182 }
01183
01184 return _zString;
01185 }
01186
01191 static orxINLINE orxU32 orxString_ToCRC(const orxSTRING _zString)
01192 {
01193
01194 orxASSERT(_zString != orxNULL);
01195
01196
01197 return(orxString_ContinueCRC(_zString, 0));
01198 }
01199
01205 static orxINLINE orxU32 orxString_NToCRC(const orxSTRING _zString, orxU32 _u32CharNumber)
01206 {
01207
01208 orxASSERT(_zString != orxNULL);
01209
01210
01211 return(orxString_NContinueCRC(_zString, 0, _u32CharNumber));
01212 }
01213
01219 static orxINLINE const orxSTRING orxString_SearchString(const orxSTRING _zString1, const orxSTRING _zString2)
01220 {
01221
01222 orxASSERT(_zString1 != orxNULL);
01223 orxASSERT(_zString2 != orxNULL);
01224
01225
01226 return(strstr(_zString1, _zString2));
01227 }
01228
01234 static orxINLINE const orxSTRING orxString_SearchChar(const orxSTRING _zString, orxCHAR _cChar)
01235 {
01236
01237 orxASSERT(_zString != orxNULL);
01238
01239
01240 return(strchr(_zString, _cChar));
01241 }
01242
01249 static orxINLINE orxS32 orxString_SearchCharIndex(const orxSTRING _zString, orxCHAR _cChar, orxU32 _u32Position)
01250 {
01251 orxS32 s32Result = -1;
01252 orxS32 s32Index;
01253 const orxCHAR *pc;
01254
01255
01256 orxASSERT(_zString != orxNULL);
01257 orxASSERT(_u32Position <= orxString_GetLength(_zString));
01258
01259
01260 for(s32Index = _u32Position, pc = _zString + s32Index; *pc != orxCHAR_NULL; pc++, s32Index++)
01261 {
01262
01263 if(*pc == _cChar)
01264 {
01265
01266 s32Result = s32Index;
01267
01268 break;
01269 }
01270 }
01271
01272
01273 return s32Result;
01274 }
01275
01281 static orxINLINE orxS32 orxCDECL orxString_Print(orxSTRING _zDstString, const orxSTRING _zSrcString, ...)
01282 {
01283 va_list stArgs;
01284 orxS32 s32Result;
01285
01286
01287 orxASSERT(_zDstString != orxNULL);
01288 orxASSERT(_zSrcString != orxNULL);
01289
01290
01291 va_start(stArgs, _zSrcString);
01292 s32Result = vsprintf(_zDstString, _zSrcString, stArgs);
01293 va_end(stArgs);
01294
01295
01296 return s32Result;
01297 }
01298
01305 static orxINLINE orxS32 orxCDECL orxString_NPrint(orxSTRING _zDstString, orxU32 _u32CharNumber, const orxSTRING _zSrcString, ...)
01306 {
01307 va_list stArgs;
01308 orxS32 s32Result;
01309
01310
01311 orxASSERT(_zDstString != orxNULL);
01312 orxASSERT(_zSrcString != orxNULL);
01313
01314
01315 va_start(stArgs, _zSrcString);
01316 s32Result = vsnprintf(_zDstString, _u32CharNumber, _zSrcString, stArgs);
01317 va_end(stArgs);
01318
01319
01320 return s32Result;
01321 }
01322
01323 #ifdef __orxMSVC__
01324
01325 #pragma warning(default : 4996)
01326
01327 #endif
01328
01329 #endif
01330