Home | MIME::Body | MIME::Decoder | MIME::Entity | MIME::Head |
MIME::IO | MIME::Latin1 | MIME::Parser | MIME::ParserBase | |
MIME::ToolUtils |
MIME::
|
# Create new body: $body = new MIME::Body::File "/path/to/file"; # Write data to the body: $IO = $body->open("w") || die "open body: $!"; $IO->print($message); $IO->close || die "close I/O handle: $!"; # Read data from the body: $IO = $body->open("r") || die "open body: $!"; while (defined($_ = $IO->getline)) { # do stuff } $IO->close || die "close I/O handle: $!";
For example, this subclass stores the data in a disk file, which is only opened when needed:
$body = new MIME::Body::File "/path/to/file";
While this subclass stores the data in an in-core scalar:
$body = new MIME::Body::Scalar \$scalar;
In any case, once a MIME::Body has been created, you use the same mechanisms for reading from or writing to it, no matter what the subclass is.
This class is an attempt to define a common interface for objects which contain that message data, regardless of how the data is physically stored. It works this way:
new()
is invoked. (For example: if the body data is going to a file, then it is
at this point that the class MIME::Body::File, and
the filename, is chosen).
a. Body is opened for writing, via open("w")
. This will trash any previous contents, and return an ``I/O handle''
opened for writing.
b. Data is written to the I/O handle, via print().
c. I/O handle is closed, via close().
a. Body is opened for reading by a user application, via open("r")
. This will return an ``I/O handle'' opened for reading.
b. Data is read from the I/O handle, via read(),
getline(),
or getlines().
c. I/O handle is closed, via close().
Users should be aware that unless they know for certain what they have, they should not assume that the body has an underlying filehandle.
new_body_for(head)
method.
Things to make you go hmm: there's nothing stopping you from writing a single class that is both a ``body'' class and an ``I/O handle'' class for that body. Look at MIME::Body::Scalar for an example.
new()
, with the arguments given to new()
. The arguments are optional, and entirely up to your class.
open()
should return an
I/O handle which has binmode()
activated. With no argument,
just returns the current value. The inherited action should be fine.
open()
method must return an ``I/O handle'' object, which can be any object that
supports a small set of standard methods for reading/writing data.
See the documentation on the MIME::IO class for details on what is expected of an I/O handle. Note that the IO::Handle class already conforms to this interface, as does MIME::IO .
# Get body handle from this MIME message, and read its data: $body = $entity->bodyhandle; $IO = $body->open("r"); while (defined($_ = $IO->getline)) { print STDOUT $_; } $IO->close;
...without requiring that they know anything more about how the
$body
object is actually storing its data (disk file, scalar
variable, array variable, or whatever).
Storing the body of each MIME message in a persistently-open IO::Handle was a possibility, but it seemed like a bad idea, considering that a single multipart MIME message could easily suck up all the available file descriptors. This risk increases if the user application is processing more than one MIME entity at a time.
$body = new MIME::Body::File "/path/to/file";
In this case, the path method would return the given path.
You can even use this class to pipe the data through shell commands on input and/or output. For example, here's an easy way to store the data in compressed format without having to explicitly do the compression yourself:
$body = new MIME::Body::File "/tmp/somefile.gz"; $body->writer("| gzip > /tmp/somefile.gz"); $body->reader("zcat /tmp/somefile.gz |"); ... $IO = $body->open("w") || die "open failed: $!"; $IO->print("I'll automatically be stored compressed!\n"); $IO->close || die "close failed: $!";
Notice the semantics of the ``path'' in this case: it names the file that is created to hold the data, even though that file can't be used directly.
Note: All of the usual caveats related to shell commands apply! To make sure you won't accidentally do something you'll regret, use taint-checking (perl -T ) in your application.
$body = new MIME::Body::Scalar \$scalar;
A single scalar argument sets the body to that value, exactly as though
you'd opened for the body for writing, written the value, and closed the
body again: $body
= new MIME::Body::Scalar ``Line 1\nLine 2\nLine 3'';
A single array reference sets the body to the result of joining all the elements of that array together:
$body = new MIME::Body::Scalar ["Line 1\n", "Line 2\n", "Line 3"];
Uses MIME::IO::Scalar as the I/O handle.
All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Thanks to Achim Bohnet for suggesting that MIME::Parser not be restricted to the use of FileHandles.