10
#ifdef __LITTLE_ENDIAN__
11
#error Cannot be both big and little endian
14
#ifndef __LITTLE_ENDIAN__
15
#error Need to define either big or little endian
19
//=================================================================================
20
template<class T> inline void swap_endianity(T &x)
22
assert(sizeof(T)<=8); // should not be called on composite types: instead specialize swap_endianity if needed.
24
for(unsigned int k=0; k<sizeof(T); ++k)
25
((char*)&x)[k] = ((char*)&old)[sizeof(T)-1-k];
29
//=================================================================================
43
assert_correct_endianity();
46
bifstream(const char *filename_format, ...) :
56
va_start(ap, filename_format);
57
int len=_vscprintf(filename_format, ap) // _vscprintf doesn't count
58
+1; // terminating '\0'
59
char *filename=new char[len];
60
vsprintf(filename, filename_format, ap);
61
input.open(filename, std::ifstream::binary);
66
va_start(ap, filename_format);
68
vasprintf(&filename, filename_format, ap);
69
input.open(filename, std::ifstream::binary);
75
void assert_correct_endianity(void)
79
assert(*(char*)&test == 0); // if this fails, you should have defined __LITTLE_ENDIAN__ instead
81
assert(*(char*)&test == 1); // if this fails, you should have defined __BIG_ENDIAN__ instead
85
void open(const char *filename_format, ...)
89
va_start(ap, filename_format);
90
int len=_vscprintf(filename_format, ap) // _vscprintf doesn't count
91
+1; // terminating '\0'
92
char *filename=new char[len];
93
vsprintf(filename, filename_format, ap);
94
input.open(filename, std::ifstream::binary);
99
va_start(ap, filename_format);
101
vasprintf(&filename, filename_format, ap);
102
input.open(filename, std::ifstream::binary);
108
void vopen(const char *filename_format, va_list ap)
111
int len=_vscprintf(filename_format, ap) // _vscprintf doesn't count
112
+1; // terminating '\0'
113
char *filename=new char[len];
114
vsprintf(filename, filename_format, ap);
115
input.open(filename, std::ifstream::binary);
119
vasprintf(&filename, filename_format, ap);
120
input.open(filename, std::ifstream::binary);
126
{ return input.good(); }
129
{ return input.fail(); }
134
void set_big_endian(void)
137
void set_little_endian(void)
138
{ big_endian=false; }
140
void read_endianity(void)
141
{ (*this)>>big_endian; }
143
void skip(long numbytes)
144
{ input.seekg(numbytes, std::ios_base::cur); }
146
void seek(long position)
147
{ input.seekg(position); }
150
{ return input.get(); }
152
private: // don't expose dangerous template
154
bifstream &templated_read(T &d)
156
input.read((char*)&d, sizeof(T));
157
#ifdef __BIG_ENDIAN__
168
void read(T *d, unsigned int num)
171
for(unsigned int i=0; i<num; ++i) (*this)>>d[i];
174
friend bifstream &operator>>(bifstream &, bool &);
175
friend bifstream &operator>>(bifstream &, unsigned char &);
176
friend bifstream &operator>>(bifstream &, short int &);
177
friend bifstream &operator>>(bifstream &, unsigned short int &);
178
friend bifstream &operator>>(bifstream &, int &);
179
friend bifstream &operator>>(bifstream &, unsigned int &);
180
friend bifstream &operator>>(bifstream &, long int &);
181
friend bifstream &operator>>(bifstream &, unsigned long int &);
182
friend bifstream &operator>>(bifstream &, float &);
183
friend bifstream &operator>>(bifstream &, double &);
187
bifstream &operator>>(bifstream &input, bool &d);
188
bifstream &operator>>(bifstream &input, char &d);
189
bifstream &operator>>(bifstream &input, signed char &d);
190
bifstream &operator>>(bifstream &input, unsigned char &d);
191
bifstream &operator>>(bifstream &input, short int &d);
192
bifstream &operator>>(bifstream &input, unsigned short int &d);
193
bifstream &operator>>(bifstream &input, int &d);
194
bifstream &operator>>(bifstream &input, unsigned int &d);
195
bifstream &operator>>(bifstream &input, long int &d);
196
bifstream &operator>>(bifstream &input, unsigned long int &d);
197
bifstream &operator>>(bifstream &input, float &d);
198
bifstream &operator>>(bifstream &input, double &d);
201
//=================================================================================
204
std::ofstream output;
209
#ifdef __BIG_ENDIAN__
215
assert_correct_endianity();
218
bofstream(const char *filename_format, ...) :
220
#ifdef __BIG_ENDIAN__
226
assert_correct_endianity();
229
va_start(ap, filename_format);
230
int len=_vscprintf(filename_format, ap) // _vscprintf doesn't count
231
+1; // terminating '\0'
232
char *filename=new char[len];
233
vsprintf(filename, filename_format, ap);
234
output.open(filename, std::ofstream::binary);
239
va_start(ap, filename_format);
241
vasprintf(&filename, filename_format, ap);
242
output.open(filename, std::ofstream::binary);
248
void assert_correct_endianity(void)
251
#ifdef __BIG_ENDIAN__
252
assert(*(char*)&test == 0); // if this fails, you should have defined __LITTLE_ENDIAN__ instead
254
assert(*(char*)&test == 1); // if this fails, you should have defined __BIG_ENDIAN__ instead
258
void open(const char *filename_format, ...)
262
va_start(ap, filename_format);
263
int len=_vscprintf(filename_format, ap) // _vscprintf doesn't count
264
+1; // terminating '\0'
265
char *filename=new char[len];
266
vsprintf(filename, filename_format, ap);
267
output.open(filename, std::ofstream::binary);
272
va_start(ap, filename_format);
274
vasprintf(&filename, filename_format, ap);
275
output.open(filename, std::ofstream::binary);
281
void vopen(const char *filename_format, va_list ap)
285
int len=_vscprintf(filename_format, ap) // _vscprintf doesn't count
286
+1; // terminating '\0'
287
char *filename=new char[len];
288
vsprintf(filename, filename_format, ap);
289
output.open(filename, std::ofstream::binary);
293
vasprintf(&filename, filename_format, ap);
294
output.open(filename, std::ofstream::binary);
300
{ return output.good(); }
303
{ return output.fail(); }
308
void set_big_endian(void)
311
void set_little_endian(void)
312
{ big_endian=false; }
314
void write_endianity(void)
315
{ (*this)<<big_endian; }
317
void write_zero(unsigned int numbytes)
318
{ for(unsigned int i=0; i<numbytes; ++i) output.put(0); }
321
{ output.put(byte); }
323
private: // don't expose dangerous templates
325
bofstream &templated_write(const T &d)
327
#ifdef __BIG_ENDIAN__
334
swap_endianity(swapped_copy);
335
output.write((const char*)&swapped_copy, sizeof(T));
337
output.write((const char*)&d, sizeof(T));
343
void write(const T *d, unsigned int num)
346
for(unsigned int i=0; i<num; ++i) (*this)<<d[i];
349
friend bofstream &operator<<(bofstream &, const bool &);
350
friend bofstream &operator<<(bofstream &, const short int &);
351
friend bofstream &operator<<(bofstream &, const unsigned short int &);
352
friend bofstream &operator<<(bofstream &, const int &);
353
friend bofstream &operator<<(bofstream &, const unsigned int &);
354
friend bofstream &operator<<(bofstream &, const long int &);
355
friend bofstream &operator<<(bofstream &, const unsigned long int &);
356
friend bofstream &operator<<(bofstream &, const float &);
357
friend bofstream &operator<<(bofstream &, const double &);
360
bofstream &operator<<(bofstream &output, const bool &d);
361
bofstream &operator<<(bofstream &output, const char &d);
362
bofstream &operator<<(bofstream &output, const signed char &d);
363
bofstream &operator<<(bofstream &output, const unsigned char &d);
364
bofstream &operator<<(bofstream &output, const short int &d);
365
bofstream &operator<<(bofstream &output, const unsigned short int &d);
366
bofstream &operator<<(bofstream &output, const int &d);
367
bofstream &operator<<(bofstream &output, const unsigned int &d);
368
bofstream &operator<<(bofstream &output, const long int &d);
369
bofstream &operator<<(bofstream &output, const unsigned long int &d);
370
bofstream &operator<<(bofstream &output, const float &d);
371
bofstream &operator<<(bofstream &output, const double &d);