Skip to content

Commit

Permalink
Parse async seekless (#3)
Browse files Browse the repository at this point in the history
* Remove CK2PlayerCharacterConverter

* Rename PlayerCharacterData to CK2PlayerCharacterData

* Remove CK2txt

* Update CK2PlayerCharacter

* Remove internal types

* Use dead-simple serialization

* Update tests

* Update tests

* Bump version
  • Loading branch information
jzebedee authored Oct 11, 2019
1 parent 7e57926 commit dbe634b
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 158 deletions.
62 changes: 11 additions & 51 deletions src/Chronicler/ChronicleCollection.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using Chronicler.Converters;
using Chronicler.Converters.Internal;
using Chronicler.Internal;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
Expand All @@ -16,14 +13,14 @@ public class ChronicleCollection
[JsonPropertyName("chronicle")]
public List<Chronicle> Chronicles { get; set; }

public static ChronicleCollection ParseJson(JsonDocument ck2json)
public static ChronicleCollection Parse(JsonDocument jsonDoc)
{
var playerId = ck2json.RootElement
var playerId = jsonDoc.RootElement
.GetProperty("player")
.GetProperty("id")
.GetRawText();

var playerCharacterElement = ck2json.RootElement
var playerCharacterElement = jsonDoc.RootElement
.GetProperty("character")
.GetProperty(playerId);

Expand All @@ -34,53 +31,16 @@ public static ChronicleCollection ParseJson(JsonDocument ck2json)
return new JsonElementSerializer(chronicleCollection).ToObject<ChronicleCollection>();
}

public static async Task<ChronicleCollection> ParseJsonAsync(Stream jsonStream)
public static ChronicleCollection Parse(Stream jsonStream)
{
static int ReadPIDFromHeader(ReadOnlySpan<byte> headerChunk)
{
var reader = new Utf8JsonReader(headerChunk);

while (reader.Read())
{
switch (reader.TokenType)
{
case JsonTokenType.PropertyName when reader.ValueTextEquals("id"):
if (reader.Read())
{
return reader.GetInt32();
}
goto fail;
}
}

fail:
throw new JsonException("couldn't find player ID");
}

int pid;
{
var headerChunk = System.Buffers.ArrayPool<byte>.Shared.Rent(0x200);

var bytesRead = await jsonStream.ReadAsync(headerChunk, 0, headerChunk.Length);
if (bytesRead < headerChunk.Length)
throw new InvalidOperationException("failed to read header");

pid = ReadPIDFromHeader(headerChunk);

System.Buffers.ArrayPool<byte>.Shared.Return(headerChunk);
}
jsonStream.Seek(0, SeekOrigin.Begin);

var ck2pcConverter = new CK2PlayerCharacterConverter
{
PlayerID = pid
};
using var reader = new StreamReader(jsonStream);
return Parse(reader.ReadToEnd());
}

var options = new JsonSerializerOptions();
options.Converters.Add(ck2pcConverter);
public static ChronicleCollection Parse(string jsonText)
=> JsonSerializer.Deserialize<ChronicleCollection>(jsonText);

var ck = await JsonSerializer.DeserializeAsync<CK2txt>(jsonStream, options);
return ck.PlayerCharacter.PlayerCharacterData.ChronicleCollection;
}
public static ValueTask<ChronicleCollection> ParseAsync(Stream jsonStream)
=> JsonSerializer.DeserializeAsync<ChronicleCollection>(jsonStream);
}
}
2 changes: 1 addition & 1 deletion src/Chronicler/Chronicler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<Description>Chronicle parsing library for Crusader Kings II</Description>
<PackageProjectUrl>https://github.com/scorpdx/chronicler</PackageProjectUrl>
<RepositoryUrl>https://github.com/scorpdx/chronicler</RepositoryUrl>
<Version>0.2.0</Version>
<Version>0.3.0</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
58 changes: 0 additions & 58 deletions src/Chronicler/Converters/Internal/CK2PlayerCharacterConverter.cs

This file was deleted.

10 changes: 0 additions & 10 deletions src/Chronicler/Internal/CK2Player.cs

This file was deleted.

10 changes: 0 additions & 10 deletions src/Chronicler/Internal/CK2PlayerCharacter.cs

This file was deleted.

13 changes: 0 additions & 13 deletions src/Chronicler/Internal/CK2txt.cs

This file was deleted.

10 changes: 0 additions & 10 deletions src/Chronicler/Internal/PlayerCharacterData.cs

This file was deleted.

32 changes: 27 additions & 5 deletions test/ChroniclerTests/ChronicleCollectionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,36 @@ public class ChronicleCollectionTest
private static string CK2JsonPath => Path.Combine("resources", "Ironman_West_Francia_HaR.json");

private static Stream GetCK2JsonStream() => File.OpenRead(CK2JsonPath);
private static readonly JsonDocument CK2Json = JsonDocument.Parse(File.ReadAllText(CK2JsonPath));
private static readonly string CK2JsonText = File.ReadAllText(CK2JsonPath);
private static readonly JsonDocument CK2Json = JsonDocument.Parse(CK2JsonText);

[Fact]
public void TestParseJson()
public void TestParseJsonDoc()
{
var chronicleCollection = Chronicler.ChronicleCollection.ParseJson(CK2Json);
var chronicleCollection = Chronicler.ChronicleCollection.Parse(CK2Json);
VerifyJson(chronicleCollection);
}

[Fact]
public async Task TestParseJsonAsync()
public void TestParseJsonText()
{
var chronicleCollection = Chronicler.ChronicleCollection.Parse(CK2JsonText);
VerifyJson(chronicleCollection);
}

[Fact]
public void TestParse()
{
using var stream = GetCK2JsonStream();
var chronicleCollection = await Chronicler.ChronicleCollection.ParseJsonAsync(stream);
var chronicleCollection = Chronicler.ChronicleCollection.Parse(stream);
VerifyJson(chronicleCollection);
}

[Fact]
public async Task TestParseAsync()
{
using var stream = GetCK2JsonStream();
var chronicleCollection = await Chronicler.ChronicleCollection.ParseAsync(stream);
VerifyJson(chronicleCollection);
}

Expand All @@ -40,6 +56,12 @@ private void VerifyJson(ChronicleCollection chronicleCollection)
chap => Assert.NotEmpty(chap.Entries),
chap => Assert.NotEmpty(chap.Entries));
Assert.False(string.IsNullOrEmpty(chronicleCollection.Chronicles[0].Chapters[0].Entries[0].Text));

const int expectedCharacterId = 6392;
Assert.Equal(expectedCharacterId, chronicleCollection.Chronicles[0].Character);

const int expectedFirstYear = 769;
Assert.Equal(expectedFirstYear, chronicleCollection.Chronicles[0].Chapters[0].Year);
}
}
}

0 comments on commit dbe634b

Please sign in to comment.