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