473,386 Members | 1,830 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

streambuf :: getting the data back from a custom stream

For a particular application of mine - I need a simulation of byte
array output stream.

* write data onto a stream
* getback the contiguous content as an array later for network
transport.

My code looks as follows.

#include <iostream>
#include <streambuf>
#include <locale>
#include <cstdio>

using namespace std;
class outbuf : public std::streambuf
{
public:
virtual ~outbuf()
{
sync();
}
char * getData() const
{
std::cout << "First " << std::hex << (void *)pbase() ;
std::cout << "Current " << std::hex << (void *)pptr() ;

return pbase();
}

streamsize getSize() const
{
return pbase() - pptr();
}
};

class myostream : public std::basic_ostream<char>
{

public:
myostream() :
basic_ostream<char>(new outbuf)
{
}
~myostream()
{
delete rdbuf();
}
};

int main()
{

myostream out;

out << "31 hexadecimal: " << std::hex << 31 << "\n";
st = out.rdbuf();
buf = dynamic_cast<outbuf *>(st);
if (!buf)
{
cerr << "error: dynamic_Cast failed";
return EXIT_FAILURE;
}

//TODO: At this point - I need to get the pointer to the beginning
of the buffer and the size of the same.
buf->getData();

cerr << "Size: " << buf->getSize() << endl;

return 0;
}
I had gone about creating a rudimentary derived class implementation
of streambuf and an output stream.
After writing data to the output stream I need to get the number of
bytes written and the pointer to the beginning of the stream. How do I
go about doing the same ??

The above example does not seem to work btw.

Thanks for the help.

Nov 10 '07 #1
4 6385
<ra***********@gmail.comwrote in message
news:11**********************@e9g2000prf.googlegro ups.com...
For a particular application of mine - I need a simulation of byte
array output stream.

* write data onto a stream
* getback the contiguous content as an array later for network
transport.

My code looks as follows.

#include <iostream>
#include <streambuf>
#include <locale>
#include <cstdio>

using namespace std;
class outbuf : public std::streambuf
{
public:
virtual ~outbuf()
{
sync();
}
char * getData() const
{
std::cout << "First " << std::hex << (void *)pbase() ;
std::cout << "Current " << std::hex << (void *)pptr() ;

return pbase();
}

streamsize getSize() const
{
return pbase() - pptr();
}
};

class myostream : public std::basic_ostream<char>
{

public:
myostream() :
basic_ostream<char>(new outbuf)
{
}
~myostream()
{
delete rdbuf();
}
};

int main()
{

myostream out;

out << "31 hexadecimal: " << std::hex << 31 << "\n";
st = out.rdbuf();
buf = dynamic_cast<outbuf *>(st);
if (!buf)
{
cerr << "error: dynamic_Cast failed";
return EXIT_FAILURE;
}

//TODO: At this point - I need to get the pointer to the beginning
of the buffer and the size of the same.
buf->getData();

cerr << "Size: " << buf->getSize() << endl;

return 0;
}
I had gone about creating a rudimentary derived class implementation
of streambuf and an output stream.
After writing data to the output stream I need to get the number of
bytes written and the pointer to the beginning of the stream. How do I
go about doing the same ??

The above example does not seem to work btw.

Thanks for the help.
I may be missing something, but why don't you just use stringstream?

#include <sstream>
#include <iostream>
#include <string>

int main()
{

std::stringstream out;

out << "31 hexadecimal: " << std::hex << 31 << "\n";

std::cout << "Size: " << out.str().size() << std::endl;
std::cout << "Data: " << out.str() << std::endl;

return 0;
}

Output:
Size: 19
Data: 31 hexadecimal: 1f
Nov 10 '07 #2
On Nov 9, 10:39 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
<rakesh.use...@gmail.comwrote in message

