File Coverage

blib/lib/MIME/Multipart/Parse/Ordered.pm
Criterion Covered Total %
statement 12 63 19.0
branch 0 12 0.0
condition 0 6 0.0
subroutine 4 8 50.0
pod 4 4 100.0
total 20 93 21.5


line stmt bran cond sub pod time code
1             package MIME::Multipart::Parse::Ordered;
2              
3 1     1   31956 use 5.006;
  1         5  
  1         43  
4 1     1   7 use strict;
  1         1  
  1         39  
5 1     1   6 use warnings FATAL => 'all';
  1         7  
  1         50  
6 1     1   7 use Carp;
  1         1  
  1         986  
7              
8             =head1 NAME
9              
10             MIME::Multipart::Parse::Ordered - simple mime multipart parser, maintains document order
11              
12             =head1 VERSION
13              
14             Version 0.03
15              
16             =cut
17              
18             our $VERSION = '0.03';
19              
20              
21             =head1 SYNOPSIS
22              
23             This is a really basic MIME multipart parser,
24             and the only reason for its existence is that
25             I could not find an existing parser that would
26             give me the parts directly (not on fs) and also
27             give me the order.
28              
29             my $mmps = MIME::Multipart::Parse::Ordered->new();
30             my $listref = $mmps->parse($my_file_handle);
31             print $listref->[0]->{"Preamble"};
32             print $listref->[0]->{"Content-Type.params"}->{"boundary"};
33             foreach (@$listref){
34             print $_->{"Body"}
35             if $_->{"Content-Type"} eq 'text/plain';
36             }
37              
38             =head1 SUBROUTINES/METHODS
39              
40             =head2 new
41              
42             Created a new MIME::Multipart::Parse::Ordered
43              
44             =cut
45              
46             sub new {
47 0     0 1   my $p = shift;
48 0   0       my $c = ref($p) || $p;
49 0           my $o = {};
50 0           bless $o, $c;
51 0           return $o;
52             }
53              
54             =head2 parse
55              
56             takes one argument: a file handle.
57              
58             returns a listref, each item corresponding to a MIME header in
59             the document. The first is the multipart file header itself.
60             Each header item is stored as key/value. Additional parameters
61             are stored $key.params. e.g. the boundary is at
62              
63             $o->[0]->{"Content-Type.params"}->{"boundary"}
64              
65             The first item may also have {"Preamble"} and {"Epilog"} if these
66             existed in the file.
67              
68             The content of each part is stored as {"Body"}.
69              
70             =cut
71              
72             sub parse {
73             # load a MIME-multipart-style file containing at least one application/x-ptk.markdown
74 0     0 1   my ($o,$fh) = @_;
75 0           $o->{fh} = $fh;
76              
77 0           my $mp1 = <$fh>;
78 0           my $mp1e = 'MIME Version: 1.0';
79 0 0         die "Multipart header line 1 must begin ``$mp1e'' " unless $mp1 =~ /^$mp1e/;
80            
81 0           my $general_header = $o->parseHeader();
82 0 0         croak "no boundary defined" unless $general_header->{"Content-Type.params"}->{"boundary"};
83 0           $o->{boundary} = $general_header->{"Content-Type.params"}->{"boundary"};
84            
85 0           $general_header->{Preamble} = $o->parseBody();
86              
87 0           my @parts = ($general_header);
88              
89 0   0       while(! (eof($fh) || $o->{eof})){
90 0           my $header = $o->parseHeader();
91 0           $header->{Body} = $o->parseBody();
92 0           push @parts, $header;
93             }
94              
95 0           $general_header->{Epilog} = $o->parseBody();
96              
97 0           return \@parts;
98              
99             }
100              
101             =head2 parseBody
102              
103             Used internally, parses mime "body"
104              
105             =cut
106              
107             sub parseBody {
108 0     0 1   my ($o) = @_;
109 0           my $fh = $o->{fh};
110 0           my $body = '';
111 0           my $boundary = $o->{boundary};
112 0           while(<$fh>){
113 0 0         $o->{eof} = 1 if /^--$boundary--/;
114 0 0         last if /^--$boundary/;
115 0           $body .= $_;
116             }
117 0           return $body;
118             }
119              
120             =head2 parseHeader
121              
122             Used internally, parses a MIME header.
123              
124             =cut
125              
126             sub parseHeader {
127 0     0 1   my ($o) = @_;
128 0           my $fh = $o->{fh};
129 0           my %header = ();
130 0           my ($k,$v,$e,$p);
131 0           while(<$fh>){
132 0 0         last if /^\s*$/; # break on a blank line...
133 0           my @parts = split /;/;
134 0 0         if(/^\S/){ # non space at start means a new header item
135 0           my $header = shift @parts;
136 0           ($k,$v) = split(/\:/, $header, 2);
137 0           $k =~ s/(?:^\s+|\s+$)//g;
138 0           $v =~ s/(?:^\s+|\s+$)//g;
139 0           $header{$k} = $v;
140 0           $p = $k.'.params';
141 0           $header{$p} = {};
142             }
143 0           foreach my $part(@parts){
144 0           my ($l,$w) = split(/=/, $part, 2);
145 0           $l =~ s/(?:^\s+|\s+$)//g;
146 0           $w =~ s/(?:^\s+|\s+$)//g;
147 0           $header{$p}->{$l} = $w;
148             }
149             }
150 0           return \%header;
151             }
152              
153             =head1 AUTHOR
154              
155             jimi, C<< >>
156              
157             =head1 BUGS
158              
159             Please report any bugs or feature requests to C, or through
160             the web interface at L. I will be notified, and then you'll
161             automatically be notified of progress on your bug as I make changes.
162              
163              
164              
165              
166             =head1 SUPPORT
167              
168             You can find documentation for this module with the perldoc command.
169              
170             perldoc MIME::Multipart::Parse::Ordered
171              
172              
173             You can also look for information at:
174              
175             =over 4
176              
177             =item * RT: CPAN's request tracker (report bugs here)
178              
179             L
180              
181             =item * AnnoCPAN: Annotated CPAN documentation
182              
183             L
184              
185             =item * CPAN Ratings
186              
187             L
188              
189             =item * Search CPAN
190              
191             L
192              
193             =back
194              
195              
196             =head1 ACKNOWLEDGEMENTS
197              
198              
199             =head1 LICENSE AND COPYRIGHT
200              
201             Copyright 2013 jimi.
202              
203             This program is free software; you can redistribute it and/or modify it
204             under the terms of the the Artistic License (2.0). You may obtain a
205             copy of the full license at:
206              
207             L
208              
209             Any use, modification, and distribution of the Standard or Modified
210             Versions is governed by this Artistic License. By using, modifying or
211             distributing the Package, you accept this license. Do not use, modify,
212             or distribute the Package, if you do not accept this license.
213              
214             If your Modified Version has been derived from a Modified Version made
215             by someone other than you, you are nevertheless required to ensure that
216             your Modified Version complies with the requirements of this license.
217              
218             This license does not grant you the right to use any trademark, service
219             mark, tradename, or logo of the Copyright Holder.
220              
221             This license includes the non-exclusive, worldwide, free-of-charge
222             patent license to make, have made, use, offer to sell, sell, import and
223             otherwise transfer the Package with respect to any patent claims
224             licensable by the Copyright Holder that are necessarily infringed by the
225             Package. If you institute patent litigation (including a cross-claim or
226             counterclaim) against any party alleging that the Package constitutes
227             direct or contributory patent infringement, then this Artistic License
228             to you shall terminate on the date that such litigation is filed.
229              
230             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
231             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
232             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
233             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
234             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
235             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
236             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
237             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
238              
239              
240             =cut
241              
242             1; # End of MIME::Multipart::ParseSimple