public bool TryGetChild(out JsonObject value)
        {
            DbRow record = _database.Get();

            if (record.SizeOrLength == 0)
            {
                value = default;
                return(false);
            }
            if (record.JsonType != JsonValueType.Object)
            {
                JsonThrowHelper.ThrowInvalidOperationException();
            }

            record = _database.Get(DbRow.Size);

            int newStart = DbRow.Size + DbRow.Size;
            int newEnd   = newStart + DbRow.Size;

            record = _database.Get(newStart);

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

            CustomDb copy = _database;

            copy.Span = _database.Slice(newStart, newEnd - newStart);
            value     = new JsonObject(_jsonData, copy);
            return(true);
        }
예제 #2
0
        public void Remove(JsonObject obj)
        {
            ReadOnlySpan <byte> values = obj._jsonData;
            CustomDb            db     = obj._database;

            DbRow objRecord = db.Get();
            int   reduce    = objRecord.SizeOrLength;

            int idx = _database.Span.IndexOf(db.Span);

            int sliceVal = idx + db.Length;

            if (idx >= DbRow.Size)
            {
                reduce++;
                reduce++;
                idx -= DbRow.Size;
            }

            Span <byte> temp = _database.Slice(0, idx);

            for (int i = 0; i < temp.Length; i += DbRow.Size)
            {
                DbRow record = MemoryMarshal.Read <DbRow>(temp.Slice(i));
                if (!record.IsSimpleValue)
                {
                    DbRow myObj = _database.Get(i + record.SizeOrLength * DbRow.Size);
                    if (myObj.Location > objRecord.Location)
                    {
                        int   sizeOrlength = record.SizeOrLength - reduce;
                        int   numberOfRows = sizeOrlength == 0 ? 1 : sizeOrlength; //TODO: fix up for arrays
                        bool  hasChildren  = record.HasChildren;                   //TODO: Re-calculate HasChildren since it can become false
                        DbRow fixup        = new DbRow(record.JsonType, record.Location, hasChildren, sizeOrlength, numberOfRows);
                        MemoryMarshal.Write(temp.Slice(i), ref fixup);
                    }
                }
            }

            _database.Slice(sliceVal).CopyTo(_database.Slice(idx));
            _database.Span = _database.Slice(0, _database.Length - db.Length - DbRow.Size);
        }
        public void Remove(JsonObject obj)
        {
            ReadOnlySpan <byte> values = obj._jsonData;
            CustomDb            db     = obj._database;

            DbRow objRecord = db.Get();
            int   reduce    = objRecord.SizeOrLength;

            int idx = _database.Span.IndexOf(db.Span);

            int sliceVal = idx + db.Length;

            if (idx >= DbRow.Size)
            {
                reduce++;
                reduce++;
                idx -= DbRow.Size;
            }

            Span <byte> temp = _database.Slice(0, idx);

            for (int i = 0; i < temp.Length; i += DbRow.Size)
            {
                DbRow record = MemoryMarshal.Read <DbRow>(temp.Slice(i));
                if (!record.IsSimpleValue)
                {
                    DbRow myObj = _database.Get(i + record.SizeOrLength * DbRow.Size);
                    if (myObj.Location > objRecord.Location)
                    {
                        DbRow fixup = new DbRow(record.JsonType, record.Location, record.SizeOrLength - reduce);
                        MemoryMarshal.Write(temp.Slice(i), ref fixup);
                    }
                }
            }

            _database.Slice(sliceVal).CopyTo(_database.Slice(idx));
            _database.Span = _database.Slice(0, _database.Length - db.Length - DbRow.Size);
        }
예제 #4
0
        public JsonObject Parse()
        {
            var database = new CustomDb(_pool, DbRow.Size + _utf8Json.Length);
            var stack    = new CustomStack(Utf8JsonReader.StackFreeMaxDepth * StackRow.Size);
            var reader   = new Utf8JsonReader(_utf8Json);

            bool inArray                = false;
            int  arrayItemsCount        = 0;
            int  numberOfRowsForMembers = 0;
            int  numberOfRowsForValues  = 0;
            int  parentLocation         = -1;

            while (reader.Read())
            {
                JsonTokenType tokenType = reader.TokenType;

                if (tokenType == JsonTokenType.StartObject)
                {
                    if (parentLocation != -1)
                    {
                        database.SetHasChildren(parentLocation);
                    }
                    parentLocation = database.Index;
                    if (inArray)
                    {
                        arrayItemsCount++;
                    }
                    numberOfRowsForValues++;
                    database.Append(JsonValueType.Object, reader.TokenStartIndex);
                    var row = new StackRow(numberOfRowsForMembers + 1);
                    stack.Push(row);
                    numberOfRowsForMembers = 0;
                }
                else if (tokenType == JsonTokenType.EndObject)
                {
                    parentLocation = -1;
                    int rowIndex = reader.NoMoreData ? 0 : database.FindIndexOfFirstUnsetSizeOrLength(JsonValueType.Object);
                    database.SetLength(rowIndex, numberOfRowsForMembers);
                    if (numberOfRowsForMembers != 0)
                    {
                        database.SetNumberOfRows(rowIndex, numberOfRowsForMembers);
                    }
                    StackRow row = stack.Pop();
                    numberOfRowsForMembers += row.SizeOrLength;
                }
                else if (tokenType == JsonTokenType.StartArray)
                {
                    if (parentLocation != -1)
                    {
                        database.SetHasChildren(parentLocation);
                    }
                    parentLocation = database.Index;
                    if (inArray)
                    {
                        arrayItemsCount++;
                    }
                    numberOfRowsForMembers++;
                    database.Append(JsonValueType.Array, reader.TokenStartIndex);
                    var row = new StackRow(arrayItemsCount, numberOfRowsForValues + 1);
                    stack.Push(row);
                    arrayItemsCount       = 0;
                    numberOfRowsForValues = 0;
                }
                else if (tokenType == JsonTokenType.EndArray)
                {
                    parentLocation = -1;
                    int rowIndex = reader.NoMoreData ? 0 : database.FindIndexOfFirstUnsetSizeOrLength(JsonValueType.Array);
                    database.SetLength(rowIndex, arrayItemsCount);
                    if (numberOfRowsForValues != 0)
                    {
                        database.SetNumberOfRows(rowIndex, numberOfRowsForValues);
                    }
                    StackRow row = stack.Pop();
                    arrayItemsCount        = row.SizeOrLength;
                    numberOfRowsForValues += row.NumberOfRows;
                }
                else
                {
                    Debug.Assert(tokenType == JsonTokenType.PropertyName || tokenType == JsonTokenType.Value);
                    numberOfRowsForValues++;
                    numberOfRowsForMembers++;
                    database.Append(reader.ValueType, reader.TokenStartIndex, reader.Value.Length);
                    if (tokenType == JsonTokenType.Value && inArray)
                    {
                        arrayItemsCount++;
                    }
                }

                inArray = reader.InArray;
            }

            stack.Dispose();
            database.Resize();
            return(new JsonObject(_utf8Json, database));
        }
예제 #5
0
 internal JsonObject(ReadOnlySpan <byte> jsonData, CustomDb database, ReadOnlySpan <byte> name = default)
 {
     _database    = database;
     _jsonData    = jsonData;
     PropertyName = name;
 }
 internal JsonObject(ReadOnlySpan <byte> jsonData, CustomDb database)
 {
     _database = database;
     _jsonData = jsonData;
 }