Skip to content

Conversation

@thekid
Copy link
Member

@thekid thekid commented Apr 20, 2025

Implements #7

$ xp -w '\io\streams\Compression::algorithms()'
io.streams.compress.Algorithms@{
  io.streams.compress.Gzip(token: gzip, extension: .gz, supported: true, levels: 1..9)
  io.streams.compress.Bzip2(token: bzip2, extension: .bz2, supported: false, levels: 1..9)
  io.streams.compress.Brotli(token: br, extension: .br, supported: false, levels: 1..11)
  io.streams.compress.ZStandard(token: zstd, extension: .zstd, supported: true, levels: 1..22)
}

@thekid
Copy link
Member Author

thekid commented Apr 20, 2025

However, due to ext/zstd not supporting incremental (de)compression (see kjdev/php-ext-zstd#64), this will not be as efficient for large payloads - do we need a way to prioritize algorithms such as brotli in the accept() function?

Adressed with kjdev/php-ext-zstd#77 - let's see if the author accepts this PR, we could then refactor the implementation to make use of these new APIs.

@thekid thekid added the enhancement New feature or request label Apr 21, 2025
@thekid
Copy link
Member Author

thekid commented Jul 29, 2025

kjdev/php-ext-zstd#79 is merged, but not released yet. Updating the implementation to use the incremental API though.

@thekid
Copy link
Member Author

thekid commented Jul 31, 2025

Verified on Linux with extension compiled from scratch, and on Windows with extension created by tag in my fork, see https://github.com/thekid/php-ext-zstd/releases/tag/0.15.0

@thekid
Copy link
Member Author

thekid commented Aug 1, 2025

To make this compatible with both the zstd extension officially released as well as the upcoming one with incremental support, we could do the following:

diff --git a/src/main/php/io/streams/compress/ZStandard.class.php b/src/main/php/io/streams/compress/ZStandard.class.php
index 06cfe46..0cd7019 100755
--- a/src/main/php/io/streams/compress/ZStandard.class.php
+++ b/src/main/php/io/streams/compress/ZStandard.class.php
@@ -4,6 +4,17 @@ use io\IOException;
 use io\streams\{InputStream, OutputStream, Compression};
 
 class ZStandard extends Algorithm {
+  private static $in, $out;
+
+  static function __static() {
+    if (function_exists('zstd_uncompress_init')) {
+      self::$in= ZStandardInputStream::class;
+      self::$out= ZStandardOutputStream::class;
+    } else {
+      self::$in= BufferedZStandardInputStream::class;
+      self::$out= BufferedZStandardOutputStream::class;
+    }
+  }
 
   /** Returns whether this algorithm is supported in the current setup */
   public function supported(): bool { return extension_loaded('zstd'); }
@@ -40,11 +51,11 @@ class ZStandard extends Algorithm {
 
   /** Opens an input stream for reading */
   public function open(InputStream $in): InputStream {
-    return new ZStandardInputStream($in);
+    return new self::$in($in);
   }
 
   /** Opens an output stream for writing */
   public function create(OutputStream $out, int $level= Compression::DEFAULT): OutputStream {
-    return new ZStandardOutputStream($out, $this->level($level));
+    return new self::$out($out, $this->level($level));
   }
 }
\ No newline at end of file

However, this would bring us back to the question raised above: With the buffered implementations being less efficient, especially for bigger payloads, would we need a way to prioritize algorithms?

Or we just wait until the new release is available from https://github.com/kjdev/php-ext-zstd 🙂

@thekid
Copy link
Member Author

thekid commented Aug 15, 2025

Or we just wait until the new release is available from https://github.com/kjdev/php-ext-zstd 🙂

There it is: https://github.com/kjdev/php-ext-zstd/releases/tag/0.15.0

@thekid thekid merged commit 59ed903 into main Aug 15, 2025
14 checks passed
@thekid thekid deleted the feature/zstandard branch August 15, 2025 18:27
@thekid
Copy link
Member Author

thekid commented Aug 15, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants