formatter.cs

来自「没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没」· CS 代码 · 共 625 行

CS
625
字号
/* * Formatter.cs - Implementation of the *          "System.Private.NumberFormat.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 abstract class Formatter{	// ----------------------------------------------------------------------	//  Private static variables for formatter	//	private const string validformats = "CcDdEeFfGgNnPpRrXx";	static private IDictionary formats = new Hashtable();	// ----------------------------------------------------------------------	//  Protected data for other methods	//	static protected readonly char[] decimalDigits =	{'0','1','2','3','4','5','6','7','8','9'};	// ----------------------------------------------------------------------	//  Protected state information	//	protected int precision;	// ----------------------------------------------------------------------	//  Protected utility methods	//	static protected NumberFormatInfo 		NumberFormatInfo(IFormatProvider provider)	{		if(provider == null)		{			return System.Globalization.NumberFormatInfo.CurrentInfo;		}		else		{			NumberFormatInfo nfi =				(NumberFormatInfo) provider.GetFormat(								typeof(System.Globalization.NumberFormatInfo));			if(nfi != null)			{				return nfi;			}			else			{				return System.Globalization.NumberFormatInfo.CurrentInfo;			}		}	}	static protected bool IsSignedInt(Object o)	{		return (o is SByte || o is Int16 || o is Int32 || o is Int64);	}		static protected bool IsUnsignedInt(Object o)	{		return (o is Byte || o is UInt16 || o is UInt32 || o is UInt64);	}	#if CONFIG_EXTENDED_NUMERICS	static protected bool IsFloat(Object o)	{		return (o is Single || o is Double);	}		static protected bool IsDecimal(Object o)	{		return (o is Decimal);	}	static protected double OToDouble(Object o)	{		double ret;		if (o is Int32)		{			Int32 n = (Int32)o;			ret = (double)n;		}		else if (o is UInt32)		{			UInt32 n = (UInt32)o;			ret = (double)n;		}		else if (o is SByte)		{			SByte n = (SByte)o;			ret = (double)n;		}		else if (o is Byte)		{			Byte n = (Byte)o;			ret = (double)n;		}		else if (o is Int16)		{			Int16 n = (Int16)o;			ret = (double)n;		}		else if (o is UInt16)		{			UInt16 n = (UInt16)o;			ret = (double)n;		}		else if (o is Int64)		{			Int64 n = (Int64)o;			ret = (double)n;		}		else if (o is UInt64)		{			UInt64 n = (UInt64)o;			ret = (double)n;		}		else if (o is Single)		{			Single n = (Single)o;			ret = (double)n;		}		else if (o is Double)		{			ret = (double)o;		}		else if (o is Decimal)		{			Decimal n = (Decimal)o;			ret = (double)n;		}		else		{			throw new FormatException(_("Format_TypeException"));		}		return ret;	}#endif // CONFIG_EXTENDED_NUMERICS	static protected ulong OToUlong(Object o)	{		ulong ret;		if (o is Int32)		{			Int32 n = (Int32)o;			ret = (ulong)n;		}		else if (o is UInt32)		{			UInt32 n = (UInt32)o;			ret = (ulong)n;		}		else if (o is SByte)		{			SByte n = (SByte)o;			ret = (ulong)n;		}		else if (o is Byte)		{			Byte n = (Byte)o;			ret = (ulong)n;		}		else if (o is Int16)		{			Int16 n = (Int16)o;			ret = (ulong)n;		}		else if (o is UInt16)		{			UInt16 n = (UInt16)o;			ret = (ulong)n;		}		else if (o is Int64)		{			Int64 n = (Int64)o;			ret = (ulong)n;		}		else if (o is UInt64)		{			ret = (ulong)o;		}#if CONFIG_EXTENDED_NUMERICS		else if (o is Single)		{			Single n = (Single)o;			ret = (ulong)n;		}		else if (o is Double)		{			Double n = (Double)o;			ret = (ulong)n;		}		else if (o is Decimal)		{			Decimal n = (Decimal)o;			ret = (ulong)n;		}#endif		else		{			throw new FormatException(_("Format_TypeException"));		}		return ret;	}	static protected long OToLong(Object o)	{		long ret;		if (o is Int32)		{			Int32 n = (Int32)o;			ret = (long)n;		}		else if (o is UInt32)		{			UInt32 n = (UInt32)o;			ret = (long)n;		}		else if (o is SByte)		{			SByte n = (SByte)o;			ret = (long)n;		}		else if (o is Byte)		{			Byte n = (Byte)o;			ret = (long)n;		}		else if (o is Int16)		{			Int16 n = (Int16)o;			ret = (long)n;		}		else if (o is UInt16)		{			UInt16 n = (UInt16)o;			ret = (long)n;		}		else if (o is Int64)		{			ret = (long)o;		}		else if (o is UInt64)		{			UInt64 n = (UInt64)o;			ret = (long)n;		}#if CONFIG_EXTENDED_NUMERICS		else if (o is Single)		{			Single n = (Single)o;			ret = (long)n;		}		else if (o is Double)		{			Double n = (Double)o;			ret = (long)n;		}		else if (o is Decimal)		{			Decimal n = (Decimal)o;			ret = (long)n;		}#endif		else		{			throw new FormatException(_("Format_TypeException"));		}		return ret;	}	static protected string FormatAnyRound(Object o, int precision,										   IFormatProvider provider)	{		string ret;		//  Type validation		if (IsSignedInt(o) && (OToLong(o) < 0) )		{			ulong value=(ulong) -OToLong(o);			if(value==0)			{				// because -(Int64.MinValue) does not exist				ret = "-9223372036854775808.";			}			else			{				ret = "-" + Formatter.FormatInteger(value);			}		}		else if (IsSignedInt(o) || IsUnsignedInt(o))		{			ret = Formatter.FormatInteger(OToUlong(o));		}#if CONFIG_EXTENDED_NUMERICS		else if (IsDecimal(o))		{			// Rounding code			decimal r;			int i;			for (i=0, r=0.5m; i < precision; i++) 			{				r *= 0.1m;			}			//  Pick the call based on the inputs negativity.			if ((decimal)o < 0)			{				ret = "-" + Formatter.FormatDecimal(-((decimal)o)+r);			}			else			{				ret = Formatter.FormatDecimal((decimal)o+r);			}			if (ret.Length - ret.IndexOf('.') > precision + 1) 			{				ret = ret.Substring(0, ret.IndexOf('.')+precision+1);			}		}		else if (IsFloat(o))		{			// Beware rounding code			double val = OToDouble(o);			if (Double.IsNaN(val))			{				return NumberFormatInfo(provider).NaNSymbol;			}			else if (Double.IsPositiveInfinity(val))			{				return NumberFormatInfo(provider).PositiveInfinitySymbol;			}			else if (Double.IsNegativeInfinity(val))			{				return NumberFormatInfo(provider).NegativeInfinitySymbol;			}			else if (val < 0)			{				ret = "-" + 					Formatter.FormatFloat(							-val + 5 * Math.Pow(10, -precision - 1)							,precision);			}			else			{				ret = Formatter.FormatFloat(						val + 5 * Math.Pow(10, -precision - 1) 						,precision);			}		}#endif		else		{			//  This is a bad place to be.			throw new FormatException(_("Format_TypeException"));			}		return ret;	}	static protected string FormatInteger(ulong value)	{		//  Note:  CustomFormatter counts on having the trailing decimal		//  point.  If you're considering taking it out, think hard.				if (value == 0) return ".";		StringBuilder ret = new StringBuilder(".");		ulong work = value;		while (work > 0) {			ret.Insert(0, decimalDigits[work % 10]);			work /= 10;		}		return ret.ToString();	}#if CONFIG_EXTENDED_NUMERICS	static protected string FormatDecimal(decimal value)	{		//  Guard clause(s)		if (value == 0.0m) return ".";		//  Variable declarations		int [] bits = Decimal.GetBits(value);	    int scale = (bits[3] >> 16) & 0xff;		decimal work = value;		StringBuilder ret = new StringBuilder();		//  Scale the decimal		for (int i = 0; i<scale; i++) work *= 10.0m;	   		//  Pick off one digit at a time		while (work > 0.0m) 		{			ret.Insert(0, decimalDigits[					(int)(work - Decimal.Truncate(work*0.1m)*10.0m)]);			work = Decimal.Truncate(work * 0.1m);		}		//  Pad out significant digits		if (ret.Length < scale) 		{			ret.Insert(0, "0", scale - ret.Length);		}		//  Insert a decimal point		ret.Insert(ret.Length - scale, '.');		return ret.ToString();	}	static protected string FormatFloat(double value, int precision)	{		if (value == 0.0) return ".";		//  		int exponent = (int)Math.Floor(Math.Log10(Math.Abs(value)));		double work = value * Math.Pow(10, 16 - exponent);				//		//  Build a numeric representation, sans decimal point.		//		StringBuilder sb = 			new StringBuilder(FormatInteger((ulong)Math.Floor(work)));		sb.Remove(sb.Length-1, 1);    // Ditch the trailing decimal point		if (sb.Length > precision + exponent + 1)		{			sb.Remove(precision+exponent+1, sb.Length-(precision+exponent+1));		}			//		//  Cases for reinserting the decimal point.		//		if (exponent >= -1 && exponent < sb.Length)		{			sb.Insert(exponent+1,'.');		}		else if (exponent < -1)		{			sb.Insert(0,new String('0',-exponent - 1));			sb.Insert(0,".");		}		else 		{			sb.Append(new String('0', exponent - sb.Length + 1));			sb.Append('.');		}		//		//  Remove trailing zeroes.		//		while (sb[sb.Length-1] == '0') {			sb.Remove(sb.Length-1, 1);		}		return sb.ToString();	}#endif // CONFIG_EXTENDED_NUMERICS	static protected string GroupInteger(string value, int[] groupSizes,											string separator)	{		if (value == String.Empty) return "0";		int vindex = value.Length;		int i = 0;		StringBuilder ret = new StringBuilder();		while (vindex > 0)		{			if (vindex - groupSizes[i] <= 0 || groupSizes[i] == 0)			{				ret.Insert(0, value.Substring(0, vindex));				vindex = 0;			}			else			{				vindex -= groupSizes[i];				ret.Insert(0, value.Substring(vindex, groupSizes[i]));				ret.Insert(0, separator);			}			if (i < groupSizes.Length-1) ++i;		}		return ret.ToString();	}		// ----------------------------------------------------------------------	//  Public interface	//	//	//  Factory/Singleton method	//	public static Formatter CreateFormatter(String format)	{		return CreateFormatter(format, null);	}	public static Formatter CreateFormatter(String format, IFormatProvider p)	{		int precision;		Formatter ret;		if (format == null)		{			throw new FormatException(_("Format_StringException"));		}		//  Search for cached formats		if (formats[format] != null)		{			return (Formatter) formats[format];		}		// Validate the format.  		// It should be of the form 'X', 'X9', or 'X99'.		// If it's not, return a CustomFormatter.		if (validformats.IndexOf(format[0]) == -1 || format.Length > 3)		{			return new CustomFormatter(format);		}		try 		{			precision = (format.Length == 1) ? 				-1 : Byte.Parse(format.Substring(1));		}		catch (FormatException)		{			return new CustomFormatter(format);		}				switch(format[0])	// There's always a yucky switch somewhere		{		case 'C':		case 'c':			ret = new CurrencyFormatter(precision);			break;				case 'D':		case 'd':			ret = new DecimalFormatter(precision);			break;				case 'E':		case 'e':			ret = new ScientificFormatter(precision, format[0]);			break;				case 'F':		case 'f':			ret = new FixedPointFormatter(precision);			break;		case 'G':		case 'g':			ret = new GeneralFormatter(precision, format[0]);			break;		case 'N':		case 'n':			ret = new System.Private.NumberFormat.NumberFormatter(precision);			break;		case 'P':		case 'p':			ret = new PercentFormatter(precision);			break;				case 'R':		case 'r':			ret = new RoundTripFormatter(precision);			break;		case 'X':		case 'x':			ret = new HexadecimalFormatter(precision, format[0]);			break;		default:			ret = new CustomFormatter(format);			break;		}		return ret;	}	//	//  Public access method.	//	public abstract string Format(Object o, IFormatProvider provider);} // class Formatter} // namespace System.Private.Format

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?