includes/diffengine/Engine/xdiff.php
author Dan
Wed, 26 Mar 2008 02:56:23 -0400
changeset 509 175df10e0b56
parent 1 fe660c52c48f
child 1227 bdac73ed481e
permissions -rw-r--r--
Added a copy of Firebug Lite for debugging purposes. License is uncertain but being treated as MPL. (If is is not MPL then it is under something more permissive that permits relicensing anyway)

<?php
/**
 * Class used internally by Diff to actually compute the diffs.  This class
 * uses the xdiff PECL package (http://pecl.php.net/package/xdiff) to compute
 * the differences between the two input arrays.
 *
 * @author  Jon Parise <jon@horde.org>
 * @package Text_Diff
 *
 * @access private
 */
class Text_Diff_Engine_xdiff {

    function diff($from_lines, $to_lines)
    {
        array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
        array_walk($to_lines, array('Text_Diff', 'trimNewlines'));

        /* Convert the two input arrays into strings for xdiff processing. */
        $from_string = implode("\n", $from_lines);
        $to_string = implode("\n", $to_lines);

        /* Diff the two strings and convert the result to an array. */
        $diff = xdiff_string_diff($from_string, $to_string, count($to_lines));
        $diff = explode("\n", $diff);

        /* Walk through the diff one line at a time.  We build the $edits
         * array of diff operations by reading the first character of the
         * xdiff output (which is in the "unified diff" format).
         *
         * Note that we don't have enough information to detect "changed"
         * lines using this approach, so we can't add Text_Diff_Op_changed
         * instances to the $edits array.  The result is still perfectly
         * valid, albeit a little less descriptive and efficient. */
        $edits = array();
        foreach ($diff as $line) {
            switch ($line[0]) {
            case ' ':
                $edits[] = &new Text_Diff_Op_copy(array(substr($line, 1)));
                break;

            case '+':
                $edits[] = &new Text_Diff_Op_add(array(substr($line, 1)));
                break;

            case '-':
                $edits[] = &new Text_Diff_Op_delete(array(substr($line, 1)));
                break;
            }
        }

        return $edits;
    }

}