Exemplo n.º 1
0
        public bool TryGetValue(string propertyName, out JsonObject value)
        {
            var record = Record;
            
            if (record.Length == 0) {
                throw new KeyNotFoundException();
            }

            if (record.Type != JsonValueType.Object) {
                throw new NullReferenceException();
            }

            for (int i = DbRow.Size; i <= _db.Length; i += DbRow.Size) {
                record = _db.Slice(i).Read<DbRow>();

                if (!record.IsSimpleValue) {
                    i += record.Length * DbRow.Size;
                    continue;
                }

                if (new Utf8String(_values.Slice(record.Location, record.Length)) == propertyName) {
                    int newStart = i + DbRow.Size;
                    int newEnd = newStart + DbRow.Size;

                    record = _db.Slice(newStart).Read<DbRow>();

                    if (!record.IsSimpleValue) {
                        newEnd = newEnd + DbRow.Size * record.Length;
                    }

                    value = new JsonObject(_values, _db.Slice(newStart, newEnd - newStart));
                    return true;
                }

                var valueType = _db.Slice(i + DbRow.Size + 8).Read<JsonValueType>();
                if (valueType != JsonValueType.Object && valueType != JsonValueType.Array) {
                    i += DbRow.Size;
                }
            }

            value = default(JsonObject);
            return false;
        }
Exemplo n.º 2
0
        private bool AppendDbRow(JsonObject.JsonValueType type, int valueIndex, int LengthOrNumberOfRows = DbRow.UnknownNumberOfRows)
        {
            var newIndex = _dbIndex + DbRow.Size;
            if (newIndex >= _db.Length) {
                ResizeDb();
            }

            var dbRow = new DbRow(type, valueIndex, LengthOrNumberOfRows);
            _db.Span.Slice(_dbIndex).Write(dbRow);
            _dbIndex = newIndex;
            return true;
        }
Exemplo n.º 3
0
 public DbRow(JsonObject.JsonValueType type, int valueIndex, int lengthOrNumberOfRows = UnknownNumberOfRows)
 {
     Location = valueIndex;
     Length = lengthOrNumberOfRows;
     Type = type;
 }
Exemplo n.º 4
0
 private void ParseLiteral(JsonObject.JsonValueType literal, ReadOnlySpan<byte> expected)
 {
     if (!_values.Slice(_valuesIndex).StartsWith(expected)) {
         throw new FormatException("Invalid json, tried to read " + literal.ToString());
     }
     AppendDbRow(literal, _valuesIndex, expected.Length);
     _valuesIndex += expected.Length;
     SkipWhitespace();
 }
Exemplo n.º 5
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;
        }