コード例 #1
0
        public static bool TryParseBoolean(ReadOnlySpan <byte> text, out bool value, out int bytesConsumed, EncodingData encoding = default(EncodingData))
        {
            bytesConsumed = 0;
            value         = default(bool);

            if (encoding.IsInvariantUtf8)
            {
                return(InvariantUtf8.TryParseBoolean(text, out value, out bytesConsumed));
            }
            if (encoding.IsInvariantUtf16)
            {
                ReadOnlySpan <char> textChars = text.Cast <byte, char>();
                int  charactersConsumed;
                bool result = InvariantUtf16.TryParseBoolean(textChars, out value, out charactersConsumed);
                bytesConsumed = charactersConsumed * 2;
                return(result);
            }

            return(false);
        }
コード例 #2
0
        public static bool TryParseBoolean(ReadOnlySpan <byte> text, out bool value, out int bytesConsumed, TextEncoder encoder = null)
        {
            encoder = encoder == null ? TextEncoder.Utf8 : encoder;

            bytesConsumed = 0;
            value         = default(bool);

            if (encoder.IsInvariantUtf8)
            {
                return(InvariantUtf8.TryParseBoolean(text, out value, out bytesConsumed));
            }
            if (encoder.IsInvariantUtf16)
            {
                ReadOnlySpan <char> textChars = text.Cast <byte, char>();
                int  charactersConsumed;
                bool result = InvariantUtf16.TryParseBoolean(textChars, out value, out charactersConsumed);
                bytesConsumed = charactersConsumed * sizeof(char);
                return(result);
            }

            return(false);
        }
コード例 #3
0
        public static bool TryParseDecimal(ReadOnlySpan <byte> text, out decimal value, out int bytesConsumed, SymbolTable symbolTable = null)
        {
            symbolTable = symbolTable ?? SymbolTable.InvariantUtf8;

            bytesConsumed = 0;
            value         = default;

            if (symbolTable == SymbolTable.InvariantUtf8)
            {
                return(InvariantUtf8.TryParseDecimal(text, out value, out bytesConsumed));
            }
            else if (symbolTable == SymbolTable.InvariantUtf16)
            {
                ReadOnlySpan <char> textChars = text.NonPortableCast <byte, char>();
                int  charactersConsumed;
                bool result = InvariantUtf16.TryParseDecimal(textChars, out value, out charactersConsumed);
                bytesConsumed = charactersConsumed * sizeof(char);
                return(result);
            }

            return(false);
        }
コード例 #4
0
ファイル: Signed.cs プロジェクト: aggieben/corefxlab
        public static bool TryParseInt64(ReadOnlySpan <byte> text, out long value, out int bytesConsumed, EncodingData encoding = default(EncodingData), TextFormat format = default(TextFormat))
        {
            if (format.HasPrecision)
            {
                throw new NotImplementedException("Format with precision not supported.");
            }

            if (encoding.IsInvariantUtf8)
            {
                if (format.IsHexadecimal)
                {
                    return(InvariantUtf8.Hex.TryParseInt64(text, out value, out bytesConsumed));
                }
                else
                {
                    return(InvariantUtf8.TryParseInt64(text, out value, out bytesConsumed));
                }
            }
            else if (encoding.IsInvariantUtf16)
            {
                ReadOnlySpan <char> utf16Text = text.Cast <byte, char>();
                int  charsConsumed;
                bool result;
                if (format.IsHexadecimal)
                {
                    result = InvariantUtf16.Hex.TryParseInt64(utf16Text, out value, out charsConsumed);
                }
                else
                {
                    result = InvariantUtf16.TryParseInt64(utf16Text, out value, out charsConsumed);
                }
                bytesConsumed = charsConsumed * sizeof(char);
                return(result);
            }

            if (format.IsHexadecimal)
            {
                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));
            }

            uint nextSymbol;
            int  thisSymbolConsumed;

            if (!encoding.TryParseSymbol(text, out nextSymbol, out thisSymbolConsumed))
            {
                value         = default(long);
                bytesConsumed = 0;
                return(false);
            }

            int sign = 1;

            if ((EncodingData.Symbol)nextSymbol == EncodingData.Symbol.MinusSign)
            {
                sign = -1;
            }

            int signConsumed = 0;

            if ((EncodingData.Symbol)nextSymbol == EncodingData.Symbol.PlusSign || (EncodingData.Symbol)nextSymbol == EncodingData.Symbol.MinusSign)
            {
                signConsumed = thisSymbolConsumed;
                if (!encoding.TryParseSymbol(text.Slice(signConsumed), out nextSymbol, out thisSymbolConsumed))
                {
                    value         = default(long);
                    bytesConsumed = 0;
                    return(false);
                }
            }

            if (nextSymbol > 9)
            {
                value         = default(long);
                bytesConsumed = 0;
                return(false);
            }

            long parsedValue = (long)nextSymbol;
            int  index       = signConsumed + thisSymbolConsumed;

            while (index < text.Length)
            {
                bool success = encoding.TryParseSymbol(text.Slice(index), out nextSymbol, out thisSymbolConsumed);
                if (!success || nextSymbol > 9)
                {
                    bytesConsumed = index;
                    value         = (long)(parsedValue * sign);
                    return(true);
                }

                // If parsedValue > (long.MaxValue / 10), any more appended digits will cause overflow.
                // if parsedValue == (long.MaxValue / 10), any nextDigit greater than 7 or 8 (depending on sign) implies overflow.
                bool positive          = sign > 0;
                bool nextDigitTooLarge = nextSymbol > 8 || (positive && nextSymbol > 7);
                if (parsedValue > long.MaxValue / 10 || (parsedValue == long.MaxValue / 10 && nextDigitTooLarge))
                {
                    bytesConsumed = 0;
                    value         = default(long);
                    return(false);
                }

                index      += thisSymbolConsumed;
                parsedValue = parsedValue * 10 + (long)nextSymbol;
            }

            bytesConsumed = text.Length;
            value         = (long)(parsedValue * sign);
            return(true);
        }
