Summary

Class:System.Buffers.StandardFormat
Assembly:System.Memory
File(s):C:\GitHub\corefx\src\System.Memory\src\System\Buffers\StandardFormat.cs
Covered lines:69
Uncovered lines:0
Coverable lines:69
Total lines:174
Line coverage:100%
Branch coverage:100%

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
.ctor(...)44100100
op_Implicit(...)10100100
Parse(...)632100100
Parse(...)20100100
Equals(...)40100100
GetHashCode()10100100
Equals(...)20100100
ToString()516100100
op_Equality(...)10100100
op_Inequality(...)10100100

File(s)

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\StandardFormat.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
 8{
 9    /// <summary>
 10    /// Represents a standard formatting string without using an actual String. A StandardFormat consists of a character
 11    /// and an optional precision ranging from 0..99, or the special value NoPrecision.
 12    /// </summary>
 13    public readonly struct StandardFormat : IEquatable<StandardFormat>
 14    {
 15        /// <summary>
 16        /// Precision values for format that don't use a precision, or for when the precision is to be unspecified.
 17        /// </summary>
 18        public const byte NoPrecision = byte.MaxValue;
 19
 20        /// <summary>
 21        /// The maximum valid precision value.
 22        /// </summary>
 23        public const byte MaxPrecision = 99;
 24
 25        private readonly byte _format;
 26        private readonly byte _precision;
 27
 28        /// <summary>
 29        /// The character component of the format.
 30        /// </summary>
 131        public char Symbol => (char)_format;
 32
 33        /// <summary>
 34        /// The precision component of the format. Ranges from 0..9 or the special value NoPrecision.
 35        /// </summary>
 136        public byte Precision => _precision;
 37
 38        /// <summary>
 39        /// true if Precision is a value other than NoPrecision
 40        /// </summary>
 141        public bool HasPrecision => _precision != NoPrecision;
 42
 43        /// <summary>
 44        /// true if the StandardFormat == default(StandardFormat)
 45        /// </summary>
 146        public bool IsDefault => _format == 0 && _precision == 0;
 47
 48        /// <summary>
 49        /// Create a StandardFormat.
 50        /// </summary>
 51        /// <param name="symbol">A type-specific formatting character such as 'G', 'D' or 'X'</param>
 52        /// <param name="precision">An optional precision ranging from 0..9 or the special value NoPrecision (the defaul
 53        public StandardFormat(char symbol, byte precision = NoPrecision)
 154        {
 155            if (precision != NoPrecision && precision > MaxPrecision)
 156                ThrowHelper.ThrowArgumentOutOfRangeException_PrecisionTooLarge();
 157            if (symbol != (byte)symbol)
 158                ThrowHelper.ThrowArgumentOutOfRangeException_SymbolDoesNotFit();
 59
 160            _format = (byte)symbol;
 161            _precision = precision;
 162        }
 63
 64        /// <summary>
 65        /// Converts a character to a StandardFormat using the NoPrecision precision.
 66        /// </summary>
 167        public static implicit operator StandardFormat(char symbol) => new StandardFormat(symbol);
 68
 69        /// <summary>
 70        /// Converts a classic .NET format string into a StandardFormat
 71        /// </summary>
 72        public static StandardFormat Parse(ReadOnlySpan<char> format)
 173        {
 174            if (format.Length == 0)
 175                return default;
 76
 177            char symbol = format[0];
 78            byte precision;
 179            if (format.Length == 1)
 180            {
 181                precision = NoPrecision;
 182            }
 83            else
 184            {
 185                uint parsedPrecision = 0;
 386                for (int srcIndex = 1; srcIndex < format.Length; srcIndex++)
 187                {
 188                    uint digit = format[srcIndex] - 48u; // '0'
 189                    if (digit > 9)
 190                        throw new FormatException(SR.Format(SR.Argument_CannotParsePrecision, MaxPrecision));
 91
 192                    parsedPrecision = parsedPrecision * 10 + digit;
 193                    if (parsedPrecision > MaxPrecision)
 194                        throw new FormatException(SR.Format(SR.Argument_PrecisionTooLarge, MaxPrecision));
 195                }
 96
 197                precision = (byte)parsedPrecision;
 198            }
 99
 1100            return new StandardFormat(symbol, precision);
 1101        }
 102
 103        /// <summary>
 104        /// Converts a classic .NET format string into a StandardFormat
 105        /// </summary>
 1106        public static StandardFormat Parse(string format) => format == null ? default : Parse(format.AsSpan());
 107
 108        /// <summary>
 109        /// Returns true if both the Symbol and Precision are equal.
 110        /// </summary>
 1111        public override bool Equals(object obj) => obj is StandardFormat other && Equals(other);
 112
 113        /// <summary>
 114        /// Compute a hash code.
 115        /// </summary>
 1116        public override int GetHashCode() => _format.GetHashCode() ^ _precision.GetHashCode();
 117
 118        /// <summary>
 119        /// Returns true if both the Symbol and Precision are equal.
 120        /// </summary>
 1121        public bool Equals(StandardFormat other) => _format == other._format && _precision == other._precision;
 122
 123        /// <summary>
 124        /// Returns the format in classic .NET format.
 125        /// </summary>
 126        public override string ToString()
 1127        {
 128            unsafe
 1129            {
 130                const int MaxLength = 4;
 1131                char* pBuffer = stackalloc char[MaxLength];
 132
 1133                int dstIndex = 0;
 1134                char symbol = Symbol;
 1135                if (symbol != default)
 1136                {
 1137                    pBuffer[dstIndex++] = symbol;
 138
 1139                    byte precision = Precision;
 1140                    if (precision != NoPrecision)
 1141                    {
 1142                        if (precision >= 100)
 1143                        {
 1144                            pBuffer[dstIndex++] = (char)('0' + (precision / 100) % 10);
 1145                            precision = (byte)(precision % 100);
 1146                        }
 147
 1148                        if (precision >= 10)
 1149                        {
 1150                            pBuffer[dstIndex++] = (char)('0' + (precision / 10) % 10);
 1151                            precision = (byte)(precision % 10);
 1152                        }
 153
 1154                        pBuffer[dstIndex++] = (char)('0' + precision);
 1155                    }
 1156                }
 157
 1158                Debug.Assert(dstIndex <= MaxLength);
 159
 1160                return new string(pBuffer, startIndex: 0, length: dstIndex);
 161            }
 1162        }
 163
 164        /// <summary>
 165        /// Returns true if both the Symbol and Precision are equal.
 166        /// </summary>
 1167        public static bool operator ==(StandardFormat left, StandardFormat right) => left.Equals(right);
 168
 169        /// <summary>
 170        /// Returns false if both the Symbol and Precision are equal.
 171        /// </summary>
 1172        public static bool operator !=(StandardFormat left, StandardFormat right) => !left.Equals(right);
 173    }
 174}