 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Dylan Nicholson Guest
|
Posted: Mon Feb 23, 2004 11:40 am Post subject: streambuf for reading from existing memory block |
|
|
{Might be better asked in comp.std.c++. -mod}
In order to implement a streambuf for reading/writing from/to an
existing block of memory, AFACIT, it's as simple as (ignoring
templates for now):
struct membuf : std::streambuf
{
membuf(char* p, size_t sz)
{
setg(p, p, p + sz);
setp(p, p + sz);
}
};
Surely it would make sense to supply something as trivial as this as
part of the standard? Or is there a reason I can't rely on the above
working?
Dylan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Philipp Bachmann Guest
|
Posted: Mon Feb 23, 2004 7:09 pm Post subject: Re: streambuf for reading from existing memory block |
|
|
| Quote: | In order to implement a streambuf for reading/writing from/to an
existing block of memory, AFACIT, it's as simple as (ignoring
templates for now):
struct membuf : std::streambuf
{
membuf(char* p, size_t sz)
{
setg(p, p, p + sz);
setp(p, p + sz);
}
};
Surely it would make sense to supply something as trivial as this as
part of the standard? Or is there a reason I can't rely on the above
working?
|
Hello Dylan,
"streambuf"s are either both of fixed size and the stream is related to some
external resource it can "sync()" its "streambuf" to - e.g. the "filebuf"
gets flushed into a file by the "ofstream" both explicitly and if it has been
filled up -, or the "streambuf" has no upper bound as the "stringbuf".
Because your "membuf" points to memory of finite size, in your
case the question is: What is "sync()" supposed to do? I.m.o. you
have only one choice here (because you didn't mention a sink like
a network connection, a binary file etc.): Growing your buffer, and
the method to do so should be supplied by means of an "allocator"
to free yourself from one specific allocation policy.
Another consideration: The C++ standard library only provides
formatting streams. Therefore any "basic_*buf<>"s has a template
parameter indicating a character type. Writing into raw memory
only makes sense in my opinion, if you establish a second hierarchy
of streams with binary output like Dietmar Kuehl's "XDRStream", now
part of the "Berlin" project.
In short, why don't you go for "stringstream" / "stringbuf"?
Cheers,
Philipp.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Dill Guest
|
Posted: Mon Feb 23, 2004 7:27 pm Post subject: Re: streambuf for reading from existing memory block |
|
|
| Quote: | In order to implement a streambuf for reading/writing from/to an
existing block of memory, AFACIT, it's as simple as (ignoring
templates for now):
struct membuf : std::streambuf
{
membuf(char* p, size_t sz)
{
setg(p, p, p + sz);
setp(p, p + sz);
}
};
Surely it would make sense to supply something as trivial as this as
part of the standard? Or is there a reason I can't rely on the above
working?
|
One thing you're missing is seek abilities. The default streambuf
implementation for seekpos and seekoff is to return an error. I would
expect a standard memory streambuf to implement these.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
P.J. Plauger Guest
|
Posted: Mon Feb 23, 2004 7:33 pm Post subject: Re: streambuf for reading from existing memory block |
|
|
"Dylan Nicholson" <wizofaus (AT) hotmail (DOT) com> wrote
| Quote: | Surely it would make sense to supply something as trivial as this as
part of the standard? Or is there a reason I can't rely on the above
working?
|
Triviality is not generally a good criterion for including something
in the C++ Standard.
P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
tom_usenet Guest
|
Posted: Mon Feb 23, 2004 7:43 pm Post subject: Re: streambuf for reading from existing memory block |
|
|
On 23 Feb 2004 06:40:03 -0500, [email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson)
wrote:
| Quote: | {Might be better asked in comp.std.c++. -mod}
In order to implement a streambuf for reading/writing from/to an
existing block of memory, AFACIT, it's as simple as (ignoring
templates for now):
struct membuf : std::streambuf
{
membuf(char* p, size_t sz)
{
setg(p, p, p + sz);
setp(p, p + sz);
}
};
Surely it would make sense to supply something as trivial as this as
part of the standard? Or is there a reason I can't rely on the above
working?
|
Something with equivalent functionality is supplied as part of the
standard: std::strstreambuf. It even switches between read-write and
read-only based on whether the passed pointer pointed to const or not.
It shouldn't be deprecated IMHO any more than string.c_str() should -
it has legitimate uses when, e.g., interacting with C api that use
char*.
Tom
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jonathan Turkanis Guest
|
Posted: Tue Feb 24, 2004 3:24 am Post subject: Re: streambuf for reading from existing memory block |
|
|
"Dylan Nicholson" <wizofaus (AT) hotmail (DOT) com> wrote
| Quote: | {Might be better asked in comp.std.c++. -mod}
In order to implement a streambuf for reading/writing from/to an
existing block of memory, AFACIT, it's as simple as (ignoring
templates for now):
struct membuf : std::streambuf
{
membuf(char* p, size_t sz)
{
setg(p, p, p + sz);
setp(p, p + sz);
}
};
|
There is a bit more to it than that, if you want a full-featured
stream buffer. Daryle Walker has written a basic_array_streambuf
template (submitted to Boost) which does what you want. (See
http://groups.yahoo.com/group/boost/files/more_io_3b.zip; you have to
sign up for the Boost developers list to access this)
His documentation states that the template is 'fairly uninteresting,
meant mainly as a test case ', so I doubt you'll find much support for
standardization.
I've written a library (also submitted to Boost) which provides a
toolkit for quickly defining new streams and stream buffers (plus
adding chains of filters). It also makes it easy to define such a
stream buffer, although by default it would provide buffered access to
the array. (See http://www.xmission.com/~turkanis/iostreams/)
Jonathan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dylan Nicholson Guest
|
Posted: Tue Feb 24, 2004 3:32 am Post subject: Re: streambuf for reading from existing memory block |
|
|
tom_usenet <tom_usenet (AT) hotmail (DOT) com> wrote
| Quote: | On 23 Feb 2004 06:40:03 -0500, [email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson)
wrote:
Surely it would make sense to supply something as trivial as this as
part of the standard? Or is there a reason I can't rely on the above
working?
Something with equivalent functionality is supplied as part of the
standard: std::strstreambuf. It even switches between read-write and
read-only based on whether the passed pointer pointed to const or not.
Except that strstreambuf can't be used with std::iostreams! |
The problem was, I had some code that only worked with a
std::istream<char> object, and I indeed had a std::istream<char>
buffer for it to read from - unfortunately I needed to limit the
number of bytes it was allowed to read from (i.e. a substream).
The easiest way to accomplish this was (using my membuf class):
void pass_substream_to_foo(std::istream& stream, int size)
{
std::vector<char> buf(size);
stream.read(&buf[0], size);
std::membuf mbuf(&buf[0], is.gcount());
std::istream substream(&mbuf);
foo(substream);
}
Of course I'm sure there are other ways of solving this exact problem,
but it works well enough, and seems safe.
Dylan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
tom_usenet Guest
|
Posted: Tue Feb 24, 2004 1:45 pm Post subject: Re: streambuf for reading from existing memory block |
|
|
On 23 Feb 2004 22:32:21 -0500, [email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson)
wrote:
| Quote: | Something with equivalent functionality is supplied as part of the
standard: std::strstreambuf. It even switches between read-write and
read-only based on whether the passed pointer pointed to const or not.
Except that strstreambuf can't be used with std::iostreams!
|
Huh? std::strstreambuf derives from std::basic_streambuf<char>, so it
certainly can.
| Quote: | void pass_substream_to_foo(std::istream& stream, int size)
{
std::vector<char> buf(size);
stream.read(&buf[0], size);
|
std::strstreambuf mbuf(&buf[0], is.gcount());
| Quote: | std::istream substream(&mbuf);
foo(substream);
}
Of course I'm sure there are other ways of solving this exact problem,
but it works well enough, and seems safe.
|
The above change is all that is required I think. Take a look at D.7
(page 703) in the standard. It even works with signed and unsigned
char buffers.
Tom
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Feb 24, 2004 7:27 pm Post subject: Re: streambuf for reading from existing memory block |
|
|
[email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson) wrote in message
news:<7d428a77.0402231612.4c0126ea (AT) posting (DOT) google.com>...
| Quote: | tom_usenet <tom_usenet (AT) hotmail (DOT) com> wrote in message
news:<onak30ppm13edjfqd5r9f1j00e2393qeg1 (AT) 4ax (DOT) com>...
On 23 Feb 2004 06:40:03 -0500, [email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson)
wrote:
Surely it would make sense to supply something as trivial as this
as part of the standard? Or is there a reason I can't rely on the
above working?
Something with equivalent functionality is supplied as part of the
standard: std::strstreambuf. It even switches between read-write and
read-only based on whether the passed pointer pointed to const or
not.
Except that strstreambuf can't be used with std::iostreams!
|
But std::strstreambuf can.
| Quote: | The problem was, I had some code that only worked with a
std::istream<char> object, and I indeed had a std::istream<char
buffer for it to read from - unfortunately I needed to limit the
number of bytes it was allowed to read from (i.e. a substream). The
easiest way to accomplish this was (using my membuf class):
void pass_substream_to_foo(std::istream& stream, int size)
{
std::vector
stream.read(&buf[0], size);
std::membuf mbuf(&buf[0], is.gcount());
|
std::strstreambuf mbuf( &buf[ 0 ], is.gcount() ) ;
should work. And is fully standard.
Putting your own class (membur) in std:: is forbidden. Normally, you
can get away with it, if there is a good reason to do so, but what is
the reason here?
| Quote: | std::istream substream(&mbuf);
foo(substream);
}
Of course I'm sure there are other ways of solving this exact problem,
but it works well enough, and seems safe.
|
In this particular case, wouldn't a simple filtering streambuf be more
appropriate. No need to copy all of the data.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dylan Nicholson Guest
|
Posted: Wed Feb 25, 2004 3:06 pm Post subject: Re: streambuf for reading from existing memory block |
|
|
tom_usenet <tom_usenet (AT) hotmail (DOT) com> wrote
| Quote: | On 23 Feb 2004 22:32:21 -0500, [email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson)
wrote:
Something with equivalent functionality is supplied as part of the
standard: std::strstreambuf. It even switches between read-write and
read-only based on whether the passed pointer pointed to const or not.
Except that strstreambuf can't be used with std::iostreams!
Huh? std::strstreambuf derives from std::basic_streambuf<char>, so it
certainly can.
|
Hmm, well not under VC6 it doesn't - it was part of the pre-standard
iostreams library. I suspect this might be true of other compilers..
| Quote: |
The above change is all that is required I think. Take a look at D.7
(page 703) in the standard. It even works with signed and unsigned
char buffers.
Well you've answered my question anyway - the standard library does |
supply what I needed, but unfortunately not for all the compilers I
need to support.
Dylan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dylan Nicholson Guest
|
Posted: Thu Feb 26, 2004 12:21 am Post subject: Re: streambuf for reading from existing memory block |
|
|
tom_usenet <tom_usenet (AT) hotmail (DOT) com> wrote
| Quote: | On 23 Feb 2004 22:32:21 -0500, [email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson)
wrote:
Something with equivalent functionality is supplied as part of the
standard: std::strstreambuf. It even switches between read-write and
read-only based on whether the passed pointer pointed to const or not.
Except that strstreambuf can't be used with std::iostreams!
Huh? std::strstreambuf derives from std::basic_streambuf<char>, so it
certainly can.
Ok, ignore this thread completely! For some reason I got the |
impression that some of the compilers I were using only supported
"non-std" strstreambuf, but it turned out not to be the case.
std::strstreambuf<> is exactly what I was looking for.
Dylan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|