예제 #1
0
        public JsonObject Parse(ReadOnlySpan <byte> utf8Json, BufferPool pool = null)
        {
            _pool = pool;
            if (_pool == null)
            {
                _pool = ManagedBufferPool.Shared;
            }
            _scratchManager = _pool.Rent(utf8Json.Length * 4);
            _scratchMemory  = _scratchManager.Memory;

            int dbLength = _scratchMemory.Length / 2;

            _db    = _scratchMemory.Slice(0, dbLength);
            _stack = new TwoStacks(_scratchMemory.Slice(dbLength));

            _values            = utf8Json;
            _insideObject      = 0;
            _insideArray       = 0;
            _tokenType         = 0;
            _valuesIndex       = 0;
            _dbIndex           = 0;
            _jsonStartIsObject = false;

            SkipWhitespace();

            _jsonStartIsObject = _values[_valuesIndex] == '{';

            int arrayItemsCount        = 0;
            int numberOfRowsForMembers = 0;

            while (Read())
            {
                var tokenType = _tokenType;
                switch (tokenType)
                {
                case JsonTokenType.ObjectStart:
                    AppendDbRow(JsonObject.JsonValueType.Object, _valuesIndex);
                    while (!_stack.TryPushObject(numberOfRowsForMembers))
                    {
                        ResizeDb();
                    }
                    numberOfRowsForMembers = 0;
                    break;

                case JsonTokenType.ObjectEnd:
                    _db.Span.Slice(FindLocation(_stack.ObjectStackCount - 1, true)).Write <int>(numberOfRowsForMembers);
                    numberOfRowsForMembers += _stack.PopObject();
                    break;

                case JsonTokenType.ArrayStart:
                    AppendDbRow(JsonObject.JsonValueType.Array, _valuesIndex);
                    while (!_stack.TryPushArray(arrayItemsCount))
                    {
                        ResizeDb();
                    }
                    arrayItemsCount = 0;
                    break;

                case JsonTokenType.ArrayEnd:
                    _db.Span.Slice(FindLocation(_stack.ArrayStackCount - 1, false)).Write <int>(arrayItemsCount);
                    arrayItemsCount += _stack.PopArray();
                    break;

                case JsonTokenType.Property:
                    ParsePropertyName();
                    ParseValue();
                    numberOfRowsForMembers++;
                    numberOfRowsForMembers++;
                    break;

                case JsonTokenType.Value:
                    ParseValue();
                    arrayItemsCount++;
                    numberOfRowsForMembers++;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var result = new JsonObject(_values, _db.Slice(0, _dbIndex).Span, _pool, _scratchManager);

            _scratchManager = null;
            return(result);
        }
예제 #2
0
        public JsonObject Parse(ReadOnlySpan<byte> utf8Json, BufferPool pool = null)
        {
            _pool = pool;
            if (_pool == null) _pool = ManagedBufferPool.Shared;
            _scratchManager = _pool.Rent(utf8Json.Length * 4);
            _scratchMemory = _scratchManager.Memory;

            int dbLength = _scratchMemory.Length / 2;
            _db = _scratchMemory.Slice(0, dbLength);
            _stack = new TwoStacks(_scratchMemory.Slice(dbLength));

            _values = utf8Json;
            _insideObject = 0;
            _insideArray = 0;
            _tokenType = 0;
            _valuesIndex = 0;
            _dbIndex = 0;
            _jsonStartIsObject = false;

            SkipWhitespace();

            _jsonStartIsObject = _values[_valuesIndex] == '{';

            int arrayItemsCount = 0;
            int numberOfRowsForMembers = 0;

            while (Read()) {
                var tokenType = _tokenType;
                switch (tokenType) {
                    case JsonTokenType.ObjectStart:
                        AppendDbRow(JsonObject.JsonValueType.Object, _valuesIndex);
                        while(!_stack.TryPushObject(numberOfRowsForMembers)) {
                            ResizeDb();
                        }
                        numberOfRowsForMembers = 0;
                        break;
                    case JsonTokenType.ObjectEnd:
                        _db.Span.Slice(FindLocation(_stack.ObjectStackCount - 1, true)).Write<int>(numberOfRowsForMembers);
                        numberOfRowsForMembers += _stack.PopObject();
                        break;
                    case JsonTokenType.ArrayStart:
                        AppendDbRow(JsonObject.JsonValueType.Array, _valuesIndex);
                        while (!_stack.TryPushArray(arrayItemsCount)) {
                            ResizeDb();
                        }
                        arrayItemsCount = 0;
                        break;
                    case JsonTokenType.ArrayEnd:
                        _db.Span.Slice(FindLocation(_stack.ArrayStackCount - 1, false)).Write<int>(arrayItemsCount);
                        arrayItemsCount += _stack.PopArray();
                        break;
                    case JsonTokenType.Property:
                        ParsePropertyName();
                        ParseValue();
                        numberOfRowsForMembers++;
                        numberOfRowsForMembers++;
                        break;
                    case JsonTokenType.Value:
                        ParseValue();
                        arrayItemsCount++;
                        numberOfRowsForMembers++;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }

            var result =  new JsonObject(_values, _db.Slice(0, _dbIndex).Span, _pool, _scratchManager);
            _scratchManager = null;
            return result;
        }