mirror of
https://github.com/reactos/reactos.git
synced 2024-11-07 15:10:53 +00:00
04135b7ce4
If the last chunk of the string sent to StringOut isn't a whole line and forcePrint is set to false, send back what's left after processing. The caller is then responsible for prepending that string next time it calls StringOut. Should fix the rest of debug log corruptions. svn path=/trunk/; revision=55670
285 lines
7.2 KiB
C++
285 lines
7.2 KiB
C++
/*
|
|
* PROJECT: ReactOS Automatic Testing Utility
|
|
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
|
* PURPOSE: Various helper functions
|
|
* COPYRIGHT: Copyright 2008-2009 Colin Finck <colin@reactos.org>
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
#define DBGPRINT_BUFSIZE 511
|
|
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.
|
|
* The string may have LF or CRLF line endings.
|
|
*
|
|
* @param String
|
|
* The std::string to output
|
|
*/
|
|
string
|
|
StringOut(const string& String, const BOOL forcePrint)
|
|
{
|
|
char DbgString[DBGPRINT_BUFSIZE + 1];
|
|
size_t i, start = 0, last_newline = 0, size = 0, curr_pos = 0;
|
|
string NewString;
|
|
|
|
/* Unify the line endings (the piped output of the tests may use CRLF) */
|
|
for(i = 0; i < String.size(); i++)
|
|
{
|
|
/* If this is a CRLF line-ending, only copy a \n to the new string and skip the next character */
|
|
if(String[i] == '\r' && String[i + 1] == '\n')
|
|
{
|
|
NewString += '\n';
|
|
++i;
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise copy the string */
|
|
NewString += String[i];
|
|
}
|
|
|
|
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;
|
|
DbgPrint(DbgString);
|
|
}
|
|
|
|
last_newline = curr_pos;
|
|
}
|
|
}
|
|
|
|
/* Output the string */
|
|
cout << NewString;
|
|
|
|
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')
|
|
{
|
|
memcpy(DbgString, NewString.c_str() + start, size);
|
|
DbgString[size] = 0;
|
|
DbgPrint(DbgString);
|
|
|
|
NewString.clear();
|
|
return NewString;
|
|
}
|
|
|
|
/* Return the remaining chunk */
|
|
return NewString.substr(start, size);
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
delete AsciiBuffer;
|
|
}
|
|
|
|
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());
|
|
}
|