Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Unified Diff: third_party/openvr/src/src/vrcommon/strtools_public.cpp

Issue 2754253003: Add OpenVR SDK to third_party (Closed)
Patch Set: feedback Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/openvr/src/src/vrcommon/strtools_public.cpp
diff --git a/third_party/openvr/src/src/vrcommon/strtools_public.cpp b/third_party/openvr/src/src/vrcommon/strtools_public.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..74ea2a5b2dcae285ba66bdabbc3155b55bb6aaa0
--- /dev/null
+++ b/third_party/openvr/src/src/vrcommon/strtools_public.cpp
@@ -0,0 +1,437 @@
+//========= Copyright Valve Corporation ============//
+#include "strtools_public.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool StringHasPrefix( const std::string & sString, const std::string & sPrefix )
+{
+ return 0 == strnicmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() );
+}
+
+bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix )
+{
+ return 0 == strncmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() );
+}
+
+
+bool StringHasSuffix( const std::string &sString, const std::string &sSuffix )
+{
+ size_t cStrLen = sString.length();
+ size_t cSuffixLen = sSuffix.length();
+
+ if ( cSuffixLen > cStrLen )
+ return false;
+
+ std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen );
+
+ return 0 == stricmp( sStringSuffix.c_str(), sSuffix.c_str() );
+}
+
+bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix )
+{
+ size_t cStrLen = sString.length();
+ size_t cSuffixLen = sSuffix.length();
+
+ if ( cSuffixLen > cStrLen )
+ return false;
+
+ std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen );
+
+ return 0 == strncmp( sStringSuffix.c_str(), sSuffix.c_str(),cSuffixLen );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+std::string UTF16to8(const wchar_t * in)
+{
+ std::string out;
+ unsigned int codepoint = 0;
+ for ( ; in && *in != 0; ++in )
+ {
+ if (*in >= 0xd800 && *in <= 0xdbff)
+ codepoint = ((*in - 0xd800) << 10) + 0x10000;
+ else
+ {
+ if (*in >= 0xdc00 && *in <= 0xdfff)
+ codepoint |= *in - 0xdc00;
+ else
+ codepoint = *in;
+
+ if (codepoint <= 0x7f)
+ out.append(1, static_cast<char>(codepoint));
+ else if (codepoint <= 0x7ff)
+ {
+ out.append(1, static_cast<char>(0xc0 | ((codepoint >> 6) & 0x1f)));
+ out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
+ }
+ else if (codepoint <= 0xffff)
+ {
+ out.append(1, static_cast<char>(0xe0 | ((codepoint >> 12) & 0x0f)));
+ out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f)));
+ out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
+ }
+ else
+ {
+ out.append(1, static_cast<char>(0xf0 | ((codepoint >> 18) & 0x07)));
+ out.append(1, static_cast<char>(0x80 | ((codepoint >> 12) & 0x3f)));
+ out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f)));
+ out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
+ }
+ codepoint = 0;
+ }
+ }
+ return out;
+}
+
+std::wstring UTF8to16(const char * in)
+{
+ std::wstring out;
+ unsigned int codepoint = 0;
+ int following = 0;
+ for ( ; in && *in != 0; ++in )
+ {
+ unsigned char ch = *in;
+ if (ch <= 0x7f)
+ {
+ codepoint = ch;
+ following = 0;
+ }
+ else if (ch <= 0xbf)
+ {
+ if (following > 0)
+ {
+ codepoint = (codepoint << 6) | (ch & 0x3f);
+ --following;
+ }
+ }
+ else if (ch <= 0xdf)
+ {
+ codepoint = ch & 0x1f;
+ following = 1;
+ }
+ else if (ch <= 0xef)
+ {
+ codepoint = ch & 0x0f;
+ following = 2;
+ }
+ else
+ {
+ codepoint = ch & 0x07;
+ following = 3;
+ }
+ if (following == 0)
+ {
+ if (codepoint > 0xffff)
+ {
+ out.append(1, static_cast<wchar_t>(0xd800 + (codepoint >> 10)));
+ out.append(1, static_cast<wchar_t>(0xdc00 + (codepoint & 0x03ff)));
+ }
+ else
+ out.append(1, static_cast<wchar_t>(codepoint));
+ codepoint = 0;
+ }
+ }
+ return out;
+}
+
+
+void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource )
+{
+ pchBuffer[ unBufferSizeBytes - 1 ] = '\0';
+ strncpy( pchBuffer, pchSource, unBufferSizeBytes - 1 );
+}
+
+
+// --------------------------------------------------------------------
+// Purpose: converts a string to upper case
+// --------------------------------------------------------------------
+std::string StringToUpper( const std::string & sString )
+{
+ std::string sOut;
+ sOut.reserve( sString.size() + 1 );
+ for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ )
+ {
+ sOut.push_back( (char)toupper( *i ) );
+ }
+
+ return sOut;
+}
+
+
+// --------------------------------------------------------------------
+// Purpose: converts a string to lower case
+// --------------------------------------------------------------------
+std::string StringToLower( const std::string & sString )
+{
+ std::string sOut;
+ sOut.reserve( sString.size() + 1 );
+ for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ )
+ {
+ sOut.push_back( (char)tolower( *i ) );
+ }
+
+ return sOut;
+}
+
+
+uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen )
+{
+ uint32_t unLen = (uint32_t)sValue.length() + 1;
+ if( !pchBuffer || !unBufferLen )
+ return unLen;
+
+ if( unBufferLen < unLen )
+ {
+ pchBuffer[0] = '\0';
+ }
+ else
+ {
+ memcpy( pchBuffer, sValue.c_str(), unLen );
+ }
+
+ return unLen;
+}
+
+void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen )
+{
+ sDest.resize( unBufferLen + 1 );
+ memcpy( const_cast< char* >( sDest.c_str() ), pchBuffer, unBufferLen );
+ const_cast< char* >( sDest.c_str() )[ unBufferLen ] = '\0';
+}
+
+/** Returns a std::string from a uint64_t */
+std::string Uint64ToString( uint64_t ulValue )
+{
+ char buf[ 22 ];
+#if defined( _WIN32 )
+ sprintf_s( buf, "%llu", ulValue );
+#else
+ snprintf( buf, sizeof( buf ), "%llu", (long long unsigned int ) ulValue );
+#endif
+ return buf;
+}
+
+
+/** returns a uint64_t from a string */
+uint64_t StringToUint64( const std::string & sValue )
+{
+ return strtoull( sValue.c_str(), NULL, 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper for converting a numeric value to a hex digit, value should be 0-15.
+//-----------------------------------------------------------------------------
+char cIntToHexDigit( int nValue )
+{
+ //Assert( nValue >= 0 && nValue <= 15 );
+ return "0123456789ABCDEF"[ nValue & 15 ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper for converting a hex char value to numeric, return -1 if the char
+// is not a valid hex digit.
+//-----------------------------------------------------------------------------
+int iHexCharToInt( char cValue )
+{
+ int32_t iValue = cValue;
+ if ( (uint32_t)( iValue - '0' ) < 10 )
+ return iValue - '0';
+
+ iValue |= 0x20;
+ if ( (uint32_t)( iValue - 'a' ) < 6 )
+ return iValue - 'a' + 10;
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Internal implementation of encode, works in the strict RFC manner, or
+// with spaces turned to + like HTML form encoding.
+//-----------------------------------------------------------------------------
+void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, bool bUsePlusForSpace )
+{
+ //AssertMsg( nDestLen > 3*nSourceLen, "Target buffer for V_URLEncode should be 3x source length, plus one for terminating null\n" );
+
+ int iDestPos = 0;
+ for ( int i=0; i < nSourceLen; ++i )
+ {
+ // worst case we need 3 additional chars
+ if( (iDestPos+3) > nDestLen )
+ {
+ pchDest[0] = '\0';
+// AssertMsg( false, "Target buffer too short\n" );
+ return;
+ }
+
+ // We allow only a-z, A-Z, 0-9, period, underscore, and hyphen to pass through unescaped.
+ // These are the characters allowed by both the original RFC 1738 and the latest RFC 3986.
+ // Current specs also allow '~', but that is forbidden under original RFC 1738.
+ if ( !( pchSource[i] >= 'a' && pchSource[i] <= 'z' ) && !( pchSource[i] >= 'A' && pchSource[i] <= 'Z' ) && !(pchSource[i] >= '0' && pchSource[i] <= '9' )
+ && pchSource[i] != '-' && pchSource[i] != '_' && pchSource[i] != '.'
+ )
+ {
+ if ( bUsePlusForSpace && pchSource[i] == ' ' )
+ {
+ pchDest[iDestPos++] = '+';
+ }
+ else
+ {
+ pchDest[iDestPos++] = '%';
+ uint8_t iValue = pchSource[i];
+ if ( iValue == 0 )
+ {
+ pchDest[iDestPos++] = '0';
+ pchDest[iDestPos++] = '0';
+ }
+ else
+ {
+ char cHexDigit1 = cIntToHexDigit( iValue % 16 );
+ iValue /= 16;
+ char cHexDigit2 = cIntToHexDigit( iValue );
+ pchDest[iDestPos++] = cHexDigit2;
+ pchDest[iDestPos++] = cHexDigit1;
+ }
+ }
+ }
+ else
+ {
+ pchDest[iDestPos++] = pchSource[i];
+ }
+ }
+
+ if( (iDestPos+1) > nDestLen )
+ {
+ pchDest[0] = '\0';
+ //AssertMsg( false, "Target buffer too short to terminate\n" );
+ return;
+ }
+
+ // Null terminate
+ pchDest[iDestPos++] = 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Internal implementation of decode, works in the strict RFC manner, or
+// with spaces turned to + like HTML form encoding.
+//
+// Returns the amount of space used in the output buffer.
+//-----------------------------------------------------------------------------
+size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen, bool bUsePlusForSpace )
+{
+ if ( nDecodeDestLen < nEncodedSourceLen )
+ {
+ //AssertMsg( false, "V_URLDecode needs a dest buffer at least as large as the source" );
+ return 0;
+ }
+
+ int iDestPos = 0;
+ for( int i=0; i < nEncodedSourceLen; ++i )
+ {
+ if ( bUsePlusForSpace && pchEncodedSource[i] == '+' )
+ {
+ pchDecodeDest[ iDestPos++ ] = ' ';
+ }
+ else if ( pchEncodedSource[i] == '%' )
+ {
+ // Percent signifies an encoded value, look ahead for the hex code, convert to numeric, and use that
+
+ // First make sure we have 2 more chars
+ if ( i < nEncodedSourceLen - 2 )
+ {
+ char cHexDigit1 = pchEncodedSource[i+1];
+ char cHexDigit2 = pchEncodedSource[i+2];
+
+ // Turn the chars into a hex value, if they are not valid, then we'll
+ // just place the % and the following two chars direct into the string,
+ // even though this really shouldn't happen, who knows what bad clients
+ // may do with encoding.
+ bool bValid = false;
+ int iValue = iHexCharToInt( cHexDigit1 );
+ if ( iValue != -1 )
+ {
+ iValue *= 16;
+ int iValue2 = iHexCharToInt( cHexDigit2 );
+ if ( iValue2 != -1 )
+ {
+ iValue += iValue2;
+ pchDecodeDest[ iDestPos++ ] = (char)iValue;
+ bValid = true;
+ }
+ }
+
+ if ( !bValid )
+ {
+ pchDecodeDest[ iDestPos++ ] = '%';
+ pchDecodeDest[ iDestPos++ ] = cHexDigit1;
+ pchDecodeDest[ iDestPos++ ] = cHexDigit2;
+ }
+ }
+
+ // Skip ahead
+ i += 2;
+ }
+ else
+ {
+ pchDecodeDest[ iDestPos++ ] = pchEncodedSource[i];
+ }
+ }
+
+ // We may not have extra room to NULL terminate, since this can be used on raw data, but if we do
+ // go ahead and do it as this can avoid bugs.
+ if ( iDestPos < nDecodeDestLen )
+ {
+ pchDecodeDest[iDestPos] = 0;
+ }
+
+ return (size_t)iDestPos;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
+// This version of the call isn't a strict RFC implementation, but uses + for space as is
+// the standard in HTML form encoding, despite it not being part of the RFC.
+//
+// Dest buffer should be at least as large as source buffer to guarantee room for decode.
+//-----------------------------------------------------------------------------
+void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen )
+{
+ return V_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, true );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
+// This version of the call isn't a strict RFC implementation, but uses + for space as is
+// the standard in HTML form encoding, despite it not being part of the RFC.
+//
+// Dest buffer should be at least as large as source buffer to guarantee room for decode.
+// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
+//-----------------------------------------------------------------------------
+size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen )
+{
+ return V_URLDecodeInternal( pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, true );
+}
+
+//-----------------------------------------------------------------------------
+void V_StripExtension( std::string &in )
+{
+ // Find the last dot. If it's followed by a dot or a slash, then it's part of a
+ // directory specifier like ../../somedir/./blah.
+ std::string::size_type test = in.rfind( '.' );
+ if ( test != std::string::npos )
+ {
+ // This handles things like ".\blah" or "c:\my@email.com\abc\def\geh"
+ // Which would otherwise wind up with "" and "c:\my@email", respectively.
+ if ( in.rfind( '\\' ) < test && in.rfind( '/' ) < test )
+ {
+ in.resize( test );
+ }
+ }
+}
+
« no previous file with comments | « third_party/openvr/src/src/vrcommon/strtools_public.h ('k') | third_party/openvr/src/src/vrcommon/vrpathregistry_public.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698