1 //========= Copyright Valve Corporation, All rights reserved. ============//
2 //
3 // Misc string functions.  This is just what we need to compile SDR,
4 // stripped out from Steam's version that had a bunch of extra stuff in it.
5 //
6 //========================================================================//
7 
8 #ifndef VSTDLIB_STRTOOLS_H
9 #define VSTDLIB_STRTOOLS_H
10 #pragma once
11 
12 #include <ctype.h>
13 #include <string.h>
14 #ifdef __MINGW32__
15 // for __MINGW_PRINTF_FORMAT
16 #include <stdio.h>
17 #endif
18 #include <stdlib.h>
19 #include <limits.h>
20 #include <stdarg.h>
21 
22 #include <minbase/minbase_identify.h>
23 #include <minbase/minbase_annotations.h>
24 
25 template< class T > class CUtlMemory;
26 template< class T, class A > class CUtlVector;
27 template < typename K, typename T, typename I, typename L > class CUtlMap;
28 class CUtlBuffer;
29 
30 #ifdef _WIN64
31 #define str_size unsigned int
32 #else
33 #define str_size size_t
34 #endif
35 
V_strlen(const char * str)36 inline int V_strlen(const char *str) { return static_cast<int>( strlen ( str ) ); }
V_strcmp(const char * s1,const char * s2)37 inline int V_strcmp(const char *s1, const char *s2) { return strcmp( s1, s2 ); }
V_memcmp(const void * m1,const void * m2,size_t count)38 inline int V_memcmp (const void *m1, const void *m2, size_t count){ return memcmp( m1, m2, count ); }
V_memmove(OUT_BYTECAP (count)void * dest,IN_BYTECAP (count)const void * src,size_t count)39 inline void V_memmove (OUT_BYTECAP(count) void *dest, IN_BYTECAP(count) const void *src, size_t count)	{ memmove( dest, src, count ); }
V_memset(OUT_BYTECAP (count)void * dest,int fill,size_t count)40 inline void V_memset (OUT_BYTECAP(count) void *dest, int fill, size_t count) { memset( dest, fill, count ); }
V_memcpy(OUT_BYTECAP (count)void * dest,IN_BYTECAP (count)const void * src,size_t count)41 inline void V_memcpy( OUT_BYTECAP( count ) void *dest, IN_BYTECAP( count ) const void *src, size_t count )	{ memcpy( dest, src, count ); }
V_strstr(const char * s1,const char * search)42 inline const char*V_strstr( const char *s1, const char *search ) { return strstr( s1, search ); }
V_strchr(char * s,char c)43 inline char *V_strchr( char *s, char c ) { return strchr( s, c ); }
V_strstr(char * s1,const char * search)44 inline char*V_strstr( char *s1, const char *search ) { return (char*)strstr( s1, search ); }
45 
46 extern int	V_strncmp( const char *s1, const char *s2, int count );
47 extern const char*V_strnistr( const char* pStr, const char* pSearch, int n );
48 extern const char*V_strnchr( const char* pStr, char c, int n );
49 extern int V_strnicmp( const char *s1, const char *s2, int n );
V_stricmp(const char * s1,const char * s2)50 inline int V_stricmp( const char *s1, const char *s2 ) { return V_strnicmp( s1, s2, INT_MAX ); }
51 const char* V_stristr( const char* pStr, const char* pSearch );
52 extern char* V_strlower_fast( char *start );
53 extern char* V_strupper_fast( char *start );
54 
55 extern void V_strncpy( OUT_Z_CAP(maxLen) char *pDest, const char *pSrc, size_t maxLen );
V_strcpy_safe(OUT_Z_ARRAY char (& pDest)[maxLenInChars],const char * pSrc)56 template <size_t maxLenInChars> void V_strcpy_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], const char *pSrc )
57 {
58 	V_strncpy( pDest, pSrc, maxLenInChars );
59 }
60 
61 extern int V_vsnprintf( OUT_Z_CAP(maxLen) char *pDest, int maxLen, const char *pFormat, va_list params );
62 extern int V_vsnprintfRet( OUT_Z_CAP(maxLen) char *pDest, int maxLen, const char *pFormat, va_list params, bool *pbTruncated );
63 extern int V_snprintf( OUT_Z_CAP(destLen) char *pDest, size_t destLen, PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 3, 4 );
V_sprintf_safe(OUT_Z_ARRAY char (& pDest)[maxLenInChars],PRINTF_FORMAT_STRING const char * pFormat,...)64 template <size_t maxLenInChars> int V_sprintf_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char *pFormat, ... )
65 {
66 	va_list params;
67 	va_start( params, pFormat );
68 	int result = V_vsnprintf( pDest, maxLenInChars, pFormat, params );
69 	va_end( params );
70 	return result;
71 }
72 
V_vsprintf_safe(OUT_Z_ARRAY char (& pDest)[maxLenInChars],PRINTF_FORMAT_STRING const char * pFormat,va_list params)73 template <size_t maxLenInChars> int V_vsprintf_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char *pFormat, va_list params ) { return V_vsnprintf( pDest, maxLenInChars, pFormat, params ); }
74 
75 #define COPY_ALL_CHARACTERS -1
76 char *V_strncat(INOUT_Z_CAP(destBufferSize) char *, const char *, size_t destBufferSize, int max_chars_to_copy=COPY_ALL_CHARACTERS );
77 template <size_t cchDest> char *V_strcat_safe( INOUT_Z_ARRAY char (&pDest)[cchDest], const char *pSrc, int nMaxCharsToCopy=COPY_ALL_CHARACTERS )
78 {
79 	return V_strncat( pDest, pSrc, cchDest, nMaxCharsToCopy );
80 }
81 
82 // Return true if the string is "empty": Either null, or an empty string
V_isempty(const char * pszString)83 inline bool V_isempty( const char* pszString ) { return !pszString || !pszString[0]; }
84 
85 // is* helpers
V_isspace(char c)86 inline bool V_isspace(char c) { return isspace((unsigned char)c) != 0; }
87 
88 // Split the specified string on the specified separator.
89 // Returns a list of strings separated by pSeparator.
90 // You are responsible for freeing the contents of outStrings (call outStrings.PurgeAndDeleteElements).
91 extern void V_AllocAndSplitString( const char *pString, const char *pSeparator, CUtlVector<char*, CUtlMemory<char*> > &outStrings, bool bIncludeEmptyStrings = false );
92 
93 // Strips trailing *ASCII* whitespace characters.  (Any
94 // character that returns true for V_isspace returns true.)  Doesn't
95 // handle all unicode whitespace characters
96 extern void V_StripTrailingWhitespaceASCII( char *pch );
97 
98 // trim whitespace from both ends of the string
99 extern int V_StrTrim( char *pStr );
100 
101 #ifdef POSIX
102 #ifdef ANDROID
103 #include <wchar.h>
104 #endif
105 #define _atoi64 atoll
106 #define _wtoi(arg) wcstol(arg, NULL, 10)
107 #ifdef ANDROID
108 // TODO - Android doesn't support wcstoi64, so just use a basic implementation of our own.
109 #define _wcstoi64 vstdlib_wcstoi64
110 #define _wcstoui64 vstdlib_wcstoui64
111 #else
112 #define _wcstoi64 wcstoll
113 #define _wcstoui64 wcstoull
114 #endif
115 #define _wtoi64(arg) _wcstoi64(arg, NULL, 10)
116 #define _i64toa( num, buf, base ) sprintf( buf, "%lld", num )
117 #define _stricmp strcasecmp
118 #define _strtoi64 strtoll
119 #define _strtoui64 strtoull
120 #define _vsnprintf vsnprintf
121 #if defined(OSX) || defined(ANDROID)
122 // TODO - OSX doesn't support wcscasecmp until 10.7, so just
123 // use a basic implementation of our own.
124 #define _wcsicmp vstdlib_wcsicmp
125 #define _wcsnicmp vstdlib_wcsnicmp
126 #else
127 #define _wcsicmp wcscasecmp
128 #define _wcsnicmp wcsncasecmp
129 #endif
130 #define _wcschr wcschr
131 #ifdef TEXT
132 #undef TEXT
133 #endif
134 #define TEXT(str) str
135 
136 #endif // POSIX
137 
138 
139 #endif	// VSTDLIB_STRTOOLS_H
140