DiffMatchPatch\Patch::splitMax PHP Method

splitMax() public method

Intended to be called only from within apply(). Modifies $patches. TODO try to fix it!
public splitMax ( PatchObject[] &$patches )
$patches PatchObject[] Array of PatchObjects.
    public function splitMax(&$patches)
    {
        $patchSize = $this->getMatch()->getMaxBits();
        if ($patchSize == 0) {
            // TODO PHP has fixed size int, so this case isn't relevant.
            return;
        }
        for ($i = 0; $i < count($patches); $i++) {
            if ($patches[$i]->getLength1() <= $patchSize) {
                continue;
            }
            $bigPatch = $patches[$i];
            // Remove the big old patch.
            array_splice($patches, $i, 1);
            $i--;
            $start1 = $bigPatch->getStart1();
            $start2 = $bigPatch->getStart2();
            $preContext = '';
            $bigPatchDiffs = $bigPatch->getChanges();
            while (count($bigPatchDiffs)) {
                // Create one of several smaller patches.
                $empty = true;
                $patch = new PatchObject();
                $preContextLen = mb_strlen($preContext);
                $patch->setStart1($start1 - $preContextLen);
                $patch->setStart2($start2 - $preContextLen);
                if ($preContext != '') {
                    $patch->setLength1($preContextLen);
                    $patch->setLength2($preContextLen);
                    $patch->appendChanges(array(Diff::EQUAL, $preContext));
                }
                while (count($bigPatchDiffs) && $patch->getLength1() < $patchSize - $this->getMargin()) {
                    list($diffType, $diffText) = $bigPatchDiffs[0];
                    $diffTextLen = mb_strlen($diffText);
                    if ($diffType == Diff::INSERT) {
                        // Insertions are harmless.
                        $patch->setLength2($patch->getLength2() + $diffTextLen);
                        $start2 += $diffTextLen;
                        $patch->appendChanges(array_shift($bigPatchDiffs));
                        $empty = false;
                    } elseif ($diffType == Diff::DELETE && ($patchDiffs = $patch->getChanges()) && count($patchDiffs) == 1 && $patchDiffs[0][0] == Diff::EQUAL && 2 * $patchSize < $diffTextLen) {
                        // This is a large deletion.  Let it pass in one chunk.
                        $patch->setLength1($patch->getLength1() + $diffTextLen);
                        $start1 += $diffTextLen;
                        array_shift($bigPatchDiffs);
                        $patch->appendChanges(array($diffType, $diffText));
                        $empty = false;
                    } else {
                        // Deletion or equality.  Only take as much as we can stomach.
                        $diffText = mb_substr($diffText, 0, $patchSize - $patch->getLength1() - $this->getMargin());
                        $diffTextLen = mb_strlen($diffText);
                        $patch->setLength1($patch->getLength1() + $diffTextLen);
                        $start1 += $diffTextLen;
                        if ($diffType == Diff::EQUAL) {
                            $patch->setLength2($patch->getLength2() + $diffTextLen);
                            $start2 += $diffTextLen;
                        } else {
                            $empty = false;
                        }
                        if ($diffText == $bigPatchDiffs[0][1]) {
                            array_shift($bigPatchDiffs);
                        } else {
                            $bigPatchDiffs[0][1] = mb_substr($bigPatchDiffs[0][1], $diffTextLen);
                        }
                        $patch->appendChanges(array($diffType, $diffText));
                    }
                }
                // Compute the head context for the next patch.
                $diff = $this->getDiff();
                $diff->setChanges($patch->getChanges());
                $preContext = $diff->text2();
                $preContext = mb_substr($preContext, -$this->getMargin());
                // Append the end context for this patch.
                $diff->setChanges($bigPatchDiffs);
                $postContext = $diff->text1();
                $postContext = mb_substr($postContext, 0, $this->getMargin());
                if ($postContext != '') {
                    $patch->setLength1($patch->getLength1() + mb_strlen($postContext));
                    $patch->setLength2($patch->getLength2() + mb_strlen($postContext));
                    if (($patchDiffs = $patch->getChanges()) && count($patchDiffs) && $patchDiffs[count($patchDiffs) - 1][0] == Diff::EQUAL) {
                        $patchDiffs[count($patchDiffs) - 1][1] .= $postContext;
                        $patch->setChanges($patchDiffs);
                    } else {
                        $patch->appendChanges(array(Diff::EQUAL, $postContext));
                    }
                }
                if (!$empty) {
                    $i++;
                    array_splice($patches, $i, 0, array($patch));
                }
            }
        }
    }