Json parsing
This commit is contained in:
parent
7027d0b869
commit
4a77e852cb
2 changed files with 71 additions and 4 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue