1/*---------------------------------------------------------------------------* 2 * PFile.h * 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#ifndef __PFILE_H 21#define __PFILE_H 22 23 24 25#include <stdarg.h> 26#include <stddef.h> 27 28#include "ESR_ReturnCode.h" 29#include "PortPrefix.h" 30#include "ptypes.h" 31#include "pstdio.h" 32 33 34/** 35 * @addtogroup PFileModule PFile API functions 36 * Portable file API. 37 * 38 * Must call pmemInit() before using this module. 39 * If threads are to be used, ptrdInit() must be called before using this module as well. 40 * 41 * NOTE: It is technically impossible to provide a cross-platform version of scanf() and its 42 * variants (since vscanf() does not exist). As a result, this module does not provide this 43 * functionality. End-users are encourages to do their own parsing. 44 * 45 * @{ 46 */ 47 48#define USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS 1 49 50 51#ifdef USE_NARROW_CHAR 52 53/** 54 * Portable EOF constant 55 */ 56#define PEOF EOF 57 58#else 59 60/** 61* Portable EOF constant 62*/ 63#define PEOF WEOF 64 65#endif /* USE_NARROW_CHAR */ 66 67/** 68 * Portable file. 69 */ 70 71#ifdef USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS 72 73typedef FILE PFile; 74 75#else 76typedef struct PFile_t 77{ 78 /** 79 * Closes the PFile and destroys it. 80 * 81 * @param self PFile handle 82 * @return ESR_INVALID_ARGUMENT if self is null 83 */ 84 ESR_ReturnCode(*destroy)(struct PFile_t* self); 85 86 87 ESR_ReturnCode(*open)(struct PFile_t* self, const LCHAR* mode); 88 89 /** 90 * Closes a PFile. 91 * 92 * @param self PFile handle 93 * @return ESR_CLOSE_ERROR if file cannot be closed 94 */ 95 ESR_ReturnCode(*close)(struct PFile_t* self); 96 97 /** 98 * Reads from a PFile. 99 * 100 * @param self PFile handle 101 * @param buffer Storage location for data 102 * @param size Item size in bytes 103 * @param count [in/out] Maximum number of items to be read. On output, contains the 104 * number of full items actually read, which may be less than count if 105 * an error occurs or if the end of the file is encountered before reaching 106 * count. 107 * @return ESR_INVALID_ARGUMENT if self is null; ESR_READ_ERROR if a reading error occurs 108 */ 109 ESR_ReturnCode(*read)(struct PFile_t* self, void* buffer, size_t size, size_t* count); 110 111 /** 112 * Writes data to a PFile. 113 * 114 * @param self PFile handle 115 * @param buffer Pointer to data to be written 116 * @param size Item size in bytes 117 * @param count [in/out] Maximum number of items to be read. On output, contains the 118 * number of full items actually written, which may be less than count if 119 * an error occurs. 120 * @return ESR_INVALID_ARGUMENT if self is null; ESR_WRITE_ERROR if a writing error occurs 121 */ 122 ESR_ReturnCode(*write)(struct PFile_t* self, const void* buffer, size_t size, size_t* count); 123 124 /** 125 * Flushes a PFile. 126 * 127 * @param self PFile handle 128 * @return ESR_INVALID_ARGUMENT if self is null; ESR_FLUSH_ERROR if a flushing error occurs 129 */ 130 ESR_ReturnCode(*flush)(struct PFile_t* self); 131 132 /** 133 * Flushes a PFile. 134 * 135 * @param self PFile handle 136 * @param offset Number of bytes from <code>origin</code> 137 * @param origin Initial position 138 * @return ESR_INVALID_ARGUMENT if self is null; ESR_SEEK_ERROR if a seeking error occurs 139 */ 140 ESR_ReturnCode(*seek)(struct PFile_t* self, long offset, int origin); 141 142 /** 143 * Gets the current position of a PFile. 144 * 145 * @param self PFile handle 146 * @param position [out] The position 147 * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if an internal error occurs 148 */ 149 ESR_ReturnCode(*getPosition)(struct PFile_t* self, size_t* position); 150 151 /** 152 * Indicates if the PFile is open. 153 * 154 * @param self PFile handle 155 * @param isOpen [out] True if file is open 156 * @return ESR_INVALID_ARGUMENT if self is null 157 */ 158 ESR_ReturnCode(*isOpen)(struct PFile_t* self, ESR_BOOL* isOpen); 159 160 /** 161 * Indicates if the PFile is at the end of file. 162 * 163 * @param self PFile handle 164 * @param isEof [out] True if end of file has been reached 165 * @return ESR_INVALID_ARGUMENT if self is null 166 */ 167 ESR_ReturnCode(*isEOF)(struct PFile_t* self, ESR_BOOL* isEof); 168 169 /** 170 * Returns filename associated with PFile. 171 * 172 * @param self PFile handle 173 * @param filename [out] The filename 174 * @param len [in/out] Length of filename argument. If the return code is ESR_BUFFER_OVERFLOW, 175 * the required length is returned in this variable. 176 * @return ESR_INVALID_ARGUMENT if self or filename are null; ESR_BUFFER_OVERFLOW if buffer is too small 177 * to contain results 178 */ 179 ESR_ReturnCode(*getFilename)(struct PFile_t* self, LCHAR* filename, size_t* len); 180 181 /** 182 * Indicates if the error-flag is set in the PFile. This functionality is provided solely 183 * for backwards-compatibility reasons with ANSI-C ferror(). 184 * 185 * @param self PFile handle 186 * @param isError [out] True if the error-flag is set 187 * @return ESR_INVALID_ARGUMENT if self is null 188 */ 189 ESR_ReturnCode(*isErrorSet)(struct PFile_t* self, ESR_BOOL* isError); 190 191 /** 192 * Clears the error-flag in the PFile. This functionality is provided solely 193 * for backwards-compatibility reasons with ANSI-C ferror(). 194 * 195 * @param self PFile handle 196 * @return ESR_INVALID_ARGUMENT if self is null 197 */ 198 ESR_ReturnCode(*clearError)(struct PFile_t* self); 199 200 /** 201 * vfprintf() implementation for PFile. 202 * 203 * @param self PFile handle 204 * @param result Function result 205 * @param format see vfprintf() 206 * @param args see vfprintf() 207 * @return see vfprintf() 208 */ 209 ESR_ReturnCode(*vfprintf)(struct PFile_t* self, int* result, const LCHAR* format, va_list args); 210 /** 211 * fgetc() implementation for PFile. 212 * In case the underlying function returns an error, it will be propegated by the wrapper. 213 * 214 * @param self PFile handle 215 * @param result Function result 216 * @return see fgetc() 217 */ 218 ESR_ReturnCode(*fgetc)(struct PFile_t* self, LINT* result); 219 /** 220 * fgets() implementation for PFile. 221 * In case the underlying function returns an error, it will be propegated by the wrapper. 222 * 223 * @param self PFile handle 224 * @param string See fgets() 225 * @param n See fgets() 226 * @param result Function result 227 * @return see fgets() 228 */ 229 ESR_ReturnCode(*fgets)(struct PFile_t* self, LCHAR* string, int n, LCHAR** result); 230 /** 231 * Hide the memory footprint of this object from the PMemory module. 232 * 233 * NOTE: Because this function may be called by PMemory on shutdown, 234 * no PLog (which is shutdown before PMemory) functions should 235 * be used. 236 * @return ESR_INVALID_ARGUMENT if self is null 237 */ 238 ESR_ReturnCode(*hideMemoryAllocation)(struct PFile_t* self); 239} 240PFile; 241 242#endif 243 244 245 246/* 247 * Expose functions only if use wrappers is not defined, otherwize only expose wrapper functions. 248 */ 249 250#ifndef USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS 251 252/** 253 * Closes the PFile and destroys it. 254 * 255 * @param self PFile handle 256 * @return ESR_INVALID_ARGUMENT if self is null 257 */ 258PORTABLE_API ESR_ReturnCode PFileDestroy(PFile* self); 259 260 261PORTABLE_API ESR_ReturnCode PFileOpen(PFile* self, const LCHAR* mode); 262 263/** 264 * Closes a PFile. 265 * 266 * @param self PFile handle 267 * @return ESR_CLOSE_ERROR if file cannot be closed 268 */ 269PORTABLE_API ESR_ReturnCode PFileClose(PFile* self); 270 271/** 272 * Reads from a PFile. 273 * 274 * @param self PFile handle 275 * @param buffer Storage location for data 276 * @param size Item size in bytes 277 * @param count [in/out] Maximum number of items to be read. On output, contains the 278 * number of full items actually read, which may be less than count if 279 * an error occurs or if the end of the file is encountered before reaching 280 * count. 281 * @return ESR_INVALID_ARGUMENT if self is null; ESR_READ_ERROR if a reading error occurs 282 */ 283PORTABLE_API ESR_ReturnCode PFileRead(PFile* self, void* buffer, size_t size, size_t* count); 284 285/** 286 * Writes data to a PFile. 287 * 288 * @param self PFile handle 289 * @param buffer Pointer to data to be written 290 * @param size Item size in bytes 291 * @param count [in/out] Maximum number of items to be read. On output, contains the 292 * number of full items actually written, which may be less than count if 293 * an error occurs. 294 * @return ESR_INVALID_ARGUMENT if self is null; ESR_WRITE_ERROR if a writing error occurs 295 */ 296PORTABLE_API ESR_ReturnCode PFileWrite(PFile* self, void* buffer, size_t size, size_t* count); 297 298/** 299 * Flushes a PFile. 300 * 301 * @param self PFile handle 302 * @return ESR_INVALID_ARGUMENT if self is null; ESR_FLUSH_ERROR if a flushing error occurs 303 */ 304PORTABLE_API ESR_ReturnCode PFileFlush(PFile* self); 305 306/** 307 * Flushes a PFile. 308 * 309 * @param self PFile handle 310 * @param offset Number of bytes from <code>origin</code> 311 * @param origin Initial position 312 * @return ESR_INVALID_ARGUMENT if self is null; ESR_SEEK_ERROR if a seeking error occurs 313 */ 314PORTABLE_API ESR_ReturnCode PFileSeek(PFile* self, long offset, int origin); 315 316/** 317 * Gets the current position of a PFile. 318 * 319 * @param self PFile handle 320 * @param position [out] The position 321 * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if an internal error occurs 322 */ 323PORTABLE_API ESR_ReturnCode PFileGetPosition(PFile* self, size_t* position); 324 325/** 326 * Indicates if the PFile is open. 327 * 328 * @param self PFile handle 329 * @param isOpen [out] True if file is open 330 * @return ESR_INVALID_ARGUMENT if self is null 331 */ 332PORTABLE_API ESR_ReturnCode PFileIsOpen(PFile* self, ESR_BOOL* isOpen); 333 334 335/** 336 * Indicates if the PFile is at the end of file. 337 * 338 * @param self PFile handle 339 * @param isEof [out] True if end of file has been reached 340 * @return ESR_INVALID_ARGUMENT if self is null 341 */ 342PORTABLE_API ESR_ReturnCode PFileIsEOF(PFile* self, ESR_BOOL* isEof); 343 344/** 345 * Indicates if the error-flag is set in the PFile. This functionality is provided solely 346 * for backwards-compatibility reasons with ANSI-C ferror(). 347 * 348 * @param self PFile handle 349 * @param isError [out] True if the error-flag is set 350 * @return ESR_INVALID_ARGUMENT if self is null 351 */ 352PORTABLE_API ESR_ReturnCode PFileIsErrorSet(PFile* self, ESR_BOOL* isError); 353 354/** 355 * Clears the error-flag in the PFile. This functionality is provided solely 356 * for backwards-compatibility reasons with ANSI-C ferror(). 357 * 358 * @param self PFile handle 359 * @return ESR_INVALID_ARGUMENT if self is null 360 */ 361PORTABLE_API ESR_ReturnCode PFileClearError(PFile* self); 362 363/** 364 * fprintf() implementation for PFile. 365 * 366 * @param self PFile handle 367 * @param result Function result 368 * @param format see fprintf() 369 * @param args see fprintf() 370 * @return see fprintf() 371 */ 372PORTABLE_API ESR_ReturnCode PFileFprintf(PFile* self, int* result, const LCHAR* format, va_list args); 373 374/** 375 * vfprintf() implementation for PFile. 376 * 377 * @param self PFile handle 378 * @param result Function result 379 * @param format see vfprintf() 380 * @param args see vfprintf() 381 * @return see vfprintf() 382 */ 383PORTABLE_API ESR_ReturnCode PFileVfprintf(PFile* self, int* result, const LCHAR* format, va_list args); 384/** 385 * fgetc() implementation for PFile. 386 * 387 * @param self PFile handle 388 * @param result Function result 389 * @return see fgetc() 390 */ 391PORTABLE_API ESR_ReturnCode PFileFgetc(PFile* self, LINT* result); 392/** 393 * fgets() implementation for PFile. 394 * 395 * @param self PFile handle 396 * @param string See fgets() 397 * @param n See fgets() 398 * @param result Function result 399 * @return see fgets() 400 */ 401PORTABLE_API ESR_ReturnCode PFileFgets(PFile* self, LCHAR* string, int n, LCHAR** result); 402 403/** 404 * Reads an integer from the PFile. 405 * 406 * @param self PFile handle 407 * @param value [out] Integer that was read 408 * @return ESR_READ_ERROR if a reading error occurs; ESR_SEEK_ERROR if a seeking error occurs; 409 * ESR_INVALID_STATE if no EOF is reached before an integer 410 */ 411PORTABLE_API ESR_ReturnCode PFileReadInt(PFile* self, int* value); 412 413/** 414 * Reads a string token from the PFile. 415 * 416 * @param self PFile handle 417 * @param value [out] String that was read 418 * @param len Size of value argument. 419 * @return ESR_BUFFER_OVERFLOW if the value argument is too small; ESR_READ_ERROR if a reading error occurs; 420 * ESR_SEEK_ERROR if a seeking error occurs; ESR_INVALID_STATE if no EOF is reached before an LCHAR* 421 */ 422PORTABLE_API ESR_ReturnCode PFileReadLCHAR(PFile* self, LCHAR* value, size_t len); 423 424/** 425 * Returns filename associated with PFile. 426 * 427 * @param self PFile handle 428 * @param filename [out] The filename 429 * @param len [in/out] Length of filename argument. If the return code is ESR_BUFFER_OVERFLOW, 430 * the required length is returned in this variable. 431 * @return ESR_INVALID_ARGUMENT if self or filename are null; ESR_BUFFER_OVERFLOW if buffer is too small 432 * to contain results 433 */ 434PORTABLE_API ESR_ReturnCode PFileGetFilename(PFile* self, LCHAR* filename, size_t* len); 435 436#endif /* USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS */ 437 438/** 439 * Backwards compatible fopen(). 440 * 441 * @param filename See fopen() 442 * @param mode See fopen() 443 * @return see fopen() 444 */ 445PORTABLE_API PFile* pfopen(const LCHAR* filename, const LCHAR* mode); 446 447/** 448 * Backwards compatible fread(). 449 * 450 * @param buffer See fread() 451 * @param size See fread() 452 * @param count See fread() 453 * @param stream See fread() 454 * @return see fread() 455 */ 456PORTABLE_API size_t pfread(void* buffer, size_t size, size_t count, PFile* stream); 457 458/** 459 * Backwards compatible fwrite(). 460 * 461 * @param buffer See fwrite() 462 * @param size See fwrite() 463 * @param count See fwrite() 464 * @param stream See fwrite() 465 * @return see fwrite() 466 */ 467PORTABLE_API size_t pfwrite(const void* buffer, size_t size, size_t count, PFile* stream); 468 469/** 470 * Backwards compatible fclose(). 471 * 472 * @param stream See fclose() 473 * @return see fclose() 474 */ 475PORTABLE_API int pfclose(PFile* stream); 476 477/** 478 * Backwards compatible rewind() 479 * 480 * @param stream See rewind() 481 * @return see rewind() 482 */ 483PORTABLE_API void prewind(PFile* stream); 484 485/** 486 * Backwards compatible fseek(). 487 * 488 * @param stream See fseek() 489 * @param offset See fseek() 490 * @param origin See fseek() 491 * @return see fseek() 492 */ 493PORTABLE_API int pfseek(PFile* stream, long offset, int origin); 494 495/** 496 * Backwards compatible ftell(). 497 * 498 * @param stream See ftell() 499 * @return see ftell() 500 */ 501PORTABLE_API long pftell(PFile* stream); 502 503/** 504 * Backwards compatible fgets(). 505 * 506 * @param string See fgets() 507 * @param n See fgets() 508 * @param stream See fgets() 509 * @return see fgets() 510 */ 511PORTABLE_API LCHAR* pfgets(LCHAR* string, int n, PFile* stream); 512 513/** 514 * Backwards compatible feof(). 515 * 516 * @param stream See feof() 517 * @return see feof() 518 */ 519PORTABLE_API int pfeof(PFile* stream); 520 521/** 522 * Backwards compatible ferror(). 523 * 524 * @param stream See ferror() 525 * @return see ferror() 526 */ 527PORTABLE_API int pferror(PFile* stream); 528 529/** 530 * Backwards compatible clearerr(). 531 * 532 * @param stream See clearerr() 533 */ 534PORTABLE_API void pclearerr(PFile* stream); 535 536/** 537 * Backwards compatible fgetc(). 538 * 539 * @param stream See clearerr() 540 * @return see clearerr() 541 */ 542PORTABLE_API LINT pfgetc(PFile* stream); 543 544/** 545 * Backwards compatible fflush(). 546 * 547 * @param stream See fflush() 548 * @return see fflush() 549 */ 550PORTABLE_API int pfflush(PFile* stream); 551 552/** 553 * Backwards compatible vfprintf(). 554 * 555 * @param stream See vfprintf() 556 * @param format See vfprintf() 557 * @param args See vfprintf() 558 * @return see vfprintf() 559 */ 560PORTABLE_API int pvfprintf(PFile* stream, const LCHAR* format, va_list args); 561 562/** 563 * Backwards compatible fprintf(). 564 * 565 * @param stream See fprintf() 566 * @param format See fprintf() 567 * @return see fprintf() 568 */ 569PORTABLE_API int pfprintf(PFile* stream, const LCHAR* format, ...); 570 571/** 572 * Backwards compatible printf(). 573 * 574 * @param format See printf() 575 * @return see printf() 576 */ 577 578#ifndef USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS 579PORTABLE_API int pprintf(const LCHAR* format, ...); 580#endif 581 582/* 583 * The following are only defined when using pfile wrappers. 584 */ 585 586#ifdef USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS 587PORTABLE_API ESR_ReturnCode pf_convert_backslashes_to_forwardslashes ( LCHAR *string_to_convert ); 588PORTABLE_API ESR_ReturnCode pf_is_path_absolute ( const LCHAR* input_path, ESR_BOOL* isAbsolute ); 589PORTABLE_API ESR_ReturnCode pf_make_dir ( const LCHAR* path ); 590PORTABLE_API ESR_ReturnCode pf_get_cwd ( LCHAR* path, size_t *len ); 591PORTABLE_API ESR_ReturnCode pf_change_dir ( const LCHAR* path ); 592#endif 593 594/** 595 * @} 596 */ 597#endif /* __PFILE_H */ 598