Skip to content

Commit

Permalink
Switch to a struct JsonDeserializer (#95)
Browse files Browse the repository at this point in the history
The state itself still needs to be a class, but this will
cause usages of generic parameters constrained to IDeserialize
to be specialized.
  • Loading branch information
agocke authored Nov 7, 2022
1 parent 3cdb6c3 commit 69a8ef3
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions src/serde/json/JsonDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@

namespace Serde.Json
{
public sealed partial class JsonDeserializer : IDeserializer
internal partial struct JsonDeserializer : IDeserializer
{
private byte[] _utf8Bytes;
private JsonReaderState _readerState;
private int _offset;
// Need to use a class so it can be referenced from the Enumerable and
// Dictionary implementations
private sealed class DeserializerState
{
public byte[] Utf8Bytes = null!;
public JsonReaderState ReaderState;
public int Offset;
}
private readonly DeserializerState _state;

public static JsonDeserializer FromString(string s)
{
Expand All @@ -20,20 +26,26 @@ public static JsonDeserializer FromString(string s)

private JsonDeserializer(byte[] bytes)
{
_utf8Bytes = bytes;
_readerState = default;
_offset = 0;
_state = new DeserializerState
{
Utf8Bytes = bytes,
ReaderState = default,
Offset = 0
};
}

private void SaveState(in Utf8JsonReader reader)
{
_readerState = reader.CurrentState;
_offset += (int)reader.BytesConsumed;
_state.ReaderState = reader.CurrentState;
_state.Offset += (int)reader.BytesConsumed;
}

private Utf8JsonReader GetReader()
{
return new Utf8JsonReader(_utf8Bytes.AsSpan()[_offset..], isFinalBlock: true, _readerState);
return new Utf8JsonReader(
_state.Utf8Bytes.AsSpan()[_state.Offset..],
isFinalBlock: true,
_state.ReaderState);
}

public T DeserializeAny<T, V>(V v) where V : class, IDeserializeVisitor<T>
Expand Down Expand Up @@ -101,15 +113,15 @@ public T DeserializeDouble<T, V>(V v) where V : class, IDeserializeVisitor<T>
{
var reader = GetReader();
var d = reader.GetDouble();
_readerState = reader.CurrentState;
_state.ReaderState = reader.CurrentState;
return v.VisitDouble(d);
}

public T DeserializeDecimal<T, V>(V v) where V : class, IDeserializeVisitor<T>
{
var reader = GetReader();
var d = reader.GetDecimal();
_readerState = reader.CurrentState;
_state.ReaderState = reader.CurrentState;
return v.VisitDecimal(d);
}

Expand Down

0 comments on commit 69a8ef3

Please sign in to comment.