about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/PublicInbox/View.pm14
-rw-r--r--lib/PublicInbox/ViewDiff.pm45
2 files changed, 27 insertions, 32 deletions
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 2f99179e..3dbf8bac 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -560,7 +560,7 @@ sub add_text_body { # callback for each_part
         my ($part, $depth, $idx) = @$p;
         my $ct = $part->content_type || 'text/plain';
         my $fn = $part->filename;
-        my $rv = $ctx->{obuf};
+        my $rv = $ctx->{obuf} //= \(my $obuf = '');
         my ($s, $err) = msg_part_text($part, $ct);
         $s // return $$rv .= (attach_link($ctx, $ct, $p, $fn) // '');
         if ($part->{is_submsg}) {
@@ -618,18 +618,16 @@ sub add_text_body { # callback for each_part
                 $$rv .= "\n";
         }
         delete $part->{bdy}; # save memory
-        foreach my $cur (@sections) {
+        for my $cur (@sections) { # $cur may be huge
                 if ($cur =~ /\A>/) {
                         # we use a <span> here to allow users to specify
                         # their own color for quoted text
-                        $$rv .= qq(<span\nclass="q">);
-                        $$rv .= $l->to_html($cur);
-                        $$rv .= '</span>';
+                        $ctx->zmore(qq(<span\nclass="q">),
+                                        $l->to_html($cur), '</span>');
                 } elsif ($diff) {
                         flush_diff($ctx, \$cur);
-                } else {
-                        # regular lines, OK
-                        $$rv .= $l->to_html($cur);
+                } else { # regular lines, OK
+                        $ctx->zmore($l->to_html($cur));
                 }
                 undef $cur; # free memory
         }
diff --git a/lib/PublicInbox/ViewDiff.pm b/lib/PublicInbox/ViewDiff.pm
index 076aa1af..36601910 100644
--- a/lib/PublicInbox/ViewDiff.pm
+++ b/lib/PublicInbox/ViewDiff.pm
@@ -156,10 +156,7 @@ sub diff_header ($$$) {
                 warn "BUG? <$$x> had no ^index line";
         }
         $$x =~ s!^diff --git!anchor1($ctx, $pb) // 'diff --git'!ems;
-        my $dst = $ctx->{obuf};
-        $$dst .= qq(<span\nclass="head">);
-        $$dst .= $$x;
-        $$dst .= '</span>';
+        $ctx->zmore(qq(<span\nclass="head">$$x</span>));
         $dctx;
 }
 
@@ -182,9 +179,10 @@ sub diff_before_or_after ($$) {
                 my $ch = $ctx->{changed_href} // '#related';
                 $$x .= qq(<a href="$ch">changed</a>,);
                 $$x .= ascii_html(pop @x); # $4: insertions/deletions
-                $$x .= $lnk->to_html(pop @x); # notes, commit message, etc
+                # notes, commit message, etc
+                $ctx->zmore($$x .= $lnk->to_html(pop @x));
         } else {
-                $ctx->{-linkify}->to_html($$x);
+                $ctx->zmore($ctx->{-linkify}->to_html($$x));
         }
 }
 
@@ -195,8 +193,7 @@ sub flush_diff ($$) {
         my @top = split($EXTRACT_DIFFS, $$cur);
         undef $$cur; # free memory
 
-        my $linkify = $ctx->{-linkify};
-        my $dst = $ctx->{obuf};
+        my $lnk = $ctx->{-linkify};
         my $dctx; # {}, keys: Q, oid_a, oid_b
 
         while (defined(my $x = shift @top)) {
@@ -223,28 +220,28 @@ sub flush_diff ($$) {
                                 if (!defined($dctx)) {
                                         $after .= $s;
                                 } elsif ($s =~ s/\A@@ (\S+) (\S+) @@//) {
-                                        $$dst .= qq(<span\nclass="hunk">);
-                                        $$dst .= diff_hunk($dctx, $1, $2);
-                                        $$dst .= $linkify->to_html($s);
-                                        $$dst .= '</span>';
-                                } elsif ($s =~ /\A\+/) {
-                                        $$dst .= qq(<span\nclass="add">);
-                                        $$dst .= $linkify->to_html($s);
-                                        $$dst .= '</span>';
+                                        $ctx->zmore(qq(<span\nclass="hunk">) .
+                                                diff_hunk($dctx, $1, $2) .
+                                                $lnk->to_html($s) .
+                                                '</span>');
+                                } elsif ($s =~ /\A\+/) { # $s may be huge
+                                        $ctx->zmore(qq(<span\nclass="add">),
+                                                        $lnk->to_html($s),
+                                                        '</span>');
                                 } elsif ($s =~ /\A-- $/sm) { # email sig starts
                                         $dctx = undef;
                                         $after .= $s;
-                                } elsif ($s =~ /\A-/) {
-                                        $$dst .= qq(<span\nclass="del">);
-                                        $$dst .= $linkify->to_html($s);
-                                        $$dst .= '</span>';
-                                } else {
-                                        $$dst .= $linkify->to_html($s);
+                                } elsif ($s =~ /\A-/) { # $s may be huge
+                                        $ctx->zmore(qq(<span\nclass="del">),
+                                                $lnk->to_html($s),
+                                                '</span>');
+                                } else { # $s may be huge
+                                        $ctx->zmore($lnk->to_html($s));
                                 }
                         }
-                        $$dst .= diff_before_or_after($ctx, \$after) if !$dctx;
+                        diff_before_or_after($ctx, \$after) if !$dctx;
                 } else {
-                        $$dst .= diff_before_or_after($ctx, \$x);
+                        diff_before_or_after($ctx, \$x);
                 }
         }
 }