 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
John Dill Guest
|
Posted: Thu Oct 16, 2003 9:00 pm Post subject: xsputn and overflow |
|
|
I am wondering if you overload the xsputn function in a streambuf,
does it make overloading overflow redundant? For example, if I am
managing a buffer in my streambuf where xsputn facilitates the buffer
management, is overflow ever going to be used, other than being called
directly?
Another way to put the question is if I overload xsputn, is overflow
called indirectly from somewhere else?
Thanks,
John
[ 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: Fri Oct 17, 2003 4:49 pm Post subject: Re: xsputn and overflow |
|
|
| Quote: | I am wondering if you overload the xsputn function in a streambuf,
does it make overloading overflow redundant? For example, if I am
managing a buffer in my streambuf where xsputn facilitates the buffer
management, is overflow ever going to be used, other than being called
directly?
Another way to put the question is if I overload xsputn, is overflow
called indirectly from somewhere else?
|
Thanks for the email responses. I guess really my question is how
should a streambuf's functions be implemented in terms of one another.
Should sync be implemented in terms of overflow for flushing the
buffer for instance? The relationships between overflow, sync, and
xsputn as far as which function should call which (if at all) would be
nice, and ditto for underflow, uflow, (sync?), and xsgetn.
Best,
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Paolo Carlini Guest
|
Posted: Fri Oct 17, 2003 7:04 pm Post subject: Re: xsputn and overflow |
|
|
John Dill wrote:
| Quote: | ... is overflow
called indirectly from somewhere else?
|
Definitely! The following, f.i. is the current implementation of
sputc in mainline libstdc++-v3.
int_type
sputc(char_type __c)
{
int_type __ret;
if (__builtin_expect(this->pptr() < this->epptr(), true))
{
*this->pptr() = __c;
this->pbump(1);
__ret = traits_type::to_int_type(__c);
}
else
__ret = this->overflow(traits_type::to_int_type(__c));
return __ret;
}
Paolo.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dietmar Kuehl Guest
|
Posted: Fri Oct 17, 2003 10:01 pm Post subject: Re: xsputn and overflow |
|
|
John Dill wrote:
| Quote: | I am wondering if you overload the xsputn function in a streambuf,
does it make overloading overflow redundant? For example, if I am
managing a buffer in my streambuf where xsputn facilitates the buffer
management, is overflow ever going to be used, other than being called
directly?
|
Overriding 'overflow()' makes implementing 'xsputn()' redundant but
not the other way around: 'xsputn()' is defined to behave as if a
sequence of 'sputc()' calls are issued but it will use a more clever
approach if there is a buffer. 'xsputn()' is a pure optimization hook
you can use if overriding 'overflow()' alone does not yield in
sufficient performance. However, it is actually rarely called directly.
For example, numeric formatting uses 'std::ostreambuf_iterator<...>'s
which use 'sputc()' internally but only calls to 'sputn()' call
'xsputn()'.
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Oct 19, 2003 10:04 pm Post subject: Re: xsputn and overflow |
|
|
Dietmar Kuehl <dietmar_kuehl (AT) yahoo (DOT) com> writes:
| Quote: | John Dill wrote:
I am wondering if you overload the xsputn function in a
streambuf, does it make overloading overflow redundant? For
example, if I am managing a buffer in my streambuf where xsputn
facilitates the buffer management, is overflow ever going to be
used, other than being called directly?
Overriding 'overflow()' makes implementing 'xsputn()' redundant but
not the other way around: 'xsputn()' is defined to behave as if a
sequence of 'sputc()' calls are issued but it will use a more clever
approach if there is a buffer.
|
I would have thought that the real win would be if there wasn't a
buffer. If say I'm writing to an unbuffered file -- overflow will
always do a write( fd, &ch, 1 ), where as xsputn would do a write( fd,
buffer, n ).
| Quote: | 'xsputn()' is a pure optimization hook you can use if overriding
'overflow()' alone does not yield in sufficient performance.
However, it is actually rarely called directly. For example, numeric
formatting uses 'std::ostreambuf_iterator<...>'s which use 'sputc()'
internally but only calls to 'sputn()' call 'xsputn()'.
|
This is horrible. The normal way of converting an int ends up with the
digits backwards; you have to generate all of the digits before
outputting the first. The fastest and easiest way I know of doing this
is to generate into an in memory buffer, using *--p to write each digit,
then output the lot with xsputn.
--
James Kanze mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Oct 19, 2003 10:05 pm Post subject: Re: xsputn and overflow |
|
|
[email]john-dill (AT) uiowa (DOT) edu[/email] (John Dill) writes:
| Quote: | I am wondering if you overload the xsputn function in a streambuf,
does it make overloading overflow redundant? For example, if I am
managing a buffer in my streambuf where xsputn facilitates the
buffer management, is overflow ever going to be used, other than
being called directly?
Another way to put the question is if I overload xsputn, is
overflow called indirectly from somewhere else?
Thanks for the email responses. I guess really my question is how
should a streambuf's functions be implemented in terms of one
another.
|
Why not, if the semantics fit. I usually implement overflow in terms of
sync, but the reverse is also possible.
With regards to xsputn, it is in addition to other functions. As far as
I know, it is never called by sputc, only by sputn. If you cannot
implement it better than by just calling sputc, don't bother. If you
can, it might speed up certain operations, but it is never required.
Overflow IS required.
| Quote: | Should sync be implemented in terms of overflow for flushing the
buffer for instance?
|
As I said, I've usually done the reverse.
| Quote: | The relationships between overflow, sync, and xsputn as far as which
function should call which (if at all) would be nice,
|
IMHO, either overflow should call sync, or sync call overflow -- you
don't want the same functionality twice:-). For xsputn, I've yet to
implement it; it only makes sense when you can improve the performance
by skipping some of the buffering in sputc.
| Quote: | and ditto for underflow, uflow, (sync?), and xsgetn.
|
Formally, there is no need for sync to do anything on input. I used it
in filtering streambuf's to resynchronize with the original source,
putting back any unextracted characters, but this is really more of an
extension than anything else; I'm not sure it's that good for anything
either, since as I've implemented it, it doesn't chain, and in my actual
applications, I've never called it from anywhere but the destructor.
I'm not too familiar with uflow. At present, I still have to deal with
some classical streams which don't support it. Everything works without
redefining it, so unless there is some real gain... (Dietmar Kuehl
knows more about this side of things that I do.) As of xsgetn, the same
thing holds as with xsputn -- the default implementation calls sbumpc;
if you can't do better by going around the buffering, don't bother.
--
James Kanze mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Mon Oct 20, 2003 9:14 pm Post subject: Re: xsputn and overflow |
|
|
James Kanze <kanze (AT) alex (DOT) gabi-soft.fr> wrote:
| Quote: | 'xsputn()' is a pure optimization hook you can use if overriding
|> 'overflow()' alone does not yield in sufficient performance.
|> However, it is actually rarely called directly. For example, numeric
|> formatting uses 'std::ostreambuf_iterator<...>'s which use 'sputc()'
|> internally but only calls to 'sputn()' call 'xsputn()'.
This is horrible. The normal way of converting an int ends up with the
digits backwards; you have to generate all of the digits before
outputting the first. The fastest and easiest way I know of doing this
is to generate into an in memory buffer, using *--p to write each digit,
then output the lot with xsputn.
That creates the raw digits but it does not format the resulting |
output very easily.
The operator << () uses the locale infromation and the formatting
flags/settings to output the results, meaning that it is likely that the
outputhe ostreambuf_iterator approach is not so inefficient as it first
appears. operator << () eventually gets the num_put facet from the
stream's locale and does the actual output through this facet's member
function put(). If you think you can do it in reverse you can write a
class derived from num_put and providing the virtual function's do_put()
to actually do it.:)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Mon Oct 20, 2003 9:17 pm Post subject: Re: xsputn and overflow |
|
|
James Kanze <kanze (AT) alex (DOT) gabi-soft.fr> wrote:
| Quote: | john-dill (AT) uiowa (DOT) edu (John Dill) writes:
|> > I am wondering if you overload the xsputn function in a streambuf,
|> > does it make overloading overflow redundant? For example, if I am
|> > managing a buffer in my streambuf where xsputn facilitates the
|> > buffer management, is overflow ever going to be used, other than
|> > being called directly?
|> > Another way to put the question is if I overload xsputn, is
|> > overflow called indirectly from somewhere else?
|> Thanks for the email responses. I guess really my question is how
|> should a streambuf's functions be implemented in terms of one
|> another.
Why not, if the semantics fit. I usually implement overflow in terms of
sync, but the reverse is also possible.
With regards to xsputn, it is in addition to other functions. As far as
I know, it is never called by sputc, only by sputn. If you cannot
implement it better than by just calling sputc, don't bother. If you
can, it might speed up certain operations, but it is never required.
Overflow IS required.
|> Should sync be implemented in terms of overflow for flushing the
|> buffer for instance?
As I said, I've usually done the reverse.
|> The relationships between overflow, sync, and xsputn as far as which
|> function should call which (if at all) would be nice,
IMHO, either overflow should call sync, or sync call overflow -- you
don't want the same functionality twice:-). For xsputn, I've yet to
implement it; it only makes sense when you can improve the performance
by skipping some of the buffering in sputc.
|> and ditto for underflow, uflow, (sync?), and xsgetn.
Formally, there is no need for sync to do anything on input. I used it
in filtering streambuf's to resynchronize with the original source,
putting back any unextracted characters, but this is really more of an
extension than anything else; I'm not sure it's that good for anything
either, since as I've implemented it, it doesn't chain, and in my actual
applications, I've never called it from anywhere but the destructor.
I'm not too familiar with uflow. At present, I still have to deal with
some classical streams which don't support it. Everything works without
redefining it, so unless there is some real gain... (Dietmar Kuehl
knows more about this side of things that I do.) As of xsgetn, the same
thing holds as with xsputn -- the default implementation calls sbumpc;
if you can't do better by going around the buffering, don't bother.
|
The important virtual functions for output, are sync() and
overflow(). Overflow() is ussually required since the default
overflow() [that in basic_streambuf<C,T>] always returns failure. If the
stream buffer is bufferd. then sync() is required to flush the buffer to
the device... It too defaults to always returning failure.
sputn() returns the result of xsputn(), which defaults to outputing
the data via sbumpc().
For input the impprtant virtual functions are
underflow(),uflow(),pbackfail().
Underflwo is called when sgetc() has no buffer or the buffer has been
exhausted. uflow is called by sbumpc() when there is no buffer or the
buffer has been exhausted. Underflow defaults to returning failure.
Uflow defaults to using underflow and advancing the pointer. Pbackfail
is called if a char can not be put back by merely adjusting the current
poiniter. That is either it is a the start of the buffer, or the
character to put back is not the character in the buffer position.
Sgetn() returns the result of xsgetn() and defaults to calling sbumpc()
to do the transfer.
I hardly ever impliment xsgetn() or xsputn() except if it is
signifigantly faster than the default. fairly large blocks of data in an
unbufferd streambuf come to mind, such as a streambuf to use cstdio
(FILE *) io, then in general the buffering done by FILE is sufficient
for char read/writes, but freadd/fwrite will be faster then alot of
fgetc(),fputc()'s.
If you want your stream buffer to be seekable you must write seekpos()
and seekoff() ans these default to always returning failure.
if your streambuf uses any of std::locale, you must write imbue which is
used to change locale info in the streambuf. basic_ios::imbue() changes
the locale info in the stream and calls rdbuf()->pubimbue() to get the
stream buffer in sync with basic_ios. pubimbue calls imbue. I think the
default imbue() of the standard does nothing, but am not sure as my
compiler's implimentation notes its implimentation as non standard.
hope this helps someone.
[ 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: Tue Oct 21, 2003 3:38 pm Post subject: Re: xsputn and overflow |
|
|
Dietmar Kuehl <dietmar_kuehl (AT) yahoo (DOT) com> wrote
| Quote: | John Dill wrote:
I am wondering if you overload the xsputn function in a streambuf,
does it make overloading overflow redundant? For example, if I am
managing a buffer in my streambuf where xsputn facilitates the buffer
management, is overflow ever going to be used, other than being called
directly?
Overriding 'overflow()' makes implementing 'xsputn()' redundant but
not the other way around: 'xsputn()' is defined to behave as if a
sequence of 'sputc()' calls are issued but it will use a more clever
approach if there is a buffer. 'xsputn()' is a pure optimization hook
you can use if overriding 'overflow()' alone does not yield in
sufficient performance. However, it is actually rarely called directly.
For example, numeric formatting uses 'std::ostreambuf_iterator<...>'s
which use 'sputc()' internally but only calls to 'sputn()' call
'xsputn()'.
|
It appears that the only application that I've seen with xsputn was
when the stream was dynamically resizing a output buffer and instead
of incrementing the buffer size by one in overflow repeatedly, just
expanded the buffer by the right size in xsputn. If you are
processing character by character, is there much gain in using a
buffer for output?
I've also been wondering what would be the advantages of having a
input buffer for a filtering streambuf (more than one char). The main
thing that I can think of is >1 char putback perhaps, would could be
useful in some serialization contexts. Any other
advantages/disadvantages?
Best,
John
[ 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: Tue Oct 21, 2003 3:51 pm Post subject: Re: xsputn and overflow |
|
|
| Quote: | Formally, there is no need for sync to do anything on input. I used it
in filtering streambuf's to resynchronize with the original source,
putting back any unextracted characters, but this is really more of an
extension than anything else; I'm not sure it's that good for anything
either, since as I've implemented it, it doesn't chain, and in my actual
applications, I've never called it from anywhere but the destructor.
I'm not too familiar with uflow. At present, I still have to deal with
some classical streams which don't support it. Everything works without
redefining it, so unless there is some real gain... (Dietmar Kuehl
knows more about this side of things that I do.) As of xsgetn, the same
thing holds as with xsputn -- the default implementation calls sbumpc;
if you can't do better by going around the buffering, don't bother.
|
I'm still struggling with this idea of buffered input streambuf
support between underflow and uflow. There are a couple of
applications I can think of where this could be used. The first is
multiple putback char where the streambuf would store a buffer of char
read which could be putback into the stream in reverse order. The
second is something like a text structure of the information held in a
class, but if the format fails, it would put all the character data
read back into the input stream automatically for you (I don't know if
this is outside the scope of streambuf).
Another thing I noticed was the behavior of unget in your
FilteringInputStreambuf. Since the extraction of a character goes
through the filter you define, if you putback the pushback buffer, the
processed character goes back, not the original. For example if you
defined an uppercase filter, and you read a character and then put it
back, you would put back the uppercased character, correct? If you
eat or ignore characters, then you can not restore the stream contents
to before the read correct?
I don't really know if either of these are really useful either.
Would either of these have any good applications?
Thanks,
John
[ 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: Wed Oct 22, 2003 6:15 pm Post subject: Re: xsputn and overflow |
|
|
[email]john-dill (AT) uiowa (DOT) edu[/email] (John Dill) wrote in message
news:<302c79f4.0310201012.69686986 (AT) posting (DOT) google.com>...
| Quote: | Dietmar Kuehl <dietmar_kuehl (AT) yahoo (DOT) com> wrote in message
news:<bmnh7p$n1onc$1 (AT) ID-86292 (DOT) news.uni-berlin.de>...
John Dill wrote:
I am wondering if you overload the xsputn function in a
streambuf, does it make overloading overflow redundant? For
example, if I am managing a buffer in my streambuf where xsputn
facilitates the buffer management, is overflow ever going to be
used, other than being called directly?
Overriding 'overflow()' makes implementing 'xsputn()' redundant but
not the other way around: 'xsputn()' is defined to behave as if a
sequence of 'sputc()' calls are issued but it will use a more clever
approach if there is a buffer. 'xsputn()' is a pure optimization
hook you can use if overriding 'overflow()' alone does not yield in
sufficient performance. However, it is actually rarely called
directly. For example, numeric formatting uses
'std::ostreambuf_iterator<...>'s which use 'sputc()' internally but
only calls to 'sputn()' call 'xsputn()'.
It appears that the only application that I've seen with xsputn was
when the stream was dynamically resizing a output buffer and instead
of incrementing the buffer size by one in overflow repeatedly, just
expanded the buffer by the right size in xsputn. If you are
processing character by character, is there much gain in using a
buffer for output?
I've also been wondering what would be the advantages of having a
input buffer for a filtering streambuf (more than one char). The main
thing that I can think of is >1 char putback perhaps, would could be
useful in some serialization contexts. Any other
advantages/disadvantages?
|
In both cases: if sgetc (or sbumpc or snextc) find the desired
characters in the buffer, they don't call underflow. Typically, sgetc,
sbumpc and snextc will be small, inlined functions; underflow will be a
virtual function. The performance difference can be important.
In my own cases, it never has been, so I haven't worried about it. Who
cares about performance when reading a configuration file, and handling
buffering through several layers of filtering streambuf's, most of which
skipped characters on input, is far from trivial. On the other hand, if
you're parsing large programs in Fortran, buffering a filtering
streambuf which converted everything to upper case might make a
difference, and wouldn't be too difficult to handle -- the filtering
streambuf would use xsgetn to read a block, and then convert it
(resulting in two virtual function calls per block, rather than two per
character).
--
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 |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Wed Oct 22, 2003 6:15 pm Post subject: Re: xsputn and overflow |
|
|
[email]john-dill (AT) uiowa (DOT) edu[/email] (John Dill) wrote in message
news:<302c79f4.0310201428.71b42357 (AT) posting (DOT) google.com>...
[...]
| Quote: | Another thing I noticed was the behavior of unget in your
FilteringInputStreambuf. Since the extraction of a character goes
through the filter you define, if you putback the pushback buffer, the
processed character goes back, not the original. For example if you
defined an uppercase filter, and you read a character and then put it
back, you would put back the uppercased character, correct?
|
Right, but in this case, you are putting back to the filtering
streambuf, and not to the original source. So the behavior is normal.
| Quote: | If you eat or ignore characters, then you can not restore the stream
contents to before the read correct?
|
Correct, but again, you are putting back to the filtering streambuf, and
not to the original source.
There is one place where there could be a problem. When you close a
filtering input streambuf, if there is an unextracted character in its
buffer, that character gets put back to the original source. Even
though it has been "filtered". If the filtering streambuf reads ahead,
after having extracted the character it will return, or if it
translates, as in your toupper example, then the character put back will
not correspond to the one read from the original streambuf.
To tell the truth, it's something I hadn't really considered (i.e. what
happens is what happens, and not something I actually specified, then
coded).
In practice, this has never cause me a problem, but that is doubtlessly
because I've never been in either of the cases I just mentioned. The
only times I've closed a filtering streambuf and read further on the
original source is when the filtering streambuf detected its end of
file, say by recognizing a special character at the start of the line.
In such cases, the filtering streambuf can easily unget the untranslated
character, or even take the precaution of reading it via a sgetc, so
that there is nothing left for the destructor to put back.
Thus, in practice, I'm not sure how useful this feature of the filtering
streambuf putting back the unextracted character in its buffer actually
is.
| Quote: | I don't really know if either of these are really useful either.
Would either of these have any good applications?
|
All I can say is that I've never needed them. And I've used filtering
streambuf's in just about every application I've worked on for the last
ten years.
--
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 |
|
 |
Dietmar Kuehl Guest
|
Posted: Wed Oct 22, 2003 8:02 pm Post subject: Re: xsputn and overflow |
|
|
[email]john-dill (AT) uiowa (DOT) edu[/email] (John Dill) wrote:
| Quote: | I'm still struggling with this idea of buffered input streambuf
support between underflow and uflow.
|
For buffered input there is no point in implementing 'uflow()'. Actually,
my understanding *was* that both 'underflow()' and 'uflow()' are necessary
for unbuffered input: 'underflow()' would return always the same character
until 'uflow()' is called which returns the character but moves one such
that the next call to 'underflow()' or 'uflow()' return the next character.
Recently, I was convinced by a discussion here that 'underflow()' is
actually supposed to setup the buffer delimited by 'gptr()' and 'egptr()'
to contain at least the returned character. In this case, I see no point
in 'uflow()' at all: moving on to the next character is accomplished by
calling 'gbump(1)' in this case. That is, rather than being necessary,
'uflow()' may be only a performance improvement, even for unbuffered I/O.
| Quote: | Another thing I noticed was the behavior of unget in your
FilteringInputStreambuf. Since the extraction of a character goes
through the filter you define, if you putback the pushback buffer, the
processed character goes back, not the original.
|
That's a good one! Personally, I don't see any need nor good in ungetting
characters. However, if ungetting of characters is to be supported by a
filtering stream buffer, I would guess that this effectively requires
that the filtering stream buffer actually buffers at least the ungot
characters.
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
[ 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: Fri Oct 24, 2003 12:30 am Post subject: Re: xsputn and overflow |
|
|
[email]dietmar_kuehl (AT) yahoo (DOT) com[/email] (Dietmar Kuehl) wrote in message
news:<5b15f8fd.0310220353.7601445b (AT) posting (DOT) google.com>...
[...]
| Quote: | Another thing I noticed was the behavior of unget in your
FilteringInputStreambuf. Since the extraction of a character goes
through the filter you define, if you putback the pushback buffer,
the processed character goes back, not the original.
That's a good one! Personally, I don't see any need nor good in
ungetting characters. However, if ungetting of characters is to be
supported by a filtering stream buffer, I would guess that this
effectively requires that the filtering stream buffer actually buffers
at least the ungot characters.
|
I think the question here is more with regards to the relationship
between the filtering streambuf and its actual source. When I actually
implemented my first filtering streambuf, I asked myself what should
happen if the user decided to return to the unfiltered streambuf.
Generally speaking, I would expect that any characters not actually
extracted in the filtering streambuf would be present in the original
source. If the character is in my one character local buffer, however,
it has been extracted from the original source, but not from the
filtering streambuf, and thus not in so far as the user is concerned.
The result is that in the destructor, if the input buffer is not empty,
the character it contains is put back into the original streambuf. As
was correctly pointed out, this is the mapped character, however, and
not the unmapped one. Or if some input causes the generation of extra
characters in the filtering streambuf, it could be a character that was
never in the original stream.
As for an example as to why this might be a problem, imagine reading a
stream of text in Deganavari. At some point in the text, your parser
says that the next thing to be read is a number. In Deganavari. The
numeric conversion routines of the iostream only handle Latin Arabic
digits, however. So you quickly slip in a filtering streambuf which
converts Deganavari digits (u0966-u096F) into Latin Arabic digits
(u0030-u0039), use << to read the number, and then remove the
filtering streambuf. Of course, the << (actually num_get, of course)
will have "looked ahead" at least one more character to see where to
stop; that character will have been extracted from the original stream,
but not from the filtering streambuf. If the filtering streambuf
doesn't somehow unget this character, it is lost.
Now imagine that in addition to the ten decimal digits, I also map
things like Deganavari equivalents of a-f (for hex), my Deganavari input
is the equivalent of "123ab", and I use my current streambuf strategy.
Without the unget, the client code sees the equivalent of "123b",
definitly an error. With it, the client code sees "123ab", but with a
Latin 'a' (u0061), and not the Deganavari equivalent that was in the
original code (probably something like u0915 or u091F). Also an
error.
I'm not sure what to do about this. Handling it completely correctly is
relatively complex, and requires some degree of interaction with the
user defined parts of the class -- the template part has no way of
knowing if and when the user defined part is inserting characters
directly, instead of from the original source, nor what mappings it is
using. Which means that the complexity percolates to the outside -- not
just the template, but the user instantiations are affected. For a
problem which doesn't really occur in most cases. (Well, it's never
occured in any of my filtering streambufs.)
I'll have to think about it, and see what I can come up with.
--
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 |
|
 |
|
|
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
|
|