1 /* 2 * ReactOS test program - 3 * 4 * _tfileio.c 5 * 6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 #define WIN32_LEAN_AND_MEAN 24 #include <windows.h> 25 #include <tchar.h> 26 #include <wchar.h> 27 #include <stdio.h> 28 29 30 #ifdef UNICODE 31 #define _tfopen _wfopen 32 #define _tunlink _wunlink 33 #define _TEOF WEOF 34 #define _gettchar getwchar 35 #define _puttchar putwchar 36 #define _THEX_FORMAT _T("0x%04x ") 37 #else /*UNICODE*/ 38 #define _tfopen fopen 39 #define _tunlink _unlink 40 #define _TEOF EOF 41 #define _gettchar getchar 42 #define _puttchar putchar 43 #define _THEX_FORMAT "0x%02x " 44 #endif /*UNICODE*/ 45 46 47 #define TEST_BUFFER_SIZE 200 48 #define TEST_FILE_LINES 4 49 50 extern BOOL verbose_flagged; 51 extern BOOL status_flagged; 52 53 static TCHAR test_buffer[TEST_BUFFER_SIZE]; 54 55 static TCHAR dos_data[] = _T("line1: this is a bunch of readable text.\r\n")\ 56 _T("line2: some more printable text and punctuation !@#$%^&*()\r\n")\ 57 _T("line3: followed up with some numerals 1234567890\r\n")\ 58 _T("line4: done.\r\n"); 59 60 static TCHAR nix_data[] = _T("line1: this is a bunch of readable text.\n")\ 61 _T("line2: some more printable text and punctuation !@#$%^&*()\n")\ 62 _T("line3: followed up with some numerals 1234567890\n")\ 63 _T("line4: done.\n"); 64 65 #ifdef UNICODE 66 #define TEST_B1_FILE_SIZE ((((sizeof(dos_data)/2)-1)+TEST_FILE_LINES)/2) // (166+4)/2=85 67 #define TEST_B2_FILE_SIZE (((sizeof(dos_data)/2)-1)*2) // (166*2) =332 68 #define TEST_B3_FILE_SIZE ((((sizeof(nix_data)/2)-1)+TEST_FILE_LINES)/2) // (162+4)/2=83 69 #define TEST_B4_FILE_SIZE (((sizeof(nix_data)/2)-1)*2) // (162*2) =324 70 #else /*UNICODE*/ 71 #define TEST_B1_FILE_SIZE (sizeof(dos_data)-1+TEST_FILE_LINES) // (166+4)=170 72 #define TEST_B2_FILE_SIZE (sizeof(dos_data)-1-TEST_FILE_LINES) // (166-4)=162 73 #define TEST_B3_FILE_SIZE (sizeof(nix_data)-1+TEST_FILE_LINES) // (162+4)=166 74 #define TEST_B4_FILE_SIZE (sizeof(nix_data)-1) // (162) =162 75 #endif /*UNICODE*/ 76 77 78 // result = create_test_file(file_name, _T("wb"), _T("rb"), file_data); 79 80 static BOOL test_file_truncate(TCHAR* file_name) 81 { 82 BOOL result = FALSE; 83 int count = -1; 84 int error_code; 85 TCHAR ch; 86 TCHAR* file_data = _T("this file should have been truncated to zero bytes..."); 87 FILE *file = _tfopen(file_name, _T("wb")); 88 89 if (verbose_flagged) { 90 _tprintf(_T("test_file_truncate(\"%s\")\n"), file_name); 91 } 92 93 if (file != NULL) { 94 if (_fputts(file_data, file) != _TEOF) { 95 } else { 96 _tprintf(_T("ERROR: failed to write data to file \"%s\"\n"), file_name); 97 _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); 98 } 99 fclose(file); 100 } else { 101 _tprintf(_T("ERROR: failed to open/create file \"%s\" for output\n"), file_name); 102 _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); 103 } 104 105 file = _tfopen(file_name, _T("wb")); 106 if (file != NULL) { 107 error_code = ferror(file); 108 if (error_code) { 109 _tprintf(_T("ERROR: (%s) ferror returned %d\n"), file_name, error_code); 110 } 111 fclose(file); 112 } else { 113 _tprintf(_T("ERROR: (%s) failed to open file for truncating\n"), file_name); 114 } 115 116 file = _tfopen(file_name, _T("rb")); 117 if (file != NULL) { 118 count = 0; 119 while ((ch = _fgettc(file)) != _TEOF) { 120 if (verbose_flagged) { 121 _tprintf(_THEX_FORMAT, ch); 122 } 123 ++count; 124 } 125 error_code = ferror(file); 126 if (error_code) { 127 _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code); 128 perror("Read error"); 129 } 130 fclose(file); 131 } else { 132 _tprintf(_T("ERROR: (%s) failed to open file for reading\n"), file_name); 133 } 134 if (count) { 135 result = TRUE; 136 } 137 return result; 138 } 139 140 static BOOL create_output_file(TCHAR* file_name, TCHAR* file_mode, TCHAR* file_data) 141 { 142 BOOL result = FALSE; 143 FILE *file = _tfopen(file_name, file_mode); 144 if (file != NULL) { 145 if (_fputts(file_data, file) != _TEOF) { 146 result = TRUE; 147 } else { 148 _tprintf(_T("ERROR: failed to write data to file \"%s\"\n"), file_name); 149 _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); 150 } 151 fclose(file); 152 } else { 153 _tprintf(_T("ERROR: failed to open/create file \"%s\" for output\n"), file_name); 154 _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); 155 } 156 return result; 157 } 158 159 static BOOL verify_output_file(TCHAR* file_name, TCHAR* file_mode, TCHAR* file_data) 160 { 161 int error_code; 162 int offset = 0; 163 int line_num = 0; 164 BOOL result = FALSE; 165 BOOL error_flagged = FALSE; 166 FILE* file = _tfopen(file_name, file_mode); 167 if (file == NULL) { 168 _tprintf(_T("ERROR: (%s) Can't open file for reading\n"), file_name); 169 _tprintf(_T("ERROR: ferror returned %d\n"), ferror(file)); 170 return FALSE; 171 } else if (status_flagged) { 172 _tprintf(_T("STATUS: (%s) opened file for reading\n"), file_name); 173 } 174 while (_fgetts(test_buffer, TEST_BUFFER_SIZE, file)) { 175 int length = _tcslen(test_buffer); 176 int req_len = _tcschr(file_data+offset, _T('\n')) - (file_data+offset) + 1; 177 178 ++line_num; 179 if (length > req_len) { 180 _tprintf(_T("ERROR: read excess bytes from line %d, length %d, but expected %d\n"), line_num, length, req_len); 181 error_flagged = TRUE; 182 break; 183 } 184 if (length < req_len) { 185 _tprintf(_T("ERROR: read to few bytes from line %d, length %d, but expected %d\n"), line_num, length, req_len); 186 error_flagged = TRUE; 187 break; 188 } 189 if (status_flagged) { 190 _tprintf(_T("STATUS: Verifying %d bytes read from line %d\n"), length, line_num); 191 } 192 if (_tcsncmp(test_buffer, file_data+offset, length - 1) == 0) { 193 result = TRUE; 194 } else { 195 if (status_flagged) { 196 int i; 197 _tprintf(_T("WARNING: (%s) failed to verify file\n"), file_name); 198 for (i = 0; i < length; i++) { 199 if (file_data[offset+i] != test_buffer[i]) { 200 _tprintf(_T("line %d, offset %d expected: 0x%04x found: 0x%04x\n"), line_num, i, (int)file_data[offset+i], (int)test_buffer[i]); 201 } 202 } 203 _tprintf(_T("\n")); 204 } else { 205 error_flagged = TRUE; 206 } 207 } 208 offset += length; 209 } 210 error_code = ferror(file); 211 if (error_code) { 212 _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code); 213 perror("Read error"); 214 } 215 if (!line_num) { 216 _tprintf(_T("ERROR: (%s) failed to read from file\n"), file_name); 217 } 218 if (error_flagged == TRUE) { 219 _tprintf(_T("ERROR: (%s) failed to verify file\n"), file_name); 220 result = FALSE; 221 } 222 fclose(file); 223 return result; 224 } 225 226 static int create_test_file(TCHAR* file_name, TCHAR* write_mode, TCHAR* read_mode, TCHAR* file_data) 227 { 228 if (status_flagged) { 229 _tprintf(_T("STATUS: Attempting to create output file %s\n"), file_name); 230 } 231 if (create_output_file(file_name, write_mode, file_data)) { 232 if (status_flagged) { 233 _tprintf(_T("STATUS: Attempting to verify output file %s\n"), file_name); 234 } 235 if (verify_output_file(file_name, read_mode, file_data)) { 236 if (status_flagged) { 237 _tprintf(_T("SUCCESS: %s verified ok\n"), file_name); 238 } 239 } else { 240 //_tprintf(_T("ERROR: failed to verify file %s\n"), file_name); 241 return 2; 242 } 243 } else { 244 _tprintf(_T("ERROR: failed to create file %s\n"), file_name); 245 return 1; 246 } 247 return 0; 248 } 249 250 static int check_file_size(TCHAR* file_name, TCHAR* file_mode, int expected) 251 { 252 int count = 0; 253 FILE* file; 254 TCHAR ch; 255 int error_code; 256 257 if (status_flagged) { 258 //_tprintf(_T("STATUS: (%s) checking for %d bytes in %s mode\n"), file_name, expected, _tcschr(file_mode, _T('b')) ? _T("binary") : _T("text")); 259 _tprintf(_T("STATUS: (%s) checking for %d bytes with mode %s\n"), file_name, expected, file_mode); 260 } 261 file = _tfopen(file_name, file_mode); 262 if (file == NULL) { 263 _tprintf(_T("ERROR: (%s) failed to open file for reading\n"), file_name); 264 return 1; 265 } 266 while ((ch = _fgettc(file)) != _TEOF) { 267 if (verbose_flagged) { 268 _tprintf(_THEX_FORMAT, ch); 269 } 270 ++count; 271 } 272 error_code = ferror(file); 273 if (error_code) { 274 _tprintf(_T("ERROR: (%s) ferror returned %d after reading\n"), file_name, error_code); 275 perror("Read error"); 276 } 277 278 if (verbose_flagged) { 279 // _puttc(_T('\n'), stdout); 280 } 281 fclose(file); 282 if (count == expected) { 283 if (status_flagged) { 284 _tprintf(_T("PASSED: (%s) read %d bytes\n"), file_name, count); 285 } 286 } else { 287 _tprintf(_T("FAILED: (%s) read %d bytes but expected %d using mode \"%s\"\n"), file_name, count, expected, file_mode); 288 } 289 return (count == expected) ? 0 : -1; 290 } 291 292 static int test_console_io(void) 293 { 294 TCHAR buffer[81]; 295 TCHAR ch; 296 int i, j; 297 298 _tprintf(_T("Enter a line for echoing:\n")); 299 300 //for (i = 0; (i < 80) && ((ch = _gettchar()) != _TEOF) && (ch != _T('\n')); i++) { 301 for (i = 0; (i < 80) && ((ch = _gettc(stdin)) != _TEOF) && (ch != _T('\n')); i++) { 302 buffer[i] = (TCHAR)ch; 303 } 304 buffer[i] = _T('\0'); 305 for (j = 0; j < i; j++) { 306 _puttc(buffer[j], stdout); 307 } 308 _puttc(_T('\n'), stdout); 309 _tprintf(_T("%s\n"), buffer); 310 return 0; 311 } 312 313 static int test_console_getchar(void) 314 { 315 int result = 0; 316 TCHAR ch; 317 318 _tprintf(_T("Enter lines for dumping or <ctrl-z><nl> to finish:\n")); 319 320 //while ((ch = _gettchar()) != _TEOF) { 321 while ((ch = _gettc(stdin)) != _TEOF) { 322 _tprintf(_THEX_FORMAT, ch); 323 //printf("0x%04x ", ch); 324 } 325 return result; 326 } 327 328 static int test_console_putch(void) 329 { 330 int result = 0; 331 332 _putch('1'); 333 _putch('@'); 334 _putch('3'); 335 _putch(':'); 336 _putch('\n'); 337 _putch('a'); 338 _putch('B'); 339 _putch('c'); 340 _putch(':'); 341 _putch('\n'); 342 return result; 343 } 344 345 static int test_unlink_files(void) 346 { 347 int result = 0; 348 349 //printf("sizeof dos_data: %d\n", sizeof(dos_data)); 350 //printf("sizeof nix_data: %d\n", sizeof(nix_data)); 351 352 result |= _tunlink(_T("binary.dos")); 353 result |= _tunlink(_T("binary.nix")); 354 result |= _tunlink(_T("text.dos")); 355 result |= _tunlink(_T("text.nix")); 356 return result; 357 } 358 359 static int test_text_fileio(TCHAR* file_name, TCHAR* file_data, int tsize, int bsize) 360 { 361 int result = 0; 362 363 result = create_test_file(file_name, _T("w"), _T("r"), file_data); 364 result = check_file_size(file_name, _T("r"), tsize); 365 result = check_file_size(file_name, _T("rb"), bsize); 366 return result; 367 } 368 369 static int test_binary_fileio(TCHAR* file_name, TCHAR* file_data, int tsize, int bsize) 370 { 371 int result = 0; 372 373 result = create_test_file(file_name, _T("wb"), _T("rb"), file_data); 374 result = check_file_size(file_name, _T("r"), tsize); 375 result = check_file_size(file_name, _T("rb"), bsize); 376 return result; 377 } 378 379 static int test_files(int test_num, char* type) 380 { 381 int result = 0; 382 383 printf("performing test: %d (%s)\n", test_num, type); 384 385 386 if (test_file_truncate(_T("zerosize.foo"))) { 387 printf("System unable to truncate files yet, unlinking:\n"); 388 test_unlink_files(); 389 } 390 391 switch (test_num) { 392 case 1: 393 result = test_text_fileio(_T("text.dos"), dos_data, 166, TEST_B1_FILE_SIZE); 394 break; 395 case 2: 396 result = test_binary_fileio(_T("binary.dos"), dos_data, TEST_B2_FILE_SIZE, 166); 397 break; 398 case 3: 399 result = test_text_fileio(_T("text.nix"), nix_data, 162, TEST_B3_FILE_SIZE); 400 break; 401 case 4: 402 result = test_binary_fileio(_T("binary.nix"), nix_data, TEST_B4_FILE_SIZE, 162); 403 break; 404 case 5: 405 result = test_console_io(); 406 break; 407 case 6: 408 result = test_console_getchar(); 409 break; 410 case 7: 411 result = test_console_putch(); 412 break; 413 case -1: 414 result = test_unlink_files(); 415 break; 416 default: 417 _tprintf(_T("no test number selected\n")); 418 break; 419 } 420 return result; 421 } 422