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 + -
显示快捷键?