Skip to content

Commit

Permalink
Migration to System.Text.Json
Browse files Browse the repository at this point in the history
  • Loading branch information
chubrik committed Apr 25, 2022
1 parent c615e7d commit 967b3de
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 100 deletions.
22 changes: 10 additions & 12 deletions OsmDataKit/Internal/CacheProvider.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
using Kit;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;

namespace OsmDataKit.Internal
{
internal static class CacheProvider
{
private static readonly JsonSerializerOptions _options =
new() { Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) };

public static bool Has(string cacheName) => File.Exists(CachePath(cacheName));

public static void Delete(string cacheName) => File.Delete(CachePath(cacheName));
Expand All @@ -20,11 +25,8 @@ public static GeoContext Get(string cacheName)
if (path == null)
throw new ArgumentNullException(nameof(path));
using var fileStream = File.OpenRead(path);
using var streamReader = new StreamReader(fileStream);
using var jsonTextReader = new JsonTextReader(streamReader);
var context = new JsonSerializer().Deserialize<GeoContext>(jsonTextReader);
var json = File.ReadAllText(path);
var context = JsonSerializer.Deserialize<GeoContext>(json, _options);
if (context == null)
throw new InvalidOperationException(
Expand Down Expand Up @@ -60,12 +62,8 @@ public static void Put(string cacheName, GeoContext context)
File.Delete(path);
}
using var fileStream = File.OpenWrite(path);
using var streamWriter = new StreamWriter(fileStream);
using var jsonTextWriter = new JsonTextWriter(streamWriter);
new JsonSerializer().Serialize(jsonTextWriter, context);
jsonTextWriter.Close();
var json = JsonSerializer.Serialize(context, _options);
File.WriteAllText(path, json);
});
}

Expand Down
11 changes: 5 additions & 6 deletions OsmDataKit/Internal/GeoContext.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;

namespace OsmDataKit.Internal
{
[JsonObject]
internal sealed class GeoContext
{
[JsonIgnore]
Expand All @@ -20,21 +19,21 @@ internal sealed class GeoContext
public List<long> MissedWayIds { get; set; } = new List<long>(0);
public List<long> MissedRelationIds { get; set; } = new List<long>(0);

[JsonProperty("Nodes")]
[JsonPropertyName("Nodes")]
public NodeObject[] JsonNodes
{
get => Nodes.Values.ToArray();
set => Nodes = value.ToDictionary(i => i.Id);
}

[JsonProperty("Ways")]
[JsonPropertyName("Ways")]
public WayObject[] JsonWays
{
get => Ways.Values.ToArray();
set => Ways = value.ToDictionary(i => i.Id);
}

[JsonProperty("Relations")]
[JsonPropertyName("Relations")]
public RelationObject[] JsonRelations
{
get => Relations.Values.ToArray();
Expand Down
29 changes: 15 additions & 14 deletions OsmDataKit/Internal/GeoObjectConverter.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using Newtonsoft.Json;
using System;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace OsmDataKit.Internal
{
Expand All @@ -11,47 +12,47 @@ internal abstract class GeoObjectConverter<T> : JsonConverter<T> where T : GeoOb
protected const string TagsPropName = "g";

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<string, string>? ReadTagsJson(JsonReader reader)
protected Dictionary<string, string>? ReadTagsJson(ref Utf8JsonReader reader)
{
reader.Read();

if (reader.TokenType != JsonToken.StartObject)
if (reader.TokenType != JsonTokenType.StartObject)
throw new InvalidOperationException();

reader.Read();

if (reader.TokenType == JsonToken.EndObject)
if (reader.TokenType == JsonTokenType.EndObject)
return null;

var tags = new Dictionary<string, string>();
string key, value;

for (; ; )
{
if (reader.TokenType != JsonToken.PropertyName)
if (reader.TokenType != JsonTokenType.PropertyName)
throw new InvalidOperationException();

tags.Add((string)reader.Value!, reader.ReadAsString()!);

key = reader.GetString()!;
reader.Read();
value = reader.GetString()!;
tags.Add(key, value);
reader.Read();

if (reader.TokenType == JsonToken.EndObject)
if (reader.TokenType == JsonTokenType.EndObject)
return tags;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void WriteTagsJson(JsonWriter writer, T value)
protected void WriteTagsJson(Utf8JsonWriter writer, T value)
{
if (value.Tags?.Count > 0)
{
writer.WritePropertyName(TagsPropName);
writer.WriteStartObject();

foreach (var pair in value.Tags)
{
writer.WritePropertyName(pair.Key);
writer.WriteValue(pair.Value);
}
writer.WriteString(pair.Key, pair.Value);

writer.WriteEndObject();
}
Expand Down
42 changes: 24 additions & 18 deletions OsmDataKit/Internal/NodeObjectConverter.cs
Original file line number Diff line number Diff line change
@@ -1,71 +1,77 @@
using Newtonsoft.Json;
using System;
using System;
using System.Collections.Generic;
using System.Text.Json;

namespace OsmDataKit.Internal
{
internal class NodeObjectConverter : GeoObjectConverter<NodeObject>
{
private const string _locationPropName = "l";

public override NodeObject ReadJson(JsonReader reader, Type objectType, NodeObject? existingValue, bool hasExistingValue, JsonSerializer serializer)
public override NodeObject Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonToken.StartObject)
if (reader.TokenType != JsonTokenType.StartObject)
throw new InvalidOperationException();

long id = 0;
Dictionary<string, string>? tags = null;
Location? location = null;
double latitude, longitude;

for (; ; )
{
reader.Read();

if (reader.TokenType == JsonToken.EndObject)
if (reader.TokenType == JsonTokenType.EndObject)
return new NodeObject(id, location!.Value, tags);

if (reader.TokenType != JsonToken.PropertyName)
if (reader.TokenType != JsonTokenType.PropertyName)
throw new InvalidOperationException();

switch (reader.Value)
switch (reader.GetString())
{
case IdPropName:
reader.Read();
id = (long)reader.Value;
id = reader.GetInt64();
break;

case TagsPropName:
tags = ReadTagsJson(reader);
tags = ReadTagsJson(ref reader);
break;

case _locationPropName:
reader.Read();

if (reader.TokenType != JsonToken.StartArray)
if (reader.TokenType != JsonTokenType.StartArray)
throw new InvalidOperationException();

location = new Location(reader.ReadAsDouble()!.Value, reader.ReadAsDouble()!.Value);

reader.Read();
latitude = reader.GetDouble();
reader.Read();
longitude = reader.GetDouble();
location = new Location(latitude, longitude);
reader.Read();

if (reader.TokenType != JsonToken.EndArray)
if (reader.TokenType != JsonTokenType.EndArray)
throw new InvalidOperationException();

break;

default:
throw new InvalidOperationException();
}
}
}

public override void WriteJson(JsonWriter writer, NodeObject? value, JsonSerializer serializer)
public override void Write(Utf8JsonWriter writer, NodeObject value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WritePropertyName(IdPropName);
writer.WriteValue(value!.Id);
writer.WriteNumber(IdPropName, value.Id);
WriteTagsJson(writer, value);
writer.WritePropertyName(_locationPropName);
writer.WriteStartArray();
writer.WriteValue(value.Latitude);
writer.WriteValue(value.Longitude);
writer.WriteNumberValue(value.Latitude);
writer.WriteNumberValue(value.Longitude);
writer.WriteEndArray();
writer.WriteEndObject();
}
Expand Down
Loading

0 comments on commit 967b3de

Please sign in to comment.