Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }