Move to using span slicing instead of string substrings (#135)

* Move to using span slicing instead of string substrings

* Adding unit test for JsonReaderExtensionsTests ReadValueAsTimeSpanDaprFormat method
This commit is contained in:
gmanvel 2019-10-25 20:31:33 +02:00 committed by Aman Bhardwaj
parent 3f27f1a1cc
commit f55249830a
2 changed files with 63 additions and 9 deletions

View File

@ -394,25 +394,32 @@ namespace Dapr.Actors
{
case JsonToken.String:
var valueString = (string)reader.Value;
var spanOfValue = valueString.AsSpan();
try
{
// Change the value returned by Dapr runtime, so that it can be parsed with TimeSpan.
// Format returned by Dapr runtime: 4h15m50s60ms. It doesnt have days.
// Dapr runtime should handle timespans in ISO 8601 format.
// Replace ms before m & s. Also aappend 0 days for parsing correctly with TimeSpan
int hIndex = valueString.IndexOf('h');
int mIndex = valueString.IndexOf('m');
int sIndex = valueString.IndexOf('s');
int msIndex = valueString.IndexOf("ms");
// Replace ms before m & s. Also append 0 days for parsing correctly with TimeSpan
int hIndex = spanOfValue.IndexOf('h');
int mIndex = spanOfValue.IndexOf('m');
int sIndex = spanOfValue.IndexOf('s');
int msIndex = spanOfValue.IndexOf("ms");
// handle days from hours.
var hours = int.Parse(valueString.Substring(0, hIndex));
var hoursSpan = spanOfValue.Slice(0, hIndex);
var hours = int.Parse(hoursSpan);
var days = hours / 24;
hours = hours % 24;
var minutes = int.Parse(valueString.Substring(hIndex + 1, mIndex - (hIndex + 1)));
var seconds = int.Parse(valueString.Substring(mIndex + 1, sIndex - (mIndex + 1)));
var milliseconds = int.Parse(valueString.Substring(sIndex + 1, msIndex - (sIndex + 1)));
var minutesSpan = spanOfValue.Slice(hIndex + 1, mIndex - (hIndex + 1));
var minutes = int.Parse(minutesSpan);
var secondsSpan = spanOfValue.Slice(mIndex + 1, sIndex - (mIndex + 1));
var seconds = int.Parse(secondsSpan);
var millisecondsSpan = spanOfValue.Slice(sIndex + 1, msIndex - (sIndex + 1));
var milliseconds = int.Parse(millisecondsSpan);
value = new TimeSpan(days, hours, minutes, seconds, milliseconds);
}

View File

@ -0,0 +1,47 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
namespace Dapr.Actors.Test
{
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using Xunit;
public class JsonReaderExtensionTests
{
public static readonly IEnumerable<object[]> DaprFormatTimeSpanJsonStringsAndExpectedDeserializedValues = new List<object[]>
{
new object[]
{
"{\"dueTime\":\"4h15m50s60ms\"",
new TimeSpan(0, 4, 15, 50, 60),
},
new object[]
{
"{\"dueTime\":\"0h35m10s12ms\"",
new TimeSpan(0, 0, 35, 10, 12),
},
};
[Theory]
[MemberData(nameof(DaprFormatTimeSpanJsonStringsAndExpectedDeserializedValues))]
public void DaprFormat_TimeSpan_Parsing(string daprFormatTimeSpanJsonString, TimeSpan expectedDeserializedValue)
{
using var textReader = new StringReader(daprFormatTimeSpanJsonString);
using var jsonTextReader = new JsonTextReader(textReader);
while (jsonTextReader.TokenType != JsonToken.String)
{
jsonTextReader.Read();
}
var deserializedTimeSpan = jsonTextReader.ReadValueAsTimeSpanDaprFormat();
Assert.Equal(expectedDeserializedValue, deserializedTimeSpan);
}
}
}