customformatter.cs
来自「没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没」· CS 代码 · 共 527 行
CS
527 行
/* * CustomFormatter.cs - Implementation of the * "System.Private.Formatter" class. * * Copyright (C) 2001 Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */namespace System.Private.NumberFormat{using System;using System.Collections;using System.Globalization;using System.Text;internal class CustomFormatter : Formatter{ // // Constants and read-only // private const char zeroPlaceholder = '0'; private const char digitPlaceholder = '#'; private const char decimalSeparator = '.'; private const char groupSeparator = ','; private const char percentagePlaceholder = '%'; private static readonly char[] engineeringFormat = {'E','e'}; private static readonly char[] sectionSeparator = {';'}; // // Stored format information // private string originalFormat; private string positiveFormat; private string negativeFormat; private string zeroFormat; bool includeNegSign; // Should a '-' be included? // // Constructor - Take custom format string as input. // public CustomFormatter(string inFormat) { string[] fmts; this.originalFormat = inFormat; fmts = originalFormat.Split(sectionSeparator, 3); if (fmts.Length == 0) { this.positiveFormat = null; this.negativeFormat = null; this.zeroFormat = null; this.includeNegSign = true; } else if (fmts.Length == 1) { this.positiveFormat = inFormat; this.negativeFormat = inFormat; this.zeroFormat = inFormat; this.includeNegSign = true; } else if (fmts.Length == 2) { this.positiveFormat = fmts[0]; this.negativeFormat = fmts[1]; this.zeroFormat = fmts[0]; this.includeNegSign = false; } else { this.positiveFormat = fmts[0]; if (this.negativeFormat == String.Empty) { this.negativeFormat = fmts[0]; this.includeNegSign=true; } else { this.negativeFormat = fmts[1]; this.includeNegSign=false; } this.zeroFormat = fmts[2]; } } private int ScientificStart(string format) { int ret, pos; pos = format.IndexOfAny(engineeringFormat, 0); while (pos != -1) { ret = pos++; if (format[pos] == '+' || format[pos] == '-') { pos++; } if (format[pos] == '0') { return ret; } pos = format.IndexOfAny(engineeringFormat, pos); } return -1; } private string FormatFromSign(int sign) { string ret = null; switch(sign) { case 1: ret = positiveFormat; break; case -1: ret = negativeFormat; break; case 0: ret = zeroFormat; break; } return ret; } // // FormatRawNumber - Given a string of form 'n*.n*', format it based // upon the custom format. // private string FormatRawNumber(string value, string format, int sign, IFormatProvider provider) { string rawnumber; int firstzero, lastzero; int scale = 0; // Locate the decimal point int decimalPos = format.IndexOf(decimalSeparator); if (decimalPos == -1) decimalPos = format.Length; // Scaling int formatindex = decimalPos - 1; while (formatindex >=0 && format[formatindex] == groupSeparator) { scale += 3; --formatindex; } // Move the decimal point StringBuilder temp = new StringBuilder(); if (scale <= value.IndexOf('.')) { temp.Append(value.Substring(0, value.IndexOf('.') - scale)) .Append(".") .Append(value.Substring(value.IndexOf('.') - scale, scale)); } else { temp.Append(".") .Append(value .Substring(0, value.IndexOf('.')) .PadLeft(scale, '0')); } temp.Append(value.Substring(value.IndexOf('.') + 1)); if (includeNegSign && sign == -1) { temp.Insert(0, NumberFormatInfo(provider).NegativeSign); } rawnumber = temp.ToString(); // Formatting int rawindex = rawnumber.IndexOf('.') - 1; StringBuilder ret = new StringBuilder(); while (rawindex >= 0 && formatindex >= 0) { if (format[formatindex] == digitPlaceholder) { ret.Insert(0, rawnumber[rawindex--]); } else if (format[formatindex] == zeroPlaceholder ) { // Don't put a negative if a zero should go there. if ( rawnumber[rawindex] < '0' || rawnumber[rawindex] > '9') { int i = formatindex + 1; while (format[i] == ',') ++i; if (format[i] == '.') { ret.Insert(0,'0'); } else { ret.Insert(0, rawnumber[rawindex--]); } } else { ret.Insert(0, rawnumber[rawindex--]); } } else if (format[formatindex] == groupSeparator) { ret.Insert(0, NumberFormatInfo(provider).NumberGroupSeparator); } else { ret.Insert(0, format[formatindex]); } --formatindex; } if (rawindex >= 0) { ret.Insert(0, rawnumber.Substring(0, rawindex+1)); } // Zero pad firstzero = format.IndexOf(zeroPlaceholder); if (firstzero != -1) { while (firstzero <= formatindex) { if (format[formatindex] == digitPlaceholder || format[formatindex] == zeroPlaceholder) { ret.Insert(0, '0'); } else if (format[formatindex] == groupSeparator) { ret.Insert(0, NumberFormatInfo(provider).NumberGroupSeparator); } else { ret.Insert(0, format[formatindex]); } --formatindex; } } // Fill out literal portion while (formatindex >= 0) { if( !( format[formatindex] == digitPlaceholder || format[formatindex] == zeroPlaceholder || format[formatindex] == groupSeparator )) { ret.Insert(0, format[formatindex]); } --formatindex; } // Decimal point dealings rawindex = rawnumber.IndexOf('.') + 1; formatindex = decimalPos + 1; if(decimalPos < format.Length) { ret.Append(NumberFormatInfo(provider).NumberDecimalSeparator); } while (rawindex < rawnumber.Length && formatindex < format.Length) { if (format[formatindex] == digitPlaceholder || format[formatindex] == zeroPlaceholder ) { ret.Append(rawnumber[rawindex++]); } else { ret.Append(format[formatindex]); } ++formatindex; } // More zero padding lastzero = format.LastIndexOf(zeroPlaceholder); while (lastzero >= formatindex) { if (format[formatindex] == digitPlaceholder || format[formatindex] == zeroPlaceholder) { ret.Append('0'); } else { ret.Append(format[formatindex]); } formatindex++; } while (formatindex < format.Length) { if ( !( format[formatindex] == digitPlaceholder || format[formatindex] == zeroPlaceholder )) { ret.Append(format[formatindex]); } ++formatindex; } return ret.ToString(); }#if CONFIG_EXTENDED_NUMERICS private string FormatScientific(double d, string format, int sign, IFormatProvider provider) { int exponent = (int)Math.Floor(Math.Log10(d)); double mantissa = d/Math.Pow(10,exponent); int i = ScientificStart(format); // Format the mantissa StringBuilder ret = new StringBuilder( FormatFloat(mantissa, format.Substring(0, i), sign, provider)) .Append(format[i++]); // Sign logic if (format[i] == '+' && exponent >= 0) { ret.Append(NumberFormatInfo(provider).PositiveSign); } else if (exponent < 0) { ret.Append(NumberFormatInfo(provider).NegativeSign); } if (format[i] == '+' || format[i] == '-') { ++i; } // Place exponent value into string. int exponentMin = 0; while (i<format.Length && format[i] == '0') { ++i; ++exponentMin; } // Format the exponent and append, string exponentString = Formatter.FormatInteger((ulong)Math.Abs(exponent)); ret.Append(exponentString.Substring(0, exponentString.Length-1) .PadLeft(exponentMin,'0')); // Fill out the string ret.Append(format.Substring(i)); return ret.ToString(); }#endif // CONFIG_EXTENDED_NUMERICS private string FormatInteger(ulong value, string format, int sign, IFormatProvider provider) { return FormatRawNumber(Formatter.FormatInteger(value) ,format, sign, provider); }#if CONFIG_EXTENDED_NUMERICS private string FormatFloat(double d, string format, int sign, IFormatProvider provider) { int formatindex, precision; formatindex = format.IndexOf('.'); if (formatindex == -1) { precision = 0; } else { for (formatindex++, precision = 0; formatindex < format.Length; formatindex++) { if (format[formatindex] == digitPlaceholder || format[formatindex] == zeroPlaceholder) { ++precision; } } } return FormatRawNumber( Formatter.FormatFloat(d, precision + 2), format, sign, provider); } private string FormatDecimal(decimal value, string format, int sign, IFormatProvider provider) { if (format.IndexOf(percentagePlaceholder) != -1) { return FormatRawNumber(Formatter.FormatDecimal(value*100), format, sign, provider); } else { return FormatRawNumber(Formatter.FormatDecimal(value), format, sign, provider); } }#endif // CONFIG_EXTENDED_NUMERICS // // Public access method. // public override string Format(Object o, IFormatProvider provider) { if (IsSignedInt(o)) { long val = OToLong(o); int sign; if(val < 0) { sign = -1; val = -val; } else if(val > 0) { sign = 1; } else { sign = 0; } string format = FormatFromSign(sign); #if CONFIG_EXTENDED_NUMERICS if (ScientificStart(format) == -1) { return FormatInteger((ulong)val, format, sign, provider); } else { return FormatScientific((double)val, format, sign, provider); } #else return FormatInteger((ulong)val, format, sign, provider); #endif } else if (IsUnsignedInt(o)) { ulong val = OToUlong(o); string format = ( (val==0) ? zeroFormat : positiveFormat); #if CONFIG_EXTENDED_NUMERICS if (ScientificStart(format) == -1) { return FormatInteger(val, format, val == 0 ? 0 : 1, provider); } else { return FormatScientific( (double)val, format, val == 0 ? 0 : 1, provider); } #else return FormatInteger(val, format, val == 0 ? 0 : 1, provider); #endif }#if CONFIG_EXTENDED_NUMERICS else if (IsFloat(o)) { double val = OToDouble(o); string format = FormatFromSign(Math.Sign(val)); if (ScientificStart(format) == -1) { return FormatFloat(Math.Abs(val), format, Math.Sign(val), provider); } else { return FormatScientific(Math.Abs(val), format, Math.Sign(val), provider); } } else if (IsDecimal(o)) { decimal val = (decimal) o; string format = FormatFromSign(Math.Sign(val)); if (ScientificStart(format) == -1) { return FormatDecimal(Math.Abs(val), format, Math.Sign(val), provider); } else { return FormatScientific((double)Math.Abs(val), format, Math.Sign(val), provider); } }#endif // CONFIG_EXTENDED_NUMERICS else if (o is IFormattable) { return ((IFormattable)o).ToString(originalFormat, provider); } else { return o.ToString(); } }} // class CustomFormatter} // namespace System.Private.NumberFormat
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?