MIME::Xparser - A mime parser that is somewhat reminiscent of the way SAX parses XML (i.e. it invokes callbacks as things are found).
use Your_Content_Handler; use MIME::Xparser;
my $handler = new Your_Content_Handler; my $parser = new MIME::Xparser;
$parser->set_content_handler($handler);
$parser->start_document(); while (<YOUR_FILE>) { $parser->line($_); } $parser->end_document();
A program which wishes to parse a mime document feeds lines of input to the parser (as shown above).
The parser examines each line fed to it, and invokes a series of handler methods (listed below) at the appropriate time.
The handler methods are provided by the handler class, which you must provide.
Structure methods are used to communicate the structure of the document to your handler.
Data methods are used to pass the lines of data to your handler. The data is not altered. The data is explicitly categorized via the method invoked to pass the data, and implicitly categorized by the sequence of structure calls.
The parser provides no information about the document except the structure.
It is up to the content handler to save and parse out what ever data it needs when handling the document. One utility function is available that may help. A later version of this module may provide some additional assistance, though it will never be the intention of this module to handle the content of a mime document except as required to find its structure.
As mentioned, you must provide the handler. The source code includes several simple handlers at the very top. The distribution includes two sample scripts that define handlers and parse data.
Returns a parser object. You can specifiy the handler at this time if you wish.
Sets the content handler to use. No useful return value.
Tells the parser you are about to start parsing a document. No useful return value.
Tells the parser you have finished parsing a document. No useful return value.
Returns true between calls to start_document and end_document, false otherwise. Useful to see if end_document should be called, which may be useful if a single parser is being used to scan multiple messages (such as in a mailbox).
This is used to pass the next line of input to the parser. The lines do not need to be terminated with a new line, either CRLF, \n, or anything else. Each string is assumed to be a single logical line of input.
No useful return value.
The following may be useful to a handler. These are regular subs, not methods. They are not exported, so you will need to specify them by their full name, or import them yourself.
Returns the first value found in the string, either a SINGLE mime token, or a quoted string.
A quoted string value does not include the quotes, and escaped quotes within the value will no longer include the escape character (\).
A token is exactly one token, so (for example) it cannot pull out something like the mime/type (in a single call) because that is two tokens.
The string must already have been trimmed so that the desired value is the first thing in the string.
E.g. # a typical header $string = "A-typical-Header: something=the-value";
# get a string that has the desired value at the front ($contains_the_value) = $string =~ m/something=(.*)/;
# and extract that value $the_value = MIME::Xparser::parse_value($contains_the_value);
@ARRAY
Returns a string which is the header lines joined together using an algorithm that will work for typical data. I.e. a single white space is removed from the beginning of each line, and any number of trailing \r's or \n's are trimmed from each line, and the resulting lines are joined into a single string.
Your content handler should provide the following methods. AUTOLOAD can be used to reduce the number of methods required.
All methods receive your handler object, as per any method call. Additional parameters only are shown.
The four data methods, header, neck, body, and boundary, receive the original data unaltered. I.e. If the strings are echoed as they are received then the original data will be identically reproduced.
@the_lines_making_up_one_header
The parameter input to the handler is an array of strings which are the lines that make up a single header.
The word header, here, means a single header item, not the entire block of header lines at the top of a mime entity.
$null_line
The parameter input to the handler is a single string which is the null line that seperated the headers from the body.
$one_line_from_the_body
The parameter input to the handler is a single string which is a line of data from the body.
$a_boundary_line
The parameter input to the handler is a single string which is a boundary line found between parts.
The following tries to indicate the nesting of the calls that your handler will see. (1) (2) (3) denotes that one of the indicated sets of calls will be made in any given situation.
Some methods and sets of methods may be invoked multiple times as appropriate, but that is not shown.
start_document
start_message
start_headers
header
end_headers
neck
(1) start_body
body
end_body
(2) start_parts
start_preamble
body
end_preamble
boundary
start_part
start_headers
header
end_headers
(1) (2) or (3)
end_part
boundary
start_postamble
body
end_postamble
end_parts
(3) start_body
start_message
(recursively invoke the calls already shown)
end_message
end_body
end_message
end_document
version 0.4
This example displays the structure of the messages in a mail box file. it uses one of the provided example content handlers.
#!/usr/bin/perl
# usage: this-file an-mbox-file use MIME::Xparser;
my $handler = new MIME::Xparser::Handler::Structure(); my $parser = new MIME::Xparser($handler);
FOR: for (;;) { while (<>) { if (m/^From /) { $parser->end_document() if $parser->in_document(); print "\n$_"; $parser->start_document(); next FOR; } $parser->line($_); } $parser->end_document() if $parser->in_document(); last; }
ALSO
The distribution includes extract-pl which extracts attachments from a mail box file, and examine-pl which shows the structure of a message and a few keys other bits of data. These illustrate some uses of the module.
The Xparser.pm module includes two trivial handlers at the top of the code. These are both potentially useful and are examples of simple handlers.
perl Makefile.PL make make test make install
Or simply copy the Xparser.pm file into a MIME subdirectory of your perl @INC path.
MIME-Version is found but not used.
Embedded message/rfc822 parts are parsed whether you want them to be or not. (That's not really a bug, and your handler is free to skip them if it wishes.)
Virtually no assistance is provided for the parsing requirements that a handler might have. Again, this is not a bug, though it might be considered a flaw.
The null-line denoting the end of the headers allows for \r in the line. Specifically we test for ^\r?$. This works well on unix systems reading data that may have either \n new lines or \CR\LF (which is the standard for "raw" mail data) but may or may not be appropriate for other systems. Therefore this may or may not be a bug for anyone.
Others - probably?
=cut
Malcolm Dew-Jones <yf110@victoria.tc.ca>