Topic: What does setbuf *normally* do?


Author: enrightm@acm.org (Mike Enright)
Date: 1999/04/25
Raw View
none@none.invalid (Max Polk) wrote:

>
>I find C++ very usable because you can still "get to the bytes" and write
>file formats and whatnot.  ostringstream is apparently pulling us away
>from the raw bytes and making us use string instead, which cannot be
>attached to a char array.  Surely, all the places where you can get
>bitten with ostrstream are to be avoided.  But the result is that we
>can't use iostreams on char *'s we allocate!  That is a serious mistake.

Isn't it possible to make a streambuf derivative that allows the
client to allocate the buffer?

I think all you'd need is a streambuf derived like this:
class CharStreamBuf : public std::streambuf
{
public:
  CharStreamBuf() {}
protected:
  // client calls this via pubsetbuf.
  std::streambuf* setbuf(char* s, std::streamsize n)
  {
    setg(s, s, s+n);
    setp(s, s+n);
    return this;
  }
  // MSVC std::streambuf::setbuf implementation does nothing but
  // return this.
};

And then maybe a derivative of std::iostream for convenience in
attaching the streambuf to some iostream.

The CharStreamBuf would be eof() if you read or wrote up to the end of
the assigned buffer. The actual reading and writing are done by the
default implementations of various methods provided by std::streambuf.

In finalizing my answer to this question, I had a question of my own:

The Standard (27.5.2.4.2 paragraph 2) says "Default Behavior: If
gptr() is non-null and gptr()!=eptr() then do nothing. Returns this."
But it doesn't say what _other than nothing_ would be done if gptr()
were null or if gptr()==eptr(). If the MSVC implementation were
conforming, then the clause should say: "Default behavior: Returns
this." Having established that fact, it is also apparent that
std::streambuf might be useful on its own if it's setbuf called setg
and setp as I show above.


--
Mike Enright
enrightm@acm.org (Email replies cheerfully ignored, use the news group)
http://www.users.cts.com/sd/m/menright/
Cardiff-by-the-Sea, California, USA
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: none@none.invalid (Max Polk)
Date: 1999/03/28
Raw View
This concerns users of ostringstream who call rdbuf to get the underying
stringbuf then call pubsetbuf on it to attach an ostringstream to a user-
allocated char array.

I have a packed series of character arrays in a structure that I wish to
fill using iostreams.  I have been looking into using ostringstream to
write to each character array in this structure in favor of the
deprecated ostrstring.

After searching, I found a public method to change the buffer for a
ostringstream.  Simply use pubsetbuf on the stringbuf you obtain from
rdbuf.  It passes the char * and length it represents to the stringbuf's
protected setbuf.

At this point, I can use inserters and manipulators to format the data
and it gets placed into the character arrays in the structure just fine
via the ostringstream.  The only problem is that when the ostringstream
gets destroyed, it crashes my program every time.

Instead of passing it a pointer to an automatic character array in the
middle of the structure, if I pass a char * allocated with new it stops
crashing.  Presumably it is deleting the memory for me that I passed to
it.

In 27.7.1.3 in the C++ Standard, it says that the setbuf being used in
the above case is implementation defined.  Is the expectation that upon
ostringstream destruction, its internal stringbuf will call delete on the
buffer it is using?  If so, users allocate memory and let the
ostringstream destructor take care of deleting it for them.

And also, if this is the expectation, then there is *NO WAY POSSIBLE* to
link an ostringstream to automatic char arrays.  In a simple structure
containing several char arrays, one might want an ostringstream attached
to each array.  But apparently this is not possible since stringbuf calls
delete on the buffer.

I find C++ very usable because you can still "get to the bytes" and write
file formats and whatnot.  ostringstream is apparently pulling us away
from the raw bytes and making us use string instead, which cannot be
attached to a char array.  Surely, all the places where you can get
bitten with ostrstream are to be avoided.  But the result is that we
can't use iostreams on char *'s we allocate!  That is a serious mistake.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]