Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/main/php/io/streams/StreamTransfer.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -71,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));
}
}

Expand Down
20 changes: 18 additions & 2 deletions src/test/php/io/unittest/StreamTransferTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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]
Expand All @@ -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');
Expand Down