1 /** \file
2  * \brief Binary File Access.
3  *
4  * See Copyright Notice in im_lib.d
5  */
6 
7 module im.binfile;
8 
9 extern (C) @safe nothrow:
10 
11 /** \defgroup binfile Binary File Access
12  *
13  * \par
14  * These functions are very usefull for reading/writing binary files
15  * that have headers or data that have to be converted depending on
16  * the current CPU byte order. It can invert 2, 4 or 8 bytes numbers to/from little/big-endian orders.
17  * \par
18  * It will process the data only if the file format is diferent from the current CPU.
19  * \par
20  * Can read from disk or memory. In case of a memory buffer, the file name must be the \ref imBinMemoryFileName structure.
21  * \par
22  * See \ref im_binfile.h
23  * \ingroup util */
24 
25 /** \brief Binary File Structure (Private).
26  * \ingroup binfile */
27 struct _imBinFile;
28 alias imBinFile = _imBinFile;
29 
30 /** Opens an existant binary file for reading.
31  * The default file byte order is the CPU byte order.
32  * Returns NULL if failed.
33  * \ingroup binfile */
34 imBinFile* imBinFileOpen(const(char) * pFileName);
35 
36 /** Creates a new binary file for writing.
37  * The default file byte order is the CPU byte order.
38  * Returns NULL if failed.
39  * \ingroup binfile */
40 imBinFile* imBinFileNew(const(char) * pFileName);
41 
42 /** Closes the file.
43  * \ingroup binfile */
44 void imBinFileClose(imBinFile* bfile);
45 
46 /** Indicates that was an error on the last operation.
47  * \ingroup binfile */
48 int imBinFileError(imBinFile* bfile);
49 
50 /** Returns the file size in bytes.
51  * \ingroup binfile */
52 ulong imBinFileSize(imBinFile* bfile);
53 
54 /** Changes the file byte order. Returns the old one.
55  * \ingroup binfile */
56 int imBinFileByteOrder(imBinFile* bfile, int pByteOrder);
57 
58 /** Reads an array of count values with byte sizes: 1, 2, 4, or 8. And invert the byte order if necessary after read. \n
59  * Returns the actual count of values read.
60  * \ingroup binfile */
61 ulong imBinFileRead(imBinFile* bfile, void* pValues, ulong pCount, int pSizeOf);
62 
63 /** Writes an array of values with sizes: 1, 2, 4, or 8. And invert the byte order if necessary before write.\n
64  * <b>ATENTION</b>: The function will not make a temporary copy of the values to invert the byte order.\n
65  * So after the call the values will be invalid, if the file byte order is diferent from the CPU byte order. \n
66  * Returns the actual count of values writen.
67  * \ingroup binfile */
68 ulong imBinFileWrite(imBinFile* bfile, void* pValues, ulong pCount, int pSizeOf);
69 
70 /** Writes a string without the NULL terminator. The function uses sprintf to compose the string. \n
71  * The internal buffer is fixed at 4096 bytes. \n
72  * Returns the actual count of values writen.
73  * \ingroup binfile */
74 ulong imBinFilePrintf(imBinFile* bfile, const(char) *format, ...);
75 
76 /** Reads a line until line break. \n
77  * Returns the line in array, must have room enough. Line break is discarted. \n
78  * Use *size to inform buffer size. *size return the actual number os characters read.
79  * \ingroup binfile */
80 int imBinFileReadLine(imBinFile* handle, char* comment, int *size);
81 
82 /** Skips a line, including line break.
83  * \ingroup binfile */
84 int imBinFileSkipLine(imBinFile* handle);
85 
86 /** Reads an integer number from the current position until found a non integer character.
87  * Returns a non zero value if sucessfull.
88  * \ingroup binfile */
89 int imBinFileReadInteger(imBinFile* handle, int *value);
90 
91 /** Reads an floating point number from the current position until found a non number character.
92  * Returns a non zero value if sucessfull.
93  * \ingroup binfile */
94 int imBinFileReadReal(imBinFile* handle, double *value);
95 
96 /** Moves the file pointer from the begining of the file.\n
97  * When writing to a file seeking can go beyond the end of the file.
98  * \ingroup binfile */
99 void imBinFileSeekTo(imBinFile* bfile, ulong pOffset);
100 
101 /** Moves the file pointer from current position.\n
102  * If the offset is a negative value the pointer moves backwards.
103  * \ingroup binfile */
104 void imBinFileSeekOffset(imBinFile* bfile, long pOffset);
105 
106 /** Moves the file pointer from the end of the file.\n
107  * The offset is usually a negative value.
108  * \ingroup binfile */
109 void imBinFileSeekFrom(imBinFile* bfile, long pOffset);
110 
111 /** Returns the current offset position.
112  * \ingroup binfile */
113 ulong imBinFileTell(imBinFile* bfile);
114 
115 /** Indicates that the file pointer is at the end of the file.
116  * \ingroup binfile */
117 int imBinFileEndOfFile(imBinFile* bfile);
118 
119 /** Predefined I/O Modules.
120  * \ingroup binfile */
121 enum imBinFileModule
122 {
123 	IM_RAWFILE,   /**< System dependent file I/O Rotines. */
124 	IM_STREAM,    /**< Standard Ansi C Stream I/O Rotines. */
125 	IM_MEMFILE,   /**< Uses a memory buffer (see \ref imBinMemoryFileName). */
126 	IM_SUBFILE,   /**< It is a sub file. FileName is a imBinFile* pointer from any other module. */
127   IM_FILEHANDLE,/**< System dependent file I/O Rotines, but FileName is a system file handle ("int" in UNIX and "HANDLE" in Windows). */
128 	IM_IOCUSTOM0  /**< Other registered modules starts from here. */
129 };
130 
131 /** Sets the current I/O module.
132  * \returns the previous function set, or -1 if failed.
133  * See also \ref imBinFileModule.
134  * \ingroup binfile */
135 int imBinFileSetCurrentModule(int pModule);
136 
137 /** \brief Memory File Filename Parameter Structure
138  *
139  * \par
140  *  Fake file name for the memory I/O module.
141  * \ingroup binfile */
142 struct _imBinMemoryFileName
143 {
144   ubyte *buffer; /**< The memory buffer. If you are reading the buffer must exists.
145                           *   If you are writing the buffer can be internally allocated to the given size. The buffer is never free.
146                           *   The buffer is allocated using "malloc", and reallocated using "realloc". Use "free" to release it.
147                           *   To avoid RTL conflicts use the function imBinMemoryRelease. */
148   int size;              /**< Size of the buffer. */
149   float reallocate;      /**< Reallocate factor for the memory buffer when writing (size += reallocate*size).
150                           *   Set reallocate to 0 to disable reallocation, in this case buffer must not be NULL. */
151 }
152 alias imBinMemoryFileName = _imBinMemoryFileName;
153 
154 /** Release the internal memory allocated when writing a Memory File (see \ref imBinMemoryFileName).
155  * \ingroup binfile */
156 void imBinMemoryRelease(ubyte *buffer);