news:11**********************@e9g2000prf.googlegro ups.com...
For a particular application of mine - I need a simulation of byte
array output stream.
* write data onto a stream
* getback the contiguous content as an array later for network
transport.
My code looks as follows.
#include <iostream>
#include <streambuf>
#include <locale>
#include <cstdio>
using namespace std;
class outbuf : public std::streambuf
{
public:
virtual ~outbuf()
{
sync();
}
char * getData() const
{
std::cout << "First " << std::hex << (void *)pbase() ;
std::cout << "Current " << std::hex << (void *)pptr() ;
return pbase();
}
streamsize getSize() const
{
return pbase() - pptr();
}
};
class myostream : public std::basic_ostream<char>
{
public:
myostream() :
basic_ostream<char>(new outbuf)
{
}
~myostream()
{
delete rdbuf();
}
};
int main()
{
myostream out;
out << "31 hexadecimal: " << std::hex << 31 << "\n";
st = out.rdbuf();
buf = dynamic_cast<outbuf *>(st);
if (!buf)
{
cerr << "error: dynamic_Cast failed";
return EXIT_FAILURE;
}
//TODO: At this point - I need to get the pointer to the beginning
of the buffer and the size of the same.
buf->getData();
cerr << "Size: " << buf->getSize() << endl;
return 0;
}
I had gone about creating a rudimentary derived class implementation
of streambuf and an output stream.
After writing data to the output stream I need to get the number of
bytes written and the pointer to the beginning of the stream. How do I
go about doing the same ??
The above example does not seem to work btw.
Thanks for the help.

I may be missing something, but why don't you just use stringstream?

#include <sstream>
#include <iostream>
#include <string>

int main()
{

std::stringstream out;

out << "31 hexadecimal: " << std::hex << 31 << "\n";

std::cout << "Size: " << out.str().size() << std::endl;
std::cout << "Data: " << out.str() << std::endl;

return 0;

}

Output:
Size: 19
Data: 31 hexadecimal: 1f

Sorry for mentioning the additional criteria.. My intention is to
have a stream to write binary data and not text data. istringstreams
serve the purpose except that they write text data. I am not sure how
binary data would actually work.
I am looking for something like ibytestream / obytestream .

Nov 10 '07 #3
On Nov 10, 2:28 am, rakesh.use...@gmail.com wrote:
For a particular application of mine - I need a simulation of byte
array output stream.
* write data onto a stream
* getback the contiguous content as an array later for network
transport.
That sounds like stringstream to me. Otherwise, you might want
the old strstream.

Of course, if you really want to (e.g. you have other
constraits), it's pretty trivial to implement a streambuf which
writes to a vector<char>.
My code looks as follows.
#include <iostream>
#include <streambuf>
#include <locale>
#include <cstdio>
using namespace std;
class outbuf : public std::streambuf
{
public:
virtual ~outbuf()
{
sync();
}
Is the contiguous array owned by outbuf, or is it provided by
the client? I don't see any constructor, so it must be owned by
outbuf. On the other hand, I don't see any private data members
either, which makes me wonder: even if the buffer is owned by
the client, you have to save a pointer to it, or something.

Anyway, if the buffer is owned by outbuf, the sych isn't
necessary, since the buffer(s) won't exist after the destructor.
And for in memory streambuf work, sych is normally a no-op
anyway; the buffer is always synchronized.
char * getData() const
{
std::cout << "First " << std::hex << (void *)pbase() ;
std::cout << "Current " << std::hex << (void *)pptr() ;
I have doubts that std::hex actually affects the output of a
pointer. (It's implementation defined, but I'd always output
pointers in hex, regardless of the base.) If you do want to set
it, however, be sure to restore the base field to its initial
value. (Of course, I'm supposing that these statements are only
here for debugging purposes.)

As currently written, it is guaranteed that pbase and pptr are
always null.
return pbase();
}
streamsize getSize() const
{
return pbase() - pptr();
}
};
And where is your data, or the virtual functions you need to
override (overflow, at least).
class myostream : public std::basic_ostream<char>
{
public:
myostream() :
basic_ostream<char>(new outbuf)
{
}
~myostream()
{
delete rdbuf();
}

};
It's not really necessary to use dynamic allocation here,
although the alternatives are a bit tricky (since we should
ensure that outbuf is constructed before passing its address to
the ostream constructor.
int main()
{
myostream out;
out << "31 hexadecimal: " << std::hex << 31 << "\n";
st = out.rdbuf();
buf = dynamic_cast<outbuf *>(st);
if (!buf)
{
cerr << "error: dynamic_Cast failed";
return EXIT_FAILURE;
}
//TODO: At this point - I need to get the pointer to the beginning
of the buffer and the size of the same.
buf->getData();
cerr << "Size: " << buf->getSize() << endl;
return 0;
}
I had gone about creating a rudimentary derived class implementation
of streambuf and an output stream.
After writing data to the output stream I need to get the number of
bytes written and the pointer to the beginning of the stream. How do I
go about doing the same ??
You might start by allocating a buffer somewhere, and managing
it.
The above example does not seem to work btw.
Obviously. How can it if you don't override overflow? Maybe
something like the following:

class ArrayStreambuf : public std::streambuf
{
public:
typedef std::vector<char>::const_iterator
iterator ;
iterator begin() const
{
return myBuffer.begin() ;
}

iterator end() const
{
return myBuffer.end() ;
}

protected:
virtual int overflow( int ch )
{
if ( ch != EOF ) {
myBuffer.push_back( ch ) ;
size_t start = myBuffer.size() ;
myBuffer.resize( myBuffer.capacity() ) ;
setp( &myBuffer[ 0 ] + start,
&myBuffer[ 0 ] + myBuffer.size() ) ;
}
return ch == EOF ? 0 : ch ;
}

private:
std::vector< char myBuffer ;
} ;

The above simply uses the normal std::vector growth scheme. You
may want something different. Maybe add a constructor which
initializes the buffer to a minium size and calls setp, or
resize to std::max( capacity(), size() + someMinimumIncrement ).
or whatever your application requires.

Similarly, you may want to access the buffer otherwise than
through its iterators. Returning the address of the first
element and the size, for example, will allow calling the low
level system write function directly.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Nov 11 '07 #4
On Nov 10, 6:32 pm, Rakesh Kumar <rakesh.use...@gmail.comwrote:
On Nov 9, 10:39 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
I may be missing something, but why don't you just use stringstream?
#include <sstream>
#include <iostream>
#include <string>
int main()
{
std::stringstream out;
out << "31 hexadecimal: " << std::hex << 31 << "\n";
std::cout << "Size: " << out.str().size() << std::endl;
std::cout << "Data: " << out.str() << std::endl;
return 0;
}
Output:
Size: 19
Data: 31 hexadecimal: 1f
Sorry for mentioning the additional criteria.. My intention is to
have a stream to write binary data and not text data.
And how is that relevant. filebuf is the only standard stream
which makes a distinction (and your example still formatted the
data as text).
istringstreams serve the purpose except that they write text
data. I am not sure how binary data would actually work.
I am looking for something like ibytestream / obytestream .
In that case, istream and ostream aren't really what you want;
their role is formatting text. Write you're own ibytestream and
obytestream (or rather ixdrstream and oxdrstream, or whatever,
according to the binary format you are using), deriving from ios
and using streambuf for the actual data transfers.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Nov 11 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Matt Chaplain | last post by:
Hi there. I'm writing a program that uses the Telnet protocol over TCP/IP sockets. Of course, that has no bearing here, so I'll rephrase that in Standard C++ :) In essense, I'm trying to...
3
by: Viktor Lundström | last post by:
Hi! I was planning to wrap a socket inside an iostream, to achieve something like this: TCPSocket s(..); s << "Hello!" << endl; Information on the web seems to be a bit scarce on how to do...
3
by: Christopher Benson-Manica | last post by:
This is starting to seem ridiculous to me :( #include <streambuf> #include <iostream> class TWFileStream : public std::streambuf { private: char cbuf;
9
by: Fred Ma | last post by:
Hello, I posted previously under the thread: How to break this up into streambuf/ostream I've asked our library to get "C++ IOStreams and Locales..." by A. Langer et al. Meantime, I've...
9
by: Marcin Kalicinski | last post by:
Hi, I have a set of C-like functions for file access (like fopen, fwrite, fread, fseek etc.). But I want to access the files using C++ stream, not these functions. What I probably need to do is...
2
by: Raf256 | last post by:
Hello, my custom streambuf works fine with output via << and with input via .get() but fails to input via >> or getline... any idea why? -------------------- A custom stream buffer (for...
7
by: smith4894 | last post by:
Hello all, I'm working on writing my own streambuf classes (to use in my custom ostream/isteam classes that will handle reading/writing data to a mmap'd file). When reading from the mmap...
7
by: Christopher Pisz | last post by:
I found an article http://spec.winprog.org/streams/ as a starting point, but it seems to do alot of things that aren't very standard at all. One particular problem is, that he is using a vector as...
10
by: hsmit.home | last post by:
Hi everyone, I'm having some difficulty with the following piece of code. I have stripped it to it's bare minimum to demonstrate the problem at hand. Compiler: MS Visual C++ 2005 Express...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.