123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- <?php
- namespace App\Services\Web3\RLP;
- use InvalidArgumentException;
- use ArrayAccess;
- class Buffer implements ArrayAccess
- {
-
- protected $data = [];
-
- protected $encoding = '';
-
- public function __construct($data=[], string $encoding='utf8')
- {
- $this->encoding = strtolower($encoding);
- if ($data) {
- $this->data = $this->decodeToData($data);
- }
- }
-
- public function offsetSet($offset, $value)
- {
- if (is_null($offset)) {
- $this->data[] = $value;
- } else {
- $this->data[$offset] = $value;
- }
- }
-
- public function offsetExists($offset)
- {
- return isset($this->data[$offset]);
- }
-
- public function offsetUnset($offset)
- {
- unset($this->data[$offset]);
- }
-
- public function offsetGet($offset)
- {
- return isset($this->data[$offset]) ? $this->data[$offset] : null;
- }
-
- public function toString(string $encoding='utf8')
- {
- $output = '';
- $input = $this->data;
- switch ($encoding) {
- case 'hex':
- foreach ($input as $data) {
- $hex = dechex($data);
-
- if ((strlen($hex) % 2) !== 0) {
- $hex = '0' . $hex;
- }
- $output .= $hex;
- }
- break;
- case 'ascii':
- foreach ($input as $data) {
- $output .= chr($data);
- }
- break;
- case 'utf8':
-
-
-
-
-
- foreach ($input as $data) {
- $output .= chr($data);
- }
- break;
- default:
- throw new InvalidArgumentException('ToString encoding must be valid.');
- break;
- }
- return $output;
- }
-
- public function length()
- {
- return count($this->data);
- }
-
- public function concat()
- {
- $inputs = func_get_args();
- foreach ($inputs as $input) {
- if (is_array($input)) {
- $input = new Buffer($input);
- }
- if ($input instanceof Buffer) {
- $length = $input->length();
- for ($i = 0; $i < $length; $i++) {
- $this->data[] = $input[$i];
- }
- } else {
- throw new InvalidArgumentException('Input must be array or Buffer when call concat.');
- }
- }
- return $this;
- }
-
- public function slice(int $start=0, $end=null)
- {
- if ($end === null) {
- $end = $this->length();
- }
- if ($end > 0) {
- $end -= $start;
- } elseif ($end === 0) {
- return new Buffer([]);
- }
- $sliced = array_slice($this->data, $start, $end);
- return new Buffer($sliced);
- }
-
- protected function decodeToData($input)
- {
- $output = [];
- if (is_array($input)) {
- $output = $this->arrayToData($input);
- } elseif (is_int($input)) {
- $output = $this->intToData($input);
- } elseif (is_numeric($input)) {
- $output = $this->numericToData($input);
- } elseif (is_string($input)) {
- $output = $this->stringToData($input, $this->encoding);
- }
- return $output;
- }
-
- protected function arrayToData(array $inputs)
- {
- $output = [];
- foreach ($inputs as $input) {
- if (is_array($input)) {
-
-
- throw new InvalidArgumentException('Do not use multidimensional array.');
- } elseif (is_string($input)) {
- $output = array_merge($output, $this->stringToData($input, $this->encoding));
- } elseif (is_numeric($input)) {
- $output = array_merge($output, $this->numericToData($input));
- }
- }
- return $output;
- }
-
- protected function stringToData(string $input, string $encoding)
- {
- $output = [];
- switch ($encoding) {
- case 'hex':
- if (strpos($input, '0x') === 0) {
-
- $input = str_replace('0x', '', $input);
- }
- if (strlen($input) % 2 !== 0) {
- $input = '0' . $input;
- }
-
-
-
-
- $output = array_map('hexdec', str_split($input, 2));
- break;
- case 'ascii':
- $output = array_map('ord', str_split($input, 1));
- break;
- case 'utf8':
- $output = unpack('C*', $input);
- break;
- default:
- throw new InvalidArgumentException('StringToData encoding must be valid.');
- break;
- }
- return $output;
- }
-
- protected function numericToData($intput)
- {
- $output = (int) $intput;
- return [$output];
- }
-
- protected function intToData($input)
- {
- return array_fill(0, $input, 0);
- }
- }
|