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