NonCanonicalReader   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 9
eloc 18
dl 0
loc 63
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __destruct() 0 4 2
A addControlMappings() 0 4 2
A __construct() 0 5 1
A addControlMapping() 0 7 2
A readCharacter() 0 9 2
1
<?php
2
3
namespace PhpSchool\Terminal;
4
5
/**
6
 * This class takes a terminal and disabled canonical mode. It reads the input
7
 * and returns characters and control sequences as `InputCharacters` as soon
8
 * as they are read - character by character.
9
 *
10
 * On destruct canonical mode will be enabled if it was when in it was constructed.
11
 *
12
 * @author Aydin Hassan <[email protected]>
13
 */
14
class NonCanonicalReader
15
{
16
    /**
17
     * @var Terminal
18
     */
19
    private $terminal;
20
21
    /**
22
     * @var bool
23
     */
24
    private $wasCanonicalModeEnabled;
25
26
    /**
27
     * Map of characters to controls.
28
     * Eg map 'w' to the up control.
29
     *
30
     * @var array
31
     */
32
    private $mappings = [];
33
34
    public function __construct(Terminal $terminal)
35
    {
36
        $this->terminal = $terminal;
37
        $this->wasCanonicalModeEnabled = $terminal->isCanonicalMode();
38
        $this->terminal->disableCanonicalMode();
39
    }
40
41
    public function addControlMapping(string $character, string $mapToControl) : void
42
    {
43
        if (!InputCharacter::controlExists($mapToControl)) {
44
            throw new \InvalidArgumentException(sprintf('Control "%s" does not exist', $mapToControl));
45
        }
46
47
        $this->mappings[$character] = $mapToControl;
48
    }
49
50
    public function addControlMappings(array $mappings) : void
51
    {
52
        foreach ($mappings as $character => $mapToControl) {
53
            $this->addControlMapping($character, $mapToControl);
54
        }
55
    }
56
57
    /**
58
     * This should be ran with the terminal canonical mode disabled.
59
     *
60
     * @return InputCharacter
61
     */
62
    public function readCharacter() : InputCharacter
63
    {
64
        $char = $this->terminal->read(4);
65
66
        if (isset($this->mappings[$char])) {
67
            return InputCharacter::fromControlName($this->mappings[$char]);
68
        }
69
70
        return new InputCharacter($char);
71
    }
72
73
    public function __destruct()
74
    {
75
        if ($this->wasCanonicalModeEnabled) {
76
            $this->terminal->enableCanonicalMode();
77
        }
78
    }
79
}
80