I started reading this interesting question:
http://www.cplusplus.com/forum/general/97851/
As you can see it is explained there that if you open a stream in a binary mode (example: ofstream out("file", ios::out | ios::binary) you cannot however use << and >> operators to put-get binary data in stream, but you need to use only "read" and "write" (you cannot = it is not suggested, becouse can not work properly).
In the same time you cannot also subclass becouse operators << and >> defined in istream and ostream are not virtual (and also for another reason).
----------
My class is a simply wrapper that allows to use << and >> (and overload) for binary stream transmission. Moreover it allows (thing not allowed by standard streams) to specify endianness (LittleEndian or BigEndian).
example:
1 2 3 4
|
std::ofstream outs("file.bin", std::ios::out | std::ios::binary);
std2::BinaryStream out(&outs, std2::BigEndian); //second parameter is optional. If omitted it is assumed as LittleEndian
std2::int32 a = 5; std2::uint16 b = 1;
out<<a<<b;
|
when writing "out<<a<<b", BinaryStream will be safetly put 4bytes (in BigEndian format) to store 4bytes integer "a".... then will be safetly put 2bytes (in BigEndian format) to store 2bytes integer "b"
note: int == std2::int32 in all platforms supported by library (checked on wikipedia).
so you can use << and >> rather than "read" and "write" (however they appear in my class as readRawBinary and writeRawBinary) that does not allow endianness.
Moreover << and >> allow to implement subroutines (through overloading operator << and >>) for your custom data.
example:
1 2 3 4 5 6 7 8 9
|
struct MyClass {
std2::int32 a;
std2::uint b;
};
std2::BinaryStream &operator<< (std2::BinaryStream &s, const MyClass &t) {
s<<t.a<<t.b;
return s;
}
|
in this example you define your implementation to binary write MyClass using "<<"
the advantage of the approach is that all MyClass elements will be written with the user-specified endianness (becouse using internally << for basic integer data).
Not only: implementing MyClass operator<<, you can also store a std::list<MyClass> and std::vector<MyClass> (it will be stored in this way:
- 4bytes (int is always 4bytes in the supported platforms) for size list.
(written in the custom-defined endianness)
-nbytes (all elements contained in list)
EDIT: forgot to mention that my class doesn't support natively floats and doubles... They are hard to implement correctly in a platform-independant way and, morover, they are not so suitable to a good binary file (note: my class can handle all streams derived from istream or ostream... however I think the most common use could be for ifstream/ofstream/fstream)