orx  1.9
Portable Game Engine
orxString.h
Go to the documentation of this file.
1 /* Orx - Portable Game Engine
2  *
3  * Copyright (c) 2008-2018 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_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 
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  if(orxString_ToFloat(zString, &(stValue.fX), &zString) != orxSTATUS_FAILURE)
1136  {
1137  /* Skips all white spaces */
1138  zString = orxString_SkipWhiteSpaces(zString);
1139 
1140  /* Is a vector separator character? */
1141  if(*zString == orxSTRING_KC_VECTOR_SEPARATOR)
1142  {
1143  /* Skips all white spaces */
1144  zString = orxString_SkipWhiteSpaces(zString + 1);
1145 
1146  /* Gets Y value */
1147  if(orxString_ToFloat(zString, &(stValue.fY), &zString) != orxSTATUS_FAILURE)
1148  {
1149  /* Skips all white spaces */
1150  zString = orxString_SkipWhiteSpaces(zString);
1151 
1152  /* Is a vector separator character? */
1153  if(*zString == orxSTRING_KC_VECTOR_SEPARATOR)
1154  {
1155  /* Skips all white spaces */
1156  zString = orxString_SkipWhiteSpaces(zString + 1);
1157 
1158  /* Gets Z value */
1159  if(orxString_ToFloat(zString, &(stValue.fZ), &zString) != orxSTATUS_FAILURE)
1160  {
1161  /* Skips all white spaces */
1162  zString = orxString_SkipWhiteSpaces(zString);
1163 
1164  /* Has a valid ending marker? */
1165  if((*zString == orxSTRING_KC_VECTOR_END)
1166  || (*zString == orxSTRING_KC_VECTOR_END_ALT))
1167  {
1168  /* Updates result */
1169  eResult = orxSTATUS_SUCCESS;
1170  }
1171  }
1172  }
1173  }
1174  }
1175  }
1176  }
1177 
1178  /* Valid? */
1179  if(eResult != orxSTATUS_FAILURE)
1180  {
1181  /* Updates vector */
1182  orxVector_Copy(_pvOutValue, &stValue);
1183 
1184  /* Asks for remaining string? */
1185  if(_pzRemaining != orxNULL)
1186  {
1187  /* Stores it */
1188  *_pzRemaining = zString + 1;
1189  }
1190  }
1191 
1192  /* Done! */
1193  return eResult;
1194 }
1195 
1202 static orxINLINE orxSTATUS orxString_ToBool(const orxSTRING _zString, orxBOOL *_pbOutValue, const orxSTRING *_pzRemaining)
1203 {
1204  orxS32 s32Value;
1205  orxSTATUS eResult;
1206 
1207  /* Checks */
1208  orxASSERT(_pbOutValue != orxNULL);
1209  orxASSERT(_zString != orxNULL);
1210 
1211  /* Tries numeric value */
1212  eResult = orxString_ToS32Base(_zString, 10, &s32Value, _pzRemaining);
1213 
1214  /* Valid? */
1215  if(eResult != orxSTATUS_FAILURE)
1216  {
1217  /* Updates boolean */
1218  *_pbOutValue = (s32Value != 0) ? orxTRUE : orxFALSE;
1219  }
1220  else
1221  {
1222  orxU32 u32Length;
1223 
1224  /* Gets length of false */
1225  u32Length = orxString_GetLength(orxSTRING_FALSE);
1226 
1227  /* Is false? */
1228  if(orxString_NICompare(_zString, orxSTRING_FALSE, u32Length) == 0)
1229  {
1230  /* Updates boolean */
1231  *_pbOutValue = orxFALSE;
1232 
1233  /* Has remaining? */
1234  if(_pzRemaining != orxNULL)
1235  {
1236  /* Updates it */
1237  *_pzRemaining += u32Length;
1238  }
1239 
1240  /* Updates result */
1241  eResult = orxSTATUS_SUCCESS;
1242  }
1243  else
1244  {
1245  /* Gets length of true */
1246  u32Length = orxString_GetLength(orxSTRING_TRUE);
1247 
1248  /* Is true? */
1249  if(orxString_NICompare(_zString, orxSTRING_TRUE, u32Length) == 0)
1250  {
1251  /* Updates boolean */
1252  *_pbOutValue = orxTRUE;
1253 
1254  /* Has remaining? */
1255  if(_pzRemaining != orxNULL)
1256  {
1257  /* Updates it */
1258  *_pzRemaining += u32Length;
1259  }
1260 
1261  /* Updates result */
1262  eResult = orxSTATUS_SUCCESS;
1263  }
1264  }
1265  }
1266 
1267  /* Done! */
1268  return eResult;
1269 }
1270 
1275 static orxINLINE orxSTRING orxString_LowerCase(orxSTRING _zString)
1276 {
1277  orxCHAR *pc;
1278 
1279  /* Checks */
1280  orxASSERT(_zString != orxNULL);
1281 
1282  /* Converts the whole string */
1283  for(pc = _zString; *pc != orxCHAR_NULL; pc++)
1284  {
1285  /* Needs to be converted? */
1286  if(*pc >= 'A' && *pc <= 'Z')
1287  {
1288  /* Lower case */
1289  *pc |= 0x20;
1290  }
1291  }
1292 
1293  return _zString;
1294 }
1295 
1300 static orxINLINE orxSTRING orxString_UpperCase(orxSTRING _zString)
1301 {
1302  orxCHAR *pc;
1303 
1304  /* Checks */
1305  orxASSERT(_zString != orxNULL);
1306 
1307  /* Converts the whole string */
1308  for(pc = _zString; *pc != orxCHAR_NULL; pc++)
1309  {
1310  /* Needs to be converted? */
1311  if(*pc >= 'a' && *pc <= 'z')
1312  {
1313  /* Upper case */
1314  *pc &= ~0x20;
1315  }
1316  }
1317 
1318  return _zString;
1319 }
1320 
1327 static orxINLINE orxU32 orxString_NContinueCRC(const orxSTRING _zString, orxU32 _u32CRC, orxU32 _u32CharNumber)
1328 {
1329  orxU32 u32CRC, u32Length;
1330  const orxU8 *pu8;
1331 
1332 #ifdef __orxLITTLE_ENDIAN__
1333 
1334 #define orxCRC_GET_FIRST(VALUE) VALUE
1335 #define orxCRC_INDEX_0 0
1336 #define orxCRC_INDEX_1 1
1337 #define orxCRC_INDEX_2 2
1338 #define orxCRC_INDEX_3 3
1339 #define orxCRC_INDEX_4 4
1340 #define orxCRC_INDEX_5 5
1341 #define orxCRC_INDEX_6 6
1342 #define orxCRC_INDEX_7 7
1343 
1344 #else /* __orxLITTLE_ENDIAN__ */
1345 
1346 #define orxCRC_GET_FIRST(VALUE) ((VALUE >> 24) | ((VALUE >> 8) & 0x0000FF00) | ((VALUE << 8) & 0x00FF0000) | (VALUE << 24))
1347 #define orxCRC_INDEX_0 3
1348 #define orxCRC_INDEX_1 2
1349 #define orxCRC_INDEX_2 1
1350 #define orxCRC_INDEX_3 0
1351 #define orxCRC_INDEX_4 7
1352 #define orxCRC_INDEX_5 6
1353 #define orxCRC_INDEX_6 5
1354 #define orxCRC_INDEX_7 4
1355 
1356 #endif /* __orxLITTLE_ENDIAN__ */
1357 
1358  /* Checks */
1359  orxASSERT(_zString != orxNULL);
1360  orxASSERT(_u32CharNumber <= orxString_GetLength(_zString));
1361 
1362  /* Inits CRC */
1363  u32CRC = ~_u32CRC;
1364 
1365  /* For all slices */
1366  for(u32Length = _u32CharNumber, pu8 = (const orxU8 *)_zString; u32Length >= 8; u32Length -= 8, pu8 += 8)
1367  {
1368  orxU32 u32First, u32Second;
1369 
1370  /* Gets the slice's data */
1371  orxMemory_Copy(&u32First, pu8, sizeof(orxU32));
1372  orxMemory_Copy(&u32Second, pu8 + 4, sizeof(orxU32));
1373  u32First ^= orxCRC_GET_FIRST(u32CRC);
1374 
1375  /* Updates the CRC */
1376  u32CRC = saau32CRCTable[orxCRC_INDEX_7][u32First & 0xFF]
1377  ^ saau32CRCTable[orxCRC_INDEX_6][(u32First >> 8) & 0xFF]
1378  ^ saau32CRCTable[orxCRC_INDEX_5][(u32First >> 16) & 0xFF]
1379  ^ saau32CRCTable[orxCRC_INDEX_4][u32First >> 24]
1380  ^ saau32CRCTable[orxCRC_INDEX_3][u32Second & 0xFF]
1381  ^ saau32CRCTable[orxCRC_INDEX_2][(u32Second >> 8) & 0xFF]
1382  ^ saau32CRCTable[orxCRC_INDEX_1][(u32Second >> 16) & 0xFF]
1383  ^ saau32CRCTable[orxCRC_INDEX_0][u32Second >> 24];
1384  }
1385 
1386  /* For all remaining characters */
1387  for(; u32Length != 0; u32Length--, pu8++)
1388  {
1389  /* Updates the CRC */
1390  u32CRC = saau32CRCTable[0][((orxU8)(u32CRC & 0xFF)) ^ *pu8] ^ (u32CRC >> 8);
1391  }
1392 
1393 #undef orxCRC_GET_FIRST
1394 #undef orxCRC_INDEX_0
1395 #undef orxCRC_INDEX_1
1396 #undef orxCRC_INDEX_2
1397 #undef orxCRC_INDEX_3
1398 #undef orxCRC_INDEX_4
1399 #undef orxCRC_INDEX_5
1400 #undef orxCRC_INDEX_6
1401 #undef orxCRC_INDEX_7
1402 
1403  /* Done! */
1404  return ~u32CRC;
1405 }
1406 
1412 static orxINLINE orxU32 orxString_ContinueCRC(const orxSTRING _zString, orxU32 _u32CRC)
1413 {
1414  orxU32 u32CRC;
1415 
1416  /* Updates CRC */
1417  u32CRC = orxString_NContinueCRC(_zString, _u32CRC, orxString_GetLength(_zString));
1418 
1419  /* Done! */
1420  return u32CRC;
1421 }
1422 
1428 static orxINLINE orxU32 orxString_NToCRC(const orxSTRING _zString, orxU32 _u32CharNumber)
1429 {
1430  /* Checks */
1431  orxASSERT(_zString != orxNULL);
1432  orxASSERT(_u32CharNumber <= orxString_GetLength(_zString));
1433 
1434  /* Done! */
1435  return orxString_NContinueCRC(_zString, 0, _u32CharNumber);
1436 }
1437 
1442 static orxINLINE orxU32 orxString_ToCRC(const orxSTRING _zString)
1443 {
1444  /* Checks */
1445  orxASSERT(_zString != orxNULL);
1446 
1447  /* Done! */
1448  return orxString_ContinueCRC(_zString, 0);
1449 }
1450 
1456 static orxINLINE const orxSTRING orxString_SearchString(const orxSTRING _zString1, const orxSTRING _zString2)
1457 {
1458  /* Checks */
1459  orxASSERT(_zString1 != orxNULL);
1460  orxASSERT(_zString2 != orxNULL);
1461 
1462  /* Returns result */
1463  return(strstr(_zString1, _zString2));
1464 }
1465 
1471 static orxINLINE const orxSTRING orxString_SearchChar(const orxSTRING _zString, orxCHAR _cChar)
1472 {
1473  /* Checks */
1474  orxASSERT(_zString != orxNULL);
1475 
1476  /* Returns result */
1477  return(strchr(_zString, _cChar));
1478 }
1479 
1486 static orxINLINE orxS32 orxString_SearchCharIndex(const orxSTRING _zString, orxCHAR _cChar, orxU32 _u32Position)
1487 {
1488  orxS32 s32Result = -1;
1489  orxS32 s32Index;
1490  const orxCHAR *pc;
1491 
1492  /* Checks */
1493  orxASSERT(_zString != orxNULL);
1494  orxASSERT(_u32Position <= orxString_GetLength(_zString));
1495 
1496  /* For all characters */
1497  for(s32Index = _u32Position, pc = _zString + s32Index; *pc != orxCHAR_NULL; pc++, s32Index++)
1498  {
1499  /* Found? */
1500  if(*pc == _cChar)
1501  {
1502  /* Updates result */
1503  s32Result = s32Index;
1504 
1505  break;
1506  }
1507  }
1508 
1509  /* Done! */
1510  return s32Result;
1511 }
1512 
1518 static orxINLINE orxS32 orxCDECL orxString_Print(orxSTRING _zDstString, const orxSTRING _zSrcString, ...)
1519 {
1520  va_list stArgs;
1521  orxS32 s32Result;
1522 
1523  /* Checks */
1524  orxASSERT(_zDstString != orxNULL);
1525  orxASSERT(_zSrcString != orxNULL);
1526 
1527  /* Gets variable arguments & prints the string */
1528  va_start(stArgs, _zSrcString);
1529  s32Result = vsprintf(_zDstString, _zSrcString, stArgs);
1530  va_end(stArgs);
1531 
1532  /* Clamps result */
1533  s32Result = orxMAX(s32Result, 0);
1534 
1535  /* Done! */
1536  return s32Result;
1537 }
1538 
1545 static orxINLINE orxS32 orxCDECL orxString_NPrint(orxSTRING _zDstString, orxU32 _u32CharNumber, const orxSTRING _zSrcString, ...)
1546 {
1547  va_list stArgs;
1548  orxS32 s32Result;
1549 
1550  /* Checks */
1551  orxASSERT(_zDstString != orxNULL);
1552  orxASSERT(_zSrcString != orxNULL);
1553 
1554  /* Gets variable arguments & prints the string */
1555  va_start(stArgs, _zSrcString);
1556  s32Result = vsnprintf(_zDstString, (size_t)_u32CharNumber, _zSrcString, stArgs);
1557  va_end(stArgs);
1558 
1559 #ifdef __orxMSVC__
1560  /* Overflow? */
1561  if(s32Result <= 0)
1562  {
1563  /* Updates result */
1564  s32Result = _u32CharNumber;
1565  }
1566 #endif /* __orxWINDOWS__ */
1567 
1568  /* Clamps result */
1569  s32Result = orxCLAMP(s32Result, 0, (orxS32)_u32CharNumber);
1570 
1571  /* Done! */
1572  return s32Result;
1573 }
1574 
1580 static orxINLINE orxS32 orxCDECL orxString_Scan(const orxSTRING _zString, const orxSTRING _zFormat, ...)
1581 {
1582  va_list stArgs;
1583  orxS32 s32Result;
1584 
1585  /* Checks */
1586  orxASSERT(_zString != orxNULL);
1587 
1588 #ifdef __orxMSVC__
1589 
1590  /* Ugly workaround the missing vsscanf in MSVC up to version 2013 */
1591  {
1592  void *p[16];
1593  orxS32 i;
1594 
1595  /* Starts variable list */
1596  va_start(stArgs, _zFormat);
1597 
1598  /* For all potential parameters */
1599  for(i = 0; i < orxARRAY_GET_ITEM_COUNT(p); i++)
1600  {
1601  /* Gets its address */
1602  p[i] = va_arg(stArgs, void *);
1603  }
1604 
1605  /* Scans the string */
1606  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]);
1607 
1608  /* Ends variable list */
1609  va_end(stArgs);
1610  }
1611 
1612 #else /* __orxMSVC__ */
1613 
1614  /* Gets variable arguments & scans the string */
1615  va_start(stArgs, _zFormat);
1616  s32Result = vsscanf(_zString, _zFormat, stArgs);
1617  va_end(stArgs);
1618 
1619 #endif /* __orxMSVC__ */
1620 
1621  /* Clamps result */
1622  s32Result = orxMAX(s32Result, 0);
1623 
1624  /* Done! */
1625  return s32Result;
1626 }
1627 
1632 static orxINLINE const orxSTRING orxString_GetExtension(const orxSTRING _zFileName)
1633 {
1634  orxS32 s32Index, s32NextIndex;
1635  const orxSTRING zResult;
1636 
1637  /* Checks */
1638  orxASSERT(_zFileName != orxNULL);
1639 
1640  /* Finds last '.' */
1641  for(s32Index = orxString_SearchCharIndex(_zFileName, '.', 0);
1642  (s32Index >= 0) && ((s32NextIndex = orxString_SearchCharIndex(_zFileName, '.', s32Index + 1)) > 0);
1643  s32Index = s32NextIndex);
1644 
1645  /* Updates result */
1646  zResult = (s32Index >= 0) ? _zFileName + s32Index + 1 : orxSTRING_EMPTY;
1647 
1648  /* Done! */
1649  return zResult;
1650 }
1651 
1652 /* *** String module functions *** */
1653 
1656 extern orxDLLAPI void orxFASTCALL orxString_Setup();
1657 
1661 extern orxDLLAPI orxSTATUS orxFASTCALL orxString_Init();
1662 
1665 extern orxDLLAPI void orxFASTCALL orxString_Exit();
1666 
1667 
1672 extern orxDLLAPI orxU32 orxFASTCALL orxString_GetID(const orxSTRING _zString);
1673 
1678 extern orxDLLAPI const orxSTRING orxFASTCALL orxString_GetFromID(orxU32 _u32ID);
1679 
1684 extern orxDLLAPI const orxSTRING orxFASTCALL orxString_Store(const orxSTRING _zString);
1685 
1686 
1687 #ifdef __orxMSVC__
1688 
1689  #pragma warning(default : 4996)
1690 
1691 #endif /* __orxMSVC__ */
1692 
1693 #endif /* _orxSTRING_H_ */
1694 
#define orxARRAY_GET_ITEM_COUNT(ARRAY)
Definition: orxDecl.h:412
static orxINLINE const orxSTRING orxString_GetExtension(const orxSTRING _zFileName)
Definition: orxString.h:1632
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:1275
#define orxCRC_INDEX_7
static orxINLINE orxU32 orxString_ContinueCRC(const orxSTRING _zString, orxU32 _u32CRC)
Definition: orxString.h:1412
#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:1428
#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:77
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:1486
#define orxCLAMP(V, MIN, MAX)
Definition: orxMath.h:104
#define orxFALSE
Definition: orxType.h:185
static orxINLINE orxS32 orxCDECL orxString_Scan(const orxSTRING _zString, const orxSTRING _zFormat,...)
Definition: orxString.h:1580
#define orxCHAR_DIRECTORY_SEPARATOR_WINDOWS
Definition: orxType.h:228
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:792
static orxINLINE orxU32 orxString_NContinueCRC(const orxSTRING _zString, orxU32 _u32CRC, orxU32 _u32CharNumber)
Definition: orxString.h:1327
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: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:1300
#define orxMAX(A, B)
Definition: orxMath.h:96
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:1202
static orxINLINE orxS32 orxCDECL orxString_Print(orxSTRING _zDstString, const orxSTRING _zSrcString,...)
Definition: orxString.h:1518
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:1456
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:1545
static orxINLINE orxSTATUS orxString_ToS64Base(const orxSTRING _zString, orxU32 _u32Base, orxS64 *_ps64OutValue, const orxSTRING *_pzRemaining)
Definition: orxString.h:928
orxFLOAT fZ
Definition: orxVector.h:85
#define orxDLLAPI
Definition: orxDecl.h:394
#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:1471
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:1442
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 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: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:135
#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.8.11