my own streams

L

Lasse Skyum

I would like to implement my own i/o streams for reading from my own
dataformat. Is it possible to derive one or more classes from
istream,ostream or iostream to do this? When member function would I then
have to implement?

Thanks!
 
M

Mike Wahler

Lasse Skyum said:
I would like to implement my own i/o streams for reading from my own
dataformat.

I can't know for sure without more elaboration from you,
but I suspect what you're wanting to do doesn't need the
creation of a 'custom' stream, but only of custom stream
inserters/extractors.

Ask if you want an example.
Is it possible to derive one or more classes from
istream,ostream or iostream to do this?

Such 'custom' streams are usually implemented by inheriting
from stream buffer classes, not stream classes.
When member function would I then
have to implement?

Whichever ones you want to support.

Much good information about this is in this great book:
http://www.langer.camelot.de/iostreams.htm

-Mike
 
L

Lasse Skyum

I can't know for sure without more elaboration from you,

Okay, it because I've made some functions that loads scripts, graphics and
geometry from streams. Currently I feed the functions fstream's but because
I havde decided to put all my files into a compressed collection-file I
can't do that anymore.

My idea was to uncompress it to a chunk of memory and make an istream that
read from it...
 
M

Mike Wahler

Lasse Skyum said:
Okay, it because I've made some functions that loads scripts, graphics and
geometry from streams. Currently I feed the functions fstream's but because
I havde decided to put all my files into a compressed collection-file I
can't do that anymore.

My idea was to uncompress it to a chunk of memory and make an istream that
read from it...

Why not define a custom extractor which does the decompress,
and stores the data wherever you need it?

-Mike
 
L

Lasse Skyum

Why not define a custom extractor which does the decompress,
and stores the data wherever you need it?

Hi Mike,

I'm sure that would be a verry clever way to do it... unfortunatly I don't
understand what you mean by "custom extractor" ... is that a C++ STL thing?
(I'm verry new to STL)

My plan is now just to make my own CIStream, COStream, CIOStream with
similar functionality so I can easily switch over. Just thought I would
stick to standard C++ to make it more "clean" and reusable...
 
R

Rob Williscroft

Lasse Skyum wrote in
Hi Mike,

I'm sure that would be a verry clever way to do it... unfortunatly I
don't understand what you mean by "custom extractor" ... is that a C++
STL thing? (I'm verry new to STL)

Not really, STL isn't an offical term, when used sensibly is means
the standard containers, iterators and algorithms libraries, e.g.
std::vector< T >, std::set< T >, and std::sort().

Here is a class Test with its own extractor an inserter.

#include <iostream>
#include <ostream>
#include <iomanip>
#include <sstream>

class Test
{
int a, b;
public:
Test() {}
Test( int aa, int bb ) : a( aa ), b ( bb ) {}
friend std::istream &operator >> (
std::istream &is,
Test &rhs
);
friend std::eek:stream &operator << (
std::eek:stream &os,
Test const &rhs
)
{
return os << "(" << rhs.a << "," << rhs.b << ")";
}

};

std::istream &operator >> (
std::istream &is,
Test &rhs
)
{
char c;
if ( !(is >> c) ) return is;
if ( c != '(' )
{
is.setstate( std::ios_base::failbit );
return is;
}
if ( !(is >> rhs.a) ) return is;
if ( !(is >> c ) ) return is;
if ( c != ',' )
{
is.setstate( std::ios_base::failbit );
return is;
}
if ( !(is >> rhs.b) ) return is;
if ( !(is >> c ) ) return is;
if ( c != ')' )
{
is.setstate( std::ios_base::failbit );
return is;
}
return is;
}


int main()
{
using namespace std;

Test a( 1, 2), b( 3, 4 ), c;
stringstream ss;
ss << a << " " << b << " %";

if (ss >> c) cerr << "extracted c\n";
else cerr << "didn't extract c\n";

cerr << a << ", " << b << ", " << c << "\n";

if (ss >> c) cerr << "extracted c\n";
else cerr << "didn't extract c\n";

cerr << a << ", " << b << ", " << c << "\n";


if (ss >> c) cerr << "extracted c\n";
else cerr << "didn't extract c\n";

if ( ss.fail() ) cerr << "ss failbit set\n";
else cerr << "ss failbit clear\n";
}
My plan is now just to make my own CIStream, COStream, CIOStream with
similar functionality so I can easily switch over. Just thought I
would stick to standard C++ to make it more "clean" and reusable...

Providing your own stream inserters (operator <<) and extractors
(operator >>) is "clean" and reusable..


Rob.
 
M

Micah Cowan

Rob Williscroft said:
Lasse Skyum wrote in


Providing your own stream inserters (operator <<) and extractors
(operator >>) is "clean" and reusable..

Yes, but they only allow for "all-at-once" decompress-and-dumps,
right? For accesses such as compression, or transparent
encoding/decoding from some particular encoding format, I've
found that having custom streams is often handier, as (with text)
I can get text data one line at a time, or use the standard
inserters/extractors; or (with binary) I can grab data a chunk at
a time. I did this sort of thing for reading/writing Base64
transparently. Naturally, it's significantly more work than just
creating inserters and extractors, so you have to decide whether
the extra flexibility is worth the time and effort.

To OP: If you /do/ decide to create youre own streams, then the
main work is in deriving a new streambuf class. After this is
done, you don't really even need to create a stream class, as you
can pass your streambuf class to the constructor (or to the
rdbuf() member function) of the standard stream classes.

Good luck!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top