This section of the archives stores flipcode's complete Developer Toolbox collection,
featuring a variety of mini-articles and source code contributions from our readers.

Binary IO Class
Submitted by

This is a stream wrapper around the standard iostream streams that allows binary
I/O using the <> operators..

The classes
-----------

The output stream is called bofstream, and the input stream is bifstream. Both
are inherited from a bfstream_aux class that provides some common functions
between the streams.
The functions provided are similar to the standard streams, unless stated. Note,
not all the stream functions are available as they do not make sense for binary
I/O..

Summary of I/O
---------------

Output style
==============
simple types like int, float.. - use <<
string and buffers - use << but must delim them using ends
stl strings - use << but must delim them using ends
arrays and pointers array - use write but you can loop through each element and use << (preferred)
class objects - declare a bofstream friend operator<< justlike the std streams

Input style
============
simple types like int, float - use >>
arrays and pointers array - use read but can use a loop and use >>
string and char buffers - use getline, not >>. You have been warned!
stl strings - use >> or getline. String must be delim using ends
class objects - declare a bifstream friend operator >> just like the std streams

There are a few other functions that you can use to do I/O (like get(),..).
Note: For string data output, you need to specify the terminated the string
explicitly
Eg.
output_stream << "A string" << ends; // terminated the string using ends
Take a look at the BinaryTest section in the sample for some examples of binary
I/O using <>.

Doing more
-----------

Another added feature is that you can do I/O in both text and binary mode with
the same piece of code.

All that is needed is you format your output for text output using these
manipulators.

_ - inserts a space
t_ - inserts a tab
endl - inserts a newline. Does not flush the stream like the standard stream

The above manipulators does nothing in binary mode, but in text mode, the output
will be formatted correctly.

Example

bofstream os("output.txt");

os << 3 << _ << 4 << _ 5 << endl; // 3 4 5 newline

os << 6 endl
<< 7 endl
<< 8 endl; // 6 7 8 on a newline each

os << "This is a string" << ends; // string must be terminated by a ends

Output.txt will be

3 4 5
6
7
8
This is a string

The loader can be written as follows

bifstream is("output.txt");

int i;

is >> i >> i >> i; // read 3 4 5

is >> i >> i >> i ; // reads 6 7 8

string s;

is >> s; // reads "This is a string"

If you want to do the output in binary mode, all that is needed is to specify
the ios::binary flag when opening the file stream. The writer/loader does not
need to change.
e.g.
bofstream os("output.txt", ios::binary);
bifstream is("output.txt", ios::binary);

Some restrictions for this to work properly
-------------------------------------------

- Each output entry must be seperated by a space, tab or a newline. If you
output without a seperator, then the loader may load them as a single entry,
instead of two
Example

output_stream << 7 << 8 << endl; // output without a seperator

input_stream >> i; // reads 78 - incorrect

- Each string must be start on a newline and terminated with using ends. So
before writing a string, make sure the previous output has called endl. ends
will insert a newline automatically so the next entry will always have a
seperator.

- Each block of data using write() must start on a newline (same restriction as
the string). The write() function will insert a newline automatically after
writing the block. Note that the output in text mode is garbage if you use
write(). It is suggested to write out the elements individually using << for
readability.

- Certain functions require caution while using them. For example, the values in
seeking functions are going to be different depending on whether the file is in
text or binary mode. Some functions like putback() should not be used at all!

The TestText section of the sample has some examples of formatting the data.

Some things to take note
-------------------------

- Do not use >> to read string types unless the storage is a std::string and it
is deliminted using ends. Use getline instead as >> relies on the sizeof(type)
to read in data.

eg.

char buffer[80];

// input_stream >> buffer;

- Don't output a file in text mode and try read it in as binary mode or vice
versa. It won't work! Both file modes must be the same for I/O.
- If you edit the output file that was opened in text mode, you need to save it
in a "Text only" format. Saving the file in notepad will not work because
notepads automatically adds additional '\r' and '\n'when you save. You have to
use Wordpad to edit the output file.
- You can free to use/modify the code for your own use but I will am not
responsible for anything, whether direct or indirect, as a result of using this
wrapper. If you do find a bug, bug me at darkaurora@yahoo.com

The source code is provided as it is, without any warranty or liability. You are free to modify the
code for your own use.The author is not liable for any damages resulting from the usage of the code.

Output Summary:

simple types like int, float,.. - use <<
string and buffers - use << as long as they are terminated. Terminate them by ends
stl strings - use <<. Terminate them be ends
arrays and pointers - use write but you can loop through each element and use <<
class objects - use a bofstream friend operator<< just like the std streams

Input Summary:

simple types like int, float,.. - use >>
arrays and pointers - use read but can use a loop and use >>
string and buffers - use getline, not >>. You have been warned!
stl strings - use >> (if deliminter is '\0') or else use getline
class objects - use a bifstream friend operator >> just like the std streams

//@@ Moves the file position to a newline in if the file is in text mode. Function does nothing in binary mode
void text_skip_to_newline()
{
if (!bBinary_)
fs_.ignore(limit_int::max(),'\n'); // ignore everything until a newline is met
}