mirror of
https://gitlab.com/hashborgir/d2tools.git
synced 2024-11-30 12:36:03 +00:00
278 lines
6.8 KiB
PHP
278 lines
6.8 KiB
PHP
<?php
|
|
|
|
require_once './src/D2Functions.php';
|
|
require_once './src/D2BitReader.php';
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class D2ByteReader {
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private string $data = '';
|
|
/**
|
|
* @var int
|
|
*/
|
|
private int $offset = 0;
|
|
|
|
/**
|
|
* @param string $data
|
|
*/
|
|
public function __construct(string $data) {
|
|
if (!$data)
|
|
return false;
|
|
$this->data = $data;
|
|
}
|
|
|
|
/**
|
|
* @param int $numBytes
|
|
* @return bool
|
|
*/
|
|
public function skip(int $numBytes): bool {
|
|
if ($numBytes < 0 || $numBytes > strlen($this->data))
|
|
return false;
|
|
$this->offset += $numBytes;
|
|
return $true;
|
|
}
|
|
|
|
/**
|
|
* @param int $pos
|
|
* @return bool
|
|
*/
|
|
public function seek(int $pos): bool {
|
|
if ($pos < 0 || $pos > strlen($this->data))
|
|
return false;
|
|
$this->offset = $pos;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param int $offset
|
|
* @param int $numBytes
|
|
* @param bool $str
|
|
* @return string
|
|
*/
|
|
public function read(int $offset, int $numBytes) {
|
|
$this->seek($offset);
|
|
$bytes = null;
|
|
for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) {
|
|
$bytes .= $this->data[$i];
|
|
}
|
|
return $bytes;
|
|
}
|
|
|
|
/**
|
|
* @param int $offset
|
|
* @param int $numBytes
|
|
* @param bool $str
|
|
* @return string
|
|
*/
|
|
public function readh(int $offset, int $numBytes, bool $str = true) {
|
|
$this->seek($offset);
|
|
$bytes = null;
|
|
for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) {
|
|
$str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i];
|
|
}
|
|
return unpack('H*', $bytes)[1];
|
|
}
|
|
|
|
/**
|
|
* @param int $offset
|
|
* @param int $numBytes
|
|
* @param bool $str
|
|
* @return array
|
|
*/
|
|
public function readc(int $offset, int $numBytes, bool $str = true) {
|
|
$this->seek($offset);
|
|
$bytes = null;
|
|
for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) {
|
|
$str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i];
|
|
}
|
|
return unpack('C*', $bytes);
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function rewind(): bool {
|
|
$this->offset = 0;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param int $offset
|
|
* @param int $byte
|
|
* @return void
|
|
*/
|
|
public function writeByte(int $offset, int $byte) {
|
|
$this->data[$offset] = pack('C', $byte);
|
|
}
|
|
|
|
/**
|
|
* @param int $offset
|
|
* @param string $bytes
|
|
* @return false|void
|
|
*/
|
|
public function writeBytes(int $offset, string $bytes) {
|
|
if ($offset < 0 || $offset > strlen($this->data) || $bytes == '')
|
|
return false;
|
|
$_bytes = str_split($bytes, 2);
|
|
foreach ($_bytes as $k => $byte) {
|
|
$pos = $offset + $k;
|
|
$this->data[$pos] = pack('H*', $byte);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param int $offset
|
|
* @param string $bytes
|
|
* @return false|void
|
|
*/
|
|
public function insertBytes(int $offset, string $bytes) {
|
|
if ($offset < 0 || $offset > strlen($this->data) || $bytes == '')
|
|
return false;
|
|
$data = bin2hex($this->data); // convert to hex bytes string
|
|
$newData = substr_replace($data, $bytes, $offset, 0);
|
|
$this->data = hex2bin($newData);
|
|
}
|
|
|
|
/**
|
|
* @return false|string
|
|
*/
|
|
public function getData() {
|
|
return $this->data ? $this->data : false;
|
|
}
|
|
|
|
/**
|
|
* @param $data
|
|
* @return void
|
|
*/
|
|
public function setData($data){
|
|
$this->data = $data;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function getOffset(): int {
|
|
return $this->offset;
|
|
}
|
|
|
|
/**
|
|
* @param string $str
|
|
* @return bool
|
|
*/
|
|
public function isHexString(string $str): bool {
|
|
if (strlen($str) % 2 == 0 && (ctype_xdigit($str))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param $input
|
|
* @return string
|
|
*/
|
|
public function toBits($input): string {
|
|
$output = '';
|
|
if ($this->isHexString($input)) {
|
|
foreach (str_split($input, 2) as $byte) {
|
|
$output .= (strrev(str_pad(decbin(hexdec($byte)), 8, 0, STR_PAD_LEFT)));
|
|
}
|
|
return $output;
|
|
} else if (is_string($input)) {
|
|
foreach (str_split($input) as $i) {
|
|
$output .= strrev(str_pad(decbin(ord($i)), 8, 0, STR_PAD_LEFT));
|
|
}
|
|
return $output;
|
|
} else if (is_int($input)) {
|
|
return strrev(str_pad(decbin($input), 8, 0, STR_PAD_LEFT));
|
|
} else if (is_array($input)) {
|
|
foreach ($input as $i) {
|
|
$output .= $this->tobits($i);
|
|
}
|
|
return $output;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $bits
|
|
* @return string
|
|
*/
|
|
public function toBytesR(string $bits) : string {
|
|
$bytes = '';
|
|
foreach (str_split($bits, 8) as $byteString) {
|
|
$bytes .= strtoupper(str_pad(dechex(bindec(($byteString))), 2, 0, STR_PAD_LEFT));
|
|
}
|
|
return $bytes;
|
|
}
|
|
|
|
/**
|
|
* @param string $bits
|
|
* @return string
|
|
*/
|
|
public function toBytes(string $bits) : string {
|
|
foreach (str_split($bits, 8) as $byteString) {
|
|
$bytes .= strtoupper(str_pad(dechex(bindec(strrev($byteString))), 2, 0, STR_PAD_LEFT));
|
|
}
|
|
return $bytes;
|
|
}
|
|
|
|
/**
|
|
* @param string $bits
|
|
* @return string
|
|
*/
|
|
public function bitsToHexString(string $bits): string {
|
|
$bytes = '';
|
|
foreach (str_split($bits, 8) as $byte) {
|
|
$bytes .= (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT));
|
|
}
|
|
return $bytes;
|
|
}
|
|
|
|
/**
|
|
* @param string $bits
|
|
* @return array
|
|
*/
|
|
public function bitsToHexArray(string $bits): array {
|
|
$bytes = [];
|
|
foreach (str_split($bits, 8) as $byte) {
|
|
$bytes[] = (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT));
|
|
}
|
|
return $bytes;
|
|
}
|
|
|
|
/**
|
|
* @param string $bits
|
|
* @return array
|
|
*/
|
|
public function bitsToIntArray(string $bits): array {
|
|
$bytes = [];
|
|
foreach (str_split($bits, 8) as $byte) {
|
|
$bytes[] = (int) (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT));
|
|
}
|
|
return $bytes;
|
|
}
|
|
|
|
/**
|
|
* @param int $byte
|
|
* @param int $pos
|
|
* @param bool $bit
|
|
* @return int
|
|
*/
|
|
public function setBit(int $byte, int $pos, bool $bit) {
|
|
return ($bit ? ($byte | (1 << $pos)) : ($byte & ~(1 << $pos)) );
|
|
}
|
|
|
|
/**
|
|
* @param int $byte
|
|
* @param int $pos
|
|
* @return int
|
|
*/
|
|
public function getBit(int $byte, int $pos): int {
|
|
return intval(($byte & (1 << $pos)) != 0);
|
|
}
|
|
|
|
} |