Completed
Push — master ( bbb742...e4897b )
by smiley
02:38
created

ByteArray::equal()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class ByteArray
4
 *
5
 * @filesource   ByteArray.php
6
 * @created      05.12.2017
7
 * @package      chillerlan\Traits\ArrayHelpers
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Traits\ArrayHelpers;
14
15
use ReflectionClass, SplFixedArray;
16
17
/**
18
 * @extends \SplFixedArray
19
 */
20
class ByteArray extends SplFixedArray{
21
22
	/**
23
	 * @return string
24
	 */
25
	public function toString():string{
26
		return $this->map('chr');
27
	}
28
29
	/**
30
	 * @return string
31
	 */
32
	public function toHex():string{
33
		return $this->map(function($v){
34
			return str_pad(dechex($v), '2', '0', STR_PAD_LEFT);
35
		});
36
	}
37
38
	/**
39
	 * @return string
40
	 */
41
	public function toJSON():string{
42
		return json_encode($this->toArray());
43
	}
44
45
	/**
46
	 * @return string
47
	 */
48
	public function toBase64():string{
49
		return base64_encode($this->toString());
50
	}
51
52
	/**
53
	 * @return string
54
	 */
55
	public function toBin():string{
56
		return $this->map(function($v){
57
			return str_pad(decbin($v), '8', '0', STR_PAD_LEFT);
58
		});
59
	}
60
61
	/**
62
	 * @param callable $m
63
	 *
64
	 * @return string
65
	 */
66
	private function map(callable $m):string{
67
		return implode('', array_map($m, $this->toArray()));
68
	}
69
70
	/**
71
	 * @param \SplFixedArray $src
72
	 * @param int            $length
73
	 * @param int|null       $offset
74
	 * @param int|null       $srcOffset
75
	 *
76
	 * @return \chillerlan\Traits\ArrayHelpers\ByteArray
77
	 */
78
	public function copyFrom(SplFixedArray $src, int $length = null, int $offset = null, int $srcOffset = null):ByteArray{
79
		$length    = $length !== null ? $length : $src->count();
80
		$offset    = $offset !== null ? $offset : 0;
81
		$srcOffset = $srcOffset !== null ? $srcOffset : 0;
82
83
		$diff = $offset + $length;
84
85
		if($diff > $this->count()){
86
			$this->setSize($diff);
87
		}
88
89
		for($i = 0; $i < $length; $i++){
90
			$this[$i + $offset] = $src[$i + $srcOffset];
91
		}
92
93
		return $this;
94
	}
95
96
	/**
97
	 * @param int      $offset
98
	 * @param int|null $length
99
	 *
100
	 * @return \chillerlan\Traits\ArrayHelpers\ByteArray
101
	 */
102
	public function slice(int $offset, int $length = null):ByteArray{
103
		/** @var \chillerlan\Traits\ArrayHelpers\ByteArray $slice */
104
		$slice  = (new ReflectionClass($this))->newInstanceArgs([$length ?? $this->count() - $offset]);
105
106
		foreach($slice as $i => $_){
107
			$slice[$i] = $this[$offset + $i];
108
		}
109
110
		return $slice;
111
	}
112
113
	/**
114
	 * @param \SplFixedArray $array
115
	 *
116
	 * @return bool
117
	 */
118
	public function equal(SplFixedArray $array):bool{
119
120
		if($this->count() !== $array->count()){
121
			return false; // @todo: throw Exception?
122
		}
123
124
		$diff = 0;
125
126
		foreach($this as $k => $v){
127
			$diff |= $v ^ $array[$k];
128
		}
129
130
		$diff = ($diff - 1) >> 31;
131
132
		return ($diff & 1) === 1;
133
	}
134
135
}
136