Completed
Push — master ( e760e0...e9e3b8 )
by Harry
02:14
created

FirstDiff::firstDifference()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 8.2222
c 0
b 0
f 0
cc 7
eloc 11
nc 6
nop 2
1
<?php
2
3
namespace Graze\BufferedConsole\Diff;
4
5
class FirstDiff
6
{
7
    /**
8
     * Loop through each line, and produce a difference report of what to write out to the terminal
9
     *
10
     * Assumes the beginning of old and new are the same line
11
     *
12
     * @param string[] $old
13
     * @param string[] $new
14
     *
15
     * @return array [[:col, :str]]
16
     */
17
    public function lines(array $old, array $new)
18
    {
19
        $out = [];
20
        for ($i=0; $i < count($old) || $i < count($new); $i++) {
21
            if ($i >= count($old)) {
22
                $out[] = ['col' => 0, 'str' => $new[$i]]; // write out the entire line for extra lines
23
            } elseif ($i >= count($new)) {
24
                $out[] = ['col' => 0, 'str' => '']; // clear the line if the new array has less entries than the old one
25
            } else {
26
                $col = $this->firstDifference($old[$i], $new[$i]);
27
                if ($col === -1) {
28
                    $out[] = null;
29
                } else {
30
                    $out[] = ['col' => $col, 'str' => mb_substr($new[$i], $col)];
31
                }
32
            }
33
        }
34
        return $out;
35
    }
36
37
    /**
38
     * Looks through a line to find the character to of the first difference between the 2 strings.
39
     *
40
     * If no difference is found, returns -1
41
     *
42
     * @param string $old
43
     * @param string $new
44
     *
45
     * @return int
46
     */
47
    public function firstDifference($old, $new)
48
    {
49
        // loop through old and new character by character and compare
50
        $oldLen = mb_strlen($old);
51
        $newLen = mb_strlen($new);
52
53
        if ($oldLen === 0) {
54
            return 0;
55
        }
56
57
        for ($i = 0; $i < $oldLen && $i < $newLen; $i++) {
58
            if (mb_substr($old, $i, 1) !== mb_substr($new, $i, 1)) {
59
                return $i;
60
            }
61
        }
62
        if ($i < $oldLen || $i < $newLen) {
63
            return $i;
64
        }
65
        return -1;
66
    }
67
}
68