Exemple #1
0
        public static unsafe void Format(StringBuffer formatter, TimeSpan timeSpan, StringView format)
        {
            const int tempCharsLength = 7;
            var       tempChars       = stackalloc char[tempCharsLength];

            formatter.EnsureCapacity(20);

            if (timeSpan.Ticks < 0)
            {
                formatter.Append('-');
                timeSpan = new TimeSpan(-timeSpan.Ticks);
            }

            var(days, hours, minutes, seconds, ticks) = timeSpan;

            switch (ParseTimeSpanFormat(format))
            {
            case TimeSpanFormat.Constant:
                if (days > 0)
                {
                    formatter.Append(days, StringView.Empty);
                    formatter.Append('.');
                }

                AppendNumber(formatter, hours, 2, tempChars, tempCharsLength);
                formatter.Append(':');
                AppendNumber(formatter, minutes, 2, tempChars, tempCharsLength);
                formatter.Append(':');
                AppendNumber(formatter, seconds, 2, tempChars, tempCharsLength);

                if (ticks != 0)
                {
                    formatter.Append('.');
                    AppendNumber(formatter, ticks, 7, tempChars, tempCharsLength);
                }
                break;

            case TimeSpanFormat.GeneralShort:
                if (days > 0)
                {
                    formatter.Append(days, StringView.Empty);
                    formatter.Append(':');
                }

                formatter.Append(hours, StringView.Empty);
                formatter.Append(':');
                AppendNumber(formatter, minutes, 2, tempChars, tempCharsLength);
                formatter.Append(':');
                AppendNumber(formatter, seconds, 2, tempChars, tempCharsLength);

                if (ticks != 0)
                {
                    formatter.Append('.');
                    AppendNumber(formatter, ticks, 7, tempChars, tempCharsLength);
                    formatter.TrimEnd('0');
                }
                break;

            case TimeSpanFormat.GeneralLong:
                formatter.Append(days, StringView.Empty);
                formatter.Append(':');

                AppendNumber(formatter, hours, 2, tempChars, tempCharsLength);
                formatter.Append(':');
                AppendNumber(formatter, minutes, 2, tempChars, tempCharsLength);
                formatter.Append(':');
                AppendNumber(formatter, seconds, 2, tempChars, tempCharsLength);

                formatter.Append('.');
                AppendNumber(formatter, ticks, 7, tempChars, tempCharsLength);
                break;
            }
        }
        static void NumberToString(StringBuffer formatter, ref Number number, char format, int maxDigits, CachedCulture culture, bool isDecimal = false)
        {
            // ANDing with 0xFFDF has the effect of uppercasing the character
            switch (format & 0xFFDF)
            {
            case 'C':
            {
                var cultureData = culture.CurrencyData;
                var bufferSize  = cultureData.GetBufferSize(ref maxDigits, number.Scale);
                RoundNumber(ref number, number.Scale + maxDigits);

                var buffer = stackalloc char[bufferSize];
                var ptr    = FormatCurrency(
                    buffer,
                    ref number,
                    maxDigits,
                    cultureData,
                    number.Sign > 0 ? culture.CurrencyNegativePattern : culture.CurrencyPositivePattern,
                    culture.CurrencySymbol
                    );

                formatter.Append(buffer, (int)(ptr - buffer));
                break;
            }

            case 'F':
            {
                var cultureData = culture.FixedData;
                var bufferSize  = cultureData.GetBufferSize(ref maxDigits, number.Scale);
                RoundNumber(ref number, number.Scale + maxDigits);

                var buffer = stackalloc char[bufferSize];
                var ptr    = buffer;
                if (number.Sign > 0)
                {
                    AppendString(&ptr, cultureData.NegativeSign);
                }

                ptr = FormatFixed(ptr, ref number, maxDigits, cultureData);
                formatter.Append(buffer, (int)(ptr - buffer));
                break;
            }

            case 'N':
            {
                var cultureData = culture.NumberData;
                var bufferSize  = cultureData.GetBufferSize(ref maxDigits, number.Scale);
                RoundNumber(ref number, number.Scale + maxDigits);

                var buffer = stackalloc char[bufferSize];
                var ptr    = FormatNumber(
                    buffer,
                    ref number,
                    maxDigits,
                    number.Sign > 0 ? culture.NumberNegativePattern : culture.NumberPositivePattern,
                    cultureData
                    );

                formatter.Append(buffer, (int)(ptr - buffer));
                break;
            }

            case 'E':
            {
                var cultureData = culture.ScientificData;
                var bufferSize  = cultureData.GetBufferSize(ref maxDigits, number.Scale);
                maxDigits++;

                RoundNumber(ref number, maxDigits);

                var buffer = stackalloc char[bufferSize];
                var ptr    = buffer;
                if (number.Sign > 0)
                {
                    AppendString(&ptr, cultureData.NegativeSign);
                }

                ptr = FormatScientific(
                    ptr,
                    ref number,
                    maxDigits,
                    format,         // TODO: fix casing
                    cultureData.DecimalSeparator,
                    culture.PositiveSign,
                    culture.NegativeSign
                    );

                formatter.Append(buffer, (int)(ptr - buffer));
                break;
            }

            case 'P':
            {
                number.Scale += 2;
                var cultureData = culture.PercentData;
                var bufferSize  = cultureData.GetBufferSize(ref maxDigits, number.Scale);
                RoundNumber(ref number, number.Scale + maxDigits);

                var buffer = stackalloc char[bufferSize];
                var ptr    = FormatPercent(
                    buffer,
                    ref number,
                    maxDigits,
                    cultureData,
                    number.Sign > 0 ? culture.PercentNegativePattern : culture.PercentPositivePattern,
                    culture.PercentSymbol
                    );

                formatter.Append(buffer, (int)(ptr - buffer));
                break;
            }

            case 'G':
            {
                var enableRounding = true;
                if (maxDigits < 1)
                {
                    if (isDecimal && maxDigits == -1)
                    {
                        // if we're formatting a decimal, default to 29 digits precision
                        // only for G formatting without a precision specifier
                        maxDigits      = DecimalPrecision;
                        enableRounding = false;
                    }
                    else
                    {
                        maxDigits = number.Precision;
                    }
                }

                var bufferSize = maxDigits + culture.DecimalBufferSize;
                var buffer     = stackalloc char[bufferSize];
                var ptr        = buffer;

                // round for G formatting only if a precision is given
                // we need to handle the minus zero case also
                if (enableRounding)
                {
                    RoundNumber(ref number, maxDigits);
                }
                else if (isDecimal && number.Digits[0] == 0)
                {
                    number.Sign = 0;
                }

                if (number.Sign > 0)
                {
                    AppendString(&ptr, culture.NegativeSign);
                }

                ptr = FormatGeneral(
                    ptr,
                    ref number,
                    maxDigits,
                    (char)(format - ('G' - 'E')),
                    culture.NumberData.DecimalSeparator,
                    culture.PositiveSign,
                    culture.NegativeSign,
                    !enableRounding
                    );

                formatter.Append(buffer, (int)(ptr - buffer));
                break;
            }

            default:
                throw new FormatException(string.Format(SR.UnknownFormatSpecifier, format));
            }
        }
Exemple #3
0
 static void NumberToCustomFormatString(StringBuffer formatter, ref Number number, StringView specifier, CachedCulture culture)
 {
 }