]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/MsgIter.pm
ef0d209f6b391efc45ab843c3c8154a5cbd66557
[public-inbox.git] / lib / PublicInbox / MsgIter.pm
1 # Copyright (C) 2016 all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3 #
4 package PublicInbox::MsgIter;
5 use strict;
6 use warnings;
7 use base qw(Exporter);
8 our @EXPORT = qw(msg_iter);
9 use Email::MIME;
10 use Scalar::Util qw(readonly);
11
12 # Workaround Email::MIME versions without
13 # commit dcef9be66c49ae89c7a5027a789bbbac544499ce
14 # ("removing all trailing newlines was too much")
15 # This is necessary for Debian jessie
16 my $bad = 1.923;
17 my $good = 1.935;
18 my $ver = $Email::MIME::VERSION;
19 my $extra_nl = 1 if ($ver >= $bad && $ver < $good);
20
21 # Like Email::MIME::walk_parts, but this is:
22 # * non-recursive
23 # * passes depth and indices to the iterator callback
24 sub msg_iter ($$) {
25         my ($mime, $cb) = @_;
26         my @parts = $mime->subparts;
27         if (@parts) {
28                 my $i = 0;
29                 @parts = map { [ $_, 1, ++$i ] } @parts;
30                 while (my $p = shift @parts) {
31                         my ($part, $depth, @idx) = @$p;
32                         my @sub = $part->subparts;
33                         if (@sub) {
34                                 $depth++;
35                                 $i = 0;
36                                 @sub = map { [ $_, $depth, @idx, ++$i ] } @sub;
37                                 @parts = (@sub, @parts);
38                         } else {
39                                 if ($extra_nl) {
40                                         my $lf = $part->{mycrlf};
41                                         my $bref = $part->{body};
42                                         if (readonly($$bref)) {
43                                                 my $s = $$bref . $lf;
44                                                 $part->{body} = \$s;
45                                         } else {
46                                                 $$bref .= $lf;
47                                         }
48                                 }
49                                 $cb->($p);
50                         }
51                 }
52         } else {
53                 $cb->([$mime, 0, 0]);
54         }
55 }
56
57 1;