From 453dee4881a9c764b09d33f3a827879f2cd3669d Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 7 May 2020 21:05:45 +0000 Subject: [PATCH] msg_iter: pass $idx as a scalar, not array This doesn't make any difference for most multipart messages (or any single part messages). However, this starts having space savings when parts start nesting. It also slightly simplifies callers. --- lib/PublicInbox/MsgIter.pm | 6 ++++-- lib/PublicInbox/SearchIdx.pm | 2 +- lib/PublicInbox/View.pm | 18 +++++++++--------- lib/PublicInbox/WwwAttach.pm | 4 ++-- t/mime.t | 5 +++-- t/msg_iter.t | 2 +- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/PublicInbox/MsgIter.pm b/lib/PublicInbox/MsgIter.pm index cd5a5d99..7c28d019 100644 --- a/lib/PublicInbox/MsgIter.pm +++ b/lib/PublicInbox/MsgIter.pm @@ -20,12 +20,14 @@ sub em_each_part ($$;$$) { my $i = 0; @parts = map { [ $_, 1, ++$i ] } @parts; while (my $p = shift @parts) { - my ($part, $depth, @idx) = @$p; + my ($part, $depth, $idx) = @$p; my @sub = $part->subparts; if (@sub) { $depth++; $i = 0; - @sub = map { [ $_, $depth, @idx, ++$i ] } @sub; + @sub = map { + [ $_, $depth, "$idx.".(++$i) ] + } @sub; @parts = (@sub, @parts); } else { $cb->($p, $cb_arg); diff --git a/lib/PublicInbox/SearchIdx.pm b/lib/PublicInbox/SearchIdx.pm index 998341a7..f357a8fa 100644 --- a/lib/PublicInbox/SearchIdx.pm +++ b/lib/PublicInbox/SearchIdx.pm @@ -277,7 +277,7 @@ sub index_diff ($$$) { } sub index_xapian { # msg_iter callback - my $part = $_[0]->[0]; # ignore $depth and @idx + my $part = $_[0]->[0]; # ignore $depth and $idx my ($self, $doc) = @{$_[1]}; my $ct = $part->content_type || 'text/plain'; my $fn = $part->filename; diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index e42fb362..3328c865 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -482,9 +482,8 @@ sub multipart_text_as_html { sub attach_link ($$$$;$) { my ($ctx, $ct, $p, $fn, $err) = @_; - my ($part, $depth, @idx) = @$p; - my $nl = $idx[-1] > 1 ? "\n" : ''; - my $idx = join('.', @idx); + my ($part, $depth, $idx) = @$p; + my $nl = substr($idx, -2) eq '.1' ? '' : "\n"; # like join("\n", ...) my $size = bytes::length($part->body); # hide attributes normally, unless we want to aid users in @@ -519,8 +518,8 @@ sub add_text_body { # callback for each_part my ($p, $ctx) = @_; my $upfx = $ctx->{mhref}; my $ibx = $ctx->{-inbox}; - # $p - from each_part: [ Email::MIME-like, depth, @idx ] - my ($part, $depth, @idx) = @$p; + # $p - from each_part: [ Email::MIME-like, depth, $idx ] + my ($part, $depth, $idx) = @$p; my $ct = $part->content_type || 'text/plain'; my $fn = $part->filename; my ($s, $err) = msg_part_text($part, $ct); @@ -537,13 +536,14 @@ sub add_text_body { # callback for each_part # headers for solver unless some coderepo are configured: my $diff; if ($s =~ /^--- [^\n]+\n\+{3} [^\n]+\n@@ /ms) { - # diffstat anchors do not link across attachments or messages: - $idx[0] = $upfx . $idx[0] if $upfx ne ''; - $ctx->{-apfx} = join('/', @idx); + # diffstat anchors do not link across attachments or messages, + # -apfx is just a stable prefix for making diffstat anchors + # linkable to the first diff hunk w/o crossing attachments + $idx =~ tr!.!/!; # compatibility with previous versions + $ctx->{-apfx} = $upfx . $idx; # do attr => filename mappings for diffstats in git diffs: $ctx->{-anchors} = {} if $s =~ /^diff --git /sm; - $diff = 1; delete $ctx->{-long_path}; my $spfx; diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm index 774b38ae..b1009907 100644 --- a/lib/PublicInbox/WwwAttach.pm +++ b/lib/PublicInbox/WwwAttach.pm @@ -11,9 +11,9 @@ use PublicInbox::MIME; use PublicInbox::MsgIter; sub get_attach_i { # ->each_part callback - my ($part, $depth, @idx) = @{$_[0]}; + my ($part, $depth, $idx) = @{$_[0]}; my $res = $_[1]; - return if join('.', @idx) ne $res->[3]; # $idx + return if $idx ne $res->[3]; # [0-9]+(?:\.[0-9]+)+ $res->[0] = 200; my $ct = $part->content_type; $ct = parse_content_type($ct) if $ct; diff --git a/t/mime.t b/t/mime.t index 0d478ace..b9a4d66b 100644 --- a/t/mime.t +++ b/t/mime.t @@ -98,9 +98,10 @@ $msg = PublicInbox::MIME->new($raw); my $nr = 0; msg_iter($msg, sub { my ($part, $level, @ex) = @{$_[0]}; - if ($ex[0] == 1) { + is($level, 1, 'at expected level'); + if (join('fail if $#ex > 0', @ex) eq '1') { is($part->body_str, "your tree directly? \r\n", 'body OK'); - } elsif ($ex[0] == 2) { + } elsif (join('fail if $#ex > 0', @ex) eq '2') { is($part->body, "-----BEGIN PGP SIGNATURE-----\n\n" . "=7wIb\n" . "-----END PGP SIGNATURE-----\n", diff --git a/t/msg_iter.t b/t/msg_iter.t index 5c57e043..e8115e25 100644 --- a/t/msg_iter.t +++ b/t/msg_iter.t @@ -28,7 +28,7 @@ use_ok('PublicInbox::MsgIter'); $s =~ s/\s+//s; push @parts, [ $s, $level, @ex ]; }); - is_deeply(\@parts, [ [qw(a 2 1 1)], [qw(b 2 1 2)], [qw(sig 1 2)] ], + is_deeply(\@parts, [ [qw(a 2 1.1)], [qw(b 2 1.2)], [qw(sig 1 2)] ], 'nested part shows up properly'); } -- 2.44.0