From f3465dd4a141486d20371a25375f48b3121a50e0 Mon Sep 17 00:00:00 2001 From: Jitendra Adhikari Date: Thu, 21 Jun 2018 07:25:53 +0700 Subject: [PATCH 1/3] refactor: split logic for mundane checks out from main loop --- src/Comment.php | 65 +++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/src/Comment.php b/src/Comment.php index 97d1200..1a7be49 100644 --- a/src/Comment.php +++ b/src/Comment.php @@ -9,6 +9,12 @@ */ class Comment { + /** @var bool If current char is within a string */ + protected $inStr = false; + + /** @var int Lines of comments 0 = no comment, 1 = single line, 2 = multi lines */ + protected $comment = 0; + /** * Strip comments from JSON string. * @@ -22,40 +28,20 @@ public function strip($json) return $json; } - $index = -1; - $inStr = false; - $return = ''; - $char = ''; - $comment = 'none'; + list($index, $return, $char) = [-1, '', '']; while (isset($json[++$index])) { - list($prev, $char) = [$char, $json[$index]]; - - if ('none' === $comment && $char === '"' && $prev !== '\\') { - $inStr = !$inStr; - } - - $charnext = $char . (isset($json[$index + 1]) ? $json[$index + 1] : ''); + list($prev, $char, $charnext) = [$char, $json[$index], $json[$index] . ($json[$index + 1] ?? '')]; - if (!$inStr && 'none' === $comment) { - $comment = $charnext === '//' ? 'single' : ($charnext === '/*' ? 'multi' : 'none'); - } - - if ($inStr || 'none' === $comment) { + if ($this->inStringOrCommentEnd($prev, $char, $charnext)) { $return .= $char; continue; } - if (($comment === 'single' && $char == "\n") - || ($comment === 'multi' && $charnext == '*/') - ) { - // Cosmetic fix only! - if ($comment === 'single') { - $return = rtrim($return) . $char; - } - - $comment = 'none'; + $wasSingle = 1 === $this->comment; + if ($this->hasCommentEnded($char, $charnext) && $wasSingle) { + $return = rtrim($return) . $char; } $index += $charnext === '*/' ? 1 : 0; @@ -64,6 +50,33 @@ public function strip($json) return $return; } + protected function inStringOrCommentEnd(string $prev, string $char, string $charnext): bool + { + if (0 === $this->comment && $char === '"' && $prev !== '\\') { + $this->inStr = !$this->inStr; + } + + if (!$this->inStr && 0 === $this->comment) { + $this->comment = $charnext === '//' ? 1 : ($charnext === '/*' ? 2 : 0); + } + + return $this->inStr || 0 === $this->comment; + } + + protected function hasCommentEnded(string $char, string $charnext): bool + { + $singleEnded = $this->comment === 1 && $char == "\n"; + $multiEnded = $this->comment === 2 && $charnext == '*/'; + + if ($singleEnded || $multiEnded) { + $this->comment = 0; + + return true; + } + + return false; + } + /** * Strip comments and decode JSON string. * From 1b532e110c740c7f71580fb06c32bcd01fc321bc Mon Sep 17 00:00:00 2001 From: Jitendra Adhikari Date: Thu, 21 Jun 2018 07:26:29 +0700 Subject: [PATCH 2/3] test: remove covers annotation [not required] --- tests/CommentTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/CommentTest.php b/tests/CommentTest.php index 423734b..6f3ba03 100644 --- a/tests/CommentTest.php +++ b/tests/CommentTest.php @@ -4,12 +4,10 @@ use Ahc\Json\Comment; -/** @coversDefaultClass \Ahc\Json\Comment */ class CommentTest extends \PHPUnit_Framework_TestCase { /** * @dataProvider theTests - * @covers \Ahc\Json\Comment::strip */ public function testStrip($json, $expect) { @@ -18,7 +16,6 @@ public function testStrip($json, $expect) /** * @dataProvider theTests - * @covers \Ahc\Json\Comment::decode */ public function testDecode($json) { From c18b0c3c7a5713e172834de9e47daf2c569fc19b Mon Sep 17 00:00:00 2001 From: Jitendra Adhikari Date: Thu, 21 Jun 2018 07:31:12 +0700 Subject: [PATCH 3/3] chore(support): we still have php5 here :) --- src/Comment.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Comment.php b/src/Comment.php index 1a7be49..d22f011 100644 --- a/src/Comment.php +++ b/src/Comment.php @@ -31,8 +31,9 @@ public function strip($json) list($index, $return, $char) = [-1, '', '']; while (isset($json[++$index])) { - list($prev, $char, $charnext) = [$char, $json[$index], $json[$index] . ($json[$index + 1] ?? '')]; + list($prev, $char) = [$char, $json[$index]]; + $charnext = $char . (isset($json[$index + 1]) ? $json[$index + 1] : ''); if ($this->inStringOrCommentEnd($prev, $char, $charnext)) { $return .= $char; @@ -50,7 +51,7 @@ public function strip($json) return $return; } - protected function inStringOrCommentEnd(string $prev, string $char, string $charnext): bool + protected function inStringOrCommentEnd($prev, $char, $charnext) { if (0 === $this->comment && $char === '"' && $prev !== '\\') { $this->inStr = !$this->inStr; @@ -63,7 +64,7 @@ protected function inStringOrCommentEnd(string $prev, string $char, string $char return $this->inStr || 0 === $this->comment; } - protected function hasCommentEnded(string $char, string $charnext): bool + protected function hasCommentEnded($char, $charnext) { $singleEnded = $this->comment === 1 && $char == "\n"; $multiEnded = $this->comment === 2 && $charnext == '*/';