orx  1.11
Portable Game Engine
orxString.h
Go to the documentation of this file.
1 /* Orx - Portable Game Engine
2  *
3  * Copyright (c) 2008-2020 Orx-Project
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  *
18  * 2. Altered source versions must be plainly marked as such, and must not be
19  * misrepresented as being the original software.
20  *
21  * 3. This notice may not be removed or altered from any source
22  * distribution.
23  */
24 
44 #ifndef _orxSTRING_H_
45 #define _orxSTRING_H_
46 
47 
48 #include "orxInclude.h"
49 #include "memory/orxMemory.h"
50 #include "math/orxVector.h"
51 
52 #ifdef __orxMSVC__
53 
54  #pragma warning(disable : 4996)
55 
56  #define strtoll _strtoi64
57  #define strtoull _strtoui64
58 
59 #endif /* __orxMSVC__ */
60 
61 #define STRTO_CAST (int)
62 
63 #include <stdio.h>
64 #include <stdarg.h>
65 #include <string.h>
66 #include <stdlib.h>
67 
68 #ifndef __orxWINDOWS__
69  #include <strings.h>
70 #endif /* !__orxWINDOWS__ */
71 
72 #include "debug/orxDebug.h"
73 
74 
75 #define orxSTRING_KC_VECTOR_START '('
76 #define orxSTRING_KC_VECTOR_START_ALT '{'
77 #define orxSTRING_KC_VECTOR_SEPARATOR ','
78 #define orxSTRING_KC_VECTOR_END ')'
79 #define orxSTRING_KC_VECTOR_END_ALT '}'
80 
81 
84 #define orxSTRING_KU32_CRC_POLYNOMIAL 0xEDB88320U
89 extern orxDLLAPI orxU32 saau32CRCTable[8][256];
90 
91 
92 /* *** String inlined functions *** */
93 
94 
99 static orxINLINE const orxSTRING orxString_SkipWhiteSpaces(const orxSTRING _zString)
100 {
101  const orxSTRING zResult;
102 
103  /* Non null? */
104  if(_zString != orxNULL)
105  {
106  /* Skips all white spaces */
107  for(zResult = _zString; (*zResult == ' ') || (*zResult == '\t') || (*zResult == orxCHAR_CR) || (*zResult == orxCHAR_LF); zResult++);
108 
109  /* Empty? */
110  if(*zResult == orxCHAR_NULL)
111  {
112  /* Updates result */
113  zResult = orxSTRING_EMPTY;
114  }
115  }
116  else
117  {
118  /* Updates result */
119  zResult = orxNULL;
120  }
121 
122  /* Done! */
123  return zResult;
124 }
125 
130 static orxINLINE const orxSTRING orxString_SkipPath(const orxSTRING _zString)
131 {
132  const orxSTRING zResult;
133 
134  /* Non null? */
135  if(_zString != orxNULL)
136  {
137  const orxCHAR *pc;
138 
139  /* Updates result */
140  zResult = _zString;
141 
142  /* For all characters */
143  for(pc = _zString; *pc != orxCHAR_NULL; pc++)
144  {
145  /* Is a directory separator? */
147  {
148  orxCHAR cNextChar = *(pc + 1);
149 
150  /* Non terminal and not a directory separator? */
151  if((cNextChar != orxCHAR_NULL) && (cNextChar != orxCHAR_DIRECTORY_SEPARATOR_LINUX) && (cNextChar != orxCHAR_DIRECTORY_SEPARATOR_WINDOWS))
152  {
153  /* Updates result */
154  zResult = pc + 1;
155  }
156  }
157  }
158  }
159  else
160  {
161  /* Updates result */
162  zResult = orxNULL;
163  }
164 
165  /* Done! */
166  return zResult;
167 }
168 
173 static orxINLINE orxU32 orxString_GetLength(const orxSTRING _zString)
174 {
175  /* Checks */
176  orxASSERT(_zString != orxNULL);
177 
178  /* Done! */
179  return((orxU32)strlen(_zString));
180 }
181 
186 static orxINLINE orxBOOL orxString_IsCharacterASCII(orxU32 _u32CharacterCodePoint)
187 {
188  /* Done! */
189  return((_u32CharacterCodePoint < 0x80) ? orxTRUE : orxFALSE);
190 }
191 
196 static orxINLINE orxBOOL orxString_IsCharacterAlphaNumeric(orxU32 _u32CharacterCodePoint)
197 {
198  /* Done! */
199  return (((_u32CharacterCodePoint >= 'a') && (_u32CharacterCodePoint <= 'z'))
200  || ((_u32CharacterCodePoint >= 'A') && (_u32CharacterCodePoint <= 'Z'))
201  || ((_u32CharacterCodePoint >= '0') && (_u32CharacterCodePoint <= '9'))) ? orxTRUE : orxFALSE;
202 }
203 
208 static orxINLINE orxU32 orxString_GetUTF8CharacterLength(orxU32 _u32CharacterCodePoint)
209 {
210  orxU32 u32Result;
211 
212  /* 1-byte long? */
213  if(_u32CharacterCodePoint < 0x80)
214  {
215  /* Updates result */
216  u32Result = 1;
217  }
218  else if(_u32CharacterCodePoint < 0x0800)
219  {
220  /* Updates result */
221  u32Result = 2;
222  }
223  else if(_u32CharacterCodePoint < 0x00010000)
224  {
225  /* Updates result */
226  u32Result = 3;
227  }
228  else if(_u32CharacterCodePoint < 0x00110000)
229  {
230  /* Updates result */
231  u32Result = 4;
232  }
233  else
234  {
235  /* Updates result */
236  u32Result = orxU32_UNDEFINED;
237  }
238 
239  /* Done! */
240  return u32Result;
241 }
242 
249 static orxU32 orxFASTCALL orxString_PrintUTF8Character(orxSTRING _zDstString, orxU32 _u32Size, orxU32 _u32CharacterCodePoint)
250 {
251  orxU32 u32Result;
252 
253  /* Gets character's encoded length */
254  u32Result = orxString_GetUTF8CharacterLength(_u32CharacterCodePoint);
255 
256  /* Enough room? */
257  if(u32Result <= _u32Size)
258  {
259  /* Depending on character's length */
260  switch(u32Result)
261  {
262  case 1:
263  {
264  /* Writes character */
265  *_zDstString = (orxCHAR)_u32CharacterCodePoint;
266 
267  break;
268  }
269 
270  case 2:
271  {
272  /* Writes first character */
273  *_zDstString++ = (orxCHAR)(0xC0 | ((_u32CharacterCodePoint & 0x07C0) >> 6));
274 
275  /* Writes second character */
276  *_zDstString = (orxCHAR)(0x80 | (_u32CharacterCodePoint & 0x3F));
277 
278  break;
279  }
280 
281  case 3:
282  {
283  /* Writes first character */
284  *_zDstString++ = (orxCHAR)(0xE0 | ((_u32CharacterCodePoint & 0xF000) >> 12));
285 
286  /* Writes second character */
287  *_zDstString++ = (orxCHAR)(0x80 | ((_u32CharacterCodePoint & 0x0FC0) >> 6));
288 
289  /* Writes third character */
290  *_zDstString = (orxCHAR)(0x80 | (_u32CharacterCodePoint & 0x3F));
291 
292  break;
293  }
294 
295  case 4:
296  {
297  /* Writes first character */
298  *_zDstString++ = (orxCHAR)(0xF0 | ((_u32CharacterCodePoint & 0x001C0000) >> 18));
299 
300  /* Writes second character */
301  *_zDstString++ = (orxCHAR)(0x80 | ((_u32CharacterCodePoint & 0x0003F000) >> 12));
302 
303  /* Writes third character */
304  *_zDstString++ = (orxCHAR)(0x80 | ((_u32CharacterCodePoint & 0x00000FC0) >> 6));
305 
306  /* Writes fourth character */
307  *_zDstString = (orxCHAR)(0x80 | (_u32CharacterCodePoint & 0x3F));
308 
309  break;
310  }
311 
312  default:
313  {
314  /* Logs message */
315  orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Can't print invalid unicode character <0x%X> to string.", _u32CharacterCodePoint);
316 
317  /* Updates result */
318  u32Result = orxU32_UNDEFINED;
319 
320  break;
321  }
322  }
323  }
324  else
325  {
326  /* Logs message */
327  orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Can't print unicode character <0x%X> to string as there isn't enough space for it.", _u32CharacterCodePoint);
328 
329  /* Updates result */
330  u32Result = orxU32_UNDEFINED;
331  }
332 
333  /* Done! */
334  return u32Result;
335 }
336 
342 static orxU32 orxFASTCALL orxString_GetFirstCharacterCodePoint(const orxSTRING _zString, const orxSTRING *_pzRemaining)
343 {
344  const orxU8 *pu8Byte;
345  orxU32 u32Result;
346 
347  /* Checks */
348  orxASSERT(_zString != orxNULL);
349 
350  /* Gets the first byte */
351  pu8Byte = (const orxU8 *)_zString;
352 
353  /* ASCII? */
354  if(*pu8Byte < 0x80)
355  {
356  /* Updates result */
357  u32Result = *pu8Byte;
358  }
359  /* Invalid UTF-8 byte sequence */
360  else if(*pu8Byte < 0xC0)
361  {
362  /* Logs message */
363  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 %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
364 
365  /* Updates result */
366  u32Result = orxU32_UNDEFINED;
367  }
368  /* Overlong UTF-8 2-byte sequence */
369  else if(*pu8Byte < 0xC2)
370  {
371  /* Logs message */
372  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 %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
373 
374  /* Updates result */
375  u32Result = orxU32_UNDEFINED;
376  }
377  /* 2-byte sequence */
378  else if(*pu8Byte < 0xE0)
379  {
380  /* Updates result with first character */
381  u32Result = *pu8Byte++ & 0x1F;
382 
383  /* Valid second character? */
384  if((*pu8Byte & 0xC0) == 0x80)
385  {
386  /* Updates result */
387  u32Result = (u32Result << 6) | (*pu8Byte & 0x3F);
388  }
389  else
390  {
391  /* Logs message */
392  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 %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
393 
394  /* Updates result */
395  u32Result = orxU32_UNDEFINED;
396  }
397  }
398  /* 3-byte sequence */
399  else if(*pu8Byte < 0xF0)
400  {
401  /* Updates result with first character */
402  u32Result = *pu8Byte++ & 0x0F;
403 
404  /* Valid second character? */
405  if((*pu8Byte & 0xC0) == 0x80)
406  {
407  /* Updates result */
408  u32Result = (u32Result << 6) | (*pu8Byte++ & 0x3F);
409 
410  /* Valid third character? */
411  if((*pu8Byte & 0xC0) == 0x80)
412  {
413  /* Updates result */
414  u32Result = (u32Result << 6) | (*pu8Byte & 0x3F);
415  }
416  else
417  {
418  /* Logs message */
419  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 %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
420 
421  /* Updates result */
422  u32Result = orxU32_UNDEFINED;
423  }
424  }
425  else
426  {
427  /* Logs message */
428  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 %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
429 
430  /* Updates result */
431  u32Result = orxU32_UNDEFINED;
432  }
433  }
434  /* 4-byte sequence */
435  else if(*pu8Byte < 0xF5)
436  {
437  /* Updates result with first character */
438  u32Result = *pu8Byte++ & 0x07;
439 
440  /* Valid second character? */
441  if((*pu8Byte & 0xC0) == 0x80)
442  {
443  /* Updates result */
444  u32Result = (u32Result << 6) | (*pu8Byte++ & 0x3F);
445 
446  /* Valid third character? */
447  if((*pu8Byte & 0xC0) == 0x80)
448  {
449  /* Updates result */
450  u32Result = (u32Result << 6) | (*pu8Byte++ & 0x3F);
451 
452  /* Valid fourth character? */
453  if((*pu8Byte & 0xC0) == 0x80)
454  {
455  /* Updates result */
456  u32Result = (u32Result << 6) | (*pu8Byte & 0x3F);
457  }
458  else
459  {
460  /* Logs message */
461  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 %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
462 
463  /* Updates result */
464  u32Result = orxU32_UNDEFINED;
465  }
466  }
467  else
468  {
469  /* Logs message */
470  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 %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
471 
472  /* Updates result */
473  u32Result = orxU32_UNDEFINED;
474  }
475  }
476  else
477  {
478  /* Logs message */
479  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 %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
480 
481  /* Updates result */
482  u32Result = orxU32_UNDEFINED;
483  }
484  }
485  else
486  {
487  /* Logs message */
488  orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF-8 string at <0x%X>: invalid out-of-bound byte '%c' (0x%2X) at index %d.", _zString, *pu8Byte, *pu8Byte, pu8Byte - (orxU8 *)_zString);
489 
490  /* Updates result */
491  u32Result = orxU32_UNDEFINED;
492  }
493 
494  /* Asks for remaining string? */
495  if(_pzRemaining != orxNULL)
496  {
497  /* Stores it */
498  *_pzRemaining = (orxSTRING)(pu8Byte + 1);
499  }
500 
501  /* Done! */
502  return u32Result;
503 }
504 
509 static orxINLINE orxU32 orxString_GetCharacterCount(const orxSTRING _zString)
510 {
511  const orxCHAR *pc;
512  orxU32 u32Result;
513 
514  /* Checks */
515  orxASSERT(_zString != orxNULL);
516 
517  /* For all characters */
518  for(pc = _zString, u32Result = 0; *pc != orxCHAR_NULL; u32Result++)
519  {
520  /* Invalid current character ID */
522  {
523  /* Updates result */
524  u32Result = orxU32_UNDEFINED;
525 
526  /* Logs message */
527  orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Invalid or non-UTF8 string <%s>, can't count characters.", _zString);
528 
529  break;
530  }
531  }
532 
533  /* Done! */
534  return u32Result;
535 }
536 
543 static orxINLINE orxSTRING orxString_NCopy(orxSTRING _zDstString, const orxSTRING _zSrcString, orxU32 _u32CharNumber)
544 {
545  /* Checks */
546  orxASSERT(_zDstString != orxNULL);
547  orxASSERT(_zSrcString != orxNULL);
548 
549  /* Done! */
550  return(strncpy(_zDstString, _zSrcString, (size_t)_u32CharNumber));
551 }
552 
557 static orxINLINE orxSTRING orxString_Duplicate(const orxSTRING _zSrcString)
558 {
559  orxU32 u32Size;
560  orxSTRING zResult;
561 
562  /* Checks */
563  orxASSERT(_zSrcString != orxNULL);
564 
565  /* Gets string size in bytes */
566  u32Size = (orxString_GetLength(_zSrcString) + 1) * sizeof(orxCHAR);
567 
568  /* Allocates it */
569  zResult = (orxSTRING)orxMemory_Allocate(u32Size, orxMEMORY_TYPE_TEXT);
570 
571  /* Valid? */
572  if(zResult != orxNULL)
573  {
574  /* Copies source to it */
575  orxMemory_Copy(zResult, _zSrcString, u32Size);
576  }
577 
578  /* Done! */
579  return zResult;
580 }
581 
585 static orxINLINE orxSTATUS orxString_Delete(orxSTRING _zString)
586 {
587  /* Checks */
588  orxASSERT(_zString != orxNULL);
589  orxASSERT(_zString != orxSTRING_EMPTY);
590 
591  /* Frees its memory */
592  orxMemory_Free(_zString);
593 
594  /* Done! */
595  return orxSTATUS_SUCCESS;
596 }
597 
604 static orxINLINE orxS32 orxString_Compare(const orxSTRING _zString1, const orxSTRING _zString2)
605 {
606  /* Checks */
607  orxASSERT(_zString1 != orxNULL);
608  orxASSERT(_zString2 != orxNULL);
609 
610  /* Done! */
611  return(strcmp(_zString1, _zString2));
612 }
613 
622 static orxINLINE orxS32 orxString_NCompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
623 {
624  /* Checks */
625  orxASSERT(_zString1 != orxNULL);
626  orxASSERT(_zString2 != orxNULL);
627 
628  /* Done! */
629  return strncmp(_zString1, _zString2, (size_t)_u32CharNumber);
630 }
631 
638 static orxINLINE orxS32 orxString_ICompare(const orxSTRING _zString1, const orxSTRING _zString2)
639 {
640  /* Checks */
641  orxASSERT(_zString1 != orxNULL);
642  orxASSERT(_zString2 != orxNULL);
643 
644 #ifdef __orxWINDOWS__
645 
646  /* Done! */
647  return(stricmp(_zString1, _zString2));
648 
649 #else /* __orxWINDOWS__ */
650 
651  /* Done! */
652  return strcasecmp(_zString1, _zString2);
653 
654 #endif /* __orxWINDOWS__ */
655 }
656 
665 static orxINLINE orxS32 orxString_NICompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
666 {
667  /* Checks */
668  orxASSERT(_zString1 != orxNULL);
669  orxASSERT(_zString2 != orxNULL);
670 
671 #ifdef __orxWINDOWS__
672 
673  /* Done! */
674  return strnicmp(_zString1, _zString2, (size_t)_u32CharNumber);
675 
676 #else /* __orxWINDOWS__ */
677 
678  /* Done! */
679  return strncasecmp(_zString1, _zString2, _u32CharNumber);
680 
681 #endif /* __orxWINDOWS__ */
682 }
683 
689 static orxINLINE orxU32 orxString_ExtractBase(const orxSTRING _zString, const orxSTRING *_pzRemaining)
690 {
691  const orxSTRING zString;
692  orxU32 u32Result, u32Offset;
693 
694  /* Checks */
695  orxASSERT(_zString != orxNULL);
696 
697  /* Skips white spaces */
698  zString = orxString_SkipWhiteSpaces(_zString);
699 
700  /* Default result and offset: decimal */
701  u32Result = 10;
702  u32Offset = 0;
703 
704  /* Depending on first character */
705  switch(zString[0])
706  {
707  case '0':
708  {
709  /* Depending on second character */
710  switch(zString[1] | 0x20)
711  {
712  case 'x':
713  {
714  /* Updates result and offset: hexadecimal */
715  u32Result = 16;
716  u32Offset = 2;
717 
718  break;
719  }
720 
721  case 'b':
722  {
723  /* Updates result and offset: binary */
724  u32Result = 2;
725  u32Offset = 2;
726 
727  break;
728  }
729 
730  default:
731  {
732  /* Octal? */
733  if((zString[1] >= '0')
734  && (zString[1] <= '9'))
735  {
736  /* Updates result and offset: octal */
737  u32Result = 8;
738  u32Offset = 1;
739  }
740 
741  break;
742  }
743  }
744 
745  break;
746  }
747 
748  case '#':
749  {
750  /* Updates result and offset: hexadecimal */
751  u32Result = 16;
752  u32Offset = 1;
753 
754  break;
755  }
756 
757  default:
758  {
759  break;
760  }
761  }
762 
763  /* Asks for remaining string? */
764  if(_pzRemaining != orxNULL)
765  {
766  /* Stores it */
767  *_pzRemaining = zString + u32Offset;
768  }
769 
770  /* Done! */
771  return u32Result;
772 }
773 
781 static orxINLINE orxSTATUS orxString_ToS32Base(const orxSTRING _zString, orxU32 _u32Base, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
782 {
783  orxCHAR *pcEnd;
784  orxSTATUS eResult;
785 
786  /* Checks */
787  orxASSERT(_ps32OutValue != orxNULL);
788  orxASSERT(_zString != orxNULL);
789 
790  /* Convert */
791  *_ps32OutValue = (orxS32)strtol(_zString, &pcEnd, STRTO_CAST _u32Base);
792 
793  /* Valid conversion ? */
794  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
795  {
796  /* Updates result */
797  eResult = orxSTATUS_SUCCESS;
798  }
799  else
800  {
801  /* Updates result */
802  eResult = orxSTATUS_FAILURE;
803  }
804 
805  /* Asks for remaining string? */
806  if(_pzRemaining != orxNULL)
807  {
808  /* Stores it */
809  *_pzRemaining = pcEnd;
810  }
811 
812  /* Done! */
813  return eResult;
814 }
815 
822 static orxINLINE orxSTATUS orxString_ToS32(const orxSTRING _zString, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
823 {
824  const orxSTRING zValue;
825  orxU32 u32Base;
826  orxSTATUS eResult;
827 
828  /* Checks */
829  orxASSERT(_ps32OutValue != orxNULL);
830  orxASSERT(_zString != orxNULL);
831 
832  /* Extracts base */
833  u32Base = orxString_ExtractBase(_zString, &zValue);
834 
835  /* Gets value */
836  eResult = orxString_ToS32Base(zValue, u32Base, _ps32OutValue, _pzRemaining);
837 
838  /* Done! */
839  return eResult;
840 }
841 
849 static orxINLINE orxSTATUS orxString_ToU32Base(const orxSTRING _zString, orxU32 _u32Base, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
850 {
851  orxCHAR *pcEnd;
852  orxSTATUS eResult;
853 
854  /* Checks */
855  orxASSERT(_pu32OutValue != orxNULL);
856  orxASSERT(_zString != orxNULL);
857 
858  /* Convert */
859  *_pu32OutValue = (orxU32)strtoul(_zString, &pcEnd, STRTO_CAST _u32Base);
860 
861  /* Valid conversion ? */
862  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
863  {
864  /* Updates result */
865  eResult = orxSTATUS_SUCCESS;
866  }
867  else
868  {
869  /* Updates result */
870  eResult = orxSTATUS_FAILURE;
871  }
872 
873  /* Asks for remaining string? */
874  if(_pzRemaining != orxNULL)
875  {
876  /* Stores it */
877  *_pzRemaining = pcEnd;
878  }
879 
880  /* Done! */
881  return eResult;
882 }
883 
890 static orxINLINE orxSTATUS orxString_ToU32(const orxSTRING _zString, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
891 {
892  const orxSTRING zValue;
893  orxU32 u32Base;
894  orxSTATUS eResult;
895 
896  /* Checks */
897  orxASSERT(_pu32OutValue != orxNULL);
898  orxASSERT(_zString != orxNULL);
899 
900  /* Extracts base */
901  u32Base = orxString_ExtractBase(_zString, &zValue);
902 
903  /* Gets value */
904  eResult = orxString_ToU32Base(zValue, u32Base, _pu32OutValue, _pzRemaining);
905 
906  /* Done! */
907  return eResult;
908 }
909 
917 static orxINLINE orxSTATUS orxString_ToS64Base(const orxSTRING _zString, orxU32 _u32Base, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
918 {
919  orxCHAR *pcEnd;
920  orxSTATUS eResult;
921 
922  /* Checks */
923  orxASSERT(_ps64OutValue != orxNULL);
924  orxASSERT(_zString != orxNULL);
925 
926  /* Convert */
927  *_ps64OutValue = (orxS64)strtoll(_zString, &pcEnd, STRTO_CAST _u32Base);
928 
929  /* Valid conversion ? */
930  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
931  {
932  /* Updates result */
933  eResult = orxSTATUS_SUCCESS;
934  }
935  else
936  {
937  /* Updates result */
938  eResult = orxSTATUS_FAILURE;
939  }
940 
941  /* Asks for remaining string? */
942  if(_pzRemaining != orxNULL)
943  {
944  /* Stores it */
945  *_pzRemaining = pcEnd;
946  }
947 
948  /* Done! */
949  return eResult;
950 }
951 
958 static orxINLINE orxSTATUS orxString_ToS64(const orxSTRING _zString, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
959 {
960  const orxSTRING zValue;
961  orxU32 u32Base;
962  orxSTATUS eResult;
963 
964  /* Checks */
965  orxASSERT(_ps64OutValue != orxNULL);
966  orxASSERT(_zString != orxNULL);
967 
968  /* Extracts base */
969  u32Base = orxString_ExtractBase(_zString, &zValue);
970 
971  /* Gets signed value */
972  eResult = orxString_ToS64Base(zValue, u32Base, _ps64OutValue, _pzRemaining);
973 
974  /* Done! */
975  return eResult;
976 }
977 
985 static orxINLINE orxSTATUS orxString_ToU64Base(const orxSTRING _zString, orxU32 _u32Base, orxU64 *_pu64OutValue, const orxSTRING *_pzRemaining)
986 {
987  orxCHAR *pcEnd;
988  orxSTATUS eResult;
989 
990  /* Checks */
991  orxASSERT(_pu64OutValue != orxNULL);
992  orxASSERT(_zString != orxNULL);
993 
994  /* Convert */
995  *_pu64OutValue = (orxU64)strtoull(_zString, &pcEnd, STRTO_CAST _u32Base);
996 
997  /* Valid conversion ? */
998  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
999  {
1000  /* Updates result */
1001  eResult = orxSTATUS_SUCCESS;
1002  }
1003  else
1004  {
1005  /* Updates result */
1006  eResult = orxSTATUS_FAILURE;
1007  }
1008 
1009  /* Asks for remaining string? */
1010  if(_pzRemaining != orxNULL)
1011  {
1012  /* Stores it */
1013  *_pzRemaining = pcEnd;
1014  }
1015 
1016  /* Done! */
1017  return eResult;
1018 }
1019 
1026 static orxINLINE orxSTATUS orxString_ToU64(const orxSTRING _zString, orxU64 *_pu64OutValue, const orxSTRING *_pzRemaining)
1027 {
1028  const orxSTRING zValue;
1029  orxU32 u32Base;
1030  orxSTATUS eResult;
1031 
1032  /* Checks */
1033  orxASSERT(_pu64OutValue != orxNULL);
1034  orxASSERT(_zString != orxNULL);
1035 
1036  /* Extracts base */
1037  u32Base = orxString_ExtractBase(_zString, &zValue);
1038 
1039  /* Gets signed value */
1040  eResult = orxString_ToU64Base(zValue, u32Base, _pu64OutValue, _pzRemaining);
1041 
1042  /* Done! */
1043  return eResult;
1044 }
1045 
1052 static orxINLINE orxSTATUS orxString_ToFloat(const orxSTRING _zString, orxFLOAT *_pfOutValue, const orxSTRING *_pzRemaining)
1053 {
1054  orxCHAR *pcEnd;
1055  orxSTATUS eResult;
1056 
1057  /* Checks */
1058  orxASSERT(_pfOutValue != orxNULL);
1059  orxASSERT(_zString != orxNULL);
1060 
1061  /* Linux / Mac / iOS / Android / MSVC? */
1062 #if defined(__orxLINUX__) || defined(__orxMAC__) || defined (__orxIOS__) || defined(__orxMSVC__) || defined(__orxANDROID__)
1063 
1064  /* Converts it */
1065  *_pfOutValue = (orxFLOAT)strtod(_zString, &pcEnd);
1066 
1067 #else /* __orxLINUX__ || __orxMAC__ || __orxIOS__ || __orxMSVC__ || __orxANDROID__ */
1068 
1069  /* Converts it */
1070  *_pfOutValue = strtof(_zString, &pcEnd);
1071 
1072 #endif /* __orxLINUX__ || __orxMAC__ || __orxIOS__ || __orxMSVC__ || __orxANDROID__ */
1073 
1074  /* Valid conversion ? */
1075  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
1076  {
1077  /* Updates result */
1078  eResult = orxSTATUS_SUCCESS;
1079  }
1080  else
1081  {
1082  /* Updates result */
1083  eResult = orxSTATUS_FAILURE;
1084  }
1085 
1086  /* Asks for remaining string? */
1087  if(_pzRemaining != orxNULL)
1088  {
1089  /* Stores it */
1090  *_pzRemaining = pcEnd;
1091  }
1092 
1093  /* Done! */
1094  return eResult;
1095 }
1096 
1103 static orxINLINE orxSTATUS orxString_ToVector(const orxSTRING _zString, orxVECTOR *_pvOutValue, const orxSTRING *_pzRemaining)
1104 {
1105  orxVECTOR stValue;
1106  const orxSTRING zString;
1107  orxSTATUS eResult = orxSTATUS_FAILURE;
1108 
1109  /* Checks */
1110  orxASSERT(_pvOutValue != orxNULL);
1111  orxASSERT(_zString != orxNULL);
1112 
1113  /* Skips all white spaces */
1114  zString = orxString_SkipWhiteSpaces(_zString);
1115 
1116  /* Is a vector start character? */
1117  if((*zString == orxSTRING_KC_VECTOR_START)
1118  || (*zString == orxSTRING_KC_VECTOR_START_ALT))
1119  {
1120  orxCHAR cEndMarker;
1121 
1122  /* Gets end marker */
1124 
1125  /* Skips all white spaces */
1126  zString = orxString_SkipWhiteSpaces(zString + 1);
1127 
1128  /* Gets X value */
1129  if(orxString_ToFloat(zString, &(stValue.fX), &zString) != orxSTATUS_FAILURE)
1130  {
1131  /* Skips all white spaces */
1132  zString = orxString_SkipWhiteSpaces(zString);
1133 
1134  /* Is a vector separator character? */
1135  if(*zString == orxSTRING_KC_VECTOR_SEPARATOR)
1136  {
1137  /* Skips all white spaces */
1138  zString = orxString_SkipWhiteSpaces(zString + 1);
1139 
1140  /* Gets Y value */
1141  if(orxString_ToFloat(zString, &(stValue.fY), &zString) != orxSTATUS_FAILURE)
1142  {
1143  /* Skips all white spaces */
1144  zString = orxString_SkipWhiteSpaces(zString);
1145 
1146  /* Is a vector separator character? */
1147  if(*zString == orxSTRING_KC_VECTOR_SEPARATOR)
1148  {
1149  /* Skips all white spaces */
1150  zString = orxString_SkipWhiteSpaces(zString + 1);
1151 
1152  /* Gets Z value */
1153  if(orxString_ToFloat(zString, &(stValue.fZ), &zString) != orxSTATUS_FAILURE)
1154  {
1155  /* Skips all white spaces */
1156  zString = orxString_SkipWhiteSpaces(zString);
1157 
1158  /* Has a valid end marker? */
1159  if(*zString == cEndMarker)
1160  {
1161  /* Updates result */
1162  eResult = orxSTATUS_SUCCESS;
1163  }
1164  }
1165  }
1166  /* Has a valid end marker? */
1167  else if(*zString == cEndMarker)
1168  {
1169  /* Clears Z component */
1170  stValue.fZ = orxFLOAT_0;
1171 
1172  /* Updates result */
1173  eResult = orxSTATUS_SUCCESS;
1174  }
1175  }
1176  }
1177  }
1178  }
1179 
1180  /* Valid? */
1181  if(eResult != orxSTATUS_FAILURE)
1182  {
1183  /* Updates vector */
1184  orxVector_Copy(_pvOutValue, &stValue);
1185 
1186  /* Asks for remaining string? */
1187  if(_pzRemaining != orxNULL)
1188  {
1189  /* Stores it */
1190  *_pzRemaining = zString + 1;
1191  }
1192  }
1193 
1194  /* Done! */
1195  return eResult;
1196 }
1197 
1204 static orxINLINE orxSTATUS orxString_ToBool(const orxSTRING _zString, orxBOOL *_pbOutValue, const orxSTRING *_pzRemaining)
1205 {
1206  orxS32 s32Value;
1207  orxSTATUS eResult;
1208 
1209  /* Checks */
1210  orxASSERT(_pbOutValue != orxNULL);
1211  orxASSERT(_zString != orxNULL);
1212 
1213  /* Tries numeric value */
1214  eResult = orxString_ToS32Base(_zString, 10, &s32Value, _pzRemaining);
1215 
1216  /* Valid? */
1217  if(eResult != orxSTATUS_FAILURE)
1218  {
1219  /* Updates boolean */
1220  *_pbOutValue = (s32Value != 0) ? orxTRUE : orxFALSE;
1221  }
1222  else
1223  {
1224  orxU32 u32Length;
1225 
1226  /* Gets length of false */
1227  u32Length = orxString_GetLength(orxSTRING_FALSE);
1228 
1229  /* Is false? */
1230  if(orxString_NICompare(_zString, orxSTRING_FALSE, u32Length) == 0)
1231  {
1232  /* Updates boolean */
1233  *_pbOutValue = orxFALSE;
1234 
1235  /* Has remaining? */
1236  if(_pzRemaining != orxNULL)
1237  {
1238  /* Updates it */
1239  *_pzRemaining += u32Length;
1240  }
1241 
1242  /* Updates result */
1243  eResult = orxSTATUS_SUCCESS;
1244  }
1245  else
1246  {
1247  /* Gets length of true */
1248  u32Length = orxString_GetLength(orxSTRING_TRUE);
1249 
1250  /* Is true? */
1251  if(orxString_NICompare(_zString, orxSTRING_TRUE, u32Length) == 0)
1252  {
1253  /* Updates boolean */
1254  *_pbOutValue = orxTRUE;
1255 
1256  /* Has remaining? */
1257  if(_pzRemaining != orxNULL)
1258  {
1259  /* Updates it */
1260  *_pzRemaining += u32Length;
1261  }
1262 
1263  /* Updates result */
1264  eResult = orxSTATUS_SUCCESS;
1265  }
1266  }
1267  }
1268 
1269  /* Done! */
1270  return eResult;
1271 }
1272 
1277 static orxINLINE orxSTRING orxString_LowerCase(orxSTRING _zString)
1278 {
1279  orxCHAR *pc;
1280 
1281  /* Checks */
1282  orxASSERT(_zString != orxNULL);
1283 
1284  /* Converts the whole string */
1285  for(pc = _zString; *pc != orxCHAR_NULL; pc++)
1286  {
1287  /* Needs to be converted? */
1288  if(*pc >= 'A' && *pc <= 'Z')
1289  {
1290  /* Lower case */
1291  *pc |= 0x20;
1292  }
1293  }
1294 
1295  return _zString;
1296 }
1297 
1302 static orxINLINE orxSTRING orxString_UpperCase(orxSTRING _zString)
1303 {
1304  orxCHAR *pc;
1305 
1306  /* Checks */
1307  orxASSERT(_zString != orxNULL);
1308 
1309  /* Converts the whole string */
1310  for(pc = _zString; *pc != orxCHAR_NULL; pc++)
1311  {
1312  /* Needs to be converted? */
1313  if(*pc >= 'a' && *pc <= 'z')
1314  {
1315  /* Upper case */
1316  *pc &= ~0x20;
1317  }
1318  }
1319 
1320  return _zString;
1321 }
1322 
1329 static orxINLINE orxSTRINGID orxString_NContinueCRC(const orxSTRING _zString, orxSTRINGID _stCRC, orxU32 _u32CharNumber)
1330 {
1331  orxU32 u32CRC, u32Length;
1332  const orxU8 *pu8;
1333 
1334 #ifdef __orxLITTLE_ENDIAN__
1335 
1336 #define orxCRC_GET_FIRST(VALUE) VALUE
1337 #define orxCRC_INDEX_0 0
1338 #define orxCRC_INDEX_1 1
1339 #define orxCRC_INDEX_2 2
1340 #define orxCRC_INDEX_3 3
1341 #define orxCRC_INDEX_4 4
1342 #define orxCRC_INDEX_5 5
1343 #define orxCRC_INDEX_6 6
1344 #define orxCRC_INDEX_7 7
1345 
1346 #else /* __orxLITTLE_ENDIAN__ */
1347 
1348 #define orxCRC_GET_FIRST(VALUE) (((VALUE) >> 24) | (((VALUE) >> 8) & 0x0000FF00) | (((VALUE) << 8) & 0x00FF0000) | ((VALUE) << 24))
1349 #define orxCRC_INDEX_0 3
1350 #define orxCRC_INDEX_1 2
1351 #define orxCRC_INDEX_2 1
1352 #define orxCRC_INDEX_3 0
1353 #define orxCRC_INDEX_4 7
1354 #define orxCRC_INDEX_5 6
1355 #define orxCRC_INDEX_6 5
1356 #define orxCRC_INDEX_7 4
1357 
1358 #endif /* __orxLITTLE_ENDIAN__ */
1359 
1360  /* Checks */
1361  orxASSERT(_zString != orxNULL);
1362  orxASSERT(_u32CharNumber <= orxString_GetLength(_zString));
1363 
1364  /* Inits CRC */
1365  u32CRC = ~(orxU32)_stCRC;
1366 
1367  /* For all slices */
1368  for(u32Length = _u32CharNumber, pu8 = (const orxU8 *)_zString; u32Length >= 8; u32Length -= 8, pu8 += 8)
1369  {
1370  orxU32 u32First, u32Second;
1371 
1372  /* Gets the slice's data */
1373  orxMemory_Copy(&u32First, pu8, sizeof(orxU32));
1374  orxMemory_Copy(&u32Second, pu8 + 4, sizeof(orxU32));
1375  u32First ^= orxCRC_GET_FIRST(u32CRC);
1376 
1377  /* Updates the CRC */
1378  u32CRC = saau32CRCTable[orxCRC_INDEX_7][u32First & 0xFF]
1379  ^ saau32CRCTable[orxCRC_INDEX_6][(u32First >> 8) & 0xFF]
1380  ^ saau32CRCTable[orxCRC_INDEX_5][(u32First >> 16) & 0xFF]
1381  ^ saau32CRCTable[orxCRC_INDEX_4][u32First >> 24]
1382  ^ saau32CRCTable[orxCRC_INDEX_3][u32Second & 0xFF]
1383  ^ saau32CRCTable[orxCRC_INDEX_2][(u32Second >> 8) & 0xFF]
1384  ^ saau32CRCTable[orxCRC_INDEX_1][(u32Second >> 16) & 0xFF]
1385  ^ saau32CRCTable[orxCRC_INDEX_0][u32Second >> 24];
1386  }
1387 
1388  /* For all remaining characters */
1389  for(; u32Length != 0; u32Length--, pu8++)
1390  {
1391  /* Updates the CRC */
1392  u32CRC = saau32CRCTable[0][((orxU8)(u32CRC & 0xFF)) ^ *pu8] ^ (u32CRC >> 8);
1393  }
1394 
1395 #undef orxCRC_GET_FIRST
1396 #undef orxCRC_INDEX_0
1397 #undef orxCRC_INDEX_1
1398 #undef orxCRC_INDEX_2
1399 #undef orxCRC_INDEX_3
1400 #undef orxCRC_INDEX_4
1401 #undef orxCRC_INDEX_5
1402 #undef orxCRC_INDEX_6
1403 #undef orxCRC_INDEX_7
1404 
1405  /* Done! */
1406  return (orxSTRINGID)~u32CRC;
1407 }
1408 
1414 static orxINLINE orxSTRINGID orxString_ContinueCRC(const orxSTRING _zString, orxSTRINGID _stCRC)
1415 {
1416  orxSTRINGID stCRC;
1417 
1418  /* Updates CRC */
1419  stCRC = orxString_NContinueCRC(_zString, _stCRC, orxString_GetLength(_zString));
1420 
1421  /* Done! */
1422  return stCRC;
1423 }
1424 
1430 static orxINLINE orxSTRINGID orxString_NToCRC(const orxSTRING _zString, orxU32 _u32CharNumber)
1431 {
1432  /* Checks */
1433  orxASSERT(_zString != orxNULL);
1434  orxASSERT(_u32CharNumber <= orxString_GetLength(_zString));
1435 
1436  /* Done! */
1437  return orxString_NContinueCRC(_zString, 0, _u32CharNumber);
1438 }
1439 
1444 static orxINLINE orxSTRINGID orxString_ToCRC(const orxSTRING _zString)
1445 {
1446  /* Checks */
1447  orxASSERT(_zString != orxNULL);
1448 
1449  /* Done! */
1450  return orxString_ContinueCRC(_zString, 0);
1451 }
1452 
1458 static orxINLINE const orxSTRING orxString_SearchString(const orxSTRING _zString1, const orxSTRING _zString2)
1459 {
1460  /* Checks */
1461  orxASSERT(_zString1 != orxNULL);
1462  orxASSERT(_zString2 != orxNULL);
1463 
1464  /* Returns result */
1465  return(strstr(_zString1, _zString2));
1466 }
1467 
1473 static orxINLINE const orxSTRING orxString_SearchChar(const orxSTRING _zString, orxCHAR _cChar)
1474 {
1475  /* Checks */
1476  orxASSERT(_zString != orxNULL);
1477 
1478  /* Returns result */
1479  return(strchr(_zString, _cChar));
1480 }
1481 
1488 static orxINLINE orxS32 orxString_SearchCharIndex(const orxSTRING _zString, orxCHAR _cChar, orxS32 _s32Position)
1489 {
1490  orxS32 s32Index, s32Result = -1;
1491  const orxCHAR *pc;
1492 
1493  /* Checks */
1494  orxASSERT(_zString != orxNULL);
1495  orxASSERT(_s32Position <= (orxS32)orxString_GetLength(_zString));
1496 
1497  /* For all characters */
1498  for(s32Index = _s32Position, pc = _zString + s32Index; *pc != orxCHAR_NULL; pc++, s32Index++)
1499  {
1500  /* Found? */
1501  if(*pc == _cChar)
1502  {
1503  /* Updates result */
1504  s32Result = s32Index;
1505 
1506  break;
1507  }
1508  }
1509 
1510  /* Done! */
1511  return s32Result;
1512 }
1513 
1519 static orxINLINE orxS32 orxCDECL orxString_Print(orxSTRING _zDstString, const orxSTRING _zSrcString, ...)
1520 {
1521  va_list stArgs;
1522  orxS32 s32Result;
1523 
1524  /* Checks */
1525  orxASSERT(_zDstString != orxNULL);
1526  orxASSERT(_zSrcString != orxNULL);
1527 
1528  /* Gets variable arguments & prints the string */
1529  va_start(stArgs, _zSrcString);
1530  s32Result = vsprintf(_zDstString, _zSrcString, stArgs);
1531  va_end(stArgs);
1532 
1533  /* Clamps result */
1534  s32Result = orxMAX(s32Result, 0);
1535 
1536  /* Done! */
1537  return s32Result;
1538 }
1539 
1546 static orxINLINE orxS32 orxCDECL orxString_NPrint(orxSTRING _zDstString, orxU32 _u32CharNumber, const orxSTRING _zSrcString, ...)
1547 {
1548  va_list stArgs;
1549  orxS32 s32Result;
1550 
1551  /* Checks */
1552  orxASSERT(_zDstString != orxNULL);
1553  orxASSERT(_zSrcString != orxNULL);
1554 
1555  /* Gets variable arguments & prints the string */
1556  va_start(stArgs, _zSrcString);
1557  s32Result = vsnprintf(_zDstString, (size_t)_u32CharNumber, _zSrcString, stArgs);
1558  va_end(stArgs);
1559 
1560 #ifdef __orxMSVC__
1561  /* Overflow? */
1562  if(s32Result <= 0)
1563  {
1564  /* Updates result */
1565  s32Result = _u32CharNumber;
1566  }
1567 #endif /* __orxMSVC__ */
1568 
1569  /* Clamps result */
1570  s32Result = orxCLAMP(s32Result, 0, (orxS32)_u32CharNumber);
1571 
1572  /* Done! */
1573  return s32Result;
1574 }
1575 
1581 static orxINLINE orxS32 orxCDECL orxString_Scan(const orxSTRING _zString, const orxSTRING _zFormat, ...)
1582 {
1583  va_list stArgs;
1584  orxS32 s32Result;
1585 
1586  /* Checks */
1587  orxASSERT(_zString != orxNULL);
1588 
1589 #ifdef __orxMSVC__
1590 
1591  /* Ugly workaround the missing vsscanf in MSVC up to version 2013 */
1592  {
1593  void *p[16];
1594  orxS32 i;
1595 
1596  /* Starts variable list */
1597  va_start(stArgs, _zFormat);
1598 
1599  /* For all potential parameters */
1600  for(i = 0; i < orxARRAY_GET_ITEM_COUNT(p); i++)
1601  {
1602  /* Gets its address */
1603  p[i] = va_arg(stArgs, void *);
1604  }
1605 
1606  /* Scans the string */
1607  s32Result = sscanf(_zString, _zFormat, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
1608 
1609  /* Ends variable list */
1610  va_end(stArgs);
1611  }
1612 
1613 #else /* __orxMSVC__ */
1614 
1615  /* Gets variable arguments & scans the string */
1616  va_start(stArgs, _zFormat);
1617  s32Result = vsscanf(_zString, _zFormat, stArgs);
1618  va_end(stArgs);
1619 
1620 #endif /* __orxMSVC__ */
1621 
1622  /* Clamps result */
1623  s32Result = orxMAX(s32Result, 0);
1624 
1625  /* Done! */
1626  return s32Result;
1627 }
1628 
1633 static orxINLINE const orxSTRING orxString_GetExtension(const orxSTRING _zFileName)
1634 {
1635  orxS32 s32Index, s32NextIndex;
1636  const orxSTRING zResult;
1637 
1638  /* Checks */
1639  orxASSERT(_zFileName != orxNULL);
1640 
1641  /* Finds last '.' */
1642  for(s32Index = orxString_SearchCharIndex(_zFileName, '.', 0);
1643  (s32Index >= 0) && ((s32NextIndex = orxString_SearchCharIndex(_zFileName, '.', s32Index + 1)) > 0);
1644  s32Index = s32NextIndex);
1645 
1646  /* Updates result */
1647  zResult = (s32Index >= 0) ? _zFileName + s32Index + 1 : orxSTRING_EMPTY;
1648 
1649  /* Done! */
1650  return zResult;
1651 }
1652 
1653 /* *** String module functions *** */
1654 
1657 extern orxDLLAPI void orxFASTCALL orxString_Setup();
1658 
1662 extern orxDLLAPI orxSTATUS orxFASTCALL orxString_Init();
1663 
1666 extern orxDLLAPI void orxFASTCALL orxString_Exit();
1667 
1668 
1673 extern orxDLLAPI orxSTRINGID orxFASTCALL orxString_GetID(const orxSTRING _zString);
1674 
1679 extern orxDLLAPI const orxSTRING orxFASTCALL orxString_GetFromID(orxSTRINGID _u32ID);
1680 
1685 extern orxDLLAPI const orxSTRING orxFASTCALL orxString_Store(const orxSTRING _zString);
1686 
1687 
1688 #ifdef __orxMSVC__
1689 
1690  #pragma warning(default : 4996)
1691 
1692 #endif /* __orxMSVC__ */
1693 
1694 #endif /* _orxSTRING_H_ */
1695 
#define orxARRAY_GET_ITEM_COUNT(ARRAY)
Definition: orxDecl.h:399
static orxINLINE const orxSTRING orxString_GetExtension(const orxSTRING _zFileName)
Definition: orxString.h:1633
static orxINLINE orxSTATUS orxString_ToS64(const orxSTRING _zString, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:958
orxDLLAPI orxSTRINGID orxFASTCALL orxString_GetID(const orxSTRING _zString)
#define orxCRC_INDEX_3
orxDLLAPI void orxFASTCALL orxString_Setup()
static orxINLINE orxS32 orxString_SearchCharIndex(const orxSTRING _zString, orxCHAR _cChar, orxS32 _s32Position)
Definition: orxString.h:1488
orxDLLAPI const orxSTRING orxFASTCALL orxString_Store(const orxSTRING _zString)
#define orxCRC_INDEX_6
static orxINLINE orxSTRINGID orxString_NContinueCRC(const orxSTRING _zString, orxSTRINGID _stCRC, orxU32 _u32CharNumber)
Definition: orxString.h:1329
static orxINLINE orxBOOL orxString_IsCharacterAlphaNumeric(orxU32 _u32CharacterCodePoint)
Definition: orxString.h:196
static orxINLINE orxSTATUS orxString_ToU32Base(const orxSTRING _zString, orxU32 _u32Base, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:849
static orxINLINE orxS32 orxString_NICompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
Definition: orxString.h:665
static orxINLINE const orxSTRING orxString_SkipWhiteSpaces(const orxSTRING _zString)
Definition: orxString.h:99
static orxINLINE orxSTRING orxString_Duplicate(const orxSTRING _zSrcString)
Definition: orxString.h:557
#define orxSTRING_KC_VECTOR_END
Definition: orxString.h:78
static orxINLINE orxSTRING orxString_LowerCase(orxSTRING _zString)
Definition: orxString.h:1277
#define orxCRC_INDEX_7
#define orxTRUE
Definition: orxType.h:188
orxDLLAPI orxU32 saau32CRCTable[8][256]
orxDLLAPI orxSTATUS orxFASTCALL orxString_Init()
static orxINLINE orxS32 orxString_NCompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
Definition: orxString.h:622
static orxINLINE orxSTRINGID orxString_NToCRC(const orxSTRING _zString, orxU32 _u32CharNumber)
Definition: orxString.h:1430
static const orxU32 orxU32_UNDEFINED
Definition: orxType.h:204
#define orxSTRING_KC_VECTOR_END_ALT
Definition: orxString.h:79
static orxINLINE orxSTATUS orxString_ToU64(const orxSTRING _zString, orxU64 *_pu64OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:1026
static orxINLINE orxSTATUS orxString_ToU32(const orxSTRING _zString, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:890
orxFLOAT fY
Definition: orxVector.h:77
static orxINLINE orxU32 orxString_ExtractBase(const orxSTRING _zString, const orxSTRING *_pzRemaining)
Definition: orxString.h:689
#define orxCLAMP(V, MIN, MAX)
Definition: orxMath.h:89
#define orxCHAR_CR
Definition: orxType.h:218
orxDLLAPI const orxSTRING orxFASTCALL orxString_GetFromID(orxSTRINGID _u32ID)
#define orxFALSE
Definition: orxType.h:187
static orxINLINE orxS32 orxCDECL orxString_Scan(const orxSTRING _zString, const orxSTRING _zFormat,...)
Definition: orxString.h:1581
#define orxCHAR_DIRECTORY_SEPARATOR_WINDOWS
Definition: orxType.h:231
orxFLOAT fX
Definition: orxVector.h:69
orxDLLAPI void *orxFASTCALL orxMemory_Allocate(orxU32 _u32Size, orxMEMORY_TYPE _eMemType)
static orxINLINE orxSTATUS orxString_ToS32Base(const orxSTRING _zString, orxU32 _u32Base, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:781
static orxINLINE const orxSTRING orxString_SkipPath(const orxSTRING _zString)
Definition: orxString.h:130
orxDLLAPI const orxSTRING orxSTRING_EMPTY
#define orxCRC_INDEX_0
static orxINLINE orxSTATUS orxString_ToVector(const orxSTRING _zString, orxVECTOR *_pvOutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:1103
orxDLLAPI const orxSTRING orxSTRING_TRUE
#define orxCRC_INDEX_1
static orxU32 orxFASTCALL orxString_GetFirstCharacterCodePoint(const orxSTRING _zString, const orxSTRING *_pzRemaining)
Definition: orxString.h:342
static orxINLINE orxSTRING orxString_UpperCase(orxSTRING _zString)
Definition: orxString.h:1302
#define orxMAX(A, B)
Definition: orxMath.h:81
static orxINLINE orxU32 orxString_GetLength(const orxSTRING _zString)
Definition: orxString.h:173
#define orxSTRING_KC_VECTOR_START
Definition: orxString.h:75
static orxINLINE orxSTATUS orxString_ToBool(const orxSTRING _zString, orxBOOL *_pbOutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:1204
static orxINLINE orxS32 orxCDECL orxString_Print(orxSTRING _zDstString, const orxSTRING _zSrcString,...)
Definition: orxString.h:1519
static orxINLINE orxSTATUS orxString_ToU64Base(const orxSTRING _zString, orxU32 _u32Base, orxU64 *_pu64OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:985
static orxINLINE orxSTATUS orxString_Delete(orxSTRING _zString)
Definition: orxString.h:585
static orxINLINE orxU32 orxString_GetUTF8CharacterLength(orxU32 _u32CharacterCodePoint)
Definition: orxString.h:208
static orxINLINE orxS32 orxString_Compare(const orxSTRING _zString1, const orxSTRING _zString2)
Definition: orxString.h:604
static orxU32 orxFASTCALL orxString_PrintUTF8Character(orxSTRING _zDstString, orxU32 _u32Size, orxU32 _u32CharacterCodePoint)
Definition: orxString.h:249
static orxINLINE orxSTRINGID orxString_ContinueCRC(const orxSTRING _zString, orxSTRINGID _stCRC)
Definition: orxString.h:1414
static orxINLINE const orxSTRING orxString_SearchString(const orxSTRING _zString1, const orxSTRING _zString2)
Definition: orxString.h:1458
orxSTATUS
Definition: orxType.h:246
static orxINLINE orxS32 orxString_ICompare(const orxSTRING _zString1, const orxSTRING _zString2)
Definition: orxString.h:638
static orxINLINE orxS32 orxCDECL orxString_NPrint(orxSTRING _zDstString, orxU32 _u32CharNumber, const orxSTRING _zSrcString,...)
Definition: orxString.h:1546
static orxINLINE orxSTATUS orxString_ToS64Base(const orxSTRING _zString, orxU32 _u32Base, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:917
orxFLOAT fZ
Definition: orxVector.h:85
static orxINLINE orxSTRINGID orxString_ToCRC(const orxSTRING _zString)
Definition: orxString.h:1444
#define orxDLLAPI
Definition: orxDecl.h:381
#define STRTO_CAST
Definition: orxString.h:61
#define orxCRC_INDEX_5
#define orxCHAR_LF
Definition: orxType.h:219
static orxINLINE orxBOOL orxString_IsCharacterASCII(orxU32 _u32CharacterCodePoint)
Definition: orxString.h:186
static orxINLINE const orxSTRING orxString_SearchChar(const orxSTRING _zString, orxCHAR _cChar)
Definition: orxString.h:1473
orxDLLAPI void orxFASTCALL orxString_Exit()
static orxINLINE orxSTATUS orxString_ToFloat(const orxSTRING _zString, orxFLOAT *_pfOutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:1052
static const orxFLOAT orxFLOAT_0
Definition: orxType.h:192
orxDLLAPI void orxFASTCALL orxMemory_Free(void *_pMem)
#define orxSTRING_KC_VECTOR_SEPARATOR
Definition: orxString.h:77
#define orxCHAR_NULL
Definition: orxType.h:217
static orxINLINE orxSTATUS orxString_ToS32(const orxSTRING _zString, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:822
#define orxDEBUG_PRINT(LEVEL, STRING,...)
Definition: orxDebug.h:327
static orxINLINE orxU32 orxString_GetCharacterCount(const orxSTRING _zString)
Definition: orxString.h:509
static orxINLINE void * orxMemory_Copy(void *_pDest, const void *_pSrc, orxU32 _u32Size)
Definition: orxMemory.h:148
static orxINLINE orxSTRING orxString_NCopy(orxSTRING _zDstString, const orxSTRING _zSrcString, orxU32 _u32CharNumber)
Definition: orxString.h:543
orxDLLAPI const orxSTRING orxSTRING_FALSE
#define orxSTRING_KC_VECTOR_START_ALT
Definition: orxString.h:76
#define orxASSERT(TEST,...)
Definition: orxDebug.h:353
static orxINLINE orxVECTOR * orxVector_Copy(orxVECTOR *_pvDst, const orxVECTOR *_pvSrc)
Definition: orxVector.h:135
#define orxCHAR_DIRECTORY_SEPARATOR_LINUX
Definition: orxType.h:232
#define orxCRC_INDEX_2
#define orxCRC_INDEX_4
#define orxCRC_GET_FIRST(VALUE)

Generated for orx by doxygen 1.8.11