aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/bakame/http-structured-fields/src/Bytes.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/bakame/http-structured-fields/src/Bytes.php')
-rw-r--r--vendor/bakame/http-structured-fields/src/Bytes.php83
1 files changed, 83 insertions, 0 deletions
diff --git a/vendor/bakame/http-structured-fields/src/Bytes.php b/vendor/bakame/http-structured-fields/src/Bytes.php
new file mode 100644
index 000000000..aa747b76b
--- /dev/null
+++ b/vendor/bakame/http-structured-fields/src/Bytes.php
@@ -0,0 +1,83 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Bakame\Http\StructuredFields;
+
+use Stringable;
+use Throwable;
+
+use function base64_decode;
+use function base64_encode;
+use function preg_match;
+
+/**
+ * @see https://www.rfc-editor.org/rfc/rfc9651.html#section-3.3.5
+ */
+final class Bytes
+{
+ private function __construct(private readonly string $value)
+ {
+ }
+
+ /**
+ * Returns a new instance from a Base64 encoded string.
+ */
+ public static function fromEncoded(Stringable|string $encoded): self
+ {
+ $encoded = (string) $encoded;
+ if (1 !== preg_match('/^[a-z\d+\/=]*$/i', $encoded)) {
+ throw new SyntaxError('The byte sequence '.$encoded.' contains invalid characters.');
+ }
+
+ $decoded = base64_decode($encoded, true);
+ if (false === $decoded) {
+ throw new SyntaxError('Unable to base64 decode the byte sequence '.$encoded);
+ }
+
+ return new self($decoded);
+ }
+
+ public static function tryFromEncoded(Stringable|string $encoded): ?self
+ {
+ try {
+ return self::fromEncoded($encoded);
+ } catch (Throwable) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns a new instance from a raw decoded string.
+ */
+ public static function fromDecoded(Stringable|string $decoded): self
+ {
+ return new self((string) $decoded);
+ }
+
+ /**
+ * Returns the decoded string.
+ */
+ public function decoded(): string
+ {
+ return $this->value;
+ }
+
+ /**
+ * Returns the base64 encoded string.
+ */
+ public function encoded(): string
+ {
+ return base64_encode($this->value);
+ }
+
+ public function equals(mixed $other): bool
+ {
+ return $other instanceof self && $other->value === $this->value;
+ }
+
+ public function type(): Type
+ {
+ return Type::Bytes;
+ }
+}