uint ReadCount(ReadOnlySpan <byte> json) { uint count; var reader = new JsonReader(new Utf8String(json)); while (reader.Read()) { switch (reader.TokenType) { case JsonReader.JsonTokenType.Property: var name = reader.GetName(); var value = reader.GetValue(); Console.WriteLine("Property {0} = {1}", name, value); if (name == "Count") { if (!PrimitiveParser.TryParse(value, out count)) { return(1); } return(count); } break; } } return(1); }
public static bool TryParseUInt32 <TMultispan>(this TMultispan bytes, EncodingData encoding, out uint value, out int consumed) where TMultispan : ISequence <Span <byte> > { Position position = Position.BeforeFirst; var first = bytes.TryGetItem(ref position); if (!position.IsValid) { throw new ArgumentException("bytes cannot be empty"); } if (!PrimitiveParser.TryParse(first, EncodingData.Encoding.Utf8, out value, out consumed)) { return(false); // TODO: maybe we should continue in some cases, e.g. if the first span ends in a decimal separator // ... cont, maybe consumed could be set even if TryParse returns false } if (position.IsEnd || first.Length > consumed) { return(true); } var second = bytes.TryGetItem(ref position); Span <byte> temp; int numberOfBytesFromSecond = second.Length; if (numberOfBytesFromSecond > 64) { numberOfBytesFromSecond = 64; } var tempBufferLength = first.Length + numberOfBytesFromSecond; if (tempBufferLength > 128) { temp = new byte[tempBufferLength]; } else { unsafe { byte *data = stackalloc byte[tempBufferLength]; temp = new Span <byte>(data, tempBufferLength); } } first.TryCopyTo(temp); second.Slice(0, numberOfBytesFromSecond).TryCopyTo(temp.Slice(first.Length)); if (!PrimitiveParser.TryParse(temp, EncodingData.Encoding.Utf8, out value, out consumed)) { return(false); } if (position.IsEnd || temp.Length > consumed) { return(true); } throw new NotImplementedException(); }
// TODO: format should be ReadOnlySpan<T> public static Format.Parsed Parse(Span <char> format) { if (format.Length == 0) { return(default(Format.Parsed)); } uint precision = NoPrecision; if (format.Length > 1) { var span = format.Slice(1, format.Length - 1); if (!PrimitiveParser.TryParse(span, out precision)) { throw new NotImplementedException("UnableToParsePrecision"); } if (precision > Parsed.MaxPrecision) { // TODO: this is a contract violation throw new Exception("PrecisionValueOutOfRange"); } } // TODO: this is duplicated from above. It needs to be refactored var specifier = format[0]; return(new Parsed(specifier, (byte)precision)); }
// once we have a non allocating conversion from string to ReadOnlySpan<char>, we can remove this overload public static Format.Parsed Parse(string format) { if (format == null || format.Length == 0) { return(default(Format.Parsed)); } uint precision = NoPrecision; if (format.Length > 1) { if (!PrimitiveParser.TryParse(format, 1, format.Length - 1, out precision)) { throw new NotImplementedException("Unable to parse precision specification"); } if (precision > Parsed.MaxPrecision) { // TODO: this is a contract violation throw new Exception("PrecisionValueOutOfRange"); } } var specifier = format[0]; return(new Parsed(specifier, (byte)precision)); }
/// <summary> /// Parses a <see cref="ulong"/> from the specified <see cref="ReadableBuffer"/> /// </summary> /// <param name="buffer">The <see cref="ReadableBuffer"/> to parse</param> public unsafe static ulong GetUInt64(this ReadableBuffer buffer) { byte *addr; ulong value; int consumed, len = buffer.Length; if (buffer.IsSingleSpan) { // It fits! addr = (byte *)buffer.First.UnsafePointer; } else if (len < 128) // REVIEW: What's a good number { var data = stackalloc byte[len]; buffer.CopyTo(new Span <byte>(data, len)); addr = data; // memory allocated via stackalloc is valid and // intact until the end of the method; we don't need to worry about scope } else { // Heap allocated copy to parse into array (should be rare) var arr = buffer.ToArray(); if (!PrimitiveParser.TryParse(arr, 0, EncodingData.InvariantUtf8, Format.Parsed.HexUppercase, out value, out consumed)) { throw new InvalidOperationException(); } return(value); } if (!PrimitiveParser.TryParse(addr, 0, len, EncodingData.InvariantUtf8, Format.Parsed.HexUppercase, out value, out consumed)) { throw new InvalidOperationException(); } return(value); }
/// <summary> /// Parses a <see cref="uint"/> from the specified <see cref="ReadableBuffer"/> /// </summary> /// <param name="buffer">The <see cref="ReadableBuffer"/> to parse</param> public unsafe static uint GetUInt32(this ReadableBuffer buffer) { ReadOnlySpan <byte> textSpan; if (buffer.IsSingleSpan) { // It fits! textSpan = buffer.First.Span; } else if (buffer.Length < 128) // REVIEW: What's a good number { var data = stackalloc byte[128]; var destination = new Span <byte>(data, 128); buffer.CopyTo(destination); textSpan = destination.Slice(0, buffer.Length); } else { // Heap allocated copy to parse into array (should be rare) textSpan = new ReadOnlySpan <byte>(buffer.ToArray()); } uint value; var utf8Buffer = new Utf8String(textSpan); if (!PrimitiveParser.TryParse(utf8Buffer, out value)) { throw new InvalidOperationException(); } return(value); }
public unsafe void ParseSubstringToUInt32(string text, int index, int count, uint expectedValue, int expectedConsumed) { uint parsedValue; int charsConsumed; bool result = PrimitiveParser.TryParse(text, index, count, out parsedValue, out charsConsumed); Assert.True(result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedConsumed, charsConsumed); }
public unsafe void ParseSpanOfCharToUInt32(string text, uint expectedValue, int expectedConsumed) { var span = new ReadOnlySpan <char>(text.ToCharArray()); uint parsedValue; int charsConsumed; bool result = PrimitiveParser.TryParse(span, out parsedValue, out charsConsumed); Assert.True(result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedConsumed, charsConsumed); }
public unsafe void ParseUtf8StringToUInt32(string text, uint expectedValue, int expectedConsumed) { var utf8 = new Utf8String(text); uint parsedValue; int bytesConsumed; bool result = PrimitiveParser.TryParse(utf8, out parsedValue, out bytesConsumed); Assert.True(result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedConsumed, bytesConsumed); }
public unsafe void ParseUtf8SpanOfBytesToUInt32(string text, uint expectedValue, int expectedConsumed) { byte[] textBuffer = Encoding.UTF8.GetBytes(text); var span = new ReadOnlySpan <byte>(textBuffer); uint parsedValue; int bytesConsumed; bool result = PrimitiveParser.TryParse(span, EncodingData.Encoding.Utf8, out parsedValue, out bytesConsumed); Assert.True(result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedConsumed, bytesConsumed); }