Summary

Class:System.Buffers.Text.Utf8Formatter
Assembly:System.Memory
File(s):C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Boolean.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.G.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.L.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.O.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.R.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Decimal.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Decimal.E.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Decimal.F.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Decimal.G.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Float.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Guid.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Signed.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Signed.D.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Signed.Default.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Signed.N.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.D.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.Default.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.N.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.X.cs
C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.TimeSpan.cs
Covered lines:998
Uncovered lines:122
Coverable lines:1120
Total lines:2473
Line coverage:89.1%
Branch coverage:91.3%

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
TryFormat(...)1051295.6594.74
TryFormat(...)732100100
TryFormat(...)616100100
.cctor()10100100
TryFormatDateTimeG(...)516100100
TryFormatDateTimeO(...)8128100100
TryFormatDateTimeR(...)22100100
TryFormatDateTimeL(...)22100100
TryFormat(...)208192100100
TryFormatDecimalE(...)12512100100
TryFormatDecimalF(...)1816384100100
TryFormatDecimalG(...)1616384100100
TryFormat(...)10100100
TryFormat(...)10100100
TryFormatFloatingPoint(...)9256100100
TryFormat(...)132048100100
TryFormat(...)10100100
TryFormat(...)10100100
TryFormat(...)10100100
TryFormat(...)10100100
TryFormat(...)10100100
TryFormat(...)10100100
TryFormat(...)10100100
TryFormat(...)10100100
TryFormatInt64(...)14102410090.48
TryFormatInt64D(...)34100100
TryFormatInt64D_MinValue(...)22100100
TryFormatInt64Default(...)91644.4444.44
TryFormatInt32MultipleDigits(...)3400
TryFormatInt64MultipleDigits(...)34100100
TryFormatInt64MoreThanNegativeBillionMaxUInt(...)3200
TryFormatInt64LessThanNegativeBillionMaxUInt(...)2200
TryFormatInt64N(...)34100100
TryFormatInt64N_MinValue(...)22100100
TryFormatUInt64(...)14102410090.48
TryFormatUInt64D(...)864100100
TryFormatUInt64Default(...)51644.4444.44
TryFormatUInt32SingleDigit(...)22100100
TryFormatUInt32MultipleDigits(...)2200
TryFormatUInt64MultipleDigits(...)22100100
TryFormatUInt64LessThanBillionMaxUInt(...)3200
TryFormatUInt64MoreThanBillionMaxUInt(...)3200
TryFormatUInt64N(...)864100100
TryFormatUInt64X(...)68100100
TryFormat(...)281677721698.493.88

