orx  stable
Portable Game Engine
orxString.h
Go to the documentation of this file.
1 /* Orx - Portable Game Engine
2  *
3  * Copyright (c) 2008-2017 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 #ifdef __orxIOS__
62  #define STRTO_CAST (int)
63 #else /* __orxIOS__ */
64  #define STRTO_CAST (size_t)
65 #endif /* __orxIOS__ */
66 
67 #include <stdio.h>
68 #include <stdarg.h>
69 #include <string.h>
70 #include <stdlib.h>
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++);
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  orxU8 *pu8Byte;
345  orxU32 u32Result;
346 
347  /* Checks */
348  orxASSERT(_zString != orxNULL);
349 
350  /* Gets the first byte */
351  pu8Byte = (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_GetCharacterCounter(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 
558 static orxINLINE orxSTRING orxString_Copy(orxSTRING _zDstString, const orxSTRING _zSrcString)
559 {
560  /* Checks */
561  orxASSERT(_zDstString != orxNULL);
562  orxASSERT(_zSrcString != orxNULL);
563 
564  /* Done! */
565  return(strcpy(_zDstString, _zSrcString));
566 }
567 
572 static orxINLINE orxSTRING orxString_Duplicate(const orxSTRING _zSrcString)
573 {
574  orxU32 u32Size;
575  orxSTRING zResult;
576 
577  /* Checks */
578  orxASSERT(_zSrcString != orxNULL);
579 
580  /* Gets string size in bytes */
581  u32Size = (orxString_GetLength(_zSrcString) + 1) * sizeof(orxCHAR);
582 
583  /* Allocates it */
584  zResult = (orxSTRING)orxMemory_Allocate(u32Size, orxMEMORY_TYPE_TEXT);
585 
586  /* Valid? */
587  if(zResult != orxNULL)
588  {
589  /* Copies source to it */
590  orxMemory_Copy(zResult, _zSrcString, u32Size);
591  }
592 
593  /* Done! */
594  return zResult;
595 }
596 
600 static orxINLINE orxSTATUS orxString_Delete(orxSTRING _zString)
601 {
602  /* Checks */
603  orxASSERT(_zString != orxNULL);
604  orxASSERT(_zString != orxSTRING_EMPTY);
605 
606  /* Frees its memory */
607  orxMemory_Free(_zString);
608 
609  /* Done! */
610  return orxSTATUS_SUCCESS;
611 }
612 
619 static orxINLINE orxS32 orxString_Compare(const orxSTRING _zString1, const orxSTRING _zString2)
620 {
621  /* Checks */
622  orxASSERT(_zString1 != orxNULL);
623  orxASSERT(_zString2 != orxNULL);
624 
625  /* Done! */
626  return(strcmp(_zString1, _zString2));
627 }
628 
637 static orxINLINE orxS32 orxString_NCompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
638 {
639  /* Checks */
640  orxASSERT(_zString1 != orxNULL);
641  orxASSERT(_zString2 != orxNULL);
642 
643  /* Done! */
644  return strncmp(_zString1, _zString2, (size_t)_u32CharNumber);
645 }
646 
653 static orxINLINE orxS32 orxString_ICompare(const orxSTRING _zString1, const orxSTRING _zString2)
654 {
655  /* Checks */
656  orxASSERT(_zString1 != orxNULL);
657  orxASSERT(_zString2 != orxNULL);
658 
659 #ifdef __orxWINDOWS__
660 
661  /* Done! */
662  return(stricmp(_zString1, _zString2));
663 
664 #else /* __orxWINDOWS__ */
665 
666  /* Done! */
667  return strcasecmp(_zString1, _zString2);
668 
669 #endif /* __orxWINDOWS__ */
670 }
671 
680 static orxINLINE orxS32 orxString_NICompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
681 {
682  /* Checks */
683  orxASSERT(_zString1 != orxNULL);
684  orxASSERT(_zString2 != orxNULL);
685 
686 #ifdef __orxWINDOWS__
687 
688  /* Done! */
689  return strnicmp(_zString1, _zString2, (size_t)_u32CharNumber);
690 
691 #else /* __orxWINDOWS__ */
692 
693  /* Done! */
694  return strncasecmp(_zString1, _zString2, _u32CharNumber);
695 
696 #endif /* __orxWINDOWS__ */
697 }
698 
704 static orxINLINE orxU32 orxString_ExtractBase(const orxSTRING _zString, const orxSTRING *_pzRemaining)
705 {
706  orxU32 u32Result, u32Offset;
707 
708  /* Checks */
709  orxASSERT(_zString != orxNULL);
710 
711  /* Default result and offset: decimal */
712  u32Result = 10;
713  u32Offset = 0;
714 
715  /* Depending on first character */
716  switch(_zString[0])
717  {
718  case '0':
719  {
720  /* Depending on second character */
721  switch(_zString[1] | 0x20)
722  {
723  case 'x':
724  {
725  /* Updates result and offset: hexadecimal */
726  u32Result = 16;
727  u32Offset = 2;
728 
729  break;
730  }
731 
732  case 'b':
733  {
734  /* Updates result and offset: binary */
735  u32Result = 2;
736  u32Offset = 2;
737 
738  break;
739  }
740 
741  default:
742  {
743  /* Octal? */
744  if((_zString[1] >= '0')
745  && (_zString[1] <= '9'))
746  {
747  /* Updates result and offset: octal */
748  u32Result = 8;
749  u32Offset = 1;
750  }
751 
752  break;
753  }
754  }
755 
756  break;
757  }
758 
759  case '#':
760  {
761  /* Updates result and offset: hexadecimal */
762  u32Result = 16;
763  u32Offset = 1;
764 
765  break;
766  }
767 
768  default:
769  {
770  break;
771  }
772  }
773 
774  /* Asks for remaining string? */
775  if(_pzRemaining != orxNULL)
776  {
777  /* Stores it */
778  *_pzRemaining = _zString + u32Offset;
779  }
780 
781  /* Done! */
782  return u32Result;
783 }
784 
792 static orxINLINE orxSTATUS orxString_ToS32Base(const orxSTRING _zString, orxU32 _u32Base, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
793 {
794  orxCHAR *pcEnd;
795  orxSTATUS eResult;
796 
797  /* Checks */
798  orxASSERT(_ps32OutValue != orxNULL);
799  orxASSERT(_zString != orxNULL);
800 
801  /* Convert */
802  *_ps32OutValue = (orxS32)strtol(_zString, &pcEnd, STRTO_CAST _u32Base);
803 
804  /* Valid conversion ? */
805  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
806  {
807  /* Updates result */
808  eResult = orxSTATUS_SUCCESS;
809  }
810  else
811  {
812  /* Updates result */
813  eResult = orxSTATUS_FAILURE;
814  }
815 
816  /* Asks for remaining string? */
817  if(_pzRemaining != orxNULL)
818  {
819  /* Stores it */
820  *_pzRemaining = pcEnd;
821  }
822 
823  /* Done! */
824  return eResult;
825 }
826 
833 static orxINLINE orxSTATUS orxString_ToS32(const orxSTRING _zString, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
834 {
835  const orxSTRING zValue;
836  orxU32 u32Base;
837  orxSTATUS eResult;
838 
839  /* Checks */
840  orxASSERT(_ps32OutValue != orxNULL);
841  orxASSERT(_zString != orxNULL);
842 
843  /* Extracts base */
844  u32Base = orxString_ExtractBase(_zString, &zValue);
845 
846  /* Gets value */
847  eResult = orxString_ToS32Base(zValue, u32Base, _ps32OutValue, _pzRemaining);
848 
849  /* Done! */
850  return eResult;
851 }
852 
860 static orxINLINE orxSTATUS orxString_ToU32Base(const orxSTRING _zString, orxU32 _u32Base, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
861 {
862  orxCHAR *pcEnd;
863  orxSTATUS eResult;
864 
865  /* Checks */
866  orxASSERT(_pu32OutValue != orxNULL);
867  orxASSERT(_zString != orxNULL);
868 
869  /* Convert */
870  *_pu32OutValue = (orxU32)strtoul(_zString, &pcEnd, STRTO_CAST _u32Base);
871 
872  /* Valid conversion ? */
873  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
874  {
875  /* Updates result */
876  eResult = orxSTATUS_SUCCESS;
877  }
878  else
879  {
880  /* Updates result */
881  eResult = orxSTATUS_FAILURE;
882  }
883 
884  /* Asks for remaining string? */
885  if(_pzRemaining != orxNULL)
886  {
887  /* Stores it */
888  *_pzRemaining = pcEnd;
889  }
890 
891  /* Done! */
892  return eResult;
893 }
894 
901 static orxINLINE orxSTATUS orxString_ToU32(const orxSTRING _zString, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
902 {
903  const orxSTRING zValue;
904  orxU32 u32Base;
905  orxSTATUS eResult;
906 
907  /* Checks */
908  orxASSERT(_pu32OutValue != orxNULL);
909  orxASSERT(_zString != orxNULL);
910 
911  /* Extracts base */
912  u32Base = orxString_ExtractBase(_zString, &zValue);
913 
914  /* Gets value */
915  eResult = orxString_ToU32Base(zValue, u32Base, _pu32OutValue, _pzRemaining);
916 
917  /* Done! */
918  return eResult;
919 }
920 
928 static orxINLINE orxSTATUS orxString_ToS64Base(const orxSTRING _zString, orxU32 _u32Base, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
929 {
930  orxCHAR *pcEnd;
931  orxSTATUS eResult;
932 
933  /* Checks */
934  orxASSERT(_ps64OutValue != orxNULL);
935  orxASSERT(_zString != orxNULL);
936 
937  /* Convert */
938  *_ps64OutValue = (orxS64)strtoll(_zString, &pcEnd, STRTO_CAST _u32Base);
939 
940  /* Valid conversion ? */
941  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
942  {
943  /* Updates result */
944  eResult = orxSTATUS_SUCCESS;
945  }
946  else
947  {
948  /* Updates result */
949  eResult = orxSTATUS_FAILURE;
950  }
951 
952  /* Asks for remaining string? */
953  if(_pzRemaining != orxNULL)
954  {
955  /* Stores it */
956  *_pzRemaining = pcEnd;
957  }
958 
959  /* Done! */
960  return eResult;
961 }
962 
969 static orxINLINE orxSTATUS orxString_ToS64(const orxSTRING _zString, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
970 {
971  const orxSTRING zValue;
972  orxU32 u32Base;
973  orxSTATUS eResult;
974 
975  /* Checks */
976  orxASSERT(_ps64OutValue != orxNULL);
977  orxASSERT(_zString != orxNULL);
978 
979  /* Extracts base */
980  u32Base = orxString_ExtractBase(_zString, &zValue);
981 
982  /* Gets signed value */
983  eResult = orxString_ToS64Base(zValue, u32Base, _ps64OutValue, _pzRemaining);
984 
985  /* Done! */
986  return eResult;
987 }
988 
996 static orxINLINE orxSTATUS orxString_ToU64Base(const orxSTRING _zString, orxU32 _u32Base, orxU64 *_pu64OutValue, const orxSTRING *_pzRemaining)
997 {
998  orxCHAR *pcEnd;
999  orxSTATUS eResult;
1000 
1001  /* Checks */
1002  orxASSERT(_pu64OutValue != orxNULL);
1003  orxASSERT(_zString != orxNULL);
1004 
1005  /* Convert */
1006  *_pu64OutValue = (orxU64)strtoull(_zString, &pcEnd, STRTO_CAST _u32Base);
1007 
1008  /* Valid conversion ? */
1009  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
1010  {
1011  /* Updates result */
1012  eResult = orxSTATUS_SUCCESS;
1013  }
1014  else
1015  {
1016  /* Updates result */
1017  eResult = orxSTATUS_FAILURE;
1018  }
1019 
1020  /* Asks for remaining string? */
1021  if(_pzRemaining != orxNULL)
1022  {
1023  /* Stores it */
1024  *_pzRemaining = pcEnd;
1025  }
1026 
1027  /* Done! */
1028  return eResult;
1029 }
1030 
1037 static orxINLINE orxSTATUS orxString_ToU64(const orxSTRING _zString, orxU64 *_pu64OutValue, const orxSTRING *_pzRemaining)
1038 {
1039  const orxSTRING zValue;
1040  orxU32 u32Base;
1041  orxSTATUS eResult;
1042 
1043  /* Checks */
1044  orxASSERT(_pu64OutValue != orxNULL);
1045  orxASSERT(_zString != orxNULL);
1046 
1047  /* Extracts base */
1048  u32Base = orxString_ExtractBase(_zString, &zValue);
1049 
1050  /* Gets signed value */
1051  eResult = orxString_ToU64Base(zValue, u32Base, _pu64OutValue, _pzRemaining);
1052 
1053  /* Done! */
1054  return eResult;
1055 }
1056 
1063 static orxINLINE orxSTATUS orxString_ToFloat(const orxSTRING _zString, orxFLOAT *_pfOutValue, const orxSTRING *_pzRemaining)
1064 {
1065  orxCHAR *pcEnd;
1066  orxSTATUS eResult;
1067 
1068  /* Checks */
1069  orxASSERT(_pfOutValue != orxNULL);
1070  orxASSERT(_zString != orxNULL);
1071 
1072  /* Linux / Mac / iOS / Android / MSVC? */
1073 #if defined(__orxLINUX__) || defined(__orxMAC__) || defined (__orxIOS__) || defined(__orxMSVC__) || defined(__orxANDROID__)
1074 
1075  /* Converts it */
1076  *_pfOutValue = (orxFLOAT)strtod(_zString, &pcEnd);
1077 
1078 #else /* __orxLINUX__ || __orxMAC__ || __orxIOS__ || __orxMSVC__ || __orxANDROID__ */
1079 
1080  /* Converts it */
1081  *_pfOutValue = strtof(_zString, &pcEnd);
1082 
1083 #endif /* __orxLINUX__ || __orxMAC__ || __orxIOS__ || __orxMSVC__ || __orxANDROID__ */
1084 
1085  /* Valid conversion ? */
1086  if((pcEnd != _zString) && (_zString[0] != orxCHAR_NULL))
1087  {
1088  /* Updates result */
1089  eResult = orxSTATUS_SUCCESS;
1090  }
1091  else
1092  {
1093  /* Updates result */
1094  eResult = orxSTATUS_FAILURE;
1095  }
1096 
1097  /* Asks for remaining string? */
1098  if(_pzRemaining != orxNULL)
1099  {
1100  /* Stores it */
1101  *_pzRemaining = pcEnd;
1102  }
1103 
1104  /* Done! */
1105  return eResult;
1106 }
1107 
1114 static orxINLINE orxSTATUS orxString_ToVector(const orxSTRING _zString, orxVECTOR *_pvOutValue, const orxSTRING *_pzRemaining)
1115 {
1116  orxVECTOR stValue;
1117  const orxSTRING zString;
1118  orxSTATUS eResult = orxSTATUS_FAILURE;
1119 
1120  /* Checks */
1121  orxASSERT(_pvOutValue != orxNULL);
1122  orxASSERT(_zString != orxNULL);
1123 
1124  /* Skips all white spaces */
1125  zString = orxString_SkipWhiteSpaces(_zString);
1126 
1127  /* Is a vector start character? */
1128  if((*zString == orxSTRING_KC_VECTOR_START)
1129  || (*zString == orxSTRING_KC_VECTOR_START_ALT))
1130  {
1131  /* Skips all white spaces */
1132  zString = orxString_SkipWhiteSpaces(zString + 1);
1133 
1134  /* Gets X value */
1135  eResult = orxString_ToFloat(zString, &(stValue.fX), &zString);
1136 
1137  /* Success? */
1138  if(eResult != orxSTATUS_FAILURE)
1139  {
1140  /* Skips all white spaces */
1141  zString = orxString_SkipWhiteSpaces(zString);
1142 
1143  /* Is a vector separator character? */
1144  if(*zString == orxSTRING_KC_VECTOR_SEPARATOR)
1145  {
1146  /* Skips all white spaces */
1147  zString = orxString_SkipWhiteSpaces(zString + 1);
1148 
1149  /* Gets Y value */
1150  eResult = orxString_ToFloat(zString, &(stValue.fY), &zString);
1151 
1152  /* Success? */
1153  if(eResult != orxSTATUS_FAILURE)
1154  {
1155  /* Skips all white spaces */
1156  zString = orxString_SkipWhiteSpaces(zString);
1157 
1158  /* Is a vector separator character? */
1159  if(*zString == orxSTRING_KC_VECTOR_SEPARATOR)
1160  {
1161  /* Skips all white spaces */
1162  zString = orxString_SkipWhiteSpaces(zString + 1);
1163 
1164  /* Gets Z value */
1165  eResult = orxString_ToFloat(zString, &(stValue.fZ), &zString);
1166 
1167  /* Success? */
1168  if(eResult != orxSTATUS_FAILURE)
1169  {
1170  /* Skips all white spaces */
1171  zString = orxString_SkipWhiteSpaces(zString);
1172 
1173  /* Is not a vector end character? */
1174  if((*zString != orxSTRING_KC_VECTOR_END)
1175  && (*zString != orxSTRING_KC_VECTOR_END_ALT))
1176  {
1177  /* Updates result */
1178  eResult = orxSTATUS_FAILURE;
1179  }
1180  }
1181  }
1182  }
1183  }
1184  }
1185  }
1186 
1187  /* Valid? */
1188  if(eResult != orxSTATUS_FAILURE)
1189  {
1190  /* Updates vector */
1191  orxVector_Copy(_pvOutValue, &stValue);
1192 
1193  /* Asks for remaining string? */
1194  if(_pzRemaining != orxNULL)
1195  {
1196  /* Stores it */
1197  *_pzRemaining = zString + 1;
1198  }
1199  }
1200 
1201  /* Done! */
1202  return eResult;
1203 }
1204 
1211 static orxINLINE orxSTATUS orxString_ToBool(const orxSTRING _zString, orxBOOL *_pbOutValue, const orxSTRING *_pzRemaining)
1212 {
1213  orxS32 s32Value;
1214  orxSTATUS eResult;
1215 
1216  /* Checks */
1217  orxASSERT(_pbOutValue != orxNULL);
1218  orxASSERT(_zString != orxNULL);
1219 
1220  /* Tries numeric value */
1221  eResult = orxString_ToS32Base(_zString, 10, &s32Value, _pzRemaining);
1222 
1223  /* Valid? */
1224  if(eResult != orxSTATUS_FAILURE)
1225  {
1226  /* Updates boolean */
1227  *_pbOutValue = (s32Value != 0) ? orxTRUE : orxFALSE;
1228  }
1229  else
1230  {
1231  orxU32 u32Length;
1232 
1233  /* Gets length of false */
1234  u32Length = orxString_GetLength(orxSTRING_FALSE);
1235 
1236  /* Is false? */
1237  if(orxString_NICompare(_zString, orxSTRING_FALSE, u32Length) == 0)
1238  {
1239  /* Updates boolean */
1240  *_pbOutValue = orxFALSE;
1241 
1242  /* Has remaining? */
1243  if(_pzRemaining != orxNULL)
1244  {
1245  /* Updates it */
1246  *_pzRemaining += u32Length;
1247  }
1248 
1249  /* Updates result */
1250  eResult = orxSTATUS_SUCCESS;
1251  }
1252  else
1253  {
1254  /* Gets length of true */
1255  u32Length = orxString_GetLength(orxSTRING_TRUE);
1256 
1257  /* Is true? */
1258  if(orxString_NICompare(_zString, orxSTRING_TRUE, u32Length) == 0)
1259  {
1260  /* Updates boolean */
1261  *_pbOutValue = orxTRUE;
1262 
1263  /* Has remaining? */
1264  if(_pzRemaining != orxNULL)
1265  {
1266  /* Updates it */
1267  *_pzRemaining += u32Length;
1268  }
1269 
1270  /* Updates result */
1271  eResult = orxSTATUS_SUCCESS;
1272  }
1273  }
1274  }
1275 
1276  /* Done! */
1277  return eResult;
1278 }
1279 
1284 static orxINLINE orxSTRING orxString_LowerCase(orxSTRING _zString)
1285 {
1286  orxCHAR *pc;
1287 
1288  /* Checks */
1289  orxASSERT(_zString != orxNULL);
1290 
1291  /* Converts the whole string */
1292  for(pc = _zString; *pc != orxCHAR_NULL; pc++)
1293  {
1294  /* Needs to be converted? */
1295  if(*pc >= 'A' && *pc <= 'Z')
1296  {
1297  /* Lower case */
1298  *pc |= 0x20;
1299  }
1300  }
1301 
1302  return _zString;
1303 }
1304 
1309 static orxINLINE orxSTRING orxString_UpperCase(orxSTRING _zString)
1310 {
1311  orxCHAR *pc;
1312 
1313  /* Checks */
1314  orxASSERT(_zString != orxNULL);
1315 
1316  /* Converts the whole string */
1317  for(pc = _zString; *pc != orxCHAR_NULL; pc++)
1318  {
1319  /* Needs to be converted? */
1320  if(*pc >= 'a' && *pc <= 'z')
1321  {
1322  /* Upper case */
1323  *pc &= ~0x20;
1324  }
1325  }
1326 
1327  return _zString;
1328 }
1329 
1336 static orxINLINE orxU32 orxString_NContinueCRC(const orxSTRING _zString, orxU32 _u32CRC, orxU32 _u32CharNumber)
1337 {
1338  orxU32 u32CRC, u32Length;
1339  const orxU8 *pu8;
1340 
1341 #ifdef __orxLITTLE_ENDIAN__
1342 
1343 #define orxCRC_GET_FIRST(VALUE) VALUE
1344 #define orxCRC_INDEX_0 0
1345 #define orxCRC_INDEX_1 1
1346 #define orxCRC_INDEX_2 2
1347 #define orxCRC_INDEX_3 3
1348 #define orxCRC_INDEX_4 4
1349 #define orxCRC_INDEX_5 5
1350 #define orxCRC_INDEX_6 6
1351 #define orxCRC_INDEX_7 7
1352 
1353 #else /* __orxLITTLE_ENDIAN__ */
1354 
1355 #define orxCRC_GET_FIRST(VALUE) ((VALUE >> 24) | ((VALUE >> 8) & 0x0000FF00) | ((VALUE << 8) & 0x00FF0000) | (VALUE << 24))
1356 #define orxCRC_INDEX_0 3
1357 #define orxCRC_INDEX_1 2
1358 #define orxCRC_INDEX_2 1
1359 #define orxCRC_INDEX_3 0
1360 #define orxCRC_INDEX_4 7
1361 #define orxCRC_INDEX_5 6
1362 #define orxCRC_INDEX_6 5
1363 #define orxCRC_INDEX_7 4
1364 
1365 #endif /* __orxLITTLE_ENDIAN__ */
1366 
1367  /* Checks */
1368  orxASSERT(_zString != orxNULL);
1369  orxASSERT(_u32CharNumber <= orxString_GetLength(_zString));
1370 
1371  /* Inits CRC */
1372  u32CRC = ~_u32CRC;
1373 
1374  /* For all slices */
1375  for(u32Length = _u32CharNumber, pu8 = (const orxU8 *)_zString; u32Length >= 8; u32Length -= 8, pu8 += 8)
1376  {
1377  orxU32 u32First, u32Second;
1378 
1379  /* Gets the slice's data */
1380  orxMemory_Copy(&u32First, pu8, sizeof(orxU32));
1381  orxMemory_Copy(&u32Second, pu8 + 4, sizeof(orxU32));
1382  u32First ^= orxCRC_GET_FIRST(u32CRC);
1383 
1384  /* Updates the CRC */
1385  u32CRC = saau32CRCTable[orxCRC_INDEX_7][u32First & 0xFF]
1386  ^ saau32CRCTable[orxCRC_INDEX_6][(u32First >> 8) & 0xFF]
1387  ^ saau32CRCTable[orxCRC_INDEX_5][(u32First >> 16) & 0xFF]
1388  ^ saau32CRCTable[orxCRC_INDEX_4][u32First >> 24]
1389  ^ saau32CRCTable[orxCRC_INDEX_3][u32Second & 0xFF]
1390  ^ saau32CRCTable[orxCRC_INDEX_2][(u32Second >> 8) & 0xFF]
1391  ^ saau32CRCTable[orxCRC_INDEX_1][(u32Second >> 16) & 0xFF]
1392  ^ saau32CRCTable[orxCRC_INDEX_0][u32Second >> 24];
1393  }
1394 
1395  /* For all remaining characters */
1396  for(; u32Length != 0; u32Length--, pu8++)
1397  {
1398  /* Updates the CRC */
1399  u32CRC = saau32CRCTable[0][((orxU8)(u32CRC & 0xFF)) ^ *pu8] ^ (u32CRC >> 8);
1400  }
1401 
1402 #undef orxCRC_GET_FIRST
1403 #undef orxCRC_INDEX_0
1404 #undef orxCRC_INDEX_1
1405 #undef orxCRC_INDEX_2
1406 #undef orxCRC_INDEX_3
1407 #undef orxCRC_INDEX_4
1408 #undef orxCRC_INDEX_5
1409 #undef orxCRC_INDEX_6
1410 #undef orxCRC_INDEX_7
1411 
1412  /* Done! */
1413  return ~u32CRC;
1414 }
1415 
1421 static orxINLINE orxU32 orxString_ContinueCRC(const orxSTRING _zString, orxU32 _u32CRC)
1422 {
1423  orxU32 u32CRC;
1424 
1425  /* Updates CRC */
1426  u32CRC = orxString_NContinueCRC(_zString, _u32CRC, orxString_GetLength(_zString));
1427 
1428  /* Done! */
1429  return u32CRC;
1430 }
1431 
1437 static orxINLINE orxU32 orxString_NToCRC(const orxSTRING _zString, orxU32 _u32CharNumber)
1438 {
1439  /* Checks */
1440  orxASSERT(_zString != orxNULL);
1441  orxASSERT(_u32CharNumber <= orxString_GetLength(_zString));
1442 
1443  /* Done! */
1444  return orxString_NContinueCRC(_zString, 0, _u32CharNumber);
1445 }
1446 
1451 static orxINLINE orxU32 orxString_ToCRC(const orxSTRING _zString)
1452 {
1453  /* Checks */
1454  orxASSERT(_zString != orxNULL);
1455 
1456  /* Done! */
1457  return orxString_ContinueCRC(_zString, 0);
1458 }
1459 
1465 static orxINLINE const orxSTRING orxString_SearchString(const orxSTRING _zString1, const orxSTRING _zString2)
1466 {
1467  /* Checks */
1468  orxASSERT(_zString1 != orxNULL);
1469  orxASSERT(_zString2 != orxNULL);
1470 
1471  /* Returns result */
1472  return(strstr(_zString1, _zString2));
1473 }
1474 
1480 static orxINLINE const orxSTRING orxString_SearchChar(const orxSTRING _zString, orxCHAR _cChar)
1481 {
1482  /* Checks */
1483  orxASSERT(_zString != orxNULL);
1484 
1485  /* Returns result */
1486  return(strchr(_zString, _cChar));
1487 }
1488 
1495 static orxINLINE orxS32 orxString_SearchCharIndex(const orxSTRING _zString, orxCHAR _cChar, orxU32 _u32Position)
1496 {
1497  orxS32 s32Result = -1;
1498  orxS32 s32Index;
1499  const orxCHAR *pc;
1500 
1501  /* Checks */
1502  orxASSERT(_zString != orxNULL);
1503  orxASSERT(_u32Position <= orxString_GetLength(_zString));
1504 
1505  /* For all characters */
1506  for(s32Index = _u32Position, pc = _zString + s32Index; *pc != orxCHAR_NULL; pc++, s32Index++)
1507  {
1508  /* Found? */
1509  if(*pc == _cChar)
1510  {
1511  /* Updates result */
1512  s32Result = s32Index;
1513 
1514  break;
1515  }
1516  }
1517 
1518  /* Done! */
1519  return s32Result;
1520 }
1521 
1527 static orxINLINE orxS32 orxCDECL orxString_Print(orxSTRING _zDstString, const orxSTRING _zSrcString, ...)
1528 {
1529  va_list stArgs;
1530  orxS32 s32Result;
1531 
1532  /* Checks */
1533  orxASSERT(_zDstString != orxNULL);
1534  orxASSERT(_zSrcString != orxNULL);
1535 
1536  /* Gets variable arguments & prints the string */
1537  va_start(stArgs, _zSrcString);
1538  s32Result = vsprintf(_zDstString, _zSrcString, stArgs);
1539  va_end(stArgs);
1540 
1541  /* Clamps result */
1542  s32Result = orxMAX(s32Result, 0);
1543 
1544  /* Done! */
1545  return s32Result;
1546 }
1547 
1554 static orxINLINE orxS32 orxCDECL orxString_NPrint(orxSTRING _zDstString, orxU32 _u32CharNumber, const orxSTRING _zSrcString, ...)
1555 {
1556  va_list stArgs;
1557  orxS32 s32Result;
1558 
1559  /* Checks */
1560  orxASSERT(_zDstString != orxNULL);
1561  orxASSERT(_zSrcString != orxNULL);
1562 
1563  /* Gets variable arguments & prints the string */
1564  va_start(stArgs, _zSrcString);
1565  s32Result = vsnprintf(_zDstString, (size_t)_u32CharNumber, _zSrcString, stArgs);
1566  va_end(stArgs);
1567 
1568 #ifdef __orxMSVC__
1569  /* Overflow? */
1570  if(s32Result <= 0)
1571  {
1572  /* Updates result */
1573  s32Result = _u32CharNumber;
1574  }
1575 #endif /* __orxWINDOWS__ */
1576 
1577  /* Clamps result */
1578  s32Result = orxCLAMP(s32Result, 0, (orxS32)_u32CharNumber);
1579 
1580  /* Done! */
1581  return s32Result;
1582 }
1583 
1589 static orxINLINE orxS32 orxCDECL orxString_Scan(const orxSTRING _zString, const orxSTRING _zFormat, ...)
1590 {
1591  va_list stArgs;
1592  orxS32 s32Result;
1593 
1594  /* Checks */
1595  orxASSERT(_zString != orxNULL);
1596 
1597 #ifdef __orxMSVC__
1598 
1599  /* Ugly workaround the missing vsscanf in MSVC up to version 2013 */
1600  {
1601  void *p[16];
1602  orxS32 i;
1603 
1604  /* Starts variable list */
1605  va_start(stArgs, _zFormat);
1606 
1607  /* For all potential parameters */
1608  for(i = 0; i < orxARRAY_GET_ITEM_COUNT(p); i++)
1609  {
1610  /* Gets its address */
1611  p[i] = va_arg(stArgs, void *);
1612  }
1613 
1614  /* Scans the string */
1615  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]);
1616 
1617  /* Ends variable list */
1618  va_end(stArgs);
1619  }
1620 
1621 #else /* __orxMSVC__ */
1622 
1623  /* Gets variable arguments & scans the string */
1624  va_start(stArgs, _zFormat);
1625  s32Result = vsscanf(_zString, _zFormat, stArgs);
1626  va_end(stArgs);
1627 
1628 #endif /* __orxMSVC__ */
1629 
1630  /* Clamps result */
1631  s32Result = orxMAX(s32Result, 0);
1632 
1633  /* Done! */
1634  return s32Result;
1635 }
1636 
1641 static orxINLINE const orxSTRING orxString_GetExtension(const orxSTRING _zFileName)
1642 {
1643  orxS32 s32Index, s32NextIndex;
1644  const orxSTRING zResult;
1645 
1646  /* Checks */
1647  orxASSERT(_zFileName != orxNULL);
1648 
1649  /* Finds last '.' */
1650  for(s32Index = orxString_SearchCharIndex(_zFileName, '.', 0);
1651  (s32Index >= 0) && ((s32NextIndex = orxString_SearchCharIndex(_zFileName, '.', s32Index + 1)) > 0);
1652  s32Index = s32NextIndex);
1653 
1654  /* Updates result */
1655  zResult = (s32Index >= 0) ? _zFileName + s32Index + 1 : orxSTRING_EMPTY;
1656 
1657  /* Done! */
1658  return zResult;
1659 }
1660 
1661 /* *** String module functions *** */
1662 
1665 extern orxDLLAPI void orxFASTCALL orxString_Setup();
1666 
1670 extern orxDLLAPI orxSTATUS orxFASTCALL orxString_Init();
1671 
1674 extern orxDLLAPI void orxFASTCALL orxString_Exit();
1675 
1676 
1681 extern orxDLLAPI orxU32 orxFASTCALL orxString_GetID(const orxSTRING _zString);
1682 
1687 extern orxDLLAPI const orxSTRING orxFASTCALL orxString_GetFromID(orxU32 _u32ID);
1688 
1693 extern orxDLLAPI const orxSTRING orxFASTCALL orxString_Store(const orxSTRING _zString);
1694 
1695 
1696 #ifdef __orxMSVC__
1697 
1698  #pragma warning(default : 4996)
1699 
1700 #endif /* __orxMSVC__ */
1701 
1702 #endif /* _orxSTRING_H_ */
1703 
#define orxARRAY_GET_ITEM_COUNT(ARRAY)
Definition: orxDecl.h:405
static orxINLINE const orxSTRING orxString_GetExtension(const orxSTRING _zFileName)
Definition: orxString.h:1641
static orxINLINE orxSTATUS orxString_ToS64(const orxSTRING _zString, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:969
#define orxCRC_INDEX_3
orxDLLAPI void orxFASTCALL orxString_Setup()
orxDLLAPI const orxSTRING orxFASTCALL orxString_Store(const orxSTRING _zString)
#define orxCRC_INDEX_6
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:860
static orxINLINE orxS32 orxString_NICompare(const orxSTRING _zString1, const orxSTRING _zString2, orxU32 _u32CharNumber)
Definition: orxString.h:680
static orxINLINE const orxSTRING orxString_SkipWhiteSpaces(const orxSTRING _zString)
Definition: orxString.h:99
static orxINLINE orxSTRING orxString_Duplicate(const orxSTRING _zSrcString)
Definition: orxString.h:572
#define orxSTRING_KC_VECTOR_END
Definition: orxString.h:78
static orxINLINE orxSTRING orxString_LowerCase(orxSTRING _zString)
Definition: orxString.h:1284
#define orxCRC_INDEX_7
static orxINLINE orxU32 orxString_ContinueCRC(const orxSTRING _zString, orxU32 _u32CRC)
Definition: orxString.h:1421
#define orxTRUE
Definition: orxType.h:186
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:637
static const orxU32 orxU32_UNDEFINED
Definition: orxType.h:202
orxDLLAPI orxU32 orxFASTCALL orxString_GetID(const orxSTRING _zString)
static orxINLINE orxU32 orxString_NToCRC(const orxSTRING _zString, orxU32 _u32CharNumber)
Definition: orxString.h:1437
#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:1037
static orxINLINE orxSTATUS orxString_ToU32(const orxSTRING _zString, orxU32 *_pu32OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:901
orxFLOAT fY
Definition: orxVector.h:68
static orxINLINE orxU32 orxString_ExtractBase(const orxSTRING _zString, const orxSTRING *_pzRemaining)
Definition: orxString.h:704
static orxINLINE orxS32 orxString_SearchCharIndex(const orxSTRING _zString, orxCHAR _cChar, orxU32 _u32Position)
Definition: orxString.h:1495
#define orxCLAMP(V, MIN, MAX)
Definition: orxMath.h:86
#define orxFALSE
Definition: orxType.h:185
static orxINLINE orxS32 orxCDECL orxString_Scan(const orxSTRING _zString, const orxSTRING _zFormat,...)
Definition: orxString.h:1589
#define orxCHAR_DIRECTORY_SEPARATOR_WINDOWS
Definition: orxType.h:228
orxFLOAT fX
Definition: orxVector.h:60
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:792
static orxINLINE orxU32 orxString_NContinueCRC(const orxSTRING _zString, orxU32 _u32CRC, orxU32 _u32CharNumber)
Definition: orxString.h:1336
static orxINLINE const orxSTRING orxString_SkipPath(const orxSTRING _zString)
Definition: orxString.h:130
orxDLLAPI const orxSTRING orxSTRING_EMPTY
#define orxCRC_INDEX_0
static orxINLINE orxU32 orxString_GetCharacterCounter(const orxSTRING _zString)
Definition: orxString.h:509
static orxINLINE orxSTATUS orxString_ToVector(const orxSTRING _zString, orxVECTOR *_pvOutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:1114
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:1309
#define orxMAX(A, B)
Definition: orxMath.h:78
static orxINLINE orxSTRING orxString_Copy(orxSTRING _zDstString, const orxSTRING _zSrcString)
Definition: orxString.h:558
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:1211
static orxINLINE orxS32 orxCDECL orxString_Print(orxSTRING _zDstString, const orxSTRING _zSrcString,...)
Definition: orxString.h:1527
static orxINLINE orxSTATUS orxString_ToU64Base(const orxSTRING _zString, orxU32 _u32Base, orxU64 *_pu64OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:996
static orxINLINE orxSTATUS orxString_Delete(orxSTRING _zString)
Definition: orxString.h:600
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:619
static orxU32 orxFASTCALL orxString_PrintUTF8Character(orxSTRING _zDstString, orxU32 _u32Size, orxU32 _u32CharacterCodePoint)
Definition: orxString.h:249
static orxINLINE const orxSTRING orxString_SearchString(const orxSTRING _zString1, const orxSTRING _zString2)
Definition: orxString.h:1465
orxSTATUS
Definition: orxType.h:243
static orxINLINE orxS32 orxString_ICompare(const orxSTRING _zString1, const orxSTRING _zString2)
Definition: orxString.h:653
static orxINLINE orxS32 orxCDECL orxString_NPrint(orxSTRING _zDstString, orxU32 _u32CharNumber, const orxSTRING _zSrcString,...)
Definition: orxString.h:1554
static orxINLINE orxSTATUS orxString_ToS64Base(const orxSTRING _zString, orxU32 _u32Base, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:928
orxFLOAT fZ
Definition: orxVector.h:76
#define orxDLLAPI
Definition: orxDecl.h:387
#define STRTO_CAST
Definition: orxString.h:64
#define orxCRC_INDEX_5
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:1480
orxDLLAPI void orxFASTCALL orxString_Exit()
static orxINLINE orxSTATUS orxString_ToFloat(const orxSTRING _zString, orxFLOAT *_pfOutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:1063
static orxINLINE orxU32 orxString_ToCRC(const orxSTRING _zString)
Definition: orxString.h:1451
orxDLLAPI void orxFASTCALL orxMemory_Free(void *_pMem)
#define orxSTRING_KC_VECTOR_SEPARATOR
Definition: orxString.h:77
#define orxCHAR_NULL
Definition: orxType.h:214
static orxINLINE orxSTATUS orxString_ToS32(const orxSTRING _zString, orxS32 *_ps32OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:833
#define orxDEBUG_PRINT(LEVEL, STRING,...)
Definition: orxDebug.h:279
static orxINLINE void * orxMemory_Copy(void *_pDest, const void *_pSrc, orxU32 _u32Size)
Definition: orxMemory.h:159
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:298
static orxINLINE orxVECTOR * orxVector_Copy(orxVECTOR *_pvDst, const orxVECTOR *_pvSrc)
Definition: orxVector.h:126
#define orxCHAR_DIRECTORY_SEPARATOR_LINUX
Definition: orxType.h:229
#define orxCRC_INDEX_2
#define orxCRC_INDEX_4
#define orxCRC_GET_FIRST(VALUE)
orxDLLAPI const orxSTRING orxFASTCALL orxString_GetFromID(orxU32 _u32ID)

Generated for orx by doxygen 1.5.6