Exemplo n.º 1
0
 public function testPatchObj()
 {
     $p = new PatchObject();
     $p->setStart1(20);
     $p->setStart2(21);
     $p->setLength1(18);
     $p->setLength2(17);
     $p->setChanges(array(array(Diff::EQUAL, "jump"), array(Diff::DELETE, "s"), array(Diff::INSERT, "ed"), array(Diff::EQUAL, " over "), array(Diff::DELETE, "the"), array(Diff::INSERT, "a"), array(Diff::EQUAL, "\nlaz")));
     $this->assertEquals("@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n %0Alaz\n", (string) $p);
 }
Exemplo n.º 2
0
 /**
  * Look through the patches and break up any which are longer than the
  * maximum limit of the match algorithm.
  * Intended to be called only from within apply().
  * Modifies $patches. TODO try to fix it!
  *
  * @param PatchObject[] $patches 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));
             }
         }
     }
 }