public function fromText($patchText)
{
$patches = array();
if (!$patchText) {
return $patches;
}
$lines = explode("\n", $patchText);
while (count($lines)) {
$line = $lines[0];
if (!preg_match("/^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@\$/", $line, $m)) {
throw new \InvalidArgumentException("Invalid patch string: " . $line);
}
$patch = new PatchObject();
$patch->setStart1($m[1]);
if ($m[2] == '') {
$patch->setStart1($patch->getStart1() - 1);
$patch->setLength1(1);
} elseif ($m[2] == '0') {
$patch->setLength1(0);
} else {
$patch->setStart1($patch->getStart1() - 1);
$patch->setLength1($m[2]);
}
$patch->setStart2($m[3]);
if ($m[4] == '') {
$patch->setStart2($patch->getStart2() - 1);
$patch->setLength2(1);
} elseif ($m[4] == '0') {
$patch->setLength2(0);
} else {
$patch->setStart2($patch->getStart2() - 1);
$patch->setLength2($m[4]);
}
$patches[] = $patch;
array_shift($lines);
while (count($lines)) {
$line = $lines[0];
if ($line) {
$sign = mb_substr($line, 0, 1);
} else {
$sign = '';
}
$text = Utils::unescapeString(mb_substr($line, 1));
switch ($sign) {
case '+':
// Insertion.
$patch->appendChanges(array(Diff::INSERT, $text));
break;
case '-':
// Deletion.
$patch->appendChanges(array(Diff::DELETE, $text));
break;
case ' ':
// Minor equality.
$patch->appendChanges(array(Diff::EQUAL, $text));
break;
case '@':
// Start of next patch.
break 2;
case '':
// Blank line? Whatever.
break;
default:
// WTF?
throw new \UnexpectedValueException("Invalid patch mode: " . $sign . PHP_EOL . $text);
}
array_shift($lines);
}
}
return $patches;
}