public unsafe void GuidParsingUtf16(string format) { var parsedFormat = StandardFormat.Parse(format); var random = new Random(1000); var guidBytes = new byte[16]; var expected = guidWithAllNonZeroDigits; for (int i = 0; i < 100; i++) { string expectedString = expected.ToString(format, CultureInfo.InvariantCulture); Assert.True(Utf16Parser.TryParseGuid(expectedString.ToCharArray(), out Guid parsed, out int charactersConsumed, parsedFormat)); Assert.Equal(expected, parsed); Assert.Equal(expectedString.Length, charactersConsumed); random.NextBytes(guidBytes); expected = new Guid(guidBytes); } }
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 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 unsafe void BooleanPositiveTests(string text, int length, bool 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; bool actualValue; int actualConsumed; result = CustomParser.TryParseBoolean(byteSpan, out actualValue, out actualConsumed, SymbolTable.InvariantUtf8); Assert.True(result); Assert.Equal(expectedValue, actualValue); Assert.Equal(expectedConsumed, actualConsumed); //fixed (byte* bytePointer = byteBuffer) //{ // result = Parsers.Utf8.TryParseBoolean(bytePointer, length, out actualValue); // Assert.True(result); // Assert.Equal(expectedValue, actualValue); // result = Parsers.Utf8.TryParseBoolean(bytePointer, length, out actualValue, out actualConsumed); // Assert.True(result); // Assert.Equal(expectedValue, actualValue); // Assert.Equal(expectedConsumed, actualConsumed); //} result = Utf8Parser.TryParseBoolean(byteSpan, out actualValue); Assert.True(result); Assert.Equal(expectedValue, actualValue); result = Utf8Parser.TryParseBoolean(byteSpan, out actualValue, out actualConsumed); Assert.True(result); Assert.Equal(expectedValue, actualValue); Assert.Equal(expectedConsumed, actualConsumed); ReadOnlySpan <byte> utf16ByteSpan = charSpan.AsBytes(); result = CustomParser.TryParseBoolean(utf16ByteSpan, out actualValue, out actualConsumed, SymbolTable.InvariantUtf16); Assert.True(result); Assert.Equal(expectedValue, actualValue); Assert.Equal(expectedConsumed, actualConsumed / 2); //fixed (char* charPointer = charBuffer) //{ // result = Parsers.Utf16.TryParseBoolean(charPointer, length, out actualValue); // Assert.True(result); // Assert.Equal(expectedValue, actualValue); // result = Parsers.Utf16.TryParseBoolean(charPointer, length, out actualValue, out actualConsumed); // Assert.True(result); // Assert.Equal(expectedValue, actualValue); // Assert.Equal(expectedConsumed, actualConsumed); //} result = Utf16Parser.TryParseBoolean(charSpan, out actualValue); Assert.True(result); Assert.Equal(expectedValue, actualValue); result = Utf16Parser.TryParseBoolean(charSpan, out actualValue, out actualConsumed); Assert.True(result); Assert.Equal(expectedValue, actualValue); Assert.Equal(expectedConsumed, actualConsumed); }
public static bool TryParseUInt16(ReadOnlySpan <byte> text, out ushort value, out int bytesConsumed, StandardFormat format = default, SymbolTable symbolTable = null) { symbolTable = symbolTable ?? SymbolTable.InvariantUtf8; if (!format.IsDefault && format.HasPrecision) { throw new NotImplementedException("Format with precision not supported."); } if (symbolTable == SymbolTable.InvariantUtf8) { if (Parsers.IsHexFormat(format)) { return(Utf8Parser.TryParse(text, out value, out bytesConsumed, 'X')); } else { return(Utf8Parser.TryParse(text, out value, out bytesConsumed)); } } else if (symbolTable == SymbolTable.InvariantUtf16) { ReadOnlySpan <char> utf16Text = text.NonPortableCast <byte, char>(); int charactersConsumed; bool result; if (Parsers.IsHexFormat(format)) { result = Utf16Parser.Hex.TryParseUInt16(utf16Text, out value, out charactersConsumed); } else { result = Utf16Parser.TryParseUInt16(utf16Text, out value, out charactersConsumed); } bytesConsumed = charactersConsumed * sizeof(char); return(result); } if (Parsers.IsHexFormat(format)) { throw new NotImplementedException("The only supported encodings for hexadecimal parsing are InvariantUtf8 and InvariantUtf16."); } if (!(format.IsDefault || format.Symbol == 'G' || format.Symbol == 'g')) { throw new NotImplementedException(String.Format("Format '{0}' not supported.", format.Symbol)); } if (!symbolTable.TryParse(text, out SymbolTable.Symbol nextSymbol, out int thisSymbolConsumed)) { value = default; bytesConsumed = 0; return(false); } if (nextSymbol > SymbolTable.Symbol.D9) { value = default; bytesConsumed = 0; return(false); } uint parsedValue = (uint)nextSymbol; int index = thisSymbolConsumed; while (index < text.Length) { bool success = symbolTable.TryParse(text.Slice(index), out nextSymbol, out thisSymbolConsumed); if (!success || nextSymbol > SymbolTable.Symbol.D9) { bytesConsumed = index; value = (ushort)parsedValue; return(true); } // If parsedValue > (ushort.MaxValue / 10), any more appended digits will cause overflow. // if parsedValue == (ushort.MaxValue / 10), any nextDigit greater than 5 implies overflow. if (parsedValue > ushort.MaxValue / 10 || (parsedValue == ushort.MaxValue / 10 && nextSymbol > SymbolTable.Symbol.D5)) { bytesConsumed = 0; value = default; return(false); } index += thisSymbolConsumed; parsedValue = parsedValue * 10 + (uint)nextSymbol; } bytesConsumed = text.Length; value = (ushort)parsedValue; return(true); }