Topic: Streambuffer / write past end-of-buffer?


Author: tom_usenet@hotmail.com (Tom Widmer)
Date: Thu, 4 Nov 2004 04:52:58 GMT
Raw View
On Thu, 28 Oct 2004 11:12:21 GMT, kanze@gabi-soft.fr wrote:

>tom_usenet@hotmail.com (Tom Widmer) wrote in message
>news:<pbasn0pl185sk6da00kq7ac380mimkch3p@4ax.com>...
>> I think it's conforming - the buffer member is part of the streambuf
>> derived class, and streambuf doesn't care what its contents are beyond
>> the setp configured portion of it, and doesn't even care about that
>> portion most of the time.
>
>I don't think that that's the problem.

There isn't a problem, at least that's what I was trying to say (and
apparently failing).

>  Within overflow, there is a
>buffer, which is adequately large.  The fact that the last character of
>this buffer is not "visible" through the put pointers is irrelevant.

I agree.

>On the other hand, I can't find any guarantee that overflow will never
>be called unless the visible buffer is full.

I'm pretty sure there is none.

>Of course, if he uses *pptr() to write the last character, knowing that
>pptr() is always writable because of the way the buffer was allocated,
>it is probably legal.

Agreed - the std::basic_streambuf has no way of knowing that the
pptr() is being dereferenced.

