From b1448fb3a1d26fa30df38374e8c9bd1f23475a4b Mon Sep 17 00:00:00 2001 From: Krystian Duma Date: Thu, 18 Sep 2025 18:21:19 +0200 Subject: [PATCH 1/5] Revise binary tools documentation for integer and terminator updates Updated binary tools documentation to reflect changes in integer handling and added support for terminators. --- content/3.libraries/100.php/binary-tools.md | 252 +++++++++++++++++--- 1 file changed, 225 insertions(+), 27 deletions(-) diff --git a/content/3.libraries/100.php/binary-tools.md b/content/3.libraries/100.php/binary-tools.md index 3171ea7..2f6a339 100644 --- a/content/3.libraries/100.php/binary-tools.md +++ b/content/3.libraries/100.php/binary-tools.md @@ -35,8 +35,9 @@ composer require kduma/binary-tools - **UTF-8 string validation** for text data - **Multiple encoding formats** (hex, base64, base32) - **Secure string comparison** using `hash_equals()` -- **Big-endian integer support** for network protocols +- **Flexible integer support** with configurable byte order and signedness - **Position tracking** for streaming operations +- **Terminator support** for null-terminated and delimited data parsing ## Core Classes @@ -52,6 +53,14 @@ Stream-like writer for building binary data structures. Stream-like reader for parsing binary data with position tracking. +### IntType + +Enum defining integer types with configurable byte order, signedness, and platform validation. + +### Terminator + +Enum defining common binary terminators for delimited data parsing. + ## Usage Examples @@ -88,19 +97,26 @@ if ($binary->equals($other)) { ```php use KDuma\BinaryTools\BinaryWriter; use KDuma\BinaryTools\BinaryString; +use KDuma\BinaryTools\IntType; $writer = new BinaryWriter(); // Write different data types $writer->writeByte(0x42) // Single byte - ->writeUint16BE(1234) // 16-bit big-endian integer + ->writeInt(IntType::UINT16, 1234) // 16-bit unsigned integer + ->writeInt(IntType::INT32_LE, -500) // 32-bit signed little-endian ->writeBytes(BinaryString::fromHex("abcd")) // Raw bytes ->writeString(BinaryString::fromString("Hello")); // UTF-8 string // Write strings with length prefixes $text = BinaryString::fromString("Hello World"); -$writer->writeStringWithLength($text); // 8-bit length + string -$writer->writeStringWithLength($text, true); // 16-bit length + string +$writer->writeStringWith($text, length: IntType::UINT8); // 8-bit length + string +$writer->writeStringWith($text, length: IntType::UINT16); // 16-bit length + string +$writer->writeBytesWith(BinaryString::fromHex("abcd"), length: IntType::UINT16_LE); // Little-endian length + bytes + +// Write strings with terminators +$writer->writeStringWith($text, terminator: Terminator::NUL); // Null-terminated string +$writer->writeBytesWith($data, terminator: BinaryString::fromString("\r\n")); // Custom terminator // Get the result $result = $writer->getBuffer(); @@ -112,19 +128,27 @@ echo $result->toHex(); // Complete binary data as hex ```php use KDuma\BinaryTools\BinaryReader; use KDuma\BinaryTools\BinaryString; +use KDuma\BinaryTools\IntType; $data = BinaryString::fromHex("4204d2abcd48656c6c6f0548656c6c6f20576f726c64000b48656c6c6f20576f726c64"); $reader = new BinaryReader($data); // Read different data types -$byte = $reader->readByte(); // 0x42 -$uint16 = $reader->readUint16BE(); // 1234 -$bytes = $reader->readBytes(2); // Raw bytes -$string = $reader->readBytes(5); // "Hello" +$byte = $reader->readByte(); // 0x42 +$uint16 = $reader->readInt(IntType::UINT16); // 1234 +$int32le = $reader->readInt(IntType::INT32_LE); // Little-endian 32-bit signed +$bytes = $reader->readBytes(2); // BinaryString with raw bytes +$stringData = $reader->readString(5); // BinaryString with UTF-8 validation +$string = $stringData->toString(); // "Hello" - actual string value // Read strings with length prefixes -$stringWithLength = $reader->readStringWithLength(); // 8-bit length -$stringWithLength16 = $reader->readStringWithLength(true); // 16-bit length +$stringWithLength = $reader->readStringWith(length: IntType::UINT8); // 8-bit length +$stringWithLength16 = $reader->readStringWith(length: IntType::UINT16); // 16-bit length +$bytesWithLength = $reader->readBytesWith(length: IntType::UINT16_LE); // Little-endian length + bytes + +// Read strings with terminators +$nullTermString = $reader->readStringWith(terminator: Terminator::NUL); // Null-terminated +$lineData = $reader->readBytesWith(terminator: BinaryString::fromString("\r\n")); // Custom terminator // Position management echo $reader->position; // Current position @@ -140,6 +164,93 @@ $reader->seek(0); // Go to start $reader->skip(5); // Skip 5 bytes ``` +> **📝 Reading Strings vs Binary Data** +> +> - Use `readString(length)` for UTF-8 text data that needs validation +> - Use `readBytes(length)` for raw binary data (magic bytes, checksums, etc.) +> - Use `readStringWith(length: IntType)` for strings with typed length prefixes +> - Use `readBytesWith(length: IntType)` for binary data with typed length prefixes +> - Use `readStringWith(terminator: Terminator|BinaryString)` for null-terminated or delimited strings (use `BinaryString` for custom termination value) +> - Use `readBytesWith(terminator: BinaryString|BinaryString)` for null-terminated or delimited binary data (use `BinaryString` for custom termination value) +> - Call `toString()` on BinaryString objects to get actual string values + +## Terminator Support + +The library supports both length-prefixed and terminator-delimited data parsing: + +```php +use KDuma\BinaryTools\BinaryWriter; +use KDuma\BinaryTools\BinaryReader; +use KDuma\BinaryTools\BinaryString; +use KDuma\BinaryTools\Terminator; + +// Create some data with different delimiters +$writer = new BinaryWriter(); + +// Null-terminated string (C-style) +$writer->writeStringWith(BinaryString::fromString("Hello World"), terminator: Terminator::NUL); + +// Line-based data with CRLF terminator +$writer->writeBytesWith(BinaryString::fromString("Line 1"), terminator: BinaryString::fromString("\r\n")); +$writer->writeBytesWith(BinaryString::fromString("Line 2"), terminator: BinaryString::fromString("\r\n")); + +// Group separator terminated data +$writer->writeStringWith(BinaryString::fromString("Record 1"), terminator: Terminator::GS); + +// Read the data back +$reader = new BinaryReader($writer->getBuffer()); + +$nullTermString = $reader->readStringWith(terminator: Terminator::NUL); +echo $nullTermString->toString(); // "Hello World" + +$line1 = $reader->readBytesWith(terminator: BinaryString::fromString("\r\n")); +$line2 = $reader->readBytesWith(terminator: BinaryString::fromString("\r\n")); +echo $line1->toString() . " and " . $line2->toString(); // "Line 1 and Line 2" + +$record = $reader->readStringWith(terminator: Terminator::GS); +echo $record->toString(); // "Record 1" +``` + +### Available Terminators + +| Terminator | Value | Description | +|------------|-------|-------------| +| `Terminator::NUL` | `\x00` | Null character (C-style strings) | +| `Terminator::SOH` | `\x01` | Start of Heading | +| `Terminator::STX` | `\x02` | Start of Text | +| `Terminator::ETX` | `\x03` | End of Text | +| `Terminator::EOT` | `\x04` | End of Transmission | +| `Terminator::ENQ` | `\x05` | Enquiry | +| `Terminator::ACK` | `\x06` | Acknowledge | +| `Terminator::BEL` | `\x07` | Bell | +| `Terminator::BS` | `\x08` | Backspace | +| `Terminator::HT` | `\x09` | Horizontal Tab | +| `Terminator::LF` | `\x0A` | Line Feed | +| `Terminator::VT` | `\x0B` | Vertical Tab | +| `Terminator::FF` | `\x0C` | Form Feed | +| `Terminator::CR` | `\x0D` | Carriage Return | +| `Terminator::SO` | `\x0E` | Shift Out | +| `Terminator::SI` | `\x0F` | Shift In | +| `Terminator::DLE` | `\x10` | Data Link Escape | +| `Terminator::DC1` | `\x11` | Device Control 1 (XON) | +| `Terminator::DC2` | `\x12` | Device Control 2 | +| `Terminator::DC3` | `\x13` | Device Control 3 (XOFF) | +| `Terminator::DC4` | `\x14` | Device Control 4 | +| `Terminator::NAK` | `\x15` | Negative Acknowledge | +| `Terminator::SYN` | `\x16` | Synchronous Idle | +| `Terminator::ETB` | `\x17` | End of Transmission Block | +| `Terminator::CAN` | `\x18` | Cancel | +| `Terminator::EM` | `\x19` | End of Medium | +| `Terminator::SUB` | `\x1A` | Substitute | +| `Terminator::ESC` | `\x1B` | Escape | +| `Terminator::FS` | `\x1C` | File Separator | +| `Terminator::GS` | `\x1D` | Group Separator | +| `Terminator::RS` | `\x1E` | Record Separator | +| `Terminator::US` | `\x1F` | Unit Separator | +| `Terminator::SP` | `\x20` | Space | +| `Terminator::CRLF` | `\x0D\x0A` | Carriage Return + Line Feed | +| Custom `BinaryString` | Any bytes | Custom terminator sequence | + ## Common Use Cases ### Protocol Implementation @@ -149,17 +260,17 @@ $reader->skip(5); // Skip 5 bytes $writer = new BinaryWriter(); $message = BinaryString::fromString("Hello, Protocol!"); -$writer->writeByte(0x01) // Message type - ->writeUint16BE(time() & 0xFFFF) // Timestamp (16-bit) - ->writeStringWithLength($message); // Payload +$writer->writeByte(0x01) // Message type + ->writeInt(IntType::UINT16, time() & 0xFFFF) // Timestamp (16-bit) + ->writeStringWith($message, length: IntType::UINT8); // Payload $packet = $writer->getBuffer(); // Reading the protocol message $reader = new BinaryReader($packet); $messageType = $reader->readByte(); -$timestamp = $reader->readUint16BE(); -$payload = $reader->readStringWithLength(); +$timestamp = $reader->readInt(IntType::UINT16); +$payload = $reader->readStringWith(length: IntType::UINT8); echo "Type: {$messageType}, Time: {$timestamp}, Message: {$payload->toString()}"; ``` @@ -173,8 +284,8 @@ $reader = new BinaryReader($fileData); $magic = $reader->readBytes(2)->toString(); // "MZ" if ($magic === "MZ") { - $bytesOnLastPage = $reader->readUint16BE(); - $pagesInFile = $reader->readUint16BE(); + $bytesOnLastPage = $reader->readInt(IntType::UINT16); + $pagesInFile = $reader->readInt(IntType::UINT16); // ... continue parsing } ``` @@ -193,8 +304,8 @@ $users = [ $writer->writeByte(count($users)); // User count foreach ($users as $user) { - $writer->writeUint16BE($user['id']); - $writer->writeStringWithLength(BinaryString::fromString($user['name'])); + $writer->writeInt(IntType::UINT16, $user['id']); + $writer->writeStringWith(BinaryString::fromString($user['name']), length: IntType::UINT8); } $serialized = $writer->getBuffer(); @@ -204,8 +315,8 @@ $reader = new BinaryReader($serialized); $userCount = $reader->readByte(); for ($i = 0; $i < $userCount; $i++) { - $userId = $reader->readUint16BE(); - $userName = $reader->readStringWithLength()->toString(); + $userId = $reader->readInt(IntType::UINT16); + $userName = $reader->readStringWith(length: IntType::UINT8)->toString(); echo "User {$userId}: {$userName}\n"; } ``` @@ -236,10 +347,10 @@ for ($i = 0; $i < $userCount; $i++) { | `reset(): void` | Clear buffer | | `writeByte(int $byte): self` | Write single byte (0-255) | | `writeBytes(BinaryString $bytes): self` | Write binary data | -| `writeUint16BE(int $value): self` | Write 16-bit big-endian integer | +| `writeInt(IntType $type, int $value): self` | Write integer with specified type | | `writeString(BinaryString $string): self` | Write UTF-8 string | -| `writeStringWithLength(BinaryString $string, bool $use16BitLength = false): self` | Write string with length prefix | -| `writeBytesWithLength(BinaryString $bytes, bool $use16BitLength = false): self` | Write bytes with length prefix | +| `writeBytesWith(BinaryString $bytes, ?IntType $length = null, Terminator\|BinaryString\|null $terminator = null): self` | Write bytes with length prefix or terminator | +| `writeStringWith(BinaryString $string, ?IntType $length = null, Terminator\|BinaryString\|null $terminator = null): self` | Write string with length prefix or terminator | ### BinaryReader @@ -253,15 +364,102 @@ for ($i = 0; $i < $userCount; $i++) { | `$remaining_data` | Get remaining data | | `readByte(): int` | Read single byte | | `readBytes(int $count): BinaryString` | Read N bytes | -| `readUint16BE(): int` | Read 16-bit big-endian integer | +| `readInt(IntType $type): int` | Read integer with specified type | | `readString(int $length): BinaryString` | Read UTF-8 string of specific length | -| `readStringWithLength(bool $use16BitLength = false): BinaryString` | Read string with length prefix | -| `readBytesWithLength(bool $use16BitLength = false): BinaryString` | Read bytes with length prefix | +| `readBytesWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null): BinaryString` | Read bytes with length prefix or terminator | +| `readStringWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null): BinaryString` | Read string with length prefix or terminator | | `peekByte(): int` | Peek next byte without advancing | | `peekBytes(int $count): BinaryString` | Peek N bytes without advancing | | `seek(int $position): void` | Seek to position | | `skip(int $count): void` | Skip N bytes | +### IntType + +The `IntType` enum defines various integer types with different byte sizes, signedness, and byte order. + +| Type | Bytes | Signed | Little Endian | Min Value | Max Value | Platform Support | +|------|-------|--------|---------------|-----------|-----------|------------------| +| `UINT8` | 1 | No | N/A | 0 | 255 | Always | +| `INT8` | 1 | Yes | N/A | -128 | 127 | Always | +| `UINT16` | 2 | No | No | 0 | 65535 | Always | +| `INT16` | 2 | Yes | No | -32768 | 32767 | Always | +| `UINT16_LE` | 2 | No | Yes | 0 | 65535 | Always | +| `INT16_LE` | 2 | Yes | Yes | -32768 | 32767 | Always | +| `UINT32` | 4 | No | No | 0 | 4294967295 | Always | +| `INT32` | 4 | Yes | No | -2147483648 | 2147483647 | Always | +| `UINT32_LE` | 4 | No | Yes | 0 | 4294967295 | Always | +| `INT32_LE` | 4 | Yes | Yes | -2147483648 | 2147483647 | Always | +| `UINT64` | 8 | No | No | 0 | PHP_INT_MAX* | 64-bit only | +| `INT64` | 8 | Yes | No | PHP_INT_MIN* | PHP_INT_MAX* | 64-bit only | +| `UINT64_LE` | 8 | No | Yes | 0 | PHP_INT_MAX* | 64-bit only | +| `INT64_LE` | 8 | Yes | Yes | PHP_INT_MIN* | PHP_INT_MAX* | 64-bit only | + +*64-bit types are limited by PHP's integer size on the platform. + +#### IntType Methods + +| Method | Description | +|--------|-------------| +| `bytes(): int` | Get byte size of the type | +| `isSigned(): bool` | Whether the type is signed | +| `isLittleEndian(): bool` | Whether the type uses little-endian byte order | +| `isSupported(): bool` | Whether the type is supported on current platform | +| `minValue(): int` | Get minimum valid value for the type | +| `maxValue(): int` | Get maximum valid value for the type | +| `isValid(int $value): bool` | Check if value is within valid range | + +### Terminator + +| Method | Description | +|--------|-------------| +| `toBytes(): BinaryString` | Get terminator as binary bytes | + +**Available Cases:** +- `Terminator::NUL` - Null character (`\x00`) +- `Terminator::SOH` - Start of Heading (`\x01`) +- `Terminator::STX` - Start of Text (`\x02`) +- `Terminator::ETX` - End of Text (`\x03`) +- `Terminator::EOT` - End of Transmission (`\x04`) +- `Terminator::ENQ` - Enquiry (`\x05`) +- `Terminator::ACK` - Acknowledge (`\x06`) +- `Terminator::BEL` - Bell (`\x07`) +- `Terminator::BS` - Backspace (`\x08`) +- `Terminator::HT` - Horizontal Tab (`\x09`) +- `Terminator::LF` - Line Feed (`\x0A`) +- `Terminator::VT` - Vertical Tab (`\x0B`) +- `Terminator::FF` - Form Feed (`\x0C`) +- `Terminator::CR` - Carriage Return (`\x0D`) +- `Terminator::SO` - Shift Out (`\x0E`) +- `Terminator::SI` - Shift In (`\x0F`) +- `Terminator::DLE` - Data Link Escape (`\x10`) +- `Terminator::DC1` - Device Control 1 (XON) (`\x11`) +- `Terminator::DC2` - Device Control 2 (`\x12`) +- `Terminator::DC3` - Device Control 3 (XOFF) (`\x13`) +- `Terminator::DC4` - Device Control 4 (`\x14`) +- `Terminator::NAK` - Negative Acknowledge (`\x15`) +- `Terminator::SYN` - Synchronous Idle (`\x16`) +- `Terminator::ETB` - End of Transmission Block (`\x17`) +- `Terminator::CAN` - Cancel (`\x18`) +- `Terminator::EM` - End of Medium (`\x19`) +- `Terminator::SUB` - Substitute (`\x1A`) +- `Terminator::ESC` - Escape (`\x1B`) +- `Terminator::FS` - File Separator (`\x1C`) +- `Terminator::GS` - Group Separator (`\x1D`) +- `Terminator::RS` - Record Separator (`\x1E`) +- `Terminator::US` - Unit Separator (`\x1F`) +- `Terminator::SP` - Space (`\x20`) +- `Terminator::CRLF` - Carriage Return + Line Feed (`\x0D\x0A`) + +## Deprecated Methods + +The following methods are deprecated but remain available for backward compatibility: + +- `BinaryWriter::writeUint16BE(int $value)` - Use `writeInt(IntType::UINT16, $value)` instead +- `BinaryWriter::writeBytesWithLength(BinaryString $bytes, bool $use16BitLength = false)` - Use `writeBytesWith($bytes, length: IntType $length)` instead +- `BinaryWriter::writeStringWithLength(BinaryString $string, bool $use16BitLength = false)` - Use `writeStringWith($string, length: IntType $length)` instead +- `BinaryReader::readUint16BE()` - Use `readInt(IntType::UINT16)` instead +- `BinaryReader::readBytesWithLength(bool $use16BitLength = false)` - Use `readBytesWith(length: IntType::UINT8)` instead +- `BinaryReader::readStringWithLength(bool $use16BitLength = false)` - Use `readStringWith(length: IntType::UINT8)` instead ## Error Handling From 3ab776e96077c9d8110a6b3f6f4072f97724c961 Mon Sep 17 00:00:00 2001 From: Krystian Duma Date: Thu, 18 Sep 2025 18:27:29 +0200 Subject: [PATCH 2/5] Update binary-tools.md --- content/3.libraries/100.php/binary-tools.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/content/3.libraries/100.php/binary-tools.md b/content/3.libraries/100.php/binary-tools.md index 2f6a339..3e3fbd2 100644 --- a/content/3.libraries/100.php/binary-tools.md +++ b/content/3.libraries/100.php/binary-tools.md @@ -35,6 +35,7 @@ composer require kduma/binary-tools - **UTF-8 string validation** for text data - **Multiple encoding formats** (hex, base64, base32) - **Secure string comparison** using `hash_equals()` +- **Binary-safe substring search** with `BinaryString::contains()` - **Flexible integer support** with configurable byte order and signedness - **Position tracking** for streaming operations - **Terminator support** for null-terminated and delimited data parsing @@ -90,6 +91,11 @@ $other = BinaryString::fromString("Hello"); if ($binary->equals($other)) { echo "Strings are equal"; } + +// Binary-safe substring search +if ($binary->contains(BinaryString::fromString("He"))) { + echo "Binary data contains 'He'"; +} ``` ### BinaryWriter From 2d5d1f67d0f38c41a559e25d7d91e5be5dd8f671 Mon Sep 17 00:00:00 2001 From: Krystian Duma Date: Thu, 18 Sep 2025 18:52:57 +0200 Subject: [PATCH 3/5] Update terminator handling in binary-tools.md --- content/3.libraries/100.php/binary-tools.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/content/3.libraries/100.php/binary-tools.md b/content/3.libraries/100.php/binary-tools.md index 3e3fbd2..32613c7 100644 --- a/content/3.libraries/100.php/binary-tools.md +++ b/content/3.libraries/100.php/binary-tools.md @@ -153,8 +153,8 @@ $stringWithLength16 = $reader->readStringWith(length: IntType::UINT16); // 16-bi $bytesWithLength = $reader->readBytesWith(length: IntType::UINT16_LE); // Little-endian length + bytes // Read strings with terminators -$nullTermString = $reader->readStringWith(terminator: Terminator::NUL); // Null-terminated -$lineData = $reader->readBytesWith(terminator: BinaryString::fromString("\r\n")); // Custom terminator +$nullTermString = $reader->readStringWith(terminator: Terminator::NUL); // Terminator required +$lineData = $reader->readBytesWith(optional_terminator: BinaryString::fromString("\r\n")); // Terminator optional // Position management echo $reader->position; // Current position @@ -176,8 +176,10 @@ $reader->skip(5); // Skip 5 bytes > - Use `readBytes(length)` for raw binary data (magic bytes, checksums, etc.) > - Use `readStringWith(length: IntType)` for strings with typed length prefixes > - Use `readBytesWith(length: IntType)` for binary data with typed length prefixes -> - Use `readStringWith(terminator: Terminator|BinaryString)` for null-terminated or delimited strings (use `BinaryString` for custom termination value) -> - Use `readBytesWith(terminator: BinaryString|BinaryString)` for null-terminated or delimited binary data (use `BinaryString` for custom termination value) +> - Use `readStringWith(terminator: Terminator|BinaryString)` when the terminator **must** be present +> - Use `readStringWith(optional_terminator: Terminator|BinaryString)` to read until terminator or end of data +> - Use `readBytesWith(terminator: Terminator|BinaryString)` when the terminator **must** be present +> - Use `readBytesWith(optional_terminator: Terminator|BinaryString)` to read until terminator or end of data > - Call `toString()` on BinaryString objects to get actual string values ## Terminator Support @@ -372,8 +374,8 @@ for ($i = 0; $i < $userCount; $i++) { | `readBytes(int $count): BinaryString` | Read N bytes | | `readInt(IntType $type): int` | Read integer with specified type | | `readString(int $length): BinaryString` | Read UTF-8 string of specific length | -| `readBytesWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null): BinaryString` | Read bytes with length prefix or terminator | -| `readStringWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null): BinaryString` | Read string with length prefix or terminator | +| `readBytesWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null, Terminator\|BinaryString\|null $optional_terminator = null): BinaryString` | Read bytes with length prefix, required terminator, or optional terminator | +| `readStringWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null, Terminator\|BinaryString\|null $optional_terminator = null): BinaryString` | Read string with length prefix, required terminator, or optional terminator | | `peekByte(): int` | Peek next byte without advancing | | `peekBytes(int $count): BinaryString` | Peek N bytes without advancing | | `seek(int $position): void` | Seek to position | From 39d2796934d39cf51267cd29f552c25893110ba0 Mon Sep 17 00:00:00 2001 From: Krystian Duma Date: Thu, 18 Sep 2025 19:57:34 +0200 Subject: [PATCH 4/5] Implement fixed-size field padding in BinaryString Added support for fixed-size field padding in BinaryString methods. --- content/3.libraries/100.php/binary-tools.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/content/3.libraries/100.php/binary-tools.md b/content/3.libraries/100.php/binary-tools.md index 32613c7..b5d975b 100644 --- a/content/3.libraries/100.php/binary-tools.md +++ b/content/3.libraries/100.php/binary-tools.md @@ -39,6 +39,7 @@ composer require kduma/binary-tools - **Flexible integer support** with configurable byte order and signedness - **Position tracking** for streaming operations - **Terminator support** for null-terminated and delimited data parsing +- **Fixed-size field padding** with configurable pad byte support ## Core Classes @@ -124,6 +125,10 @@ $writer->writeBytesWith(BinaryString::fromHex("abcd"), length: IntType::UINT16_L $writer->writeStringWith($text, terminator: Terminator::NUL); // Null-terminated string $writer->writeBytesWith($data, terminator: BinaryString::fromString("\r\n")); // Custom terminator +// Write fixed-size fields with padding +$writer->writeBytesWith(BinaryString::fromString('OK'), padding: BinaryString::fromString("\x20"), padding_size: 4); +$writer->writeStringWith(BinaryString::fromString('ID'), padding_size: 4); // Defaults to NUL padding + // Get the result $result = $writer->getBuffer(); echo $result->toHex(); // Complete binary data as hex @@ -156,6 +161,10 @@ $bytesWithLength = $reader->readBytesWith(length: IntType::UINT16_LE); // Littl $nullTermString = $reader->readStringWith(terminator: Terminator::NUL); // Terminator required $lineData = $reader->readBytesWith(optional_terminator: BinaryString::fromString("\r\n")); // Terminator optional +// Read padded fields (total size includes padding) +$status = $reader->readBytesWith(padding: BinaryString::fromString("\x20"), padding_size: 4); +$identifier = $reader->readStringWith(padding_size: 4); // Defaults to NUL padding + // Position management echo $reader->position; // Current position echo $reader->remaining_bytes; // Bytes left @@ -180,6 +189,8 @@ $reader->skip(5); // Skip 5 bytes > - Use `readStringWith(optional_terminator: Terminator|BinaryString)` to read until terminator or end of data > - Use `readBytesWith(terminator: Terminator|BinaryString)` when the terminator **must** be present > - Use `readBytesWith(optional_terminator: Terminator|BinaryString)` to read until terminator or end of data +> - Use `readBytesWith(padding_size: int, padding: Terminator|BinaryString)` for fixed-size padded fields (pad byte must be single byte and absent from data) +> - Terminator arguments must be non-empty in both modes > - Call `toString()` on BinaryString objects to get actual string values ## Terminator Support @@ -357,8 +368,8 @@ for ($i = 0; $i < $userCount; $i++) { | `writeBytes(BinaryString $bytes): self` | Write binary data | | `writeInt(IntType $type, int $value): self` | Write integer with specified type | | `writeString(BinaryString $string): self` | Write UTF-8 string | -| `writeBytesWith(BinaryString $bytes, ?IntType $length = null, Terminator\|BinaryString\|null $terminator = null): self` | Write bytes with length prefix or terminator | -| `writeStringWith(BinaryString $string, ?IntType $length = null, Terminator\|BinaryString\|null $terminator = null): self` | Write string with length prefix or terminator | +| `writeBytesWith(BinaryString $bytes, ?IntType $length = null, Terminator\|BinaryString\|null $terminator = null, Terminator\|BinaryString\|null $padding = null, ?int $padding_size = null): self` | Write bytes with length prefix, terminator, or fixed padding | +| `writeStringWith(BinaryString $string, ?IntType $length = null, Terminator\|BinaryString\|null $terminator = null, Terminator\|BinaryString\|null $padding = null, ?int $padding_size = null): self` | Write string with length prefix, terminator, or fixed padding | ### BinaryReader @@ -374,8 +385,8 @@ for ($i = 0; $i < $userCount; $i++) { | `readBytes(int $count): BinaryString` | Read N bytes | | `readInt(IntType $type): int` | Read integer with specified type | | `readString(int $length): BinaryString` | Read UTF-8 string of specific length | -| `readBytesWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null, Terminator\|BinaryString\|null $optional_terminator = null): BinaryString` | Read bytes with length prefix, required terminator, or optional terminator | -| `readStringWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null, Terminator\|BinaryString\|null $optional_terminator = null): BinaryString` | Read string with length prefix, required terminator, or optional terminator | +| `readBytesWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null, Terminator\|BinaryString\|null $optional_terminator = null, Terminator\|BinaryString\|null $padding = null, ?int $padding_size = null): BinaryString` | Read bytes with length prefix, terminator, or fixed padding | +| `readStringWith(?IntType $length = null, Terminator\|BinaryString\|null $terminator = null, Terminator\|BinaryString\|null $optional_terminator = null, Terminator\|BinaryString\|null $padding = null, ?int $padding_size = null): BinaryString` | Read string with length prefix, terminator, or fixed padding | | `peekByte(): int` | Peek next byte without advancing | | `peekBytes(int $count): BinaryString` | Peek N bytes without advancing | | `seek(int $position): void` | Seek to position | From f724507203ca8ab35ce0687f24fb1cc9e604b8ce Mon Sep 17 00:00:00 2001 From: Krystian Duma Date: Thu, 18 Sep 2025 21:13:15 +0200 Subject: [PATCH 5/5] Add API reference for Binary Tools in PHP Added API reference documentation for Binary Tools in PHP, including BinaryString, BinaryWriter, and BinaryReader classes with detailed method descriptions and usage examples. --- content/3.libraries/100.php/binary-tools.md | 871 ++++++++++++++++++++ 1 file changed, 871 insertions(+) diff --git a/content/3.libraries/100.php/binary-tools.md b/content/3.libraries/100.php/binary-tools.md index b5d975b..1e5d184 100644 --- a/content/3.libraries/100.php/binary-tools.md +++ b/content/3.libraries/100.php/binary-tools.md @@ -495,3 +495,874 @@ try { echo "Error: " . $e->getMessage(); } ``` + +## Binary Tools for PHP - API Reference + +This documentation is auto-generated from the source code. + +### Table of Contents + +* [`\KDuma\BinaryTools\BinaryString`](#BinaryString) + * [`BinaryString::$value`](#BinaryStringvalue) + * [`BinaryString::toString()`](#BinaryStringtoString) + * [`BinaryString::toHex()`](#BinaryStringtoHex) + * [`BinaryString::toBase64()`](#BinaryStringtoBase64) + * [`BinaryString::toBase32(...)`](#BinaryStringtoBase32) + * [`BinaryString::size()`](#BinaryStringsize) + * [`BinaryString::fromString(...)`](#BinaryStringfromString) + * [`BinaryString::fromHex(...)`](#BinaryStringfromHex) + * [`BinaryString::fromBase64(...)`](#BinaryStringfromBase64) + * [`BinaryString::fromBase32(...)`](#BinaryStringfromBase32) + * [`BinaryString::equals(...)`](#BinaryStringequals) + * [`BinaryString::contains(...)`](#BinaryStringcontains) +* [`\KDuma\BinaryTools\BinaryWriter`](#BinaryWriter) + * [`BinaryWriter::getBuffer()`](#BinaryWritergetBuffer) + * [`BinaryWriter::getLength()`](#BinaryWritergetLength) + * [`BinaryWriter::reset()`](#BinaryWriterreset) + * [`BinaryWriter::writeByte(...)`](#BinaryWriterwriteByte) + * [`BinaryWriter::writeBytes(...)`](#BinaryWriterwriteBytes) + * [`BinaryWriter::writeBytesWith(...)`](#BinaryWriterwriteBytesWith) + * [`BinaryWriter::writeInt(...)`](#BinaryWriterwriteInt) + * [`BinaryWriter::writeString(...)`](#BinaryWriterwriteString) + * [`BinaryWriter::writeStringWith(...)`](#BinaryWriterwriteStringWith) + * [`BinaryWriter::writeUint16BE(...)`](#BinaryWriterwriteUint16BE) + * [`BinaryWriter::writeBytesWithLength(...)`](#BinaryWriterwriteBytesWithLength) + * [`BinaryWriter::writeStringWithLength(...)`](#BinaryWriterwriteStringWithLength) +* [`\KDuma\BinaryTools\BinaryReader`](#BinaryReader) + * [`BinaryReader::$length`](#BinaryReaderlength) + * [`BinaryReader::$data`](#BinaryReaderdata) + * [`BinaryReader::$position`](#BinaryReaderposition) + * [`BinaryReader::$remaining_bytes`](#BinaryReaderremaining_bytes) + * [`BinaryReader::$has_more_data`](#BinaryReaderhas_more_data) + * [`BinaryReader::$remaining_data`](#BinaryReaderremaining_data) + * [`BinaryReader::readByte()`](#BinaryReaderreadByte) + * [`BinaryReader::readBytes(...)`](#BinaryReaderreadBytes) + * [`BinaryReader::readBytesWith(...)`](#BinaryReaderreadBytesWith) + * [`BinaryReader::readInt(...)`](#BinaryReaderreadInt) + * [`BinaryReader::readString(...)`](#BinaryReaderreadString) + * [`BinaryReader::readStringWith(...)`](#BinaryReaderreadStringWith) + * [`BinaryReader::peekByte()`](#BinaryReaderpeekByte) + * [`BinaryReader::peekBytes(...)`](#BinaryReaderpeekBytes) + * [`BinaryReader::skip(...)`](#BinaryReaderskip) + * [`BinaryReader::seek(...)`](#BinaryReaderseek) + * [`BinaryReader::readUint16BE()`](#BinaryReaderreadUint16BE) + * [`BinaryReader::readBytesWithLength(...)`](#BinaryReaderreadBytesWithLength) + * [`BinaryReader::readStringWithLength(...)`](#BinaryReaderreadStringWithLength) +* [Enums](#enums) + * [`\KDuma\BinaryTools\IntType`](#IntType) + * [`\KDuma\BinaryTools\Terminator`](#Terminator) + +### BinaryString + +**Namespace:** `KDuma\BinaryTools` + +**Type:** Final Class + +#### Properties + +#### `$value` + +```php +string $value +``` + +-------------------- + +#### Methods + +##### toString() + +```php +\KDuma\BinaryTools\BinaryString::toString(): string +``` + +Returns the raw binary value as a PHP string. + +**Returns:** string + +-------------------- + +##### toHex() + +```php +\KDuma\BinaryTools\BinaryString::toHex(): string +``` + +Serialises the binary value into an ASCII hexadecimal string. + +**Returns:** string + +-------------------- + +##### toBase64() + +```php +\KDuma\BinaryTools\BinaryString::toBase64(): string +``` + +Serialises the binary value using Base64 encoding. + +**Returns:** string + +-------------------- + +##### toBase32(...) + +```php +\KDuma\BinaryTools\BinaryString::toBase32( + string $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" +): string +``` + +Returns a Base32-encoded string representation of the binary value. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`alphabet`** | string (optional) | Alphabet to use when encoding. | + +**Returns:** string + +-------------------- + +##### size() + +```php +\KDuma\BinaryTools\BinaryString::size(): int +``` + +Returns the number of bytes contained in the value. + +**Returns:** int + +-------------------- + +##### fromString(...) + +```php +\KDuma\BinaryTools\BinaryString::fromString( + string $value +): static +``` + +Creates a BinaryString from an existing PHP string without validation. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`value`** | string | Raw binary data. | + +**Returns:** static + +-------------------- + +##### fromHex(...) + +```php +\KDuma\BinaryTools\BinaryString::fromHex( + string $hex +): static +``` + +Creates a BinaryString from a hexadecimal dump. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`hex`** | string | Hexadecimal representation of the data. | + +**Returns:** static + +-------------------- + +##### fromBase64(...) + +```php +\KDuma\BinaryTools\BinaryString::fromBase64( + string $base64 +): static +``` + +Creates a BinaryString from a Base64-encoded payload. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`base64`** | string | Base64 representation of the data. | + +**Returns:** static + +-------------------- + +##### fromBase32(...) + +```php +\KDuma\BinaryTools\BinaryString::fromBase32( + string $base32, + string $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" +): static +``` + +Decodes a Base32-encoded string to a BinaryString instance using the specified alphabet. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`base32`** | string | Base32 payload to decode. | +| **`alphabet`** | string (optional) | Alphabet that was used during encoding. | + +**Returns:** static + +-------------------- + +##### equals(...) + +```php +\KDuma\BinaryTools\BinaryString::equals( + \KDuma\BinaryTools\BinaryString $other +): bool +``` + +Performs a timing-safe comparison with another BinaryString. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`other`** | \KDuma\BinaryTools\BinaryString | Value to compare against. | + +**Returns:** bool + +-------------------- + +##### contains(...) + +```php +\KDuma\BinaryTools\BinaryString::contains( + \KDuma\BinaryTools\BinaryString $needle +): bool +``` + +Determines whether the provided binary fragment appears in the value. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`needle`** | \KDuma\BinaryTools\BinaryString | Fragment to look for. | + +**Returns:** bool + +-------------------- + +--- + +### BinaryWriter + +**Namespace:** `KDuma\BinaryTools` + +**Type:** Final Class + +#### Methods + +##### getBuffer() + +```php +\KDuma\BinaryTools\BinaryWriter::getBuffer(): \KDuma\BinaryTools\BinaryString +``` + +Returns the buffered bytes as a BinaryString without resetting the writer. + +**Returns:** \KDuma\BinaryTools\BinaryString + +-------------------- + +##### getLength() + +```php +\KDuma\BinaryTools\BinaryWriter::getLength(): int +``` + +Returns the number of bytes written so far. + +**Returns:** int + +-------------------- + +##### reset() + +```php +\KDuma\BinaryTools\BinaryWriter::reset(): void +``` + +Clears the buffer so subsequent writes start from an empty state. + +**Returns:** void + +-------------------- + +##### writeByte(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeByte( + int $byte +): self +``` + +Appends a single byte value (0-255) to the buffer. + +**Throws:** \InvalidArgumentException When the value is outside the valid byte range. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`byte`** | int | Byte value to write. | + +**Returns:** self + +-------------------- + +##### writeBytes(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeBytes( + \KDuma\BinaryTools\BinaryString $bytes +): self +``` + +Appends raw bytes to the buffer. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`bytes`** | \KDuma\BinaryTools\BinaryString | Data to append. | + +**Returns:** self + +-------------------- + +##### writeBytesWith(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeBytesWith( + \KDuma\BinaryTools\BinaryString $bytes, + ?\KDuma\BinaryTools\IntType $length = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $terminator = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $optional_terminator = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $padding = null, + ?int $padding_size = null +): self +``` + +Writes variable-length data using one of the available strategies: typed length, terminator or fixed padding. + +**Throws:** \InvalidArgumentException When configuration is invalid or the data violates the chosen mode. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`bytes`** | \KDuma\BinaryTools\BinaryString | Data to write. | +| **`length`** | \?KDuma\BinaryTools\IntType (optional) | Integer type describing the length field when using length mode. | +| **`terminator`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Mandatory terminator sequence. | +| **`optional_terminator`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Optional terminator sequence (currently emits a notice and behaves like $terminator). | +| **`padding`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Single-byte padding value for fixed-width fields. | +| **`padding_size`** | ?int (optional) | Total field width when padding is enabled. | + +**Returns:** self + +-------------------- + +##### writeInt(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeInt( + \KDuma\BinaryTools\IntType $type, + int $value +): self +``` + +Serialises an integer according to the provided {@see IntType} definition. + +**Throws:** \RuntimeException When the type is unsupported on this platform. + +**Throws:** \InvalidArgumentException When the value lies outside the type's range. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`type`** | \KDuma\BinaryTools\IntType | Integer description covering width, signedness, and byte order. | +| **`value`** | int | Value to serialise. | + +**Returns:** self + +-------------------- + +##### writeString(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeString( + \KDuma\BinaryTools\BinaryString $string +): self +``` + +Writes a UTF-8 validated string without terminator or padding. + +**Throws:** \InvalidArgumentException When the data is not valid UTF-8. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`string`** | \KDuma\BinaryTools\BinaryString | UTF-8 string data to emit. | + +**Returns:** self + +-------------------- + +##### writeStringWith(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeStringWith( + \KDuma\BinaryTools\BinaryString $string, + ?\KDuma\BinaryTools\IntType $length = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $terminator = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $optional_terminator = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $padding = null, + ?int $padding_size = null +): self +``` + +Writes a UTF-8 string using one of the variable-length strategies. + +**Throws:** \InvalidArgumentException When configuration is invalid or the string is not UTF-8. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`string`** | \KDuma\BinaryTools\BinaryString | UTF-8 string data to emit. | +| **`length`** | \?KDuma\BinaryTools\IntType (optional) | Integer type describing the length field when using length mode. | +| **`terminator`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Mandatory terminator sequence. | +| **`optional_terminator`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Optional terminator sequence (currently emits a notice and behaves like $terminator). | +| **`padding`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Single-byte padding value for fixed-width fields. | +| **`padding_size`** | ?int (optional) | Total field width when padding is enabled. | + +**Returns:** self + +-------------------- + +##### writeUint16BE(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeUint16BE( + int $value +): self +``` + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`value`** | int | Unsigned 16-bit value. | + +**Returns:** self + +-------------------- + +##### writeBytesWithLength(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeBytesWithLength( + \KDuma\BinaryTools\BinaryString $bytes, + bool $use16BitLength = false +): self +``` + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`bytes`** | \KDuma\BinaryTools\BinaryString | Payload to write. | +| **`use16BitLength`** | bool (optional) | When true, emits a 16-bit length; otherwise an 8-bit length. | + +**Returns:** self + +-------------------- + +##### writeStringWithLength(...) + +```php +\KDuma\BinaryTools\BinaryWriter::writeStringWithLength( + \KDuma\BinaryTools\BinaryString $string, + bool $use16BitLength = false +): self +``` + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`string`** | \KDuma\BinaryTools\BinaryString | UTF-8 string to write. | +| **`use16BitLength`** | bool (optional) | When true, emits a 16-bit length; otherwise an 8-bit length. | + +**Returns:** self + +-------------------- + +--- + +### BinaryReader + +**Namespace:** `KDuma\BinaryTools` + +**Type:** Final Class + +#### Properties + +#### `$length` + +```php +int $length +``` + +-------------------- + +#### `$data` + +```php +KDuma\BinaryTools\BinaryString $data +``` + +-------------------- + +#### `$position` + +```php +int $position +``` + +-------------------- + +#### `$remaining_bytes` + +```php +int $remaining_bytes +``` + +-------------------- + +#### `$has_more_data` + +```php +bool $has_more_data +``` + +-------------------- + +#### `$remaining_data` + +```php +KDuma\BinaryTools\BinaryString $remaining_data +``` + +-------------------- + +#### Methods + +##### readByte() + +```php +\KDuma\BinaryTools\BinaryReader::readByte(): int +``` + +Reads the next byte from the stream. + +**Throws:** RuntimeException When no more data is available. + +**Returns:** int + +-------------------- + +##### readBytes(...) + +```php +\KDuma\BinaryTools\BinaryReader::readBytes( + int $count +): \KDuma\BinaryTools\BinaryString +``` + +Reads exactly $count bytes from the current position. + +**Throws:** RuntimeException When fewer than $count bytes remain. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`count`** | int | Number of bytes to read. | + +**Returns:** \KDuma\BinaryTools\BinaryString + +-------------------- + +##### readBytesWith(...) + +```php +\KDuma\BinaryTools\BinaryReader::readBytesWith( + ?\KDuma\BinaryTools\IntType $length = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $terminator = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $optional_terminator = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $padding = null, + ?int $padding_size = null +): \KDuma\BinaryTools\BinaryString +``` + +Reads variable-length data using exactly one of the supplied strategies (length, terminator, optional terminator, or padding). + +**Throws:** \InvalidArgumentException When mutually exclusive modes are combined or configuration is invalid. + +**Throws:** RuntimeException When the data violates the expectations of the chosen mode. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`length`** | \?KDuma\BinaryTools\IntType (optional) | Integer type that stores the byte length when using length mode. | +| **`terminator`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Required terminator sequence when using terminator mode. | +| **`optional_terminator`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Terminator sequence that may be absent (fully consumes buffer when missing). | +| **`padding`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Single-byte padding value used for fixed-width fields. | +| **`padding_size`** | ?int (optional) | Total field width in bytes when padding is enabled. | + +**Returns:** \KDuma\BinaryTools\BinaryString + +-------------------- + +##### readInt(...) + +```php +\KDuma\BinaryTools\BinaryReader::readInt( + \KDuma\BinaryTools\IntType $type +): int +``` + +Reads an integer using the provided {@see IntType} definition. + +**Throws:** RuntimeException When the type is unsupported or the value cannot be represented. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`type`** | \KDuma\BinaryTools\IntType | Integer description covering width, signedness, and byte order. | + +**Returns:** int + +-------------------- + +##### readString(...) + +```php +\KDuma\BinaryTools\BinaryReader::readString( + int $length +): \KDuma\BinaryTools\BinaryString +``` + +Reads a fixed-length UTF-8 string. + +**Throws:** RuntimeException When insufficient data remains or decoding fails. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`length`** | int | Number of bytes to consume. | + +**Returns:** \KDuma\BinaryTools\BinaryString + +-------------------- + +##### readStringWith(...) + +```php +\KDuma\BinaryTools\BinaryReader::readStringWith( + ?\KDuma\BinaryTools\IntType $length = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $terminator = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $optional_terminator = null, + \KDuma\BinaryTools\Terminator|\KDuma\BinaryTools\BinaryString|null $padding = null, + ?int $padding_size = null +): \KDuma\BinaryTools\BinaryString +``` + +Reads a UTF-8 string using one of the variable-length strategies (length, terminator, optional terminator, or padding). + +**Throws:** \InvalidArgumentException When configuration is invalid. + +**Throws:** RuntimeException When decoding fails or the data violates mode rules. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`length`** | \?KDuma\BinaryTools\IntType (optional) | Integer type specifying the length field when using length mode. | +| **`terminator`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Required terminator. | +| **`optional_terminator`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Optional terminator. | +| **`padding`** | \KDuma\BinaryTools\Terminator\|KDuma\BinaryTools\BinaryString\|null (optional) | Single-byte padding value for fixed-width fields. | +| **`padding_size`** | ?int (optional) | Total field width when padding is enabled. | + +**Returns:** \KDuma\BinaryTools\BinaryString + +-------------------- + +##### peekByte() + +```php +\KDuma\BinaryTools\BinaryReader::peekByte(): int +``` + +Returns the next byte without advancing the read pointer. + +**Throws:** RuntimeException When no more data remains. + +**Returns:** int - int Unsigned byte value. + +-------------------- + +##### peekBytes(...) + +```php +\KDuma\BinaryTools\BinaryReader::peekBytes( + int $count +): \KDuma\BinaryTools\BinaryString +``` + +Returns the next $count bytes without advancing the read pointer. + +**Throws:** RuntimeException When fewer than $count bytes remain. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`count`** | int | Number of bytes to inspect. | + +**Returns:** \KDuma\BinaryTools\BinaryString + +-------------------- + +##### skip(...) + +```php +\KDuma\BinaryTools\BinaryReader::skip( + int $count +): void +``` + +Advances the read pointer by $count bytes. + +**Throws:** RuntimeException When insufficient data remains. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`count`** | int | Number of bytes to skip. | + +**Returns:** void + +-------------------- + +##### seek(...) + +```php +\KDuma\BinaryTools\BinaryReader::seek( + int $position +): void +``` + +Moves the read pointer to an absolute offset inside the buffer. + +**Throws:** RuntimeException When the target lies outside the buffer. + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`position`** | int | Zero-based offset to seek to. | + +**Returns:** void + +-------------------- + +##### readUint16BE() + +```php +\KDuma\BinaryTools\BinaryReader::readUint16BE(): int +``` + +**Returns:** int + +-------------------- + +##### readBytesWithLength(...) + +```php +\KDuma\BinaryTools\BinaryReader::readBytesWithLength( + bool $use16BitLength = false +): \KDuma\BinaryTools\BinaryString +``` + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`use16BitLength`** | bool (optional) | When true, reads a 16-bit length; otherwise an 8-bit length. | + +**Returns:** \KDuma\BinaryTools\BinaryString + +-------------------- + +##### readStringWithLength(...) + +```php +\KDuma\BinaryTools\BinaryReader::readStringWithLength( + bool $use16BitLength = false +): \KDuma\BinaryTools\BinaryString +``` + +| Param | Type | Description | +| ----- | ---- | ----------- | +| **`use16BitLength`** | bool (optional) | When true, reads a 16-bit length; otherwise an 8-bit length. | + +**Returns:** \KDuma\BinaryTools\BinaryString + +-------------------- + +--- + +### Enums + +#### IntType + +**Namespace:** `\KDuma\BinaryTools\IntType` + +| Members | Value | Description | +| ------- | ----- | ----------- | +| **`UINT8`** | 'UINT8' | Unsigned 8-bit integer (0-255) - Single byte | +| **`INT8`** | 'INT8' | Signed 8-bit integer (-128 to 127) - Single byte | +| **`UINT16`** | 'UINT16' | Unsigned 16-bit integer (0-65535) - Big-endian byte order | +| **`INT16`** | 'INT16' | Signed 16-bit integer (-32768 to 32767) - Big-endian byte order | +| **`UINT32`** | 'UINT32' | Unsigned 32-bit integer (0-4294967295) - Big-endian byte order | +| **`INT32`** | 'INT32' | Signed 32-bit integer (-2147483648 to 2147483647) - Big-endian byte order | +| **`UINT16_LE`** | 'UINT16_LE' | Unsigned 16-bit integer (0-65535) - Little-endian byte order | +| **`INT16_LE`** | 'INT16_LE' | Signed 16-bit integer (-32768 to 32767) - Little-endian byte order | +| **`UINT32_LE`** | 'UINT32_LE' | Unsigned 32-bit integer (0-4294967295) - Little-endian byte order | +| **`INT32_LE`** | 'INT32_LE' | Signed 32-bit integer (-2147483648 to 2147483647) - Little-endian byte order | +| **`UINT64`** | 'UINT64' | Unsigned 64-bit integer - Big-endian byte order (platform dependent range) | +| **`INT64`** | 'INT64' | Signed 64-bit integer - Big-endian byte order (platform dependent range) | +| **`UINT64_LE`** | 'UINT64_LE' | Unsigned 64-bit integer - Little-endian byte order (platform dependent range) | +| **`INT64_LE`** | 'INT64_LE' | Signed 64-bit integer - Little-endian byte order (platform dependent range) | + +-------------------- + +#### Terminator + +**Namespace:** `\KDuma\BinaryTools\Terminator` + +| Members | Value | Description | +| ------- | ----- | ----------- | +| **`NUL`** | 'NUL' | Null character (0x00) - Commonly used for C-style string termination | +| **`SOH`** | 'SOH' | Start of Heading (0x01) - Indicates the start of a header block | +| **`STX`** | 'STX' | Start of Text (0x02) - Marks the beginning of text data | +| **`ETX`** | 'ETX' | End of Text (0x03) - Marks the end of text data | +| **`EOT`** | 'EOT' | End of Transmission (0x04) - Indicates end of data transmission | +| **`ENQ`** | 'ENQ' | Enquiry (0x05) - Request for response or status | +| **`ACK`** | 'ACK' | Acknowledge (0x06) - Positive acknowledgment signal | +| **`BEL`** | 'BEL' | Bell (0x07) - Audio alert or notification signal | +| **`BS`** | 'BS' | Backspace (0x08) - Move cursor back one position | +| **`HT`** | 'HT' | Horizontal Tab (0x09) - Move to next tab stop | +| **`LF`** | 'LF' | Line Feed (0x0A) - Move to next line (Unix line ending) | +| **`VT`** | 'VT' | Vertical Tab (0x0B) - Move to next vertical tab position | +| **`FF`** | 'FF' | Form Feed (0x0C) - Start new page or clear screen | +| **`CR`** | 'CR' | Carriage Return (0x0D) - Return to start of line (classic Mac line ending) | +| **`SO`** | 'SO' | Shift Out (0x0E) - Switch to alternate character set | +| **`SI`** | 'SI' | Shift In (0x0F) - Switch back to standard character set | +| **`DLE`** | 'DLE' | Data Link Escape (0x10) - Escape sequence for data link protocols | +| **`DC1`** | 'DC1' | Device Control 1 (0x11) - Also known as XON for flow control | +| **`DC2`** | 'DC2' | Device Control 2 (0x12) - General device control | +| **`DC3`** | 'DC3' | Device Control 3 (0x13) - Also known as XOFF for flow control | +| **`DC4`** | 'DC4' | Device Control 4 (0x14) - General device control | +| **`NAK`** | 'NAK' | Negative Acknowledge (0x15) - Error or rejection signal | +| **`SYN`** | 'SYN' | Synchronous Idle (0x16) - Synchronization in data streams | +| **`ETB`** | 'ETB' | End of Transmission Block (0x17) - End of data block marker | +| **`CAN`** | 'CAN' | Cancel (0x18) - Cancel current operation | +| **`EM`** | 'EM' | End of Medium (0x19) - End of storage medium | +| **`SUB`** | 'SUB' | Substitute (0x1A) - Replacement for invalid character | +| **`ESC`** | 'ESC' | Escape (0x1B) - Start of escape sequence | +| **`FS`** | 'FS' | File Separator (0x1C) - Delimiter between files | +| **`GS`** | 'GS' | Group Separator (0x1D) - Delimiter between groups of data | +| **`RS`** | 'RS' | Record Separator (0x1E) - Delimiter between records | +| **`US`** | 'US' | Unit Separator (0x1F) - Delimiter between units of data | +| **`SP`** | 'SP' | Space (0x20) - Standard whitespace character | +| **`CRLF`** | 'CRLF' | Carriage Return + Line Feed (0x0D 0x0A) - Windows line ending | + +-------------------- +