Completed
Pull Request — master (#339)
by thomas
104:00 queued 33:35
created

Stack::isEmpty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace BitWasp\Bitcoin\Script\Interpreter;
4
5
use BitWasp\Buffertools\BufferInterface;
6
7
class Stack implements \Countable, \ArrayAccess, \Iterator
8
{
9
    /**
10
     * @var int
11
     */
12
    private $position = 0;
13
14
    /**
15
     * @var array
16
     */
17
    private $values = [];
18
19 2280
    public function current()
20
    {
21
        return $this->values[$this->position];
22 2280
    }
23
24 1329
    public function next()
25
    {
26 1329
        ++$this->position;
27
    }
28
29 1329
    public function key()
30
    {
31 1329
        return $this->position;
32 1329
    }
33
34
    public function valid()
35
    {
36
        return isset($this->values[$this->position]);
37
    }
38
39 2241
    public function rewind()
40
    {
41 2241
        $this->position = 0;
42
    }
43
44 2241
    public function count()
45
    {
46 2241
        return count($this->values);
47 2241
    }
48
49 2219
    public function isEmpty()
50
    {
51 2219
        return count($this->values) === 0;
52
    }
53
54 1815
    public function bottom()
55
    {
56 1815
        $count = count($this);
57
        if ($count < 1) {
58
            throw new \RuntimeException('No values in stack');
59 82
        }
60
61 82
        return $this->values[$count - 1];
62 82
    }
63
64
    /**
65
     * @see \ArrayAccess::offsetGet()
66 82
     * @param int $offset
67
     * @return \BitWasp\Buffertools\BufferInterface
68
     */
69
    public function offsetGet($offset)
70
    {
71
        $index = count($this) + $offset;
72
        if (!isset($this->values[$index])) {
73
            throw new \RuntimeException('No value at this position');
74 1723
        }
75
76 1723
        return $this->values[$index];
77 1723
    }
78 2
79
    /**
80
     * @see \ArrayAccess::offsetSet()
81 1723
     * @param int $offset
82
     * @param BufferInterface $value
83
     * @throws \InvalidArgumentException
84
     */
85
    public function offsetSet($offset, $value)
86
    {
87
        if (!$value instanceof BufferInterface) {
88
            throw new \InvalidArgumentException;
89
        }
90 37
91
        $count = count($this);
92 37
        $index = $count + $offset;
93
        if (isset($this->values[$index])) {
94
            $this->values[$index] = $value;
95
            return;
96 37
        }
97 37
98 37
        if ($index !== $count) {
99 37
            throw new \RuntimeException('Index must be end position');
100 37
        }
101
    }
102
103
    /**
104
     * @see \ArrayAccess::offsetExists()
105
     * @param int $offset
106
     * @return bool
107
     */
108
    public function offsetExists($offset)
109
    {
110
        $index = count($this) + $offset;
111
        return isset($this->values[$index]);
112
    }
113 3
114
    /**
115 3
     * @see \ArrayAccess::offsetUnset()
116 3
     * @param int $offset
117
     */
118
    public function offsetUnset($offset)
119
    {
120
        $count = count($this);
121
        $index = $count + $offset;
122
        if (!isset($this->values[$index])) {
123 48
            throw new \RuntimeException('Nothing at this position');
124
        }
125 48
126 48
        array_splice($this->values, $index, 1);
127 48
    }
128 3
129
    /**
130
     * @param int $first
131 45
     * @param int $second
132 45
     */
133
    public function swap($first, $second)
134
    {
135
        $val1 = $this->offsetGet($first);
136
        $val2 = $this->offsetGet($second);
137
        $this->offsetSet($second, $val1);
138 37
        $this->offsetSet($first, $val2);
139
    }
140 37
141 37
    /**
142 37
     * @param int $offset
143 37
     * @param BufferInterface $value
144 37
     */
145
    public function add($offset, $value)
146
    {
147
        $size = count($this);
148
        $index = $size + $offset;
149
        if ($index > $size) {
150 12
            throw new \RuntimeException('Invalid add position');
151
        }
152 12
153 12
        // Unwind current values, push provided value, reapply popped values
154 12
        $values = [];
155
        for ($i = $size; $i > $index; $i--) {
156
            $values[] = $this->pop();
157
        }
158
159 12
        $this->push($value);
160 12
        for ($i = count($values); $i > 0; $i--) {
161 12
            $this->push(array_pop($values));
162 7
        }
163
    }
164 12
165 12
    public function pop()
166 12
    {
167 7
        $count = count($this);
168 12
        if ($count === 0) {
169
            throw new \RuntimeException('Cannot pop from empty stack');
170 1540
        }
171
172 1540
        $value = array_pop($this->values);
173 1540
        return $value;
174 3
    }
175
176
    public function push($buffer)
177 1537
    {
178 1537
        $this->values[] = $buffer;
179
    }
180
181 2114
    /**
182
     * @return int
183 2114
     */
184 2114
    public function end()
185
    {
186
        $count = count($this);
187
        if ($count === 0) {
188
            return 0;
189
        }
190
191
        return $count - 1;
192
    }
193
194
    /**
195
     * @param int $length
196
     * @return $this
197
     */
198
    public function resize($length)
199
    {
200
        if ($length > count($this)) {
201
            throw new \RuntimeException('Invalid start or length');
202
        }
203 23
204
        while (count($this) > $length) {
205 23
            $this->pop();
206
        }
207
208
        return $this;
209 23
    }
210
}
211