2009-03-21 01:39:04 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Automatic Testing Utility
|
2017-09-29 18:13:54 +00:00
|
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
2009-03-21 01:39:04 +00:00
|
|
|
* PURPOSE: Various helper functions
|
2017-09-29 18:13:54 +00:00
|
|
|
* COPYRIGHT: Copyright 2008-2015 Colin Finck (colin@reactos.org)
|
2009-03-21 01:39:04 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
2015-06-23 09:54:46 +00:00
|
|
|
#define DBGPRINT_BUFSIZE 511
|
2009-03-21 01:39:04 +00:00
|
|
|
static const char HexCharacters[] = "0123456789ABCDEF";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Escapes a string according to RFC 1738.
|
|
|
|
* Required for passing parameters to the web service.
|
|
|
|
*
|
|
|
|
* @param Input
|
|
|
|
* Constant pointer to a char array, which contains the input buffer to escape.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* The escaped string as std::string.
|
|
|
|
*/
|
|
|
|
string
|
|
|
|
EscapeString(const char* Input)
|
|
|
|
{
|
|
|
|
string ReturnedString;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if(strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~", *Input))
|
|
|
|
{
|
|
|
|
/* It's a character we don't need to escape, just add it to the output string */
|
|
|
|
ReturnedString += *Input;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We need to escape this character */
|
|
|
|
ReturnedString += '%';
|
|
|
|
ReturnedString += HexCharacters[((UCHAR)*Input >> 4) % 16];
|
|
|
|
ReturnedString += HexCharacters[(UCHAR)*Input % 16];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while(*++Input);
|
|
|
|
|
|
|
|
return ReturnedString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Escapes a string according to RFC 1738.
|
|
|
|
* Required for passing parameters to the web service.
|
|
|
|
*
|
|
|
|
* @param Input
|
|
|
|
* Pointer to a std::string, which contains the input buffer to escape.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* The escaped string as std::string.
|
|
|
|
*/
|
|
|
|
string
|
|
|
|
EscapeString(const string& Input)
|
|
|
|
{
|
|
|
|
return EscapeString(Input.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines whether a string contains entirely numeric values.
|
|
|
|
*
|
|
|
|
* @param Input
|
|
|
|
* Constant pointer to a char array containing the input to check.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* true if the string is entirely numeric, false otherwise.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
IsNumber(const char* Input)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if(!isdigit(*Input))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
++Input;
|
|
|
|
}
|
|
|
|
while(*Input);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Outputs a string through the standard output and the debug output.
|
2015-06-23 09:54:46 +00:00
|
|
|
* The string may have LF or CRLF line endings.
|
2009-03-21 01:39:04 +00:00
|
|
|
*
|
2015-06-23 09:54:46 +00:00
|
|
|
* @param String
|
2009-03-21 01:39:04 +00:00
|
|
|
* The std::string to output
|
|
|
|
*/
|
2015-06-23 09:54:46 +00:00
|
|
|
string
|
|
|
|
StringOut(const string& String, bool forcePrint)
|
2009-03-21 01:39:04 +00:00
|
|
|
{
|
2015-06-23 09:54:46 +00:00
|
|
|
char DbgString[DBGPRINT_BUFSIZE + 1];
|
|
|
|
size_t i, start = 0, last_newline = 0, size = 0, curr_pos = 0;
|
|
|
|
string NewString;
|
2009-03-21 01:39:04 +00:00
|
|
|
|
|
|
|
/* Unify the line endings (the piped output of the tests may use CRLF) */
|
2015-06-23 09:54:46 +00:00
|
|
|
for(i = 0; i < String.size(); i++)
|
2009-03-21 01:39:04 +00:00
|
|
|
{
|
|
|
|
/* If this is a CRLF line-ending, only copy a \n to the new string and skip the next character */
|
2015-06-23 09:54:46 +00:00
|
|
|
if(String[i] == '\r' && String[i + 1] == '\n')
|
2009-03-21 01:39:04 +00:00
|
|
|
{
|
2015-06-23 09:54:46 +00:00
|
|
|
NewString += '\n';
|
|
|
|
++i;
|
2009-03-21 01:39:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-06-23 09:54:46 +00:00
|
|
|
/* Otherwise copy the string */
|
|
|
|
NewString += String[i];
|
2009-03-21 01:39:04 +00:00
|
|
|
}
|
|
|
|
|
2015-06-23 09:54:46 +00:00
|
|
|
curr_pos = NewString.size();
|
|
|
|
|
|
|
|
/* Try to print whole lines but obey the 512 bytes chunk size limit*/
|
|
|
|
if(NewString[curr_pos - 1] == '\n' || (curr_pos - start) == DBGPRINT_BUFSIZE)
|
|
|
|
{
|
|
|
|
if((curr_pos - start) >= DBGPRINT_BUFSIZE)
|
|
|
|
{
|
|
|
|
/* No newlines so far, or the string just fits */
|
|
|
|
if(last_newline <= start || ((curr_pos - start == DBGPRINT_BUFSIZE) && NewString[curr_pos - 1] == '\n'))
|
|
|
|
{
|
|
|
|
size = curr_pos - start;
|
|
|
|
memcpy(DbgString, NewString.c_str() + start, size);
|
|
|
|
start = curr_pos;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size = last_newline - start;
|
|
|
|
memcpy(DbgString, NewString.c_str() + start, size);
|
|
|
|
start = last_newline;
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgString[size] = 0;
|
2015-06-23 10:06:38 +00:00
|
|
|
DbgPrint("%s", DbgString);
|
2015-06-23 09:54:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
last_newline = curr_pos;
|
|
|
|
}
|
2012-02-15 21:18:13 +00:00
|
|
|
}
|
2009-03-21 01:39:04 +00:00
|
|
|
|
2015-06-23 09:54:46 +00:00
|
|
|
size = curr_pos - start;
|
|
|
|
|
|
|
|
/* Only print if forced to or if the rest is a whole line */
|
|
|
|
if(forcePrint == true || NewString[curr_pos - 1] == '\n')
|
|
|
|
{
|
|
|
|
/* Output the whole string */
|
|
|
|
if(Configuration.DoPrint())
|
2015-06-23 10:06:38 +00:00
|
|
|
cout << NewString << flush;
|
2015-06-23 09:54:46 +00:00
|
|
|
|
|
|
|
memcpy(DbgString, NewString.c_str() + start, size);
|
|
|
|
DbgString[size] = 0;
|
2015-06-23 10:06:38 +00:00
|
|
|
DbgPrint("%s", DbgString);
|
2015-06-23 09:54:46 +00:00
|
|
|
|
|
|
|
NewString.clear();
|
|
|
|
return NewString;
|
|
|
|
}
|
2012-02-17 12:31:32 +00:00
|
|
|
|
2015-06-23 09:54:46 +00:00
|
|
|
/* Output full lines only */
|
|
|
|
if(Configuration.DoPrint())
|
2015-06-23 10:06:38 +00:00
|
|
|
cout << NewString.substr(0, start) << flush;
|
2014-10-11 14:34:56 +00:00
|
|
|
|
2015-06-23 09:54:46 +00:00
|
|
|
/* Return the remaining chunk */
|
|
|
|
return NewString.substr(start, size);
|
2009-03-21 01:39:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a value from a specified INI file and returns it converted to ASCII.
|
|
|
|
*
|
|
|
|
* @param AppName
|
|
|
|
* Constant pointer to a WCHAR array with the INI section to look in (lpAppName parameter passed to GetPrivateProfileStringW)
|
|
|
|
*
|
|
|
|
* @param KeyName
|
|
|
|
* Constant pointer to a WCHAR array containing the key to look for in the specified section (lpKeyName parameter passed to GetPrivateProfileStringW)
|
|
|
|
*
|
|
|
|
* @param FileName
|
|
|
|
* Constant pointer to a WCHAR array containing the path to the INI file
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* Returns the data of the value as std::string or an empty string if no data could be retrieved.
|
|
|
|
*/
|
|
|
|
string
|
|
|
|
GetINIValue(PCWCH AppName, PCWCH KeyName, PCWCH FileName)
|
|
|
|
{
|
|
|
|
DWORD Length;
|
|
|
|
PCHAR AsciiBuffer;
|
|
|
|
string ReturnedString;
|
|
|
|
WCHAR Buffer[2048];
|
|
|
|
|
|
|
|
/* Load the value into a temporary Unicode buffer */
|
|
|
|
Length = GetPrivateProfileStringW(AppName, KeyName, NULL, Buffer, sizeof(Buffer) / sizeof(WCHAR), FileName);
|
|
|
|
|
|
|
|
if(Length)
|
|
|
|
{
|
|
|
|
/* Convert the string to ASCII charset */
|
|
|
|
AsciiBuffer = new char[Length + 1];
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, Buffer, Length + 1, AsciiBuffer, Length + 1, NULL, NULL);
|
|
|
|
|
|
|
|
ReturnedString = AsciiBuffer;
|
2014-04-05 21:56:15 +00:00
|
|
|
delete[] AsciiBuffer;
|
2009-03-21 01:39:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ReturnedString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts an ASCII string to a Unicode one.
|
|
|
|
*
|
|
|
|
* @param AsciiString
|
|
|
|
* Constant pointer to a char array containing the ASCII string
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* The Unicode string as std::wstring
|
|
|
|
*/
|
|
|
|
wstring
|
|
|
|
AsciiToUnicode(const char* AsciiString)
|
|
|
|
{
|
|
|
|
DWORD Length;
|
|
|
|
PWSTR UnicodeString;
|
|
|
|
wstring ReturnString;
|
|
|
|
|
|
|
|
Length = MultiByteToWideChar(CP_ACP, 0, AsciiString, -1, NULL, 0);
|
|
|
|
|
|
|
|
UnicodeString = new WCHAR[Length];
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, AsciiString, -1, UnicodeString, Length);
|
|
|
|
ReturnString = UnicodeString;
|
|
|
|
delete UnicodeString;
|
|
|
|
|
|
|
|
return ReturnString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts an ASCII string to a Unicode one.
|
|
|
|
*
|
|
|
|
* @param AsciiString
|
|
|
|
* Pointer to a std::string containing the ASCII string
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* The Unicode string as std::wstring
|
|
|
|
*/
|
|
|
|
wstring
|
|
|
|
AsciiToUnicode(const string& AsciiString)
|
|
|
|
{
|
|
|
|
return AsciiToUnicode(AsciiString.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts a Unicode string to an ASCII one.
|
|
|
|
*
|
|
|
|
* @param UnicodeString
|
|
|
|
* Constant pointer to a WCHAR array containing the Unicode string
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* The ASCII string as std::string
|
|
|
|
*/
|
|
|
|
string
|
|
|
|
UnicodeToAscii(PCWSTR UnicodeString)
|
|
|
|
{
|
|
|
|
DWORD Length;
|
|
|
|
PCHAR AsciiString;
|
|
|
|
string ReturnString;
|
|
|
|
|
|
|
|
Length = WideCharToMultiByte(CP_ACP, 0, UnicodeString, -1, NULL, 0, NULL, NULL);
|
|
|
|
|
|
|
|
AsciiString = new char[Length];
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, UnicodeString, -1, AsciiString, Length, NULL, NULL);
|
|
|
|
ReturnString = AsciiString;
|
|
|
|
delete AsciiString;
|
|
|
|
|
|
|
|
return ReturnString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts a Unicode string to an ASCII one.
|
|
|
|
*
|
|
|
|
* @param UnicodeString
|
|
|
|
* Pointer to a std::wstring containing the Unicode string
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* The ASCII string as std::string
|
|
|
|
*/
|
|
|
|
string
|
|
|
|
UnicodeToAscii(const wstring& UnicodeString)
|
|
|
|
{
|
|
|
|
return UnicodeToAscii(UnicodeString.c_str());
|
|
|
|
}
|