From ae38f0c0803b788fd336384629d762ec1f7341cf Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sun, 15 Feb 2026 14:47:47 +0100 Subject: [PATCH 1/2] Make it possible to supply chunk size to transfer() & transmit() --- .../php/io/streams/StreamTransfer.class.php | 13 ++++++++---- .../io/unittest/StreamTransferTest.class.php | 20 +++++++++++++++++-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main/php/io/streams/StreamTransfer.class.php b/src/main/php/io/streams/StreamTransfer.class.php index b2b8d03b7..94952d361 100755 --- a/src/main/php/io/streams/StreamTransfer.class.php +++ b/src/main/php/io/streams/StreamTransfer.class.php @@ -41,21 +41,26 @@ public function __construct(InputStream $in, OutputStream $out) { public function transferAll() { $r= 0; while ($this->in->available()) { - $r+= $this->out->write($this->in->read()); + $chunk= $this->in->read(); + $this->out->write($chunk); + $r+= strlen($chunk); } return $r; } /** * Transmit all available input from in, yielding control after each chunk. + * Uses default chunk size of 8192 bytes. * + * @param int $size * @return iterable * @throws io.IOException */ - public function transmit() { + public function transmit($size= 8192) { while ($this->in->available()) { - $this->out->write($this->in->read()); - yield; + $chunk= $this->in->read($size); + $this->out->write($chunk); + yield strlen($chunk); } } diff --git a/src/test/php/io/unittest/StreamTransferTest.class.php b/src/test/php/io/unittest/StreamTransferTest.class.php index 9ad36754e..b97a1c065 100755 --- a/src/test/php/io/unittest/StreamTransferTest.class.php +++ b/src/test/php/io/unittest/StreamTransferTest.class.php @@ -2,7 +2,7 @@ use io\IOException; use io\streams\{InputStream, MemoryInputStream, MemoryOutputStream, OutputStream, StreamTransfer}; -use test\{Assert, Test}; +use test\{Assert, Test, Values}; class StreamTransferTest { @@ -49,9 +49,10 @@ public function transfer_all() { $out= new MemoryOutputStream(); $s= new StreamTransfer(new MemoryInputStream('Hello'), $out); - $s->transferAll(); + $size= $s->transferAll(); Assert::equals('Hello', $out->bytes()); + Assert::equals(5, $size); } #[Test] @@ -64,6 +65,21 @@ public function transmit() { Assert::equals('Hello', $out->bytes()); } + #[Test, Values([[0, []], [1, [1]], [1024, [1024]], [1025, [1024, 1]], [2077, [1024, 1024, 29]]])] + public function transmit_chunks($length, $chunks) { + $out= new MemoryOutputStream(); + $data= str_repeat('*', $length); + + $s= new StreamTransfer(new MemoryInputStream($data), $out); + $transmitted= []; + foreach ($s->transmit(1024) as $yield) { + $transmitted[]= $yield; + } + + Assert::equals($data, $out->bytes()); + Assert::equals($chunks, $transmitted); + } + #[Test] public function nothing_available_after_transfer() { $in= new MemoryInputStream('Hello'); From c80f18adb005fd6ccf6673b82fe5bc8617f89191 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sun, 15 Feb 2026 14:52:39 +0100 Subject: [PATCH 2/2] QA: Simplify code in close() --- src/main/php/io/streams/StreamTransfer.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/php/io/streams/StreamTransfer.class.php b/src/main/php/io/streams/StreamTransfer.class.php index 94952d361..6d5926265 100755 --- a/src/main/php/io/streams/StreamTransfer.class.php +++ b/src/main/php/io/streams/StreamTransfer.class.php @@ -76,15 +76,15 @@ public function close() { try { $this->in->close(); } catch (IOException $e) { - $errors.= 'Could not close input stream: '.$e->getMessage().', '; + $errors.= ', Could not close input stream: '.$e->getMessage(); } try { $this->out->close(); } catch (IOException $e) { - $errors.= 'Could not close output stream: '.$e->getMessage().', '; + $errors.= ', Could not close output stream: '.$e->getMessage(); } if ($errors) { - throw new IOException(rtrim($errors, ', ')); + throw new IOException(substr($errors, 2)); } }