コード例 #5
0
ファイル: Unsigned.cs プロジェクト: tmds/corefxlab
        public static bool TryParseUInt64(ReadOnlySpan <byte> text, out ulong value, out int bytesConsumed, TextFormat format = default(TextFormat), TextEncoder encoder = null)
        {
            encoder = encoder == null ? TextEncoder.Utf8 : encoder;

            if (!format.IsDefault && format.HasPrecision)
            {
                throw new NotImplementedException("Format with precision not supported.");
            }

            if (encoder.IsInvariantUtf8)
            {
                if (format.IsHexadecimal)
                {
                    return(InvariantUtf8.Hex.TryParseUInt64(text, out value, out bytesConsumed));
                }
                else
                {
                    return(InvariantUtf8.TryParseUInt64(text, out value, out bytesConsumed));
                }
            }
            else if (encoder.IsInvariantUtf16)
            {
                ReadOnlySpan <char> utf16Text = text.Cast <byte, char>();
                int  charsConsumed;
                bool result;
                if (format.IsHexadecimal)
                {
                    result = InvariantUtf16.Hex.TryParseUInt64(utf16Text, out value, out charsConsumed);
                }
                else
                {
                    result = InvariantUtf16.TryParseUInt64(utf16Text, out value, out charsConsumed);
                }
                bytesConsumed = charsConsumed * sizeof(char);
                return(result);
            }

            if (format.IsHexadecimal)
            {
                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));
            }

            uint nextSymbol;
            int  thisSymbolConsumed;

            if (!encoder.TryParseSymbol(text, out nextSymbol, out thisSymbolConsumed))
            {
                value         = default(ulong);
                bytesConsumed = 0;
                return(false);
            }

            if (nextSymbol > 9)
            {
                value         = default(ulong);
                bytesConsumed = 0;
                return(false);
            }

            ulong parsedValue = nextSymbol;
            int   index       = thisSymbolConsumed;

            while (index < text.Length)
            {
                bool success = encoder.TryParseSymbol(text.Slice(index), out nextSymbol, out thisSymbolConsumed);
                if (!success || nextSymbol > 9)
                {
                    bytesConsumed = index;
                    value         = (ulong)parsedValue;
                    return(true);
                }

                // If parsedValue > (ulong.MaxValue / 10), any more appended digits will cause overflow.
                // if parsedValue == (ulong.MaxValue / 10), any nextDigit greater than 5 implies overflow.
                if (parsedValue > ulong.MaxValue / 10 || (parsedValue == ulong.MaxValue / 10 && nextSymbol > 5))
                {
                    bytesConsumed = 0;
                    value         = default(ulong);
                    return(false);
                }

                index      += thisSymbolConsumed;
                parsedValue = parsedValue * 10 + nextSymbol;
            }

            bytesConsumed = text.Length;
            value         = (ulong)parsedValue;
            return(true);
        }
