Topic: Deriving from filebuf using Standard Library
Author: jkanze@otelo.ibmmail.com
Date: 1998/09/17 Raw View
In article <01bde0c4$43c46c40$8a1ec2d0@porky>,
"P.J. Plauger" <pjp@dinkumware.com> wrote:
> No. More like pptr() - pbase(), but be careful with such low-level
expressions.
> Pointers can be null.
Am I correct in assuming that the pointers returned by pptr() and pbase()
are either both null, or both point into the same object? (If not, the
result of the subtraction is undefined behavior.) If so, is this
guaranteed by the standard, or simply the consequences of any reasonable
implementation?
I am talking here only of the cases actually defined by the standard,
such as filebuf. Obviously, if I derive from streambuf, and call setp
with arbitrary values, then pptr and pbase are likely to return these
arbitrary values. Which raises a second question: are there any constraints
in the standard as to the values I can pass to setp? (One would hope so,
since it is going to be very hard on the implementer of streambuf if there
isn't.)
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient=E9e objet --
-- Beratung in objektorientierter Datenverarbeitung
-----=3D=3D Posted via Deja News, The Leader in Internet Discussion =3D=3D=
-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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: jkanze@otelo.ibmmail.com
Date: 1998/09/15 Raw View
In article <01gL1.896$yj.4417563@newsr2.u-net.net>,
"Dr Paul A Bristow" <pbristow@hetp.u-net.com> wrote:
>
> MSVC++5 documentation gives an example of deriving a class called hstreambuf
> from filebuf.
> (It actually transfers some input to the printer port ('file' PRN) to format
> it on an HP Laserjet printer in landscape two up per page - which is quite
> environmentally friendly!)
>
> I have tried to convert this to use the C++ Standard Library but am stuck at
> several places.
> First I can't find the equivalent of the filedesc or handle from:
>
> filebuf fb;
> fb.open("PRN", ios::out);
> if (!fb.is_open() ) exit(somehow); // But it always is open
> int fd = fb.fd(); // actually 3 for PRN (1 for cout?)
> used thus:
> hstreambuf hsb(fd);
The notion of an integral file descripter doesn't exist in the standard
(since not all systems would support it), but it is a frequent extension.
> hstreambuf::hstreambuf(int filed) : filebuf(filed)
> { ....} // constructor ... details in the example given - sends prolog to
> printer to set to landscape etc
This sounds like a candidate for a filtering streambuf (see my article
in the Sept. C++ Reports); the "correct" idiom here is delegation, rather
than inheritance. Basically, hstreambuf should derive directly from
streambuf, and take a pointer to the filebuf.
> hstreambuf prints heading with page numbers, the text input, and moves to
> right hand page
> after 56 lines.
>
> destructor sends an epilog to finish page.
>
> Nor can I find the equivalent of out_waiting() ( is this same as pptr() -
> pbump()??)
I have no idea what this function is or should do, but from the code in
the example, it looks like it is just pptr() - pbase().
Note that in addition to having bad design (using inheritance where
delegation is the normal solution) the code in the example doesn't work
for accented characters (or for that matter, if the source contains a
DEL character), and the buffer handling is tricky and error prone, to
say the least. Try to determine what is happening with each character,
and rewrite it correctly using a filtering streambuf; I think the experience
will be interesting for you, and the results will probably be more robust
that the example code. (In general, you shouldn't bother buffering in
a filtering streambuf, since the final destination will do it for you.)
Note that my filtering streambuf's do not provide for a prologue and an
epilogue. If you use them, you will have to modify the template code
to support this. Then, the extractor function ( operator()() ) of the
instantiation class would look something like this:
int
HPInserter::operator()( std::streambuf& dest , int ch )
{
int result = traits_type::eof() ;
switch ( ch )
{
case '\t' : // ...
case '\n' : // ...
// ...
default :
if ( isprint( static_cast< char >( ch ) , getloc() ) )
result = dest.sputc( ch ) ;
break ;
}
return result ;
}
Even this is a bit of a hack, since the static_cast may invoke undefined
behavior (say if ch > CHAR_MAX); in practice, I've never seen an
implementation where it wouldn't work.
Note that if the native code set on this machine isn't the same as that
on the HP printer, you'll have to define the correct locale for the
filebuf, too, in order to do the conversion. In practice, there's is
a very good chance that both use ISO 8859-1, however.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient e objet --
-- Beratung in objektorientierter Datenverarbeitung
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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: "P.J. Plauger" <pjp@dinkumware.com>
Date: 1998/09/15 Raw View
Dr Paul A Bristow <pbristow@hetp.u-net.com> wrote in article <01gL1.896$yj.4417563@newsr2.u-net.net>...
> First I can't find the equivalent of the filedesc or handle from:
>
> filebuf fb;
> fb.open("PRN", ios::out);
> if (!fb.is_open() ) exit(somehow); // But it always is open
> int fd = fb.fd(); // actually 3 for PRN (1 for cout?)
The member function filebuf::fd is not a part of Standard C++, for good
and proper reasons. VC++ does, however, have a conforming extension
that should give you what you want. Open the file with fopen, then use
the pointer to FILE to create the filebuf, as in:
FILE *pf = fopen("PRN", "w");
filebuf fb(pf); // extension
(Error checking code omitted.) Now you know how to refer to the file by
more traditional means.
> Nor can I find the equivalent of out_waiting() ( is this same as pptr() -
> pbump()??)
No. More like pptr() - pbase(), but be careful with such low-level expressions.
Pointers can be null.
P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com/hot_news.html
[ 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: Matt Austern <austern@sgi.com>
Date: 1998/09/15 Raw View
"P.J. Plauger" <pjp@dinkumware.com> writes:
> > Nor can I find the equivalent of out_waiting() ( is this same as pptr() -
> > pbump()??)
>
> No. More like pptr() - pbase(), but be careful with such low-level expressions.
> Pointers can be null.
But if any one of the put area pointers is null then the other two
must be null as well, and subtracting one null pointer from another is
well defined. (5.7, paragraph 8.)
[ 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: "Dr Paul A Bristow" <pbristow@hetp.u-net.com>
Date: 1998/09/14 Raw View
MSVC++5 documentation gives an example of deriving a class called hstreambuf
from filebuf.
(It actually transfers some input to the printer port ('file' PRN) to format
it on an HP Laserjet printer in landscape two up per page - which is quite
environmentally friendly!)
I have tried to convert this to use the C++ Standard Library but am stuck at
several places.
First I can't find the equivalent of the filedesc or handle from:
filebuf fb;
fb.open("PRN", ios::out);
if (!fb.is_open() ) exit(somehow); // But it always is open
int fd = fb.fd(); // actually 3 for PRN (1 for cout?)
used thus:
hstreambuf hsb(fd);
hstreambuf::hstreambuf(int filed) : filebuf(filed)
{ ....} // constructor ... details in the example given - sends prolog to
printer to set to landscape etc
hstreambuf prints heading with page numbers, the text input, and moves to
right hand page
after 56 lines.
destructor sends an epilog to finish page.
Nor can I find the equivalent of out_waiting() ( is this same as pptr() -
pbump()??)
Theanks for any suggestions on what I should be doing?
Paul Bristow
hetp Chromatography, pbristow at hetp.u-net.com
[ 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 ]