/*---------------------------------------------------------------------------*
* PFile.h *
* *
* Copyright 2007, 2008 Nuance Communciations, Inc. *
* *
* Licensed under the Apache License, Version 2.0 (the 'License'); *
* you may not use this file except in compliance with the License. *
* *
* You may obtain a copy of the License at *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an 'AS IS' BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*---------------------------------------------------------------------------*/
#ifndef __PFILE_H
#define __PFILE_H
#include <stdarg.h>
#include <stddef.h>
#include "ESR_ReturnCode.h"
#include "PortPrefix.h"
#include "ptypes.h"
#include "pstdio.h"
/**
* @addtogroup PFileModule PFile API functions
* Portable file API.
*
* Must call pmemInit() before using this module.
* If threads are to be used, ptrdInit() must be called before using this module as well.
*
* NOTE: It is technically impossible to provide a cross-platform version of scanf() and its
* variants (since vscanf() does not exist). As a result, this module does not provide this
* functionality. End-users are encourages to do their own parsing.
*
* @{
*/
#define USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS 1
#ifdef USE_NARROW_CHAR
/**
* Portable EOF constant
*/
#define PEOF EOF
#else
/**
* Portable EOF constant
*/
#define PEOF WEOF
#endif /* USE_NARROW_CHAR */
/**
* Portable file.
*/
#ifdef USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS
typedef FILE PFile;
#else
typedef struct PFile_t
{
/**
* Closes the PFile and destroys it.
*
* @param self PFile handle
* @return ESR_INVALID_ARGUMENT if self is null
*/
ESR_ReturnCode(*destroy)(struct PFile_t* self);
ESR_ReturnCode(*open)(struct PFile_t* self, const LCHAR* mode);
/**
* Closes a PFile.
*
* @param self PFile handle
* @return ESR_CLOSE_ERROR if file cannot be closed
*/
ESR_ReturnCode(*close)(struct PFile_t* self);
/**
* Reads from a PFile.
*
* @param self PFile handle
* @param buffer Storage location for data
* @param size Item size in bytes
* @param count [in/out] Maximum number of items to be read. On output, contains the
* number of full items actually read, which may be less than count if
* an error occurs or if the end of the file is encountered before reaching
* count.
* @return ESR_INVALID_ARGUMENT if self is null; ESR_READ_ERROR if a reading error occurs
*/
ESR_ReturnCode(*read)(struct PFile_t* self, void* buffer, size_t size, size_t* count);
/**
* Writes data to a PFile.
*
* @param self PFile handle
* @param buffer Pointer to data to be written
* @param size Item size in bytes
* @param count [in/out] Maximum number of items to be read. On output, contains the
* number of full items actually written, which may be less than count if
* an error occurs.
* @return ESR_INVALID_ARGUMENT if self is null; ESR_WRITE_ERROR if a writing error occurs
*/
ESR_ReturnCode(*write)(struct PFile_t* self, const void* buffer, size_t size, size_t* count);
/**
* Flushes a PFile.
*
* @param self PFile handle
* @return ESR_INVALID_ARGUMENT if self is null; ESR_FLUSH_ERROR if a flushing error occurs
*/
ESR_ReturnCode(*flush)(struct PFile_t* self);
/**
* Flushes a PFile.
*
* @param self PFile handle
* @param offset Number of bytes from <code>origin</code>
* @param origin Initial position
* @return ESR_INVALID_ARGUMENT if self is null; ESR_SEEK_ERROR if a seeking error occurs
*/
ESR_ReturnCode(*seek)(struct PFile_t* self, long offset, int origin);
/**
* Gets the current position of a PFile.
*
* @param self PFile handle
* @param position [out] The position
* @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if an internal error occurs
*/
ESR_ReturnCode(*getPosition)(struct PFile_t* self, size_t* position);
/**
* Indicates if the PFile is open.
*
* @param self PFile handle
* @param isOpen [out] True if file is open
* @return ESR_INVALID_ARGUMENT if self is null
*/
ESR_ReturnCode(*isOpen)(struct PFile_t* self, ESR_BOOL* isOpen);
/**
* Indicates if the PFile is at the end of file.
*
* @param self PFile handle
* @param isEof [out] True if end of file has been reached
* @return ESR_INVALID_ARGUMENT if self is null
*/
ESR_ReturnCode(*isEOF)(struct PFile_t* self, ESR_BOOL* isEof);
/**
* Returns filename associated with PFile.
*
* @param self PFile handle
* @param filename [out] The filename
* @param len [in/out] Length of filename argument. If the return code is ESR_BUFFER_OVERFLOW,
* the required length is returned in this variable.
* @return ESR_INVALID_ARGUMENT if self or filename are null; ESR_BUFFER_OVERFLOW if buffer is too small
* to contain results
*/
ESR_ReturnCode(*getFilename)(struct PFile_t* self, LCHAR* filename, size_t* len);
/**
* Indicates if the error-flag is set in the PFile. This functionality is provided solely
* for backwards-compatibility reasons with ANSI-C ferror().
*
* @param self PFile handle
* @param isError [out] True if the error-flag is set
* @return ESR_INVALID_ARGUMENT if self is null
*/
ESR_ReturnCode(*isErrorSet)(struct PFile_t* self, ESR_BOOL* isError);
/**
* Clears the error-flag in the PFile. This functionality is provided solely
* for backwards-compatibility reasons with ANSI-C ferror().
*
* @param self PFile handle
* @return ESR_INVALID_ARGUMENT if self is null
*/
ESR_ReturnCode(*clearError)(struct PFile_t* self);
/**
* vfprintf() implementation for PFile.
*
* @param self PFile handle
* @param result Function result
* @param format see vfprintf()
* @param args see vfprintf()
* @return see vfprintf()
*/
ESR_ReturnCode(*vfprintf)(struct PFile_t* self, int* result, const LCHAR* format, va_list args);
/**
* fgetc() implementation for PFile.
* In case the underlying function returns an error, it will be propegated by the wrapper.
*
* @param self PFile handle
* @param result Function result
* @return see fgetc()
*/
ESR_ReturnCode(*fgetc)(struct PFile_t* self, LINT* result);
/**
* fgets() implementation for PFile.
* In case the underlying function returns an error, it will be propegated by the wrapper.
*
* @param self PFile handle
* @param string See fgets()
* @param n See fgets()
* @param result Function result
* @return see fgets()
*/
ESR_ReturnCode(*fgets)(struct PFile_t* self, LCHAR* string, int n, LCHAR** result);
/**
* Hide the memory footprint of this object from the PMemory module.
*
* NOTE: Because this function may be called by PMemory on shutdown,
* no PLog (which is shutdown before PMemory) functions should
* be used.
* @return ESR_INVALID_ARGUMENT if self is null
*/
ESR_ReturnCode(*hideMemoryAllocation)(struct PFile_t* self);
}
PFile;
#endif
/*
* Expose functions only if use wrappers is not defined, otherwize only expose wrapper functions.
*/
#ifndef USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS
/**
* Closes the PFile and destroys it.
*
* @param self PFile handle
* @return ESR_INVALID_ARGUMENT if self is null
*/
PORTABLE_API ESR_ReturnCode PFileDestroy(PFile* self);
PORTABLE_API ESR_ReturnCode PFileOpen(PFile* self, const LCHAR* mode);
/**
* Closes a PFile.
*
* @param self PFile handle
* @return ESR_CLOSE_ERROR if file cannot be closed
*/
PORTABLE_API ESR_ReturnCode PFileClose(PFile* self);
/**
* Reads from a PFile.
*
* @param self PFile handle
* @param buffer Storage location for data
* @param size Item size in bytes
* @param count [in/out] Maximum number of items to be read. On output, contains the
* number of full items actually read, which may be less than count if
* an error occurs or if the end of the file is encountered before reaching
* count.
* @return ESR_INVALID_ARGUMENT if self is null; ESR_READ_ERROR if a reading error occurs
*/
PORTABLE_API ESR_ReturnCode PFileRead(PFile* self, void* buffer, size_t size, size_t* count);
/**
* Writes data to a PFile.
*
* @param self PFile handle
* @param buffer Pointer to data to be written
* @param size Item size in bytes
* @param count [in/out] Maximum number of items to be read. On output, contains the
* number of full items actually written, which may be less than count if
* an error occurs.
* @return ESR_INVALID_ARGUMENT if self is null; ESR_WRITE_ERROR if a writing error occurs
*/
PORTABLE_API ESR_ReturnCode PFileWrite(PFile* self, void* buffer, size_t size, size_t* count);
/**
* Flushes a PFile.
*
* @param self PFile handle
* @return ESR_INVALID_ARGUMENT if self is null; ESR_FLUSH_ERROR if a flushing error occurs
*/
PORTABLE_API ESR_ReturnCode PFileFlush(PFile* self);
/**
* Flushes a PFile.
*
* @param self PFile handle
* @param offset Number of bytes from <code>origin</code>
* @param origin Initial position
* @return ESR_INVALID_ARGUMENT if self is null; ESR_SEEK_ERROR if a seeking error occurs
*/
PORTABLE_API ESR_ReturnCode PFileSeek(PFile* self, long offset, int origin);
/**
* Gets the current position of a PFile.
*
* @param self PFile handle
* @param position [out] The position
* @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if an internal error occurs
*/
PORTABLE_API ESR_ReturnCode PFileGetPosition(PFile* self, size_t* position);
/**
* Indicates if the PFile is open.
*
* @param self PFile handle
* @param isOpen [out] True if file is open
* @return ESR_INVALID_ARGUMENT if self is null
*/
PORTABLE_API ESR_ReturnCode PFileIsOpen(PFile* self, ESR_BOOL* isOpen);
/**
* Indicates if the PFile is at the end of file.
*
* @param self PFile handle
* @param isEof [out] True if end of file has been reached
* @return ESR_INVALID_ARGUMENT if self is null
*/
PORTABLE_API ESR_ReturnCode PFileIsEOF(PFile* self, ESR_BOOL* isEof);
/**
* Indicates if the error-flag is set in the PFile. This functionality is provided solely
* for backwards-compatibility reasons with ANSI-C ferror().
*
* @param self PFile handle
* @param isError [out] True if the error-flag is set
* @return ESR_INVALID_ARGUMENT if self is null
*/
PORTABLE_API ESR_ReturnCode PFileIsErrorSet(PFile* self, ESR_BOOL* isError);
/**
* Clears the error-flag in the PFile. This functionality is provided solely
* for backwards-compatibility reasons with ANSI-C ferror().
*
* @param self PFile handle
* @return ESR_INVALID_ARGUMENT if self is null
*/
PORTABLE_API ESR_ReturnCode PFileClearError(PFile* self);
/**
* fprintf() implementation for PFile.
*
* @param self PFile handle
* @param result Function result
* @param format see fprintf()
* @param args see fprintf()
* @return see fprintf()
*/
PORTABLE_API ESR_ReturnCode PFileFprintf(PFile* self, int* result, const LCHAR* format, va_list args);
/**
* vfprintf() implementation for PFile.
*
* @param self PFile handle
* @param result Function result
* @param format see vfprintf()
* @param args see vfprintf()
* @return see vfprintf()
*/
PORTABLE_API ESR_ReturnCode PFileVfprintf(PFile* self, int* result, const LCHAR* format, va_list args);
/**
* fgetc() implementation for PFile.
*
* @param self PFile handle
* @param result Function result
* @return see fgetc()
*/
PORTABLE_API ESR_ReturnCode PFileFgetc(PFile* self, LINT* result);
/**
* fgets() implementation for PFile.
*
* @param self PFile handle
* @param string See fgets()
* @param n See fgets()
* @param result Function result
* @return see fgets()
*/
PORTABLE_API ESR_ReturnCode PFileFgets(PFile* self, LCHAR* string, int n, LCHAR** result);
/**
* Reads an integer from the PFile.
*
* @param self PFile handle
* @param value [out] Integer that was read
* @return ESR_READ_ERROR if a reading error occurs; ESR_SEEK_ERROR if a seeking error occurs;
* ESR_INVALID_STATE if no EOF is reached before an integer
*/
PORTABLE_API ESR_ReturnCode PFileReadInt(PFile* self, int* value);
/**
* Reads a string token from the PFile.
*
* @param self PFile handle
* @param value [out] String that was read
* @param len Size of value argument.
* @return ESR_BUFFER_OVERFLOW if the value argument is too small; ESR_READ_ERROR if a reading error occurs;
* ESR_SEEK_ERROR if a seeking error occurs; ESR_INVALID_STATE if no EOF is reached before an LCHAR*
*/
PORTABLE_API ESR_ReturnCode PFileReadLCHAR(PFile* self, LCHAR* value, size_t len);
/**
* Returns filename associated with PFile.
*
* @param self PFile handle
* @param filename [out] The filename
* @param len [in/out] Length of filename argument. If the return code is ESR_BUFFER_OVERFLOW,
* the required length is returned in this variable.
* @return ESR_INVALID_ARGUMENT if self or filename are null; ESR_BUFFER_OVERFLOW if buffer is too small
* to contain results
*/
PORTABLE_API ESR_ReturnCode PFileGetFilename(PFile* self, LCHAR* filename, size_t* len);
#endif /* USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS */
/**
* Backwards compatible fopen().
*
* @param filename See fopen()
* @param mode See fopen()
* @return see fopen()
*/
PORTABLE_API PFile* pfopen(const LCHAR* filename, const LCHAR* mode);
/**
* Backwards compatible fread().
*
* @param buffer See fread()
* @param size See fread()
* @param count See fread()
* @param stream See fread()
* @return see fread()
*/
PORTABLE_API size_t pfread(void* buffer, size_t size, size_t count, PFile* stream);
/**
* Backwards compatible fwrite().
*
* @param buffer See fwrite()
* @param size See fwrite()
* @param count See fwrite()
* @param stream See fwrite()
* @return see fwrite()
*/
PORTABLE_API size_t pfwrite(const void* buffer, size_t size, size_t count, PFile* stream);
/**
* Backwards compatible fclose().
*
* @param stream See fclose()
* @return see fclose()
*/
PORTABLE_API int pfclose(PFile* stream);
/**
* Backwards compatible rewind()
*
* @param stream See rewind()
* @return see rewind()
*/
PORTABLE_API void prewind(PFile* stream);
/**
* Backwards compatible fseek().
*
* @param stream See fseek()
* @param offset See fseek()
* @param origin See fseek()
* @return see fseek()
*/
PORTABLE_API int pfseek(PFile* stream, long offset, int origin);
/**
* Backwards compatible ftell().
*
* @param stream See ftell()
* @return see ftell()
*/
PORTABLE_API long pftell(PFile* stream);
/**
* Backwards compatible fgets().
*
* @param string See fgets()
* @param n See fgets()
* @param stream See fgets()
* @return see fgets()
*/
PORTABLE_API LCHAR* pfgets(LCHAR* string, int n, PFile* stream);
/**
* Backwards compatible feof().
*
* @param stream See feof()
* @return see feof()
*/
PORTABLE_API int pfeof(PFile* stream);
/**
* Backwards compatible ferror().
*
* @param stream See ferror()
* @return see ferror()
*/
PORTABLE_API int pferror(PFile* stream);
/**
* Backwards compatible clearerr().
*
* @param stream See clearerr()
*/
PORTABLE_API void pclearerr(PFile* stream);
/**
* Backwards compatible fgetc().
*
* @param stream See clearerr()
* @return see clearerr()
*/
PORTABLE_API LINT pfgetc(PFile* stream);
/**
* Backwards compatible fflush().
*
* @param stream See fflush()
* @return see fflush()
*/
PORTABLE_API int pfflush(PFile* stream);
/**
* Backwards compatible vfprintf().
*
* @param stream See vfprintf()
* @param format See vfprintf()
* @param args See vfprintf()
* @return see vfprintf()
*/
PORTABLE_API int pvfprintf(PFile* stream, const LCHAR* format, va_list args);
/**
* Backwards compatible fprintf().
*
* @param stream See fprintf()
* @param format See fprintf()
* @return see fprintf()
*/
PORTABLE_API int pfprintf(PFile* stream, const LCHAR* format, ...);
/**
* Backwards compatible printf().
*
* @param format See printf()
* @return see printf()
*/
#ifndef USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS
PORTABLE_API int pprintf(const LCHAR* format, ...);
#endif
/*
* The following are only defined when using pfile wrappers.
*/
#ifdef USE_LIGHT_WEIGHT_PANSI_FILE_WRAPPERS
PORTABLE_API ESR_ReturnCode pf_convert_backslashes_to_forwardslashes ( LCHAR *string_to_convert );
PORTABLE_API ESR_ReturnCode pf_is_path_absolute ( const LCHAR* input_path, ESR_BOOL* isAbsolute );
PORTABLE_API ESR_ReturnCode pf_make_dir ( const LCHAR* path );
PORTABLE_API ESR_ReturnCode pf_get_cwd ( LCHAR* path, size_t *len );
PORTABLE_API ESR_ReturnCode pf_change_dir ( const LCHAR* path );
#endif
/**
* @}
*/
#endif /* __PFILE_H */