Skip to content

Commit 2dcc4fc

Browse files
committed
Add SIMD JSON decoding capabilities
1 parent 486fe3b commit 2dcc4fc

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

src/Decoder.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,19 @@ public function handleData($data)
112112
$data = (string)\substr($this->buffer, 0, $newline);
113113
$this->buffer = (string)\substr($this->buffer, $newline + 1);
114114

115+
// decode data with simdjson when the extension is available
116+
if (\extension_loaded('simdjson')) {
117+
try {
118+
$data = \simdjson_decode($data, $this->assoc, $this->depth);
119+
120+
$this->emit('data', array($data));
121+
} catch (\Throwable $err) {
122+
$this->handleError(new \RuntimeException('Unable to decode JSON: ' . $err->getMessage(), $err->getCode(), $err));
123+
}
124+
125+
continue;
126+
}
127+
115128
// decode data with options given in ctor
116129
// @codeCoverageIgnoreStart
117130
if ($this->options === 0) {

tests/DecoderTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ public function testEmitDataBigIntOptionWillForwardAsString()
6161
if (!defined('JSON_BIGINT_AS_STRING')) {
6262
$this->markTestSkipped('Const JSON_BIGINT_AS_STRING only available in PHP 5.4+');
6363
}
64+
65+
if (\extension_loaded('simdjson')) {
66+
$this->markTestSkipped('Flags cannot be passed to simdjson_decode');
67+
}
68+
6469
$this->decoder = new Decoder($this->input, false, 512, JSON_BIGINT_AS_STRING);
6570
$this->decoder->on('data', $this->expectCallableOnceWith($this->identicalTo('999888777666555444333222111000')));
6671

@@ -87,8 +92,8 @@ public function testEmitDataErrorWillForwardError()
8792
$this->input->emit('data', array("invalid\n"));
8893

8994
$this->assertInstanceOf('RuntimeException', $error);
90-
$this->assertContainsString('Syntax error', $error->getMessage());
91-
$this->assertEquals(JSON_ERROR_SYNTAX, $error->getCode());
95+
$this->assertMatchesRegularExpression('/(syntax error|improper structure)/i', $error->getMessage());
96+
$this->assertEquals(\extension_loaded('simdjson') ? SIMDJSON_ERR_TAPE_ERROR : JSON_ERROR_SYNTAX, $error->getCode());
9297
}
9398

9499
public function testEmitDataErrorWillForwardErrorAlsoWhenCreatedWithThrowOnError()

0 commit comments

Comments
 (0)