MIME::IO

Home | MIME::Body | MIME::Decoder | MIME::Entity | MIME::Head
MIME::IO | MIME::Latin1 | MIME::Parser | MIME::ParserBase
MIME::ToolUtils

# MIME:: IO It's MIME time! | NAME DESCRIPTION BUILT-IN SUBCLASSES MIME::IO::Handle MIME::IO::Scalar NOTES AUTHOR VERSION

## NAME

MIME::IO - a small package for turning things into IO handles

## DESCRIPTION

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.

## BUILT-IN SUBCLASSES

### MIME::IO::Handle

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.

### MIME::IO::Scalar

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"

## NOTES

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::).

## AUTHOR

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.

## VERSION

$Revision: 3.201 $ $Date: 1997/01/19 00:52:58 $