[InlineData("-129", false, 0, 0, 0)] // negative overflow test public unsafe void ParseCustomCultureByteArrayToSbyte(string text, bool expectSuccess, int index, sbyte expectedValue, int expectedBytesConsumed) { sbyte parsedValue; int bytesConsumed; var utf8digitsAndSymbols = new byte[][] { new byte[] { 48, }, new byte[] { 49, }, new byte[] { 50, }, new byte[] { 51, }, new byte[] { 52, }, new byte[] { 53, }, new byte[] { 54, }, new byte[] { 55, }, new byte[] { 56, }, new byte[] { 57, }, // digit 9 new byte[] { 46, }, // decimal separator null, // so that it is != to uft8DigitsAndSymbols new byte[] { 73, 110, 102, 105, 110, 105, 116, 121, }, new byte[] { 45, }, // minus sign new byte[] { 43, }, // plus sign new byte[] { 78, 97, 78, }, // NaN new byte[] { 69, }, // E }; var utf8ParsingTrie = new EncodingData.TrieNode[] { new EncodingData.TrieNode { valueOrNumChildren = 17, index = 0x3004390D }, new EncodingData.TrieNode { valueOrNumChildren = 43, index = 18 }, new EncodingData.TrieNode { valueOrNumChildren = 45, index = 19 }, new EncodingData.TrieNode { valueOrNumChildren = 46, index = 20 }, new EncodingData.TrieNode { valueOrNumChildren = 48, index = 21 }, new EncodingData.TrieNode { valueOrNumChildren = 49, index = 22 }, new EncodingData.TrieNode { valueOrNumChildren = 50, index = 23 }, new EncodingData.TrieNode { valueOrNumChildren = 51, index = 24 }, new EncodingData.TrieNode { valueOrNumChildren = 52, index = 25 }, new EncodingData.TrieNode { valueOrNumChildren = 53, index = 26 }, new EncodingData.TrieNode { valueOrNumChildren = 54, index = 27 }, new EncodingData.TrieNode { valueOrNumChildren = 55, index = 28 }, new EncodingData.TrieNode { valueOrNumChildren = 56, index = 29 }, new EncodingData.TrieNode { valueOrNumChildren = 57, index = 30 }, new EncodingData.TrieNode { valueOrNumChildren = 69, index = 31 }, new EncodingData.TrieNode { valueOrNumChildren = 73, index = 32 }, new EncodingData.TrieNode { valueOrNumChildren = 78, index = 33 }, new EncodingData.TrieNode { valueOrNumChildren = 101, index = 34 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 14 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 13 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 10 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 0 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 1 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 2 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 3 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 4 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 5 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 6 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 7 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 8 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 9 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 16 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 12 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 15 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 16 }, }; EncodingData fd = new EncodingData(utf8digitsAndSymbols, utf8ParsingTrie, EncodingData.Encoding.Utf8); Format.Parsed nf = new Format.Parsed('R'); bool result = PrimitiveParser.TryParseSByte(UtfEncode(text, false), index, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); }
[InlineData("18446744073709551616", false, 0, 0, 0)] // overflow test public unsafe void ParseUtf16SpanToUlong(string text, bool expectSuccess, int index, ulong expectedValue, int expectedBytesConsumed) { ulong parsedValue; int bytesConsumed; EncodingData fd = EncodingData.InvariantUtf16; Format.Parsed nf = new Format.Parsed('R'); var span = UtfEncode(text, true).Slice(index); bool result = PrimitiveParser.TryParseUInt64(span, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); }
[InlineData("18446744073709551616", false, 0, 0, 0)] // overflow test public unsafe void ParseUtf16ByteStarToUlong(string text, bool expectSuccess, int index, ulong expectedValue, int expectedBytesConsumed) { ulong parsedValue; int bytesConsumed; byte[] textBytes = UtfEncode(text, true); EncodingData fd = EncodingData.InvariantUtf16; Format.Parsed nf = new Format.Parsed('R'); fixed (byte* arrayPointer = textBytes) { bool result = PrimitiveParser.TryParseUInt64(arrayPointer, index, textBytes.Length, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); } }
[InlineData("1.6540654e100000", false, 0, 0, 0)] // overflow test public unsafe void ParseUtf8ByteStarToDouble(string text, bool expectSuccess, int index, double expectedValue, int expectedBytesConsumed) { double parsedValue; int bytesConsumed; EncodingData fd = EncodingData.InvariantUtf8; Format.Parsed nf = new Format.Parsed('N'); byte[] textBytes = UtfEncode(text, false); fixed (byte* arrayPointer = textBytes) { bool result = PrimitiveParser.TryParseDouble(arrayPointer, index, textBytes.Length, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); } }
[InlineData("4294967296", false, 0, 0, 0)] // overflow test public unsafe void ParseUtf16ByteArrayToUint(string text, bool expectSuccess, int index, uint expectedValue, int expectedBytesConsumed) { uint parsedValue; int bytesConsumed; EncodingData fd = EncodingData.InvariantUtf16; Format.Parsed nf = new Format.Parsed('R'); bool result = PrimitiveParser.TryParseUInt32(UtfEncode(text, true), index, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); }
[InlineData("ลป๑", false, 0, 0, 0)] // public unsafe void ParseCustomCultureThaiByteArrayToLong(string text, bool expectSuccess, int index, long expectedValue, int expectedBytesConsumed) { long parsedValue; int bytesConsumed; var thaiUtf8DigitsAndSymbols = new byte[][] { new byte[] { 0xe0, 0xb9, 0x90 }, new byte[] { 0xe0, 0xb9, 0x91 }, new byte[] { 0xe0, 0xb9, 0x92 }, new byte[] { 0xe0, 0xb9, 0x93 }, new byte[] { 0xe0, 0xb9, 0x94 }, new byte[] { 0xe0, 0xb9, 0x95 }, new byte[] { 0xe0, 0xb9, 0x96 }, new byte[] { 0xe0, 0xb9, 0x97 }, new byte[] { 0xe0, 0xb9, 0x98 }, new byte[] { 0xe0, 0xb9, 0x99 }, new byte[] { 0xE0, 0xB8, 0x88, 0xE0, 0xB8, 0x94 }, null, new byte[] { 0xE0, 0xB8, 0xAA, 0xE0, 0xB8, 0xB4, 0xE0, 0xB9, 0x88, 0xE0, 0xB8, 0x87, 0xE0, 0xB8, 0x97, 0xE0, 0xB8, 0xB5, 0xE0, 0xB9, 0x88, 0xE0, 0xB9, 0x83, 0xE0, 0xB8, 0xAB, 0xE0, 0xB8, 0x8D, 0xE0, 0xB9, 0x88, 0xE0, 0xB9, 0x82, 0xE0, 0xB8, 0x95, 0xE0, 0xB9, 0x80, 0xE0, 0xB8, 0xAB, 0xE0, 0xB8, 0xA5, 0xE0, 0xB8, 0xB7, 0xE0, 0xB8, 0xAD, 0xE0, 0xB9, 0x80, 0xE0, 0xB8, 0x81, 0xE0, 0xB8, 0xB4, 0xE0, 0xB8, 0x99 }, new byte[] { 0xE0, 0xB8, 0xA5, 0xE0, 0xB8, 0x9A }, new byte[] { 43 }, new byte[] { 0xE0, 0xB9, 0x84, 0xE0, 0xB8, 0xA1, 0xE0, 0xB9, 0x88, 0xE0, 0xB9, 0x83, 0xE0, 0xB8, 0x8A, 0xE0, 0xB9, 0x88, 0xE0, 0xB8, 0x95, 0xE0, 0xB8, 0xB1, 0xE0, 0xB8, 0xA7, 0xE0, 0xB9, 0x80, 0xE0, 0xB8, 0xA5, 0xE0, 0xB8, 0x82 }, new byte[] { 69 }, new byte[] { 101 }, }; var thaiUtf8ParsingTrie = new EncodingData.TrieNode[] { new EncodingData.TrieNode { valueOrNumChildren = 4, index = 0 }, new EncodingData.TrieNode { valueOrNumChildren = 43, index = 5 }, new EncodingData.TrieNode { valueOrNumChildren = 69, index = 6 }, new EncodingData.TrieNode { valueOrNumChildren = 101, index = 7 }, new EncodingData.TrieNode { valueOrNumChildren = 0xE0, index = 8 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 14 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 16 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 16 }, new EncodingData.TrieNode { valueOrNumChildren = 2, index = 0 }, new EncodingData.TrieNode { valueOrNumChildren = 0xB8, index = 11 }, new EncodingData.TrieNode { valueOrNumChildren = 0xB9, index = 15 }, new EncodingData.TrieNode { valueOrNumChildren = 3, index = 0 }, new EncodingData.TrieNode { valueOrNumChildren = 0x88, index = 27 }, new EncodingData.TrieNode { valueOrNumChildren = 0xA5, index = 28 }, new EncodingData.TrieNode { valueOrNumChildren = 0xAA, index = 29 }, new EncodingData.TrieNode { valueOrNumChildren = 11, index = -1878877941 /* 0x9002990B */ }, new EncodingData.TrieNode { valueOrNumChildren = 0x84, index = 30 }, new EncodingData.TrieNode { valueOrNumChildren = 0x90, index = 31 }, new EncodingData.TrieNode { valueOrNumChildren = 0x91, index = 32 }, new EncodingData.TrieNode { valueOrNumChildren = 0x92, index = 33 }, new EncodingData.TrieNode { valueOrNumChildren = 0x93, index = 34 }, new EncodingData.TrieNode { valueOrNumChildren = 0x94, index = 35 }, new EncodingData.TrieNode { valueOrNumChildren = 0x95, index = 36 }, new EncodingData.TrieNode { valueOrNumChildren = 0x96, index = 37 }, new EncodingData.TrieNode { valueOrNumChildren = 0x97, index = 38 }, new EncodingData.TrieNode { valueOrNumChildren = 0x98, index = 39 }, new EncodingData.TrieNode { valueOrNumChildren = 0x99, index = 40 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 10 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 13 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 12 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 15 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 0 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 1 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 2 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 3 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 4 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 5 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 6 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 7 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 8 }, new EncodingData.TrieNode { valueOrNumChildren = 0, index = 9 }, }; EncodingData fd = new EncodingData(thaiUtf8DigitsAndSymbols, thaiUtf8ParsingTrie, EncodingData.Encoding.Utf8); Format.Parsed nf = new Format.Parsed('R'); bool result = PrimitiveParser.TryParseInt64(UtfEncode(text, false), index, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); }
[InlineData("1.6540654e100000", false, 0, 0, 0)] // overflow test public void ParseUtf8ByteArrayToDouble(string text, bool expectSuccess, int index, double expectedValue, int expectedBytesConsumed) { double parsedValue; int bytesConsumed; EncodingData fd = EncodingData.InvariantUtf8; Format.Parsed nf = new Format.Parsed('N'); bool result = PrimitiveParser.TryParseDouble(UtfEncode(text, false), index, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); }
public static bool TryFormat(this Guid value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten) { if (format.IsDefault) { format.Symbol = 'G'; } Precondition.Require(format.Symbol == 'G' || format.Symbol == 'D' || format.Symbol == 'N' || format.Symbol == 'B' || format.Symbol == 'P'); bool dash = true; char tail = '\0'; bytesWritten = 0; switch (format.Symbol) { case 'D': case 'G': break; case 'N': dash = false; break; case 'B': if (!TryWriteChar('{', buffer, formattingData, ref bytesWritten)) { return false; } tail = '}'; break; case 'P': if (!TryWriteChar('(', buffer, formattingData, ref bytesWritten)) { return false; } tail = ')'; break; default: Precondition.Require(false); // how did we get here? break; } var byteFormat = new Format.Parsed('x', 2); unsafe { byte* bytes = (byte*)&value; if (!TryWriteByte(bytes[3], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[2], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[1], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[0], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (dash) { if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; } } if (!TryWriteByte(bytes[5], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[4], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (dash) { if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; } } if (!TryWriteByte(bytes[7], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[6], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (dash) { if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; } } if (!TryWriteByte(bytes[8], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[9], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (dash) { if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; } } if (!TryWriteByte(bytes[10], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[11], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[12], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[13], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[14], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } if (!TryWriteByte(bytes[15], buffer, byteFormat, formattingData, ref bytesWritten)) { return false; } } if (tail != '\0') { if (!TryWriteChar(tail, buffer, formattingData, ref bytesWritten)) { return false; } } return true; }
[InlineData("-2147483649", false, 0, 0, 0)] // negative overflow test public void ParseUtf8SpanToInt(string text, bool expectSuccess, int index, int expectedValue, int expectedBytesConsumed) { int parsedValue; int bytesConsumed; EncodingData fd = EncodingData.InvariantUtf8; Format.Parsed nf = new Format.Parsed('N'); var span = UtfEncode(text, false).Slice(index); bool result = PrimitiveParser.TryParseInt32(span, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); }
[InlineData("-129", false, 0, 0, 0)] // negative overflow test public void ParseUtf16ByteArrayToSbyte(string text, bool expectSuccess, int index, sbyte expectedValue, int expectedBytesConsumed) { sbyte parsedValue; int bytesConsumed; FormattingData fd = FormattingData.InvariantUtf16; Format.Parsed nf = new Format.Parsed('N'); bool result = InvariantParser.TryParse(UtfEncode(text, true), index, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); }
[InlineData("18446744073709551616", false, 0, 0, 0)] // overflow test public unsafe void ParseUtf8ByteArrayToUlong(string text, bool expectSuccess, int index, ulong expectedValue, int expectedBytesConsumed) { ulong parsedValue; int bytesConsumed; FormattingData fd = FormattingData.InvariantUtf8; Format.Parsed nf = new Format.Parsed('R'); bool result = InvariantParser.TryParse(UtfEncode(text, false), index, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); }
[InlineData("65536", false, 0, 0, 0)] // overflow test public unsafe void ParseUtf8ByteStarToUshort(string text, bool expectSuccess, int index, ushort expectedValue, int expectedBytesConsumed) { ushort parsedValue; int bytesConsumed; byte[] textBytes = UtfEncode(text, false); FormattingData fd = FormattingData.InvariantUtf8; Format.Parsed nf = new Format.Parsed('R'); fixed (byte* arrayPointer = textBytes) { bool result = InvariantParser.TryParse(arrayPointer, index, textBytes.Length, fd, nf, out parsedValue, out bytesConsumed); Assert.Equal(expectSuccess, result); Assert.Equal(expectedValue, parsedValue); Assert.Equal(expectedBytesConsumed, bytesConsumed); } }
public static bool TryFormat(this float value, Span <byte> buffer, Span <char> format, FormattingData formattingData, out int bytesWritten) { Format.Parsed parsedFormat = Format.Parse(format); return(TryFormat(value, buffer, parsedFormat, formattingData, out bytesWritten)); }
public unsafe static bool TryParseSingle(byte *text, int index, int length, EncodingData encoding, Format.Parsed format, out float value, out int bytesConsumed) { // Precondition replacement if (length < 1 || index < 0) { value = 0; bytesConsumed = 0; return(false); } value = 0f; bytesConsumed = 0; if (encoding.IsInvariantUtf8) { string floatString = ""; bool decimalPlace = false, e = false, signed = false, digitLast = false, eLast = false; if ((length) >= 3 && text[index] == 'N' && text[index + 1] == 'a' && text[index + 2] == 'N') { value = float.NaN; bytesConsumed = 3; return(true); } if (text[index] == '-' || text[index] == '+') { signed = true; floatString += (char)text[index]; index++; bytesConsumed++; } if ((length - index) >= 8 && text[index] == 'I' && text[index + 1] == 'n' && text[index + 2] == 'f' && text[index + 3] == 'i' && text[index + 4] == 'n' && text[index + 5] == 'i' && text[index + 6] == 't' && text[index + 7] == 'y') { if (signed && text[index - 1] == '-') { value = float.NegativeInfinity; } else { value = float.PositiveInfinity; } bytesConsumed += 8; return(true); } for (int byteIndex = index; byteIndex < length; byteIndex++) { byte nextByte = text[byteIndex]; byte nextByteVal = (byte)(nextByte - '0'); if (nextByteVal > 9) { if (!decimalPlace && nextByte == '.') { if (digitLast) { digitLast = false; } if (eLast) { eLast = false; } bytesConsumed++; decimalPlace = true; floatString += (char)nextByte; } else if (!e && nextByte == 'e' || nextByte == 'E') { e = true; eLast = true; bytesConsumed++; floatString += (char)nextByte; } else if (eLast && nextByte == '+' || nextByte == '-') { eLast = false; bytesConsumed++; floatString += (char)nextByte; } else if ((decimalPlace && signed && bytesConsumed == 2) || ((signed || decimalPlace) && bytesConsumed == 1)) { value = 0; bytesConsumed = 0; return(false); } else { if (float.TryParse(floatString, out value)) { return(true); } else { bytesConsumed = 0; return(false); } } } else { if (eLast) { eLast = false; } if (!digitLast) { digitLast = true; } bytesConsumed++; floatString += (char)nextByte; } } if ((decimalPlace && signed && bytesConsumed == 2) || ((signed || decimalPlace) && bytesConsumed == 1)) { value = 0; bytesConsumed = 0; return(false); } else { if (float.TryParse(floatString, out value)) { return(true); } else { bytesConsumed = 0; return(false); } } } return(false); }