[KMTESTS:CC]
[reactos.git] / rostests / rosautotest / tools.cpp
1 /*
2 * PROJECT: ReactOS Automatic Testing Utility
3 * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
4 * PURPOSE: Various helper functions
5 * COPYRIGHT: Copyright 2008-2015 Colin Finck <colin@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 #define DBGPRINT_BUFSIZE 511
11 static const char HexCharacters[] = "0123456789ABCDEF";
12
13 /**
14 * Escapes a string according to RFC 1738.
15 * Required for passing parameters to the web service.
16 *
17 * @param Input
18 * Constant pointer to a char array, which contains the input buffer to escape.
19 *
20 * @return
21 * The escaped string as std::string.
22 */
23 string
24 EscapeString(const char* Input)
25 {
26 string ReturnedString;
27
28 do
29 {
30 if(strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~", *Input))
31 {
32 /* It's a character we don't need to escape, just add it to the output string */
33 ReturnedString += *Input;
34 }
35 else
36 {
37 /* We need to escape this character */
38 ReturnedString += '%';
39 ReturnedString += HexCharacters[((UCHAR)*Input >> 4) % 16];
40 ReturnedString += HexCharacters[(UCHAR)*Input % 16];
41 }
42 }
43 while(*++Input);
44
45 return ReturnedString;
46 }
47
48 /**
49 * Escapes a string according to RFC 1738.
50 * Required for passing parameters to the web service.
51 *
52 * @param Input
53 * Pointer to a std::string, which contains the input buffer to escape.
54 *
55 * @return
56 * The escaped string as std::string.
57 */
58 string
59 EscapeString(const string& Input)
60 {
61 return EscapeString(Input.c_str());
62 }
63
64 /**
65 * Determines whether a string contains entirely numeric values.
66 *
67 * @param Input
68 * Constant pointer to a char array containing the input to check.
69 *
70 * @return
71 * true if the string is entirely numeric, false otherwise.
72 */
73 bool
74 IsNumber(const char* Input)
75 {
76 do
77 {
78 if(!isdigit(*Input))
79 return false;
80
81 ++Input;
82 }
83 while(*Input);
84
85 return true;
86 }
87
88 /**
89 * Outputs a string through the standard output and the debug output.
90 * The string may have LF or CRLF line endings.
91 *
92 * @param String
93 * The std::string to output
94 */
95 string
96 StringOut(const string& String, bool forcePrint)
97 {
98 char DbgString[DBGPRINT_BUFSIZE + 1];
99 size_t i, start = 0, last_newline = 0, size = 0, curr_pos = 0;
100 string NewString;
101
102 /* Unify the line endings (the piped output of the tests may use CRLF) */
103 for(i = 0; i < String.size(); i++)
104 {
105 /* If this is a CRLF line-ending, only copy a \n to the new string and skip the next character */
106 if(String[i] == '\r' && String[i + 1] == '\n')
107 {
108 NewString += '\n';
109 ++i;
110 }
111 else
112 {
113 /* Otherwise copy the string */
114 NewString += String[i];
115 }
116
117 curr_pos = NewString.size();
118
119 /* Try to print whole lines but obey the 512 bytes chunk size limit*/
120 if(NewString[curr_pos - 1] == '\n' || (curr_pos - start) == DBGPRINT_BUFSIZE)
121 {
122 if((curr_pos - start) >= DBGPRINT_BUFSIZE)
123 {
124 /* No newlines so far, or the string just fits */
125 if(last_newline <= start || ((curr_pos - start == DBGPRINT_BUFSIZE) && NewString[curr_pos - 1] == '\n'))
126 {
127 size = curr_pos - start;
128 memcpy(DbgString, NewString.c_str() + start, size);
129 start = curr_pos;
130 }
131 else
132 {
133 size = last_newline - start;
134 memcpy(DbgString, NewString.c_str() + start, size);
135 start = last_newline;
136 }
137
138 DbgString[size] = 0;
139 DbgPrint("%s", DbgString);
140 }
141
142 last_newline = curr_pos;
143 }
144 }
145
146 size = curr_pos - start;
147
148 /* Only print if forced to or if the rest is a whole line */
149 if(forcePrint == true || NewString[curr_pos - 1] == '\n')
150 {
151 /* Output the whole string */
152 if(Configuration.DoPrint())
153 cout << NewString << flush;
154
155 memcpy(DbgString, NewString.c_str() + start, size);
156 DbgString[size] = 0;
157 DbgPrint("%s", DbgString);
158
159 NewString.clear();
160 return NewString;
161 }
162
163 /* Output full lines only */
164 if(Configuration.DoPrint())
165 cout << NewString.substr(0, start) << flush;
166
167 /* Return the remaining chunk */
168 return NewString.substr(start, size);
169 }
170
171 /**
172 * Gets a value from a specified INI file and returns it converted to ASCII.
173 *
174 * @param AppName
175 * Constant pointer to a WCHAR array with the INI section to look in (lpAppName parameter passed to GetPrivateProfileStringW)
176 *
177 * @param KeyName
178 * Constant pointer to a WCHAR array containing the key to look for in the specified section (lpKeyName parameter passed to GetPrivateProfileStringW)
179 *
180 * @param FileName
181 * Constant pointer to a WCHAR array containing the path to the INI file
182 *
183 * @return
184 * Returns the data of the value as std::string or an empty string if no data could be retrieved.
185 */
186 string
187 GetINIValue(PCWCH AppName, PCWCH KeyName, PCWCH FileName)
188 {
189 DWORD Length;
190 PCHAR AsciiBuffer;
191 string ReturnedString;
192 WCHAR Buffer[2048];
193
194 /* Load the value into a temporary Unicode buffer */
195 Length = GetPrivateProfileStringW(AppName, KeyName, NULL, Buffer, sizeof(Buffer) / sizeof(WCHAR), FileName);
196
197 if(Length)
198 {
199 /* Convert the string to ASCII charset */
200 AsciiBuffer = new char[Length + 1];
201 WideCharToMultiByte(CP_ACP, 0, Buffer, Length + 1, AsciiBuffer, Length + 1, NULL, NULL);
202
203 ReturnedString = AsciiBuffer;
204 delete[] AsciiBuffer;
205 }
206
207 return ReturnedString;
208 }
209
210 /**
211 * Converts an ASCII string to a Unicode one.
212 *
213 * @param AsciiString
214 * Constant pointer to a char array containing the ASCII string
215 *
216 * @return
217 * The Unicode string as std::wstring
218 */
219 wstring
220 AsciiToUnicode(const char* AsciiString)
221 {
222 DWORD Length;
223 PWSTR UnicodeString;
224 wstring ReturnString;
225
226 Length = MultiByteToWideChar(CP_ACP, 0, AsciiString, -1, NULL, 0);
227
228 UnicodeString = new WCHAR[Length];
229 MultiByteToWideChar(CP_ACP, 0, AsciiString, -1, UnicodeString, Length);
230 ReturnString = UnicodeString;
231 delete UnicodeString;
232
233 return ReturnString;
234 }
235
236 /**
237 * Converts an ASCII string to a Unicode one.
238 *
239 * @param AsciiString
240 * Pointer to a std::string containing the ASCII string
241 *
242 * @return
243 * The Unicode string as std::wstring
244 */
245 wstring
246 AsciiToUnicode(const string& AsciiString)
247 {
248 return AsciiToUnicode(AsciiString.c_str());
249 }
250
251 /**
252 * Converts a Unicode string to an ASCII one.
253 *
254 * @param UnicodeString
255 * Constant pointer to a WCHAR array containing the Unicode string
256 *
257 * @return
258 * The ASCII string as std::string
259 */
260 string
261 UnicodeToAscii(PCWSTR UnicodeString)
262 {
263 DWORD Length;
264 PCHAR AsciiString;
265 string ReturnString;
266
267 Length = WideCharToMultiByte(CP_ACP, 0, UnicodeString, -1, NULL, 0, NULL, NULL);
268
269 AsciiString = new char[Length];
270 WideCharToMultiByte(CP_ACP, 0, UnicodeString, -1, AsciiString, Length, NULL, NULL);
271 ReturnString = AsciiString;
272 delete AsciiString;
273
274 return ReturnString;
275 }
276
277 /**
278 * Converts a Unicode string to an ASCII one.
279 *
280 * @param UnicodeString
281 * Pointer to a std::wstring containing the Unicode string
282 *
283 * @return
284 * The ASCII string as std::string
285 */
286 string
287 UnicodeToAscii(const wstring& UnicodeString)
288 {
289 return UnicodeToAscii(UnicodeString.c_str());
290 }