aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-07-13 14:10:40 +0900
committernsfisis <nsfisis@gmail.com>2024-07-13 14:10:40 +0900
commitf26f497131923886889deb4b843b179518888b1f (patch)
tree10ff8467135865d4aadb6bf4d3978dd1d011ed1a /src
parent1f4170811730477e9cd7d9620608c4ab619bdefc (diff)
downloadphp-waddiwasi-f26f497131923886889deb4b843b179518888b1f.tar.gz
php-waddiwasi-f26f497131923886889deb4b843b179518888b1f.tar.zst
php-waddiwasi-f26f497131923886889deb4b843b179518888b1f.zip
feat: add examples/hello-world
Diffstat (limited to 'src')
-rw-r--r--src/Stream/BlobStream.php95
-rw-r--r--src/Stream/StreamInterface.php8
2 files changed, 99 insertions, 4 deletions
diff --git a/src/Stream/BlobStream.php b/src/Stream/BlobStream.php
new file mode 100644
index 0000000..972b8f6
--- /dev/null
+++ b/src/Stream/BlobStream.php
@@ -0,0 +1,95 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Nsfisis\Waddiwasi\Stream;
+
+use function assert;
+use function ord;
+use function strlen;
+use function substr;
+
+/**
+ * Read-only blob stream.
+ */
+final class BlobStream implements StreamInterface
+{
+ /**
+ * @var int<0, max>
+ */
+ private int $pos = 0;
+
+ /**
+ * @var positive-int
+ */
+ private readonly int $len;
+
+ /**
+ * Creates a new blob stream with the given content.
+ *
+ * @param non-empty-string $content
+ * The content of the blob.
+ */
+ public function __construct(
+ private readonly string $content,
+ ) {
+ $this->len = strlen($content);
+ }
+
+ public function close(): void
+ {
+ }
+
+ public function read(int $bytes): string
+ {
+ $this->ensureNBytesAvailable($bytes);
+ $ret = substr($this->content, $this->pos, $bytes);
+ $this->pos += $bytes;
+ assert($ret !== '');
+ return $ret;
+ }
+
+ public function readByte(): int
+ {
+ $this->ensureNBytesAvailable(1);
+ return ord($this->content[$this->pos++]);
+ }
+
+ public function peekByte(): int
+ {
+ $this->ensureNBytesAvailable(1);
+ return ord($this->content[$this->pos]);
+ }
+
+ public function seek(int $bytes): void
+ {
+ $this->ensureNBytesAvailable($bytes);
+ $this->pos += $bytes;
+ }
+
+ /**
+ * @phpstan-pure
+ */
+ public function tell(): int
+ {
+ return $this->pos;
+ }
+
+ /**
+ * @phpstan-pure
+ */
+ public function eof(): bool
+ {
+ return $this->len <= $this->pos;
+ }
+
+ /**
+ * @param positive-int $bytes
+ */
+ private function ensureNBytesAvailable(int $bytes): void
+ {
+ if ($this->len < $this->pos + $bytes) {
+ throw new UnexpectedEofException(sprintf("Unexpected EOF while reading from blob (%d bytes expected, %d bytes read)", $bytes, $this->len - $this->pos));
+ }
+ }
+}
diff --git a/src/Stream/StreamInterface.php b/src/Stream/StreamInterface.php
index 0655d22..723c38b 100644
--- a/src/Stream/StreamInterface.php
+++ b/src/Stream/StreamInterface.php
@@ -15,7 +15,7 @@ interface StreamInterface
* A binary string of $bytes bytes.
*
* @throws UnexpectedEofException
- * Thrown if the stream does not have enough bytes to read.
+ * If the stream does not have enough bytes to read.
*
* @phpstan-impure
*/
@@ -28,7 +28,7 @@ interface StreamInterface
* An 8-bit unsigned integer read from the stream.
*
* @throws UnexpectedEofException
- * Thrown if the stream have reached the end.
+ * If the stream have reached the end.
*
* @phpstan-impure
*/
@@ -41,7 +41,7 @@ interface StreamInterface
* An 8-bit unsigned integer read from the stream.
*
* @throws UnexpectedEofException
- * Thrown if the stream have reached the end.
+ * If the stream have reached the end.
*
* @phpstan-impure
*/
@@ -53,7 +53,7 @@ interface StreamInterface
* @param positive-int $bytes
*
* @throws UnexpectedEofException
- * Thrown if the stream does not have enough bytes to seek.
+ * If the stream does not have enough bytes to seek.
*
* @phpstan-impure
*/