public static bool TryFormat(this DateTime value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (format.IsDefault)
            {
                format.Symbol = 'G';
            }
            Precondition.Require(format.Symbol == 'R' || format.Symbol == 'O' || format.Symbol == 'G');

            switch (format.Symbol)
            {
                case 'R':
                    var utc = value.ToUniversalTime();
                    if (formattingData.IsUtf16)
                    {
                        return TryFormatDateTimeRfc1123(utc, buffer, EncodingData.InvariantUtf16, out bytesWritten);
                    }
                    else
                    {
                        return TryFormatDateTimeRfc1123(utc, buffer, EncodingData.InvariantUtf8, out bytesWritten);
                    }
                case 'O':
                    if (formattingData.IsUtf16)
                    {
                        return TryFormatDateTimeFormatO(value, true, buffer, EncodingData.InvariantUtf16, out bytesWritten);
                    }
                    else
                    {
                        return TryFormatDateTimeFormatO(value, true, buffer, EncodingData.InvariantUtf8, out bytesWritten);
                    }
                case 'G':
                    return TryFormatDateTimeFormagG(value, buffer, formattingData, out bytesWritten);
                default:
                    throw new NotImplementedException();
            }      
        }
        public static bool TryFormat(this DateTimeOffset value, Span<byte> buffer, TextFormat format, EncodingData formattingData, out int bytesWritten)
        {
            if (format.IsDefault)
            {
                format.Symbol = 'G';
            }
            Precondition.Require(format.Symbol == 'R' || format.Symbol == 'O' || format.Symbol == 'G');
            switch (format.Symbol)
            {
                case 'R':

                    if (formattingData.IsInvariantUtf16) // TODO: there are many checks like this one in the code. They need to also verify that the UTF8 branch is invariant.
                    {
                        return TryFormatDateTimeRfc1123(value.UtcDateTime, buffer, EncodingData.InvariantUtf16, out bytesWritten);
                    }
                    else
                    {
                        return TryFormatDateTimeRfc1123(value.UtcDateTime, buffer, EncodingData.InvariantUtf8, out bytesWritten);
                    }
                case 'O':
                    if (formattingData.IsInvariantUtf16)
                    {
                        return TryFormatDateTimeFormatO(value.UtcDateTime, false, buffer, EncodingData.InvariantUtf16, out bytesWritten);
                    }
                    else
                    {
                        return TryFormatDateTimeFormatO(value.UtcDateTime, false, buffer, EncodingData.InvariantUtf8, out bytesWritten);
                    }
                case 'G':
                    return TryFormatDateTimeFormagG(value.DateTime, buffer, formattingData, out bytesWritten);
                default:
                    throw new NotImplementedException();
            }
        }
Esempio n. 3
0
        internal static bool TryFormatInt64(long value, byte numberOfBytes, Span<byte> buffer, TextFormat format, EncodingData formattingData, out int bytesWritten)
        {
            Precondition.Require(numberOfBytes <= sizeof(long));

            if (value >= 0)
            {
                return TryFormatUInt64(unchecked((ulong)value), numberOfBytes, buffer, format, formattingData, out bytesWritten);
            }
            else if (format.IsHexadecimal)
            {
                ulong bitMask = GetBitMask(numberOfBytes);
                return TryFormatUInt64(unchecked((ulong)value) & bitMask, numberOfBytes, buffer, format, formattingData, out bytesWritten);
            }
            else
            {
                int minusSignBytes = 0;
                if(!formattingData.TryEncode(EncodingData.Symbol.MinusSign, buffer, out minusSignBytes))
                {
                    bytesWritten = 0;
                    return false;
                }

                int digitBytes = 0;
                if(!TryFormatUInt64(unchecked((ulong)-value), numberOfBytes, buffer.Slice(minusSignBytes), format, formattingData, out digitBytes))
                {
                    bytesWritten = 0;
                    return false;
                }
                bytesWritten = digitBytes + minusSignBytes;
                return true;
            }
        }
Esempio n. 4
0
        // TODO: format should be ReadOnlySpan<char>
        internal static bool TryFormatInt64(long value, byte numberOfBytes, Span<byte> buffer, ReadOnlySpan<char> format, EncodingData formattingData, out int bytesWritten)
        {
            Precondition.Require(numberOfBytes <= sizeof(long));

            TextFormat parsedFormat = TextFormat.Parse(format);
            return TryFormatInt64(value, numberOfBytes, buffer, parsedFormat, formattingData, out bytesWritten);
        }
Esempio n. 5
0
        internal static bool TryFormatUInt64(ulong value, byte numberOfBytes, Span<byte> buffer, TextFormat format, EncodingData formattingData, out int bytesWritten)
        {
            if(format.Symbol == 'g')
            {
                format.Symbol = 'G';
            }

            if (format.IsHexadecimal && formattingData.IsInvariantUtf16) {
                return TryFormatHexadecimalInvariantCultureUtf16(value, buffer, format, out bytesWritten);
            }

            if (format.IsHexadecimal && formattingData.IsInvariantUtf8) {
                return TryFormatHexadecimalInvariantCultureUtf8(value, buffer, format, out bytesWritten);
            }

            if ((formattingData.IsInvariantUtf16) && (format.Symbol == 'D' || format.Symbol == 'G')) {
                return TryFormatDecimalInvariantCultureUtf16(value, buffer, format, out bytesWritten);
            }

            if ((formattingData.IsInvariantUtf8) && (format.Symbol == 'D' || format.Symbol == 'G')) {
                return TryFormatDecimalInvariantCultureUtf8(value, buffer, format, out bytesWritten);
            }

            return TryFormatDecimal(value, buffer, format, formattingData, out bytesWritten);     
        }
