Comments and cleanup

This commit is contained in:
Hash Borgir 2023-06-01 23:30:55 -06:00
parent 74eb169be4
commit c63393c225
2 changed files with 167 additions and 137 deletions

View File

@ -1,21 +1,23 @@
<?php <?php
/** /**
* * D2BitReader class.
*/ */
class D2BitReader { class D2BitReader {
/** /**
* @var string * @var string The bit string.
*/ */
private string $bits = ''; private string $bits = '';
/** /**
* @var int * @var int The offset position.
*/ */
private int $offset = 0; private int $offset = 0;
/** /**
* @param string $bits * D2BitReader constructor.
*
* @param string $bits The bit string.
*/ */
public function __construct(string $bits = '') { public function __construct(string $bits = '') {
$this->bits = $bits; $this->bits = $bits;
@ -23,22 +25,24 @@ class D2BitReader {
} }
/** /**
* @param int $numBits * Skips a specified number of bits.
* @return int *
* @param int $numBits The number of bits to skip.
* @return int The new offset position.
*/ */
public function skip(int $numBits): int { public function skip(int $numBits): int {
$this->offset += $numBits; $this->offset += $numBits;
return $this->offset; return $this->offset;
} }
/* read X number of bits, like fread */
/** /**
* @param int $numBits * Reads a specified number of bits.
* @param bool $str *
* @return string * @param int $numBits The number of bits to read.
* @param bool $str Determines whether to return a string or an array of bits.
* @return string|array The read bits.
*/ */
public function read(int $numBits = 0, bool $str = true): string { public function read(int $numBits = 0, bool $str = true): string|array {
$bits = null; $bits = null;
for ($i = $this->offset; $i < $this->offset + $numBits; $i++) { for ($i = $this->offset; $i < $this->offset + $numBits; $i++) {
$str ? $bits .= $this->bits[$i] : $bits[] = $this->bits[$i]; $str ? $bits .= $this->bits[$i] : $bits[] = $this->bits[$i];
@ -48,20 +52,23 @@ class D2BitReader {
} }
/** /**
* @param string $bits * Writes bits to a specified offset in the bit string.
* @param string $bitsToWrite *
* @param int $offset * @param string $bits The original bit string.
* @return array|string|string[] * @param string $bitsToWrite The bits to write.
* @param int $offset The offset position to write at.
* @return array|string|string[] The modified bit string.
*/ */
public function writeBits(string $bits, string $bitsToWrite, int $offset) { public function writeBits(string $bits, string $bitsToWrite, int $offset) {
//$this->bits = substr_replace($bits, $bitsToWrite, $offset, strlen($bitsToWrite));
return substr_replace($bits, $bitsToWrite, $offset, strlen($bitsToWrite)); return substr_replace($bits, $bitsToWrite, $offset, strlen($bitsToWrite));
} }
/** /**
* @param int $numBits * Reads a specified number of bits in reverse order.
* @param bool $str *
* @return string * @param int $numBits The number of bits to read.
* @param bool $str Determines whether to return a string or an array of bits.
* @return string The read bits in reverse order.
*/ */
public function readb(int $numBits = 0, bool $str = true): string { public function readb(int $numBits = 0, bool $str = true): string {
$bits = ''; $bits = '';
@ -73,8 +80,10 @@ class D2BitReader {
} }
/** /**
* @param int $numBits * Reads a specified number of bits in reverse order.
* @return string *
* @param int $numBits The number of bits to read.
* @return string The read bits in reverse order.
*/ */
public function readr(int $numBits = 0): string { public function readr(int $numBits = 0): string {
$bits = null; $bits = null;
@ -85,11 +94,11 @@ class D2BitReader {
return strrev($bits); return strrev($bits);
} }
/* seek to offset (like fseek) */
/** /**
* @param int $pos * Sets the offset position.
* @return bool *
* @param int $pos The new offset position.
* @return bool Returns true if the offset position is valid, false otherwise.
*/ */
public function seek(int $pos): bool { public function seek(int $pos): bool {
if ($pos < 0 || $pos > strlen($this->bits)) { if ($pos < 0 || $pos > strlen($this->bits)) {
@ -99,35 +108,35 @@ class D2BitReader {
return true; return true;
} }
/* rewind offset to 0 */
/** /**
* @return bool * Rewinds the offset position to 0.
*
* @return bool Returns true on success.
*/ */
public function rewind(): bool { public function rewind(): bool {
$this->offset = 0; $this->offset = 0;
return true; return true;
} }
/* Get Bit */
/** /**
* @param string $bitNum * Retrieves the value of a bit at a given position.
* @return int *
* @param string $bitNum The position of the bit.
* @return int The value of the bit (0 or 1).
*/ */
public function getBit(string $bitNum): int { public function getBit(string $bitNum): int {
if ($bitNum < 0 || $bitNum > strlen($this->bits)) { if ($bitNum < 0 || $bitNum > strlen($this->bits)) {
return false; return false;
} }
return ((int) $this->bits[$bitNum] ? 1 : 0 ); return ((int) $this->bits[$bitNum] ? 1 : 0);
} }
/* Set Bit */
/** /**
* @param int $bitNum * Sets the value of a bit at a given position.
* @param int $bitVal *
* @return bool * @param int $bitNum The position of the bit.
* @param int $bitVal The value to set (0 or 1).
* @return bool Returns true on success.
*/ */
public function setBit(int $bitNum, int $bitVal): bool { public function setBit(int $bitNum, int $bitVal): bool {
if ($bitVal < 0 || $bitVal > 1) { if ($bitVal < 0 || $bitVal > 1) {
@ -138,14 +147,18 @@ class D2BitReader {
} }
/** /**
* @return string * Retrieves the bit string.
*
* @return string The bit string.
*/ */
public function getBits(): string { public function getBits(): string {
return $this->bits; return $this->bits;
} }
/** /**
* @param string $bits * Sets the bit string.
*
* @param string $bits The new bit string.
* @return void * @return void
*/ */
public function setBits(string $bits) { public function setBits(string $bits) {
@ -153,21 +166,25 @@ class D2BitReader {
} }
/** /**
* @return int * Retrieves the offset position.
*
* @return int The offset position.
*/ */
public function getOffset(): int { public function getOffset(): int {
return $this->offset; return $this->offset;
} }
/** /**
* @param int $offset * Sets the offset position.
* @return bool *
* @param int $offset The new offset position.
* @return bool Returns true if the offset position is valid, false otherwise.
*/ */
public function setOffset(int $offset): bool { public function setOffset(int $offset): bool {
if ($offset < 0 || $offset > strlen($this->bits)) if ($offset < 0 || $offset > strlen($this->bits)) {
return false; return false;
}
$this->offset = $offset; $this->offset = $offset;
return true; return true;
} }
} }

View File

@ -4,70 +4,84 @@ require_once './src/D2Functions.php';
require_once './src/D2BitReader.php'; require_once './src/D2BitReader.php';
/** /**
* * A class for reading and manipulating bytes.
*/ */
class D2ByteReader { class D2ByteReader {
/** /**
* @var string * @var string The byte data.
*/ */
private string $data = ''; private string $data = '';
/** /**
* @var int * @var int The current offset position.
*/ */
private int $offset = 0; private int $offset = 0;
/** /**
* @param string $data * Constructs a new D2ByteReader instance.
*
* @param string $data The byte data to read.
*/ */
public function __construct(string $data) { public function __construct(string $data) {
if (!$data) if (!$data) {
return false; return false;
}
$this->data = $data; $this->data = $data;
} }
/** /**
* @param int $numBytes * Skips a specified number of bytes.
* @return bool *
* @param int $numBytes The number of bytes to skip.
* @return bool Returns true on success, false otherwise.
*/ */
public function skip(int $numBytes): bool { public function skip(int $numBytes): bool {
if ($numBytes < 0 || $numBytes > strlen($this->data)) if ($numBytes < 0 || $numBytes > strlen($this->data)) {
return false; return false;
}
$this->offset += $numBytes; $this->offset += $numBytes;
return $true; return true;
} }
/** /**
* @param int $pos * Moves the offset position to a specified position.
* @return bool *
* @param int $pos The new offset position.
* @return bool Returns true if the offset position is valid, false otherwise.
*/ */
public function seek(int $pos): bool { public function seek(int $pos): bool {
if ($pos < 0 || $pos > strlen($this->data)) if ($pos < 0 || $pos > strlen($this->data)) {
return false; return false;
}
$this->offset = $pos; $this->offset = $pos;
return true; return true;
} }
/** /**
* @param int $offset * Reads a specified number of bytes from the current offset position.
* @param int $numBytes *
* @param bool $str * @param int $offset The offset position to start reading from.
* @return string * @param int $numBytes The number of bytes to read.
* @param bool $str Indicates whether to return the result as a string (default) or an array.
* @return string|array The read bytes.
*/ */
public function read(int $offset, int $numBytes) { public function read(int $offset, int $numBytes, bool $str = true) {
$this->seek($offset); $this->seek($offset);
$bytes = null; $bytes = null;
for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) { for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) {
$bytes .= $this->data[$i]; $str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i];
} }
return $bytes; return $bytes;
} }
/** /**
* @param int $offset * Reads a specified number of bytes from the current offset position and returns them as a hex string.
* @param int $numBytes *
* @param bool $str * @param int $offset The offset position to start reading from.
* @return string * @param int $numBytes The number of bytes to read.
* @param bool $str Indicates whether to return the result as a string (default) or an array.
* @return string The read bytes as a hex string.
*/ */
public function readh(int $offset, int $numBytes, bool $str = true) { public function readh(int $offset, int $numBytes, bool $str = true) {
$this->seek($offset); $this->seek($offset);
@ -79,10 +93,12 @@ class D2ByteReader {
} }
/** /**
* @param int $offset * Reads a specified number of bytes from the current offset position and returns them as an array of integers.
* @param int $numBytes *
* @param bool $str * @param int $offset The offset position to start reading from.
* @return array * @param int $numBytes The number of bytes to read.
* @param bool $str Indicates whether to return the result as a string (default) or an array.
* @return array The read bytes as an array of integers.
*/ */
public function readc(int $offset, int $numBytes, bool $str = true) { public function readc(int $offset, int $numBytes, bool $str = true) {
$this->seek($offset); $this->seek($offset);
@ -94,7 +110,9 @@ class D2ByteReader {
} }
/** /**
* @return bool * Rewinds the offset position to the beginning.
*
* @return bool Returns true on success.
*/ */
public function rewind(): bool { public function rewind(): bool {
$this->offset = 0; $this->offset = 0;
@ -102,8 +120,10 @@ class D2ByteReader {
} }
/** /**
* @param int $offset * Writes a byte at the specified offset position.
* @param int $byte *
* @param int $offset The offset position to write the byte.
* @param int $byte The byte value to write.
* @return void * @return void
*/ */
public function writeByte(int $offset, int $byte) { public function writeByte(int $offset, int $byte) {
@ -111,13 +131,16 @@ class D2ByteReader {
} }
/** /**
* @param int $offset * Writes multiple bytes starting from the specified offset position.
* @param string $bytes *
* @return false|void * @param int $offset The offset position to start writing from.
* @param string $bytes The bytes to write.
* @return false|void Returns false on failure or void on success.
*/ */
public function writeBytes(int $offset, string $bytes) { public function writeBytes(int $offset, string $bytes) {
if ($offset < 0 || $offset > strlen($this->data) || $bytes == '') if ($offset < 0 || $offset > strlen($this->data) || $bytes == '') {
return false; return false;
}
$_bytes = str_split($bytes, 2); $_bytes = str_split($bytes, 2);
foreach ($_bytes as $k => $byte) { foreach ($_bytes as $k => $byte) {
$pos = $offset + $k; $pos = $offset + $k;
@ -126,27 +149,34 @@ class D2ByteReader {
} }
/** /**
* @param int $offset * Inserts bytes at the specified offset position.
* @param string $bytes *
* @return false|void * @param int $offset The offset position to insert the bytes.
* @param string $bytes The bytes to insert.
* @return false|void Returns false on failure or void on success.
*/ */
public function insertBytes(int $offset, string $bytes) { public function insertBytes(int $offset, string $bytes) {
if ($offset < 0 || $offset > strlen($this->data) || $bytes == '') if ($offset < 0 || $offset > strlen($this->data) || $bytes == '') {
return false; return false;
}
$data = bin2hex($this->data); // convert to hex bytes string $data = bin2hex($this->data); // convert to hex bytes string
$newData = substr_replace($data, $bytes, $offset, 0); $newData = substr_replace($data, $bytes, $offset, 0);
$this->data = hex2bin($newData); $this->data = hex2bin($newData);
} }
/** /**
* @return false|string * Returns the byte data.
*
* @return false|string Returns the byte data on success, or false if no data is set.
*/ */
public function getData() { public function getData() {
return $this->data ? $this->data : false; return $this->data ? $this->data : false;
} }
/** /**
* @param $data * Sets the byte data.
*
* @param $data The byte data to set.
* @return void * @return void
*/ */
public function setData($data){ public function setData($data){
@ -154,26 +184,32 @@ class D2ByteReader {
} }
/** /**
* @return int * Returns the current offset position.
*
* @return int The current offset position.
*/ */
public function getOffset(): int { public function getOffset(): int {
return $this->offset; return $this->offset;
} }
/** /**
* @param string $str * Checks if a string is a valid hexadecimal string.
* @return bool *
* @param string $str The string to check.
* @return bool Returns true if the string is a valid hexadecimal string, false otherwise.
*/ */
public function isHexString(string $str): bool { public function isHexString(string $str): bool {
if (strlen($str) % 2 == 0 && (ctype_xdigit($str))) { if (strlen($str) % 2 == 0 && ctype_xdigit($str)) {
return true; return true;
} }
return false; return false;
} }
/** /**
* @param $input * Converts input to a string of bits.
* @return string *
* @param mixed $input The input to convert.
* @return string The converted string of bits.
*/ */
public function toBits($input): string { public function toBits($input): string {
$output = ''; $output = '';
@ -191,29 +227,34 @@ class D2ByteReader {
return strrev(str_pad(decbin($input), 8, 0, STR_PAD_LEFT)); return strrev(str_pad(decbin($input), 8, 0, STR_PAD_LEFT));
} else if (is_array($input)) { } else if (is_array($input)) {
foreach ($input as $i) { foreach ($input as $i) {
$output .= $this->tobits($i); $output .= $this->toBits($i);
} }
return $output; return $output;
} }
} }
/** /**
* @param string $bits * Converts a string of bits to bytes (reversing the bit order).
* @return string *
* @param string $bits The string of bits to convert.
* @return string The converted bytes.
*/ */
public function toBytesR(string $bits) : string { public function toBytesR(string $bits) : string {
$bytes = ''; $bytes = '';
foreach (str_split($bits, 8) as $byteString) { foreach (str_split($bits, 8) as $byteString) {
$bytes .= strtoupper(str_pad(dechex(bindec(($byteString))), 2, 0, STR_PAD_LEFT)); $bytes .= strtoupper(str_pad(dechex(bindec($byteString)), 2, 0, STR_PAD_LEFT));
} }
return $bytes; return $bytes;
} }
/** /**
* @param string $bits * Converts a string of bits to bytes.
* @return string *
* @param string $bits The string of bits to convert.
* @return string The converted bytes.
*/ */
public function toBytes(string $bits) : string { public function toBytes(string $bits) : string {
$bytes = '';
foreach (str_split($bits, 8) as $byteString) { foreach (str_split($bits, 8) as $byteString) {
$bytes .= strtoupper(str_pad(dechex(bindec(strrev($byteString))), 2, 0, STR_PAD_LEFT)); $bytes .= strtoupper(str_pad(dechex(bindec(strrev($byteString))), 2, 0, STR_PAD_LEFT));
} }
@ -221,58 +262,30 @@ class D2ByteReader {
} }
/** /**
* @param string $bits * Converts a string of bits to a hexadecimal string.
* @return string *
* @param string $bits The string of bits to convert.
* @return string The converted hexadecimal string.
*/ */
public function bitsToHexString(string $bits): string { public function bitsToHexString(string $bits): string {
$bytes = ''; $bytes = '';
foreach (str_split($bits, 8) as $byte) { foreach (str_split($bits, 8) as $byte) {
$bytes .= (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT)); $bytes .= (str_pad(dechex(bindec(strrev($byte))), 2, 0, STR_PAD_LEFT));
} }
return $bytes; return $bytes;
} }
/** /**
* @param string $bits * Converts a string of bits to an array of hexadecimal values.
* @return array *
* @param string $bits The string of bits to convert.
* @return array The converted array of hexadecimal values.
*/ */
public function bitsToHexArray(string $bits): array { public function bitsToHexArray(string $bits): array {
$bytes = []; $bytes = [];
foreach (str_split($bits, 8) as $byte) { foreach (str_split($bits, 8) as $byte) {
$bytes[] = (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT)); $bytes[] = (str_pad(dechex(bindec(strrev($byte))), 2, 0, STR_PAD_LEFT));
} }
return $bytes; 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);
}
}