BinaryStream source - wanna test?

Hi... after several questions about this subject I developed a first version of a BinaryStream class.

My compilation system (focused on gcc or mingw-gcc) is divided in checksys phase (little program for a basic check) and real build (see Makefile)

You can have some doubts about checksystem (becouse a lot of defines are not truely checked) but I did a deep seach on wikipedia and such, so I am almost sure I didn't make wrong assumptions.
After all my library should run under Windows, Linux and MacOs, and not pretends to be completely universal.

You can still ask yourself why I re-define int8,16,32,64 and uint8,16,32,64. Two reasons for that:
1) "old" compiler (like mine) can not have <cstdint>
2) (windows specific) -> windows is not compiled with the compiler you usually use. surely NOT with gcc. So you cannot completely trust with the defined typedef (you can trust at 99% but not 100%).

You will surely note that my class miss exception handling.
This becouse: 1) I am not an advanced programmer, but a basic one
2) exception handling is already present into the true stream.

My class, infact, is a sort of binary "wrapper" that manages a standard cpp stream and allows you to overload operators << and >> to write a data in a binary way.

I hope that someone will test this class and will say its own opinion.

Here is where you can download the class:

http://nobun.users.sourceforge.net/BinaryStream.zip

Last edited on
Could you explain a little more? Isn't it std::ios::bin?
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)
Last edited on
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.


Not sure why you would want to. If you want to store stuff in a specific byte order you can do so perfectly fine with read and write. Seems like a solution to a non-problem to me and potentially confusing since the extraction and insertion operators typically do formatted input and output on text mode streams.
Well I don't agree completely to you, but however with this class I tried,as a personal exercise, to find a solution for the question in:

http://www.cplusplus.com/forum/general/97851/

However it is not completely true you can use read/write for this stuff.
Obliovsly you use read and write to perform this action (internally my class do this) but it is more error-prone... moreover you required to know endianness in your platform (during compilation process I check the system and create a proper header to complete such informations) and your code will be not portable to another (different endianness) platform, if you don't use htons or similar.

The logic of my class is similar to QDataStream in Qt... some things (also in sourcecode) are highly inspired on it.

The main focus is... it is a lot easier (and less error prone) to use << and >> to do the work in an automated way (and will save you a lot of code) and, moreover, << and >> can help you to create subroutines (like the example) to store particular data. This can be expecially useful in situations like one I find in one of my program (where I used QDataStream for this stuff) where storing bin data of a particular type follows a lot of rules and exceptions (for size and actual write)... in this way I can create the detailed subroutine for << and >> and place the code one time only, then using simply << and >> to place actual data later.

(in this way you can also distinguish text << and >> - default stream class - and binary << and >>... this still avoid confusion).

NOTE: I am not thinking I have found a problem that will "save the world"... simply I try to find an implementation for the "task" in the discussion linked above... that can be a little more user friendly.

NOTE2: I don't agree about confusion. Probably becouse I'm used to use QT that allows extraction and insertion operators (<< >>) both for formatted text mode (QTextStream) and for binary mode (QDataStream I don't see any risk of confusion... the fact it is a separate class (and its name avoid all kind of confusion - BinaryStream - ) I think prevent any kind of confusion
Last edited on
Topic archived. No new replies allowed.