Esempio n. 6
0
        // Sets up cultures with digits represented by 1 or 5 'A's (0) through 1 or 5 'J's (9) and the minus sigh represented by an underscore followed by a question mark
        static CustomCultureTests()
        {
            byte[][] utf16digitsAndSymbols = new byte[17][];
            for (ushort digit = 0; digit < 10; digit++)
            {
                char digitChar = (char)(digit + 'A');
                var digitString = new string(digitChar, 5);
                utf16digitsAndSymbols[digit] = GetBytesUtf16(digitString);
            }
            utf16digitsAndSymbols[(ushort)EncodingData.Symbol.DecimalSeparator] = GetBytesUtf16(".");
            utf16digitsAndSymbols[(ushort)EncodingData.Symbol.GroupSeparator] = GetBytesUtf16(",");
            utf16digitsAndSymbols[(ushort)EncodingData.Symbol.MinusSign] = GetBytesUtf16("_?");
            Culture5 = new EncodingData(utf16digitsAndSymbols, EncodingData.Encoding.Utf16);

            utf16digitsAndSymbols = new byte[17][];
            for (ushort digit = 0; digit < 10; digit++)
            {
                char digitChar = (char)(digit + 'A');
                var digitString = new string(digitChar, 1);
                utf16digitsAndSymbols[digit] = GetBytesUtf16(digitString);
            }
            utf16digitsAndSymbols[(ushort)EncodingData.Symbol.DecimalSeparator] = GetBytesUtf16(".");
            utf16digitsAndSymbols[(ushort)EncodingData.Symbol.GroupSeparator] = GetBytesUtf16(",");
            utf16digitsAndSymbols[(ushort)EncodingData.Symbol.MinusSign] = GetBytesUtf16("_?");
            Culture1 = new EncodingData(utf16digitsAndSymbols, EncodingData.Encoding.Utf16);
        }
 public static bool TryFormat(this float value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
 {
     if (format.IsDefault)
     {
         format.Symbol = 'G';
     }
     Precondition.Require(format.Symbol == 'G');
     return FloatFormatter.TryFormatNumber(value, true, buffer, format, formattingData, out bytesWritten);
 }
Esempio n. 8
0
 public StreamFormatter(Stream stream, EncodingData encoding, ArrayPool<byte> pool, int bufferSize = 256)
 {
     _pool = pool;
     _buffer = null;
     if (bufferSize > 0)
     {
         _buffer = _pool.Rent(bufferSize);
     }
     _encoding = encoding;
     _stream = stream;
 }
Esempio n. 9
0
        public static bool TryFormat(this char value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (formattingData.IsUtf16)
            {
                if (buffer.Length < 2)
                {
                    bytesWritten = 0;
                    return false;
                }
                buffer[0] = (byte)value;
                buffer[1] = (byte)(value >> 8);
                bytesWritten = 2;
                return true;
            }

            if (buffer.Length < 1)
            {
                bytesWritten = 0;
                return false;
            }

            // fast path for ASCII
            if (value <= 127)
            {
                buffer[0] = (byte)value;
                bytesWritten = 1;
                return true;
            }

            // TODO: This can be directly encoded to SpanByte. There is no conversion between spans yet
            var encoded = new Utf8EncodedCodePoint(value);
            bytesWritten = encoded.Length;
            if (buffer.Length < bytesWritten)
            {
                bytesWritten = 0;
                return false;
            }

            buffer[0] = encoded.Byte0;
            if(bytesWritten > 1)
            {
                buffer[1] = encoded.Byte1;
            }
            if(bytesWritten > 2)
            {
                buffer[2] = encoded.Byte2;
            }
            if(bytesWritten > 3)
            {
                buffer[3] = encoded.Byte3;
            }
            return true;
        }
Esempio n. 10
0
        public bool TryFormat(Span<byte> buffer, Format.Parsed format, EncodingData encoding, out int bytesWritten)
        {
            if (!PrimitiveFormatter.TryFormat(_age, buffer, format, encoding, out bytesWritten)) return false;


            char symbol = _inMonths ? 'm' : 'y';
            int symbolBytes;
            if (!PrimitiveFormatter.TryFormat(symbol, buffer.Slice(bytesWritten), format, encoding, out symbolBytes)) return false;

            bytesWritten += symbolBytes;
            return true;
        }
        public bool TryFormat(Span<byte> buffer, out int bytesWritten, TextFormat format, EncodingData encoding)
        {
            if (!PrimitiveFormatter.TryFormat(_age, buffer, out bytesWritten, format, encoding)) return false;


            char symbol = _inMonths ? 'm' : 'y';
            int symbolBytes;
            if (!PrimitiveFormatter.TryEncode(symbol, buffer.Slice(bytesWritten), out symbolBytes, encoding.TextEncoding)) return false;

            bytesWritten += symbolBytes;
            return true;
        }
        public static bool TryParseDecimal(ReadOnlySpan<byte> text, out decimal value, out int bytesConsumed, EncodingData encoding = default(EncodingData))
        {
            bytesConsumed = 0;
            value = default(decimal);

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

            return false;
        }
Esempio n. 13
0
        public static bool TryFormatNumber(double value, bool isSingle, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            Precondition.Require(format.Symbol == 'G' || format.Symbol == 'E' || format.Symbol == 'F');

            bytesWritten = 0;
            int written;

            if (Double.IsNaN(value))
            {
                return formattingData.TryWriteSymbol(EncodingData.Symbol.NaN, buffer, out bytesWritten);
            }

            if (Double.IsInfinity(value))
            {
                if (Double.IsNegativeInfinity(value))
                {
                    if (!formattingData.TryWriteSymbol(EncodingData.Symbol.MinusSign, buffer, out written))
                    {
                        bytesWritten = 0;
                        return false;
                    }
                    bytesWritten += written;
                }
                if (!formattingData.TryWriteSymbol(EncodingData.Symbol.InfinitySign, buffer.Slice(bytesWritten), out written))
                {
                    bytesWritten = 0;
                    return false;
                }
                bytesWritten += written;
                return true;
            }

            // TODO: the lines below need to be replaced with properly implemented algorithm
            // the problem is the algorithm is complex, so I am commiting a stub for now
            var hack = value.ToString(format.Symbol.ToString());
            return hack.TryFormat(buffer, default(Format.Parsed), formattingData, out bytesWritten);
        }
Esempio n. 14
0
        internal static bool TryFormatInt64(long value, byte numberOfBytes, Span <byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            Precondition.Require(numberOfBytes <= sizeof(long));

            if (value >= 0)
            {
                return(TryFormatUInt64(unchecked ((ulong)value), numberOfBytes, buffer, format, formattingData, out bytesWritten));
            }
            else if (format.IsHexadecimal)
            {
                ulong bitMask = GetBitMask(numberOfBytes);
                return(TryFormatUInt64(unchecked ((ulong)value) & bitMask, numberOfBytes, buffer, format, formattingData, out bytesWritten));
            }
            else
            {
                int minusSignBytes = 0;
                if (!formattingData.TryWriteSymbol(EncodingData.Symbol.MinusSign, buffer, out minusSignBytes))
                {
                    bytesWritten = 0;
                    return(false);
                }

                int digitBytes = 0;
                if (!TryFormatUInt64(unchecked ((ulong)-value), numberOfBytes, buffer.Slice(minusSignBytes), format, formattingData, out digitBytes))
                {
                    bytesWritten = 0;
                    return(false);
                }
                bytesWritten = digitBytes + minusSignBytes;
                return(true);
            }
        }
Esempio n. 15
0
 public static bool TryFormat(this long value, Span <byte> buffer, out int bytesWritten, TextFormat format = default(TextFormat), EncodingData encoding = default(EncodingData))
 {
     return(IntegerFormatter.TryFormatInt64(value, 8, buffer, out bytesWritten, format, encoding));
 }
Esempio n. 16
0
        // TODO: this whole routine is too slow. It does div and mod twice, which are both costly (especially that some JITs cannot optimize it).
        // It does it twice to avoid reversing the formatted buffer, which can be tricky given it should handle arbitrary cultures.
        // One optimization I thought we could do is to do div/mod once and store digits in a temp buffer (but that would allocate). Modification to the idea would be to store the digits in a local struct
        // Another idea possibly worth tying would be to special case cultures that have constant digit size, and go back to the format + reverse buffer approach.
        private static bool TryFormatDecimal(ulong value, Span<byte> buffer, TextFormat format, EncodingData formattingData, out int bytesWritten)
        {
            if(format.IsDefault)
            {
                format.Symbol = 'G';
            }
            format.Symbol = Char.ToUpperInvariant(format.Symbol); // TODO: this is costly. I think the transformation should happen in Parse
            Precondition.Require(format.Symbol == 'D' || format.Symbol == 'G' || format.Symbol == 'N');

            // Reverse value on decimal basis, count digits and trailing zeros before the decimal separator
            ulong reversedValueExceptFirst = 0;
            var digitsCount = 1;
            var trailingZerosCount = 0;

            // We reverse the digits in numeric form because reversing encoded digits is hard and/or costly.
            // If value contains 20 digits, its reversed value will not fit into ulong size.
            // So reverse it till last digit (reversedValueExceptFirst will have all the digits except the first one).
            while (value >= 10)
            {
                var digit = value % 10UL;
                value = value / 10UL;

                if (reversedValueExceptFirst == 0 && digit == 0)
                {
                    trailingZerosCount++;
                }
                else
                {
                    reversedValueExceptFirst = reversedValueExceptFirst * 10UL + digit;
                    digitsCount++;
                }
            }

            bytesWritten = 0;
            int digitBytes;
            // If format is D and precision is greater than digitsCount + trailingZerosCount, append leading zeros
            if (format.Symbol == 'D' && format.HasPrecision)
            {
                var leadingZerosCount = format.Precision - digitsCount - trailingZerosCount;
                while (leadingZerosCount-- > 0)
                {
                    if (!formattingData.TryEncode(EncodingData.Symbol.D0, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return false;
                    }
                    bytesWritten += digitBytes;
                }
            }

            // Append first digit
            if (!formattingData.TryEncode((EncodingData.Symbol)value, buffer.Slice(bytesWritten), out digitBytes))
            {
                bytesWritten = 0;
                return false;
            }
            bytesWritten += digitBytes;
            digitsCount--;

            if (format.Symbol == 'N')
            {
                const int GroupSize = 3;

                // Count amount of digits before first group separator. It will be reset to groupSize every time digitsLeftInGroup == zero
                var digitsLeftInGroup = (digitsCount + trailingZerosCount) % GroupSize;
                if (digitsLeftInGroup == 0)
                {
                    if (digitsCount + trailingZerosCount > 0)
                    {
                        // There is a new group immediately after the first digit
                        if (!formattingData.TryEncode(EncodingData.Symbol.GroupSeparator, buffer.Slice(bytesWritten), out digitBytes))
                        {
                            bytesWritten = 0;
                            return false;
                        }
                        bytesWritten += digitBytes;
                    }
                    digitsLeftInGroup = GroupSize;
                }

                // Append digits
                while (reversedValueExceptFirst > 0)
                {
                    if (digitsLeftInGroup == 0)
                    {
                        if (!formattingData.TryEncode(EncodingData.Symbol.GroupSeparator, buffer.Slice(bytesWritten), out digitBytes))
                        {
                            bytesWritten = 0;
                            return false;
                        }
                        bytesWritten += digitBytes;
                        digitsLeftInGroup = GroupSize;
                    }

                    var nextDigit = reversedValueExceptFirst % 10UL;
                    reversedValueExceptFirst = reversedValueExceptFirst / 10UL;

                    if (!formattingData.TryEncode((EncodingData.Symbol)nextDigit, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return false;
                    }
                    bytesWritten += digitBytes;
                    digitsLeftInGroup--;
                }

                // Append trailing zeros if any
                while (trailingZerosCount-- > 0)
                {
                    if (digitsLeftInGroup == 0)
                    {
                        if (!formattingData.TryEncode(EncodingData.Symbol.GroupSeparator, buffer.Slice(bytesWritten), out digitBytes))
                        {
                            bytesWritten = 0;
                            return false;
                        }
                        bytesWritten += digitBytes;
                        digitsLeftInGroup = GroupSize;
                    }

                    if (!formattingData.TryEncode(EncodingData.Symbol.D0, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return false;
                    }
                    bytesWritten += digitBytes;
                    digitsLeftInGroup--;
                }
            }
            else
            {
                while (reversedValueExceptFirst > 0)
                {
                    var bufferSlice = buffer.Slice(bytesWritten);
                    var nextDigit = reversedValueExceptFirst % 10UL;
                    reversedValueExceptFirst = reversedValueExceptFirst / 10UL;
                    if (!formattingData.TryEncode((EncodingData.Symbol)nextDigit, bufferSlice, out digitBytes))
                    {
                        bytesWritten = 0;
                        return false;
                    }
                    bytesWritten += digitBytes;
                }

                // Append trailing zeros if any
                while (trailingZerosCount-- > 0)
                {
                    if (!formattingData.TryEncode(EncodingData.Symbol.D0, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return false;
                    }
                    bytesWritten += digitBytes;
                }
            }

            // If format is N and precision is not defined or is greater than zero, append trailing zeros after decimal point
            if (format.Symbol == 'N')
            {
                int trailingZerosAfterDecimalCount = format.HasPrecision ? format.Precision : 2;

                if (trailingZerosAfterDecimalCount > 0)
                {
                    if (!formattingData.TryEncode(EncodingData.Symbol.DecimalSeparator, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return false;
                    }
                    bytesWritten += digitBytes;

                    while (trailingZerosAfterDecimalCount-- > 0)
                    {
                        if (!formattingData.TryEncode(EncodingData.Symbol.D0, buffer.Slice(bytesWritten), out digitBytes))
                        {
                            bytesWritten = 0;
                            return false;
                        }
                        bytesWritten += digitBytes;
                    }
                }
            }

            return true;
        }
Esempio n. 17
0
        public static bool TryFormat(this Utf8String value, Span <byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (formattingData.IsUtf16)
            {
                bytesWritten = 0;
                int justWritten;
                foreach (var cp in value.CodePoints)
                {
                    if (!Utf16.Utf16LittleEndianEncoder.TryEncodeCodePoint(cp, buffer.Slice(bytesWritten), out justWritten))
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    bytesWritten += justWritten;
                }
                return(true);
            }

            if (buffer.Length < value.Length)
            {
                bytesWritten = 0;
                return(false);
            }

            buffer.Set(value.Bytes);
            bytesWritten = value.Length;
            return(true);
        }
Esempio n. 18
0
        [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);
        }
Esempio n. 19
0
        public static bool TryParseBoolean(ReadOnlySpan<byte> text, out bool value, out int consumedBytes, EncodingData encoding = default(EncodingData))
        {
            consumedBytes = 0;
            value = default(bool);
            if (text.Length < 1)
            {
                return false;
            }

            if (encoding.IsInvariantUtf8)
            {
                byte firstCodeUnit = text[0];

                if (firstCodeUnit == '1')
                {
                    consumedBytes = 1;
                    value = true;
                    return true;
                }
                else if (firstCodeUnit == '0')
                {
                    consumedBytes = 1;
                    value = false;
                    return true;
                }
                else if (IsTrue(text))
                {
                    consumedBytes = 4;
                    value = true;
                    return true;
                }
                else if (IsFalse(text))
                {
                    consumedBytes = 5;
                    value = false;
                    return true;
                }
                else
                {
                    return false;
                }
            }

            if (encoding.IsInvariantUtf16)
            {
                ReadOnlySpan<char> textChars = text.Cast<byte, char>();
                char firstCodeUnit = textChars[0];

                if (firstCodeUnit == '1')
                {
                    consumedBytes = 2;
                    value = true;
                    return true;
                }
                else if (firstCodeUnit == '0')
                {
                    consumedBytes = 2;
                    value = false;
                    return true;
                }
                else if (IsTrue(textChars))
                {
                    consumedBytes = 8;
                    value = true;
                    return true;
                }
                else if (IsFalse(textChars))
                {
                    consumedBytes = 10;
                    value = false;
                    return true;
                }
                else
                {
                    return false;
                }
            }

            return false;
        }
Esempio n. 20
0
 public static bool TryParseByte(ReadOnlySpan <byte> text, out byte value, out int bytesConsumed, EncodingData encoding = default(EncodingData), TextFormat format = default(TextFormat))
 {
     return(Internal.InternalParser.TryParseByte(text, encoding, format, out value, out bytesConsumed));
 }
Esempio n. 21
0
        static bool TryFormatDateTimeRfc1123(DateTime value, Span <byte> buffer, out int bytesWritten, EncodingData encoding)
        {
            if (encoding.IsInvariantUtf8)
            {
                bytesWritten = 0;
                if (buffer.Length < 29)
                {
                    return(false);
                }

                s_dayNamesUtf8[(int)value.DayOfWeek].CopyTo(buffer);
                TryFormat(value.Day, buffer.Slice(5), out bytesWritten, D2, encoding);
                buffer[7] = (byte)' ';
                var monthBytes = s_monthNamesUtf8[value.Month - 1];
                monthBytes.CopyTo(buffer.Slice(8));
                buffer[11] = (byte)' ';
                TryFormat(value.Year, buffer.Slice(12), out bytesWritten, D4, encoding);
                buffer[16] = (byte)' ';
                TryFormat(value.Hour, buffer.Slice(17), out bytesWritten, D2, encoding);
                buffer[19] = (byte)':';
                TryFormat(value.Minute, buffer.Slice(20), out bytesWritten, D2, encoding);
                buffer[22] = (byte)':';
                TryFormat(value.Second, buffer.Slice(23), out bytesWritten, D2, encoding);
                s_gmtUtf8Bytes.CopyTo(buffer.Slice(25));
                bytesWritten = 29;
                return(true);
            }

            bytesWritten = 0;
            if (!TryWriteString(s_dayNames[(int)value.DayOfWeek], buffer, ref bytesWritten, encoding))
            {
                return(false);
            }
            if (!TryWriteInt32(value.Day, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(' ', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }
            if (!TryWriteString(s_monthNames[value.Month - 1], buffer, ref bytesWritten, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(' ', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }
            if (!TryWriteInt32(value.Year, buffer, ref bytesWritten, D4, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(' ', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }
            if (!TryWriteInt32(value.Hour, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }
            if (!TryWriteInt32(value.Minute, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }
            if (!TryWriteInt32(value.Second, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteString(" GMT", buffer, ref bytesWritten, encoding))
            {
                return(false);
            }
            return(true);
        }
Esempio n. 22
0
        static bool TryFormatDateTimeFormatO(DateTimeOffset value, bool isDateTime, Span <byte> buffer, out int bytesWritten, EncodingData encoding)
        {
            bytesWritten = 0;
            if (!TryWriteInt32(value.Year, buffer, ref bytesWritten, D4, encoding))
            {
                return(false);
            }
            if (!TryWriteChar('-', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Month, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar('-', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Day, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar('T', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Hour, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Minute, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Second, buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }

            // add optional fractional second only if needed...
            var rounded = new DateTimeOffset(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second, TimeSpan.Zero);
            var delta   = value - rounded;

            if (delta.Ticks != 0)
            {
                if (!TryWriteChar('.', buffer, ref bytesWritten, encoding))
                {
                    return(false);
                }
                var timeFrac = delta.Ticks * FractionalTimeScale / System.TimeSpan.TicksPerSecond;
                if (!TryWriteInt64(timeFrac, buffer, ref bytesWritten, D7, encoding))
                {
                    return(false);
                }
            }

            if (isDateTime)
            {
                if (!TryWriteChar('Z', buffer, ref bytesWritten, encoding))
                {
                    return(false);
                }
            }
            else
            {
                if (!TryWriteChar('+', buffer, ref bytesWritten, encoding))
                {
                    return(false);
                }
                int bytes;
                if (!value.Offset.TryFormat(buffer.Slice(bytesWritten), out bytes, t, encoding))
                {
                    return(false);
                }
                bytesWritten += bytes;
            }

            return(true);
        }
        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);
        }
Esempio n. 24
0
        public unsafe static bool TryParse(byte *text, int index, int length, EncodingData encoding,
                                           Format.Parsed format, out double value, out int bytesConsumed)
        {
            // Precondition replacement
            if (length < 1 || index < 0)
            {
                value         = 0;
                bytesConsumed = 0;
                return(false);
            }

            value         = 0.0;
            bytesConsumed = 0;

            if (encoding.IsInvariantUtf8)
            {
                string doubleString = "";
                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         = double.NaN;
                    bytesConsumed = 3;
                    return(true);
                }
                if (text[index] == '-' || text[index] == '+')
                {
                    signed        = true;
                    doubleString += (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 = double.NegativeInfinity;
                    }
                    else
                    {
                        value = double.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;
                            doubleString += (char)nextByte;
                        }
                        else if (!e && nextByte == 'e' || nextByte == 'E')
                        {
                            e     = true;
                            eLast = true;
                            bytesConsumed++;
                            doubleString += (char)nextByte;
                        }
                        else if (eLast && nextByte == '+' || nextByte == '-')
                        {
                            eLast = false;
                            bytesConsumed++;
                            doubleString += (char)nextByte;
                        }
                        else if ((decimalPlace && signed && bytesConsumed == 2) || ((signed || decimalPlace) && bytesConsumed == 1))
                        {
                            value         = 0;
                            bytesConsumed = 0;
                            return(false);
                        }
                        else
                        {
                            if (double.TryParse(doubleString, out value))
                            {
                                return(true);
                            }
                            else
                            {
                                bytesConsumed = 0;
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        if (eLast)
                        {
                            eLast = false;
                        }
                        if (!digitLast)
                        {
                            digitLast = true;
                        }
                        bytesConsumed++;
                        doubleString += (char)nextByte;
                    }
                }

                if ((decimalPlace && signed && bytesConsumed == 2) || ((signed || decimalPlace) && bytesConsumed == 1))
                {
                    value         = 0;
                    bytesConsumed = 0;
                    return(false);
                }
                else
                {
                    if (double.TryParse(doubleString, out value))
                    {
                        return(true);
                    }
                    else
                    {
                        bytesConsumed = 0;
                        return(false);
                    }
                }
            }

            return(false);
        }
Esempio n. 25
0
 public static bool TryFormat(this float value, Span <byte> buffer, out int bytesWritten, TextFormat format, EncodingData encoding)
 {
     if (format.IsDefault)
     {
         format.Symbol = 'G';
     }
     Precondition.Require(format.Symbol == 'G');
     return(FloatFormatter.TryFormatNumber(value, true, buffer, out bytesWritten, format, encoding));
 }
Esempio n. 26
0
        public static bool TryFormat(this char value, Span <byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (formattingData.IsUtf16)
            {
                if (buffer.Length < 2)
                {
                    bytesWritten = 0;
                    return(false);
                }
                buffer[0]    = (byte)value;
                buffer[1]    = (byte)(value >> 8);
                bytesWritten = 2;
                return(true);
            }

            if (buffer.Length < 1)
            {
                bytesWritten = 0;
                return(false);
            }

            // fast path for ASCII
            if (value <= 127)
            {
                buffer[0]    = (byte)value;
                bytesWritten = 1;
                return(true);
            }

            // TODO: This can be directly encoded to SpanByte. There is no conversion between spans yet
            var encoded = new Utf8EncodedCodePoint(value);

            bytesWritten = encoded.Length;
            if (buffer.Length < bytesWritten)
            {
                bytesWritten = 0;
                return(false);
            }

            buffer[0] = encoded.Byte0;
            if (bytesWritten > 1)
            {
                buffer[1] = encoded.Byte1;
            }
            if (bytesWritten > 2)
            {
                buffer[2] = encoded.Byte2;
            }
            if (bytesWritten > 3)
            {
                buffer[3] = encoded.Byte3;
            }
            return(true);
        }
Esempio n. 27
0
 public static bool TryFormat(this long value, Span <byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
 {
     return(IntegerFormatter.TryFormatInt64(value, 8, buffer, format, formattingData, out bytesWritten));
 }
Esempio n. 28
0
 internal static bool TryFormatUInt64(ulong value, byte numberOfBytes, Span <byte> buffer, Span <char> format, EncodingData formattingData, out int bytesWritten)
 {
     Format.Parsed parsedFormat = Format.Parse(format);
     return(TryFormatUInt64(value, numberOfBytes, buffer, parsedFormat, formattingData, out bytesWritten));
 }
 static bool TryWriteInt64(long i, Span<byte> buffer, TextFormat byteFormat, EncodingData formattingData, ref int bytesWritten)
 {
     int written;
     if (!i.TryFormat(buffer.Slice(bytesWritten), out written, byteFormat, formattingData))
     {
         bytesWritten = 0;
         return false;
     }
     bytesWritten += written;
     return true;
 }
Esempio n. 30
0
        public static bool TryFormat(this TimeSpan value, Span <byte> buffer, out int bytesWritten, TextFormat format = default(TextFormat), EncodingData encoding = default(EncodingData))
        {
            if (format.IsDefault)
            {
                format.Symbol = 'c';
            }
            Precondition.Require(format.Symbol == 'G' || format.Symbol == 't' || format.Symbol == 'c' || format.Symbol == 'g');

            if (format.Symbol != 't')
            {
                return(TryFormatTimeSpanG(value, buffer, out bytesWritten, format, encoding));
            }

            // else it's format 't' (short time used to print time offsets)
            return(TryFormatTimeSpanT(value, buffer, out bytesWritten, encoding));
        }
Esempio n. 31
0
        private static bool TryFormatTimeSpanG(TimeSpan value, Span <byte> buffer, out int bytesWritten, TextFormat format = default(TextFormat), EncodingData encoding = default(EncodingData))
        {
            bytesWritten = 0;

            if (value.Ticks < 0)
            {
                if (!TryWriteChar('-', buffer, ref bytesWritten, encoding))
                {
                    return(false);
                }
            }

            bool daysWritten = false;

            if (value.Days != 0 || format.Symbol == 'G')
            {
                if (!TryWriteInt32(Abs(value.Days), buffer, ref bytesWritten, default(TextFormat), encoding))
                {
                    return(false);
                }
                daysWritten = true;
                if (format.Symbol == 'c')
                {
                    if (!TryWriteChar('.', buffer, ref bytesWritten, encoding))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!TryWriteChar(':', buffer, ref bytesWritten, encoding))
                    {
                        return(false);
                    }
                }
            }

            var hourFormat = default(TextFormat);

            if ((daysWritten || format.Symbol == 'c') && format.Symbol != 'g')
            {
                hourFormat = D2;
            }
            if (!TryWriteInt32(Abs(value.Hours), buffer, ref bytesWritten, hourFormat, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }

            if (!TryWriteInt32(Abs(value.Minutes), buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }

            if (!TryWriteInt32(Abs(value.Seconds), buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }

            long remainingTicks;

            if (value.Ticks != long.MinValue)
            {
                remainingTicks = Abs(value.Ticks) % TimeSpan.TicksPerSecond;
            }
            else
            {
                remainingTicks = long.MaxValue % TimeSpan.TicksPerSecond;
                remainingTicks = (remainingTicks + 1) % TimeSpan.TicksPerSecond;
            }

            var ticksFormat = D7;

            if (remainingTicks != 0)
            {
                if (!TryWriteChar('.', buffer, ref bytesWritten, encoding))
                {
                    return(false);
                }
                var fraction = remainingTicks * FractionalTimeScale / TimeSpan.TicksPerSecond;
                if (!TryWriteInt64(fraction, buffer, ref bytesWritten, ticksFormat, encoding))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 32
0
        private static bool TryFormatTimeSpanT(TimeSpan value, Span<byte> buffer, EncodingData formattingData, out int bytesWritten)
        {
            bytesWritten = 0;

            if (value.Ticks < 0)
            {
                if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; }
            }

            if (!TryWriteInt32(Abs((int)value.TotalHours), buffer, D2, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(Abs(value.Minutes), buffer, D2, formattingData, ref bytesWritten)) { return false; }

            return true;
        }
 public static bool TryParseByte(ReadOnlySpan<byte> text, out byte value, out int bytesConsumed, EncodingData encoding = default(EncodingData), TextFormat format = default(TextFormat))
 {
     return Internal.InternalParser.TryParseByte(text, encoding, format, out value, out bytesConsumed);
 }
        static bool TryWriteChar(char character, Span <byte> buffer, ref int bytesWritten, EncodingData encoding)
        {
            int consumed;
            int written;

            unsafe
            {
                ReadOnlySpan <char> charSpan = new ReadOnlySpan <char>(&character, 1);

                if (!encoding.TextEncoder.TryEncode(charSpan, buffer.Slice(bytesWritten), out consumed, out written))
                {
                    bytesWritten = 0;
                    return(false);
                }
            }

            bytesWritten += written;
            return(true);
        }
Esempio n. 35
0
        public static bool TryFormat(this DateTimeOffset value, Span <byte> buffer, out int bytesWritten, TextFormat format = default(TextFormat), EncodingData encoding = default(EncodingData))
        {
            if (format.IsDefault)
            {
                format.Symbol = 'G';
            }
            Precondition.Require(format.Symbol == 'R' || format.Symbol == 'O' || format.Symbol == 'G');
            switch (format.Symbol)
            {
            case 'R':

                if (encoding.IsInvariantUtf16)     // TODO: there are many checks like this one in the code. They need to also verify that the UTF8 branch is invariant.
                {
                    return(TryFormatDateTimeRfc1123(value.UtcDateTime, buffer, out bytesWritten, EncodingData.InvariantUtf16));
                }
                else
                {
                    return(TryFormatDateTimeRfc1123(value.UtcDateTime, buffer, out bytesWritten, EncodingData.InvariantUtf8));
                }

            case 'O':
                if (encoding.IsInvariantUtf16)
                {
                    return(TryFormatDateTimeFormatO(value.UtcDateTime, false, buffer, out bytesWritten, EncodingData.InvariantUtf16));
                }
                else
                {
                    return(TryFormatDateTimeFormatO(value.UtcDateTime, false, buffer, out bytesWritten, EncodingData.InvariantUtf8));
                }

            case 'G':
                return(TryFormatDateTimeFormatG(value.DateTime, buffer, out bytesWritten, encoding));

            default:
                throw new NotImplementedException();
            }
        }
Esempio n. 36
0
        public static bool TryFormat(this string value, Span <byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (formattingData.IsUtf16)
            {
                var valueBytes = value.Length << 1;
                if (valueBytes > buffer.Length)
                {
                    bytesWritten = 0;
                    return(false);
                }

                unsafe
                {
                    fixed(char *pCharacters = value)
                    {
                        byte *pBytes = (byte *)pCharacters;

                        buffer.Set(pBytes, valueBytes);
                    }
                }

                bytesWritten = valueBytes;
                return(true);
            }


            var avaliableBytes = buffer.Length;

            bytesWritten = 0;
            for (int i = 0; i < value.Length; i++)
            {
                var c = value[i];

                var codepoint = (ushort)c;
                if (codepoint <= 0x7f) // this if block just optimizes for ascii
                {
                    if (bytesWritten + 1 > avaliableBytes)
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    buffer[bytesWritten++] = (byte)codepoint;
                }
                else
                {
                    Utf8EncodedCodePoint encoded;
                    if (!char.IsSurrogate(c))
                    {
                        encoded = new Utf8EncodedCodePoint(c);
                    }
                    else
                    {
                        if (++i >= value.Length)
                        {
                            throw new ArgumentException("Invalid surrogate pair.", nameof(value));
                        }
                        char lowSurrogate = value[i];
                        encoded = new Utf8EncodedCodePoint(c, lowSurrogate);
                    }


                    if (bytesWritten + encoded.Length > avaliableBytes)
                    {
                        bytesWritten = 0;
                        return(false);
                    }

                    buffer[bytesWritten] = encoded.Byte0;
                    if (encoded.Length > 1)
                    {
                        buffer[bytesWritten + 1] = encoded.Byte1;

                        if (encoded.Length > 2)
                        {
                            buffer[bytesWritten + 2] = encoded.Byte2;

                            if (encoded.Length > 3)
                            {
                                buffer[bytesWritten + 3] = encoded.Byte3;
                            }
                        }
                    }

                    bytesWritten += encoded.Length;
                }
            }
            return(true);
        }
        static bool TryWriteString(string text, Span <byte> buffer, ref int bytesWritten, EncodingData encoding)
        {
            int written;

            if (!encoding.TextEncoder.TryEncode(text, buffer.Slice(bytesWritten), out written))
            {
                bytesWritten = 0;
                return(false);
            }
            bytesWritten += written;
            return(true);
        }
Esempio n. 38
0
        private static bool TryFormatTimeSpanT(TimeSpan value, Span <byte> buffer, out int bytesWritten, EncodingData encoding)
        {
            bytesWritten = 0;

            if (value.Ticks < 0)
            {
                if (!TryWriteChar('-', buffer, ref bytesWritten, encoding))
                {
                    return(false);
                }
            }

            if (!TryWriteInt32(Abs((int)value.TotalHours), buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, ref bytesWritten, encoding))
            {
                return(false);
            }

            if (!TryWriteInt32(Abs(value.Minutes), buffer, ref bytesWritten, D2, encoding))
            {
                return(false);
            }

            return(true);
        }
        static bool TryWriteInt64(long i, Span <byte> buffer, ref int bytesWritten, TextFormat byteFormat, EncodingData encoding)
        {
            int written;

            if (!i.TryFormat(buffer.Slice(bytesWritten), out written, byteFormat, encoding))
            {
                bytesWritten = 0;
                return(false);
            }
            bytesWritten += written;
            return(true);
        }
Esempio n. 40
0
        public static bool TryFormat(this DateTime value, Span <byte> buffer, out int bytesWritten, TextFormat format = default(TextFormat), EncodingData encoding = default(EncodingData))
        {
            if (format.IsDefault)
            {
                format.Symbol = 'G';
            }
            Precondition.Require(format.Symbol == 'R' || format.Symbol == 'O' || format.Symbol == 'G');

            switch (format.Symbol)
            {
            case 'R':
                var utc = value.ToUniversalTime();
                if (encoding.IsInvariantUtf16)
                {
                    return(TryFormatDateTimeRfc1123(utc, buffer, out bytesWritten, EncodingData.InvariantUtf16));
                }
                else
                {
                    return(TryFormatDateTimeRfc1123(utc, buffer, out bytesWritten, EncodingData.InvariantUtf8));
                }

            case 'O':
                if (encoding.IsInvariantUtf16)
                {
                    return(TryFormatDateTimeFormatO(value, true, buffer, out bytesWritten, EncodingData.InvariantUtf16));
                }
                else
                {
                    return(TryFormatDateTimeFormatO(value, true, buffer, out bytesWritten, EncodingData.InvariantUtf8));
                }

            case 'G':
                return(TryFormatDateTimeFormatG(value, buffer, out bytesWritten, encoding));

            default:
                throw new NotImplementedException();
            }
        }
Esempio n. 41
0
 internal static bool TryFormatUInt64(ulong value, byte numberOfBytes, Span<byte> buffer, ReadOnlySpan<char> format, EncodingData formattingData, out int bytesWritten)
 {
     TextFormat parsedFormat = TextFormat.Parse(format);
     return TryFormatUInt64(value, numberOfBytes, buffer, parsedFormat, formattingData, out bytesWritten);
 }
Esempio n. 42
0
 public static bool TryFormat(this Guid value, Span <byte> buffer, ReadOnlySpan <char> format, EncodingData formattingData, out int bytesWritten)
 {
     Format.Parsed parsedFormat = Format.Parse(format);
     return(TryFormat(value, buffer, parsedFormat, formattingData, out bytesWritten));
 }
Esempio n. 43
0
        // TODO: format should be ReadOnlySpan<char>
        internal static bool TryFormatInt64(long value, byte numberOfBytes, Span <byte> buffer, Span <char> format, EncodingData formattingData, out int bytesWritten)
        {
            Precondition.Require(numberOfBytes <= sizeof(long));

            Format.Parsed parsedFormat = Format.Parse(format);
            return(TryFormatInt64(value, numberOfBytes, buffer, parsedFormat, formattingData, out bytesWritten));
        }
Esempio n. 44
0
        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);
        }
Esempio n. 45
0
        // TODO: this whole routine is too slow. It does div and mod twice, which are both costly (especially that some JITs cannot optimize it).
        // It does it twice to avoid reversing the formatted buffer, which can be tricky given it should handle arbitrary cultures.
        // One optimization I thought we could do is to do div/mod once and store digits in a temp buffer (but that would allocate). Modification to the idea would be to store the digits in a local struct
        // Another idea possibly worth tying would be to special case cultures that have constant digit size, and go back to the format + reverse buffer approach.
        private static bool TryFormatDecimal(ulong value, Span <byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (format.IsDefault)
            {
                format.Symbol = 'G';
            }
            format.Symbol = Char.ToUpperInvariant(format.Symbol); // TODO: this is costly. I think the transformation should happen in Parse
            Precondition.Require(format.Symbol == 'D' || format.Symbol == 'G' || format.Symbol == 'N');

            // Reverse value on decimal basis, count digits and trailing zeros before the decimal separator
            ulong reversedValueExceptFirst = 0;
            var   digitsCount        = 1;
            var   trailingZerosCount = 0;

            // We reverse the digits in numeric form because reversing encoded digits is hard and/or costly.
            // If value contains 20 digits, its reversed value will not fit into ulong size.
            // So reverse it till last digit (reversedValueExceptFirst will have all the digits except the first one).
            while (value >= 10)
            {
                var digit = value % 10UL;
                value = value / 10UL;

                if (reversedValueExceptFirst == 0 && digit == 0)
                {
                    trailingZerosCount++;
                }
                else
                {
                    reversedValueExceptFirst = reversedValueExceptFirst * 10UL + digit;
                    digitsCount++;
                }
            }

            bytesWritten = 0;
            int digitBytes;

            // If format is D and precision is greater than digitsCount + trailingZerosCount, append leading zeros
            if (format.Symbol == 'D' && format.HasPrecision)
            {
                var leadingZerosCount = format.Precision - digitsCount - trailingZerosCount;
                while (leadingZerosCount-- > 0)
                {
                    if (!formattingData.TryWriteDigitOrSymbol(0, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    bytesWritten += digitBytes;
                }
            }

            // Append first digit
            if (!formattingData.TryWriteDigit(value, buffer.Slice(bytesWritten), out digitBytes))
            {
                bytesWritten = 0;
                return(false);
            }
            bytesWritten += digitBytes;
            digitsCount--;

            if (format.Symbol == 'N')
            {
                const int GroupSize = 3;

                // Count amount of digits before first group separator. It will be reset to groupSize every time digitsLeftInGroup == zero
                var digitsLeftInGroup = (digitsCount + trailingZerosCount) % GroupSize;
                if (digitsLeftInGroup == 0)
                {
                    if (digitsCount + trailingZerosCount > 0)
                    {
                        // There is a new group immediately after the first digit
                        if (!formattingData.TryWriteSymbol(EncodingData.Symbol.GroupSeparator, buffer.Slice(bytesWritten), out digitBytes))
                        {
                            bytesWritten = 0;
                            return(false);
                        }
                        bytesWritten += digitBytes;
                    }
                    digitsLeftInGroup = GroupSize;
                }

                // Append digits
                while (reversedValueExceptFirst > 0)
                {
                    if (digitsLeftInGroup == 0)
                    {
                        if (!formattingData.TryWriteSymbol(EncodingData.Symbol.GroupSeparator, buffer.Slice(bytesWritten), out digitBytes))
                        {
                            bytesWritten = 0;
                            return(false);
                        }
                        bytesWritten     += digitBytes;
                        digitsLeftInGroup = GroupSize;
                    }

                    var nextDigit = reversedValueExceptFirst % 10UL;
                    reversedValueExceptFirst = reversedValueExceptFirst / 10UL;

                    if (!formattingData.TryWriteDigit(nextDigit, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    bytesWritten += digitBytes;
                    digitsLeftInGroup--;
                }

                // Append trailing zeros if any
                while (trailingZerosCount-- > 0)
                {
                    if (digitsLeftInGroup == 0)
                    {
                        if (!formattingData.TryWriteSymbol(EncodingData.Symbol.GroupSeparator, buffer.Slice(bytesWritten), out digitBytes))
                        {
                            bytesWritten = 0;
                            return(false);
                        }
                        bytesWritten     += digitBytes;
                        digitsLeftInGroup = GroupSize;
                    }

                    if (!formattingData.TryWriteDigitOrSymbol(0, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    bytesWritten += digitBytes;
                    digitsLeftInGroup--;
                }
            }
            else
            {
                while (reversedValueExceptFirst > 0)
                {
                    var bufferSlice = buffer.Slice(bytesWritten);
                    var nextDigit   = reversedValueExceptFirst % 10UL;
                    reversedValueExceptFirst = reversedValueExceptFirst / 10UL;
                    if (!formattingData.TryWriteDigit(nextDigit, bufferSlice, out digitBytes))
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    bytesWritten += digitBytes;
                }

                // Append trailing zeros if any
                while (trailingZerosCount-- > 0)
                {
                    if (!formattingData.TryWriteDigitOrSymbol(0, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    bytesWritten += digitBytes;
                }
            }

            // If format is N and precision is not defined or is greater than zero, append trailing zeros after decimal point
            if (format.Symbol == 'N')
            {
                int trailingZerosAfterDecimalCount = format.HasPrecision ? format.Precision : 2;

                if (trailingZerosAfterDecimalCount > 0)
                {
                    if (!formattingData.TryWriteSymbol(EncodingData.Symbol.DecimalSeparator, buffer.Slice(bytesWritten), out digitBytes))
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    bytesWritten += digitBytes;

                    while (trailingZerosAfterDecimalCount-- > 0)
                    {
                        if (!formattingData.TryWriteDigitOrSymbol(0, buffer.Slice(bytesWritten), out digitBytes))
                        {
                            bytesWritten = 0;
                            return(false);
                        }
                        bytesWritten += digitBytes;
                    }
                }
            }

            return(true);
        }
Esempio n. 46
0
        static bool TryWriteInt64(long i, Span <byte> buffer, Format.Parsed byteFormat, EncodingData formattingData, ref int bytesWritten)
        {
            int written;

            if (!i.TryFormat(buffer.Slice(bytesWritten), byteFormat, formattingData, out written))
            {
                bytesWritten = 0;
                return(false);
            }
            bytesWritten += written;
            return(true);
        }
Esempio n. 47
0
        internal static bool TryFormatUInt64(ulong value, byte numberOfBytes, Span <byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (format.Symbol == 'g')
            {
                format.Symbol = 'G';
            }

            if (format.IsHexadecimal && formattingData.IsUtf16)
            {
                return(TryFormatHexadecimalInvariantCultureUtf16(value, buffer, format, out bytesWritten));
            }

            if (format.IsHexadecimal && formattingData.IsUtf8)
            {
                return(TryFormatHexadecimalInvariantCultureUtf8(value, buffer, format, out bytesWritten));
            }

            if ((formattingData.IsInvariantUtf16) && (format.Symbol == 'D' || format.Symbol == 'G'))
            {
                return(TryFormatDecimalInvariantCultureUtf16(value, buffer, format, out bytesWritten));
            }

            if ((formattingData.IsInvariantUtf8) && (format.Symbol == 'D' || format.Symbol == 'G'))
            {
                return(TryFormatDecimalInvariantCultureUtf8(value, buffer, format, out bytesWritten));
            }

            return(TryFormatDecimal(value, buffer, format, formattingData, out bytesWritten));
        }
Esempio n. 48
0
 public static bool TryFormat(this long value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
 {
     return IntegerFormatter.TryFormatInt64(value, 8, buffer, format, formattingData, out bytesWritten);
 }
        public static bool TryFormat(this Guid value, Span<byte> buffer, TextFormat format, EncodingData encoding, 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, encoding.TextEncoding, ref bytesWritten)) { return false; }
                    tail = '}';
                    break;

                case 'P':
                    if (!TryWriteChar('(', buffer, encoding.TextEncoding, ref bytesWritten)) { return false; }
                    tail = ')';
                    break;

                default:
                    Precondition.Require(false); // how did we get here? 
                    break;
            }


            var byteFormat = new TextFormat('x', 2);
            unsafe
            {
                byte* bytes = (byte*)&value;

                if (!TryWriteByte(bytes[3], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[2], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[1], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[0], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }

                if (dash)
                {
                    if (!TryWriteChar('-', buffer, encoding.TextEncoding, ref bytesWritten)) { return false; }
                }

                if (!TryWriteByte(bytes[5], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[4], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }

                if (dash)
                {
                    if (!TryWriteChar('-', buffer, encoding.TextEncoding, ref bytesWritten)) { return false; }
                }

                if (!TryWriteByte(bytes[7], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[6], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }

                if (dash)
                {
                    if (!TryWriteChar('-', buffer, encoding.TextEncoding, ref bytesWritten)) { return false; }
                }

                if (!TryWriteByte(bytes[8], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[9], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }

                if (dash)
                {
                    if (!TryWriteChar('-', buffer, encoding.TextEncoding, ref bytesWritten)) { return false; }
                }

                if (!TryWriteByte(bytes[10], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[11], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[12], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[13], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[14], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
                if (!TryWriteByte(bytes[15], buffer, byteFormat, encoding, ref bytesWritten)) { return false; }
            }

            if (tail != '\0')
            {
                if (!TryWriteChar(tail, buffer, encoding.TextEncoding, ref bytesWritten)) { return false; }
            }

            return true;
        }
Esempio n. 50
0
        internal static bool TryFormatUInt64(ulong value, byte numberOfBytes, Span <byte> buffer, out int bytesWritten, TextFormat format, EncodingData encoding)
        {
            if (format.Symbol == 'g')
            {
                format.Symbol = 'G';
            }

            if (format.IsHexadecimal && encoding.IsInvariantUtf16)
            {
                return(TryFormatHexadecimalInvariantCultureUtf16(value, buffer, out bytesWritten, format));
            }

            if (format.IsHexadecimal && encoding.IsInvariantUtf8)
            {
                return(TryFormatHexadecimalInvariantCultureUtf8(value, buffer, out bytesWritten, format));
            }

            if ((encoding.IsInvariantUtf16) && (format.Symbol == 'D' || format.Symbol == 'G'))
            {
                return(TryFormatDecimalInvariantCultureUtf16(value, buffer, out bytesWritten, format));
            }

            if ((encoding.IsInvariantUtf8) && (format.Symbol == 'D' || format.Symbol == 'G'))
            {
                return(TryFormatDecimalInvariantCultureUtf8(value, buffer, out bytesWritten, format));
            }

            return(TryFormatDecimal(value, buffer, out bytesWritten, format, encoding));
        }
Esempio n. 51
0
 public static bool TryFormat(this float value, Span<byte> buffer, ReadOnlySpan<char> format, EncodingData formattingData, out int bytesWritten)
 {
     Format.Parsed parsedFormat = Format.Parse(format);
     return TryFormat(value, buffer, parsedFormat, formattingData, out bytesWritten);
 }
Esempio n. 52
0
        static bool TryFormatDateTimeFormagG(DateTime value, Span<byte> buffer, EncodingData formattingData, out int bytesWritten)
        {
            // for now it only works for invariant culture
            if(!formattingData.IsInvariantUtf16 && !formattingData.IsInvariantUtf8)
            {
                throw new NotImplementedException();
            }

            bytesWritten = 0;
            if (!TryWriteInt32(value.Month, buffer, G, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar('/', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Day, buffer, G, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar('/', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Year, buffer, G, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(' ', buffer, formattingData, ref bytesWritten)) { return false; }

            var hour = value.Hour;
            if(hour == 0)
            {
                hour = 12; 
            }
            if(hour > 12)
            {
                hour = hour - 12;
            }

            if (!TryWriteInt32(hour, buffer, G, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Minute, buffer, D2, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Second, buffer, D2, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(' ', buffer, formattingData, ref bytesWritten)) { return false; }

            if(value.Hour > 11)
            {
                TryWriteString("PM", buffer, formattingData, ref bytesWritten);
            }
            else
            {
                TryWriteString("AM", buffer, formattingData, ref bytesWritten);
            }

            return true;
        }
Esempio n. 53
0
        static bool TryFormatDateTimeFormagG(DateTime value, Span <byte> buffer, EncodingData formattingData, out int bytesWritten)
        {
            // for now it only works for invariant culture
            if (!formattingData.IsInvariantUtf16 && !formattingData.IsInvariantUtf8)
            {
                throw new NotImplementedException();
            }

            bytesWritten = 0;
            if (!TryWriteInt32(value.Month, buffer, G, formattingData, ref bytesWritten))
            {
                return(false);
            }
            if (!TryWriteChar('/', buffer, formattingData, ref bytesWritten))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Day, buffer, G, formattingData, ref bytesWritten))
            {
                return(false);
            }
            if (!TryWriteChar('/', buffer, formattingData, ref bytesWritten))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Year, buffer, G, formattingData, ref bytesWritten))
            {
                return(false);
            }
            if (!TryWriteChar(' ', buffer, formattingData, ref bytesWritten))
            {
                return(false);
            }

            var hour = value.Hour;

            if (hour == 0)
            {
                hour = 12;
            }
            if (hour > 12)
            {
                hour = hour - 12;
            }

            if (!TryWriteInt32(hour, buffer, G, formattingData, ref bytesWritten))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Minute, buffer, D2, formattingData, ref bytesWritten))
            {
                return(false);
            }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten))
            {
                return(false);
            }

            if (!TryWriteInt32(value.Second, buffer, D2, formattingData, ref bytesWritten))
            {
                return(false);
            }
            if (!TryWriteChar(' ', buffer, formattingData, ref bytesWritten))
            {
                return(false);
            }

            if (value.Hour > 11)
            {
                TryWriteString("PM", buffer, formattingData, ref bytesWritten);
            }
            else
            {
                TryWriteString("AM", buffer, formattingData, ref bytesWritten);
            }

            return(true);
        }
Esempio n. 54
0
        static bool TryFormatDateTimeFormatO(DateTimeOffset value, bool isDateTime, Span<byte> buffer, EncodingData formattingData, out int bytesWritten)
        {
            bytesWritten = 0;
            if (!TryWriteInt32(value.Year, buffer, D4, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Month, buffer, D2, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Day, buffer, D2, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar('T', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Hour, buffer, D2, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Minute, buffer, D2, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(value.Second, buffer, D2, formattingData, ref bytesWritten)) { return false; }

            // add optional fractional second only if needed...
            var rounded = new DateTimeOffset(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second, TimeSpan.Zero);
            var delta = value - rounded;

            if (delta.Ticks != 0)
            {
                if (!TryWriteChar('.', buffer, formattingData, ref bytesWritten)) { return false; }
                var timeFrac = delta.Ticks * FractionalTimeScale / System.TimeSpan.TicksPerSecond;
                if (!TryWriteInt64(timeFrac, buffer, D7, formattingData, ref bytesWritten)) { return false; }
            }

            if (isDateTime)
            {
                if (!TryWriteChar('Z', buffer, formattingData, ref bytesWritten)) { return false; }
            }
            else
            {
                if (!TryWriteChar('+', buffer, formattingData, ref bytesWritten)) { return false; }
                int bytes;
                if (!value.Offset.TryFormat(buffer.Slice(bytesWritten), t, formattingData, out bytes)) { return false; }
                bytesWritten += bytes;
            }

            return true;
        }
Esempio n. 55
0
        public unsafe static bool TryParseDouble(byte* text, int index, int length, EncodingData encoding,
            Format.Parsed format, out double value, out int bytesConsumed)
        {
            // Precondition replacement
            if (length < 1 || index < 0)
            {
                value = 0;
                bytesConsumed = 0;
                return false;
            }

            value = 0.0;
            bytesConsumed = 0;

            if (encoding.IsInvariantUtf8)
            {
                string doubleString = "";
                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 = double.NaN;
                    bytesConsumed = 3;
                    return true;
                }
                if (text[index] == '-' || text[index] == '+')
                {
                    signed = true;
                    doubleString += (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 = double.NegativeInfinity;
                    }
                    else
                    {
                        value = double.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;
                            doubleString += (char)nextByte;
                        }
                        else if (!e && nextByte == 'e' || nextByte == 'E')
                        {
                            e = true;
                            eLast = true;
                            bytesConsumed++;
                            doubleString += (char)nextByte;
                        }
                        else if (eLast && nextByte == '+' || nextByte == '-')
                        {
                            eLast = false;
                            bytesConsumed++;
                            doubleString += (char)nextByte;
                        }
                        else if ((decimalPlace && signed && bytesConsumed == 2) || ((signed || decimalPlace) && bytesConsumed == 1))
                        {
                            value = 0;
                            bytesConsumed = 0;
                            return false;
                        }
                        else
                        {
                            if (double.TryParse(doubleString, out value))
                            {
                                return true;
                            }
                            else
                            {
                                bytesConsumed = 0;
                                return false;
                            }
                        }
                    }
                    else
                    {
                        if (eLast)
                            eLast = false;
                        if (!digitLast)
                            digitLast = true;
                        bytesConsumed++;
                        doubleString += (char)nextByte;
                    }
                }

                if ((decimalPlace && signed && bytesConsumed == 2) || ((signed || decimalPlace) && bytesConsumed == 1))
                {
                    value = 0;
                    bytesConsumed = 0;
                    return false;
                }
                else
                {
                    if (double.TryParse(doubleString, out value))
                    {
                        return true;
                    }
                    else
                    {
                        bytesConsumed = 0;
                        return false;
                    }
                }
            }

            return false;
        }
Esempio n. 56
0
 static bool TryFormatDateTimeRfc1123(DateTime value, Span<byte> buffer, EncodingData formattingData, out int bytesWritten)
 {
     bytesWritten = 0;
     if (!TryWriteString(s_dayNames[(int)value.DayOfWeek], buffer, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteInt32(value.Day, buffer, D2, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteChar(' ', buffer, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteString(s_monthNames[value.Month - 1], buffer, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteChar(' ', buffer, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteInt32(value.Year, buffer, D4, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteChar(' ', buffer, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteInt32(value.Hour, buffer, D2, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteInt32(value.Minute, buffer, D2, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteInt32(value.Second, buffer, D2, formattingData, ref bytesWritten)) { return false; }
     if (!TryWriteString(" GMT", buffer, formattingData, ref bytesWritten)) { return false; }
     return true;
 }
Esempio n. 57
0
        public static bool TryFormat(this TimeSpan value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (format.IsDefault)
            {
                format.Symbol = 'c';
            }
            Precondition.Require(format.Symbol == 'G' || format.Symbol == 't' || format.Symbol == 'c' || format.Symbol == 'g');

            if (format.Symbol != 't')
            {
                return TryFormatTimeSpanG(value, buffer, format, formattingData, out bytesWritten);
            }

            // else it's format 't' (short time used to print time offsets)
            return TryFormatTimeSpanT(value, buffer, formattingData, out bytesWritten);
        }
Esempio n. 58
0
        private static bool TryFormatTimeSpanG(TimeSpan value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            bytesWritten = 0;

            if (value.Ticks < 0)
            {
                if (!TryWriteChar('-', buffer, formattingData, ref bytesWritten)) { return false; }
            }

            bool daysWritten = false;
            if (value.Days != 0 || format.Symbol == 'G')
            {
                if (!TryWriteInt32(Abs(value.Days), buffer, default(Format.Parsed), formattingData, ref bytesWritten)) { return false; }
                daysWritten = true;
                if (format.Symbol == 'c')
                {
                    if (!TryWriteChar('.', buffer, formattingData, ref bytesWritten)) { return false; }
                }
                else
                {
                    if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }
                }
            }

            var hourFormat = default(Format.Parsed);
            if ((daysWritten || format.Symbol == 'c') && format.Symbol != 'g')
            {
                hourFormat = D2;
            }
            if (!TryWriteInt32(Abs(value.Hours), buffer, hourFormat, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(Abs(value.Minutes), buffer, D2, formattingData, ref bytesWritten)) { return false; }
            if (!TryWriteChar(':', buffer, formattingData, ref bytesWritten)) { return false; }

            if (!TryWriteInt32(Abs(value.Seconds), buffer, D2, formattingData, ref bytesWritten)) { return false; }

            long remainingTicks;
            if (value.Ticks != long.MinValue)
            {
                remainingTicks = Abs(value.Ticks) % TimeSpan.TicksPerSecond;
            }
            else
            {
                remainingTicks = long.MaxValue % TimeSpan.TicksPerSecond;
                remainingTicks = (remainingTicks + 1) % TimeSpan.TicksPerSecond;
            }

            var ticksFormat = D7;
            if (remainingTicks != 0)
            {
                if (!TryWriteChar('.', buffer, formattingData, ref bytesWritten)) { return false; }
                var fraction = remainingTicks * FractionalTimeScale / TimeSpan.TicksPerSecond;
                if (!TryWriteInt64(fraction, buffer, ticksFormat, formattingData, ref bytesWritten)) { return false; }
            }

            return true;
        }
Esempio n. 59
0
        [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);
        }
Esempio n. 60
0
        public static bool TryFormatNumber(double value, bool isSingle, Span <byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            Precondition.Require(format.Symbol == 'G' || format.Symbol == 'E' || format.Symbol == 'F');

            bytesWritten = 0;
            int written;

            if (Double.IsNaN(value))
            {
                return(formattingData.TryWriteSymbol(EncodingData.Symbol.NaN, buffer, out bytesWritten));
            }

            if (Double.IsInfinity(value))
            {
                if (Double.IsNegativeInfinity(value))
                {
                    if (!formattingData.TryWriteSymbol(EncodingData.Symbol.MinusSign, buffer, out written))
                    {
                        bytesWritten = 0;
                        return(false);
                    }
                    bytesWritten += written;
                }
                if (!formattingData.TryWriteSymbol(EncodingData.Symbol.InfinitySign, buffer.Slice(bytesWritten), out written))
                {
                    bytesWritten = 0;
                    return(false);
                }
                bytesWritten += written;
                return(true);
            }

            // TODO: the lines below need to be replaced with properly implemented algorithm
            // the problem is the algorithm is complex, so I am commiting a stub for now
            var hack = value.ToString(format.Symbol.ToString());

            return(hack.TryFormat(buffer, default(Format.Parsed), formattingData, out bytesWritten));
        }