Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1483 lines
63 KiB

  1. //====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #ifndef TIER1_STRTOOLS_H
  9. #define TIER1_STRTOOLS_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "tier0/basetypes.h"
  14. #include <stdio.h>
  15. #include "color.h"
  16. #include <ctype.h>
  17. #if POSIX
  18. #include <wchar.h>
  19. #include <math.h>
  20. #include <wctype.h>
  21. #endif
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <stdarg.h>
  25. class CUtlBuffer;
  26. #ifdef _WIN64
  27. #define str_size unsigned int
  28. #else
  29. #define str_size size_t
  30. #endif
  31. /// 3d memcpy. Copy (up-to) 3 dimensional data with arbitrary source and destination
  32. /// strides. Optimizes to just a single memcpy when possible. For 2d data, set numslices to 1.
  33. void CopyMemory3D( void *pDestAdr, void const *pSrcAdr,
  34. int nNumCols, int nNumRows, int nNumSlices, // dimensions of copy
  35. int nSrcBytesPerRow, int nSrcBytesPerSlice, // strides for source.
  36. int nDestBytesPerRow, int nDestBytesPerSlice // strides for dest
  37. );
  38. #define USE_FAST_CASE_CONVERSION 1
  39. #if USE_FAST_CASE_CONVERSION
  40. /// Faster conversion of an ascii char to upper case. This function does not obey locale or any language
  41. /// setting. It should not be used to convert characters for printing, but it is a better choice
  42. /// for internal strings such as used for hash table keys, etc. It's meant to be inlined and used
  43. /// in places like the various dictionary classes. Not obeying locale also protects you from things
  44. /// like your hash values being different depending on the locale setting.
  45. #define FastASCIIToUpper( c ) ( ( ( (c) >= 'a' ) && ( (c) <= 'z' ) ) ? ( (c) - 32 ) : (c) )
  46. /// similar to FastASCIIToLower
  47. #define FastASCIIToLower( c ) ( ( ( (c) >= 'A' ) && ( (c) <= 'Z' ) ) ? ( (c) + 32 ) : (c) )
  48. #else
  49. #define FastASCIIToLower tolower
  50. #define FastASCIIToUpper toupper
  51. #endif
  52. template< class T, class I > class CUtlMemory;
  53. template< class T, class A > class CUtlVector;
  54. extern const char *nexttoken(char *token, const char *str, char sep);
  55. #ifdef OSX
  56. size_t strnlen( const char *s, size_t n );
  57. #endif
  58. //-----------------------------------------------------------------------------
  59. // Portable versions of standard string functions
  60. //-----------------------------------------------------------------------------
  61. void _V_memset( void *dest, int fill, int count );
  62. void _V_memcpy( void *dest, const void *src, int count );
  63. void _V_memmove( void *dest, const void *src, int count );
  64. int _V_memcmp( const void *m1, const void *m2, int count );
  65. int _V_strlen( const char *str );
  66. int _V_strnlen( const char *str, int count );
  67. void _V_strcpy( char *dest, const char *src );
  68. char* _V_strrchr( const char *s, char c );
  69. int _V_strcmp( const char *s1, const char *s2 );
  70. int _V_wcscmp( const wchar_t *s1, const wchar_t *s2 );
  71. int _V_stricmp( const char *s1, const char *s2 );
  72. char* _V_strstr( const char *s1, const char *search );
  73. char* _V_strupr( char *start );
  74. char* _V_strlower( char *start );
  75. int _V_wcslen( const wchar_t *pwch );
  76. wchar_t* _V_wcslower ( wchar_t *start);
  77. wchar_t* _V_wcsupr ( wchar_t *start);
  78. // Compatibility with Source2
  79. #define V_strlower_fast _V_strlower
  80. #ifdef POSIX
  81. inline char *strupr( char *start )
  82. {
  83. char *str = start;
  84. while( str && *str )
  85. {
  86. *str = (char)toupper(*str);
  87. str++;
  88. }
  89. return start;
  90. }
  91. inline char *strlwr( char *start )
  92. {
  93. char *str = start;
  94. while( str && *str )
  95. {
  96. *str = (char)tolower(*str);
  97. str++;
  98. }
  99. return start;
  100. }
  101. inline wchar_t *_wcslwr( wchar_t *start )
  102. {
  103. wchar_t *str = start;
  104. while( str && *str )
  105. {
  106. *str = (wchar_t)towlower(static_cast<wint_t>(*str));
  107. str++;
  108. }
  109. return start;
  110. };
  111. inline wchar_t *_wcsupr( wchar_t *start )
  112. {
  113. wchar_t *str = start;
  114. while( str && *str )
  115. {
  116. *str = (wchar_t)towupper(static_cast<wint_t>(*str));
  117. str++;
  118. }
  119. return start;
  120. };
  121. #endif // POSIX
  122. // there are some users of these via tier1 templates in used in tier0. but tier0 can't depend on vstdlib which means in tier0 we always need the inlined ones
  123. #if ( !defined( TIER0_DLL_EXPORT ) )
  124. #if !defined( _DEBUG ) && defined( _PS3 )
  125. #include "tier1/strtools_inlines.h"
  126. // To avoid cross-prx calls, making the V_* fucntions that don't do anything but debug checks and call through to the non V_* function
  127. // go ahead and call the non-V_* functions directly.
  128. #define V_memset(dest, fill, count) memset ((dest), (fill), (count))
  129. #define V_memcpy(dest, src, count) memcpy ((dest), (src), (count))
  130. #define V_memmove(dest, src, count) memmove ((dest), (src), (count))
  131. #define V_memcmp(m1, m2, count) memcmp ((m1), (m2), (count))
  132. #define V_strcpy(dest, src) strcpy ((dest), (src))
  133. #define V_strcmp(s1, s2) strcmp ((s1), (s2))
  134. #define V_strupr(start) strupr ((start))
  135. #define V_strlower(start) strlwr ((start))
  136. #define V_wcslen(pwch) wcslen ((pwch))
  137. #define V_wcsupr(start) _wcsupr ((start))
  138. #define V_wcslower(start) _wcslwr ((start))
  139. // To avoid cross-prx calls, using inline versions of these custom functions:
  140. #define V_strlen(str) _V_strlen_inline ((str))
  141. #define V_strrchr(s, c) _V_strrchr_inline ((s), (c))
  142. #define V_wcscmp(s1, s2) _V_wcscmp_inline ((s1), (s2))
  143. #define V_stricmp(s1, s2 ) _V_stricmp_inline ((s1), (s2) )
  144. #define V_strstr(s1, search ) _V_strstr_inline ((s1), (search) )
  145. #else
  146. #define V_memset(dest, fill, count) _V_memset ((dest), (fill), static_cast<int>(count))
  147. #define V_memcpy(dest, src, count) _V_memcpy ((dest), (src), static_cast<int>(count))
  148. #define V_memmove(dest, src, count) _V_memmove ((dest), (src), static_cast<int>(count))
  149. #define V_memcmp(m1, m2, count) _V_memcmp ((m1), (m2), static_cast<int>(count))
  150. #define V_strlen(str) _V_strlen ((str))
  151. #define V_strnlen(str, count) _V_strnlen ((str), static_cast<int>(count))
  152. #define V_strcpy(dest, src) _V_strcpy ((dest), (src))
  153. #define V_strrchr(s, c) _V_strrchr ((s), (c))
  154. #define V_strcmp(s1, s2) _V_strcmp ((s1), (s2))
  155. #define V_wcscmp(s1, s2) _V_wcscmp ((s1), (s2))
  156. #define V_stricmp(s1, s2 ) _V_stricmp ((s1), (s2) )
  157. #define V_stricmp_fast(s1, s2 ) _V_stricmp ((s1), (s2) )
  158. #define V_strstr(s1, search ) _V_strstr ((s1), (search) )
  159. #define V_strupr(start) _V_strupr ((start))
  160. #define V_strupper(start) _V_strupr ((start))
  161. #define V_strlower(start) _V_strlower ((start))
  162. #define V_wcslen(pwch) _V_wcslen ((pwch))
  163. #define V_wcsupr(start) _V_wcsupr ((start))
  164. #define V_wcslower(start) _V_wcslower ((start))
  165. #endif
  166. #else
  167. inline void V_memset(void *dest, int fill, int count) { memset( dest, fill, count ); }
  168. inline void V_memcpy(void *dest, const void *src, int count) { memcpy( dest, src, count ); }
  169. inline void V_memmove(void *dest, const void *src, int count) { memmove( dest, src, count ); }
  170. inline int V_memcmp(const void *m1, const void *m2, int count) { return memcmp( m1, m2, count ); }
  171. inline int V_strlen(const char *str) { return (int) strlen ( str ); }
  172. inline int V_strnlen(const char *str, int count ) { return (int) strnlen ( str, count ); }
  173. inline void V_strcpy(char *dest, const char *src) { strcpy( dest, src ); }
  174. inline int V_wcslen(const wchar_t *pwch) { return (int)wcslen(pwch); }
  175. inline char* V_strrchr(const char *s, char c) { return (char*)strrchr( s, c ); }
  176. inline int V_strcmp(const char *s1, const char *s2) { return strcmp( s1, s2 ); }
  177. inline int V_wcscmp(const wchar_t *s1, const wchar_t *s2) { return wcscmp( s1, s2 ); }
  178. inline int V_stricmp( const char *s1, const char *s2 ) { return stricmp( s1, s2 ); }
  179. inline char* V_strstr( const char *s1, const char *search ) { return (char*)strstr( s1, search ); }
  180. #ifndef COMPILER_PS3
  181. inline char* V_strupr(char *start) { return strupr( start ); }
  182. inline char* V_strlower(char *start) { return strlwr( start ); }
  183. inline wchar_t* V_wcsupr (wchar_t *start) { return _wcsupr( start ); }
  184. inline wchar_t* V_wcslower(wchar_t *start) { return _wcslwr( start ); }
  185. #endif
  186. #endif
  187. int V_strncmp (const char *s1, const char *s2, int count);
  188. int V_strcasecmp (const char *s1, const char *s2);
  189. int V_strncasecmp (const char *s1, const char *s2, int n);
  190. int V_strnicmp (const char *s1, const char *s2, int n);
  191. int V_atoi (const char *str);
  192. int64 V_atoi64(const char *str);
  193. uint64 V_atoui64(const char *str);
  194. int64 V_strtoi64( const char *nptr, char **endptr, int base );
  195. uint64 V_strtoui64( const char *nptr, char **endptr, int base );
  196. float V_atof(const char *str);
  197. double V_atod(const char *str);
  198. char* V_stristr( char* pStr, const char* pSearch );
  199. const char* V_stristr( const char* pStr, const char* pSearch );
  200. const char* V_strnistr( const char* pStr, const char* pSearch, int n );
  201. const char* V_strnchr( const char* pStr, char c, int n );
  202. wchar_t* V_wcsistr( wchar_t* pStr, const wchar_t* pSearch );
  203. const wchar_t* V_wcsistr( const wchar_t* pStr, const wchar_t* pSearch );
  204. void V_qsort_s( void *base, size_t num, size_t width, int ( __cdecl *compare )(void *, const void *, const void *), void *context );
  205. #define V_strncmp_fast V_strncmp
  206. #define V_strnicmp_fast V_strnicmp
  207. #define V_stristr_fast V_stristr
  208. #define V_strupper_fast V_strupper
  209. // returns string immediately following prefix, (ie str+strlen(prefix)) or NULL if prefix not found
  210. const char *StringAfterPrefix ( const char *str, const char *prefix );
  211. const char *StringAfterPrefixCaseSensitive( const char *str, const char *prefix );
  212. inline bool StringHasPrefix ( const char *str, const char *prefix ) { return StringAfterPrefix ( str, prefix ) != NULL; }
  213. inline bool StringHasPrefixCaseSensitive( const char *str, const char *prefix ) { return StringAfterPrefixCaseSensitive( str, prefix ) != NULL; }
  214. template< bool CASE_SENSITIVE > inline bool _V_strEndsWithInner( const char *pStr, const char *pSuffix )
  215. {
  216. int nSuffixLen = V_strlen( pSuffix );
  217. int nStringLen = V_strlen( pStr );
  218. if ( nSuffixLen == 0 )
  219. return true; // All strings end with the empty string (matches Java & .NET behaviour)
  220. if ( nStringLen < nSuffixLen )
  221. return false;
  222. pStr += nStringLen - nSuffixLen;
  223. if ( CASE_SENSITIVE )
  224. return !V_strcmp( pStr, pSuffix );
  225. else
  226. return !V_stricmp( pStr, pSuffix );
  227. }
  228. // Does 'pStr' end with 'pSuffix'? (case sensitive/insensitive variants)
  229. inline bool V_strEndsWith( const char *pStr, const char *pSuffix ) { return _V_strEndsWithInner<TRUE>( pStr, pSuffix ); }
  230. inline bool V_striEndsWith( const char *pStr, const char *pSuffix ) { return _V_strEndsWithInner<FALSE>( pStr, pSuffix ); }
  231. #define StringIsEmpty( pchString ) ( pchString[ 0 ] == '\0' )
  232. // Normalizes a float string in place.
  233. // (removes leading zeros, trailing zeros after the decimal point, and the decimal point itself where possible)
  234. void V_normalizeFloatString( char* pFloat );
  235. // this is locale-unaware and therefore faster version of standard isdigit()
  236. // It also avoids sign-extension errors.
  237. inline bool V_isdigit( char c )
  238. {
  239. return c >= '0' && c <= '9';
  240. }
  241. inline bool V_iswdigit( int c )
  242. {
  243. return ( ( (uint)( c - '0' ) ) < 10 );
  244. }
  245. inline bool V_isempty( const char* pszString ) { return !pszString || !pszString[ 0 ]; }
  246. // The islower/isdigit/etc. functions all expect a parameter that is either
  247. // 0-0xFF or EOF. It is easy to violate this constraint simply by passing
  248. // 'char' to these functions instead of unsigned char.
  249. // The V_ functions handle the char/unsigned char mismatch by taking a
  250. // char parameter and casting it to unsigned char so that chars with the
  251. // sign bit set will be zero extended instead of sign extended.
  252. // Not that EOF cannot be passed to these functions.
  253. //
  254. // These functions could also be used for optimizations if locale
  255. // considerations make some of the CRT functions slow.
  256. #undef isdigit // In case this is implemented as a macro
  257. #define isdigit use_V_isdigit_instead_of_isdigit
  258. inline bool V_isalpha(char c) { return isalpha( (unsigned char)c ) != 0; }
  259. #undef isalpha
  260. #define isalpha use_V_isalpha_instead_of_isalpha
  261. inline bool V_isalnum(char c) { return isalnum( (unsigned char)c ) != 0; }
  262. #undef isalnum
  263. #define isalnum use_V_isalnum_instead_of_isalnum
  264. inline bool V_isprint(char c) { return isprint( (unsigned char)c ) != 0; }
  265. #undef isprint
  266. #define isprint use_V_isprint_instead_of_isprint
  267. inline bool V_isxdigit(char c) { return isxdigit( (unsigned char)c ) != 0; }
  268. #undef isxdigit
  269. #define isxdigit use_V_isxdigit_instead_of_isxdigit
  270. inline bool V_ispunct(char c) { return ispunct( (unsigned char)c ) != 0; }
  271. #undef ispunct
  272. #define ispunct use_V_ispunct_instead_of_ispunct
  273. inline bool V_isgraph(char c) { return isgraph( (unsigned char)c ) != 0; }
  274. #undef isgraph
  275. #define isgraph use_V_isgraph_instead_of_isgraph
  276. inline bool V_isupper(char c) { return isupper( (unsigned char)c ) != 0; }
  277. #undef isupper
  278. #define isupper use_V_isupper_instead_of_isupper
  279. inline bool V_islower(char c) { return islower( (unsigned char)c ) != 0; }
  280. #undef islower
  281. #define islower use_V_islower_instead_of_islower
  282. inline bool V_iscntrl(char c) { return iscntrl( (unsigned char)c ) != 0; }
  283. #undef iscntrl
  284. #define iscntrl use_V_iscntrl_instead_of_iscntrl
  285. inline bool V_isspace(int c)
  286. {
  287. // The standard white-space characters are the following: space, tab, carriage-return, newline, vertical tab, and form-feed. In the C locale, V_isspace() returns true only for the standard white-space characters.
  288. //return c == ' ' || c == 9 /*horizontal tab*/ || c == '\r' || c == '\n' || c == 11 /*vertical tab*/ || c == '\f';
  289. // codes of whitespace symbols: 9 HT, 10 \n, 11 VT, 12 form feed, 13 \r, 32 space
  290. // easy to understand version, validated:
  291. // return ((1 << (c-1)) & 0x80001F00) != 0 && ((c-1)&0xE0) == 0;
  292. // 5% faster on Core i7, 35% faster on Xbox360, no branches, validated:
  293. #ifdef _X360
  294. return ((1 << (c-1)) & 0x80001F00 & ~(-int((c-1)&0xE0))) != 0;
  295. #else
  296. // this is 11% faster on Core i7 than the previous, VC2005 compiler generates a seemingly unbalanced search tree that's faster
  297. switch(c)
  298. {
  299. case ' ':
  300. case 9:
  301. case '\r':
  302. case '\n':
  303. case 11:
  304. case '\f':
  305. return true;
  306. default:
  307. return false;
  308. }
  309. #endif
  310. }
  311. #undef isspace
  312. #define isspace use_V_isspace_instead_of_isspace
  313. // Returns true if V_isspace returns true for any character in the string
  314. inline bool V_containsWhitespace( const char *pStr )
  315. {
  316. if ( pStr )
  317. {
  318. while( *pStr )
  319. {
  320. if ( V_isspace( *pStr++ ) )
  321. return true;
  322. }
  323. }
  324. return false;
  325. }
  326. //-----------------------------------------------------------------------------
  327. // Purpose: returns true if it's a valid hex string
  328. //-----------------------------------------------------------------------------
  329. inline bool V_isvalidhex( char const *in, int inputchars )
  330. {
  331. if ( inputchars < 2 )
  332. return false;
  333. if ( inputchars % 2 == 1 )
  334. return false;
  335. for ( int i = 0; i < inputchars; i++ )
  336. {
  337. char c = in[i];
  338. if ( !(
  339. (c >= '0' && c <= '9') ||
  340. (c >= 'a' && c <= 'f') ||
  341. (c >= 'A' && c <= 'F')
  342. ) )
  343. {
  344. return false;
  345. }
  346. }
  347. return true;
  348. }
  349. //-----------------------------------------------------------------------------
  350. // Purpose: Checks if the string is lower case
  351. // NOTE: Only works with ASCII strings
  352. //-----------------------------------------------------------------------------
  353. inline bool V_isstrlower( const char *pch )
  354. {
  355. const char *pCurrent = pch;
  356. while ( *pCurrent != '\0' )
  357. {
  358. if ( *pCurrent >= 'A' && *pCurrent <= 'Z' )
  359. return false;
  360. pCurrent++;
  361. }
  362. return true;
  363. }
  364. // These are versions of functions that guarantee NULL termination.
  365. //
  366. // maxLen is the maximum number of bytes in the destination string.
  367. // pDest[maxLen-1] is always NULL terminated if pSrc's length is >= maxLen.
  368. //
  369. // This means the last parameter can usually be a sizeof() of a string.
  370. void V_strncpy( char *pDest, const char *pSrc, int maxLenInChars );
  371. // Ultimate safe strcpy function, for arrays only -- buffer size is inferred by the compiler
  372. template <size_t maxLenInChars> void V_strcpy_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], const char *pSrc )
  373. {
  374. V_strncpy( pDest, pSrc, static_cast<int>(maxLenInChars) );
  375. }
  376. // A function which duplicates a string using new[] to allocate the new string.
  377. inline char *V_strdup( const char *pSrc )
  378. {
  379. int nLen = V_strlen( pSrc );
  380. char *pResult = new char [ nLen+1 ];
  381. V_memcpy( pResult, pSrc, nLen+1 );
  382. return pResult;
  383. }
  384. // Returns the number of characters printed (not including the NULL), or maxLenInChars if truncation occurs.
  385. // pDest is always null-terminated.
  386. int V_snprintf( OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars, PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 3, 4 );
  387. int V_vsnprintf( OUT_Z_CAP(maxLenInCharacters) char *pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const char *pFormat, va_list params );
  388. // gcc insists on only having format annotations on declarations, not definitions, which is why I have both.
  389. template <size_t maxLenInChars> int V_sprintf_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 2, 3 );
  390. template <size_t maxLenInChars> int V_sprintf_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], const char *pFormat, ... )
  391. {
  392. va_list params;
  393. va_start( params, pFormat );
  394. int result = V_vsnprintf( pDest, maxLenInChars, pFormat, params );
  395. va_end( params );
  396. return result;
  397. }
  398. // gcc insists on only having format annotations on declarations, not definitions, which is why I have both.
  399. // Append formatted text to an array in a safe manner -- always null-terminated, truncation rather than buffer overrun.
  400. template <size_t maxLenInChars> int V_sprintfcat_safe( INOUT_Z_ARRAY char (&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 2, 3 );
  401. template <size_t maxLenInChars> int V_sprintfcat_safe( INOUT_Z_ARRAY char (&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char *pFormat, ... )
  402. {
  403. va_list params;
  404. va_start( params, pFormat );
  405. size_t usedLength = V_strlen(pDest);
  406. // This code is here to check against buffer overruns when uninitialized arrays are passed in.
  407. // It should never be executed. Unfortunately we can't assert in this header file.
  408. if ( usedLength >= maxLenInChars )
  409. usedLength = 0;
  410. int result = V_vsnprintf( pDest + usedLength, maxLenInChars - usedLength, pFormat, params );
  411. va_end( params );
  412. return result;
  413. }
  414. void V_wcsncpy( OUT_Z_BYTECAP(maxLenInBytes) wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes );
  415. template <size_t maxLenInChars> void V_wcscpy_safe( OUT_Z_ARRAY wchar_t (&pDest)[maxLenInChars], wchar_t const *pSrc )
  416. {
  417. V_wcsncpy( pDest, pSrc, maxLenInChars * sizeof(*pDest) );
  418. }
  419. #define COPY_ALL_CHARACTERS -1
  420. char *V_strncat( INOUT_Z_CAP(maxLenInBytes) char *, const char *, size_t maxLenInBytes, int nMaxCharsToCopy=COPY_ALL_CHARACTERS );
  421. template <size_t cchDest> char *V_strcat_safe( INOUT_Z_ARRAY char (&pDest)[cchDest], const char *pSrc, int nMaxCharsToCopy=COPY_ALL_CHARACTERS )
  422. {
  423. return V_strncat( pDest, pSrc, static_cast<int>(cchDest), nMaxCharsToCopy );
  424. }
  425. wchar_t *V_wcsncat( INOUT_Z_BYTECAP(maxLenInBytes) wchar_t *, const wchar_t *, int maxLenInBytes, int nMaxCharsToCopy=COPY_ALL_CHARACTERS );
  426. template <size_t cchDest> wchar_t *V_wcscat_safe( INOUT_Z_ARRAY wchar_t (&pDest)[cchDest], const wchar_t *pSrc, int nMaxCharsToCopy=COPY_ALL_CHARACTERS )
  427. {
  428. return V_wcsncat( pDest, pSrc, static_cast<int>(cchDest), nMaxCharsToCopy );
  429. }
  430. char *V_strnlwr(char *, size_t);
  431. // Unicode string conversion policies - what to do if an illegal sequence is encountered
  432. enum EStringConvertErrorPolicy
  433. {
  434. _STRINGCONVERTFLAG_SKIP = 1,
  435. _STRINGCONVERTFLAG_FAIL = 2,
  436. _STRINGCONVERTFLAG_ASSERT = 4,
  437. STRINGCONVERT_REPLACE = 0,
  438. STRINGCONVERT_SKIP = _STRINGCONVERTFLAG_SKIP,
  439. STRINGCONVERT_FAIL = _STRINGCONVERTFLAG_FAIL,
  440. STRINGCONVERT_ASSERT_REPLACE = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_REPLACE,
  441. STRINGCONVERT_ASSERT_SKIP = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_SKIP,
  442. STRINGCONVERT_ASSERT_FAIL = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_FAIL,
  443. };
  444. // Unicode (UTF-8, UTF-16, UTF-32) fundamental conversion functions.
  445. bool Q_IsValidUChar32( uchar32 uValue );
  446. int Q_UChar32ToUTF8Len( uchar32 uValue );
  447. int Q_UChar32ToUTF8( uchar32 uValue, char *pOut );
  448. int Q_UChar32ToUTF16Len( uchar32 uValue );
  449. int Q_UChar32ToUTF16( uchar32 uValue, uchar16 *pOut );
  450. // Validate that a Unicode string is well-formed and contains only valid code points
  451. bool Q_UnicodeValidate( const char *pUTF8 );
  452. bool Q_UnicodeValidate( const uchar16 *pUTF16 );
  453. bool Q_UnicodeValidate( const uchar32 *pUTF32 );
  454. #define V_UnicodeValidate Q_UnicodeValidate
  455. // Returns length of string in Unicode code points (printed glyphs or non-printing characters)
  456. int Q_UnicodeLength( const char *pUTF8 );
  457. int Q_UnicodeLength( const uchar16 *pUTF16 );
  458. int Q_UnicodeLength( const uchar32 *pUTF32 );
  459. #define V_UnicodeLength Q_UnicodeLength
  460. // Returns length of string in elements, not characters! These are analogous to Q_strlen and Q_wcslen
  461. inline int Q_strlen16( const uchar16 *puc16 ) { int nElems = 0; while ( puc16[nElems] ) ++nElems; return nElems; }
  462. inline int Q_strlen32( const uchar32 *puc32 ) { int nElems = 0; while ( puc32[nElems] ) ++nElems; return nElems; }
  463. // Repair invalid Unicode strings by dropping truncated characters and fixing improperly-double-encoded UTF-16 sequences.
  464. // Unlike conversion functions which replace with '?' by default, a repair operation assumes that you know that something
  465. // is wrong with the string (eg, mid-sequence truncation) and you just want to do the best possible job of cleaning it up.
  466. // You can pass a REPLACE or FAIL policy if you would prefer to replace characters with '?' or clear the entire string.
  467. // Returns nonzero on success, or 0 if the policy is FAIL and an invalid sequence was found.
  468. int Q_UnicodeRepair( char *pUTF8, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_SKIP );
  469. int Q_UnicodeRepair( uchar16 *pUTF16, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_SKIP );
  470. int Q_UnicodeRepair( uchar32 *pUTF32, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_SKIP );
  471. // Advance pointer forward by N Unicode code points (printed glyphs or non-printing characters), stopping at terminating null if encountered.
  472. char *Q_UnicodeAdvance( char *pUTF8, int nCharacters );
  473. uchar16 *Q_UnicodeAdvance( uchar16 *pUTF16, int nCharactersnCharacters );
  474. uchar32 *Q_UnicodeAdvance( uchar32 *pUTF32, int nChars );
  475. inline const char *Q_UnicodeAdvance( const char *pUTF8, int nCharacters ) { return Q_UnicodeAdvance( (char*) pUTF8, nCharacters ); }
  476. inline const uchar16 *Q_UnicodeAdvance( const uchar16 *pUTF16, int nCharacters ) { return Q_UnicodeAdvance( (uchar16*) pUTF16, nCharacters ); }
  477. inline const uchar32 *Q_UnicodeAdvance( const uchar32 *pUTF32, int nCharacters ) { return Q_UnicodeAdvance( (uchar32*) pUTF32, nCharacters ); }
  478. #define V_UnicodeAdvance Q_UnicodeAdvance
  479. // Truncate to maximum of N Unicode code points (printed glyphs or non-printing characters)
  480. inline void Q_UnicodeTruncate( char *pUTF8, int nCharacters ) { *Q_UnicodeAdvance( pUTF8, nCharacters ) = 0; }
  481. inline void Q_UnicodeTruncate( uchar16 *pUTF16, int nCharacters ) { *Q_UnicodeAdvance( pUTF16, nCharacters ) = 0; }
  482. inline void Q_UnicodeTruncate( uchar32 *pUTF32, int nCharacters ) { *Q_UnicodeAdvance( pUTF32, nCharacters ) = 0; }
  483. #define V_UnicodeTruncate Q_UnicodeTruncate
  484. // Conversion between Unicode string types (UTF-8, UTF-16, UTF-32). Deals with bytes, not element counts,
  485. // to minimize harm from the programmer mistakes which continue to plague our wide-character string code.
  486. // Returns the number of bytes written to the output, or if output is NULL, the number of bytes required.
  487. int Q_UTF8ToUTF16( const char *pUTF8, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  488. int Q_UTF8ToUTF32( const char *pUTF8, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  489. int Q_UTF16ToUTF8( const uchar16 *pUTF16, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  490. int Q_UTF16ToUTF32( const uchar16 *pUTF16, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  491. int Q_UTF32ToUTF8( const uchar32 *pUTF32, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  492. int Q_UTF32ToUTF16( const uchar32 *pUTF32, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  493. // This is disgusting and exist only easily to facilitate having 16-bit and 32-bit wchar_t's on different platforms
  494. int Q_UTF32ToUTF32( const uchar32 *pUTF32Source, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32Dest, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  495. // Conversion between count-limited UTF-n character arrays, including any potential NULL characters.
  496. // Output has a terminating NULL for safety; strip the last character if you want an unterminated string.
  497. // Returns the number of bytes written to the output, or if output is NULL, the number of bytes required.
  498. int Q_UTF8CharsToUTF16( const char *pUTF8, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  499. #define V_UTF8CharsToUTF16 Q_UTF8CharsToUTF16
  500. int Q_UTF8CharsToUTF32( const char *pUTF8, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  501. int Q_UTF16CharsToUTF8( const uchar16 *pUTF16, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  502. int Q_UTF16CharsToUTF32( const uchar16 *pUTF16, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar32 *pUTF32, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  503. int Q_UTF32CharsToUTF8( const uchar32 *pUTF32, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  504. int Q_UTF32CharsToUTF16( const uchar32 *pUTF32, int nElements, OUT_Z_BYTECAP(cubDestSizeInBytes) uchar16 *pUTF16, int cubDestSizeInBytes, EStringConvertErrorPolicy ePolicy = STRINGCONVERT_ASSERT_REPLACE );
  505. // Decode a single UTF-8 character to a uchar32, returns number of UTF-8 bytes parsed
  506. int Q_UTF8ToUChar32( const char *pUTF8_, uchar32 &uValueOut, bool &bErrorOut );
  507. #define V_UTF8ToUChar32 Q_UTF8ToUChar32
  508. // Decode a single UTF-16 character to a uchar32, returns number of UTF-16 characters (NOT BYTES) consumed
  509. int Q_UTF16ToUChar32( const uchar16 *pUTF16, uchar32 &uValueOut, bool &bErrorOut );
  510. // NOTE: WString means either UTF32 or UTF16 depending on the platform and compiler settings.
  511. #if defined( _MSC_VER ) || defined( _WIN32 )
  512. #define Q_UTF8ToWString Q_UTF8ToUTF16
  513. #define Q_UTF8CharsToWString Q_UTF8CharsToUTF16
  514. #define Q_UTF32ToWString Q_UTF32ToUTF16
  515. #define Q_WStringToUTF8 Q_UTF16ToUTF8
  516. #define Q_WStringCharsToUTF8 Q_UTF16CharsToUTF8
  517. #define Q_WStringToUTF32 Q_UTF16ToUTF32
  518. #else
  519. #define Q_UTF8ToWString Q_UTF8ToUTF32
  520. #define Q_UTF8CharsToWString Q_UTF8CharsToUTF32
  521. #define Q_UTF32ToWString Q_UTF32ToUTF32
  522. #define Q_WStringToUTF8 Q_UTF32ToUTF8
  523. #define Q_WStringCharsToUTF8 Q_UTF32CharsToUTF8
  524. #define Q_WStringToUTF32 Q_UTF32ToUTF32
  525. #endif
  526. // UNDONE: Find a non-compiler-specific way to do this
  527. #ifdef _WIN32
  528. #ifndef _VA_LIST_DEFINED
  529. #ifdef _M_ALPHA
  530. struct va_list
  531. {
  532. char *a0; /* pointer to first homed integer argument */
  533. int offset; /* byte offset of next parameter */
  534. };
  535. #else // !_M_ALPHA
  536. typedef char * va_list;
  537. #endif // !_M_ALPHA
  538. #define _VA_LIST_DEFINED
  539. #endif // _VA_LIST_DEFINED
  540. #elif POSIX
  541. #include <stdarg.h>
  542. #endif
  543. #ifdef _WIN32
  544. #define CORRECT_PATH_SEPARATOR '\\'
  545. #define CORRECT_PATH_SEPARATOR_S "\\"
  546. #define INCORRECT_PATH_SEPARATOR '/'
  547. #define INCORRECT_PATH_SEPARATOR_S "/"
  548. #define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES ":/\\"
  549. #define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
  550. #elif POSIX || defined( _PS3 )
  551. #define CORRECT_PATH_SEPARATOR '/'
  552. #define CORRECT_PATH_SEPARATOR_S "/"
  553. #define INCORRECT_PATH_SEPARATOR '\\'
  554. #define INCORRECT_PATH_SEPARATOR_S "\\"
  555. #define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES "/"
  556. #define PATHSEPARATOR(c) ((c) == '/')
  557. #endif
  558. int V_vsnprintf( OUT_Z_CAP(maxLenInCharacters) char *pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const char *pFormat, va_list params );
  559. template <size_t maxLenInCharacters> int V_vsprintf_safe( OUT_Z_ARRAY char (&pDest)[maxLenInCharacters], PRINTF_FORMAT_STRING const char *pFormat, va_list params ) { return V_vsnprintf( pDest, maxLenInCharacters, pFormat, params ); }
  560. int V_vsnwprintf( OUT_Z_CAP(maxLenInCharacters) wchar_t *pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const wchar_t *pFormat, va_list params );
  561. template <size_t maxLenInCharacters> int V_vswprintf_safe( OUT_Z_ARRAY wchar_t (&pDest)[maxLenInCharacters], PRINTF_FORMAT_STRING const wchar_t *pFormat, va_list params ) { return V_vsnwprintf( pDest, maxLenInCharacters, pFormat, params ); }
  562. int V_vsnprintfRet( OUT_Z_CAP(maxLenInCharacters) char *pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const char *pFormat, va_list params, bool *pbTruncated );
  563. template <size_t maxLenInCharacters> int V_vsprintfRet_safe( OUT_Z_ARRAY char (&pDest)[maxLenInCharacters], PRINTF_FORMAT_STRING const char *pFormat, va_list params, bool *pbTruncated ) { return V_vsnprintfRet( pDest, maxLenInCharacters, pFormat, params, pbTruncated ); }
  564. // FMTFUNCTION can only be used on ASCII functions, not wide-char functions.
  565. int V_snwprintf( OUT_Z_CAP(maxLenInCharacters) wchar_t *pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const wchar_t *pFormat, ... );
  566. template <size_t maxLenInChars> int V_swprintf_safe( OUT_Z_ARRAY wchar_t (&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const wchar_t *pFormat, ... )
  567. {
  568. va_list params;
  569. va_start( params, pFormat );
  570. int result = V_vsnwprintf( pDest, maxLenInChars, pFormat, params );
  571. va_end( params );
  572. return result;
  573. }
  574. int V_vsnprintfRet( OUT_Z_CAP(maxLen) char *pDest, int maxLen, PRINTF_FORMAT_STRING const char *pFormat, va_list params, bool *pbTruncated );
  575. // Prints out a pretified memory counter string value ( e.g., 7,233.27 Mb, 1,298.003 Kb, 127 bytes )
  576. char *V_pretifymem( float value, int digitsafterdecimal = 2, bool usebinaryonek = false );
  577. // Prints out a pretified integer with comma separators (eg, 7,233,270,000)
  578. char *V_pretifynum( int64 value );
  579. // Prints out a memory dump where stuff that's ascii is human readable, etc.
  580. class CUtlString;
  581. void V_LogMultiline( bool input, char const *label, const char *data, size_t len, CUtlString &output );
  582. // conversion functions wchar_t <-> char, returning the number of characters converted
  583. int _V_UTF8ToUnicode( const char *pUTF8, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t *pwchDest, int cubDestSizeInBytes );
  584. template< typename T > inline int V_UTF8ToUnicode( const char *pUTF8, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t *pwchDest, T cubDestSizeInBytes )
  585. {
  586. return _V_UTF8ToUnicode( pUTF8, pwchDest, static_cast<int>(cubDestSizeInBytes) );
  587. }
  588. int _V_UnicodeToUTF8( const wchar_t *pUnicode, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes );
  589. template< typename T > inline int V_UnicodeToUTF8( const wchar_t *pUnicode, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, T cubDestSizeInBytes )
  590. {
  591. return _V_UnicodeToUTF8( pUnicode, pUTF8, static_cast<int>(cubDestSizeInBytes) );
  592. }
  593. int _V_UCS2ToUnicode( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t *pUnicode, int cubDestSizeInBytes );
  594. template< typename T > inline int V_UCS2ToUnicode( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t *pUnicode, T cubDestSizeInBytes )
  595. {
  596. return _V_UCS2ToUnicode( pUCS2, pUnicode, static_cast<int>(cubDestSizeInBytes) );
  597. }
  598. int _V_UCS2ToUTF8( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, int cubDestSizeInBytes );
  599. template< typename T > inline int V_UCS2ToUTF8( const ucs2 *pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUTF8, T cubDestSizeInBytes )
  600. {
  601. return _V_UCS2ToUTF8( pUCS2, pUTF8, static_cast<int>(cubDestSizeInBytes) );
  602. }
  603. int _V_UnicodeToUCS2( const wchar_t *pUnicode, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUCS2, int cubDestSizeInBytes );
  604. template< typename T, typename U > inline int V_UnicodeToUCS2( const wchar_t *pUnicode, T cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) char *pUCS2, U cubDestSizeInBytes )
  605. {
  606. return _V_UnicodeToUCS2( pUnicode, static_cast<int>(cubSrcInBytes), pUCS2, static_cast<int>(cubDestSizeInBytes) );
  607. }
  608. int _V_UTF8ToUCS2( const char *pUTF8, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) ucs2 *pUCS2, int cubDestSizeInBytes );
  609. template< typename T, typename U > inline int V_UTF8ToUCS2( const char *pUTF8, T cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) ucs2 *pUCS2, U cubDestSizeInBytes )
  610. {
  611. return _V_UTF8ToUCS2( pUTF8, static_cast<int>(cubSrcInBytes), pUCS2, static_cast<int>(cubDestSizeInBytes) );
  612. }
  613. // Functions for converting hexidecimal character strings back into binary data etc.
  614. //
  615. // e.g.,
  616. // int output;
  617. // V_hextobinary( "ffffffff", 8, &output, sizeof( output ) );
  618. // would make output == 0xfffffff or -1
  619. // Similarly,
  620. // char buffer[ 9 ];
  621. // V_binarytohex( &output, sizeof( output ), buffer, sizeof( buffer ) );
  622. // would put "ffffffff" into buffer (note null terminator!!!)
  623. void V_hextobinary( char const *in, int numchars, OUT_Z_CAP(maxoutputbytes) byte *out, int maxoutputbytes );
  624. void V_binarytohex( const byte *in, int inputbytes, char *out, int outsize );
  625. // Tools for working with filenames
  626. // Extracts the base name of a file (no path, no extension, assumes '/' or '\' as path separator)
  627. void V_FileBase( const char *in, OUT_Z_CAP(maxlen) char *out,int maxlen );
  628. // Remove the final characters of ppath if it's '\' or '/'.
  629. void V_StripTrailingSlash( char *ppath );
  630. // Remove the final characters of ppline if they are whitespace (uses V_isspace)
  631. void V_StripTrailingWhitespace( char *ppline );
  632. // Remove the initial characters of ppline if they are whitespace (uses V_isspace)
  633. void V_StripLeadingWhitespace( char *ppline );
  634. // Remove the initial/final characters of ppline if they are " quotes
  635. void V_StripSurroundingQuotes( char *ppline );
  636. // Remove any extension from in and return resulting string in out
  637. void V_StripExtension( const char *in, char *out, int outLen );
  638. // Make path end with extension if it doesn't already have an extension
  639. void V_DefaultExtension( char *path, const char *extension, int pathStringLength );
  640. // Strips any current extension from path and ensures that extension is the new extension.
  641. // NOTE: extension string MUST include the . character
  642. void V_SetExtension( char *path, const char *extension, int pathStringLength );
  643. // Removes any filename from path ( strips back to previous / or \ character )
  644. void V_StripFilename( char *path );
  645. // Remove the final directory from the path
  646. bool V_StripLastDir( char *dirName, int maxlen );
  647. // Returns a pointer to the unqualified file name (no path) of a file name
  648. const char * V_UnqualifiedFileName( const char * in );
  649. // Given a path and a filename, composes "path\filename", inserting the (OS correct) separator if necessary
  650. void V_ComposeFileName( const char *path, const char *filename, char *dest, int destSize );
  651. // Copy out the path except for the stuff after the final pathseparator
  652. bool V_ExtractFilePath( const char *path, char *dest, int destSize );
  653. // Copy out the file extension into dest
  654. void V_ExtractFileExtension( const char *path, char *dest, int destSize );
  655. // Returns a pointer to the file extension or NULL if one doesn't exist
  656. const char *V_GetFileExtension( const char *path );
  657. // (everything after the last path seperator)
  658. const char *V_GetFileExtensionSafe( const char *path );
  659. // Dear branch integrator: V_GetFileName was removed! It was identical to V_UnqualifiedFileName.
  660. inline const char *V_GetFileName( const char * path ) { return V_UnqualifiedFileName( path ); }
  661. // This removes "./" and "../" from the pathname. pFilename should be a full pathname.
  662. // Returns false if it tries to ".." past the root directory in the drive (in which case
  663. // it is an invalid path).
  664. bool V_RemoveDotSlashes( char *pFilename, char separator = CORRECT_PATH_SEPARATOR );
  665. // If pPath is a relative path, this function makes it into an absolute path
  666. // using the current working directory as the base, or pStartingDir if it's non-NULL.
  667. // Returns false if it runs out of room in the string, or if pPath tries to ".." past the root directory.
  668. #if defined(_MSC_VER) && _MSC_VER >= 1900
  669. bool
  670. #else
  671. void
  672. #endif
  673. V_MakeAbsolutePath( char *pOut, int outLen, const char *pPath, const char *pStartingDir = NULL );
  674. inline void V_MakeAbsolutePath( char *pOut, int outLen, const char *pPath, const char *pStartingDir, bool bLowercaseName )
  675. {
  676. V_MakeAbsolutePath( pOut, outLen, pPath, pStartingDir );
  677. if ( bLowercaseName )
  678. {
  679. V_strlower( pOut );
  680. }
  681. }
  682. // Creates a relative path given two full paths
  683. // The first is the full path of the file to make a relative path for.
  684. // The second is the full path of the directory to make the first file relative to
  685. // Returns false if they can't be made relative (on separate drives, for example)
  686. bool V_MakeRelativePath( const char *pFullPath, const char *pDirectory, char *pRelativePath, int nBufLen );
  687. // Fixes up a file name, replacing ' ' with '_'
  688. void V_FixupPathSpaceToUnderscore( char *pPath );
  689. // Fixes up a file name, removing dot slashes, fixing slashes, converting to lowercase, etc.
  690. void V_FixupPathName( OUT_Z_CAP(nOutLen) char *pOut, int nOutLen, IN_Z const char *pPath );
  691. // Adds a path separator to the end of the string if there isn't one already and the string is not empty.
  692. // Triggers a fatal error if it would run out of space.
  693. void V_AppendSlash( INOUT_Z_CAP(strSize) char *pStr, int strSize, char separator = CORRECT_PATH_SEPARATOR );
  694. // Returns true if the path is an absolute path.
  695. bool V_IsAbsolutePath( IN_Z const char *pPath );
  696. // Scans pIn and replaces all occurences of pMatch with pReplaceWith.
  697. // Writes the result to pOut.
  698. // Returns true if it completed successfully.
  699. // If it would overflow pOut, it fills as much as it can and returns false.
  700. bool V_StrSubst( IN_Z const char *pIn, IN_Z const char *pMatch, IN_Z const char *pReplaceWith, OUT_Z_CAP(outLen) char *pOut, int outLen, bool bCaseSensitive=false );
  701. // Split the specified string on the specified separator.
  702. // Returns a list of strings separated by pSeparator.
  703. // You are responsible for freeing the contents of outStrings (call outStrings.PurgeAndDeleteElements).
  704. // You can pass in a CUtlStringList to hold the results, and it will automatically free the strings,
  705. // but it does this in the destructor so if you make multiple calls to V_SplitString with the same
  706. // object you must call outStrings.PurgeAndDeleteElements between each call.
  707. // If you copy and retain pointers to any of the strings you must zero them before calling
  708. // PurgeAndDeleteElements to avoid having a pointer to freed memory.
  709. void V_SplitString( IN_Z const char *pString, IN_Z const char *pSeparator, CUtlVector<char*, CUtlMemory<char*, int> > &outStrings );
  710. void V_SplitString( const char *pString, const char *pSeparator, CUtlVector< CUtlString, CUtlMemory<CUtlString, int> > &outStrings, bool bIncludeEmptyStrings = false );
  711. // Just like V_SplitString, but it can use multiple possible separators.
  712. void V_SplitString2( const char *pString, const char **pSeparators, int nSeparators, CUtlVector<char*, CUtlMemory<char*, int> > &outStrings );
  713. // Split string for wide character strings
  714. void V_SplitWString( const wchar_t *pString, const wchar_t *pSeparator, CUtlVector<wchar_t*, CUtlMemory<wchar_t*, int> > &outStrings );
  715. // Just like V_SplitString, but for wide character strings
  716. void V_SplitWString2( const wchar_t *pString, const wchar_t **pSeparators, int nSeparators, CUtlVector<wchar_t*, CUtlMemory<wchar_t*, int> > &outStrings );
  717. // Returns false if the buffer is not large enough to hold the working directory name.
  718. bool V_GetCurrentDirectory( char *pOut, int maxLen );
  719. // Set the working directory thus.
  720. bool V_SetCurrentDirectory( const char *pDirName );
  721. typedef enum
  722. {
  723. PATTERN_NONE = 0x00000000,
  724. PATTERN_DIRECTORY = 0x00000001
  725. } TStringPattern;
  726. // String matching using wildcards (*) for partial matches.
  727. bool V_StringMatchesPattern( const char* szString, const char* szPattern, int flags = 0 );
  728. // This function takes a slice out of pStr and stores it in pOut.
  729. // It follows the Python slice convention:
  730. // Negative numbers wrap around the string (-1 references the last character).
  731. // Large numbers are clamped to the end of the string.
  732. void V_StrSlice( const char *pStr, int firstChar, int lastCharNonInclusive, char *pOut, int outSize );
  733. // Chop off the left nChars of a string.
  734. void V_StrLeft( const char *pStr, int nChars, char *pOut, int outSize );
  735. // Chop off the right nChars of a string.
  736. void V_StrRight( const char *pStr, int nChars, char *pOut, int outSize );
  737. // change "special" characters to have their c-style backslash sequence. like \n, \r, \t, ", etc.
  738. // returns a pointer to a newly allocated string, which you must delete[] when finished with.
  739. char *V_AddBackSlashesToSpecialChars( char const *pSrc );
  740. // Force slashes of either type to be = separator character
  741. void V_FixSlashes( char *pname, char separator = CORRECT_PATH_SEPARATOR );
  742. // This function fixes cases of filenames like materials\\blah.vmt or somepath\otherpath\\ and removes the extra double slash.
  743. void V_FixDoubleSlashes( char *pStr );
  744. // Check if 2 paths are the same, works if slashes are different.
  745. bool V_PathsMatch( const char *pPath1, const char *pPath2 );
  746. // Convert multibyte to wchar + back
  747. // Specify -1 for nInSize for null-terminated string
  748. void V_strtowcs( const char *pString, int nInSize, wchar_t *pWString, int nOutSize );
  749. void V_wcstostr( const wchar_t *pWString, int nInSize, char *pString, int nOutSize );
  750. // buffer-safe strcat
  751. inline void V_strcat( INOUT_Z_CAP(cchDest) char *dest, const char *src, int cchDest )
  752. {
  753. V_strncat( dest, src, cchDest, COPY_ALL_CHARACTERS );
  754. }
  755. // Buffer safe wcscat
  756. inline void V_wcscat( INOUT_Z_CAP(cchDest) wchar_t *dest, const wchar_t *src, int cchDest )
  757. {
  758. V_wcsncat( dest, src, cchDest, COPY_ALL_CHARACTERS );
  759. }
  760. // Convert from a string to an array of integers.
  761. // Returns the actual # of ints converted
  762. int V_StringToIntArray( OUT_CAP(count) int *pVector, int count, const char *pString );
  763. // Convert from a string to an array of floats.
  764. // Returns the actual # of floats converted
  765. int V_StringToFloatArray( OUT_CAP(count) float *pVector, int count, const char *pString );
  766. // Convert from a string to a vector3 type
  767. void V_StringToVector( OUT_CAP(3) float *pVector, const char *pString );
  768. // Convert from a string to a 4 byte color value.
  769. void V_StringToColor32( color32 *color, const char *pString );
  770. // Convert \r\n (Windows linefeeds) to \n (Unix linefeeds).
  771. void V_TranslateLineFeedsToUnix( char *pStr );
  772. /// Given two file paths, return the length of the common starting substring containing matching components. Case insensitive, and treats slash and backslash the same
  773. /// Assert( LengthOfMatchingPaths( "d:/a/b", "d:/a/b" ) == 6 );
  774. /// Assert( LengthOfMatchingPaths( "d:/a/b", "d:/a/" ) == 5 );
  775. /// Assert( LengthOfMatchingPaths( "d:/a/b", "d:/a" ) == 5 );
  776. /// Assert( LengthOfMatchingPaths( "d:/a/ba", "d:/a/b" ) == 5 );
  777. int LengthOfMatchingPaths( char const *pFilenamePath, char const *pMatchPath );
  778. inline void V_RemoveFormatSpecifications( const char *pszFrom, char *pszTo, size_t sizeDest )
  779. {
  780. while ( *pszFrom && --sizeDest )
  781. {
  782. if ( *pszFrom == '%' )
  783. {
  784. if ( --sizeDest )
  785. {
  786. *pszTo++ = '%';
  787. }
  788. else
  789. {
  790. break;
  791. }
  792. }
  793. *pszTo++ = *pszFrom++;
  794. }
  795. *pszTo = 0;
  796. }
  797. // If pBreakCharacters == NULL, then the tokenizer will split tokens at the following characters:
  798. // { } ( ) ' :
  799. // White-space, '//' comments, and quoted strings are always handled.
  800. char const *V_ParseToken( char const *pStrIn, OUT_Z_CAP(bufsize) char *pToken, int bufsize, bool *pbOverflowed = NULL, struct characterset_t *pTokenBreakCharacters = NULL );
  801. // Parses a single line, does not trim any whitespace from start or end. Does not include the final '\n'.
  802. char const *V_ParseLine( char const *pStrIn, OUT_Z_CAP(bufsize) char *pToken, int bufsize, bool *pbOverflowed = NULL );
  803. // Returns true if additional data is waiting to be processed on this line
  804. bool V_TokenWaiting( const char *buffer );
  805. // Performs boyer moore search, returns offset of first occurrence of needle in haystack, or -1 on failure. Note that haystack and the needle can be binary (non-text) data
  806. int V_BoyerMooreSearch( const byte *pNeedle, int nNeedleLength, const byte *pHayStack, int nHayStackLength );
  807. // Creates a random ascii string (alphanumeric only) of specified length
  808. CUtlString V_RandomString( int nLength );
  809. // Encode a string for display as HTML -- this only encodes ' " & < >, which are the important ones to encode for
  810. // security and ensuring HTML display doesn't break. Other special chars like the ? sign and so forth will not
  811. // be encoded
  812. //
  813. // Returns false if there was not enough room in pDest to encode the entire source string, otherwise true
  814. bool V_BasicHtmlEntityEncode( OUT_Z_CAP( nDestSize ) char *pDest, const int nDestSize, char const *pIn, const int nInSize, bool bPreserveWhitespace = false );
  815. // Decode a string with htmlentities HTML -- this should handle all special chars, not just the ones Q_BasicHtmlEntityEncode uses.
  816. //
  817. // Returns false if there was not enough room in pDest to decode the entire source string, otherwise true
  818. bool V_HtmlEntityDecodeToUTF8( OUT_Z_CAP( nDestSize ) char *pDest, const int nDestSize, char const *pIn, const int nInSize );
  819. // strips HTML from a string. Should call Q_HTMLEntityDecodeToUTF8 afterward.
  820. void V_StripAndPreserveHTML( CUtlBuffer *pbuffer, const char *pchHTML, const char **rgszPreserveTags, uint cPreserveTags, uint cMaxResultSize );
  821. void V_StripAndPreserveHTMLCore( CUtlBuffer *pbuffer, const char *pchHTML, const char **rgszPreserveTags, uint cPreserveTags, const char **rgszNoCloseTags, uint cNoCloseTags, uint cMaxResultSize );
  822. // Extracts the domain from a URL
  823. bool V_ExtractDomainFromURL( const char *pchURL, OUT_Z_CAP( cchDomain ) char *pchDomain, int cchDomain );
  824. // returns true if the url passed in is on the specified domain
  825. bool V_URLContainsDomain( const char *pchURL, const char *pchDomain );
  826. //-----------------------------------------------------------------------------
  827. // returns true if the character is allowed in a URL, false otherwise
  828. //-----------------------------------------------------------------------------
  829. bool V_IsValidURLCharacter( const char *pch, int *pAdvanceBytes );
  830. //-----------------------------------------------------------------------------
  831. // returns true if the character is allowed in a DNS doman name, false otherwise
  832. //-----------------------------------------------------------------------------
  833. bool V_IsValidDomainNameCharacter( const char *pch, int *pAdvanceBytes );
  834. // Converts BBCode tags to HTML tags
  835. bool V_BBCodeToHTML( OUT_Z_CAP( nDestSize ) char *pDest, const int nDestSize, char const *pIn, const int nInSize );
  836. // helper to identify "mean" spaces, which we don't like in visible identifiers
  837. // such as player Name
  838. bool V_IsMeanSpaceW( wchar_t wch );
  839. // helper to identify characters which are deprecated in Unicode,
  840. // and we simply don't accept
  841. bool V_IsDeprecatedW( wchar_t wch );
  842. //-----------------------------------------------------------------------------
  843. // generic unique name helper functions
  844. //-----------------------------------------------------------------------------
  845. // returns -1 if no match, nDefault if pName==prefix, and N if pName==prefix+N
  846. inline int V_IndexAfterPrefix( const char *pName, const char *prefix, int nDefault = 0 )
  847. {
  848. if ( !pName || !prefix )
  849. return -1;
  850. const char *pIndexStr = StringAfterPrefix( pName, prefix );
  851. if ( !pIndexStr )
  852. return -1;
  853. if ( !*pIndexStr )
  854. return nDefault;
  855. return atoi( pIndexStr );
  856. }
  857. // returns startindex if none found, 2 if "prefix" found, and n+1 if "prefixn" found
  858. template < class NameArray >
  859. int V_GenerateUniqueNameIndex( const char *prefix, const NameArray &nameArray, int startindex = 0 )
  860. {
  861. if ( !prefix )
  862. return 0;
  863. int freeindex = startindex;
  864. int nNames = nameArray.Count();
  865. for ( int i = 0; i < nNames; ++i )
  866. {
  867. int index = V_IndexAfterPrefix( nameArray[ i ], prefix, 1 ); // returns -1 if no match, 0 for exact match, N for
  868. if ( index >= freeindex )
  869. {
  870. // TODO - check that there isn't more junk after the index in pElementName
  871. freeindex = index + 1;
  872. }
  873. }
  874. return freeindex;
  875. }
  876. template < class NameArray >
  877. bool V_GenerateUniqueName( char *name, int memsize, const char *prefix, const NameArray &nameArray )
  878. {
  879. if ( name == NULL || memsize == 0 )
  880. return false;
  881. if ( prefix == NULL )
  882. {
  883. name[ 0 ] = '\0';
  884. return false;
  885. }
  886. int prefixLength = V_strlen( prefix );
  887. if ( prefixLength + 1 > memsize )
  888. {
  889. name[ 0 ] = '\0';
  890. return false;
  891. }
  892. int i = V_GenerateUniqueNameIndex( prefix, nameArray );
  893. if ( i <= 0 )
  894. {
  895. V_strncpy( name, prefix, memsize );
  896. return true;
  897. }
  898. int newlen = prefixLength + ( int )log10( ( float )i ) + 1;
  899. if ( newlen + 1 > memsize )
  900. {
  901. V_strncpy( name, prefix, memsize );
  902. return false;
  903. }
  904. V_snprintf( name, memsize, "%s%d", prefix, i );
  905. return true;
  906. }
  907. extern bool V_StringToBin( const char*pString, void *pBin, uint nBinSize );
  908. extern bool V_BinToString( char*pString, void *pBin, uint nBinSize );
  909. template<typename T>
  910. struct BinString_t
  911. {
  912. BinString_t(){}
  913. explicit BinString_t( const char *pStr )
  914. {
  915. V_strncpy( m_string, pStr, sizeof(m_string) );
  916. ToBin();
  917. }
  918. explicit BinString_t( const T & that )
  919. {
  920. m_bin = that;
  921. ToString();
  922. }
  923. bool ToBin()
  924. {
  925. return V_StringToBin( m_string, &m_bin, sizeof( m_bin ) );
  926. }
  927. void ToString()
  928. {
  929. V_BinToString( m_string, &m_bin, sizeof( m_bin ) );
  930. }
  931. T m_bin;
  932. char m_string[sizeof(T)*2+2]; // 0-terminated string representing the binary data in hex
  933. };
  934. template <typename T>
  935. inline BinString_t<T> MakeBinString( const T& that )
  936. {
  937. return BinString_t<T>( that );
  938. }
  939. // Encodes a string (or binary data) in URL encoding format, see rfc1738 section 2.2.
  940. // Dest buffer should be 3 times the size of source buffer to guarantee it has room to encode.
  941. void Q_URLEncodeRaw( OUT_Z_CAP(nDestLen) char *pchDest, int nDestLen, const char *pchSource, int nSourceLen );
  942. // Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
  943. // Dest buffer should be at least as large as source buffer to gurantee room for decode.
  944. // Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
  945. //
  946. // Returns the amount of space actually used in the output buffer.
  947. size_t Q_URLDecodeRaw( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen );
  948. // Encodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces.
  949. // This is for historical reasons and HTML spec foolishness that lead to + becoming a de facto standard for spaces when encoding form data.
  950. // Dest buffer should be 3 times the size of source buffer to guarantee it has room to encode.
  951. void Q_URLEncode( OUT_Z_CAP(nDestLen) char *pchDest, int nDestLen, const char *pchSource, int nSourceLen );
  952. // Decodes a string (or binary data) in URL encoding format, this isn't the strict rfc1738 format, but instead uses + for spaces.
  953. // This is for historical reasons and HTML spec foolishness that lead to + becoming a de facto standard for spaces when encoding form data.
  954. // Dest buffer should be at least as large as source buffer to gurantee room for decode.
  955. // Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
  956. //
  957. // Returns the amount of space actually used in the output buffer.
  958. size_t Q_URLDecode( OUT_CAP(nDecodeDestLen) char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen );
  959. //-----------------------------------------------------------------------------
  960. // Purpose: Utility class to allow parsing of various types of data
  961. //-----------------------------------------------------------------------------
  962. template< class V >
  963. struct TypeParser_t
  964. {
  965. static int ComputeMaxStringSize( const V *pValue ) { return 1; }
  966. static bool WriteToString( const V *pValue, OUT_Z_CAP(nBufLen) char *pBuf, int nBufLen ) { *pBuf = 0; return false; }
  967. static bool ParseFromString( const char *pString, V *pValue ) { return false; }
  968. };
  969. // Used to put TypeParser_t function calls in arrays w/ common prototypes
  970. template< class V >
  971. struct TypeParserAdapter_t
  972. {
  973. static bool WriteToString( const void *pValue, OUT_Z_CAP(nBufLen) char *pBuf, int nBufLen ) { return TypeParser_t<V>::WriteToString( ( const V* )pValue, pBuf, nBufLen ); }
  974. static int ComputeMaxStringSize( const void *pValue ) { return TypeParser_t<V>::ComputeMaxStringSize( ( const V* )pValue ); }
  975. static bool ParseFromString( const char *pString, void *pValue ) { return TypeParser_t<V>::ParseFromString( pString, ( V* )pValue ); }
  976. };
  977. template <> struct TypeParser_t< bool >
  978. {
  979. static int ComputeMaxStringSize( const bool *pValue ) { return 6; } //"false"
  980. static bool WriteToString( const bool *pValue, OUT_Z_CAP(nBufLen) char *pBuf, int nBufLen )
  981. {
  982. int nLenWritten = V_snprintf( pBuf, ( int )nBufLen, (*pValue) ? "true" : "false" );
  983. return ( nLenWritten < nBufLen );
  984. }
  985. static bool ParseFromString( const char *pString, bool *pValue )
  986. {
  987. if ( !V_stricmp( pString, "true" ) )
  988. {
  989. *pValue = true;
  990. return true;
  991. }
  992. if ( !V_stricmp( pString, "false" ) )
  993. {
  994. *pValue = false;
  995. return true;
  996. }
  997. int nValue;
  998. if ( sscanf( pString, "%d", &nValue ) != 1 )
  999. return false;
  1000. if ( nValue != 0 && nValue != 1 )
  1001. return false;
  1002. *pValue = ( nValue == 1 );
  1003. return true;
  1004. }
  1005. };
  1006. #define DECLARE_POD_TYPE_PARSE_BASE( type, formatspecifier, maxstringdigits, SCAN ) \
  1007. template <> struct TypeParser_t< type > \
  1008. { \
  1009. static int ComputeMaxStringSize( const type *pValue ) { return maxstringdigits; } \
  1010. \
  1011. static bool WriteToString( const type *pValue, OUT_Z_CAP(nBufLen) char *pBuf, int nBufLen ) \
  1012. { \
  1013. int nLenWritten = V_snprintf( pBuf, nBufLen, formatspecifier, *pValue ); \
  1014. return ( nLenWritten < nBufLen ); \
  1015. } \
  1016. static bool ParseFromString( const char *pString, type *pValue ) \
  1017. { \
  1018. SCAN \
  1019. } \
  1020. };
  1021. #define DECLARE_POD_TYPE_PARSE( type, formatspecifier, maxstringdigits ) DECLARE_POD_TYPE_PARSE_BASE( type, formatspecifier, maxstringdigits, { return ( sscanf( pString, formatspecifier, pValue ) == 1 ); } )
  1022. #define DECLARE_POD_TYPE_PARSE_SMALLINT( type, formatspecifier, maxstringdigits, BIGINT ) DECLARE_POD_TYPE_PARSE_BASE( type, formatspecifier, maxstringdigits, { BIGINT nScannedValue; if( sscanf( pString, formatspecifier, &nScannedValue ) == 1 ) { *pValue = ( type )nScannedValue; return true; } else return false; } )
  1023. // NOTE: MS compiler won't allow sscanf of a 1-byte int, and will override memory if you try to sscanf( %d, int8 )
  1024. DECLARE_POD_TYPE_PARSE_SMALLINT( int8, "%d", 5, int ); // -127
  1025. DECLARE_POD_TYPE_PARSE_SMALLINT( uint8, "%u", 5, uint );
  1026. DECLARE_POD_TYPE_PARSE_SMALLINT( int16, "%d", 7, int ); // -32767
  1027. DECLARE_POD_TYPE_PARSE_SMALLINT( uint16, "%u", 7, uint );
  1028. DECLARE_POD_TYPE_PARSE( int32, "%d", 12 );//MIN_INT
  1029. DECLARE_POD_TYPE_PARSE( uint32, "%u", 12 );//UINT_MAX
  1030. DECLARE_POD_TYPE_PARSE( int64, "%lld", 21 ); // 18446744073709551615 -9223372036854775808
  1031. DECLARE_POD_TYPE_PARSE( uint64, "%llu", 21 );
  1032. DECLARE_POD_TYPE_PARSE( float32, "%f", 48 ); // -FLT32_MAX
  1033. DECLARE_POD_TYPE_PARSE( float64, "%lf", 318 ); // -FLOAT64_MAX (it's got a lot of zeros)
  1034. template <> struct TypeParser_t< Color >
  1035. {
  1036. static int ComputeMaxStringSize( const Color *pValue ) { return 18; } //{255 255 255 255}
  1037. static bool WriteToString( const Color *pValue, OUT_Z_CAP(nBufLen) char *pBuf, int nBufLen )
  1038. {
  1039. int nLenWritten = V_snprintf( pBuf, ( int )nBufLen, "{%d %d %d %d}", pValue->r(), pValue->g(), pValue->b(), pValue->a() );
  1040. return ( nLenWritten < nBufLen );
  1041. }
  1042. static bool ParseFromString( const char *pString, Color *pValue )
  1043. {
  1044. int r, g, b, a;
  1045. if ( sscanf( pString, "{%d %d %d %d}", &r, &g, &b, &a ) != 4 )
  1046. return false;
  1047. if ( r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255 )
  1048. return false;
  1049. pValue->SetColor( r, g, b, a );
  1050. return true;
  1051. }
  1052. };
  1053. //---------------------------------------------------------------------------------------------------------------------------------------------------
  1054. // This will return a char* valid for the current expression that will make a number comma separated:
  1055. // Log_Msg( LOG_VFXC, "%s", V_FormatNumber( -1234567 ) );
  1056. // will output:
  1057. // -1,234,567
  1058. //---------------------------------------------------------------------------------------------------------------------------------------------------
  1059. #define V_FormatNumber( nNum ) ( CFormatNumber_DontUseDirectly_UseFormatNumberMacro( ( nNum ) ).AsString() )
  1060. class CFormatNumber_DontUseDirectly_UseFormatNumberMacro
  1061. {
  1062. public:
  1063. CFormatNumber_DontUseDirectly_UseFormatNumberMacro() { m_szBuf[0] = '\0'; pString = m_szBuf; }
  1064. // Standard C formatting
  1065. void FormatNumberInternal( uint64 nNum )
  1066. {
  1067. pString = m_szBuf + sizeof( m_szBuf ) - 1;
  1068. *pString-- = '\0';
  1069. if ( nNum == 0 )
  1070. {
  1071. *pString-- = '0';
  1072. }
  1073. for ( uint64 j = 0; nNum > 0; nNum /= 10, j++ )
  1074. {
  1075. // Add comma
  1076. if ( j && !( j % 3 ) )
  1077. {
  1078. *pString-- = ',';
  1079. }
  1080. // Add digit
  1081. *pString-- = '0' + char( nNum % 10 );
  1082. }
  1083. pString++;
  1084. }
  1085. void FormatNumberInternal64( int64 nNum )
  1086. {
  1087. bool bIsNegative = ( nNum < ( int64 )0 );
  1088. uint64 nUnsigned = ( bIsNegative ) ? ( uint64 )( -nNum ) : ( uint64 )( nNum );
  1089. FormatNumberInternal( ( uint64 )nUnsigned );
  1090. if ( bIsNegative )
  1091. {
  1092. pString--;
  1093. *pString = '-';
  1094. }
  1095. }
  1096. CFormatNumber_DontUseDirectly_UseFormatNumberMacro( int64 nNum ) { FormatNumberInternal64( ( int64 )nNum ); }
  1097. CFormatNumber_DontUseDirectly_UseFormatNumberMacro( int32 nNum ) { FormatNumberInternal64( ( int64 )nNum ); }
  1098. CFormatNumber_DontUseDirectly_UseFormatNumberMacro( int16 nNum ) { FormatNumberInternal64( ( int64 )nNum ); }
  1099. void FormatNumberInternalU64( uint64 nNum )
  1100. {
  1101. FormatNumberInternal( nNum );
  1102. }
  1103. CFormatNumber_DontUseDirectly_UseFormatNumberMacro( uint64 nNum ) { FormatNumberInternalU64( ( uint64 )nNum ); }
  1104. CFormatNumber_DontUseDirectly_UseFormatNumberMacro( uint32 nNum ) { FormatNumberInternalU64( ( uint64 )nNum ); }
  1105. CFormatNumber_DontUseDirectly_UseFormatNumberMacro( uint16 nNum ) { FormatNumberInternalU64( ( uint64 )nNum ); }
  1106. // Use for access
  1107. operator const char *() const { return pString; }
  1108. const char *AsString() { return pString; }
  1109. private:
  1110. char m_szBuf[64];
  1111. char *pString;
  1112. };
  1113. // trim right whitespace
  1114. inline char* TrimRight( char *pString )
  1115. {
  1116. char *pEnd = pString + V_strlen( pString );
  1117. // trim
  1118. while ( pString < ( pEnd-- ) )
  1119. {
  1120. if ( uint( *pEnd ) <= uint( ' ' ) )
  1121. {
  1122. *pEnd = '\0';
  1123. }
  1124. else
  1125. break;
  1126. }
  1127. return pString;
  1128. }
  1129. inline const char * SkipBlanks( const char *pString )
  1130. {
  1131. const char *p = pString;
  1132. while ( *p && uint( *p ) <= uint( ' ' ) )
  1133. {
  1134. p++;
  1135. }
  1136. return p;
  1137. }
  1138. inline int V_strcspn( const char *s1, const char *search ) { return (int)( strcspn( s1, search ) ); }
  1139. // NOTE: This is for backward compatability!
  1140. // We need to DLL-export the Q methods in vstdlib but not link to them in other projects
  1141. #if !defined( VSTDLIB_BACKWARD_COMPAT )
  1142. #define Q_memset V_memset
  1143. #define Q_memcpy V_memcpy
  1144. #define Q_memmove V_memmove
  1145. #define Q_memcmp V_memcmp
  1146. #define Q_strlen V_strlen
  1147. #define Q_strcpy V_strcpy
  1148. #define Q_strrchr V_strrchr
  1149. #define Q_strcmp V_strcmp
  1150. #define Q_wcscmp V_wcscmp
  1151. #define Q_stricmp V_stricmp
  1152. #define Q_strstr V_strstr
  1153. #define Q_strupr V_strupr
  1154. #define Q_strlower V_strlower
  1155. #define Q_wcslen V_wcslen
  1156. #define Q_strncmp V_strncmp
  1157. #define Q_strcasecmp V_strcasecmp
  1158. #define Q_strncasecmp V_strncasecmp
  1159. #define Q_strnicmp V_strnicmp
  1160. #define Q_atoi V_atoi
  1161. #define Q_atoi64 V_atoi64
  1162. #define Q_atoui64 V_atoui64
  1163. #define Q_atof V_atof
  1164. #define Q_stristr V_stristr
  1165. #define Q_strnistr V_strnistr
  1166. #define Q_strnchr V_strnchr
  1167. #define Q_normalizeFloatString V_normalizeFloatString
  1168. #define Q_strncpy V_strncpy
  1169. #define Q_wcsncpy V_wcsncpy
  1170. #define Q_snprintf V_snprintf
  1171. #define Q_snwprintf V_snwprintf
  1172. #define Q_wcsncpy V_wcsncpy
  1173. #define Q_strncat V_strncat
  1174. #define Q_wcsncat V_wcsncat
  1175. #define Q_strnlwr V_strnlwr
  1176. #define Q_vsnprintf V_vsnprintf
  1177. #define Q_vsnprintfRet V_vsnprintfRet
  1178. #define Q_pretifymem V_pretifymem
  1179. #define Q_pretifynum V_pretifynum
  1180. #define Q_UTF8ToUnicode V_UTF8ToUnicode
  1181. #define Q_UnicodeToUTF8 V_UnicodeToUTF8
  1182. #define Q_hextobinary V_hextobinary
  1183. #define Q_binarytohex V_binarytohex
  1184. #define Q_FileBase V_FileBase
  1185. #define Q_StripTrailingSlash V_StripTrailingSlash
  1186. #define Q_StripExtension V_StripExtension
  1187. #define Q_DefaultExtension V_DefaultExtension
  1188. #define Q_SetExtension V_SetExtension
  1189. #define Q_StripFilename V_StripFilename
  1190. #define Q_StripLastDir V_StripLastDir
  1191. #define Q_UnqualifiedFileName V_UnqualifiedFileName
  1192. #define Q_ComposeFileName V_ComposeFileName
  1193. #define Q_ExtractFilePath V_ExtractFilePath
  1194. #define Q_ExtractFileExtension V_ExtractFileExtension
  1195. #define Q_GetFileExtension V_GetFileExtension
  1196. #define Q_RemoveDotSlashes V_RemoveDotSlashes
  1197. #define Q_MakeAbsolutePath V_MakeAbsolutePath
  1198. #define Q_AppendSlash V_AppendSlash
  1199. #define Q_IsAbsolutePath V_IsAbsolutePath
  1200. #define Q_StrSubst V_StrSubst
  1201. #define Q_SplitString V_SplitString
  1202. #define Q_SplitString2 V_SplitString2
  1203. #define Q_StrSlice V_StrSlice
  1204. #define Q_StrLeft V_StrLeft
  1205. #define Q_StrRight V_StrRight
  1206. #define Q_FixSlashes V_FixSlashes
  1207. #define Q_strtowcs V_strtowcs
  1208. #define Q_wcstostr V_wcstostr
  1209. #define Q_strcat V_strcat
  1210. #define Q_wcscat V_wcscat
  1211. #define Q_MakeRelativePath V_MakeRelativePath
  1212. #define Q_FixupPathName V_FixupPathName
  1213. #define Q_qsort_s V_qsort_s
  1214. #endif // !defined( VSTDLIB_DLL_EXPORT )
  1215. #if defined(_PS3) || defined(POSIX)
  1216. #define PRI_WS_FOR_WS L"%ls"
  1217. #define PRI_WS_FOR_S "%ls"
  1218. #define PRI_S_FOR_WS L"%s"
  1219. #define PRI_S_FOR_S "%s"
  1220. #else
  1221. #define PRI_WS_FOR_WS L"%s"
  1222. #define PRI_WS_FOR_S "%S"
  1223. #define PRI_S_FOR_WS L"%S"
  1224. #define PRI_S_FOR_S "%s"
  1225. #endif
  1226. namespace AsianWordWrap
  1227. {
  1228. // Functions used by Asian language line wrapping to determine if a character can end a line, begin a line, or be broken up when repeated (eg: "...")
  1229. bool CanEndLine( wchar_t wcCandidate );
  1230. bool CanBeginLine( wchar_t wcCandidate );
  1231. bool CanBreakRepeated( wchar_t wcCandidate );
  1232. // Used to determine if we can break a line between the first two characters passed; calls the above functions on each character
  1233. bool CanBreakAfter( const wchar_t* wsz );
  1234. }
  1235. // We use this function to determine where it is permissible to break lines
  1236. // of text while wrapping them. On most platforms, the native iswspace() function
  1237. // returns FALSE for the "non-breaking space" characters 0x00a0 and 0x202f, and so we don't
  1238. // break on them. On the 360, however, iswspace returns TRUE for them. So, on that
  1239. // platform, we work around it by defining this wrapper which returns false
  1240. // for &nbsp; and calls through to the library function for everything else.
  1241. int isbreakablewspace( wchar_t ch );
  1242. // Strip white space at the beginning and end of a string
  1243. int V_StrTrim( char *pStr );
  1244. #endif // TIER1_STRTOOLS_H