im_binfile.h
Go to the documentation of this file.00001 /** \file
00002 * \brief Binary File Access.
00003 *
00004 * See Copyright Notice in im_lib.h
00005 * $Id: im_binfile.h,v 1.2 2005/07/15 19:58:06 scuri Exp $
00006 */
00007
00008 #include "im_util.h"
00009
00010 #ifndef __IM_BINFILE_H
00011 #define __IM_BINFILE_H
00012
00013 #if defined(__cplusplus)
00014 extern "C" {
00015 #endif
00016
00017
00018 /** \defgroup binfile Binary File Access
00019 *
00020 * \par
00021 * These functions are very usefull for reading/writing binary files
00022 * that have headers or data that have to be converted depending on
00023 * the current CPU byte order. It can invert 2, 4 or 8 bytes numbers to/from little/big-endian orders.
00024 * \par
00025 * It will process the data only if the file format is diferent from the current CPU.
00026 * \par
00027 * Can read from disk or memory. In case of a memory buffer, the file name must be the \ref imBinMemoryFileName structure.
00028 * \par
00029 * See \ref im_binfile.h
00030 * \ingroup util */
00031
00032 typedef struct _imBinFile imBinFile;
00033
00034 /** Opens an existant binary file for reading.
00035 * The default file byte order is the CPU byte order.
00036 * Returns NULL if failed.
00037 * \ingroup binfile */
00038 imBinFile* imBinFileOpen(const char* pFileName);
00039
00040 /** Creates a new binary file for writing.
00041 * The default file byte order is the CPU byte order.
00042 * Returns NULL if failed.
00043 * \ingroup binfile */
00044 imBinFile* imBinFileNew(const char* pFileName);
00045
00046 /** Closes the file.
00047 * \ingroup binfile */
00048 void imBinFileClose(imBinFile* bfile);
00049
00050 /** Indicates that was an error on the last operation.
00051 * \ingroup binfile */
00052 int imBinFileError(imBinFile* bfile);
00053
00054 /** Returns the file size in bytes.
00055 * \ingroup binfile */
00056 unsigned long imBinFileSize(imBinFile* bfile);
00057
00058 /** Changes the file byte order. Returns the old one.
00059 * \ingroup binfile */
00060 int imBinFileByteOrder(imBinFile* bfile, int pByteOrder);
00061
00062 /** Reads an array of count values with byte sizes: 1, 2, 4, or 8. And invert the byte order if necessary after read.
00063 * \ingroup binfile */
00064 unsigned long imBinFileRead(imBinFile* bfile, void* pValues, unsigned long pCount, int pSizeOf);
00065
00066 /** Writes an array of values with sizes: 1, 2, 4, or 8. And invert the byte order if necessary before write.\n
00067 * <b>ATENTION</b>: The function will not make a temporary copy of the values to invert the byte order.\n
00068 * So after the call the values will be invalid, if the file byte order is diferent from the CPU byte order.
00069 * \ingroup binfile */
00070 unsigned long imBinFileWrite(imBinFile* bfile, void* pValues, unsigned long pCount, int pSizeOf);
00071
00072 /** Writes a string without the NULL terminator. The function uses sprintf to compose the string. \n
00073 * The internal buffer is fixed at 4096 bytes.
00074 * \ingroup binfile */
00075 unsigned long imBinFilePrintf(imBinFile* bfile, char *format, ...);
00076
00077 /** Moves the file pointer from the begining of the file.\n
00078 * When writing to a file seeking can go beyond the end of the file.
00079 * \ingroup binfile */
00080 void imBinFileSeekTo(imBinFile* bfile, unsigned long pOffset);
00081
00082 /** Moves the file pointer from current position.\n
00083 * If the offset is a negative value the pointer moves backwards.
00084 * \ingroup binfile */
00085 void imBinFileSeekOffset(imBinFile* bfile, long pOffset);
00086
00087 /** Moves the file pointer from the end of the file.\n
00088 * The offset is usually a negative value.
00089 * \ingroup binfile */
00090 void imBinFileSeekFrom(imBinFile* bfile, long pOffset);
00091
00092 /** Returns the current offset position.
00093 * \ingroup binfile */
00094 unsigned long imBinFileTell(imBinFile* bfile);
00095
00096 /** Indicates that the file pointer is at the end of the file.
00097 * \ingroup binfile */
00098 int imBinFileEndOfFile(imBinFile* bfile);
00099
00100 /** Predefined I/O Modules.
00101 * \ingroup binfile */
00102 enum imBinFileModule
00103 {
00104 IM_RAWFILE, /**< System dependent file I/O Rotines. */
00105 IM_STREAM, /**< Standard Ansi C Stream I/O Rotines. */
00106 IM_MEMFILE, /**< Uses a memory buffer. */
00107 IM_SUBFILE, /**< It is a sub file. FileName is a imBinFile* pointer from any other module. */
00108 IM_FILEHANDLE,/**< System dependent file I/O Rotines, but FileName is a system file handle ("int" in UNIX and "HANDLE" in Windows). */
00109 IM_IOCUSTOM0 /**< Other registered modules starts from here. */
00110 };
00111
00112 /** Sets the current I/O module.
00113 * \returns the previous function set, or -1 if failed.
00114 * \ingroup binfile */
00115 int imBinFileSetCurrentModule(int pModule);
00116
00117 /** \brief Memory File I/O Filename
00118 *
00119 * \par
00120 * Fake file name for the memory I/O module.
00121 * \ingroup binfile */
00122 typedef struct _imBinMemoryFileName
00123 {
00124 unsigned char *buffer; /**< The memory buffer. If you are reading the buffer must exists.
00125 * If you are writing the buffer can be internally allocated to the given size. The buffer is never free.*/
00126 int size; /**< Size of the buffer. */
00127 float reallocate; /**< Reallocate factor for the memory buffer when writing. size += reallocate*size. */
00128 }imBinMemoryFileName;
00129
00130
00131 #if defined(__cplusplus)
00132 }
00133 #endif
00134
00135
00136 #if defined(__cplusplus)
00137
00138 /** Base class to help the creation of new modules.\n
00139 * It handles the read/write operations with byte order correction if necessary.
00140 * \ingroup binfile */
00141 class imBinFileBase
00142 {
00143 friend class imBinSubFile;
00144
00145 protected:
00146 int IsNew,
00147 FileByteOrder,
00148 DoByteOrder; // to speed up byte order checking
00149
00150 // These will actually read/write the data
00151 virtual unsigned long ReadBuf(void* pValues, unsigned long pSize) = 0;
00152 virtual unsigned long WriteBuf(void* pValues, unsigned long pSize) = 0;
00153
00154 public:
00155
00156 int InitByteOrder(int ByteOrder)
00157 {
00158 int old_byte_order = this->FileByteOrder;
00159 this->FileByteOrder = ByteOrder;
00160
00161 if (ByteOrder != imBinCPUByteOrder())
00162 this->DoByteOrder = 1;
00163 else
00164 this->DoByteOrder = 0;
00165 return old_byte_order;
00166 }
00167
00168 // These will take care of byte swap if needed.
00169
00170 unsigned long Read(void* pValues, unsigned long pCount, int pSizeOf)
00171 {
00172 unsigned long rSize = ReadBuf(pValues, pCount * pSizeOf);
00173 if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf);
00174 return rSize/pSizeOf;
00175 }
00176
00177 unsigned long Write(void* pValues, unsigned long pCount, int pSizeOf)
00178 {
00179 if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf);
00180 return WriteBuf(pValues, pCount * pSizeOf)/pSizeOf;
00181 }
00182
00183 virtual void Open(const char* pFileName) = 0;
00184 virtual void New(const char* pFileName) = 0;
00185 virtual void Close() = 0;
00186 virtual unsigned long FileSize() = 0;
00187 virtual int HasError() const = 0;
00188 virtual void SeekTo(unsigned long pOffset) = 0;
00189 virtual void SeekOffset(long pOffset) = 0;
00190 virtual void SeekFrom(long pOffset) = 0;
00191 virtual unsigned long Tell() const = 0;
00192 virtual int EndOfFile() const = 0;
00193 };
00194
00195 /** File I/O module creation callback.
00196 * \ingroup binfile */
00197 typedef imBinFileBase* (*imBinFileNewFunc)();
00198
00199 /** Register a user I/O module.\n
00200 * Returns the new function set id.\n
00201 * Accepts up to 10 modules.
00202 * \ingroup binfile */
00203 int imBinFileRegisterModule(imBinFileNewFunc pNewFunc);
00204
00205 #endif
00206
00207 #endif