// Mozilla: see mozilla.patch for more details
std::wstring UTF8to16(constchar * in)
{ int retLength = ::MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0); if (retLength == 0)
{ return std::wstring();
}
wchar_t* retString = newwchar_t[retLength];
::MultiByteToWideChar(CP_UTF8, 0, in, -1, retString, retLength);
std::wstring retStringValue(retString);
delete[] retString;
return retStringValue;
//static std::wstring_convert< convert_type, wchar_t > s_converter; // construction of this can be expensive (or even serialized) depending on locale
/** Returns a std::string from a uint64_t */ // Mozilla: see mozilla.patch for more details // 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';
//----------------------------------------------------------------------------- // Purpose: These define the set of characters to filter for components (which // need all the escaping we can muster) vs. paths (which don't want // / and : escaped so we don't break less compliant URL handling code. //----------------------------------------------------------------------------- staticbool CharNeedsEscape_Component( constchar c )
{ return (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9')
&& c != '-' && c != '_' && c != '.');
} staticbool CharNeedsEscape_FullPath( constchar c )
{ return (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9')
&& c != '-' && c != '_' && c != '.' && c != '/' && c != ':' );
}
//----------------------------------------------------------------------------- // 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, constchar *pchSource, int nSourceLen, bool bUsePlusForSpace, std::function< bool(constchar)> fnNeedsEscape )
{ //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 ( fnNeedsEscape( 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, constchar *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++ ] = ' ';
} elseif ( 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;
}
}
// 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, constchar *pchSource, int nSourceLen )
{ return V_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, true, CharNeedsEscape_Component );
}
//----------------------------------------------------------------------------- // 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, constchar *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 );
}
}
}
//----------------------------------------------------------------------------- // Purpose: Tokenizes a string into a vector of strings //-----------------------------------------------------------------------------
std::vector<std::string> TokenizeString( const std::string & sString, char cToken )
{
std::vector<std::string> vecStrings;
std::istringstream stream( sString );
std::string s; while ( std::getline( stream, s, cToken ) )
{
vecStrings.push_back( s );
} return vecStrings;
}
// Mozilla: see mozilla.patch for more details //----------------------------------------------------------------------------- // Purpose: Repairs a should-be-UTF-8 string to a for-sure-is-UTF-8 string, plus return boolean if we subbed in '?' somewhere //----------------------------------------------------------------------------- // bool RepairUTF8( const char *pbegin, const char *pend, std::string & sOutputUtf8 ) // { // typedef std::codecvt_utf8<char32_t> facet_type; // facet_type myfacet;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.