コード例 #6
0
        public static bool TryParseByte(ReadOnlySpan <byte> text, out byte value, out int bytesConsumed, TextFormat 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 (format.IsHexadecimal)
                {
                    return(InvariantUtf8.Hex.TryParseByte(text, out value, out bytesConsumed));
                }
                else
                {
                    return(InvariantUtf8.TryParseByte(text, out value, out bytesConsumed));
                }
            }
            else if (symbolTable == SymbolTable.InvariantUtf16)
            {
                ReadOnlySpan <char> utf16Text = text.NonPortableCast <byte, char>();
                int  charsConsumed;
                bool result;
                if (format.IsHexadecimal)
                {
                    result = InvariantUtf16.Hex.TryParseByte(utf16Text, out value, out charsConsumed);
                }
                else
                {
                    result = InvariantUtf16.TryParseByte(utf16Text, out value, out charsConsumed);
                }
                bytesConsumed = charsConsumed * sizeof(char);
                return(result);
            }

            if (format.IsHexadecimal)
            {
                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));
            }

            SymbolTable.Symbol nextSymbol;
            int thisSymbolConsumed;

            if (!symbolTable.TryParse(text, out nextSymbol, out 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         = (byte)parsedValue;
                    return(true);
                }

                // If parsedValue > (byte.MaxValue / 10), any more appended digits will cause overflow.
                // if parsedValue == (byte.MaxValue / 10), any nextDigit greater than 5 implies overflow.
                if (parsedValue > byte.MaxValue / 10 || (parsedValue == byte.MaxValue / 10 && nextSymbol > SymbolTable.Symbol.D5))
                {
                    bytesConsumed = 0;
                    value         = default;
                    return(false);
                }

                index      += thisSymbolConsumed;
                parsedValue = parsedValue * 10 + (uint)nextSymbol;
            }

            bytesConsumed = text.Length;
            value         = (byte)parsedValue;
            return(true);
        }
コード例 #7
0
        public static bool TryParseInt32(ReadOnlySpan <byte> text, out int value, out int bytesConsumed, TextFormat format = default, SymbolTable symbolTable = null)
        {
            bool isDefault = format.IsDefault;

            symbolTable = symbolTable ?? SymbolTable.InvariantUtf8;

            if (!isDefault && format.HasPrecision)
            {
                throw new NotImplementedException("Format with precision not supported.");
            }

            bool isHex = format.IsHexadecimal;

            if (symbolTable == SymbolTable.InvariantUtf8)
            {
                return(isHex ? InvariantUtf8.Hex.TryParseInt32(text, out value, out bytesConsumed) :
                       InvariantUtf8.TryParseInt32(text, out value, out bytesConsumed));
            }
            else if (symbolTable == SymbolTable.InvariantUtf16)
            {
                /*return isHex ? InvariantUtf16.Hex.TryParseInt32(text, out value, out bytesConsumed) :
                 *  InvariantUtf16.TryParseInt32(text, out value, out bytesConsumed);*/
                ReadOnlySpan <char> utf16Text = text.NonPortableCast <byte, char>();
                bool result = isHex ? InvariantUtf16.Hex.TryParseInt32(utf16Text, out value, out int charsConsumed) :
                              InvariantUtf16.TryParseInt32(utf16Text, out value, out charsConsumed);
                bytesConsumed = charsConsumed * sizeof(char);
                return(result);
            }

            if (isHex)
            {
                throw new NotImplementedException("The only supported encodings for hexadecimal parsing are InvariantUtf8 and InvariantUtf16.");
            }

            if (!(isDefault || format.Symbol == 'G' || format.Symbol == 'g'))
            {
                throw new NotImplementedException(String.Format("Format '{0}' not supported.", format.Symbol));
            }

            int textLength = text.Length;

            if (textLength < 1)
            {
                goto FalseExit;
            }

            if (!symbolTable.TryParse(text, out SymbolTable.Symbol symbol, out int consumed))
            {
                goto FalseExit;
            }

            sbyte sign  = 1;
            int   index = 0;

            if (symbol == SymbolTable.Symbol.MinusSign)
            {
                sign   = -1;
                index += consumed;
                if (index >= textLength)
                {
                    goto FalseExit;
                }
                if (!symbolTable.TryParse(text.Slice(index), out symbol, out consumed))
                {
                    goto FalseExit;
                }
            }
            else if (symbol == SymbolTable.Symbol.PlusSign)
            {
                index += consumed;
                if (index >= textLength)
                {
                    goto FalseExit;
                }
                if (!symbolTable.TryParse(text.Slice(index), out symbol, out consumed))
                {
                    goto FalseExit;
                }
            }

            int answer = 0;

            if (IsValid(symbol))
            {
                int numBytes = consumed;
                if (symbol == SymbolTable.Symbol.D0)
                {
                    do
                    {
                        index += consumed;
                        if (index >= textLength)
                        {
                            goto Done;
                        }
                        if (!symbolTable.TryParse(text.Slice(index), out symbol, out consumed))
                        {
                            goto Done;
                        }
                    } while (symbol == SymbolTable.Symbol.D0);
                    if (!IsValid(symbol))
                    {
                        goto Done;
                    }
                }

                int firstNonZeroDigitIndex = index;
                if (textLength - firstNonZeroDigitIndex < Int32OverflowLength * numBytes)
                {
                    do
                    {
                        answer = answer * 10 + (int)symbol;
                        index += consumed;
                        if (index >= textLength)
                        {
                            goto Done;
                        }
                        if (!symbolTable.TryParse(text.Slice(index), out symbol, out consumed))
                        {
                            goto Done;
                        }
                    } while (IsValid(symbol));
                }
                else
                {
                    do
                    {
                        answer = answer * 10 + (int)symbol;
                        index += consumed;
                        if (index - firstNonZeroDigitIndex == (Int32OverflowLength - 1) * numBytes)
                        {
                            if (!symbolTable.TryParse(text.Slice(index), out symbol, out consumed))
                            {
                                goto Done;
                            }
                            if (IsValid(symbol))
                            {
                                if (WillOverFlow(answer, (int)symbol, sign))
                                {
                                    goto FalseExit;
                                }
                                answer = answer * 10 + (int)symbol;
                                index += consumed;
                            }
                            goto Done;
                        }
                        if (!symbolTable.TryParse(text.Slice(index), out symbol, out consumed))
                        {
                            goto Done;
                        }
                    } while (IsValid(symbol));
                }
                goto Done;
            }

FalseExit:
            bytesConsumed = 0;
            value         = 0;
            return(false);

Done:
            bytesConsumed = index;
            value         = answer * sign;
            return(true);
        }
