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 /** Reads an integer number from the current position until found a non integer character.
00077  * Returns a non zero value if sucessfull.
00078  * \ingroup binfile */
00079 int imBinFileReadInteger(imBinFile* handle, int *value);
00080 
00081 /** Reads an floating point number from the current position until found a non number character.
00082  * Returns a non zero value if sucessfull.
00083  * \ingroup binfile */
00084 int imBinFileReadFloat(imBinFile* handle, float *value);
00085 
00086 /** Moves the file pointer from the begining of the file.\n
00087  * When writing to a file seeking can go beyond the end of the file.
00088  * \ingroup binfile */
00089 void imBinFileSeekTo(imBinFile* bfile, unsigned long pOffset);
00090 
00091 /** Moves the file pointer from current position.\n
00092  * If the offset is a negative value the pointer moves backwards.
00093  * \ingroup binfile */
00094 void imBinFileSeekOffset(imBinFile* bfile, long pOffset);
00095 
00096 /** Moves the file pointer from the end of the file.\n
00097  * The offset is usually a negative value.
00098  * \ingroup binfile */
00099 void imBinFileSeekFrom(imBinFile* bfile, long pOffset);
00100 
00101 /** Returns the current offset position.
00102  * \ingroup binfile */
00103 unsigned long imBinFileTell(imBinFile* bfile);
00104 
00105 /** Indicates that the file pointer is at the end of the file.
00106  * \ingroup binfile */
00107 int imBinFileEndOfFile(imBinFile* bfile);
00108 
00109 /** Predefined I/O Modules.
00110  * \ingroup binfile */
00111 enum imBinFileModule    
00112 {               
00113         IM_RAWFILE,   /**< System dependent file I/O Rotines. */
00114         IM_STREAM,    /**< Standard Ansi C Stream I/O Rotines. */
00115         IM_MEMFILE,   /**< Uses a memory buffer (see \ref imBinMemoryFileName). */
00116         IM_SUBFILE,   /**< It is a sub file. FileName is a imBinFile* pointer from any other module. */
00117   IM_FILEHANDLE,/**< System dependent file I/O Rotines, but FileName is a system file handle ("int" in UNIX and "HANDLE" in Windows). */
00118         IM_IOCUSTOM0  /**< Other registered modules starts from here. */
00119 };
00120 
00121 /** Sets the current I/O module.
00122  * \returns the previous function set, or -1 if failed.
00123  * See also \ref imBinFileModule.
00124  * \ingroup binfile */
00125 int imBinFileSetCurrentModule(int pModule);
00126 
00127 /** \brief Memory File I/O Filename
00128  *
00129  * \par
00130  *  Fake file name for the memory I/O module.
00131  * \ingroup binfile */
00132 typedef struct _imBinMemoryFileName
00133 {
00134   unsigned char *buffer; /**< The memory buffer. If you are reading the buffer must exists. 
00135                           *   If you are writing the buffer can be internally allocated to the given size. The buffer is never free.
00136                           *   The buffer is allocated using "malloc", and reallocated using "realloc". Use "free" to release it. 
00137                           *   To avoid RTL conflicts use the function imBinMemoryRelease. */
00138   int size;              /**< Size of the buffer. */ 
00139   float reallocate;      /**< Reallocate factor for the memory buffer when writing (size += reallocate*size). 
00140                           *   Set reallocate to 0 to disable reallocation, in this case buffer must not be NULL. */
00141 }imBinMemoryFileName;
00142                                              
00143 /** Release the internal memory allocated when writing a Memory File (see \ref imBinMemoryFileName).
00144  * \ingroup binfile */
00145 void imBinMemoryRelease(unsigned char *buffer);
00146 
00147 
00148 #if     defined(__cplusplus)
00149 }
00150 #endif
00151 
00152 
00153 #if     defined(__cplusplus)
00154 
00155 /** Base class to help the creation of new modules.\n
00156  * It handles the read/write operations with byte order correction if necessary.
00157  * \ingroup binfile */
00158 class imBinFileBase
00159 {
00160   friend class imBinSubFile;
00161 
00162 protected:
00163   int IsNew,
00164       FileByteOrder,
00165       DoByteOrder;   // to speed up byte order checking
00166 
00167   // These will actually read/write the data
00168   virtual unsigned long ReadBuf(void* pValues, unsigned long pSize) = 0;
00169   virtual unsigned long WriteBuf(void* pValues, unsigned long pSize) = 0;
00170 
00171 public:
00172 
00173   int InitByteOrder(int ByteOrder)
00174   {
00175     int old_byte_order = this->FileByteOrder;
00176     this->FileByteOrder = ByteOrder;
00177     
00178           if (ByteOrder != imBinCPUByteOrder())
00179             this->DoByteOrder = 1;
00180           else
00181       this->DoByteOrder = 0;
00182     return old_byte_order;
00183   }
00184 
00185   // These will take care of byte swap if needed.
00186 
00187   unsigned long Read(void* pValues, unsigned long pCount, int pSizeOf)
00188   {
00189     unsigned long rSize = ReadBuf(pValues, pCount * pSizeOf);
00190     if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf);
00191     return rSize/pSizeOf;
00192   }
00193 
00194   unsigned long Write(void* pValues, unsigned long pCount, int pSizeOf)
00195   {
00196     if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf);
00197     return WriteBuf(pValues, pCount * pSizeOf)/pSizeOf;
00198   }
00199 
00200   virtual void Open(const char* pFileName) = 0;
00201   virtual void New(const char* pFileName) = 0;
00202   virtual void Close() = 0;
00203   virtual unsigned long FileSize() = 0;
00204   virtual int HasError() const = 0;
00205   virtual void SeekTo(unsigned long pOffset) = 0;
00206   virtual void SeekOffset(long pOffset) = 0;
00207   virtual void SeekFrom(long pOffset) = 0;
00208   virtual unsigned long Tell() const = 0;
00209   virtual int EndOfFile() const = 0;
00210 };
00211 
00212 /** File I/O module creation callback.
00213  * \ingroup binfile */
00214 typedef imBinFileBase* (*imBinFileNewFunc)();
00215 
00216 /** Register a user I/O module.\n
00217  * Returns the new function set id.\n
00218  * Accepts up to 10 modules.
00219  * \ingroup binfile */
00220 int imBinFileRegisterModule(imBinFileNewFunc pNewFunc);
00221 
00222 #endif
00223 
00224 #endif

Generated on Thu Oct 1 11:40:01 2009 for IM by  doxygen 1.6.1