Commit 39cd17af authored by Anton Smirnov's avatar Anton Smirnov
Browse files

Use objects internally

parent e43d0c33
Loading
Loading
Loading
Loading
Loading
+20 −16
Original line number Diff line number Diff line
@@ -26,9 +26,13 @@ final class Decoder
    private $decoded;
    private $options;

    /** @var mixed */
    private $state;
    /** @var \SplStack */
    private $stateStack;
    /** @var mixed|\SplQueue */
    private $value;
    /** @var \SplStack */
    private $valueStack;

    const STATE_ROOT = 1;
@@ -56,9 +60,9 @@ final class Decoder
    public function decode()
    {
        $this->state        = self::STATE_ROOT;
        $this->stateStack   = [];
        $this->stateStack   = new \SplStack();
        $this->decoded      = null;
        $this->valueStack   = [];
        $this->valueStack   = new \SplStack();

        while (!feof($this->stream)) {
            $this->processChar();
@@ -238,20 +242,19 @@ final class Decoder

    private function finalizeList()
    {
        $value = $this->convertArrayToType($this->value, 'listType');
        $value = $this->convertArrayToType(iterator_to_array($this->value), 'listType');

        $this->pop($value);
    }

    private function finalizeDict()
    {
        $dict = [];

        $dictBuilder = function (): \Generator {
            $prevKey = null;

        // we have an array [key1, value1, key2, value2, key3, value3, ...]
            // we have a queue [key1, value1, key2, value2, key3, value3, ...]
            while (\count($this->value)) {
            $dictKey = array_shift($this->value);
                $dictKey = $this->value->dequeue();
                if (\is_string($dictKey) === false) {
                    throw new ParseErrorException('Non string key found in the dictionary');
                }
@@ -261,13 +264,14 @@ final class Decoder
                if ($prevKey && strcmp($prevKey, $dictKey) >= 0) {
                    throw new ParseErrorException("Invalid order of dictionary keys: '{$dictKey}' after '{$prevKey}'");
                }
            $dictValue = array_shift($this->value);
                $dictValue = $this->value->dequeue();

            $dict[$dictKey] = $dictValue;
                yield $dictKey => $dictValue;
                $prevKey = $dictKey;
            }
        };

        $value = $this->convertArrayToType($dict, 'dictType');
        $value = $this->convertArrayToType(iterator_to_array($dictBuilder()), 'dictType');

        $this->pop($value);
    }
@@ -278,13 +282,13 @@ final class Decoder
     */
    private function push(int $newState)
    {
        array_push($this->stateStack, $this->state);
        $this->stateStack->push($this->state);
        $this->state = $newState;

        if ($this->state !== self::STATE_ROOT) {
            array_push($this->valueStack, $this->value);
            $this->valueStack->push($this->value);
        }
        $this->value = [];
        $this->value = new \SplQueue();
    }

    /**
@@ -307,11 +311,11 @@ final class Decoder
     */
    private function pop($valueToPrevLevel)
    {
        $this->state = array_pop($this->stateStack);
        $this->state = $this->stateStack->pop();

        if ($this->state !== self::STATE_ROOT) {
            $this->value = array_pop($this->valueStack);
            $this->value[] = $valueToPrevLevel;
            $this->value = $this->valueStack->pop();
            $this->value->enqueue($valueToPrevLevel);
        } else {
            // we have final result
            $this->decoded = $valueToPrevLevel;