コード例 #8
0
        public static bool TryParseInt16(ReadOnlySpan <byte> text, out short value, out int bytesConsumed, ParsedFormat 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 (IsHexFormat(format))
                {
                    return(InvariantUtf8.Hex.TryParseInt16(text, out value, out bytesConsumed));
                }
                else
                {
                    return(InvariantUtf8.TryParseInt16(text, out value, out bytesConsumed));
                }
            }
            else if (symbolTable == SymbolTable.InvariantUtf16)
            {
                ReadOnlySpan <char> utf16Text = text.NonPortableCast <byte, char>();
                int  charsConsumed;
                bool result;
                if (IsHexFormat(format))
                {
                    result = InvariantUtf16.Hex.TryParseInt16(utf16Text, out value, out charsConsumed);
                }
                else
                {
                    result = InvariantUtf16.TryParseInt16(utf16Text, out value, out charsConsumed);
                }
                bytesConsumed = charsConsumed * sizeof(char);
                return(result);
            }

            if (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));
            }

            SymbolTable.Symbol nextSymbol;
            int thisSymbolConsumed;

            if (!symbolTable.TryParse(text, out nextSymbol, out thisSymbolConsumed))
            {
                value         = default;
                bytesConsumed = 0;
                return(false);
            }

            int sign = 1;

            if ((SymbolTable.Symbol)nextSymbol == SymbolTable.Symbol.MinusSign)
            {
                sign = -1;
            }

            int signConsumed = 0;

            if (nextSymbol == SymbolTable.Symbol.PlusSign || nextSymbol == SymbolTable.Symbol.MinusSign)
            {
                signConsumed = thisSymbolConsumed;
                if (!symbolTable.TryParse(text.Slice(signConsumed), out nextSymbol, out thisSymbolConsumed))
                {
                    value         = default;
                    bytesConsumed = 0;
                    return(false);
                }
            }

            if (nextSymbol > SymbolTable.Symbol.D9)
            {
                value         = default;
                bytesConsumed = 0;
                return(false);
            }

            int parsedValue = (int)nextSymbol;
            int index       = signConsumed + 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         = (short)(parsedValue * sign);
                    return(true);
                }

                // If parsedValue > (short.MaxValue / 10), any more appended digits will cause overflow.
                // if parsedValue == (short.MaxValue / 10), any nextDigit greater than 7 or 8 (depending on sign) implies overflow.
                bool positive          = sign > 0;
                bool nextDigitTooLarge = nextSymbol > SymbolTable.Symbol.D8 || (positive && nextSymbol > SymbolTable.Symbol.D7);
                if (parsedValue > short.MaxValue / 10 || (parsedValue == short.MaxValue / 10 && nextDigitTooLarge))
                {
                    bytesConsumed = 0;
                    value         = default;
                    return(false);
                }

                index      += thisSymbolConsumed;
                parsedValue = parsedValue * 10 + (int)nextSymbol;
            }

            bytesConsumed = text.Length;
            value         = (short)(parsedValue * sign);
            return(true);
        }