public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ReadOnlySpan <byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (span.SequenceEqual(DecimalZero)) { return(0); } if (reader.TokenType == JsonTokenType.String) { if (Utf8Parser.TryParse(span, out int value, out _)) { return(value); } throw new FormatException($"Invalid integer format: '{Encoding.UTF8.GetChars(span.ToArray())}' Position: {reader.Position}"); } return(reader.GetInt32()); }
private static bool TryReadLength(ReadOnlySpan <byte> buffer, out int index, out int length) { length = 0; // Read until the first ':' to find the length index = buffer.IndexOf((byte)FieldDelimiter); if (index == -1) { // Insufficient data return(false); } var lengthSpan = buffer.Slice(0, index); if (!Utf8Parser.TryParse(buffer, out length, out var bytesConsumed) || bytesConsumed < lengthSpan.Length) { throw new FormatException($"Invalid length: '{Encoding.UTF8.GetString(lengthSpan.ToArray())}'"); } return(true); }
public static PartSysParamRandom ParseRandom(ReadOnlySpan <byte> value) { if (!Utf8Parser.TryParse(value, out float lower, out var bytesConsumed)) { return(null); } if (bytesConsumed >= value.Length || value[bytesConsumed] != '?') { return(null); } if (!Utf8Parser.TryParse(value.Slice(bytesConsumed + 1), out float upper, out _)) { return(null); } var variance = upper - lower; return(new PartSysParamRandom(lower, variance)); }
public static bool TryParseBoolean(ReadOnlySpan <byte> text, out bool value, out int bytesConsumed, SymbolTable symbolTable = null) { symbolTable = symbolTable ?? SymbolTable.InvariantUtf8; bytesConsumed = 0; value = default; if (symbolTable == SymbolTable.InvariantUtf8) { return(Utf8Parser.TryParse(text, out value, out bytesConsumed)); } if (symbolTable == SymbolTable.InvariantUtf16) { ReadOnlySpan <char> textChars = text.NonPortableCast <byte, char>(); bool result = Utf16Parser.TryParseBoolean(textChars, out value, out int charactersConsumed); bytesConsumed = charactersConsumed * sizeof(char); return(result); } return(false); }
public override int?Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { var span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (Utf8Parser.TryParse(span, out int number, out var bytesConsumed) && span.Length == bytesConsumed) { return(number); } if (int.TryParse(reader.GetString(), out number)) { return(number); } return(null); } return(reader.GetInt32()); }
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.Number && typeToConvert == typeof(string)) { return(reader.GetString() ?? ""); } var span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (Utf8Parser.TryParse(span, out long number, out var bytesConsumed) && span.Length == bytesConsumed) { return(number.ToString()); } var data = reader.GetString(); throw new InvalidOperationException($"'{data}' is not a correct expected value!") { Source = nameof(GitVersionStringConverter) }; }
internal double GetDoubleWithQuotes() { ReadOnlySpan <byte> span = GetUnescapedSpan(); if (JsonReaderHelper.TryGetFloatingPointConstant(span, out double value)) { return(value); } // NETCOREAPP implementation of the TryParse method above permits case-insensitive variants of the // float constants "NaN", "Infinity", "-Infinity". This differs from the NETFRAMEWORK implementation. // The following logic reconciles the two implementations to enforce consistent behavior. if (!(Utf8Parser.TryParse(span, out value, out int bytesConsumed) && span.Length == bytesConsumed && JsonHelpers.IsFinite(value))) { ThrowHelper.ThrowFormatException(NumericType.Double); } return(value); }
private object ReadNumber(ref Utf8JsonReader reader) { ReadOnlySpan <byte> buffer = reader.GetRawString(); if (Utf8Parser.TryParse(buffer, out long lValue, out int bytesConsumed) && bytesConsumed == buffer.Length) { return(lValue); } if (Utf8Parser.TryParse(buffer, out ulong ulValue, out bytesConsumed) && bytesConsumed == buffer.Length) { return(ulValue); } if (Utf8Parser.TryParse(buffer, out double dblValue, out bytesConsumed) && bytesConsumed == buffer.Length) { return(dblValue); } throw new JsonException(); }
public override int Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { // try to parse number directly from bytes ReadOnlySpan <byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (Utf8Parser.TryParse(span, out int number, out int bytesConsumed) && span.Length == bytesConsumed) { return(number); } // try to parse from a string if the above failed, this covers cases with other escaped/UTF characters if (int.TryParse(reader.GetString(), out number)) { return(number); } } // fallback to default handling return(reader.GetInt32()); }
/// <summary> /// Tries to convert a memory span that contains the bytes of a UTF-8 string representation of a day on the format YYYY-MM-DD to its <see cref="Day"/> equivalent and returns a value that indicates whether the conversion succeeded. /// </summary> /// <param name="value">The memory span that contains the bytes of the UTF-8 string value to parse.</param> /// <param name="day">Contains the <see cref="Day"/> value equivalent to the value contained in <paramref name="value"/>, if the conversion succeeded, or default if the conversion failed.</param> /// <returns>true if the <paramref name="value"/> parameter was converted successfully; otherwise, false.</returns> public static bool TryParse(ReadOnlySpan <byte> value, out Day day) { const byte Separator = (byte)'-'; if (value.Length == 10 && value[4] == Separator && value[7] == Separator && Utf8Parser.TryParse(value.Slice(0, 4), out uint year) && Utf8Parser.TryParse(value.Slice(5, 2), out uint month) && Utf8Parser.TryParse(value.Slice(8, 2), out uint dayNumber)) { try { day = new Day(new Month(new Year((int)year), (int)month), (int)dayNumber); return(true); } catch { } } day = default; return(false); }
public unsafe void GuidParsingUtf8(string format) { var parsedFormat = ParsedFormat.Parse(format); var random = new Random(1000); var guidBytes = new byte[16]; var expected = guidWithAllNonZeroDigits; for (int i = 0; i < 100; i++) { var expectedString = expected.ToString(format, CultureInfo.InvariantCulture); var utf8Bytes = Text.Encoding.UTF8.GetBytes(expectedString); Assert.True(Utf8Parser.TryParseGuid(utf8Bytes, out Guid parsed, out int bytesConsumed, parsedFormat)); Assert.Equal(expected, parsed); Assert.Equal(expectedString.Length, bytesConsumed); random.NextBytes(guidBytes); expected = new Guid(guidBytes); } }
/// <summary> /// 反序列化 /// </summary> /// <param name="reader"></param> /// <param name="typeToConvert"></param> /// <param name="options"></param> /// <returns></returns> public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (reader.TokenType == JsonTokenType.String) { if (Utf8Parser.TryParse(span, out long result1, out int length) && length == span.Length) { return(result1); } if (long.TryParse(reader.GetString(), out long result2)) { return(result2); } } else { return(reader.GetInt64()); } return(0L); }
public unsafe void DecimalPositiveTests(string text, int length, decimal expectedValue, int expectedConsumed) { byte[] byteBuffer = Text.Encoding.UTF8.GetBytes(text); ReadOnlySpan <byte> byteSpan = new ReadOnlySpan <byte>(byteBuffer); char[] charBuffer = text.ToCharArray(); ReadOnlySpan <char> charSpan = new ReadOnlySpan <char>(charBuffer); bool result; result = CustomParser.TryParseDecimal(byteSpan, out decimal actualValue, out int actualConsumed, SymbolTable.InvariantUtf8); Assert.True(result); Assert.Equal(expectedValue, actualValue); Assert.Equal(expectedConsumed, actualConsumed); result = Utf8Parser.TryParse(byteSpan, out actualValue, out actualConsumed); Assert.True(result); Assert.Equal(expectedValue, actualValue); Assert.Equal(expectedConsumed, actualConsumed); ReadOnlySpan <byte> utf16ByteSpan = charSpan.AsBytes(); result = CustomParser.TryParseDecimal(utf16ByteSpan, out actualValue, out actualConsumed, SymbolTable.InvariantUtf16); Assert.True(result); Assert.Equal(expectedValue, actualValue); Assert.Equal(expectedConsumed, actualConsumed / 2); result = Utf16Parser.TryParseDecimal(charSpan, out actualValue); Assert.True(result); Assert.Equal(expectedValue, actualValue); result = Utf16Parser.TryParseDecimal(charSpan, out actualValue, out actualConsumed); Assert.True(result); Assert.Equal(expectedValue, actualValue); Assert.Equal(expectedConsumed, actualConsumed); }
public override long Read( ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { ReadOnlySpan <byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (Utf8Parser.TryParse(span, out long number, out int bytesConsumed) && span.Length == bytesConsumed) { return(number); } if (long.TryParse(reader.GetString(), out number)) { return(number); } } return(reader.GetInt64()); }
public unsafe (string raw, object value) ParseNumber(bool isDecimal, int start, int end, bool notAllowedConvertUnsignedInteger) { var len = end - start; fixed(char *chars = &Slice(start, len).GetPinnableReference()) { var bytes = stackalloc byte[len]; Encoding.UTF8.GetBytes(chars, len, bytes, len); var buffer = new ReadOnlySpan <byte>(bytes, len); if (isDecimal) { var success = Utf8Parser.TryParse(buffer, out decimal decimalValue, out _); if (!success) { throw new InvalidCastException($"Can not parse value({this[start, len]}) to decimal at (start:{start},end:{end})"); } return(this[start, len], decimalValue); } else { var success = Utf8Parser.TryParse(buffer, out ulong ulongValue, out _); if (!success) { throw new InvalidCastException($"Can not parse value({this[start, len]}) to ulong at (start:{start},end:{end})"); } if (notAllowedConvertUnsignedInteger) { return(this[start, len], ulongValue); } if (ulongValue <= int.MaxValue) { return(this[start, len], (int)ulongValue); } return(ulongValue <= uint.MaxValue ? (this[start, len], (uint)ulongValue) : (this[start, len], ulongValue)); } } }
private unsafe static void PrimitiveParserByteSpanToUInt32_BytesConsumed_VariableLength() { int textLength = s_UInt32TextArray.Length; byte[][] utf8ByteArray = (byte[][])Array.CreateInstance(typeof(byte[]), textLength); for (var i = 0; i < textLength; i++) { utf8ByteArray[i] = Text.Encoding.UTF8.GetBytes(s_UInt32TextArray[i]); } foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { for (int i = 0; i < TestHelper.LoadIterations; i++) { ReadOnlySpan <byte> utf8ByteSpan = utf8ByteArray[i % textLength]; Utf8Parser.TryParse(utf8ByteSpan, out uint value, out int bytesConsumed); TestHelper.DoNotIgnore(value, bytesConsumed); } } } }
private static void Utf8Parser_TryParseDouble(ReadOnlySpan <byte> data) { Span <byte> to = stackalloc byte[1024]; if (Utf8Parser.TryParse(data, out double d1, out _)) { if (double.IsNaN(d1)) { return; } if (!Utf8Formatter.TryFormat(d1, to, out int written)) { throw new Exception(); } if (!Utf8Parser.TryParse(to.Slice(0, written), out double d2, out _)) { throw new Exception(); } } }
public static bool TryGetEscapedGuid(ReadOnlySpan <byte> source, out Guid value) { Debug.Assert(source.Length <= JsonConstants.MaximumEscapedGuidLength); Span <byte> utf8Unescaped = stackalloc byte[JsonConstants.MaximumEscapedGuidLength]; Unescape(source, utf8Unescaped, out int written); Debug.Assert(written > 0); utf8Unescaped = utf8Unescaped.Slice(0, written); Debug.Assert(!utf8Unescaped.IsEmpty); if (utf8Unescaped.Length == JsonConstants.MaximumFormatGuidLength && Utf8Parser.TryParse(utf8Unescaped, out Guid tmp, out _, 'D')) { value = tmp; return(true); } value = default; return(false); }
private static void ByteSpanToUInt32Hex_VariableLength() { int textLength = s_UInt32TextArrayHex.Length; byte[][] utf8ByteArray = (byte[][])Array.CreateInstance(typeof(byte[]), textLength); for (var i = 0; i < textLength; i++) { utf8ByteArray[i] = Encoding.UTF8.GetBytes(s_UInt32TextArrayHex[i]); } foreach (BenchmarkIteration iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { for (int i = 0; i < Benchmark.InnerIterationCount; i++) { ReadOnlySpan <byte> utf8ByteSpan = utf8ByteArray[i % textLength]; Utf8Parser.TryParse(utf8ByteSpan, out uint value, out int bytesConsumed, 'X'); TestHelpers.DoNotIgnore(value, bytesConsumed); } } } }
private static bool TryParseTimeSpanField(ReadOnlySpan <byte> corpus, out TimeSpan timeSpan, out int bytesConsumed) { BackendMetricsTokenizer.TokenType equalsDelimiterToken = BackendMetricsTokenizer.Read(corpus); if (equalsDelimiterToken != BackendMetricsTokenizer.TokenType.EqualDelimiter) { timeSpan = default; bytesConsumed = default; return(false); } corpus = corpus.Slice(1); if (!Utf8Parser.TryParse(corpus, out double milliseconds, out bytesConsumed)) { timeSpan = default; return(false); } // Can not use TimeSpan.FromMilliseconds since double has a loss of precision timeSpan = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * milliseconds)); bytesConsumed++; return(true); }
private static List <int> GetIdsFromMem(ReadOnlyMemory <byte> content) { byte utfComma = 0x2C; var ids = new List <int>(); ReadOnlySpan <byte> localContent = content.Span.Slice(1, content.Length - 2); ReadOnlySpan <byte> currentSlice = localContent.Slice(0); int position = 0, commaPosition = localContent.IndexOf(utfComma); int counter = 0; while (commaPosition >= 0) { if (Utf8Parser.TryParse(currentSlice.Slice(position, commaPosition), out int id, out _)) { ids.Add(id); } position = commaPosition + 1; currentSlice = currentSlice.Slice(position); commaPosition = currentSlice.IndexOf(utfComma); counter++; } return(ids); }
public override byte Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { var span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (Utf8Parser.TryParse(span, out byte number, out var bytesConsumed) && span.Length == bytesConsumed) { return(number); } var jsonValue = reader.GetString(); jsonValue = jsonValue.Replace("$", string.Empty); var value = Convert.ToByte(jsonValue, 16); return(value); } return(reader.GetByte()); }
public static bool TryGetEscapedGuid(ReadOnlySpan <byte> span, out Guid value) { Debug.Assert(span.Length <= JsonConstants.MaximumEscapedGuidLength); int idx = span.IndexOf(JsonConstants.BackSlash); Debug.Assert(idx != -1); Span <byte> utf8Unescaped = stackalloc byte[span.Length]; Unescape(span, utf8Unescaped, idx, out int written); Debug.Assert(written > 0); utf8Unescaped = utf8Unescaped.Slice(0, written); Debug.Assert(!utf8Unescaped.IsEmpty); if (utf8Unescaped.Length != JsonConstants.MaximumFormatGuidLength) { value = default; return(false); } return(Utf8Parser.TryParse(utf8Unescaped, out value, out int bytesConsumed, 'D') && utf8Unescaped.Length == bytesConsumed); }
private unsafe bool TryParseSlow(out bool value) { const int MaxLength = 5; ReadOnlySpan <byte> unread = UnreadSpan; if (unread.Length > MaxLength) { // Fast path had enough space but couldn't find valid data value = default; return(false); } byte * buffer = stackalloc byte[MaxLength]; Span <byte> tempSpan = new Span <byte>(buffer, MaxLength); if (Utf8Parser.TryParse(PeekSlow(tempSpan), out value, out int consumed)) { Advance(consumed); return(true); } return(false); }
internal bool TryGetValue(int index, out double value) { JsonRow row = _parsedData.Get(index); CheckExpectedType(JsonTokenType.Number, row.TokenType); ReadOnlySpan <byte> data = _utf8Json.Span; ReadOnlySpan <byte> segment = data.Slice(row.Location, row.Length); if (Utf8Parser.TryParse(segment, out double tmp, out int bytesConsumed) && segment.Length == bytesConsumed) { value = tmp; return(true); } #if NET5_0_OR_GREATER Unsafe.SkipInit(out value); #else value = default; #endif return(false); }
public bool TryGet(out ulong value) { value = 0; if (ValueSpan.Length == 0) { return(true); } if (ValueSpan.Length > 20) // Guaranteed malformed / overflow { return(false); } if (!Utf8Parser.TryParse(ValueSpan, out value, out int bytesConsumed) || bytesConsumed != ValueSpan.Length) { return(false); } return(value == 0 ? ValueSpan.Length == 1 && ValueSpan[0] == '0' : ValueSpan[0] != '0' && ValueSpan[0] != '+'); }
private void load_int() { ReadOnlySpan <byte> bytes = input.ReadLineBytes(includeLF: true); if (bytes.Length == 3 && bytes[2] == (byte)'\n' && bytes[0] == (byte)'0') { if (bytes[1] == (byte)'0') { load_false(); return; } else if (bytes[1] == (byte)'1') { load_true(); return; } } bytes = bytes.Slice(0, bytes.Length - 1); if (bytes.Length > 0 && Utf8Parser.TryParse(bytes, out int intNumber, out int bytesConsumed) && bytesConsumed == bytes.Length) { stack.add(intNumber); }
public void OnStartLine(HttpMethod method, HttpVersion version, Span <byte> target, Span <byte> path, Span <byte> query, Span <byte> customMethod, bool pathEncoded) { var requestType = RequestType.NotRecognized; if (method == HttpMethod.Get) { var pathLength = path.Length; if (Paths.SingleQuery.Length <= pathLength && path.StartsWith(Paths.SingleQuery)) { requestType = RequestType.SingleQuery; } else if (Paths.Json.Length <= pathLength && path.StartsWith(Paths.Json)) { requestType = RequestType.Json; } else if (Paths.Fortunes.Length <= pathLength && path.StartsWith(Paths.Fortunes)) { requestType = RequestType.Fortunes; } else if (Paths.Plaintext.Length <= pathLength && path.StartsWith(Paths.Plaintext)) { requestType = RequestType.PlainText; } else if (Paths.MultipleQueries.Length <= pathLength && path.StartsWith(Paths.MultipleQueries)) { if (!Utf8Parser.TryParse(path.Slice(Paths.MultipleQueries.Length), out int queries, out _) || queries < 1) { queries = 1; } else if (queries > 500) { queries = 500; } _queries = queries; requestType = RequestType.MultipleQueries; } }
private void load_int() { int len = PickleUtils.readline_into(input, ref byteBuffer, includeLF: true); object val; if (len == 3 && byteBuffer[2] == (byte)'\n' && byteBuffer[0] == (byte)'0') { if (byteBuffer[1] == (byte)'0') { load_false(); return; } else if (byteBuffer[1] == (byte)'1') { load_true(); return; } } len--; if (len > 0 && Utf8Parser.TryParse(byteBuffer.AsSpan(0, len), out int intNumber, out int bytesConsumed) && bytesConsumed == len) { val = intNumber; }
public static IEnumerable <TestData> Load() { var list = new List <TestData>(); using (var f = File.OpenRead("test.csv")) { Span <byte> initialBuffer = stackalloc byte[512]; Span <int> indexBuffer = stackalloc int[4]; ReadOnlySpan <byte> delimiter = stackalloc[] { (byte)',' }; var reader = new LineReader(f, initialBuffer); var line = reader.ReadLine(); while (true) { line = reader.ReadLine(); if (line.IsEmpty) { break; } var items = new Splitter(line, indexBuffer, delimiter); list.Add(new TestData { a = GetString(items[0]), b = GetString(items[1]), x = GetDouble(items[2]), y = GetDouble(items[3]), }); } } return(list); string GetString(ReadOnlySpan <byte> s) => Encoding.UTF8.GetString(s); double GetDouble(ReadOnlySpan <byte> s) => Utf8Parser.TryParse(s, out double value, out _) ? value : 0; }