PDA

View Full Version : About buffers, iostream objects, and files.



tonnot
31st May 2011, 08:29
I'm trying to have an object to store and retrieve data directly into-from memory.
I'd like to use iostream but it aks me for a streambuf.
All the examples I see using a filebuf as streambuf, but I want to work on memory.
Only at the beginning of my input and the end of output operations I'd want to read-write from-to a file.

Initially I want to solve this problem using standard io library.

I want to :
1.- Reserve or allocate a byte buffer. (really I want to create a vector of byte buffers...)
2. Write data to it ( any kind )
3.- Write buffers to file ( using the rdbuf ?)

By now, I cant do nothing.
'Cout' can work but I want to have my own iostream.

I used in the past the java datastream and an array of bytebuffers

But I'm unable to do the same with standard C++ (But I think that it is possible)


Can anybody help me ? I'm really lost.

wysota
31st May 2011, 09:05
The easiest solution is to implement your own stream class if you're having trouble with iostream. Or maybe you don't need a stream at all, maybe a simple set of read/write operators would suffice.

Zlatomir
31st May 2011, 09:17
Java and C++ are two different programming languages so don't try to write code in one of them exactly like you write in the other.

For serialization of your types you can overload the operators >> and << and then use them with the existing streams.

std::vector is a template class (so it can store generic types) - but i guess you want streams not vectors, so read more about streams.

tonnot
31st May 2011, 09:25
Thanks.
Yes, I know that streams are the right solution.
But .... I cant find how to use them at memory level.
All the examples and reference I have found is related with files....
Any useful link ?
Thanks again.

I have found one solution ....

stringstream s( ios_base::binary);
s.write ( reinterpret_cast<char*>( &a_double ), sizeof a_double );
s.write ( reinterpret_cast<char*>( &a_int ), sizeof a_int );

and later :
FILE.write(s.str().c_str(),12);

What do you think ?

wysota
31st May 2011, 10:05
You are not using the streaming nature of streams, so why bother using streams? This is the simplest solution you can use:

class Buffer {
public:
Buffer(int size = 256) : m_size(0), m_used(0), m_data(0){ resize(size); }
~Buffer() { if(m_data) free((void*)m_data); }
void write(const char *buf, int len) {
while(m_used+len<m_size) resize(m_size*2);
memcpy(m_data+m_used, buf, len);
m_used += len;
}
void dumpToStream(...) { /* implement yourself */ }
protected:
void resize(int s) {
if(!m_data) m_data = (char*)malloc(s); else m_data = (char*)realloc((void*)m_data, s);
}
private:
int m_size;
int m_used;
};

And your solution might fail on \0 chars, as usual in such situations.

tonnot
31st May 2011, 10:30
Thanks WY.
When I write the stringstream 'solution' really I wanted to show what i want.
My main doubt is 'I cannot use iostream' ? How can I create I iostream instance ?

My goal is to have a 'binary element' just in memory not in a file.
Reading the io reference, I have only acces to stringstream or fstream, ins't ?

I dont understand how to use streambuf directly, i cant?


And, your example is very useful, thanks.

wysota
31st May 2011, 11:09
You say you want to use iostream. But what for? You are not streaming anything, you are using classic read/write operators where you store binary data.

tonnot
31st May 2011, 11:30
I want to use iostream to read write data into memory, but I dont know how to .
I lose myself with the way to create the io instance, asociate initial memory, etc.
Basically I'd want to create a vector of io elements, on each vector I want to select the io object and then read - write data of any kind.

I want to have the benefits of to use the 'write', put, seek, << , ><, etc.
But the iostream ask me for a streambuf iostream (streambuf * sb);, and this element only let me to use filebuf and stringbuf :
This is an abstract base class, therefore no objects can be directly instantiated from it. The standard hierarchy defines two classes derived from this one that can be used to directly instantiate objects: filebuf and stringbuf.

So, my question is 'can I use this to work in memory' ? stringbuf is the way ?
Thanks

wysota
31st May 2011, 11:44
I want to use iostream to read write data into memory, but I dont know how to .
You are missing my point. You waste your time trying to use a stream in a non-streaming way. Choosing a particular approach over another has to be backed up by some evidence that there is a benefit of choosing this particular approach. You want to write binary data, you will not have any benefits from using streams. At least none that I see.


Basically I'd want to create a vector of io elements, on each vector I want to select the io object and then read - write data of any kind.
So far you are writing binary data, not "data of any kind".


But the iostream ask me for a streambuf iostream (streambuf * sb);, and this element only let me to use filebuf and stringbuf :
So subclass streambuf and create your own buffer type by implementing pure virtual methods.

tonnot
31st May 2011, 12:10
Thanks wy.
I have searched information about subclass streambuf. I dont find useful information.
I fear to 'reinvent' the wheel.
I dont understand why is so difficult to find a standard way to do what I want.
Thanks again.

squidge
31st May 2011, 13:18
I dont understand why is so difficult to find a standard way to do what I want. Simply put, there isn't a standard way of reading/writing "data of any kind" (apart from the non-stream read/write methods). The standards only apply to data of known types. If you really want to handle "data of any kind" in a stream based manor, then you need to define your own methods for each kind of data, as already suggested.