1 | #ifndef _BINARY_FILE_H |
---|
2 | #define _BINARY_FILE_H |
---|
3 | |
---|
4 | #include <stdio.h> |
---|
5 | #include <string> |
---|
6 | #include "byte_order.h" |
---|
7 | #include "file.h" |
---|
8 | |
---|
9 | enum TerminalType { TT_INT = 4, TT_BYTE = 1, TT_SHORT = 2 }; |
---|
10 | |
---|
11 | /** |
---|
12 | * Holds the compiled semantic-string. |
---|
13 | */ |
---|
14 | struct DataSemantics { |
---|
15 | |
---|
16 | DataSemantics() |
---|
17 | { |
---|
18 | totalSize = 0; chunks = NULL; |
---|
19 | quantifier = 1; |
---|
20 | isTerminal = false; |
---|
21 | numChunkNodes = 0; |
---|
22 | } |
---|
23 | |
---|
24 | ~DataSemantics() |
---|
25 | { |
---|
26 | delete[] chunks; |
---|
27 | } |
---|
28 | |
---|
29 | int totalSize; |
---|
30 | int quantifier; |
---|
31 | int numChunkNodes; |
---|
32 | bool isTerminal; |
---|
33 | union { |
---|
34 | int type; |
---|
35 | DataSemantics **chunks; |
---|
36 | }; |
---|
37 | }; |
---|
38 | |
---|
39 | typedef DataSemantics *pDataSemantics; |
---|
40 | |
---|
41 | class BinaryFile : public File { |
---|
42 | public: |
---|
43 | BinaryFile() |
---|
44 | : File( "" ), |
---|
45 | byteorder( NATIVE_BYTEORDER ) |
---|
46 | { /* nothing to be done */ } |
---|
47 | |
---|
48 | BinaryFile( const std::string& _file ) |
---|
49 | : File( _file ), |
---|
50 | byteorder( NATIVE_BYTEORDER ) |
---|
51 | { /* nothing to be done */ } |
---|
52 | |
---|
53 | BinaryFile( const BinaryFile& _file ) |
---|
54 | : File( _file.name() ), |
---|
55 | byteorder( _file.getByteorder() ) |
---|
56 | { /* nothing to be done */ } |
---|
57 | |
---|
58 | /** |
---|
59 | * Reads a chunk of data based on the _semantics string. The string contains |
---|
60 | * a description of how the bytes are laid out in the file. If you want |
---|
61 | * to read out a struct which looks like this |
---|
62 | * struct { |
---|
63 | * int magic; |
---|
64 | * short size; |
---|
65 | * float x, y, z; |
---|
66 | * }; |
---|
67 | * then the semantics string is "isf3". If you want to read 5 of these |
---|
68 | * chunks, just put the whole string into paranthesis. "(isf3)5". Nifty, isn't |
---|
69 | * it? |
---|
70 | */ |
---|
71 | void read( const char *_semantics, void* _buf, size_t& _bytesRead ); |
---|
72 | |
---|
73 | /** |
---|
74 | * The same as the read above, but with the ability to read multiple |
---|
75 | * chunks once. Very useful if you don't know how many chunks you're |
---|
76 | * going to read at compile time. |
---|
77 | */ |
---|
78 | void read( const char *_semantics, int _chunks, |
---|
79 | void* _buf, size_t& _bytesRead ); |
---|
80 | /** |
---|
81 | * Writes a chunk of data based on the _semantics string. The string contains |
---|
82 | * a description of how the bytes should be laid out in the file. Have a look |
---|
83 | * at the description to read(). |
---|
84 | */ |
---|
85 | void write( const char *_semantics, void* _buf, size_t& _bytesWritten ); |
---|
86 | inline void seekg( int _pos ) |
---|
87 | { |
---|
88 | fseek( handle(), _pos, SEEK_SET ); |
---|
89 | } |
---|
90 | /** |
---|
91 | * @brief Sets the byteorder of the file. The order affects all subsequent |
---|
92 | * calls to write() and read(). It it is not wise to change the order |
---|
93 | * in the middle of reading a file. You're totally on your own. |
---|
94 | */ |
---|
95 | inline void setByteorder( ByteOrder _order ) |
---|
96 | { byteorder = _order; } |
---|
97 | |
---|
98 | /** |
---|
99 | * Returns the file's byte-order. |
---|
100 | */ |
---|
101 | inline ByteOrder getByteorder() const |
---|
102 | { return byteorder; } |
---|
103 | |
---|
104 | private: |
---|
105 | pDataSemantics compileSemantics( const char *_semantics ); |
---|
106 | ByteOrder byteorder; |
---|
107 | }; |
---|
108 | |
---|
109 | #endif |
---|