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); }
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); }
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)); }
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; }