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