MIME::IO - a small package for turning things into IO handles
As of MIME-tools 2.0, input and output routines cannot just assume that
they are dealing with filehandles. In an effort to come up with a nice, OO
way of encapsulating input/output streams, I decided to use a minimal
subset of Graham Barr's IO::Handle interface (which is itself derived from the FileHandle interface).
Therefore, all that MIME::Body, MIME::Decoder, and the other classes
require (and, thus, all that they can assume) is that they are manipulating
an object which responds to the following small, well-defined set of
messages:
- close
-
Instance method.
This should close the input/output stream.
- getline
-
Instance method.
This should get a single line from the input stream, and return it (or
undef on end of file). The returned line should end with the newline
(unless, of course, this is the last line of a file which is not terminated
by a newline).
- getlines
-
Instance method.
This should get the entire input stream as an array of lines, which each
line is terminated by the
"\n"
(except, maybe, the last one).
- print ARGS...
-
Instance method.
This should output the ARGS to the stream.
- read BUFFER,NBYTES
-
Instance method.
This should get NBYTES from the input stream, placing them in BUFFER. It
should return the number of bytes actually read, undef on error, and 0 on
end of file.
By popular demand, I have also added the following to the built-in classes,
but I do not use them anywhere in the parsing/generating code so it's safe
for you to omit them from your class:
- seek POS,WHENCE
-
Instance method, FOR READ-OPENED STREAMS ONLY.
Seek to the given POSition in the stream. The WHENCE has the same meaning
as in the Perl built-in seek().
- tell
-
Instance method, FOR READ-OPENED STREAMS ONLY.
Tell the given position in the stream.
Thanks to Achim Bohnet for suggesting this more-generic I/O model.
Thanks to Jason L Tibbitts III for suggesting the seek/tell interface.
- DESCRIPTION
-
An I/O interface object wrapped around a raw filehandle. If you hand this
class'
wrap()
constructor an argument, it is expected to be one of the following:
-
A raw scalar filehandle name, like
"STDOUT"
or "Class::HANDLE"
. In this case, the filehandle name is wrapped in a MIME::IO object, which
is returned.
-
A raw filehandle glob, like
\*STDOUT
. In this case, the filehandle glob is wrapped in a MIME::IO object, which
is returned.
-
A blessed FileHandle object.
In this case, the FileHandle is wrapped in a MIME::IO object if and only if
your FileHandle class does not support the read() method.
-
Any other kind of blessed object, which is assumed to be already conformant to the I/O object interface. In
this case, you just get back that object.
Like this:
my $IO = wrap MIME::IO::Handle \*STDOUT;
All this class does is to provide a simple means for the MIME:: classes to wrap raw filehandles
inside a class which responds to the above messages (by passing the
messages on to the actual filehandle in the form of the standard function
calls).
The bottom line: what you get back is an object which is guaranteed to
support the methods defined above.
This interface is used by many of the MIME-tool classes, for backwards
compatibility with earlier versions of MIME-parser: if you supply a raw
filehandle where an INSTREAM or OUTSTREAM is expected, most MIME packages
will automatically wrap that raw filehandle in a MIME::IO object, which
fits the I/O handle criteria.
- NOTES
-
Clearly, when wrapping a raw external filehandle (like \*STDOUT), I didn't
want to close the file descriptor when this object is destructed... since
the user might not appreciate that. Hence, there's no DESTROY method in
this class.
When wrapping a FileHandle object, however, I believe that Perl will invoke
the FileHandle::DESTROY when the last reference goes away, so in that case,
the filehandle is closed if the wrapped FileHandle really was the last
reference to it.
- DESCRIPTION
-
An I/O interface object wrapped around a scalar. This is to implement
things that look like filehandles, but which keep all of their data
in-core.
Use it like this:
$IO = new MIME::IO::Scalar \$scalar;
$IO->print("Some data\n");
$IO->print("Some more data\n");
$IO->close; # ...$scalar now holds "Some data\nSome more data\n"
I know, I know: three-level-nesting of packages is evil when those packages
are not ``private''. Sure, I could have made this two modules, MIME::IOHandle
and MIME::IOScalar
... but it just seemed more sensible to mimic the IO:: hierarchy, one level
down (under MIME::).
Copyright (c) 1996 by Eryq / eryq@rhine.gsfc.nasa.gov
All rights reserved. This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.
$Revision: 3.201 $ $Date: 1997/01/19 00:52:58 $
$CommentsMailTo = "perl5@dcs.ed.ac.uk"; include("../syssies_footer.inc");?>