>> Personally, I tend to implement overflow
>> differently, by emptying the buffer if it's full (perhaps by calling
>> sync()), and then writing the new charater (if it isn't EOF) to the
>> start of the newly emptied buffer. overflow doesn't have to perform a
>> flush - that's what sync() is for - and the above makes the code
>> clearer.
>
>That's about the way I do it, too.  Basically, for buffered input,
>overflow is the equivalent of:
>
>    sync() ;
>    if ( c != EOF ) {
>        *pptr() = c ;
>        pbump( 1 ) ;
>    }

With the traits_type stuff and error checking added, yes.

Tom

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: daniel.frey@aixigo.de (Daniel Frey)
Date: Mon, 25 Oct 2004 20:28:24 GMT
Raw View
Hello, world!

I have a stream buffer class, which was written with the help of "The=20
C++ Standard Library" from Nicolai Josuttis. It works. So far, so good.

But I started to wonder if it is really standard conforming, as Nicolai=20
used the following trick:

- He reserved a buffer of size 'bufferSize' (p.674, 3rd printing).

- He tells the streambuf, that the size is only 'bufferSize - 1' (via=20
'setp (buffer, buffer+(bufferSize-1));')

- In the implementation of overflow(), a character is written in the=20
last character of the buffer, thus it's written one-past-the-end of the=20
buffer that the streambuf knows about. Nicolai writes explicitly: "This=20
moves the write position beyond the end position (epptr()) temporarily.".

My question: Is this conforming to the standard? Or should I find=20
another way of implementing overflow()? (Which is easy enough, no need=20
to provide code. I'm just curious what is correct C++).

Regards, Daniel

--=20
Daniel Frey

aixigo AG - financial solutions & technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de


---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tom_usenet@hotmail.com (Tom Widmer)
Date: Tue, 26 Oct 2004 21:13:41 GMT
Raw View
On Mon, 25 Oct 2004 20:28:24 GMT, daniel.frey@aixigo.de (Daniel Frey)
wrote:

>Hello, world!
>
>I have a stream buffer class, which was written with the help of "The
>C++ Standard Library" from Nicolai Josuttis. It works. So far, so good.
>
>But I started to wonder if it is really standard conforming, as Nicolai
>used the following trick:
>
>- He reserved a buffer of size 'bufferSize' (p.674, 3rd printing).
>
>- He tells the streambuf, that the size is only 'bufferSize - 1' (via
>'setp (buffer, buffer+(bufferSize-1));')
>
>- In the implementation of overflow(), a character is written in the
>last character of the buffer, thus it's written one-past-the-end of the
>buffer that the streambuf knows about. Nicolai writes explicitly: "This
>moves the write position beyond the end position (epptr()) temporarily.".
>
>My question: Is this conforming to the standard? Or should I find
>another way of implementing overflow()? (Which is easy enough, no need
>to provide code. I'm just curious what is correct C++).

I think it's conforming - the buffer member is part of the streambuf
derived class, and streambuf doesn't care what its contents are beyond
the setp configured portion of it, and doesn't even care about that
portion most of the time. Personally, I tend to implement overflow
differently, by emptying the buffer if it's full (perhaps by calling
sync()), and then writing the new charater (if it isn't EOF) to the
start of the newly emptied buffer. overflow doesn't have to perform a
flush - that's what sync() is for - and the above makes the code
clearer.

Note that if you have an earlier printing of the book, there are some
quite serious errors in the streambuf code, particularly in the input
streambuf (one of which had me scratching my head for quite a while
when some binary data would suddenly become cut off before the end
because a binary value of (char)-1 was being treated by the streambuf
as EOF). Take a look at the errata at www.josuttis.com if you haven't
already.

Tom

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Thu, 28 Oct 2004 11:12:21 GMT
Raw View
tom_usenet@hotmail.com (Tom Widmer) wrote in message
news:<pbasn0pl185sk6da00kq7ac380mimkch3p@4ax.com>...
> On Mon, 25 Oct 2004 20:28:24 GMT, daniel.frey@aixigo.de (Daniel Frey)
> wrote:

> >I have a stream buffer class, which was written with the help of "The
> >C++ Standard Library" from Nicolai Josuttis. It works. So far, so
> >good.

> >But I started to wonder if it is really standard conforming, as
> >Nicolai used the following trick:

> >- He reserved a buffer of size 'bufferSize' (p.674, 3rd printing).

> >- He tells the streambuf, that the size is only 'bufferSize - 1' (via
> >'setp (buffer, buffer+(bufferSize-1));')

> >- In the implementation of overflow(), a character is written in the
> >last character of the buffer, thus it's written one-past-the-end of
> >the buffer that the streambuf knows about. Nicolai writes explicitly:
> >"This moves the write position beyond the end position (epptr())
> >temporarily.".

> >My question: Is this conforming to the standard? Or should I find
> >another way of implementing overflow()? (Which is easy enough, no
> >need to provide code. I'm just curious what is correct C++).

> I think it's conforming - the buffer member is part of the streambuf
> derived class, and streambuf doesn't care what its contents are beyond
> the setp configured portion of it, and doesn't even care about that
> portion most of the time.

I don't think that that's the problem.  Within overflow, there is a
buffer, which is adequately large.  The fact that the last character of
this buffer is not "visible" through the put pointers is irrelevant.

On the other hand, I can't find any guarantee that overflow will never
be called unless the visible buffer is full.  The closest I can find is
   27.5.2.4.5/4: "Notes: the member functions sputc() and sputn() call
this function in case that no room can be found in the put buffer enough
to accomodate the argument character sequence."  But 1) this is just a
note, and so not normative, and 2) it specifies cases when the overflow
function will be called, but doesn't guarantee that the function won't
be called at other times.  In fact, even from the wording above, if in
sputn, pptr() - pbase() < n, it would seem that overflow may be called
immediately.

Of course, if he uses *pptr() to write the last character, knowing that
pptr() is always writable because of the way the buffer was allocated,
it is probably legal.

And of course, any code using this technique must refuse requests of
setbuf().

> Personally, I tend to implement overflow
> differently, by emptying the buffer if it's full (perhaps by calling
> sync()), and then writing the new charater (if it isn't EOF) to the
> start of the newly emptied buffer. overflow doesn't have to perform a
> flush - that's what sync() is for - and the above makes the code
> clearer.

That's about the way I do it, too.  Basically, for buffered input,
overflow is the equivalent of:

    sync() ;
    if ( c != EOF ) {
        *pptr() = c ;
        pbump( 1 ) ;
    }

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]