/*
 * IM - Image I/O Library
 * Copyright (c) 1996 CENPES/Petrobras, TeCGraf/PUC-Rio.
 * Antonio E. Scuri - scuri@tecgraf.puc-rio.br
 * 
 * BINFILE.H
 * 
 * Contains the declaration of the I/O functions of a binary file.
 * The binary file can be accessed by stream I/O functions, memory I/O functions or a custom I/O set of functions.
 * The file can be accessed for reading or writing only. You must specify the file byte order, 
 * when reading/writing a number with 2 or more bytes from/to a file and the file byte order is different from
 * the CPU byte order, the bytes that represents the number are rearranged to match the file byte order.
 * Follows a resume of the functions:
 *    Open
 *    Close
 *    Read
 *    Write
 *    Size
 *    Error
 *    Seek
 *    EOF
 *
 * History:
 *          1996.12.12 - Finished inicial version.
 *
 */

#ifndef __BINFILE_H
#define __BINFILE_H

#if	defined(__cplusplus)
extern "C" {
#endif


#include<stdarg.h>


/* The structure that handles the binary file */
typedef struct _binFile
{
  void* Handle;      /* Internal file handle used by the I/O functions */
  int WriteFlag;     /* Indicates if the file was opened for reading or for writing (Read = 0 or Write = 1) */
  int FileByteOrder; /* Indicates the file byte order (Little Endian = 0 [Intel] or Big Endian = 1 [Motorola]) */
}binFile;


/* Opens a binary file for reading or writing (Read = 0 or Write = 1).        */
/* You must specify the file byte order (Little Endian = 0 or Big Endian = 1) */
binFile* binFileOpen(char* pFileName, int pWriteFlag, int pFileByteOrder);


/* Closes the file and release any memory allocated. The pointer is then invalid */ 
void binFileClose(binFile* pFile);


/* Return the file size in bytes. */
unsigned long binFileSize(binFile* pFile);


/* Reads an array of 1 byte values. */
/* returns the number of values readed */
unsigned long binFileRead1ByteBuf(binFile* pFile, unsigned char* pValues, unsigned long pSize);


/* Reads an array of 2 byte values. */
/* returns the number of values readed */
unsigned long binFileRead2BytesBuf(binFile* pFile, unsigned short* pValues, unsigned long pSize);


/* Reads an array of 4 byte values. */
/* returns the number of values readed */
unsigned long binFileRead4BytesBuf(binFile* pFile, unsigned long* pValues, unsigned long pSize);


/* Reads an array of 8 byte values. */
/* returns the number of values readed */
unsigned long binFileRead8BytesBuf(binFile* pFile, double* pValues, unsigned long pSize);


/* Writes an array of 1 byte values. */
/* The function will not make a temporary copy of the values to invert the byte order.                        */
/* So after the call the values will be invalid, if the file byte order is diferent from the CPU byte order.  */
/* returns the number of values writed */
unsigned long binFileWrite1ByteBuf(binFile* pFile, unsigned char* pValues, unsigned long pSize);


/* Writes an array of 2 byte values. */
/* The function will not make a temporary copy of the values to invert the byte order.                        */
/* So after the call the values will be invalid, if the file byte order is diferent from the CPU byte order.  */
/* returns the number of values writed */
unsigned long binFileWrite2BytesBuf(binFile* pFile, unsigned short* pValues, unsigned long pSize);


/* Writes an array of 4 byte values. */
/* The function will not make a temporary copy of the values to invert the byte order.                        */
/* So after the call the values will be invalid, if the file byte order is diferent from the CPU byte order.  */
/* returns the number of values writed */
unsigned long binFileWrite4BytesBuf(binFile* pFile, unsigned long* pValues, unsigned long pSize);


/* Writes an array of 8 byte values. */
/* The function will not make a temporary copy of the values to invert the byte order.                        */
/* So after the call the values will be invalid, if the file byte order is diferent from the CPU byte order.  */
/* returns the number of values writed */
unsigned long binFileWrite8BytesBuf(binFile* pFile, double* pValues, unsigned long pSize);


/* writes a formated string */
/* returns the number of values writed */
unsigned long binFilePrintf(binFile* pFile, char *format, ...);


/* Indicates that was an error on the last operation. */
int binFileError(binFile* pFile);


/* Moves the file pointer from the begining of the file. */
void binFileSeekTo(binFile* pFile, unsigned long pOffset);


/* Moves the file pointer from current position.                        */
/* If the offset is a negative value the pointer moves to the begining. */
void binFileSeekOffset(binFile* pFile, long pOffset);


/* Moves the file pointer from the end of the file. */
/* the offset is a negative value */
void binFileSeekFrom(binFile* pFile, long pOffset);


/* Returns the current offset position. */
unsigned long binFileTell(binFile* pFile);


/* Indicates that the file pointer is at the end of the file. */
int binFileEndOfFile(binFile* pFile);

                              

/* The I/O function table. */
typedef struct _binFileFunctionTable
{
  void* (*Open)(char* pFileName, int pWriteFlag);
  void (*Close)(void* pHandle);
  unsigned long (*Size)(void* pHandle);
  unsigned long (*ReadBuf)(void* pHandle, unsigned char* pValues, unsigned long pSize);
  unsigned long (*WriteBuf)(void* pHandle, unsigned char* pValues, unsigned long pSize);
  unsigned long (*Printf)(void* pHandle, char *format, va_list arglist);
  int (*Error)(void* pHandle);
  void (*SeekTo)(void* pHandle, unsigned long pOffset);
  void (*SeekOffset)(void* pHandle, long pOffset);
  void (*SeekFrom)(void* pHandle, long pOffset);
  unsigned long (*Tell)(void* pHandle);
  int (*EndOfFile)(void* pHandle);
} binFileFunctionTable;


/* Changes the I/O function table.                            */
/* The default function table, uses stream file I/O functions */
void binFileSetFunctionTable(binFileFunctionTable* pFunctionTable);


/* Sets the default function table. Uses the RTL stream file I/O functions. */
void binFileSetStreamFunctionTable(void);


/* Sets a function table for a memory based file. */
/* The file open function expects the memory buffer and its size inside the file name string.      */
/* Use the sprintf function with the following format string: "%p %d".                             */
/* The buffer will not be changed. The read or write operations will not override the buffer size. */
void binFileSetMemoryFunctionTable(void);



#if	defined(__cplusplus)
}
#endif

#endif /* __BINFILE_H */

/* BINFILE.H */