File(s)

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Boolean.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Buffers.Binary;
 6
 7namespace System.Buffers.Text
 8{
 9    public static partial class Utf8Formatter
 10    {
 11        /// <summary>
 12        /// Formats a Boolean as a UTF8 string.
 13        /// </summary>
 14        /// <param name="value">Value to format</param>
 15        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 16        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 17        /// <param name="format">The standard format to use</param>
 18        /// <returns>
 19        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 20        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 21        /// </returns>
 22        /// <remarks>
 23        /// Formats supported:
 24        ///     G (default)   True/False
 25        ///     l             true/false
 26        /// </remarks>
 27        /// <exceptions>
 28        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 29        /// </exceptions>
 30        public static bool TryFormat(bool value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defaul
 131        {
 132            char symbol = FormattingHelpers.GetSymbolOrDefault(format, 'G');
 33
 134            if (value)
 135            {
 136                if (symbol == 'G')
 137                {
 38                    // By having each branch perform its own call to TryWriteUInt32BigEndian, we ensure that a
 39                    // constant value is passed to this routine, which means the compiler can reverse endianness
 40                    // at compile time instead of runtime if necessary.
 41                    const uint TrueValueUppercase = ('T' << 24) + ('r' << 16) + ('u' << 8) + ('e' << 0);
 142                    if (!BinaryPrimitives.TryWriteUInt32BigEndian(buffer, TrueValueUppercase))
 143                    {
 144                        goto BufferTooSmall;
 45                    }
 146                }
 147                else if (symbol == 'l')
 148                {
 49                    const uint TrueValueLowercase = ('t' << 24) + ('r' << 16) + ('u' << 8) + ('e' << 0);
 150                    if (!BinaryPrimitives.TryWriteUInt32BigEndian(buffer, TrueValueLowercase))
 151                    {
 152                        goto BufferTooSmall;
 53                    }
 154                }
 55                else
 056                {
 057                    goto BadFormat;
 58                }
 59
 160                bytesWritten = 4;
 161                return true;
 62            }
 63            else
 164            {
 165                if (symbol == 'G')
 166                {
 67                    // This check can't be performed earlier because we need to throw if an invalid symbol is
 68                    // provided, even if the buffer is too small.
 169                    if ((uint)4 >= (uint)buffer.Length)
 170                    {
 171                        goto BufferTooSmall;
 72                    }
 73
 74                    const uint FalsValueUppercase = ('F' << 24) + ('a' << 16) + ('l' << 8) + ('s' << 0);
 175                    BinaryPrimitives.WriteUInt32BigEndian(buffer, FalsValueUppercase);
 176                }
 177                else if (symbol == 'l')
 178                {
 179                    if ((uint)4 >= (uint)buffer.Length)
 180                    {
 181                        goto BufferTooSmall;
 82                    }
 83
 84                    const uint FalsValueLowercase = ('f' << 24) + ('a' << 16) + ('l' << 8) + ('s' << 0);
 185                    BinaryPrimitives.WriteUInt32BigEndian(buffer, FalsValueLowercase);
 186                }
 87                else
 188                {
 189                    goto BadFormat;
 90                }
 91
 192                buffer[4] = (byte)'e';
 193                bytesWritten = 5;
 194                return true;
 95            }
 96
 197BufferTooSmall:
 198            bytesWritten = 0;
 199            return false;
 100
 1101BadFormat:
 1102            return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 1103        }
 104    }
 105}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    public static partial class Utf8Formatter
 8    {
 9        private const byte TimeMarker = (byte)'T';
 10        private const byte UtcMarker = (byte)'Z';
 11
 12        private const byte GMT1 = (byte)'G';
 13        private const byte GMT2 = (byte)'M';
 14        private const byte GMT3 = (byte)'T';
 15
 16        private const byte GMT1Lowercase = (byte)'g';
 17        private const byte GMT2Lowercase = (byte)'m';
 18        private const byte GMT3Lowercase = (byte)'t';
 19
 20        // The three-letter abbreviation is packed into a 24-bit unsigned integer
 21        // where the least significant byte represents the first letter.
 122        private static readonly uint[] DayAbbreviations = new uint[]
 123        {
 124            'S' + ('u' << 8) + ('n' << 16),
 125            'M' + ('o' << 8) + ('n' << 16),
 126            'T' + ('u' << 8) + ('e' << 16),
 127            'W' + ('e' << 8) + ('d' << 16),
 128            'T' + ('h' << 8) + ('u' << 16),
 129            'F' + ('r' << 8) + ('i' << 16),
 130            'S' + ('a' << 8) + ('t' << 16),
 131        };
 32
 133        private static readonly uint[] DayAbbreviationsLowercase = new uint[]
 134        {
 135            's' + ('u' << 8) + ('n' << 16),
 136            'm' + ('o' << 8) + ('n' << 16),
 137            't' + ('u' << 8) + ('e' << 16),
 138            'w' + ('e' << 8) + ('d' << 16),
 139            't' + ('h' << 8) + ('u' << 16),
 140            'f' + ('r' << 8) + ('i' << 16),
 141            's' + ('a' << 8) + ('t' << 16)
 142        };
 43
 144        private static readonly uint[] MonthAbbreviations = new uint[]
 145        {
 146            'J' + ('a' << 8) + ('n' << 16),
 147            'F' + ('e' << 8) + ('b' << 16),
 148            'M' + ('a' << 8) + ('r' << 16),
 149            'A' + ('p' << 8) + ('r' << 16),
 150            'M' + ('a' << 8) + ('y' << 16),
 151            'J' + ('u' << 8) + ('n' << 16),
 152            'J' + ('u' << 8) + ('l' << 16),
 153            'A' + ('u' << 8) + ('g' << 16),
 154            'S' + ('e' << 8) + ('p' << 16),
 155            'O' + ('c' << 8) + ('t' << 16),
 156            'N' + ('o' << 8) + ('v' << 16),
 157            'D' + ('e' << 8) + ('c' << 16),
 158        };
 59
 160        private static readonly uint[] MonthAbbreviationsLowercase = new uint[]
 161        {
 162            'j' + ('a' << 8) + ('n' << 16),
 163            'f' + ('e' << 8) + ('b' << 16),
 164            'm' + ('a' << 8) + ('r' << 16),
 165            'a' + ('p' << 8) + ('r' << 16),
 166            'm' + ('a' << 8) + ('y' << 16),
 167            'j' + ('u' << 8) + ('n' << 16),
 168            'j' + ('u' << 8) + ('l' << 16),
 169            'a' + ('u' << 8) + ('g' << 16),
 170            's' + ('e' << 8) + ('p' << 16),
 171            'o' + ('c' << 8) + ('t' << 16),
 172            'n' + ('o' << 8) + ('v' << 16),
 173            'd' + ('e' << 8) + ('c' << 16),
 174        };
 75
 76        /// <summary>
 77        /// Formats a DateTimeOffset as a UTF8 string.
 78        /// </summary>
 79        /// <param name="value">Value to format</param>
 80        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 81        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 82        /// <param name="format">The standard format to use</param>
 83        /// <returns>
 84        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 85        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 86        /// </returns>
 87        /// <exceptions>
 88        /// <remarks>
 89        /// Formats supported:
 90        ///     default       05/25/2017 10:30:15 -08:00
 91        ///     G             05/25/2017 10:30:15
 92        ///     R             Tue, 03 Jan 2017 08:08:05 GMT       (RFC 1123)
 93        ///     l             tue, 03 jan 2017 08:08:05 gmt       (Lowercase RFC 1123)
 94        ///     O             2017-06-12T05:30:45.7680000-07:00   (Round-trippable)
 95        /// </remarks>
 96        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 97        /// </exceptions>
 98        public static bool TryFormat(DateTimeOffset value, Span<byte> buffer, out int bytesWritten, StandardFormat forma
 199        {
 1100            TimeSpan offset = Utf8Constants.s_nullUtcOffset;
 1101            char symbol = format.Symbol;
 1102            if (format.IsDefault)
 1103            {
 1104                symbol = 'G';
 1105                offset = value.Offset;
 1106            }
 107
 1108            switch (symbol)
 109            {
 110                case 'R':
 1111                    return TryFormatDateTimeR(value.UtcDateTime, buffer, out bytesWritten);
 112
 113                case 'l':
 1114                    return TryFormatDateTimeL(value.UtcDateTime, buffer, out bytesWritten);
 115
 116                case 'O':
 1117                    return TryFormatDateTimeO(value.DateTime, value.Offset, buffer, out bytesWritten);
 118
 119                case 'G':
 1120                    return TryFormatDateTimeG(value.DateTime, offset, buffer, out bytesWritten);
 121
 122                default:
 1123                    return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 124            }
 1125        }
 126
 127        /// <summary>
 128        /// Formats a DateTime as a UTF8 string.
 129        /// </summary>
 130        /// <param name="value">Value to format</param>
 131        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 132        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 133        /// <param name="format">The standard format to use</param>
 134        /// <returns>
 135        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 136        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 137        /// </returns>
 138        /// <remarks>
 139        /// Formats supported:
 140        ///     G  (default)  05/25/2017 10:30:15
 141        ///     R             Tue, 03 Jan 2017 08:08:05 GMT       (RFC 1123)
 142        ///     l             tue, 03 jan 2017 08:08:05 gmt       (Lowercase RFC 1123)
 143        ///     O             2017-06-12T05:30:45.7680000-07:00   (Round-trippable)
 144        /// </remarks>
 145        /// <exceptions>
 146        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 147        /// </exceptions>
 148        public static bool TryFormat(DateTime value, Span<byte> buffer, out int bytesWritten, StandardFormat format = de
 1149        {
 1150            char symbol = FormattingHelpers.GetSymbolOrDefault(format, 'G');
 151
 1152            switch (symbol)
 153            {
 154                case 'R':
 1155                    return TryFormatDateTimeR(value, buffer, out bytesWritten);
 156
 157                case 'l':
 1158                    return TryFormatDateTimeL(value, buffer, out bytesWritten);
 159
 160                case 'O':
 1161                    return TryFormatDateTimeO(value, Utf8Constants.s_nullUtcOffset, buffer, out bytesWritten);
 162
 163                case 'G':
 1164                    return TryFormatDateTimeG(value, Utf8Constants.s_nullUtcOffset, buffer, out bytesWritten);
 165
 166                default:
 1167                    return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 168            }
 1169        }
 170    }
 171}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.G.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    public static partial class Utf8Formatter
 8    {
 9        //
 10        // 'G' format for DateTime.
 11        //
 12        //    0123456789012345678
 13        //    ---------------------------------
 14        //    05/25/2017 10:30:15
 15        //
 16        //  Also handles the default ToString() format for DateTimeOffset
 17        //
 18        //    01234567890123456789012345
 19        //    --------------------------
 20        //    05/25/2017 10:30:15 -08:00
 21        //
 22        private static bool TryFormatDateTimeG(DateTime value, TimeSpan offset, Span<byte> buffer, out int bytesWritten)
 123        {
 24            const int MinimumBytesNeeded = 19;
 25
 126            int bytesRequired = MinimumBytesNeeded;
 27
 128            if (offset != Utf8Constants.s_nullUtcOffset)
 129            {
 130                bytesRequired += 7; // Space['+'|'-']hh:mm
 131            }
 32
 133            if (buffer.Length < bytesRequired)
 134            {
 135                bytesWritten = 0;
 136                return false;
 37            }
 38
 139            bytesWritten = bytesRequired;
 40
 41            // Hoist most of the bounds checks on buffer.
 342            { var unused = buffer[MinimumBytesNeeded - 1]; }
 43
 44            // TODO: Introduce an API which can parse DateTime instances efficiently, pulling out
 45            // all their properties (Month, Day, etc.) in one shot. This would help avoid the
 46            // duplicate work that implicitly results from calling these properties individually.
 47
 148            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Month, buffer, 0);
 149            buffer[2] = Utf8Constants.Slash;
 50
 151            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, buffer, 3);
 152            buffer[5] = Utf8Constants.Slash;
 53
 154            FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, buffer, 6);
 155            buffer[10] = Utf8Constants.Space;
 56
 157            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, buffer, 11);
 158            buffer[13] = Utf8Constants.Colon;
 59
 160            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, buffer, 14);
 161            buffer[16] = Utf8Constants.Colon;
 62
 163            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, buffer, 17);
 64
 165            if (offset != Utf8Constants.s_nullUtcOffset)
 166            {
 67                byte sign;
 68
 169                if (offset < default(TimeSpan) /* a "const" version of TimeSpan.Zero */)
 170                {
 171                    sign = Utf8Constants.Minus;
 172                    offset = TimeSpan.FromTicks(-offset.Ticks);
 173                }
 74                else
 175                {
 176                    sign = Utf8Constants.Plus;
 177                }
 78
 79                // Writing the value backward allows the JIT to optimize by
 80                // performing a single bounds check against buffer.
 81
 182                FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Minutes, buffer, 24);
 183                buffer[23] = Utf8Constants.Colon;
 184                FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Hours, buffer, 21);
 185                buffer[20] = sign;
 186                buffer[19] = Utf8Constants.Space;
 187            }
 88
 189            return true;
 190        }
 91    }
 92}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.L.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    public static partial class Utf8Formatter
 8    {
 9        // Rfc1123 - lowercase
 10        //
 11        //   01234567890123456789012345678
 12        //   -----------------------------
 13        //   tue, 03 jan 2017 08:08:05 gmt
 14        //
 15        private static bool TryFormatDateTimeL(DateTime value, Span<byte> buffer, out int bytesWritten)
 116        {
 17            // Writing the check in this fashion elides all bounds checks on 'buffer'
 18            // for the remainder of the method.
 119            if ((uint)28 >= (uint)buffer.Length)
 120            {
 121                bytesWritten = 0;
 122                return false;
 23            }
 24
 125            var dayAbbrev = DayAbbreviationsLowercase[(int)value.DayOfWeek];
 26
 127            buffer[0] = (byte)dayAbbrev;
 128            dayAbbrev >>= 8;
 129            buffer[1] = (byte)dayAbbrev;
 130            dayAbbrev >>= 8;
 131            buffer[2] = (byte)dayAbbrev;
 132            buffer[3] = Utf8Constants.Comma;
 133            buffer[4] = Utf8Constants.Space;
 34
 135            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, buffer, 5);
 136            buffer[7] = Utf8Constants.Space;
 37
 138            var monthAbbrev = MonthAbbreviationsLowercase[value.Month - 1];
 139            buffer[8] = (byte)monthAbbrev;
 140            monthAbbrev >>= 8;
 141            buffer[9] = (byte)monthAbbrev;
 142            monthAbbrev >>= 8;
 143            buffer[10] = (byte)monthAbbrev;
 144            buffer[11] = Utf8Constants.Space;
 45
 146            FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, buffer, 12);
 147            buffer[16] = Utf8Constants.Space;
 48
 149            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, buffer, 17);
 150            buffer[19] = Utf8Constants.Colon;
 51
 152            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, buffer, 20);
 153            buffer[22] = Utf8Constants.Colon;
 54
 155            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, buffer, 23);
 156            buffer[25] = Utf8Constants.Space;
 57
 158            buffer[26] = GMT1Lowercase;
 159            buffer[27] = GMT2Lowercase;
 160            buffer[28] = GMT3Lowercase;
 61
 162            bytesWritten = 29;
 163            return true;
 164        }
 65    }
 66}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.O.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    public static partial class Utf8Formatter
 8    {
 9        //
 10        // Roundtrippable format. One of
 11        //
 12        //   012345678901234567890123456789012
 13        //   ---------------------------------
 14        //   2017-06-12T05:30:45.7680000-07:00
 15        //   2017-06-12T05:30:45.7680000Z           (Z is short for "+00:00" but also distinguishes DateTimeKind.Utc fro
 16        //   2017-06-12T05:30:45.7680000            (interpreted as local time wrt to current time zone)
 17        //
 18        private static bool TryFormatDateTimeO(DateTime value, TimeSpan offset, Span<byte> buffer, out int bytesWritten)
 119        {
 20            const int MinimumBytesNeeded = 27;
 21
 122            int bytesRequired = MinimumBytesNeeded;
 123            DateTimeKind kind = DateTimeKind.Local;
 24
 125            if (offset == Utf8Constants.s_nullUtcOffset)
 126            {
 127                kind = value.Kind;
 128                if (kind == DateTimeKind.Local)
 129                {
 130                    offset = TimeZoneInfo.Local.GetUtcOffset(value);
 131                    bytesRequired += 6;
 132                }
 133                else if (kind == DateTimeKind.Utc)
 134                {
 135                    bytesRequired += 1;
 136                }
 137            }
 38            else
 139            {
 140                bytesRequired += 6;
 141            }
 42
 143            if (buffer.Length < bytesRequired)
 144            {
 145                bytesWritten = 0;
 146                return false;
 47            }
 48
 149            bytesWritten = bytesRequired;
 50
 51            // Hoist most of the bounds checks on buffer.
 352            { var unused = buffer[MinimumBytesNeeded - 1]; }
 53
 154            FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, buffer, 0);
 155            buffer[4] = Utf8Constants.Minus;
 56
 157            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Month, buffer, 5);
 158            buffer[7] = Utf8Constants.Minus;
 59
 160            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, buffer, 8);
 161            buffer[10] = TimeMarker;
 62
 163            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, buffer, 11);
 164            buffer[13] = Utf8Constants.Colon;
 65
 166            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, buffer, 14);
 167            buffer[16] = Utf8Constants.Colon;
 68
 169            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, buffer, 17);
 170            buffer[19] = Utf8Constants.Period;
 71
 172            FormattingHelpers.WriteDigits((uint)((ulong)value.Ticks % (ulong)TimeSpan.TicksPerSecond), buffer.Slice(20, 
 73
 174            if (kind == DateTimeKind.Local)
 175            {
 76                byte sign;
 77
 178                if (offset < default(TimeSpan) /* a "const" version of TimeSpan.Zero */)
 179                {
 180                    sign = Utf8Constants.Minus;
 181                    offset = TimeSpan.FromTicks(-offset.Ticks);
 182                }
 83                else
 184                {
 185                    sign = Utf8Constants.Plus;
 186                }
 87
 88                // Writing the value backward allows the JIT to optimize by
 89                // performing a single bounds check against buffer.
 90
 191                FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Minutes, buffer, 31);
 192                buffer[30] = Utf8Constants.Colon;
 193                FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Hours, buffer, 28);
 194                buffer[27] = sign;
 95
 196            }
 197            else if (kind == DateTimeKind.Utc)
 198            {
 199                buffer[27] = UtcMarker;
 1100            }
 101
 1102            return true;
 1103        }
 104    }
 105}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Date.R.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    public static partial class Utf8Formatter
 8    {
 9        // Rfc1123
 10        //
 11        //   01234567890123456789012345678
 12        //   -----------------------------
 13        //   Tue, 03 Jan 2017 08:08:05 GMT
 14        //
 15        private static bool TryFormatDateTimeR(DateTime value, Span<byte> buffer, out int bytesWritten)
 116        {
 17            // Writing the check in this fashion elides all bounds checks on 'buffer'
 18            // for the remainder of the method.
 119            if ((uint)28 >= (uint)buffer.Length)
 120            {
 121                bytesWritten = 0;
 122                return false;
 23            }
 24
 125            var dayAbbrev = DayAbbreviations[(int)value.DayOfWeek];
 26
 127            buffer[0] = (byte)dayAbbrev;
 128            dayAbbrev >>= 8;
 129            buffer[1] = (byte)dayAbbrev;
 130            dayAbbrev >>= 8;
 131            buffer[2] = (byte)dayAbbrev;
 132            buffer[3] = Utf8Constants.Comma;
 133            buffer[4] = Utf8Constants.Space;
 34
 135            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, buffer, 5);
 136            buffer[7] = Utf8Constants.Space;
 37
 138            var monthAbbrev = MonthAbbreviations[value.Month - 1];
 139            buffer[8] = (byte)monthAbbrev;
 140            monthAbbrev >>= 8;
 141            buffer[9] = (byte)monthAbbrev;
 142            monthAbbrev >>= 8;
 143            buffer[10] = (byte)monthAbbrev;
 144            buffer[11] = Utf8Constants.Space;
 45
 146            FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, buffer, 12);
 147            buffer[16] = Utf8Constants.Space;
 48
 149            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, buffer, 17);
 150            buffer[19] = Utf8Constants.Colon;
 51
 152            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, buffer, 20);
 153            buffer[22] = Utf8Constants.Colon;
 54
 155            FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, buffer, 23);
 156            buffer[25] = Utf8Constants.Space;
 57
 158            buffer[26] = GMT1;
 159            buffer[27] = GMT2;
 160            buffer[28] = GMT3;
 61
 162            bytesWritten = 29;
 163            return true;
 164        }
 65    }
 66}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Decimal.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6
 7namespace System.Buffers.Text
 8{
 9    public static partial class Utf8Formatter
 10    {
 11        /// <summary>
 12        /// Formats a Decimal as a UTF8 string.
 13        /// </summary>
 14        /// <param name="value">Value to format</param>
 15        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 16        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 17        /// <param name="format">The standard format to use</param>
 18        /// <returns>
 19        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 20        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 21        /// </returns>
 22        /// <remarks>
 23        /// Formats supported:
 24        ///     G/g  (default)
 25        ///     F/f             12.45       Fixed point
 26        ///     E/e             1.245000e1  Exponential
 27        /// </remarks>
 28        /// <exceptions>
 29        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 30        /// </exceptions>
 31        public static bool TryFormat(decimal value, Span<byte> buffer, out int bytesWritten, StandardFormat format = def
 132        {
 133            if (format.IsDefault)
 134            {
 135                format = 'G';
 136            }
 37
 138            switch (format.Symbol)
 39            {
 40                case 'g':
 41                case 'G':
 142                    {
 143                        if (format.Precision != StandardFormat.NoPrecision)
 144                            throw new NotSupportedException(SR.Argument_GWithPrecisionNotSupported);
 145                        NumberBuffer number = default;
 146                        Number.DecimalToNumber(value, ref number);
 147                        if (number.Digits[0] == 0)
 148                        {
 149                            number.IsNegative = false; // For Decimals, -0 must print as normal 0.
 150                        }
 151                        bool success = TryFormatDecimalG(ref number, buffer, out bytesWritten);
 52#if DEBUG
 53                        // This DEBUG segment exists to close a code coverage hole inside TryFormatDecimalG(). Because w
 54                        // TryFormatDecimalG() a number where trailing zeros before the decimal point have been cropped.
 55                        // ourselves and make a second call to ensure we get the same outcome.
 156                        if (success)
 157                        {
 158                            Span<byte> digits = number.Digits;
 159                            int numDigits = number.NumDigits;
 160                            if (numDigits != 0 && number.Scale == numDigits && digits[numDigits - 1] == '0')
 161                            {
 162                                while (numDigits != 0 && digits[numDigits - 1] == '0')
 163                                {
 164                                    digits[numDigits - 1] = 0;
 165                                    numDigits--;
 166                                }
 67
 168                                number.CheckConsistency();
 69
 170                                byte[] buffer2 = new byte[buffer.Length];
 171                                bool success2 = TryFormatDecimalG(ref number, buffer2, out int bytesWritten2);
 172                                Debug.Assert(success2);
 173                                Debug.Assert(bytesWritten2 == bytesWritten);
 374                                for (int i = 0; i < bytesWritten; i++)
 175                                {
 176                                    Debug.Assert(buffer[i] == buffer2[i]);
 177                                }
 178                            }
 79
 180                        }
 81#endif // DEBUG
 182                        return success;
 83                    }
 84
 85                case 'f':
 86                case 'F':
 187                    {
 188                        NumberBuffer number = default;
 189                        Number.DecimalToNumber(value, ref number);
 190                        byte precision = (format.Precision == StandardFormat.NoPrecision) ? (byte)2 : format.Precision;
 191                        Number.RoundNumber(ref number, number.Scale + precision);
 192                        Debug.Assert(!(number.Digits[0] == 0 && number.IsNegative));   // For Decimals, -0 must print as
 193                        return TryFormatDecimalF(ref number, buffer, out bytesWritten, precision);
 94                    }
 95
 96                case 'e':
 97                case 'E':
 198                    {
 199                        NumberBuffer number = default;
 1100                        Number.DecimalToNumber(value, ref number);
 1101                        byte precision = (format.Precision == StandardFormat.NoPrecision) ? (byte)6 : format.Precision;
 1102                        Number.RoundNumber(ref number, precision + 1);
 1103                        Debug.Assert(!(number.Digits[0] == 0 && number.IsNegative));   // For Decimals, -0 must print as
 1104                        return TryFormatDecimalE(ref number, buffer, out bytesWritten, precision, exponentSymbol: (byte)
 105                    }
 106
 107                default:
 1108                    return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 109            }
 1110        }
 111    }
 112}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Decimal.E.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6
 7namespace System.Buffers.Text
 8{
 9    public static partial class Utf8Formatter
 10    {
 11        private static bool TryFormatDecimalE(ref NumberBuffer number, Span<byte> buffer, out int bytesWritten, byte pre
 112        {
 13            const int NumExponentDigits = 3;
 14
 115            int scale = number.Scale;
 116            ReadOnlySpan<byte> digits = number.Digits;
 17
 118            int numBytesNeeded =
 119                ((number.IsNegative) ? 1 : 0) // minus sign
 120                + 1  // digits before the decimal point (exactly 1)
 121                + ((precision == 0) ? 0 : (precision + 1)) // period and the digits after the decimal point
 122                + 2  // 'E' or 'e' followed by '+' or '-'
 123                + NumExponentDigits; // exponent digits
 24
 125            if (buffer.Length < numBytesNeeded)
 126            {
 127                bytesWritten = 0;
 128                return false;
 29            }
 30
 131            int dstIndex = 0;
 132            int srcIndex = 0;
 133            if (number.IsNegative)
 134            {
 135                buffer[dstIndex++] = Utf8Constants.Minus;
 136            }
 37
 38            //
 39            // Emit exactly one digit before the decimal point.
 40            //
 41            int exponent;
 142            byte firstDigit = digits[srcIndex];
 143            if (firstDigit == 0)
 144            {
 145                buffer[dstIndex++] = (byte)'0';  // Special case: number before the decimal point is exactly 0: Number d
 146                exponent = 0;
 147            }
 48            else
 149            {
 150                buffer[dstIndex++] = firstDigit;
 151                srcIndex++;
 152                exponent = scale - 1;
 153            }
 54
 155            if (precision > 0)
 156            {
 157                buffer[dstIndex++] = Utf8Constants.Period;
 58
 59                //
 60                // Emit digits after the decimal point.
 61                //
 162                int numDigitsEmitted = 0;
 163                while (numDigitsEmitted < precision)
 164                {
 165                    byte digit = digits[srcIndex];
 166                    if (digit == 0)
 167                    {
 168                        while (numDigitsEmitted++ < precision)
 169                        {
 170                            buffer[dstIndex++] = (byte)'0';
 171                        }
 172                        break;
 73                    }
 174                    buffer[dstIndex++] = digit;
 175                    srcIndex++;
 176                    numDigitsEmitted++;
 177                }
 178            }
 79
 80            // Emit the exponent symbol
 181            buffer[dstIndex++] = exponentSymbol;
 182            if (exponent >= 0)
 183            {
 184                buffer[dstIndex++] = Utf8Constants.Plus;
 185            }
 86            else
 187            {
 188                buffer[dstIndex++] = Utf8Constants.Minus;
 189                exponent = -exponent;
 190            }
 91
 192            Debug.Assert(exponent < Number.DECIMAL_PRECISION, "If you're trying to reuse this routine for double/float, 
 93
 94            // Emit exactly three digits for the exponent.
 195            buffer[dstIndex++] = (byte)'0'; // The exponent for Decimal can never exceed 28 (let alone 99)
 196            buffer[dstIndex++] = (byte)((exponent / 10) + '0');
 197            buffer[dstIndex++] = (byte)((exponent % 10) + '0');
 98
 199            Debug.Assert(dstIndex == numBytesNeeded);
 1100            bytesWritten = numBytesNeeded;
 1101            return true;
 1102        }
 103    }
 104}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Decimal.F.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6
 7namespace System.Buffers.Text
 8{
 9    public static partial class Utf8Formatter
 10    {
 11        private static bool TryFormatDecimalF(ref NumberBuffer number, Span<byte> buffer, out int bytesWritten, byte pre
 112        {
 113            int scale = number.Scale;
 114            ReadOnlySpan<byte> digits = number.Digits;
 15
 116            int numBytesNeeded =
 117                ((number.IsNegative) ? 1 : 0) // minus sign
 118                + ((scale <= 0) ? 1 : scale)  // digits before the decimal point (minimum 1)
 119                + ((precision == 0) ? 0 : (precision + 1)); // if specified precision != 0, the decimal point and the di
 20
 121            if (buffer.Length < numBytesNeeded)
 122            {
 123                bytesWritten = 0;
 124                return false;
 25            }
 26
 127            int srcIndex = 0;
 128            int dstIndex = 0;
 129            if (number.IsNegative)
 130            {
 131                buffer[dstIndex++] = Utf8Constants.Minus;
 132            }
 33
 34            //
 35            // Emit digits before the decimal point.
 36            //
 137            if (scale <= 0)
 138            {
 139                buffer[dstIndex++] = (byte)'0';  // The integer portion is 0 and not stored. The formatter, however, nee
 140            }
 41            else
 142            {
 143                while (srcIndex < scale)
 144                {
 145                    byte digit = digits[srcIndex];
 146                    if (digit == 0)
 147                    {
 148                        int numTrailingZeroes = scale - srcIndex;
 349                        for (int i = 0; i < numTrailingZeroes; i++)
 150                        {
 151                            buffer[dstIndex++] = (byte)'0';
 152                        }
 153                        break;
 54                    }
 55
 156                    buffer[dstIndex++] = digit;
 157                    srcIndex++;
 158                }
 159            }
 60
 161            if (precision > 0)
 162            {
 163                buffer[dstIndex++] = Utf8Constants.Period;
 64
 65                //
 66                // Emit digits after the decimal point.
 67                //
 168                int numDigitsEmitted = 0;
 169                if (scale < 0)
 170                {
 171                    int numLeadingZeroesToEmit = Math.Min((int)precision, -scale);
 372                    for (int i = 0; i < numLeadingZeroesToEmit; i++)
 173                    {
 174                        buffer[dstIndex++] = (byte)'0';
 175                    }
 176                    numDigitsEmitted += numLeadingZeroesToEmit;
 177                }
 78
 179                while (numDigitsEmitted < precision)
 180                {
 181                    byte digit = digits[srcIndex];
 182                    if (digit == 0)
 183                    {
 184                        while (numDigitsEmitted++ < precision)
 185                        {
 186                            buffer[dstIndex++] = (byte)'0';
 187                        }
 188                        break;
 89                    }
 190                    buffer[dstIndex++] = digit;
 191                    srcIndex++;
 192                    numDigitsEmitted++;
 193                }
 194            }
 95
 196            Debug.Assert(dstIndex == numBytesNeeded);
 197            bytesWritten = numBytesNeeded;
 198            return true;
 199        }
 100    }
 101}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Decimal.G.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6using System.Runtime.CompilerServices;
 7
 8namespace System.Buffers.Text
 9{
 10    public static partial class Utf8Formatter
 11    {
 12        private static bool TryFormatDecimalG(ref NumberBuffer number, Span<byte> buffer, out int bytesWritten)
 113        {
 114            int scale = number.Scale;
 115            ReadOnlySpan<byte> digits = number.Digits;
 116            int numDigits = number.NumDigits;
 17
 118            bool isFraction = scale < numDigits;
 19            int numBytesNeeded;
 120            if (isFraction)
 121            {
 122                numBytesNeeded = numDigits + 1;  // A fraction. Must include one for the decimal point.
 123                if (scale <= 0)
 124                {
 125                    numBytesNeeded += 1 + (-scale); // A fraction of the form 0.ddd. Need to emit the non-stored 0 befor
 126                }
 127            }
 28            else
 129            {
 130                numBytesNeeded = ((scale <= 0) ? 1 : scale); // An integral. Just emit the digits before the decimal poi
 131            }
 32
 133            if (number.IsNegative)
 134            {
 135                numBytesNeeded++; // And the minus sign.
 136            }
 37
 138            if (buffer.Length < numBytesNeeded)
 139            {
 140                bytesWritten = 0;
 141                return false;
 42            }
 43
 144            int srcIndex = 0;
 145            int dstIndex = 0;
 46
 147            if (number.IsNegative)
 148            {
 149                buffer[dstIndex++] = Utf8Constants.Minus;
 150            }
 51
 52            //
 53            // Emit digits before the decimal point.
 54            //
 155            if (scale <= 0)
 156            {
 157                buffer[dstIndex++] = (byte)'0';  // The integer portion is 0 and not stored. The formatter, however, nee
 158            }
 59            else
 160            {
 161                while (srcIndex < scale)
 162                {
 163                    byte digit = digits[srcIndex];
 164                    if (digit == 0)
 165                    {
 166                        int numTrailingZeroes = scale - srcIndex;
 367                        for (int i = 0; i < numTrailingZeroes; i++)
 168                        {
 169                            buffer[dstIndex++] = (byte)'0';
 170                        }
 171                        break;
 72                    }
 73
 174                    buffer[dstIndex++] = digit;
 175                    srcIndex++;
 176                }
 177            }
 78
 179            if (isFraction)
 180            {
 181                buffer[dstIndex++] = Utf8Constants.Period;
 82
 83                //
 84                // Emit digits after the decimal point.
 85                //
 186                if (scale < 0)
 187                {
 188                    int numLeadingZeroesToEmit = -scale;
 389                    for (int i = 0; i < numLeadingZeroesToEmit; i++)
 190                    {
 191                        buffer[dstIndex++] = (byte)'0';
 192                    }
 193                }
 94
 95                byte digit;
 196                while ((digit = digits[srcIndex++]) != 0)
 197                {
 198                    buffer[dstIndex++] = digit;
 199                }
 1100            }
 101
 1102            Debug.Assert(dstIndex == numBytesNeeded);
 103
 1104            bytesWritten = numBytesNeeded;
 1105            return true;
 1106        }
 107    }
 108}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Float.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6using System.Globalization;
 7
 8namespace System.Buffers.Text
 9{
 10    public static partial class Utf8Formatter
 11    {
 12        /// <summary>
 13        /// Formats a Double as a UTF8 string.
 14        /// </summary>
 15        /// <param name="value">Value to format</param>
 16        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 17        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 18        /// <param name="format">The standard format to use</param>
 19        /// <returns>
 20        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 21        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 22        /// </returns>
 23        /// <remarks>
 24        /// Formats supported:
 25        ///     G/g  (default)
 26        ///     F/f             12.45       Fixed point
 27        ///     E/e             1.245000e1  Exponential
 28        /// </remarks>
 29        /// <exceptions>
 30        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 31        /// </exceptions>
 32        public static bool TryFormat(double value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defa
 133        {
 134            return TryFormatFloatingPoint<double>(value, buffer, out bytesWritten, format);
 135        }
 36
 37        /// <summary>
 38        /// Formats a Single as a UTF8 string.
 39        /// </summary>
 40        /// <param name="value">Value to format</param>
 41        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 42        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 43        /// <param name="format">The standard format to use</param>
 44        /// <returns>
 45        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 46        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 47        /// </returns>
 48        /// <remarks>
 49        /// Formats supported:
 50        ///     G/g  (default)
 51        ///     F/f             12.45       Fixed point
 52        ///     E/e             1.245000e1  Exponential
 53        /// </remarks>
 54        /// <exceptions>
 55        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 56        /// </exceptions>
 57        public static bool TryFormat(float value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defau
 158        {
 159            return TryFormatFloatingPoint<float>(value, buffer, out bytesWritten, format);
 160        }
 61
 62        //
 63        // Common handler for TryFormat(Double) and TryFormat(Single). You may notice that this particular routine isn't
 64        // of things. The DoubleToNumber() code is incredibly complex and is one of the few pieces of Number formatting 
 65        // be preferable not to have another version of that lying around. Until we really hit a scenario where floating
 66        // make do with this.
 67        //
 68        private static bool TryFormatFloatingPoint<T>(T value, Span<byte> buffer, out int bytesWritten, StandardFormat f
 169        {
 170            if (format.IsDefault)
 171            {
 172                format = 'G';
 173            }
 74
 175            switch (format.Symbol)
 76            {
 77                case 'g':
 78                case 'G':
 179                    if (format.Precision != StandardFormat.NoPrecision)
 180                        throw new NotSupportedException(SR.Argument_GWithPrecisionNotSupported);
 181                    break;
 82
 83                case 'f':
 84                case 'F':
 85                case 'e':
 86                case 'E':
 187                    break;
 88
 89                default:
 190                    return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 91            }
 92
 193            string formatString = format.ToString();
 194            string utf16Text = value.ToString(formatString, CultureInfo.InvariantCulture);
 195            int length = utf16Text.Length;
 196            if (length > buffer.Length)
 197            {
 198                bytesWritten = 0;
 199                return false;
 100            }
 101
 3102            for (int i = 0; i < length; i++)
 1103            {
 1104                Debug.Assert(utf16Text[i] < 128, "A culture-invariant ToString() of a floating point expected to produce
 1105                buffer[i] = (byte)(utf16Text[i]);
 1106            }
 107
 1108            bytesWritten = length;
 1109            return true;
 1110        }
 111    }
 112}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Guid.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Runtime.InteropServices;
 6
 7namespace System.Buffers.Text
 8{
 9    public static partial class Utf8Formatter
 10    {
 11        #region Constants
 12
 13        private const byte OpenBrace = (byte)'{';
 14        private const byte CloseBrace = (byte)'}';
 15
 16        private const byte OpenParen = (byte)'(';
 17        private const byte CloseParen = (byte)')';
 18
 19        private const byte Dash = (byte)'-';
 20
 21        #endregion Constants
 22
 23        /// <summary>
 24        /// Formats a Guid as a UTF8 string.
 25        /// </summary>
 26        /// <param name="value">Value to format</param>
 27        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 28        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 29        /// <param name="format">The standard format to use</param>
 30        /// <returns>
 31        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 32        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 33        /// </returns>
 34        /// <remarks>
 35        /// Formats supported:
 36        ///     D (default)     nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn
 37        ///     B               {nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}
 38        ///     P               (nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn)
 39        ///     N               nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
 40        /// </remarks>
 41        /// <exceptions>
 42        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 43        /// </exceptions>
 44        public static bool TryFormat(Guid value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defaul
 145        {
 46            const int INSERT_DASHES = unchecked((int)0x80000000);
 47            const int NO_DASHES = 0;
 48            const int INSERT_CURLY_BRACES = (CloseBrace << 16) | (OpenBrace << 8);
 49            const int INSERT_ROUND_BRACES = (CloseParen << 16) | (OpenParen << 8);
 50            const int NO_BRACES = 0;
 51            const int LEN_GUID_BASE = 32;
 52            const int LEN_ADD_DASHES = 4;
 53            const int LEN_ADD_BRACES = 2;
 54
 55            // This is a 32-bit value whose contents (where 0 is the low byte) are:
 56            // 0th byte: minimum required length of the output buffer,
 57            // 1st byte: the ASCII byte to insert for the opening brace position (or 0 if no braces),
 58            // 2nd byte: the ASCII byte to insert for the closing brace position (or 0 if no braces),
 59            // 3rd byte: high bit set if dashes are to be inserted.
 60            //
 61            // The reason for keeping a single flag instead of separate vars is that we can avoid register spillage
 62            // as we build up the output value.
 63            int flags;
 64
 165            switch (FormattingHelpers.GetSymbolOrDefault(format, 'D'))
 66            {
 67                case 'D': // nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn
 168                    flags = INSERT_DASHES + NO_BRACES + LEN_GUID_BASE + LEN_ADD_DASHES;
 169                    break;
 70
 71                case 'B': // {nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}
 172                    flags = INSERT_DASHES + INSERT_CURLY_BRACES + LEN_GUID_BASE + LEN_ADD_DASHES + LEN_ADD_BRACES;
 173                    break;
 74
 75                case 'P': // (nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn)
 176                    flags = INSERT_DASHES + INSERT_ROUND_BRACES + LEN_GUID_BASE + LEN_ADD_DASHES + LEN_ADD_BRACES;
 177                    break;
 78
 79                case 'N': // nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
 180                    flags = NO_BRACES + NO_DASHES + LEN_GUID_BASE;
 181                    break;
 82
 83                default:
 184                    return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 85            }
 86
 87            // At this point, the low byte of flags contains the minimum required length
 88
 189            if ((byte)flags > buffer.Length)
 190            {
 191                bytesWritten = 0;
 192                return false;
 93            }
 94
 195            bytesWritten = (byte)flags;
 196            flags >>= 8;
 97
 98            // At this point, the low byte of flags contains the opening brace char (if any)
 99
 1100            if ((byte)flags != 0)
 1101            {
 1102                buffer[0] = (byte)flags;
 1103                buffer = buffer.Slice(1);
 1104            }
 1105            flags >>= 8;
 106
 107            // At this point, the low byte of flags contains the closing brace char (if any)
 108            // And since we're performing arithmetic shifting the high bit of flags is set (flags is negative) if dashes
 109
 1110            DecomposedGuid guidAsBytes = default;
 1111            guidAsBytes.Guid = value;
 112
 113            // When a GUID is blitted, the first three components are little-endian, and the last component is big-endia
 114
 115            // The line below forces the JIT to hoist the bounds check for the following segment.
 116            // The JIT will optimize away the read, but it cannot optimize away the bounds check
 117            // because it may have an observeable side effect (throwing).
 118            // We use 8 instead of 7 so that we also capture the dash if we're asked to insert one.
 119
 3120            { var unused = buffer[8]; }
 1121            FormattingHelpers.WriteHexByte(guidAsBytes.Byte03, buffer, 0, FormattingHelpers.HexCasing.Lowercase);
 1122            FormattingHelpers.WriteHexByte(guidAsBytes.Byte02, buffer, 2, FormattingHelpers.HexCasing.Lowercase);
 1123            FormattingHelpers.WriteHexByte(guidAsBytes.Byte01, buffer, 4, FormattingHelpers.HexCasing.Lowercase);
 1124            FormattingHelpers.WriteHexByte(guidAsBytes.Byte00, buffer, 6, FormattingHelpers.HexCasing.Lowercase);
 125
 1126            if (flags < 0 /* use dash? */)
 1127            {
 1128                buffer[8] = Dash;
 1129                buffer = buffer.Slice(9);
 1130            }
 131            else
 1132            {
 1133                buffer = buffer.Slice(8);
 1134            }
 135
 3136            { var unused = buffer[4]; }
 1137            FormattingHelpers.WriteHexByte(guidAsBytes.Byte05, buffer, 0, FormattingHelpers.HexCasing.Lowercase);
 1138            FormattingHelpers.WriteHexByte(guidAsBytes.Byte04, buffer, 2, FormattingHelpers.HexCasing.Lowercase);
 139
 1140            if (flags < 0 /* use dash? */)
 1141            {
 1142                buffer[4] = Dash;
 1143                buffer = buffer.Slice(5);
 1144            }
 145            else
 1146            {
 1147                buffer = buffer.Slice(4);
 1148            }
 149
 3150            { var unused = buffer[4]; }
 1151            FormattingHelpers.WriteHexByte(guidAsBytes.Byte07, buffer, 0, FormattingHelpers.HexCasing.Lowercase);
 1152            FormattingHelpers.WriteHexByte(guidAsBytes.Byte06, buffer, 2, FormattingHelpers.HexCasing.Lowercase);
 153
 1154            if (flags < 0 /* use dash? */)
 1155            {
 1156                buffer[4] = Dash;
 1157                buffer = buffer.Slice(5);
 1158            }
 159            else
 1160            {
 1161                buffer = buffer.Slice(4);
 1162            }
 163
 3164            { var unused = buffer[4]; }
 1165            FormattingHelpers.WriteHexByte(guidAsBytes.Byte08, buffer, 0, FormattingHelpers.HexCasing.Lowercase);
 1166            FormattingHelpers.WriteHexByte(guidAsBytes.Byte09, buffer, 2, FormattingHelpers.HexCasing.Lowercase);
 167
 1168            if (flags < 0 /* use dash? */)
 1169            {
 1170                buffer[4] = Dash;
 1171                buffer = buffer.Slice(5);
 1172            }
 173            else
 1174            {
 1175                buffer = buffer.Slice(4);
 1176            }
 177
 3178            { var unused = buffer[11]; } // can't hoist bounds check on the final brace (if exists)
 1179            FormattingHelpers.WriteHexByte(guidAsBytes.Byte10, buffer, 0, FormattingHelpers.HexCasing.Lowercase);
 1180            FormattingHelpers.WriteHexByte(guidAsBytes.Byte11, buffer, 2, FormattingHelpers.HexCasing.Lowercase);
 1181            FormattingHelpers.WriteHexByte(guidAsBytes.Byte12, buffer, 4, FormattingHelpers.HexCasing.Lowercase);
 1182            FormattingHelpers.WriteHexByte(guidAsBytes.Byte13, buffer, 6, FormattingHelpers.HexCasing.Lowercase);
 1183            FormattingHelpers.WriteHexByte(guidAsBytes.Byte14, buffer, 8, FormattingHelpers.HexCasing.Lowercase);
 1184            FormattingHelpers.WriteHexByte(guidAsBytes.Byte15, buffer, 10, FormattingHelpers.HexCasing.Lowercase);
 185
 1186            if ((byte)flags != 0)
 1187            {
 1188                buffer[12] = (byte)flags;
 1189            }
 190
 1191            return true;
 1192        }
 193
 194        /// <summary>
 195        /// Used to provide access to the individual bytes of a GUID.
 196        /// </summary>
 197        [StructLayout(LayoutKind.Explicit)]
 198        private struct DecomposedGuid
 199        {
 200            [FieldOffset(00)] public Guid Guid;
 201            [FieldOffset(00)] public byte Byte00;
 202            [FieldOffset(01)] public byte Byte01;
 203            [FieldOffset(02)] public byte Byte02;
 204            [FieldOffset(03)] public byte Byte03;
 205            [FieldOffset(04)] public byte Byte04;
 206            [FieldOffset(05)] public byte Byte05;
 207            [FieldOffset(06)] public byte Byte06;
 208            [FieldOffset(07)] public byte Byte07;
 209            [FieldOffset(08)] public byte Byte08;
 210            [FieldOffset(09)] public byte Byte09;
 211            [FieldOffset(10)] public byte Byte10;
 212            [FieldOffset(11)] public byte Byte11;
 213            [FieldOffset(12)] public byte Byte12;
 214            [FieldOffset(13)] public byte Byte13;
 215            [FieldOffset(14)] public byte Byte14;
 216            [FieldOffset(15)] public byte Byte15;
 217        }
 218    }
 219}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    /// <summary>
 8    /// Methods to format common data types as Utf8 strings.
 9    /// </summary>
 10    public static partial class Utf8Formatter
 11    {
 12        /// <summary>
 13        /// Formats a Byte as a UTF8 string.
 14        /// </summary>
 15        /// <param name="value">Value to format</param>
 16        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 17        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 18        /// <param name="format">The standard format to use</param>
 19        /// <returns>
 20        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 21        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 22        /// </returns>
 23        /// <remarks>
 24        /// Formats supported:
 25        ///     G/g (default)
 26        ///     D/d             32767
 27        ///     N/n             32,767
 28        ///     X/x             7fff
 29        /// </remarks>
 30        /// <exceptions>
 31        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 32        /// </exceptions>
 33        public static bool TryFormat(byte value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defaul
 134            => TryFormatUInt64(value, buffer, out bytesWritten, format);
 35
 36        /// <summary>
 37        /// Formats an SByte as a UTF8 string.
 38        /// </summary>
 39        /// <param name="value">Value to format</param>
 40        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 41        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 42        /// <param name="format">The standard format to use</param>
 43        /// <returns>
 44        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 45        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 46        /// </returns>
 47        /// <remarks>
 48        /// Formats supported:
 49        ///     G/g (default)
 50        ///     D/d             32767
 51        ///     N/n             32,767
 52        ///     X/x             7fff
 53        /// </remarks>
 54        /// <exceptions>
 55        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 56        /// </exceptions>
 57        [CLSCompliant(false)]
 58        public static bool TryFormat(sbyte value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defau
 159            => TryFormatInt64(value, 0xff, buffer, out bytesWritten, format);
 60
 61        /// <summary>
 62        /// Formats a Unt16 as a UTF8 string.
 63        /// </summary>
 64        /// <param name="value">Value to format</param>
 65        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 66        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 67        /// <param name="format">The standard format to use</param>
 68        /// <returns>
 69        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 70        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 71        /// </returns>
 72        /// <remarks>
 73        /// Formats supported:
 74        ///     G/g (default)
 75        ///     D/d             32767
 76        ///     N/n             32,767
 77        ///     X/x             7fff
 78        /// </remarks>
 79        /// <exceptions>
 80        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 81        /// </exceptions>
 82        [CLSCompliant(false)]
 83        public static bool TryFormat(ushort value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defa
 184            => TryFormatUInt64(value, buffer, out bytesWritten, format);
 85
 86        /// <summary>
 87        /// Formats an Int16 as a UTF8 string.
 88        /// </summary>
 89        /// <param name="value">Value to format</param>
 90        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 91        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 92        /// <param name="format">The standard format to use</param>
 93        /// <returns>
 94        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 95        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 96        /// </returns>
 97        /// <remarks>
 98        /// Formats supported:
 99        ///     G/g (default)
 100        ///     D/d             32767
 101        ///     N/n             32,767
 102        ///     X/x             7fff
 103        /// </remarks>
 104        /// <exceptions>
 105        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 106        /// </exceptions>
 107        public static bool TryFormat(short value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defau
 1108            => TryFormatInt64(value, 0xffff, buffer, out bytesWritten, format);
 109
 110        /// <summary>
 111        /// Formats a UInt32 as a UTF8 string.
 112        /// </summary>
 113        /// <param name="value">Value to format</param>
 114        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 115        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 116        /// <param name="format">The standard format to use</param>
 117        /// <returns>
 118        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 119        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 120        /// </returns>
 121        /// <remarks>
 122        /// Formats supported:
 123        ///     G/g (default)
 124        ///     D/d             32767
 125        ///     N/n             32,767
 126        ///     X/x             7fff
 127        /// </remarks>
 128        /// <exceptions>
 129        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 130        /// </exceptions>
 131        [CLSCompliant(false)]
 132        public static bool TryFormat(uint value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defaul
 1133            => TryFormatUInt64(value, buffer, out bytesWritten, format);
 134
 135        /// <summary>
 136        /// Formats an Int32 as a UTF8 string.
 137        /// </summary>
 138        /// <param name="value">Value to format</param>
 139        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 140        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 141        /// <param name="format">The standard format to use</param>
 142        /// <returns>
 143        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 144        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 145        /// </returns>
 146        /// <remarks>
 147        /// Formats supported:
 148        ///     G/g (default)
 149        ///     D/d             32767
 150        ///     N/n             32,767
 151        ///     X/x             7fff
 152        /// </remarks>
 153        /// <exceptions>
 154        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 155        /// </exceptions>
 156        public static bool TryFormat(int value, Span<byte> buffer, out int bytesWritten, StandardFormat format = default
 1157            => TryFormatInt64(value, 0xffffffff, buffer, out bytesWritten, format);
 158
 159        /// <summary>
 160        /// Formats a UInt64 as a UTF8 string.
 161        /// </summary>
 162        /// <param name="value">Value to format</param>
 163        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 164        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 165        /// <param name="format">The standard format to use</param>
 166        /// <returns>
 167        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 168        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 169        /// </returns>
 170        /// <remarks>
 171        /// Formats supported:
 172        ///     G/g (default)
 173        ///     D/d             32767
 174        ///     N/n             32,767
 175        ///     X/x             7fff
 176        /// </remarks>
 177        /// <exceptions>
 178        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 179        /// </exceptions>
 180        [CLSCompliant(false)]
 181        public static bool TryFormat(ulong value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defau
 1182            => TryFormatUInt64(value, buffer, out bytesWritten, format);
 183
 184        /// <summary>
 185        /// Formats an Int64 as a UTF8 string.
 186        /// </summary>
 187        /// <param name="value">Value to format</param>
 188        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 189        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 190        /// <param name="format">The standard format to use</param>
 191        /// <returns>
 192        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 193        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 194        /// </returns>
 195        /// <remarks>
 196        /// Formats supported:
 197        ///     G/g (default)
 198        ///     D/d             32767
 199        ///     N/n             32,767
 200        ///     X/x             7fff
 201        /// </remarks>
 202        /// <exceptions>
 203        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 204        /// </exceptions>
 205        public static bool TryFormat(long value, Span<byte> buffer, out int bytesWritten, StandardFormat format = defaul
 1206            => TryFormatInt64(value, 0xffffffffffffffff, buffer, out bytesWritten, format);
 207    }
 208}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Signed.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Runtime.CompilerServices;
 6
 7namespace System.Buffers.Text
 8{
 9    /// <summary>
 10    /// Methods to format common data types as Utf8 strings.
 11    /// </summary>
 12    public static partial class Utf8Formatter
 13    {
 14        //
 15        // Common worker for all signed integer TryFormat overloads
 16        //
 17        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 18        private static bool TryFormatInt64(long value, ulong mask, Span<byte> buffer, out int bytesWritten, StandardForm
 119        {
 120            if (format.IsDefault)
 121            {
 122                return TryFormatInt64Default(value, buffer, out bytesWritten);
 23            }
 24
 125            switch (format.Symbol)
 26            {
 27                case 'G':
 28                case 'g':
 129                    if (format.HasPrecision)
 130                        throw new NotSupportedException(SR.Argument_GWithPrecisionNotSupported); // With a precision, 'G
 131                    return TryFormatInt64D(value, format.Precision, buffer, out bytesWritten);
 32
 33                case 'd':
 34                case 'D':
 135                    return TryFormatInt64D(value, format.Precision, buffer, out bytesWritten);
 36
 37                case 'n':
 38                case 'N':
 139                    return TryFormatInt64N(value, format.Precision, buffer, out bytesWritten);
 40
 41                case 'x':
 142                    return TryFormatUInt64X((ulong)value & mask, format.Precision, true, buffer, out bytesWritten);
 43
 44                case 'X':
 145                    return TryFormatUInt64X((ulong)value & mask, format.Precision, false, buffer, out bytesWritten);
 46
 47                default:
 148                    return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 49            }
 150        }
 51    }
 52}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Signed.D.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6using System.Runtime.CompilerServices;
 7
 8namespace System.Buffers.Text
 9{
 10    /// <summary>
 11    /// Methods to format common data types as Utf8 strings.
 12    /// </summary>
 13    public static partial class Utf8Formatter
 14    {
 15        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 16        private static bool TryFormatInt64D(long value, byte precision, Span<byte> buffer, out int bytesWritten)
 117        {
 118            bool insertNegationSign = false;
 119            if (value < 0)
 120            {
 121                insertNegationSign = true;
 122                value = -value;
 123                if (value < 0)
 124                {
 125                    Debug.Assert(value == Int64.MinValue);
 126                    return TryFormatInt64D_MinValue(precision, buffer, out bytesWritten);
 27                }
 128            }
 29
 130            return TryFormatUInt64D((ulong)value, precision, buffer, insertNegationSign, out bytesWritten);
 131        }
 32
 33        [MethodImpl(MethodImplOptions.NoInlining)]
 34        private static bool TryFormatInt64D_MinValue(byte precision, Span<byte> buffer, out int bytesWritten)
 135        {
 36            // Int64.MinValue must be treated specially since its two's complement negation doesn't fit into 64 bits.
 37            // Instead, we'll perform one's complement negation and fix up the +1 later (-x := ~x + 1).
 38            // Int64.MinValue = -9,223,372,036,854,775,808
 39            // Int64.MaxValue =  9,223,372,036,854,775,807
 40
 141            bool retVal = TryFormatUInt64D((ulong)Int64.MaxValue, precision, buffer, insertNegationSign: true, out int t
 142            if (retVal)
 143            {
 144                buffer[tempBytesWritten - 1]++; // bump the last ASCII '7' to an '8'
 145            }
 46
 147            bytesWritten = tempBytesWritten;
 148            return retVal;
 149        }
 50    }
 51}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Signed.Default.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6using System.Runtime.CompilerServices;
 7
 8namespace System.Buffers.Text
 9{
 10    /// <summary>
 11    /// Methods to format common data types as Utf8 strings.
 12    /// </summary>
 13    public static partial class Utf8Formatter
 14    {
 15        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 16        private static bool TryFormatInt64Default(long value, Span<byte> buffer, out int bytesWritten)
 117        {
 118            if ((ulong)value < 10)
 119            {
 120                return TryFormatUInt32SingleDigit((uint)value, buffer, out bytesWritten);
 21            }
 22
 123            if (IntPtr.Size == 8)    // x64
 124            {
 125                return TryFormatInt64MultipleDigits(value, buffer, out bytesWritten);
 26            }
 27            else    // x86
 028            {
 029                if (value <= int.MaxValue && value >= int.MinValue)
 030                {
 031                    return TryFormatInt32MultipleDigits((int)value, buffer, out bytesWritten);
 32                }
 33                else
 034                {
 035                    if (value <= (long)Utf8Constants.BillionMaxUIntValue && value >= -(long)Utf8Constants.BillionMaxUInt
 036                    {
 037                        return value < 0 ?
 038                        TryFormatInt64MoreThanNegativeBillionMaxUInt(-value, buffer, out bytesWritten) :
 039                        TryFormatUInt64LessThanBillionMaxUInt((ulong)value, buffer, out bytesWritten);
 40                    }
 41                    else
 042                    {
 043                        return value < 0 ?
 044                        TryFormatInt64LessThanNegativeBillionMaxUInt(-value, buffer, out bytesWritten) :
 045                        TryFormatUInt64MoreThanBillionMaxUInt((ulong)value, buffer, out bytesWritten);
 46                    }
 47                }
 48            }
 149        }
 50
 51        // TODO: Use this instead of TryFormatInt64Default to format numbers less than int.MaxValue
 52        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 53        private static bool TryFormatInt32Default(int value, Span<byte> buffer, out int bytesWritten)
 54        {
 55            if ((uint)value < 10)
 56            {
 57                return TryFormatUInt32SingleDigit((uint)value, buffer, out bytesWritten);
 58            }
 59            return TryFormatInt32MultipleDigits(value, buffer, out bytesWritten);
 60        }
 61
 62        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 63        private static bool TryFormatInt32MultipleDigits(int value, Span<byte> buffer, out int bytesWritten)
 064        {
 065            if (value < 0)
 066            {
 067                value = -value;
 068                int digitCount = FormattingHelpers.CountDigits((uint)value);
 69                // WriteDigits does not do bounds checks
 070                if (digitCount >= buffer.Length)
 071                {
 072                    bytesWritten = 0;
 073                    return false;
 74                }
 075                buffer[0] = Utf8Constants.Minus;
 076                bytesWritten = digitCount + 1;
 077                FormattingHelpers.WriteDigits((uint)value, buffer.Slice(1, digitCount));
 078                return true;
 79            }
 80            else
 081            {
 082                return TryFormatUInt32MultipleDigits((uint)value, buffer, out bytesWritten);
 83            }
 084        }
 85
 86        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 87        private static bool TryFormatInt64MultipleDigits(long value, Span<byte> buffer, out int bytesWritten)
 188        {
 189            if (value < 0)
 190            {
 191                value = -value;
 192                int digitCount = FormattingHelpers.CountDigits((ulong)value);
 93                // WriteDigits does not do bounds checks
 194                if (digitCount >= buffer.Length)
 195                {
 196                    bytesWritten = 0;
 197                    return false;
 98                }
 199                buffer[0] = Utf8Constants.Minus;
 1100                bytesWritten = digitCount + 1;
 1101                FormattingHelpers.WriteDigits((ulong)value, buffer.Slice(1, digitCount));
 1102                return true;
 103            }
 104            else
 1105            {
 1106                return TryFormatUInt64MultipleDigits((ulong)value, buffer, out bytesWritten);
 107            }
 1108        }
 109
 110        // Split long into two parts that can each fit in a uint - {1-10 digits}{9 digits}
 111        private static bool TryFormatInt64MoreThanNegativeBillionMaxUInt(long value, Span<byte> buffer, out int bytesWri
 0112        {
 0113            uint overNineDigits = (uint)(value / Utf8Constants.Billion);
 0114            uint lastNineDigits = (uint)(value - (overNineDigits * Utf8Constants.Billion));
 115
 0116            int digitCountOverNineDigits = FormattingHelpers.CountDigits(overNineDigits);
 0117            Debug.Assert(digitCountOverNineDigits >= 1 && digitCountOverNineDigits <= 10);
 0118            int digitCount = digitCountOverNineDigits + 9;
 119            // WriteDigits does not do bounds checks
 0120            if (digitCount >= buffer.Length)
 0121            {
 0122                bytesWritten = 0;
 0123                return false;
 124            }
 0125            buffer[0] = Utf8Constants.Minus;
 0126            bytesWritten = digitCount + 1;
 0127            FormattingHelpers.WriteDigits(overNineDigits, buffer.Slice(1, digitCountOverNineDigits));
 0128            FormattingHelpers.WriteDigits(lastNineDigits, buffer.Slice(digitCountOverNineDigits + 1, 9));
 0129            return true;
 0130        }
 131
 132        // Split long into three parts that can each fit in a uint - {1 digit}{9 digits}{9 digits}
 133        private static bool TryFormatInt64LessThanNegativeBillionMaxUInt(long value, Span<byte> buffer, out int bytesWri
 0134        {
 135            // value can still be negative if value == long.MinValue
 136            // Therefore, cast to ulong, since (ulong)value actually equals abs(long.MinValue)
 0137            ulong overNineDigits = (ulong)value / Utf8Constants.Billion;
 0138            uint lastNineDigits = (uint)((ulong)value - (overNineDigits * Utf8Constants.Billion));
 0139            uint overEighteenDigits = (uint)(overNineDigits / Utf8Constants.Billion);
 0140            uint middleNineDigits = (uint)(overNineDigits - (overEighteenDigits * Utf8Constants.Billion));
 141
 0142            int digitCountOverEighteenDigits = FormattingHelpers.CountDigits(overEighteenDigits);
 0143            Debug.Assert(digitCountOverEighteenDigits == 1);
 0144            int digitCount = digitCountOverEighteenDigits + 18;
 145            // WriteDigits does not do bounds checks
 0146            if (digitCount >= buffer.Length)
 0147            {
 0148                bytesWritten = 0;
 0149                return false;
 150            }
 0151            buffer[0] = Utf8Constants.Minus;
 0152            bytesWritten = digitCount + 1;
 0153            FormattingHelpers.WriteDigits(overEighteenDigits, buffer.Slice(1, digitCountOverEighteenDigits));
 0154            FormattingHelpers.WriteDigits(middleNineDigits, buffer.Slice(digitCountOverEighteenDigits + 1, 9));
 0155            FormattingHelpers.WriteDigits(lastNineDigits, buffer.Slice(digitCountOverEighteenDigits + 1 + 9, 9));
 0156            return true;
 0157        }
 158    }
 159}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Signed.N.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6using System.Runtime.CompilerServices;
 7
 8namespace System.Buffers.Text
 9{
 10    /// <summary>
 11    /// Methods to format common data types as Utf8 strings.
 12    /// </summary>
 13    public static partial class Utf8Formatter
 14    {
 15        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 16        private static bool TryFormatInt64N(long value, byte precision, Span<byte> buffer, out int bytesWritten)
 117        {
 118            bool insertNegationSign = false;
 119            if (value < 0)
 120            {
 121                insertNegationSign = true;
 122                value = -value;
 123                if (value < 0)
 124                {
 125                    Debug.Assert(value == Int64.MinValue);
 126                    return TryFormatInt64N_MinValue(precision, buffer, out bytesWritten);
 27                }
 128            }
 29
 130            return TryFormatUInt64N((ulong)value, precision, buffer, insertNegationSign, out bytesWritten);
 131        }
 32
 33        [MethodImpl(MethodImplOptions.NoInlining)]
 34        private static bool TryFormatInt64N_MinValue(byte precision, Span<byte> buffer, out int bytesWritten)
 135        {
 36            // Int64.MinValue must be treated specially since its two's complement negation doesn't fit into 64 bits.
 37            // Instead, we'll perform one's complement negation and fix up the +1 later (-x := ~x + 1).
 38            // Int64.MinValue = -9,223,372,036,854,775,808 (26 digits, including minus and commas)
 39            // Int64.MaxValue =  9,223,372,036,854,775,807
 40
 141            bool retVal = TryFormatUInt64N((ulong)Int64.MaxValue, precision, buffer, insertNegationSign: true, out int t
 142            if (retVal)
 143            {
 144                buffer[25]++; // bump the last ASCII '7' to an '8'
 145            }
 46
 147            bytesWritten = tempBytesWritten;
 148            return retVal;
 149        }
 50    }
 51}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Runtime.CompilerServices;
 6
 7namespace System.Buffers.Text
 8{
 9    /// <summary>
 10    /// Methods to format common data types as Utf8 strings.
 11    /// </summary>
 12    public static partial class Utf8Formatter
 13    {
 14        //
 15        // Common worker for all unsigned integer TryFormat overloads
 16        //
 17        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 18        private static bool TryFormatUInt64(ulong value, Span<byte> buffer, out int bytesWritten, StandardFormat format)
 119        {
 120            if (format.IsDefault)
 121            {
 122                return TryFormatUInt64Default(value, buffer, out bytesWritten);
 23            }
 24
 125            switch (format.Symbol)
 26            {
 27                case 'G':
 28                case 'g':
 129                    if (format.HasPrecision)
 130                        throw new NotSupportedException(SR.Argument_GWithPrecisionNotSupported); // With a precision, 'G
 131                    return TryFormatUInt64D(value, format.Precision, buffer, insertNegationSign: false, out bytesWritten
 32
 33                case 'd':
 34                case 'D':
 135                    return TryFormatUInt64D(value, format.Precision, buffer, insertNegationSign: false, out bytesWritten
 36
 37                case 'n':
 38                case 'N':
 139                    return TryFormatUInt64N(value, format.Precision, buffer, insertNegationSign: false, out bytesWritten
 40
 41                case 'x':
 142                    return TryFormatUInt64X(value, format.Precision, true /* useLower */, buffer, out bytesWritten);
 43
 44                case 'X':
 145                    return TryFormatUInt64X(value, format.Precision, false /* useLower */, buffer, out bytesWritten);
 46
 47                default:
 148                    return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 49            }
 150        }
 51    }
 52}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.D.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    /// <summary>
 8    /// Methods to format common data types as Utf8 strings.
 9    /// </summary>
 10    public static partial class Utf8Formatter
 11    {
 12        private static bool TryFormatUInt64D(ulong value, byte precision, Span<byte> buffer, bool insertNegationSign, ou
 113        {
 14            // Calculate the actual digit count and the number of padding zeroes requested.
 15            // From all of this we can get the required buffer length.
 16
 117            int digitCount = FormattingHelpers.CountDigits(value);
 118            int leadingZeroCount = ((precision == StandardFormat.NoPrecision) ? 0 : (int)precision) - digitCount;
 119            if (leadingZeroCount < 0)
 120            {
 121                leadingZeroCount = 0;
 122            }
 23
 124            int requiredBufferLength = digitCount + leadingZeroCount;
 25
 126            if (insertNegationSign)
 127            {
 128                requiredBufferLength++;
 129            }
 30
 131            if (requiredBufferLength > buffer.Length)
 132            {
 133                bytesWritten = 0;
 134                return false;
 35            }
 36
 137            bytesWritten = requiredBufferLength;
 38
 139            if (insertNegationSign)
 140            {
 141                buffer[0] = Utf8Constants.Minus;
 142                buffer = buffer.Slice(1);
 143            }
 44
 145            if (leadingZeroCount > 0)
 146            {
 147                FormattingHelpers.FillWithAsciiZeros(buffer.Slice(0, leadingZeroCount));
 148            }
 149            FormattingHelpers.WriteDigits(value, buffer.Slice(leadingZeroCount, digitCount));
 50
 151            return true;
 152        }
 53    }
 54}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.Default.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6using System.Runtime.CompilerServices;
 7
 8namespace System.Buffers.Text
 9{
 10    /// <summary>
 11    /// Methods to format common data types as Utf8 strings.
 12    /// </summary>
 13    public static partial class Utf8Formatter
 14    {
 15        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 16        private static bool TryFormatUInt64Default(ulong value, Span<byte> buffer, out int bytesWritten)
 117        {
 118            if (value < 10)
 119            {
 120                return TryFormatUInt32SingleDigit((uint)value, buffer, out bytesWritten);
 21            }
 22
 123            if (IntPtr.Size == 8)    // x64
 124            {
 125                return TryFormatUInt64MultipleDigits(value, buffer, out bytesWritten);
 26            }
 27            else    // x86
 028            {
 029                if (value <= uint.MaxValue)
 030                {
 031                    return TryFormatUInt32MultipleDigits((uint)value, buffer, out bytesWritten);
 32                }
 33                else
 034                {
 035                    if (value <= Utf8Constants.BillionMaxUIntValue)
 036                    {
 037                        return TryFormatUInt64LessThanBillionMaxUInt(value, buffer, out bytesWritten);
 38                    }
 39                    else
 040                    {
 041                        return TryFormatUInt64MoreThanBillionMaxUInt(value, buffer, out bytesWritten);
 42                    }
 43                }
 44            }
 145        }
 46
 47        // TODO: Use this instead of TryFormatUInt64Default to format numbers less than uint.MaxValue
 48        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 49        private static bool TryFormatUInt32Default(uint value, Span<byte> buffer, out int bytesWritten)
 50        {
 51            if (value < 10)
 52            {
 53                return TryFormatUInt32SingleDigit(value, buffer, out bytesWritten);
 54            }
 55            return TryFormatUInt32MultipleDigits(value, buffer, out bytesWritten);
 56        }
 57
 58        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 59        private static bool TryFormatUInt32SingleDigit(uint value, Span<byte> buffer, out int bytesWritten)
 160        {
 161            if (buffer.Length == 0)
 162            {
 163                bytesWritten = 0;
 164                return false;
 65            }
 166            buffer[0] = (byte)('0' + value);
 167            bytesWritten = 1;
 168            return true;
 169        }
 70
 71        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 72        private static bool TryFormatUInt32MultipleDigits(uint value, Span<byte> buffer, out int bytesWritten)
 073        {
 074            int digitCount = FormattingHelpers.CountDigits(value);
 75            // WriteDigits does not do bounds checks
 076            if (digitCount > buffer.Length)
 077            {
 078                bytesWritten = 0;
 079                return false;
 80            }
 081            bytesWritten = digitCount;
 082            FormattingHelpers.WriteDigits(value, buffer.Slice(0, digitCount));
 083            return true;
 084        }
 85
 86        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 87        private static bool TryFormatUInt64SingleDigit(ulong value, Span<byte> buffer, out int bytesWritten)
 88        {
 89            if (buffer.Length == 0)
 90            {
 91                bytesWritten = 0;
 92                return false;
 93            }
 94            buffer[0] = (byte)('0' + value);
 95            bytesWritten = 1;
 96            return true;
 97        }
 98
 99        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 100        private static bool TryFormatUInt64MultipleDigits(ulong value, Span<byte> buffer, out int bytesWritten)
 1101        {
 1102            int digitCount = FormattingHelpers.CountDigits(value);
 103            // WriteDigits does not do bounds checks
 1104            if (digitCount > buffer.Length)
 1105            {
 1106                bytesWritten = 0;
 1107                return false;
 108            }
 1109            bytesWritten = digitCount;
 1110            FormattingHelpers.WriteDigits(value, buffer.Slice(0, digitCount));
 1111            return true;
 1112        }
 113
 114        // Split ulong into two parts that can each fit in a uint - {1-10 digits}{9 digits}
 115        private static bool TryFormatUInt64LessThanBillionMaxUInt(ulong value, Span<byte> buffer, out int bytesWritten)
 0116        {
 0117            uint overNineDigits = (uint)(value / Utf8Constants.Billion);
 0118            uint lastNineDigits = (uint)(value - (overNineDigits * Utf8Constants.Billion));
 119
 0120            int digitCountOverNineDigits = FormattingHelpers.CountDigits(overNineDigits);
 0121            Debug.Assert(digitCountOverNineDigits >= 1 && digitCountOverNineDigits <= 10);
 0122            int digitCount = digitCountOverNineDigits + 9;
 123            // WriteDigits does not do bounds checks
 0124            if (digitCount > buffer.Length)
 0125            {
 0126                bytesWritten = 0;
 0127                return false;
 128            }
 0129            bytesWritten = digitCount;
 0130            FormattingHelpers.WriteDigits(overNineDigits, buffer.Slice(0, digitCountOverNineDigits));
 0131            FormattingHelpers.WriteDigits(lastNineDigits, buffer.Slice(digitCountOverNineDigits, 9));
 0132            return true;
 0133        }
 134
 135        // Split ulong into three parts that can each fit in a uint - {1-2 digits}{9 digits}{9 digits}
 136        private static bool TryFormatUInt64MoreThanBillionMaxUInt(ulong value, Span<byte> buffer, out int bytesWritten)
 0137        {
 0138            ulong overNineDigits = value / Utf8Constants.Billion;
 0139            uint lastNineDigits = (uint)(value - (overNineDigits * Utf8Constants.Billion));
 0140            uint overEighteenDigits = (uint)(overNineDigits / Utf8Constants.Billion);
 0141            uint middleNineDigits = (uint)(overNineDigits - (overEighteenDigits * Utf8Constants.Billion));
 142
 0143            int digitCountOverEighteenDigits = FormattingHelpers.CountDigits(overEighteenDigits);
 0144            Debug.Assert(digitCountOverEighteenDigits >= 1 && digitCountOverEighteenDigits <= 2);
 0145            int digitCount = digitCountOverEighteenDigits + 18;
 146            // WriteDigits does not do bounds checks
 0147            if (digitCount > buffer.Length)
 0148            {
 0149                bytesWritten = 0;
 0150                return false;
 151            }
 0152            bytesWritten = digitCount;
 0153            FormattingHelpers.WriteDigits(overEighteenDigits, buffer.Slice(0, digitCountOverEighteenDigits));
 0154            FormattingHelpers.WriteDigits(middleNineDigits, buffer.Slice(digitCountOverEighteenDigits, 9));
 0155            FormattingHelpers.WriteDigits(lastNineDigits, buffer.Slice(digitCountOverEighteenDigits + 9, 9));
 0156            return true;
 0157        }
 158    }
 159}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.N.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    /// <summary>
 8    /// Methods to format common data types as Utf8 strings.
 9    /// </summary>
 10    public static partial class Utf8Formatter
 11    {
 12        private static bool TryFormatUInt64N(ulong value, byte precision, Span<byte> buffer, bool insertNegationSign, ou
 113        {
 14            // Calculate the actual digit count, number of group separators required, and the
 15            // number of trailing zeros requested. From all of this we can get the required
 16            // buffer length.
 17
 118            int digitCount = FormattingHelpers.CountDigits(value);
 119            int commaCount = (digitCount - 1) / 3;
 120            int trailingZeroCount = (precision == StandardFormat.NoPrecision) ? 2 /* default for 'N' */ : precision;
 21
 122            int requiredBufferLength = digitCount + commaCount;
 123            if (trailingZeroCount > 0)
 124            {
 125                requiredBufferLength += trailingZeroCount + 1;
 126            }
 27
 128            if (insertNegationSign)
 129            {
 130                requiredBufferLength++;
 131            }
 32
 133            if (requiredBufferLength > buffer.Length)
 134            {
 135                bytesWritten = 0;
 136                return false;
 37            }
 38
 139            bytesWritten = requiredBufferLength;
 40
 141            if (insertNegationSign)
 142            {
 143                buffer[0] = Utf8Constants.Minus;
 144                buffer = buffer.Slice(1);
 145            }
 46
 147            FormattingHelpers.WriteDigitsWithGroupSeparator(value, buffer.Slice(0, digitCount + commaCount));
 48
 149            if (trailingZeroCount > 0)
 150            {
 151                buffer[digitCount + commaCount] = Utf8Constants.Period;
 152                FormattingHelpers.FillWithAsciiZeros(buffer.Slice(digitCount + commaCount + 1, trailingZeroCount));
 153            }
 54
 155            return true;
 156        }
 57    }
 58}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.Integer.Unsigned.X.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers.Text
 6{
 7    /// <summary>
 8    /// Methods to format common data types as Utf8 strings.
 9    /// </summary>
 10    public static partial class Utf8Formatter
 11    {
 12        private static bool TryFormatUInt64X(ulong value, byte precision, bool useLower, Span<byte> buffer, out int byte
 113        {
 114            int actualDigitCount = FormattingHelpers.CountHexDigits(value);
 115            int computedOutputLength = (precision == StandardFormat.NoPrecision)
 116                ? actualDigitCount
 117                : Math.Max(precision, actualDigitCount);
 18
 119            if (buffer.Length < computedOutputLength)
 120            {
 121                bytesWritten = 0;
 122                return false;
 23            }
 24
 125            bytesWritten = computedOutputLength;
 126            string hexTable = (useLower) ? FormattingHelpers.HexTableLower : FormattingHelpers.HexTableUpper;
 27
 28            // Writing the output backward in this manner allows the JIT to elide
 29            // bounds checking on the output buffer. The JIT won't elide the bounds
 30            // check on the hex table lookup, but we can live with that for now.
 31
 32            // It doesn't quite make sense to use the fast hex conversion functionality
 33            // for this method since that routine works on bytes, and here we're working
 34            // directly with nibbles. There may be opportunity for improvement by special-
 35            // casing output lengths of 2, 4, 8, and 16 and running them down optimized
 36            // code paths.
 37
 138            while ((uint)(--computedOutputLength) < (uint)buffer.Length)
 139            {
 140                buffer[computedOutputLength] = (byte)hexTable[(int)value & 0xf];
 141                value >>= 4;
 142            }
 143            return true;
 144        }
 45    }
 46}

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\Text\Utf8Formatter\Utf8Formatter.TimeSpan.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Diagnostics;
 6
 7namespace System.Buffers.Text
 8{
 9    public static partial class Utf8Formatter
 10    {
 11        /// <summary>
 12        /// Formats a TimeSpan as a UTF8 string.
 13        /// </summary>
 14        /// <param name="value">Value to format</param>
 15        /// <param name="buffer">Buffer to write the UTF8-formatted value to</param>
 16        /// <param name="bytesWritten">Receives the length of the formatted text in bytes</param>
 17        /// <param name="format">The standard format to use</param>
 18        /// <returns>
 19        /// true for success. "bytesWritten" contains the length of the formatted text in bytes.
 20        /// false if buffer was too short. Iteratively increase the size of the buffer and retry until it succeeds.
 21        /// </returns>
 22        /// <remarks>
 23        /// Formats supported:
 24        ///     c/t/T (default) [-][d.]hh:mm:ss[.fffffff]              (constant format)
 25        ///     G               [-]d:hh:mm:ss.fffffff                  (general long)
 26        ///     g               [-][d:][h]h:mm:ss[.f[f[f[f[f[f[f]]]]]] (general short)
 27        /// </remarks>
 28        /// <exceptions>
 29        /// <cref>System.FormatException</cref> if the format is not valid for this data type.
 30        /// </exceptions>
 31        public static bool TryFormat(TimeSpan value, Span<byte> buffer, out int bytesWritten, StandardFormat format = de
 132        {
 133            char symbol = FormattingHelpers.GetSymbolOrDefault(format, 'c');
 34
 135            switch (symbol)
 36            {
 37                case 'c':
 38                case 'G':
 39                case 'g':
 140                    break;
 41
 42                case 't':
 43                case 'T':
 044                    symbol = 'c';
 045                    break;
 46
 47                default:
 148                    return ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
 49            }
 50
 51            // First, calculate how large an output buffer is needed to hold the entire output.
 52
 153            int requiredOutputLength = 8; // start with "hh:mm:ss" and adjust as necessary
 54
 55            uint fraction;
 56            ulong totalSecondsRemaining;
 157            {
 58                // Turn this into a non-negative TimeSpan if possible.
 159                var ticks = value.Ticks;
 160                if (ticks < 0)
 161                {
 162                    ticks = -ticks;
 163                    if (ticks < 0)
 164                    {
 165                        Debug.Assert(ticks == Int64.MinValue /* -9223372036854775808 */);
 66
 67                        // We computed these ahead of time; they're straight from the decimal representation of Int64.Mi
 168                        fraction = 4775808;
 169                        totalSecondsRemaining = 922337203685;
 170                        goto AfterComputeFraction;
 71                    }
 172                }
 73
 174                totalSecondsRemaining = FormattingHelpers.DivMod((ulong)Math.Abs(value.Ticks), TimeSpan.TicksPerSecond, 
 175                fraction = (uint)fraction64;
 176            }
 77
 178AfterComputeFraction:
 79
 180            int fractionDigits = 0;
 181            if (symbol == 'c')
 182            {
 83                // Only write out the fraction if it's non-zero, and in that
 84                // case write out the entire fraction (all digits).
 185                if (fraction != 0)
 186                {
 187                    fractionDigits = Utf8Constants.DateTimeNumFractionDigits;
 188                }
 189            }
 190            else if (symbol == 'G')
 191            {
 92                // Always write out the fraction, even if it's zero.
 193                fractionDigits = Utf8Constants.DateTimeNumFractionDigits;
 194            }
 95            else
 196            {
 97                // Only write out the fraction if it's non-zero, and in that
 98                // case write out only the most significant digits.
 199                if (fraction != 0)
 1100                {
 1101                    fractionDigits = Utf8Constants.DateTimeNumFractionDigits - FormattingHelpers.CountDecimalTrailingZer
 1102                }
 1103            }
 104
 1105            Debug.Assert(fraction < 10_000_000);
 106
 107            // If we're going to write out a fraction, also need to write the leading decimal.
 1108            if (fractionDigits != 0)
 1109            {
 1110                requiredOutputLength += fractionDigits + 1;
 1111            }
 112
 1113            ulong totalMinutesRemaining = 0;
 1114            ulong seconds = 0;
 1115            if (totalSecondsRemaining > 0)
 1116            {
 117                // Only compute minutes if the TimeSpan has an absolute value of >= 1 minute.
 1118                totalMinutesRemaining = FormattingHelpers.DivMod(totalSecondsRemaining, 60 /* seconds per minute */, out
 1119            }
 120
 1121            Debug.Assert(seconds < 60);
 122
 1123            ulong totalHoursRemaining = 0;
 1124            ulong minutes = 0;
 1125            if (totalMinutesRemaining > 0)
 1126            {
 127                // Only compute hours if the TimeSpan has an absolute value of >= 1 hour.
 1128                totalHoursRemaining = FormattingHelpers.DivMod(totalMinutesRemaining, 60 /* minutes per hour */, out min
 1129            }
 130
 1131            Debug.Assert(minutes < 60);
 132
 133            // At this point, we can switch over to 32-bit divmod since the data has shrunk far enough.
 1134            Debug.Assert(totalHoursRemaining <= UInt32.MaxValue);
 135
 1136            uint days = 0;
 1137            uint hours = 0;
 1138            if (totalHoursRemaining > 0)
 1139            {
 140                // Only compute days if the TimeSpan has an absolute value of >= 1 day.
 1141                days = FormattingHelpers.DivMod((uint)totalHoursRemaining, 24 /* hours per day */, out hours);
 1142            }
 143
 1144            Debug.Assert(hours < 24);
 145
 1146            int hourDigits = 2;
 1147            if (hours < 10 && symbol == 'g')
 1148            {
 149                // Only writing a one-digit hour, not a two-digit hour
 1150                hourDigits--;
 1151                requiredOutputLength--;
 1152            }
 153
 1154            int dayDigits = 0;
 1155            if (days == 0)
 1156            {
 1157                if (symbol == 'G')
 1158                {
 1159                    requiredOutputLength += 2; // for the leading "0:"
 1160                    dayDigits = 1;
 1161                }
 1162            }
 163            else
 1164            {
 1165                dayDigits = FormattingHelpers.CountDigits(days);
 1166                requiredOutputLength += dayDigits + 1; // for the leading "d:" (or "d.")
 1167            }
 168
 1169            if (value.Ticks < 0)
 1170            {
 1171                requiredOutputLength++; // for the leading '-' sign
 1172            }
 173
 1174            if (buffer.Length < requiredOutputLength)
 1175            {
 1176                bytesWritten = 0;
 1177                return false;
 178            }
 179
 1180            bytesWritten = requiredOutputLength;
 181
 1182            int idx = 0;
 183
 184            // Write leading '-' if necessary
 1185            if (value.Ticks < 0)
 1186            {
 1187                buffer[idx++] = Utf8Constants.Minus;
 1188            }
 189
 190            // Write day (and separator) if necessary
 1191            if (dayDigits > 0)
 1192            {
 1193                FormattingHelpers.WriteDigits(days, buffer.Slice(idx, dayDigits));
 1194                idx += dayDigits;
 1195                buffer[idx++] = (symbol == 'c') ? Utf8Constants.Period : Utf8Constants.Colon;
 1196            }
 197
 198            // Write "[h]h:mm:ss"
 1199            FormattingHelpers.WriteDigits(hours, buffer.Slice(idx, hourDigits));
 1200            idx += hourDigits;
 1201            buffer[idx++] = Utf8Constants.Colon;
 1202            FormattingHelpers.WriteDigits((uint)minutes, buffer.Slice(idx, 2));
 1203            idx += 2;
 1204            buffer[idx++] = Utf8Constants.Colon;
 1205            FormattingHelpers.WriteDigits((uint)seconds, buffer.Slice(idx, 2));
 1206            idx += 2;
 207
 208            // Write fraction (and separator) if necessary
 1209            if (fractionDigits > 0)
 1210            {
 1211                buffer[idx++] = Utf8Constants.Period;
 1212                FormattingHelpers.WriteDigits(fraction, buffer.Slice(idx, fractionDigits));
 1213                idx += fractionDigits;
 1214            }
 215
 216            // And we're done!
 217
 1218            Debug.Assert(idx == requiredOutputLength);
 1219            return true;
 1220        }
 221    }
 222}

Methods/Properties

TryFormat(System.Boolean,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
.cctor()
TryFormat(System.DateTimeOffset,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.DateTime,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormatDateTimeG(System.DateTime,System.TimeSpan,System.Span`1<System.Byte>,System.Int32&)
TryFormatDateTimeL(System.DateTime,System.Span`1<System.Byte>,System.Int32&)
TryFormatDateTimeO(System.DateTime,System.TimeSpan,System.Span`1<System.Byte>,System.Int32&)
TryFormatDateTimeR(System.DateTime,System.Span`1<System.Byte>,System.Int32&)
TryFormat(System.Decimal,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormatDecimalE(System.NumberBuffer&,System.Span`1<System.Byte>,System.Int32&,System.Byte,System.Byte)
TryFormatDecimalF(System.NumberBuffer&,System.Span`1<System.Byte>,System.Int32&,System.Byte)
TryFormatDecimalG(System.NumberBuffer&,System.Span`1<System.Byte>,System.Int32&)
TryFormat(System.Double,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.Single,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormatFloatingPoint(T,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.Guid,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.Byte,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.SByte,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.UInt16,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.Int16,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.UInt32,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.Int32,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.UInt64,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormat(System.Int64,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormatInt64(System.Int64,System.UInt64,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormatInt64D(System.Int64,System.Byte,System.Span`1<System.Byte>,System.Int32&)
TryFormatInt64D_MinValue(System.Byte,System.Span`1<System.Byte>,System.Int32&)
TryFormatInt64Default(System.Int64,System.Span`1<System.Byte>,System.Int32&)
TryFormatInt32MultipleDigits(System.Int32,System.Span`1<System.Byte>,System.Int32&)
TryFormatInt64MultipleDigits(System.Int64,System.Span`1<System.Byte>,System.Int32&)
TryFormatInt64MoreThanNegativeBillionMaxUInt(System.Int64,System.Span`1<System.Byte>,System.Int32&)
TryFormatInt64LessThanNegativeBillionMaxUInt(System.Int64,System.Span`1<System.Byte>,System.Int32&)
TryFormatInt64N(System.Int64,System.Byte,System.Span`1<System.Byte>,System.Int32&)
TryFormatInt64N_MinValue(System.Byte,System.Span`1<System.Byte>,System.Int32&)
TryFormatUInt64(System.UInt64,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)
TryFormatUInt64D(System.UInt64,System.Byte,System.Span`1<System.Byte>,System.Boolean,System.Int32&)
TryFormatUInt64Default(System.UInt64,System.Span`1<System.Byte>,System.Int32&)
TryFormatUInt32SingleDigit(System.UInt32,System.Span`1<System.Byte>,System.Int32&)
TryFormatUInt32MultipleDigits(System.UInt32,System.Span`1<System.Byte>,System.Int32&)
TryFormatUInt64MultipleDigits(System.UInt64,System.Span`1<System.Byte>,System.Int32&)
TryFormatUInt64LessThanBillionMaxUInt(System.UInt64,System.Span`1<System.Byte>,System.Int32&)
TryFormatUInt64MoreThanBillionMaxUInt(System.UInt64,System.Span`1<System.Byte>,System.Int32&)
TryFormatUInt64N(System.UInt64,System.Byte,System.Span`1<System.Byte>,System.Boolean,System.Int32&)
TryFormatUInt64X(System.UInt64,System.Byte,System.Boolean,System.Span`1<System.Byte>,System.Int32&)
TryFormat(System.TimeSpan,System.Span`1<System.Byte>,System.Int32&,System.Buffers.StandardFormat)