C++ BinaryReader equivalent?

Started by
9 comments, last by Zahlman 14 years, 7 months ago
Does the C++ STL have an equivalent of C#'s BinaryReader and MemoryStream? I'm trying to read from an array of char[]. A BinaryWriter would also be nice! I'm tried to Google for these things, but I just get results for C++ .NET, which is not what I want. For those who don't know, BinaryReader is a streamreader that reads binary data, and MemoryStream is a streamobject that can encapsulate a bytearray.
Advertisement
The STL does have streams, but from what I know no binary ones. You can use i/o fstream to read binary files, but there's no generic stream reader that only encapsulates reading/writing, no matter what the source/sink may be.

Neither does the boost i/o library (as far as I know). That's why I've written my own reader/writer that integrates into the boost i/o library (to make use of their sources/sinks).

I can send you my source if you want. But I'm curious if there's something else to use...
The C++ iostreams work fine for binary data. Just make sure to open with the "b" mode to prevent line-ending translation. If you want to read from char[], you can either copy it into a string and use stringstream, or write a small streambuf subclass to use the data in-place.
Yeah, would be awesome if you could post your sources - that said, I'm really confused as well if what you're saying is that there's essentiallly no functionality like this in the STL.
I'm sorry for providing this mis-information. I must have overlooked that feature. I though opening in binary mode was only available for the file streams.
From this link I get that you can provide the necessary parameter in the constructor of stringstream.
In C/C++ you just have to setup your own little classes for that functionality. Those two classes are definitely something thing I loved about .Net when I was working on some network code in it. They are invaluable and are provided to you so you don't have to code them yourself. There are many ways to go about the task in C++, but here's the approach I use (a mixture if C/C++ constructs).

But first, disclaimers:
- The code might still have bugs in it. It's still a work in progress as I am using it and generally improving the API for it.
- The code makes uses of exceptions, so you need to use exception handling mechanisms when you use the class.
- The code is provided only for educational purposes in showing a specific approach. You should understand the concepts first before using it and eventually come up with your own solution that fits your needs.
- Finally, there might be better, more efficient, more C++'ish approaches, but I'm using what fits my needs the best, as best I could code a solution.

<Code removed since it's not needed and still a WIP>

Just throwing that out there! [smile]

[edit] Small bug fix with readonly not getting set.

[Edited by - Drew_Benton on September 17, 2009 10:02:31 AM]
Thanks guys! :)
I think I'm just going to go with using iostream for now.
Ok, now I've come up with a BinaryStream that works more or less thi way I need it to.
But there's a problem - how do I convert an integer number to a char array?
I don't want the ASCII representation of the number (meaning I can't use itoa()), but the binary representation.

Here's what I tried to do so far:

void BinaryStream::WriteInt(int Int){	for(int i = 0; i < 4; i++)	{		m_Buffer[m_BufPosition] = (int*)Int;		m_BufPosition++;	}}


It didn't work. Compiler complains that using subscripts needs pointers or array types, so I tried casting the int to a pointer, which didn't work either.
If you want to see what m_Buffer and m_BufPosition looks like, here's my class definition:

/*===============================================================================================================/*/* Class name: BinaryStream /* Purpose:	   Provide an interface for reading basic types (int, uint, char etc) from char arrays/*/*==============================================================================================================*/class BinaryStream{private:	char *m_Buffer;	int m_BufPosition;public:	BinaryStream(char *Buf[]);	char ReadByte();	char* ReadBytes(int NumBytes);	int ReadInt();	unsigned int ReadUInt();	short ReadShort();	void WriteByte(char Byte);	void WriteBytes(char *Bytes[], int Length);	void WriteInt(int Int);	void WriteUInt(unsigned int UInt);	void WriteShort(short Short);};


Edit: Yes, I tried to Google the answer - and most of the ones I found were based around converting the integer to it's ASCII equivalent.
The integer is already in memory exactly how you want it, so all you really need to do is get a pointer to it and then convert the pointer to a char*. Or you could just memcpy the integer into your buffer (which does all of the convert-pointers-and-copy for you).

The simplest way is to do this:

template <typename T>void WritePODType(T value){  memcpy(m_Buffer+m_BufPosition, &value, sizeof(value));  m_BufPosition += sizeof(value);}
Thanks! :D

This topic is closed to new replies.

Advertisement