Json parsing

This commit is contained in:
Jöran Malek 2023-12-17 00:57:15 +01:00
parent 7027d0b869
commit 4a77e852cb
2 changed files with 71 additions and 4 deletions

View file

@ -1,11 +1,78 @@
using System.Buffers;
using System.Text.Json;
using Microsoft.AspNetCore.Connections;
using Microsoft.Toolkit.HighPerformance;
using Microsoft.Toolkit.HighPerformance.Buffers;
namespace pdns_dhcp.PowerDns;
public class PowerDnsHandler : ConnectionHandler
{
public override Task OnConnectedAsync(ConnectionContext connection)
public override async Task OnConnectedAsync(ConnectionContext connection)
{
return Task.CompletedTask;
var input = connection.Transport.Input;
JsonReaderState state = default;
using ArrayPoolBufferWriter<byte> json = new();
using ArrayPoolBufferWriter<byte> buffer = new();
while (!connection.ConnectionClosed.IsCancellationRequested)
{
var read = await input.ReadAsync(connection.ConnectionClosed).ConfigureAwait(false);
if (read.IsCanceled)
{
return;
}
foreach (var memory in read.Buffer)
{
buffer.Write(memory.Span);
if (ConsumeJson(buffer, json, ref state))
{
var method = JsonSerializer.Deserialize<Method>(json.WrittenSpan);
json.Clear();
state = default;
}
}
input.AdvanceTo(read.Buffer.End);
}
static bool ConsumeJson(ArrayPoolBufferWriter<byte> inflight, ArrayPoolBufferWriter<byte> json, ref JsonReaderState state)
{
bool final = false;
Utf8JsonReader reader = new(inflight.WrittenSpan, false, state);
while (!final && reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == 0)
{
final = true;
}
}
state = reader.CurrentState;
int consumed = (int)reader.BytesConsumed;
if (consumed > 0)
{
json.Write(inflight.WrittenSpan[..consumed]);
Span<byte> buffer = default;
var remaining = inflight.WrittenCount - consumed;
if (remaining > 0)
{
buffer = inflight.GetSpan(remaining)[..remaining];
inflight.WrittenSpan[consumed..].CopyTo(buffer);
}
// clear only clears up until WrittenCount
// thus data after write-head is safe
inflight.Clear();
if (!buffer.IsEmpty)
{
inflight.Write(buffer);
}
}
return final;
}
}
}

View file

@ -18,8 +18,8 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Sep" Version="0.3.0" />
<PackageReference Include="Stl.Generators" Version="6.7.21" />
<PackageReference Include="Stl.Interception" Version="6.7.21" />
<PackageReference Include="Stl.Generators" Version="6.8.11" />
<PackageReference Include="Stl.Interception" Version="6.8.11" />
<PackageReference Include="System.IO.Pipelines" Version="8.0.0" />
</ItemGroup>