1 /*---------------------------------------------------------------------------* 2 * PFile.c * 3 * * 4 * Copyright 2007, 2008 Nuance Communciations, Inc. * 5 * * 6 * Licensed under the Apache License, Version 2.0 (the 'License'); * 7 * you may not use this file except in compliance with the License. * 8 * * 9 * You may obtain a copy of the License at * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, software * 13 * distributed under the License is distributed on an 'AS IS' BASIS, * 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 * See the License for the specific language governing permissions and * 16 * limitations under the License. * 17 * * 18 *---------------------------------------------------------------------------*/ 19 20 #include "LCHAR.h" 21 #include "pendian.h" 22 #include "PFile.h" 23 #include "PFileSystem.h" 24 #include "plog.h" 25 #include "pstdio.h" 26 27 28 ESR_ReturnCode PFileDestroy(PFile* self) 29 { 30 if (self == NULL) 31 { 32 PLogError(L("ESR_INVALID_ARGUMENT")); 33 return ESR_INVALID_ARGUMENT; 34 } 35 return self->destroy(self); 36 } 37 38 ESR_ReturnCode PFileOpen(PFile* self, const LCHAR* mode) 39 { 40 if (self == NULL) 41 { 42 PLogError(L("ESR_INVALID_ARGUMENT")); 43 return ESR_INVALID_ARGUMENT; 44 } 45 return self->open(self, mode); 46 } 47 48 ESR_ReturnCode PFileClose(PFile* self) 49 { 50 if (self == NULL) 51 { 52 PLogError(L("ESR_INVALID_ARGUMENT")); 53 return ESR_INVALID_ARGUMENT; 54 } 55 return self->close(self); 56 } 57 58 ESR_ReturnCode PFileRead(PFile* self, void* buffer, size_t size, size_t* count) 59 { 60 if (self == NULL) 61 { 62 PLogError(L("ESR_INVALID_ARGUMENT")); 63 return ESR_INVALID_ARGUMENT; 64 } 65 return self->read(self, buffer, size, count); 66 } 67 68 ESR_ReturnCode PFileWrite(PFile* self, void* buffer, size_t size, size_t* count) 69 { 70 if (self == NULL) 71 { 72 PLogError(L("ESR_INVALID_ARGUMENT")); 73 return ESR_INVALID_ARGUMENT; 74 } 75 return self->write(self, buffer, size, count); 76 } 77 78 ESR_ReturnCode PFileFlush(PFile* self) 79 { 80 if (self == NULL) 81 { 82 PLogError(L("ESR_INVALID_ARGUMENT")); 83 return ESR_INVALID_ARGUMENT; 84 } 85 return self->flush(self); 86 } 87 88 ESR_ReturnCode PFileSeek(PFile* self, long offset, int origin) 89 { 90 if (self == NULL) 91 { 92 PLogError(L("ESR_INVALID_ARGUMENT")); 93 return ESR_INVALID_ARGUMENT; 94 } 95 return self->seek(self, offset, origin); 96 } 97 98 99 ESR_ReturnCode PFileGetPosition(PFile* self, size_t* position) 100 { 101 if (self == NULL) 102 { 103 PLogError(L("ESR_INVALID_ARGUMENT")); 104 return ESR_INVALID_ARGUMENT; 105 } 106 return self->getPosition(self, position); 107 } 108 109 ESR_ReturnCode PFileIsOpen(PFile* self, ESR_BOOL* isOpen) 110 { 111 if (self == NULL) 112 { 113 PLogError(L("ESR_INVALID_ARGUMENT")); 114 return ESR_INVALID_ARGUMENT; 115 } 116 return self->isOpen(self, isOpen); 117 } 118 119 ESR_ReturnCode PFileIsEOF(PFile* self, ESR_BOOL* isEof) 120 { 121 if (self == NULL) 122 { 123 PLogError(L("ESR_INVALID_ARGUMENT")); 124 return ESR_INVALID_ARGUMENT; 125 } 126 return self->isEOF(self, isEof); 127 } 128 129 ESR_ReturnCode PFileGetFilename(PFile* self, LCHAR* filename, size_t* len) 130 { 131 ESR_ReturnCode rc; 132 133 if (self == NULL) 134 { 135 PLogError(L("ESR_INVALID_ARGUMENT")); 136 return ESR_INVALID_ARGUMENT; 137 } 138 rc = self->getFilename(self, filename, len); 139 return rc; 140 } 141 142 ESR_ReturnCode PFileIsErrorSet(PFile* self, ESR_BOOL* isError) 143 { 144 if (self == NULL) 145 { 146 PLogError(L("ESR_INVALID_ARGUMENT")); 147 return ESR_INVALID_ARGUMENT; 148 } 149 return self->isErrorSet(self, isError); 150 } 151 152 ESR_ReturnCode PFileClearError(PFile* self) 153 { 154 if (self == NULL) 155 { 156 PLogError(L("ESR_INVALID_ARGUMENT")); 157 return ESR_INVALID_ARGUMENT; 158 } 159 return self->clearError(self); 160 } 161 162 ESR_ReturnCode PFileVfprintf(PFile* self, int* result, const LCHAR* format, va_list args) 163 { 164 ESR_ReturnCode rc; 165 166 if (self == NULL) 167 { 168 PLogError(L("ESR_INVALID_ARGUMENT")); 169 return ESR_INVALID_ARGUMENT; 170 } 171 rc = self->vfprintf(self, result, format, args); 172 return rc; 173 } 174 175 ESR_ReturnCode PFileFgetc(PFile* self, LINT* result) 176 { 177 if (self == NULL) 178 { 179 PLogError(L("ESR_INVALID_ARGUMENT")); 180 return ESR_INVALID_ARGUMENT; 181 } 182 return self->fgetc(self, result); 183 } 184 185 ESR_ReturnCode PFileFgets(PFile* self, LCHAR* string, int n, LCHAR** result) 186 { 187 if (self == NULL) 188 { 189 PLogError(L("ESR_INVALID_ARGUMENT")); 190 return ESR_INVALID_ARGUMENT; 191 } 192 return self->fgets(self, string, n, result); 193 } 194 195 ESR_ReturnCode PFileReadInt(PFile* self, int* value) 196 { 197 LCHAR number[MAX_INT_DIGITS+1]; 198 size_t i, bufferSize, count, totalRead = 0; 199 ESR_ReturnCode rc; 200 201 /* Skip whitespace before token */ 202 do 203 { 204 count = pfread(number, sizeof(LCHAR), MAX_INT_DIGITS, self); 205 totalRead += count; 206 if (count < MAX_INT_DIGITS) 207 { 208 if (pferror(self)) 209 { 210 rc = ESR_READ_ERROR; 211 PLogError(ESR_rc2str(rc)); 212 goto CLEANUP; 213 } 214 else 215 { 216 rc = ESR_INVALID_STATE; 217 PLogError(L("%s: reached end of file before finding token"), ESR_rc2str(rc)); 218 goto CLEANUP; 219 } 220 } 221 /* locate first non-whitespace character */ 222 for (i = 0; i < count && LISSPACE(number[i]); ++i); 223 } 224 while (i == count); 225 bufferSize = count - i; 226 227 /* Fill remainder of buffer */ 228 if (bufferSize < MAX_INT_DIGITS) 229 { 230 count = pfread(number + bufferSize, sizeof(LCHAR), MAX_INT_DIGITS - bufferSize, self); 231 bufferSize += count; 232 totalRead += count; 233 if (count < MAX_INT_DIGITS - bufferSize && pferror(self)) 234 { 235 rc = ESR_READ_ERROR; 236 PLogError(ESR_rc2str(rc)); 237 goto CLEANUP; 238 } 239 } 240 241 /* locate first whitespace character */ 242 for (i = 0; i < bufferSize && !LISSPACE(number[i]); ++i); 243 if (i < bufferSize) 244 { 245 /* unread anything after the token */ 246 if (PFileSeek(self, - (int)(bufferSize - i), SEEK_CUR)) 247 { 248 rc = ESR_SEEK_ERROR; 249 PLogError(ESR_rc2str(rc)); 250 } 251 totalRead -= bufferSize - i; 252 number[i] = L('\0'); 253 } 254 255 if (number[0] != L('-') && !LISDIGIT(number[0])) 256 { 257 rc = ESR_INVALID_STATE; 258 PLogError(L("%s: token was not number (%s)"), ESR_rc2str(rc), number); 259 goto CLEANUP; 260 } 261 262 CHKLOG(rc, lstrtoi(number, value, 10)); 263 return rc; 264 CLEANUP: 265 if (PFileSeek(self, - (int) count, SEEK_CUR)) 266 PLogError(L("ESR_SEEK_ERROR")); 267 return rc; 268 } 269 270 ESR_ReturnCode PFileReadLCHAR(PFile* self, LCHAR* value, size_t len) 271 { 272 size_t i, bufferSize, count, totalRead = 0; 273 ESR_ReturnCode rc = ESR_SUCCESS; 274 275 /* Skip whitespace before token */ 276 do 277 { 278 count = pfread(value, sizeof(LCHAR), len, self); 279 totalRead += count; 280 if (count < len) 281 { 282 if (pferror(self)) 283 { 284 rc = ESR_READ_ERROR; 285 PLogError(ESR_rc2str(rc)); 286 goto CLEANUP; 287 } 288 else 289 { 290 rc = ESR_INVALID_STATE; 291 PLogError(L("%s: reached end of file before finding token"), ESR_rc2str(rc)); 292 goto CLEANUP; 293 } 294 } 295 /* locate first non-whitespace character */ 296 for (i = 0; i < count && LISSPACE(value[i]); ++i); 297 } 298 while (i == count); 299 bufferSize = count - i; 300 301 /* Fill remainder of buffer */ 302 if (bufferSize < len) 303 { 304 count = pfread(value + bufferSize, sizeof(LCHAR), len - bufferSize, self); 305 bufferSize += count; 306 totalRead += count; 307 if (count < len - bufferSize && pferror(self)) 308 { 309 rc = ESR_READ_ERROR; 310 PLogError(ESR_rc2str(rc)); 311 goto CLEANUP; 312 } 313 } 314 315 /* locate first whitespace character */ 316 for (i = 0; i < bufferSize && !LISSPACE(value[i]); ++i); 317 if (i < bufferSize) 318 { 319 /* unread anything after the token */ 320 if (PFileSeek(self, -(int)(bufferSize - i), SEEK_CUR)) 321 { 322 rc = ESR_SEEK_ERROR; 323 PLogError(ESR_rc2str(rc)); 324 } 325 totalRead -= bufferSize - i; 326 value[i] = L('\0'); 327 } 328 return rc; 329 CLEANUP: 330 if (PFileSeek(self, - (int) count, SEEK_CUR)) 331 PLogError(L("ESR_SEEK_ERROR")); 332 return rc; 333 } 334 335 PFile* pfopen(const LCHAR* filename, const LCHAR* mode) 336 { 337 PFile* result; 338 ESR_ReturnCode rc; 339 ESR_BOOL isLittleEndian; 340 341 #if __BYTE_ORDER==__LITTLE_ENDIAN 342 isLittleEndian = ESR_TRUE; 343 #else 344 isLittleEndian = ESR_FALSE; 345 #endif 346 347 rc = PFileSystemCreatePFile(filename, isLittleEndian, &result); 348 if (rc != ESR_SUCCESS) 349 return NULL; 350 rc = result->open(result, mode); 351 if (rc != ESR_SUCCESS) 352 { 353 result->destroy(result); 354 return NULL; 355 } 356 return result; 357 } 358 359 size_t pfread(void* buffer, size_t size, size_t count, PFile* stream) 360 { 361 ESR_ReturnCode rc; 362 363 rc = PFileRead(stream, buffer, size, &count); 364 if (rc != ESR_SUCCESS) 365 return 0; 366 return count; 367 } 368 369 size_t pfwrite(const void* buffer, size_t size, size_t count, PFile* stream) 370 { 371 ESR_ReturnCode rc; 372 373 rc = PFileWrite(stream, buffer, size, &count); 374 if (rc != ESR_SUCCESS) 375 return 0; 376 return count; 377 } 378 379 int pfclose(PFile* stream) 380 { 381 ESR_ReturnCode rc; 382 383 rc = PFileDestroy(stream); 384 if (rc != ESR_SUCCESS) 385 return PEOF; 386 return 0; 387 } 388 389 void prewind(PFile* stream) 390 { 391 PFileSeek(stream, 0, SEEK_SET); 392 } 393 394 int pfseek(PFile* stream, long offset, int origin) 395 { 396 ESR_ReturnCode rc; 397 398 rc = PFileSeek(stream, offset, origin); 399 if (rc != ESR_SUCCESS) 400 return 1; 401 return 0; 402 } 403 404 long pftell(PFile* stream) 405 { 406 size_t result; 407 ESR_ReturnCode rc; 408 409 rc = PFileGetPosition(stream, &result); 410 if (rc != ESR_SUCCESS) 411 return -1; 412 return result; 413 } 414 415 int pfeof(PFile* stream) 416 { 417 ESR_BOOL eof; 418 419 PFileIsEOF(stream, &eof); 420 if (!eof) 421 return 0; 422 return 1; 423 } 424 425 int pferror(PFile* stream) 426 { 427 ESR_BOOL error; 428 429 PFileIsErrorSet(stream, &error); 430 if (!error) 431 return 0; 432 return 1; 433 } 434 435 void pclearerr(PFile* stream) 436 { 437 PFileClearError(stream); 438 } 439 440 int pfflush(PFile* stream) 441 { 442 ESR_ReturnCode rc; 443 444 rc = PFileFlush(stream); 445 if (rc != ESR_SUCCESS) 446 return PEOF; 447 return 0; 448 } 449 450 LCHAR* pfgets(LCHAR* string, int n, PFile* self) 451 { 452 LCHAR* result; 453 ESR_ReturnCode rc; 454 455 rc = PFileFgets(self, string, n, &result); 456 if (rc != ESR_SUCCESS) 457 return NULL; 458 return result; 459 } 460 461 LINT pfgetc(PFile* self) 462 { 463 LINT result; 464 ESR_ReturnCode rc; 465 466 rc = PFileFgetc(self, &result); 467 if (rc != ESR_SUCCESS) 468 return PEOF; 469 return result; 470 } 471 472 int pfprintf(PFile* stream, const LCHAR* format, ...) 473 { 474 #ifdef FINAL_RELEASE 475 return 0; 476 #else 477 va_list args; 478 int result; 479 ESR_ReturnCode rc; 480 481 va_start(args, format); 482 rc = PFileVfprintf(stream, &result, format, args); 483 va_end(args); 484 if (rc != ESR_SUCCESS) 485 return -1; 486 return result; 487 #endif 488 } 489 490 int pvfprintf(PFile* stream, const LCHAR* format, va_list argptr) 491 { 492 #ifdef FINAL_RELEASE 493 return 0; 494 #else 495 int result; 496 ESR_ReturnCode rc; 497 498 rc = PFileVfprintf(stream, &result, format, argptr); 499 if (rc != ESR_SUCCESS) 500 return -1; 501 return result; 502 #endif 503 } 504 505 int pprintf(const LCHAR* format, ...) 506 { 507 #ifdef FINAL_RELEASE 508 return 0; 509 #else 510 va_list args; 511 int result; 512 ESR_ReturnCode rc; 513 514 va_start(args, format); 515 rc = PFileVfprintf(PSTDOUT, &result, format, args); 516 va_end(args); 517 if (rc != ESR_SUCCESS) 518 return -1; 519 return result; 520 #endif 521 } 522