Skip to content

Commit 3c40ca4

Browse files
SpacePossumsebastianbergmann
authored andcommitted
UnifiedDiffOutputBuilder - write directly to stream to prevent string copying in methods.
1 parent 4f7cdc0 commit 3c40ca4

File tree

1 file changed

+40
-33
lines changed

1 file changed

+40
-33
lines changed

src/Output/UnifiedDiffOutputBuilder.php

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,28 @@ public function __construct(string $header = "--- Original\n+++ New\n")
2727

2828
public function getDiff(array $diff): string
2929
{
30-
$old = $this->getCommonChunks($diff, 5);
30+
$buffer = \fopen('php://memory', 'r+b');
31+
32+
if ('' !== $this->header) {
33+
\fwrite($buffer, $this->header);
34+
if ("\n" !== \substr($this->header, -1, 1)) {
35+
\fwrite($buffer, "\n");
36+
}
37+
}
38+
39+
$this->writeDiffChunked($buffer, $diff, $this->getCommonChunks($diff));
40+
41+
$diff = \stream_get_contents($buffer, -1, 0);
42+
43+
\fclose($buffer);
44+
45+
return $diff;
46+
}
47+
48+
// `old` is an array with key => value pairs . Each pair represents a start and end index of `diff`
49+
// of a list of elements all containing `same` (0) entries.
50+
private function writeDiffChunked($output, array $diff, array $old)
51+
{
3152
$start = isset($old[0]) ? $old[0] : 0;
3253
$end = \count($diff);
3354

@@ -40,64 +61,50 @@ public function getDiff(array $diff): string
4061
}
4162
}
4263

43-
$buffer = '';
44-
if ('' !== $this->header) {
45-
$buffer = $this->header;
46-
if ("\n" !== \substr($this->header, -1, 1)) {
47-
$buffer .= "\n";
48-
}
49-
}
50-
5164
if (!isset($old[$start])) {
52-
$buffer = $this->getDiffBufferElementNew($diff, $buffer, $start);
65+
$this->writeDiffBufferElementNew($diff, $output, $start);
5366
++$start;
5467
}
5568

5669
for ($i = $start; $i < $end; $i++) {
5770
if (isset($old[$i])) {
58-
$i = $old[$i];
59-
$buffer = $this->getDiffBufferElementNew($diff, $buffer, $i);
71+
$i = $old[$i];
72+
$this->writeDiffBufferElementNew($diff, $output, $i);
6073
} else {
61-
$buffer = $this->getDiffBufferElement($diff, $buffer, $i);
74+
$this->writeDiffBufferElement($diff, $output, $i);
6275
}
6376
}
64-
65-
return $buffer;
6677
}
6778

6879
/**
6980
* Gets individual buffer element with opening.
7081
*
71-
* @param array $diff
72-
* @param string $buffer
73-
* @param int $diffIndex
74-
*
75-
* @return string
82+
* @param array $diff
83+
* @param resource $buffer
84+
* @param int $diffIndex
7685
*/
77-
private function getDiffBufferElementNew(array $diff, string $buffer, int $diffIndex): string
86+
private function writeDiffBufferElementNew(array $diff, $buffer, int $diffIndex)
7887
{
79-
return $this->getDiffBufferElement($diff, $buffer . "@@ @@\n", $diffIndex);
88+
\fwrite($buffer, "@@ @@\n");
89+
90+
$this->writeDiffBufferElement($diff, $buffer, $diffIndex);
8091
}
8192

8293
/**
8394
* Gets individual buffer element.
8495
*
85-
* @param array $diff
86-
* @param string $buffer
87-
* @param int $diffIndex
88-
*
89-
* @return string
96+
* @param array $diff
97+
* @param resource $buffer
98+
* @param int $diffIndex
9099
*/
91-
private function getDiffBufferElement(array $diff, string $buffer, int $diffIndex): string
100+
private function writeDiffBufferElement(array $diff, $buffer, int $diffIndex)
92101
{
93102
if ($diff[$diffIndex][1] === 1 /* ADDED */) {
94-
$buffer .= '+' . $diff[$diffIndex][0] . "\n";
103+
\fwrite($buffer, '+' . $diff[$diffIndex][0] . "\n");
95104
} elseif ($diff[$diffIndex][1] === 2 /* REMOVED */) {
96-
$buffer .= '-' . $diff[$diffIndex][0] . "\n";
105+
\fwrite($buffer, '-' . $diff[$diffIndex][0] . "\n");
97106
} else { /* Not changed (OLD) 0 or Warning 3 */
98-
$buffer .= ' ' . $diff[$diffIndex][0] . "\n";
107+
\fwrite($buffer, ' ' . $diff[$diffIndex][0] . "\n");
99108
}
100-
101-
return $buffer;
102109
}
103110
}

0 commit comments

Comments
 (0)