Skip to content

Commit 596e976

Browse files
committed
Add new $flush parameter to control flush mode for Compressor
1 parent 19a400f commit 596e976

File tree

3 files changed

+59
-7
lines changed

3 files changed

+59
-7
lines changed

src/Compressor.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@ final class Compressor extends TransformStream
3434
/** @var ?resource */
3535
private $context;
3636

37+
/** @var int */
38+
private $flush;
39+
3740
/**
3841
* @param int $encoding ZLIB_ENCODING_GZIP, ZLIB_ENCODING_RAW or ZLIB_ENCODING_DEFLATE
3942
* @param int $level optional compression level
43+
* @param int $flush optional flush mode (ZLIB_NO_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_FINISH)
4044
*/
41-
public function __construct($encoding, $level = -1)
45+
public function __construct($encoding, $level = -1, int $flush = ZLIB_NO_FLUSH)
4246
{
4347
$errstr = '';
4448
set_error_handler(function ($_, $error) use (&$errstr) {
@@ -61,12 +65,17 @@ public function __construct($encoding, $level = -1)
6165
throw new \InvalidArgumentException('Unable to initialize compressor' . $errstr); // @codeCoverageIgnore
6266
}
6367

68+
if (!in_array($flush, [ZLIB_NO_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_FINISH], true)) {
69+
throw new \InvalidArgumentException('Argument #3 ($flush) must be one of ZLIB_NO_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH or ZLIB_FINISH');
70+
}
71+
6472
$this->context = $context;
73+
$this->flush = $flush;
6574
}
6675

6776
protected function transformData($chunk)
6877
{
69-
$ret = deflate_add($this->context, $chunk, ZLIB_NO_FLUSH);
78+
$ret = deflate_add($this->context, $chunk, $this->flush);
7079

7180
if ($ret !== '') {
7281
$this->emit('data', [$ret]);

tests/CompressorTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,10 @@ public function testCtorThrowsForInvalidEncodingAndUnsetsUsedErrorHandler()
3030

3131
$this->assertEquals($handler, $checkHandler);
3232
}
33+
34+
public function testCtorThrowsForInvalidFlushMode()
35+
{
36+
$this->expectException(\InvalidArgumentException::class);
37+
new Compressor(ZLIB_ENCODING_GZIP, -1, -1);
38+
}
3339
}

tests/GzipCompressorTest.php

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ public function setUpCompressor()
1818

1919
public function testCompressEmpty()
2020
{
21-
if (DIRECTORY_SEPARATOR === '\\') {
22-
$this->markTestSkipped('Not supported on Windows');
23-
}
24-
25-
$os = DIRECTORY_SEPARATOR === '\\' ? "\x0a" : "\x03"; // NTFS(0x0a) or UNIX (0x03)
21+
$os = DIRECTORY_SEPARATOR === '\\' ? "\x0b" : "\x03"; // NTFS(0x0b) or UNIX (0x03)
2622
$this->compressor->on('data', $this->expectCallableOnceWith("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00" . $os . "\x03\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00"));
2723
$this->compressor->on('end', $this->expectCallableOnce());
2824

@@ -58,4 +54,45 @@ public function testCompressBig()
5854
// PHP < 5.4 does not support gzdecode(), so let's assert this the other way around…
5955
$this->assertEquals(gzencode($data), $buffered);
6056
}
57+
58+
public function testWriteWillOnlyFlushHeaderByDefaultToBufferDataBeforeFlushing()
59+
{
60+
$compressor = new Compressor(ZLIB_ENCODING_GZIP);
61+
62+
$os = DIRECTORY_SEPARATOR === '\\' ? "\x0b" : "\x03"; // NTFS(0x0b) or UNIX (0x03)
63+
$compressor->on('data', $this->expectCallableOnceWith("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00" . $os));
64+
65+
$compressor->write('hello');
66+
}
67+
68+
public function testWriteWithSyncFlushWillFlushHeaderWithFirstChunkImmediately()
69+
{
70+
$compressor = new Compressor(ZLIB_ENCODING_GZIP, -1, ZLIB_SYNC_FLUSH);
71+
72+
$os = DIRECTORY_SEPARATOR === '\\' ? "\x0b" : "\x03"; // NTFS(0x0b) or UNIX (0x03)
73+
$compressor->on('data', $this->expectCallableOnceWith("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00" . $os . "\xca\x48\xcd\xc9\xc9\x07\x00\x00\x00\xff\xff"));
74+
75+
$compressor->write('hello');
76+
}
77+
78+
public function testWriteWithFinishFlushWillFlushEntireGzipHeaderAndFooterWithFirstChunkImmediately()
79+
{
80+
$compressor = new Compressor(ZLIB_ENCODING_GZIP, -1, ZLIB_FINISH);
81+
82+
$os = DIRECTORY_SEPARATOR === '\\' ? "\x0b" : "\x03"; // NTFS(0x0b) or UNIX (0x03)
83+
$compressor->on('data', $this->expectCallableOnceWith("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00" . $os . "\xcb\x48\xcd\xc9\xc9\x07\x00\x86\xa6\x10\x36" . "\x05\x00\x00\x00"));
84+
85+
$compressor->write('hello');
86+
}
87+
88+
public function testWriteAfterFinishFlushWillFlushEntireGzipWithSyncFlushWillFlushEntireGzipHeaderAndFooterAgainImmediately()
89+
{
90+
$compressor = new Compressor(ZLIB_ENCODING_GZIP, -1, ZLIB_FINISH);
91+
$compressor->write('hello');
92+
93+
$os = DIRECTORY_SEPARATOR === '\\' ? "\x0b" : "\x03"; // NTFS(0x0b) or UNIX (0x03)
94+
$compressor->on('data', $this->expectCallableOnceWith("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00" . $os . "\xcb\x48\xcd\xc9\xc9\x07\x00\x86\xa6\x10\x36" . "\x05\x00\x00\x00"));
95+
96+
$compressor->write('hello');
97+
}
6198
}

0 commit comments

Comments
 (0)