![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
# 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 message data, regardless of how the data is physically stored. Here's an overview:
head() .--------. returns a... | MIME:: | .------------>| Head | .--------. `--------' | MIME:: | | Entity | .--------. `--------' | MIME:: | `------------>| Body | .--------. read() bodyhandle() `--------' | MIME:: | getline() returns a... `------------>| IO | print() open() `--------' etc... returns a...
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.
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.
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.
# 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 on som OSes. This risk increases if the user application is processing more than one MIME entity at a time.
Body Stores body When open()ed, Someday soon class: data in: returns: will return: ---------------------------------------------------------------------- MIME::Body::File disk file MIME::IO::Handle IO::Handle MIME::Body::Scalar scalar MIME::IO::Scalar IO::????
$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.
Note: I would have had MIME::Body::File return a FileHandle, except that there are some methods that FileHandle does not support in 5.002, and it was too soon to require IO::Handle.
$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.
$CommentsMailTo = "perl5@dcs.ed.ac.uk"; include("../syssies_footer.inc");?>