3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
11 ** Purpose: Home for static conversion methods.
14 ===========================================================*/
17 using System.Globalization;
18 using System.Threading;
19 using System.Reflection;
20 using System.Runtime.CompilerServices;
21 using System.Runtime.InteropServices;
22 using System.Runtime.Versioning;
23 using System.Security;
24 using System.Diagnostics.Contracts;
30 public enum Base64FormattingOptions {
35 // Returns the type code of this object. An implementation of this method
36 // must not return TypeCode.Empty (which represents a null reference) or
37 // TypeCode.Object (which represents an object that doesn't implement the
38 // IConvertible interface). An implementation of this method should return
39 // TypeCode.DBNull if the value of this object is a database null. For
40 // example, a nullable integer type should return TypeCode.DBNull if the
41 // value of the object is the database null. Otherwise, an implementation
42 // of this method should return the TypeCode that best describes the
43 // internal representation of the object.
44 // The Value class provides conversion and querying methods for values. The
45 // Value class contains static members only, and it is not possible to create
46 // instances of the class.
48 // The statically typed conversion methods provided by the Value class are all
51 // public static XXX ToXXX(YYY value)
53 // where XXX is the target type and YYY is the source type. The matrix below
54 // shows the set of supported conversions. The set of conversions is symmetric
55 // such that for every ToXXX(YYY) there is also a ToYYY(XXX).
57 // From: To: Bol Chr SBy Byt I16 U16 I32 U32 I64 U64 Sgl Dbl Dec Dat Str
58 // ----------------------------------------------------------------------
59 // Boolean x x x x x x x x x x x x x
60 // Char x x x x x x x x x x
61 // SByte x x x x x x x x x x x x x x
62 // Byte x x x x x x x x x x x x x x
63 // Int16 x x x x x x x x x x x x x x
64 // UInt16 x x x x x x x x x x x x x x
65 // Int32 x x x x x x x x x x x x x x
66 // UInt32 x x x x x x x x x x x x x x
67 // Int64 x x x x x x x x x x x x x x
68 // UInt64 x x x x x x x x x x x x x x
69 // Single x x x x x x x x x x x x x
70 // Double x x x x x x x x x x x x x
71 // Decimal x x x x x x x x x x x x x
73 // String x x x x x x x x x x x x x x x
74 // ----------------------------------------------------------------------
76 // For dynamic conversions, the Value class provides a set of methods of the
79 // public static XXX ToXXX(object value)
81 // where XXX is the target type (Boolean, Char, SByte, Byte, Int16, UInt16,
82 // Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime,
83 // or String). The implementations of these methods all take the form:
85 // public static XXX toXXX(object value) {
86 // return value == null? XXX.Default: ((IConvertible)value).ToXXX();
89 // The code first checks if the given value is a null reference (which is the
90 // same as Value.Empty), in which case it returns the default value for type
91 // XXX. Otherwise, a cast to IConvertible is performed, and the appropriate ToXXX()
92 // method is invoked on the object. An InvalidCastException is thrown if the
93 // cast to IConvertible fails, and that exception is simply allowed to propagate out
94 // of the conversion method.
96 // Constant representing the database null value. This value is used in
97 // database applications to indicate the absense of a known value. Note
98 // that Value.DBNull is NOT the same as a null object reference, which is
99 // represented by Value.Empty.
101 // The Equals() method of DBNull always returns false, even when the
102 // argument is itself DBNull.
104 // When passed Value.DBNull, the Value.GetTypeCode() method returns
107 // When passed Value.DBNull, the Value.ToXXX() methods all throw an
108 // InvalidCastException.
110 public static class Convert {
112 //A typeof operation is fairly expensive (does a system call), so we'll cache these here
113 //statically. These are exactly lined up with the TypeCode, eg. ConvertType[TypeCode.Int16]
114 //will give you the type of an Int16.
115 internal static readonly RuntimeType[] ConvertTypes = {
116 (RuntimeType)typeof(System.Empty),
117 (RuntimeType)typeof(Object),
118 (RuntimeType)typeof(System.DBNull),
119 (RuntimeType)typeof(Boolean),
120 (RuntimeType)typeof(Char),
121 (RuntimeType)typeof(SByte),
122 (RuntimeType)typeof(Byte),
123 (RuntimeType)typeof(Int16),
124 (RuntimeType)typeof(UInt16),
125 (RuntimeType)typeof(Int32),
126 (RuntimeType)typeof(UInt32),
127 (RuntimeType)typeof(Int64),
128 (RuntimeType)typeof(UInt64),
129 (RuntimeType)typeof(Single),
130 (RuntimeType)typeof(Double),
131 (RuntimeType)typeof(Decimal),
132 (RuntimeType)typeof(DateTime),
133 (RuntimeType)typeof(Object), //TypeCode is discontinuous so we need a placeholder.
134 (RuntimeType)typeof(String)
137 // Need to special case Enum because typecode will be underlying type, e.g. Int32
138 private static readonly RuntimeType EnumType = (RuntimeType)typeof(Enum);
140 internal static readonly char[] base64Table = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
141 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
142 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
143 't','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
144 '8','9','+','/','=' };
146 private const Int32 base64LineBreakPosition = 76;
149 private static bool TriggerAsserts = DoAsserts();
150 private static bool DoAsserts() {
151 Contract.Assert(ConvertTypes!=null, "[Convert.cctor]ConvertTypes!=null");
152 Contract.Assert(ConvertTypes.Length == ((int)TypeCode.String + 1), "[Convert.cctor]ConvertTypes.Length == ((int)TypeCode.String + 1)");
153 Contract.Assert(ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty),
154 "[Convert.cctor]ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty)");
155 Contract.Assert(ConvertTypes[(int)TypeCode.String]==typeof(String),
156 "[Convert.cctor]ConvertTypes[(int)TypeCode.String]==typeof(System.String)");
157 Contract.Assert(ConvertTypes[(int)TypeCode.Int32]==typeof(int),
158 "[Convert.cctor]ConvertTypes[(int)TypeCode.Int32]==typeof(int)");
163 public static readonly Object DBNull = System.DBNull.Value;
165 // Returns the type code for the given object. If the argument is null,
166 // the result is TypeCode.Empty. If the argument is not a value (i.e. if
167 // the object does not implement IConvertible), the result is TypeCode.Object.
168 // Otherwise, the result is the type code of the object, as determined by
169 // the object's implementation of IConvertible.
171 public static TypeCode GetTypeCode(object value) {
172 if (value == null) return TypeCode.Empty;
173 IConvertible temp = value as IConvertible;
176 return temp.GetTypeCode();
178 return TypeCode.Object;
181 // Returns true if the given object is a database null. This operation
182 // corresponds to "value.GetTypeCode() == TypeCode.DBNull".
184 public static bool IsDBNull(object value) {
185 if (value == System.DBNull.Value) return true;
186 IConvertible convertible = value as IConvertible;
187 return convertible != null? convertible.GetTypeCode() == TypeCode.DBNull: false;
190 // Converts the given object to the given type. In general, this method is
191 // equivalent to calling the Value.ToXXX(value) method for the given
192 // typeCode and boxing the result.
194 // The method first checks if the given object implements IConvertible. If not,
195 // the only permitted conversion is from a null to TypeCode.Empty, the
196 // result of which is null.
198 // If the object does implement IConvertible, a check is made to see if the
199 // object already has the given type code, in which case the object is
200 // simply returned. Otherwise, the appropriate ToXXX() is invoked on the
201 // object's implementation of IConvertible.
202 public static Object ChangeType(Object value, TypeCode typeCode) {
203 return ChangeType(value, typeCode, Thread.CurrentThread.CurrentCulture);
206 public static Object ChangeType(Object value, TypeCode typeCode, IFormatProvider provider) {
207 if (value == null && (typeCode == TypeCode.Empty || typeCode == TypeCode.String || typeCode == TypeCode.Object)) {
211 IConvertible v = value as IConvertible;
213 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_IConvertible"));
216 // This line is invalid for things like Enums that return a TypeCode
217 // of Int32, but the object can't actually be cast to an Int32.
218 // if (v.GetTypeCode() == typeCode) return value;
220 case TypeCode.Boolean:
221 return v.ToBoolean(provider);
223 return v.ToChar(provider);
225 return v.ToSByte(provider);
227 return v.ToByte(provider);
229 return v.ToInt16(provider);
230 case TypeCode.UInt16:
231 return v.ToUInt16(provider);
233 return v.ToInt32(provider);
234 case TypeCode.UInt32:
235 return v.ToUInt32(provider);
237 return v.ToInt64(provider);
238 case TypeCode.UInt64:
239 return v.ToUInt64(provider);
240 case TypeCode.Single:
241 return v.ToSingle(provider);
242 case TypeCode.Double:
243 return v.ToDouble(provider);
244 case TypeCode.Decimal:
245 return v.ToDecimal(provider);
246 case TypeCode.DateTime:
247 return v.ToDateTime(provider);
248 case TypeCode.String:
249 return v.ToString(provider);
250 case TypeCode.Object:
252 case TypeCode.DBNull:
253 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_DBNull"));
255 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_Empty"));
257 throw new ArgumentException(Environment.GetResourceString("Arg_UnknownTypeCode"));
261 internal static Object DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) {
262 Contract.Requires(value != null, "[Convert.DefaultToType]value!=null");
263 if (targetType==null) {
264 throw new ArgumentNullException("targetType");
266 Contract.EndContractBlock();
268 RuntimeType rtTargetType = targetType as RuntimeType;
270 if (rtTargetType != null)
272 if (value.GetType() == targetType)
277 if (rtTargetType == ConvertTypes[(int)TypeCode.Boolean])
278 return value.ToBoolean(provider);
279 if (rtTargetType == ConvertTypes[(int)TypeCode.Char])
280 return value.ToChar(provider);
281 if (rtTargetType == ConvertTypes[(int)TypeCode.SByte])
282 return value.ToSByte(provider);
283 if (rtTargetType == ConvertTypes[(int)TypeCode.Byte])
284 return value.ToByte(provider);
285 if (rtTargetType == ConvertTypes[(int)TypeCode.Int16])
286 return value.ToInt16(provider);
287 if (rtTargetType == ConvertTypes[(int)TypeCode.UInt16])
288 return value.ToUInt16(provider);
289 if (rtTargetType == ConvertTypes[(int)TypeCode.Int32])
290 return value.ToInt32(provider);
291 if (rtTargetType == ConvertTypes[(int)TypeCode.UInt32])
292 return value.ToUInt32(provider);
293 if (rtTargetType == ConvertTypes[(int)TypeCode.Int64])
294 return value.ToInt64(provider);
295 if (rtTargetType == ConvertTypes[(int)TypeCode.UInt64])
296 return value.ToUInt64(provider);
297 if (rtTargetType == ConvertTypes[(int)TypeCode.Single])
298 return value.ToSingle(provider);
299 if (rtTargetType == ConvertTypes[(int)TypeCode.Double])
300 return value.ToDouble(provider);
301 if (rtTargetType == ConvertTypes[(int)TypeCode.Decimal])
302 return value.ToDecimal(provider);
303 if (rtTargetType == ConvertTypes[(int)TypeCode.DateTime])
304 return value.ToDateTime(provider);
305 if (rtTargetType == ConvertTypes[(int)TypeCode.String])
306 return value.ToString(provider);
307 if (rtTargetType == ConvertTypes[(int)TypeCode.Object])
308 return (Object)value;
309 // Need to special case Enum because typecode will be underlying type, e.g. Int32
310 if (rtTargetType == EnumType)
312 if (rtTargetType == ConvertTypes[(int)TypeCode.DBNull])
313 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_DBNull"));
314 if (rtTargetType == ConvertTypes[(int)TypeCode.Empty])
315 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_Empty"));
318 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", value.GetType().FullName, targetType.FullName));
321 public static Object ChangeType(Object value, Type conversionType) {
322 return ChangeType(value, conversionType, Thread.CurrentThread.CurrentCulture);
325 public static Object ChangeType(Object value, Type conversionType, IFormatProvider provider) {
326 if( conversionType == null) {
327 throw new ArgumentNullException("conversionType");
329 Contract.EndContractBlock();
331 if( value == null ) {
332 if(conversionType.IsValueType) {
333 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_CannotCastNullToValueType"));
338 IConvertible ic = value as IConvertible;
340 if ( value.GetType() == conversionType) {
343 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_IConvertible"));
346 RuntimeType rtConversionType = conversionType as RuntimeType;
348 if (rtConversionType==ConvertTypes[(int)TypeCode.Boolean])
349 return ic.ToBoolean(provider);
350 if (rtConversionType==ConvertTypes[(int)TypeCode.Char])
351 return ic.ToChar(provider);
352 if (rtConversionType==ConvertTypes[(int)TypeCode.SByte])
353 return ic.ToSByte(provider);
354 if (rtConversionType==ConvertTypes[(int)TypeCode.Byte])
355 return ic.ToByte(provider);
356 if (rtConversionType==ConvertTypes[(int)TypeCode.Int16])
357 return ic.ToInt16(provider);
358 if (rtConversionType==ConvertTypes[(int)TypeCode.UInt16])
359 return ic.ToUInt16(provider);
360 if (rtConversionType==ConvertTypes[(int)TypeCode.Int32])
361 return ic.ToInt32(provider);
362 if (rtConversionType==ConvertTypes[(int)TypeCode.UInt32])
363 return ic.ToUInt32(provider);
364 if (rtConversionType==ConvertTypes[(int)TypeCode.Int64])
365 return ic.ToInt64(provider);
366 if (rtConversionType==ConvertTypes[(int)TypeCode.UInt64])
367 return ic.ToUInt64(provider);
368 if (rtConversionType==ConvertTypes[(int)TypeCode.Single])
369 return ic.ToSingle(provider);
370 if (rtConversionType==ConvertTypes[(int)TypeCode.Double])
371 return ic.ToDouble(provider);
372 if (rtConversionType==ConvertTypes[(int)TypeCode.Decimal])
373 return ic.ToDecimal(provider);
374 if (rtConversionType==ConvertTypes[(int)TypeCode.DateTime])
375 return ic.ToDateTime(provider);
376 if (rtConversionType==ConvertTypes[(int)TypeCode.String])
377 return ic.ToString(provider);
378 if (rtConversionType==ConvertTypes[(int)TypeCode.Object])
379 return (Object)value;
381 return ic.ToType(conversionType, provider);
384 // Conversions to Boolean
385 public static bool ToBoolean(Object value) {
386 return value == null? false: ((IConvertible)value).ToBoolean(null);
389 public static bool ToBoolean(Object value, IFormatProvider provider) {
390 return value == null? false: ((IConvertible)value).ToBoolean(provider);
394 public static bool ToBoolean(bool value) {
398 [CLSCompliant(false)]
399 public static bool ToBoolean(sbyte value) {
403 // To be consistent with IConvertible in the base data types else we get different semantics
404 // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
405 public static bool ToBoolean(char value) {
406 return ((IConvertible)value).ToBoolean(null);
409 public static bool ToBoolean(byte value) {
414 public static bool ToBoolean(short value) {
418 [CLSCompliant(false)]
419 public static bool ToBoolean(ushort value) {
423 public static bool ToBoolean(int value) {
427 [CLSCompliant(false)]
428 public static bool ToBoolean(uint value) {
432 public static bool ToBoolean(long value) {
436 [CLSCompliant(false)]
437 public static bool ToBoolean(ulong value) {
441 public static bool ToBoolean(String value) {
444 return Boolean.Parse(value);
447 public static bool ToBoolean(String value, IFormatProvider provider) {
450 return Boolean.Parse(value);
453 public static bool ToBoolean(float value)
458 public static bool ToBoolean(double value)
463 public static bool ToBoolean(decimal value)
468 public static bool ToBoolean(DateTime value)
470 return ((IConvertible)value).ToBoolean(null);
473 // Disallowed conversions to Boolean
474 // public static bool ToBoolean(TimeSpan value)
476 // Conversions to Char
479 public static char ToChar(object value) {
480 return value == null? (char)0: ((IConvertible)value).ToChar(null);
483 public static char ToChar(object value, IFormatProvider provider) {
484 return value == null? (char)0: ((IConvertible)value).ToChar(provider);
487 public static char ToChar(bool value) {
488 return ((IConvertible)value).ToChar(null);
491 public static char ToChar(char value) {
495 [CLSCompliant(false)]
496 public static char ToChar(sbyte value) {
497 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_Char"));
498 Contract.EndContractBlock();
502 public static char ToChar(byte value) {
506 public static char ToChar(short value) {
507 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_Char"));
508 Contract.EndContractBlock();
512 [CLSCompliant(false)]
513 public static char ToChar(ushort value) {
517 public static char ToChar(int value) {
518 if (value < 0 || value > Char.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Char"));
519 Contract.EndContractBlock();
523 [CLSCompliant(false)]
524 public static char ToChar(uint value) {
525 if (value > Char.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Char"));
526 Contract.EndContractBlock();
530 public static char ToChar(long value) {
531 if (value < 0 || value > Char.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Char"));
532 Contract.EndContractBlock();
536 [CLSCompliant(false)]
537 public static char ToChar(ulong value) {
538 if (value > Char.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Char"));
539 Contract.EndContractBlock();
545 // Remove FormatExceptions;
547 public static char ToChar(String value) {
548 return ToChar(value, null);
551 public static char ToChar(String value, IFormatProvider provider) {
553 throw new ArgumentNullException("value");
554 Contract.EndContractBlock();
556 if (value.Length != 1)
557 throw new FormatException(Environment.GetResourceString(ResId.Format_NeedSingleChar));
562 // To be consistent with IConvertible in the base data types else we get different semantics
563 // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
564 public static char ToChar(float value)
566 return ((IConvertible)value).ToChar(null);
569 // To be consistent with IConvertible in the base data types else we get different semantics
570 // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
571 public static char ToChar(double value)
573 return ((IConvertible)value).ToChar(null);
576 // To be consistent with IConvertible in the base data types else we get different semantics
577 // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
578 public static char ToChar(decimal value)
580 return ((IConvertible)value).ToChar(null);
583 public static char ToChar(DateTime value)
585 return ((IConvertible)value).ToChar(null);
589 // Disallowed conversions to Char
590 // public static char ToChar(TimeSpan value)
592 // Conversions to SByte
594 [CLSCompliant(false)]
595 public static sbyte ToSByte(object value) {
596 return value == null? (sbyte)0: ((IConvertible)value).ToSByte(null);
599 [CLSCompliant(false)]
600 public static sbyte ToSByte(object value, IFormatProvider provider) {
601 return value == null? (sbyte)0: ((IConvertible)value).ToSByte(provider);
604 [CLSCompliant(false)]
605 public static sbyte ToSByte(bool value) {
606 return value? (sbyte)Boolean.True: (sbyte)Boolean.False;
609 [CLSCompliant(false)]
610 public static sbyte ToSByte(sbyte value) {
614 [CLSCompliant(false)]
615 public static sbyte ToSByte(char value) {
616 if (value > SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
617 Contract.EndContractBlock();
621 [CLSCompliant(false)]
622 public static sbyte ToSByte(byte value) {
623 if (value > SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
624 Contract.EndContractBlock();
628 [CLSCompliant(false)]
629 public static sbyte ToSByte(short value) {
630 if (value < SByte.MinValue || value > SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
631 Contract.EndContractBlock();
635 [CLSCompliant(false)]
636 public static sbyte ToSByte(ushort value) {
637 if (value > SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
638 Contract.EndContractBlock();
642 [CLSCompliant(false)]
643 public static sbyte ToSByte(int value) {
644 if (value < SByte.MinValue || value > SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
645 Contract.EndContractBlock();
649 [CLSCompliant(false)]
650 public static sbyte ToSByte(uint value) {
651 if (value > SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
652 Contract.EndContractBlock();
656 [CLSCompliant(false)]
657 public static sbyte ToSByte(long value) {
658 if (value < SByte.MinValue || value > SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
659 Contract.EndContractBlock();
663 [CLSCompliant(false)]
664 public static sbyte ToSByte(ulong value) {
665 if (value > (ulong)SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
666 Contract.EndContractBlock();
670 [CLSCompliant(false)]
671 public static sbyte ToSByte(float value) {
672 return ToSByte((double)value);
675 [CLSCompliant(false)]
676 public static sbyte ToSByte(double value) {
677 return ToSByte(ToInt32(value));
680 [CLSCompliant(false)]
681 public static sbyte ToSByte(decimal value) {
682 return Decimal.ToSByte(Decimal.Round(value, 0));
685 [CLSCompliant(false)]
686 public static sbyte ToSByte(String value) {
689 return SByte.Parse(value, CultureInfo.CurrentCulture);
692 [CLSCompliant(false)]
693 public static sbyte ToSByte(String value, IFormatProvider provider) {
694 return SByte.Parse(value, NumberStyles.Integer, provider);
697 [CLSCompliant(false)]
698 public static sbyte ToSByte(DateTime value)
700 return ((IConvertible)value).ToSByte(null);
703 // Disallowed conversions to SByte
704 // public static sbyte ToSByte(TimeSpan value)
706 // Conversions to Byte
708 public static byte ToByte(object value) {
709 return value == null? (byte)0: ((IConvertible)value).ToByte(null);
712 public static byte ToByte(object value, IFormatProvider provider) {
713 return value == null? (byte)0: ((IConvertible)value).ToByte(provider);
716 public static byte ToByte(bool value) {
717 return value? (byte)Boolean.True: (byte)Boolean.False;
720 public static byte ToByte(byte value) {
724 public static byte ToByte(char value) {
725 if (value > Byte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
726 Contract.EndContractBlock();
730 [CLSCompliant(false)]
731 public static byte ToByte(sbyte value) {
732 if (value < Byte.MinValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
733 Contract.EndContractBlock();
737 public static byte ToByte(short value) {
738 if (value < Byte.MinValue || value > Byte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
739 Contract.EndContractBlock();
743 [CLSCompliant(false)]
744 public static byte ToByte(ushort value) {
745 if (value > Byte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
746 Contract.EndContractBlock();
750 public static byte ToByte(int value) {
751 if (value < Byte.MinValue || value > Byte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
752 Contract.EndContractBlock();
756 [CLSCompliant(false)]
757 public static byte ToByte(uint value) {
758 if (value > Byte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
759 Contract.EndContractBlock();
763 public static byte ToByte(long value) {
764 if (value < Byte.MinValue || value > Byte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
765 Contract.EndContractBlock();
769 [CLSCompliant(false)]
770 public static byte ToByte(ulong value) {
771 if (value > Byte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
772 Contract.EndContractBlock();
776 public static byte ToByte(float value) {
777 return ToByte((double)value);
780 public static byte ToByte(double value) {
781 return ToByte(ToInt32(value));
784 public static byte ToByte(decimal value) {
785 return Decimal.ToByte(Decimal.Round(value, 0));
788 public static byte ToByte(String value) {
791 return Byte.Parse(value, CultureInfo.CurrentCulture);
794 public static byte ToByte(String value, IFormatProvider provider) {
797 return Byte.Parse(value, NumberStyles.Integer, provider);
800 public static byte ToByte(DateTime value)
802 return ((IConvertible)value).ToByte(null);
806 // Disallowed conversions to Byte
807 // public static byte ToByte(TimeSpan value)
809 // Conversions to Int16
811 public static short ToInt16(object value) {
812 return value == null? (short)0: ((IConvertible)value).ToInt16(null);
815 public static short ToInt16(object value, IFormatProvider provider) {
816 return value == null? (short)0: ((IConvertible)value).ToInt16(provider);
819 public static short ToInt16(bool value) {
820 return value? (short)Boolean.True: (short)Boolean.False;
823 public static short ToInt16(char value) {
824 if (value > Int16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
825 Contract.EndContractBlock();
829 [CLSCompliant(false)]
830 public static short ToInt16(sbyte value) {
834 public static short ToInt16(byte value) {
838 [CLSCompliant(false)]
839 public static short ToInt16(ushort value) {
840 if (value > Int16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
841 Contract.EndContractBlock();
845 public static short ToInt16(int value) {
846 if (value < Int16.MinValue || value > Int16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
847 Contract.EndContractBlock();
851 [CLSCompliant(false)]
852 public static short ToInt16(uint value) {
853 if (value > Int16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
854 Contract.EndContractBlock();
858 public static short ToInt16(short value) {
862 public static short ToInt16(long value) {
863 if (value < Int16.MinValue || value > Int16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
864 Contract.EndContractBlock();
868 [CLSCompliant(false)]
869 public static short ToInt16(ulong value) {
870 if (value > (ulong)Int16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
871 Contract.EndContractBlock();
875 public static short ToInt16(float value) {
876 return ToInt16((double)value);
879 public static short ToInt16(double value) {
880 return ToInt16(ToInt32(value));
883 public static short ToInt16(decimal value) {
884 return Decimal.ToInt16(Decimal.Round(value, 0));
887 public static short ToInt16(String value) {
890 return Int16.Parse(value, CultureInfo.CurrentCulture);
893 public static short ToInt16(String value, IFormatProvider provider) {
896 return Int16.Parse(value, NumberStyles.Integer, provider);
899 public static short ToInt16(DateTime value)
901 return ((IConvertible)value).ToInt16(null);
905 // Disallowed conversions to Int16
906 // public static short ToInt16(TimeSpan value)
908 // Conversions to UInt16
910 [CLSCompliant(false)]
911 public static ushort ToUInt16(object value) {
912 return value == null? (ushort)0: ((IConvertible)value).ToUInt16(null);
915 [CLSCompliant(false)]
916 public static ushort ToUInt16(object value, IFormatProvider provider) {
917 return value == null? (ushort)0: ((IConvertible)value).ToUInt16(provider);
921 [CLSCompliant(false)]
922 public static ushort ToUInt16(bool value) {
923 return value? (ushort)Boolean.True: (ushort)Boolean.False;
926 [CLSCompliant(false)]
927 public static ushort ToUInt16(char value) {
931 [CLSCompliant(false)]
932 public static ushort ToUInt16(sbyte value) {
933 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
934 Contract.EndContractBlock();
935 return (ushort)value;
938 [CLSCompliant(false)]
939 public static ushort ToUInt16(byte value) {
943 [CLSCompliant(false)]
944 public static ushort ToUInt16(short value) {
945 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
946 Contract.EndContractBlock();
947 return (ushort)value;
950 [CLSCompliant(false)]
951 public static ushort ToUInt16(int value) {
952 if (value < 0 || value > UInt16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
953 Contract.EndContractBlock();
954 return (ushort)value;
957 [CLSCompliant(false)]
958 public static ushort ToUInt16(ushort value) {
962 [CLSCompliant(false)]
963 public static ushort ToUInt16(uint value) {
964 if (value > UInt16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
965 Contract.EndContractBlock();
966 return (ushort)value;
970 [CLSCompliant(false)]
971 public static ushort ToUInt16(long value) {
972 if (value < 0 || value > UInt16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
973 Contract.EndContractBlock();
974 return (ushort)value;
977 [CLSCompliant(false)]
978 public static ushort ToUInt16(ulong value) {
979 if (value > UInt16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
980 Contract.EndContractBlock();
981 return (ushort)value;
984 [CLSCompliant(false)]
985 public static ushort ToUInt16(float value) {
986 return ToUInt16((double)value);
989 [CLSCompliant(false)]
990 public static ushort ToUInt16(double value) {
991 return ToUInt16(ToInt32(value));
994 [CLSCompliant(false)]
995 public static ushort ToUInt16(decimal value) {
996 return Decimal.ToUInt16(Decimal.Round(value, 0));
999 [CLSCompliant(false)]
1000 public static ushort ToUInt16(String value) {
1003 return UInt16.Parse(value, CultureInfo.CurrentCulture);
1006 [CLSCompliant(false)]
1007 public static ushort ToUInt16(String value, IFormatProvider provider) {
1010 return UInt16.Parse(value, NumberStyles.Integer, provider);
1013 [CLSCompliant(false)]
1014 public static ushort ToUInt16(DateTime value)
1016 return ((IConvertible)value).ToUInt16(null);
1019 // Disallowed conversions to UInt16
1020 // public static ushort ToUInt16(TimeSpan value)
1022 // Conversions to Int32
1024 public static int ToInt32(object value) {
1025 return value == null? 0: ((IConvertible)value).ToInt32(null);
1028 public static int ToInt32(object value, IFormatProvider provider) {
1029 return value == null? 0: ((IConvertible)value).ToInt32(provider);
1033 public static int ToInt32(bool value) {
1034 return value? Boolean.True: Boolean.False;
1037 public static int ToInt32(char value) {
1041 [CLSCompliant(false)]
1042 public static int ToInt32(sbyte value) {
1046 public static int ToInt32(byte value) {
1050 public static int ToInt32(short value) {
1054 [CLSCompliant(false)]
1055 public static int ToInt32(ushort value) {
1059 [CLSCompliant(false)]
1060 public static int ToInt32(uint value) {
1061 if (value > Int32.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
1062 Contract.EndContractBlock();
1066 public static int ToInt32(int value) {
1070 public static int ToInt32(long value) {
1071 if (value < Int32.MinValue || value > Int32.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
1072 Contract.EndContractBlock();
1076 [CLSCompliant(false)]
1077 public static int ToInt32(ulong value) {
1078 if (value > Int32.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
1079 Contract.EndContractBlock();
1083 public static int ToInt32(float value) {
1084 return ToInt32((double)value);
1087 public static int ToInt32(double value) {
1089 if (value < 2147483647.5) {
1090 int result = (int)value;
1091 double dif = value - result;
1092 if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
1097 if (value >= -2147483648.5) {
1098 int result = (int)value;
1099 double dif = value - result;
1100 if (dif < -0.5 || dif == -0.5 && (result & 1) != 0) result--;
1104 throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
1107 [System.Security.SecuritySafeCritical] // auto-generated
1108 public static int ToInt32(decimal value) {
1109 return Decimal.FCallToInt32(value);
1112 public static int ToInt32(String value) {
1115 return Int32.Parse(value, CultureInfo.CurrentCulture);
1118 public static int ToInt32(String value, IFormatProvider provider) {
1121 return Int32.Parse(value, NumberStyles.Integer, provider);
1124 public static int ToInt32(DateTime value)
1126 return ((IConvertible)value).ToInt32(null);
1130 // Disallowed conversions to Int32
1131 // public static int ToInt32(TimeSpan value)
1133 // Conversions to UInt32
1135 [CLSCompliant(false)]
1136 public static uint ToUInt32(object value) {
1137 return value == null? 0: ((IConvertible)value).ToUInt32(null);
1140 [CLSCompliant(false)]
1141 public static uint ToUInt32(object value, IFormatProvider provider) {
1142 return value == null? 0: ((IConvertible)value).ToUInt32(provider);
1146 [CLSCompliant(false)]
1147 public static uint ToUInt32(bool value) {
1148 return value? (uint)Boolean.True: (uint)Boolean.False;
1151 [CLSCompliant(false)]
1152 public static uint ToUInt32(char value) {
1156 [CLSCompliant(false)]
1157 public static uint ToUInt32(sbyte value) {
1158 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
1159 Contract.EndContractBlock();
1163 [CLSCompliant(false)]
1164 public static uint ToUInt32(byte value) {
1168 [CLSCompliant(false)]
1169 public static uint ToUInt32(short value) {
1170 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
1171 Contract.EndContractBlock();
1175 [CLSCompliant(false)]
1176 public static uint ToUInt32(ushort value) {
1180 [CLSCompliant(false)]
1181 public static uint ToUInt32(int value) {
1182 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
1183 Contract.EndContractBlock();
1187 [CLSCompliant(false)]
1188 public static uint ToUInt32(uint value) {
1192 [CLSCompliant(false)]
1193 public static uint ToUInt32(long value) {
1194 if (value < 0 || value > UInt32.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
1195 Contract.EndContractBlock();
1199 [CLSCompliant(false)]
1200 public static uint ToUInt32(ulong value) {
1201 if (value > UInt32.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
1202 Contract.EndContractBlock();
1206 [CLSCompliant(false)]
1207 public static uint ToUInt32(float value) {
1208 return ToUInt32((double)value);
1211 [CLSCompliant(false)]
1212 public static uint ToUInt32(double value) {
1213 if (value >= -0.5 && value < 4294967295.5) {
1214 uint result = (uint)value;
1215 double dif = value - result;
1216 if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
1219 throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
1222 [CLSCompliant(false)]
1223 public static uint ToUInt32(decimal value) {
1224 return Decimal.ToUInt32(Decimal.Round(value, 0));
1227 [CLSCompliant(false)]
1228 public static uint ToUInt32(String value) {
1231 return UInt32.Parse(value, CultureInfo.CurrentCulture);
1234 [CLSCompliant(false)]
1235 public static uint ToUInt32(String value, IFormatProvider provider) {
1238 return UInt32.Parse(value, NumberStyles.Integer, provider);
1241 [CLSCompliant(false)]
1242 public static uint ToUInt32(DateTime value)
1244 return ((IConvertible)value).ToUInt32(null);
1247 // Disallowed conversions to UInt32
1248 // public static uint ToUInt32(TimeSpan value)
1250 // Conversions to Int64
1252 public static long ToInt64(object value) {
1253 return value == null? 0: ((IConvertible)value).ToInt64(null);
1256 public static long ToInt64(object value, IFormatProvider provider) {
1257 return value == null? 0: ((IConvertible)value).ToInt64(provider);
1261 public static long ToInt64(bool value) {
1262 return value? Boolean.True: Boolean.False;
1265 public static long ToInt64(char value) {
1269 [CLSCompliant(false)]
1270 public static long ToInt64(sbyte value) {
1274 public static long ToInt64(byte value) {
1278 public static long ToInt64(short value) {
1282 [CLSCompliant(false)]
1283 public static long ToInt64(ushort value) {
1287 public static long ToInt64(int value) {
1291 [CLSCompliant(false)]
1292 public static long ToInt64(uint value) {
1296 [CLSCompliant(false)]
1297 public static long ToInt64(ulong value) {
1298 if (value > Int64.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
1299 Contract.EndContractBlock();
1303 public static long ToInt64(long value) {
1308 public static long ToInt64(float value) {
1309 return ToInt64((double)value);
1312 public static long ToInt64(double value) {
1313 return checked((long)Math.Round(value));
1316 public static long ToInt64(decimal value) {
1317 return Decimal.ToInt64(Decimal.Round(value, 0));
1320 public static long ToInt64(string value) {
1323 return Int64.Parse(value, CultureInfo.CurrentCulture);
1326 public static long ToInt64(String value, IFormatProvider provider) {
1329 return Int64.Parse(value, NumberStyles.Integer, provider);
1332 public static long ToInt64(DateTime value)
1334 return ((IConvertible)value).ToInt64(null);
1337 // Disallowed conversions to Int64
1338 // public static long ToInt64(TimeSpan value)
1340 // Conversions to UInt64
1342 [CLSCompliant(false)]
1343 public static ulong ToUInt64(object value) {
1344 return value == null? 0: ((IConvertible)value).ToUInt64(null);
1347 [CLSCompliant(false)]
1348 public static ulong ToUInt64(object value, IFormatProvider provider) {
1349 return value == null? 0: ((IConvertible)value).ToUInt64(provider);
1352 [CLSCompliant(false)]
1353 public static ulong ToUInt64(bool value) {
1354 return value? (ulong)Boolean.True: (ulong)Boolean.False;
1357 [CLSCompliant(false)]
1358 public static ulong ToUInt64(char value) {
1363 [CLSCompliant(false)]
1364 public static ulong ToUInt64(sbyte value) {
1365 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
1366 Contract.EndContractBlock();
1367 return (ulong)value;
1370 [CLSCompliant(false)]
1371 public static ulong ToUInt64(byte value) {
1375 [CLSCompliant(false)]
1376 public static ulong ToUInt64(short value) {
1377 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
1378 Contract.EndContractBlock();
1379 return (ulong)value;
1382 [CLSCompliant(false)]
1383 public static ulong ToUInt64(ushort value) {
1387 [CLSCompliant(false)]
1388 public static ulong ToUInt64(int value) {
1389 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
1390 Contract.EndContractBlock();
1391 return (ulong)value;
1394 [CLSCompliant(false)]
1395 public static ulong ToUInt64(uint value) {
1399 [CLSCompliant(false)]
1400 public static ulong ToUInt64(long value) {
1401 if (value < 0) throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
1402 Contract.EndContractBlock();
1403 return (ulong)value;
1406 [CLSCompliant(false)]
1407 public static ulong ToUInt64(UInt64 value) {
1411 [CLSCompliant(false)]
1412 public static ulong ToUInt64(float value) {
1413 return ToUInt64((double)value);
1416 [CLSCompliant(false)]
1417 public static ulong ToUInt64(double value) {
1418 return checked((ulong)Math.Round(value));
1421 [CLSCompliant(false)]
1422 public static ulong ToUInt64(decimal value) {
1423 return Decimal.ToUInt64(Decimal.Round(value, 0));
1426 [CLSCompliant(false)]
1427 public static ulong ToUInt64(String value) {
1430 return UInt64.Parse(value, CultureInfo.CurrentCulture);
1433 [CLSCompliant(false)]
1434 public static ulong ToUInt64(String value, IFormatProvider provider) {
1437 return UInt64.Parse(value, NumberStyles.Integer, provider);
1440 [CLSCompliant(false)]
1441 public static ulong ToUInt64(DateTime value)
1443 return ((IConvertible)value).ToUInt64(null);
1446 // Disallowed conversions to UInt64
1447 // public static ulong ToUInt64(TimeSpan value)
1449 // Conversions to Single
1451 public static float ToSingle(object value) {
1452 return value == null? 0: ((IConvertible)value).ToSingle(null);
1455 public static float ToSingle(object value, IFormatProvider provider) {
1456 return value == null? 0: ((IConvertible)value).ToSingle(provider);
1459 [CLSCompliant(false)]
1460 public static float ToSingle(sbyte value) {
1464 public static float ToSingle(byte value) {
1468 public static float ToSingle(char value) {
1469 return ((IConvertible)value).ToSingle(null);
1472 public static float ToSingle(short value) {
1476 [CLSCompliant(false)]
1477 public static float ToSingle(ushort value) {
1481 public static float ToSingle(int value) {
1485 [CLSCompliant(false)]
1486 public static float ToSingle(uint value) {
1490 public static float ToSingle(long value) {
1494 [CLSCompliant(false)]
1495 public static float ToSingle(ulong value) {
1499 public static float ToSingle(float value) {
1503 public static float ToSingle(double value) {
1504 return (float)value;
1507 public static float ToSingle(decimal value) {
1508 return (float)value;
1511 public static float ToSingle(String value) {
1514 return Single.Parse(value, CultureInfo.CurrentCulture);
1517 public static float ToSingle(String value, IFormatProvider provider) {
1520 return Single.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
1524 public static float ToSingle(bool value)
1526 return value? Boolean.True: Boolean.False;
1529 public static float ToSingle(DateTime value)
1531 return ((IConvertible)value).ToSingle(null);
1534 // Disallowed conversions to Single
1535 // public static float ToSingle(TimeSpan value)
1537 // Conversions to Double
1539 public static double ToDouble(object value) {
1540 return value == null? 0: ((IConvertible)value).ToDouble(null);
1543 public static double ToDouble(object value, IFormatProvider provider) {
1544 return value == null? 0: ((IConvertible)value).ToDouble(provider);
1548 [CLSCompliant(false)]
1549 public static double ToDouble(sbyte value) {
1553 public static double ToDouble(byte value) {
1557 public static double ToDouble(short value) {
1561 public static double ToDouble(char value) {
1562 return ((IConvertible)value).ToDouble(null);
1565 [CLSCompliant(false)]
1566 public static double ToDouble(ushort value) {
1570 public static double ToDouble(int value) {
1574 [CLSCompliant(false)]
1575 public static double ToDouble(uint value) {
1579 public static double ToDouble(long value) {
1583 [CLSCompliant(false)]
1584 public static double ToDouble(ulong value) {
1588 public static double ToDouble(float value) {
1592 public static double ToDouble(double value) {
1596 public static double ToDouble(decimal value) {
1597 return (double)value;
1600 public static double ToDouble(String value) {
1603 return Double.Parse(value, CultureInfo.CurrentCulture);
1606 public static double ToDouble(String value, IFormatProvider provider) {
1609 return Double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
1612 public static double ToDouble(bool value) {
1613 return value? Boolean.True: Boolean.False;
1616 public static double ToDouble(DateTime value)
1618 return ((IConvertible)value).ToDouble(null);
1621 // Disallowed conversions to Double
1622 // public static double ToDouble(TimeSpan value)
1624 // Conversions to Decimal
1626 public static decimal ToDecimal(object value) {
1627 return value == null? 0: ((IConvertible)value).ToDecimal(null);
1630 public static decimal ToDecimal(object value, IFormatProvider provider) {
1631 return value == null? 0: ((IConvertible)value).ToDecimal(provider);
1634 [CLSCompliant(false)]
1635 public static decimal ToDecimal(sbyte value) {
1639 public static decimal ToDecimal(byte value) {
1643 public static decimal ToDecimal(char value) {
1644 return ((IConvertible)value).ToDecimal(null);
1647 public static decimal ToDecimal(short value) {
1651 [CLSCompliant(false)]
1652 public static decimal ToDecimal(ushort value) {
1656 public static decimal ToDecimal(int value) {
1660 [CLSCompliant(false)]
1661 public static decimal ToDecimal(uint value) {
1665 public static decimal ToDecimal(long value) {
1669 [CLSCompliant(false)]
1670 public static decimal ToDecimal(ulong value) {
1674 public static decimal ToDecimal(float value) {
1675 return (decimal)value;
1678 public static decimal ToDecimal(double value) {
1679 return (decimal)value;
1682 public static decimal ToDecimal(String value) {
1685 return Decimal.Parse(value, CultureInfo.CurrentCulture);
1688 public static Decimal ToDecimal(String value, IFormatProvider provider) {
1691 return Decimal.Parse(value, NumberStyles.Number, provider);
1694 public static decimal ToDecimal(decimal value) {
1698 public static decimal ToDecimal(bool value) {
1699 return value? Boolean.True: Boolean.False;
1702 public static decimal ToDecimal(DateTime value)
1704 return ((IConvertible)value).ToDecimal(null);
1707 // Disallowed conversions to Decimal
1708 // public static decimal ToDecimal(TimeSpan value)
1710 // Conversions to DateTime
1712 public static DateTime ToDateTime(DateTime value) {
1716 public static DateTime ToDateTime(object value) {
1717 return value == null? DateTime.MinValue: ((IConvertible)value).ToDateTime(null);
1720 public static DateTime ToDateTime(object value, IFormatProvider provider) {
1721 return value == null? DateTime.MinValue: ((IConvertible)value).ToDateTime(provider);
1724 public static DateTime ToDateTime(String value) {
1726 return new DateTime(0);
1727 return DateTime.Parse(value, CultureInfo.CurrentCulture);
1730 public static DateTime ToDateTime(String value, IFormatProvider provider) {
1732 return new DateTime(0);
1733 return DateTime.Parse(value, provider);
1736 [CLSCompliant(false)]
1737 public static DateTime ToDateTime(sbyte value) {
1738 return ((IConvertible)value).ToDateTime(null);
1741 public static DateTime ToDateTime(byte value) {
1742 return ((IConvertible)value).ToDateTime(null);
1745 public static DateTime ToDateTime(short value) {
1746 return ((IConvertible)value).ToDateTime(null);
1749 [CLSCompliant(false)]
1750 public static DateTime ToDateTime(ushort value) {
1751 return ((IConvertible)value).ToDateTime(null);
1754 public static DateTime ToDateTime(int value) {
1755 return ((IConvertible)value).ToDateTime(null);
1758 [CLSCompliant(false)]
1759 public static DateTime ToDateTime(uint value) {
1760 return ((IConvertible)value).ToDateTime(null);
1763 public static DateTime ToDateTime(long value) {
1764 return ((IConvertible)value).ToDateTime(null);
1767 [CLSCompliant(false)]
1768 public static DateTime ToDateTime(ulong value) {
1769 return ((IConvertible)value).ToDateTime(null);
1772 public static DateTime ToDateTime(bool value) {
1773 return ((IConvertible)value).ToDateTime(null);
1776 public static DateTime ToDateTime(char value) {
1777 return ((IConvertible)value).ToDateTime(null);
1780 public static DateTime ToDateTime(float value) {
1781 return ((IConvertible)value).ToDateTime(null);
1784 public static DateTime ToDateTime(double value) {
1785 return ((IConvertible)value).ToDateTime(null);
1788 public static DateTime ToDateTime(decimal value) {
1789 return ((IConvertible)value).ToDateTime(null);
1792 // Disallowed conversions to DateTime
1793 // public static DateTime ToDateTime(TimeSpan value)
1795 // Conversions to String
1797 public static string ToString(Object value) {
1798 return ToString(value,null);
1801 public static string ToString(Object value, IFormatProvider provider) {
1802 IConvertible ic = value as IConvertible;
1804 return ic.ToString(provider);
1805 IFormattable formattable = value as IFormattable;
1806 if (formattable != null)
1807 return formattable.ToString(null, provider);
1808 return value == null? String.Empty: value.ToString();
1811 public static string ToString(bool value) {
1812 Contract.Ensures(Contract.Result<string>() != null);
1813 return value.ToString();
1816 public static string ToString(bool value, IFormatProvider provider) {
1817 Contract.Ensures(Contract.Result<string>() != null);
1818 return value.ToString(provider);
1821 public static string ToString(char value) {
1822 Contract.Ensures(Contract.Result<string>() != null);
1823 return Char.ToString(value);
1826 public static string ToString(char value, IFormatProvider provider) {
1827 Contract.Ensures(Contract.Result<string>() != null);
1828 return value.ToString(provider);
1831 [CLSCompliant(false)]
1832 public static string ToString(sbyte value) {
1833 Contract.Ensures(Contract.Result<string>() != null);
1834 return value.ToString(CultureInfo.CurrentCulture);
1837 [CLSCompliant(false)]
1838 public static string ToString(sbyte value, IFormatProvider provider) {
1839 Contract.Ensures(Contract.Result<string>() != null);
1840 return value.ToString(provider);
1843 public static string ToString(byte value) {
1844 Contract.Ensures(Contract.Result<string>() != null);
1845 return value.ToString(CultureInfo.CurrentCulture);
1848 public static string ToString(byte value, IFormatProvider provider) {
1849 Contract.Ensures(Contract.Result<string>() != null);
1850 return value.ToString(provider);
1853 public static string ToString(short value) {
1854 Contract.Ensures(Contract.Result<string>() != null);
1855 return value.ToString(CultureInfo.CurrentCulture);
1858 public static string ToString(short value, IFormatProvider provider) {
1859 Contract.Ensures(Contract.Result<string>() != null);
1860 return value.ToString(provider);
1863 [CLSCompliant(false)]
1864 public static string ToString(ushort value) {
1865 Contract.Ensures(Contract.Result<string>() != null);
1866 return value.ToString(CultureInfo.CurrentCulture);
1869 [CLSCompliant(false)]
1870 public static string ToString(ushort value, IFormatProvider provider) {
1871 Contract.Ensures(Contract.Result<string>() != null);
1872 return value.ToString(provider);
1875 public static string ToString(int value) {
1876 Contract.Ensures(Contract.Result<string>() != null);
1877 return value.ToString(CultureInfo.CurrentCulture);
1880 public static string ToString(int value, IFormatProvider provider) {
1881 Contract.Ensures(Contract.Result<string>() != null);
1882 return value.ToString(provider);
1885 [CLSCompliant(false)]
1886 public static string ToString(uint value) {
1887 Contract.Ensures(Contract.Result<string>() != null);
1888 return value.ToString(CultureInfo.CurrentCulture);
1891 [CLSCompliant(false)]
1892 public static string ToString(uint value, IFormatProvider provider) {
1893 Contract.Ensures(Contract.Result<string>() != null);
1894 return value.ToString(provider);
1897 public static string ToString(long value) {
1898 Contract.Ensures(Contract.Result<string>() != null);
1899 return value.ToString(CultureInfo.CurrentCulture);
1902 public static string ToString(long value, IFormatProvider provider) {
1903 Contract.Ensures(Contract.Result<string>() != null);
1904 return value.ToString(provider);
1907 [CLSCompliant(false)]
1908 public static string ToString(ulong value) {
1909 Contract.Ensures(Contract.Result<string>() != null);
1910 return value.ToString(CultureInfo.CurrentCulture);
1913 [CLSCompliant(false)]
1914 public static string ToString(ulong value, IFormatProvider provider) {
1915 Contract.Ensures(Contract.Result<string>() != null);
1916 return value.ToString(provider);
1919 public static string ToString(float value) {
1920 Contract.Ensures(Contract.Result<string>() != null);
1921 return value.ToString(CultureInfo.CurrentCulture);
1924 public static string ToString(float value, IFormatProvider provider) {
1925 Contract.Ensures(Contract.Result<string>() != null);
1926 return value.ToString(provider);
1929 public static string ToString(double value) {
1930 Contract.Ensures(Contract.Result<string>() != null);
1931 return value.ToString(CultureInfo.CurrentCulture);
1934 public static string ToString(double value, IFormatProvider provider) {
1935 Contract.Ensures(Contract.Result<string>() != null);
1936 return value.ToString(provider);
1939 public static string ToString(decimal value) {
1940 Contract.Ensures(Contract.Result<string>() != null);
1941 return value.ToString(CultureInfo.CurrentCulture);
1944 public static string ToString(Decimal value, IFormatProvider provider) {
1945 Contract.Ensures(Contract.Result<string>() != null);
1946 return value.ToString(provider);
1949 public static string ToString(DateTime value) {
1950 Contract.Ensures(Contract.Result<string>() != null);
1951 return value.ToString();
1954 public static string ToString(DateTime value, IFormatProvider provider) {
1955 Contract.Ensures(Contract.Result<string>() != null);
1956 return value.ToString(provider);
1959 public static String ToString(String value) {
1960 Contract.Ensures(Contract.Result<string>() == value); // We were always skipping the null check here.
1964 public static String ToString(String value,IFormatProvider provider) {
1965 Contract.Ensures(Contract.Result<string>() == value); // We were always skipping the null check here.
1966 return value; // avoid the null check
1971 // Conversions which understand Base XXX numbers.
1973 // Parses value in base base. base can only
1974 // be 2, 8, 10, or 16. If base is 16, the number may be preceded
1975 // by 0x; any other leading or trailing characters cause an error.
1977 public static byte ToByte (String value, int fromBase) {
1978 if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
1979 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
1981 Contract.EndContractBlock();
1982 int r = ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
1983 if (r < Byte.MinValue || r > Byte.MaxValue)
1984 throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
1988 // Parses value in base fromBase. fromBase can only
1989 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
1990 // by 0x; any other leading or trailing characters cause an error.
1992 [CLSCompliant(false)]
1993 public static sbyte ToSByte (String value, int fromBase) {
1994 if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
1995 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
1997 Contract.EndContractBlock();
1998 int r = ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight | ParseNumbers.TreatAsI1);
1999 if (fromBase != 10 && r <= Byte.MaxValue)
2002 if (r < SByte.MinValue || r > SByte.MaxValue)
2003 throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
2007 // Parses value in base fromBase. fromBase can only
2008 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2009 // by 0x; any other leading or trailing characters cause an error.
2011 public static short ToInt16 (String value, int fromBase) {
2012 if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
2013 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2015 Contract.EndContractBlock();
2016 int r = ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight | ParseNumbers.TreatAsI2);
2017 if (fromBase != 10 && r <= UInt16.MaxValue)
2020 if (r < Int16.MinValue || r > Int16.MaxValue)
2021 throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
2025 // Parses value in base fromBase. fromBase can only
2026 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2027 // by 0x; any other leading or trailing characters cause an error.
2029 [CLSCompliant(false)]
2030 public static ushort ToUInt16 (String value, int fromBase) {
2031 if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
2032 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2034 Contract.EndContractBlock();
2035 int r = ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
2036 if (r < UInt16.MinValue || r > UInt16.MaxValue)
2037 throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
2041 // Parses value in base fromBase. fromBase can only
2042 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2043 // by 0x; any other leading or trailing characters cause an error.
2045 public static int ToInt32 (String value, int fromBase) {
2046 if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
2047 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2049 Contract.EndContractBlock();
2050 return ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight);
2053 // Parses value in base fromBase. fromBase can only
2054 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2055 // by 0x; any other leading or trailing characters cause an error.
2057 [CLSCompliant(false)]
2058 public static uint ToUInt32 (String value, int fromBase) {
2059 if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
2060 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2062 Contract.EndContractBlock();
2063 return (uint) ParseNumbers.StringToInt(value,fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight);
2066 // Parses value in base fromBase. fromBase can only
2067 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2068 // by 0x; any other leading or trailing characters cause an error.
2070 public static long ToInt64 (String value, int fromBase) {
2071 if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
2072 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2074 Contract.EndContractBlock();
2075 return ParseNumbers.StringToLong(value,fromBase,ParseNumbers.IsTight);
2078 // Parses value in base fromBase. fromBase can only
2079 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2080 // by 0x; any other leading or trailing characters cause an error.
2082 [CLSCompliant(false)]
2083 public static ulong ToUInt64 (String value, int fromBase) {
2084 if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
2085 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2087 Contract.EndContractBlock();
2088 return (ulong) ParseNumbers.StringToLong(value,fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight);
2091 // Convert the byte value to a string in base fromBase
2092 [System.Security.SecuritySafeCritical] // auto-generated
2093 public static String ToString (byte value, int toBase) {
2094 if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
2095 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2097 Contract.EndContractBlock();
2098 return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI1);
2101 // Convert the Int16 value to a string in base fromBase
2102 [System.Security.SecuritySafeCritical] // auto-generated
2103 public static String ToString (short value, int toBase) {
2104 if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
2105 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2107 Contract.EndContractBlock();
2108 return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI2);
2111 // Convert the Int32 value to a string in base toBase
2112 [System.Security.SecuritySafeCritical] // auto-generated
2113 public static String ToString (int value, int toBase) {
2114 if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
2115 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2117 Contract.EndContractBlock();
2118 return ParseNumbers.IntToString(value, toBase, -1, ' ', 0);
2121 // Convert the Int64 value to a string in base toBase
2122 [System.Security.SecuritySafeCritical] // auto-generated
2123 public static String ToString (long value, int toBase) {
2124 if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
2125 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
2127 Contract.EndContractBlock();
2128 return ParseNumbers.LongToString(value, toBase, -1, ' ', 0);
2131 public static String ToBase64String(byte[] inArray) {
2132 if (inArray==null) {
2133 throw new ArgumentNullException("inArray");
2135 Contract.Ensures(Contract.Result<string>() != null);
2136 Contract.EndContractBlock();
2137 return ToBase64String(inArray, 0, inArray.Length, Base64FormattingOptions.None);
2140 [System.Runtime.InteropServices.ComVisible(false)]
2141 public static String ToBase64String(byte[] inArray, Base64FormattingOptions options) {
2142 if (inArray==null) {
2143 throw new ArgumentNullException("inArray");
2145 Contract.Ensures(Contract.Result<string>() != null);
2146 Contract.EndContractBlock();
2147 return ToBase64String(inArray, 0, inArray.Length, options);
2150 public static String ToBase64String(byte[] inArray, int offset, int length) {
2151 return ToBase64String(inArray, offset, length, Base64FormattingOptions.None);
2154 [System.Security.SecuritySafeCritical] // auto-generated
2155 [System.Runtime.InteropServices.ComVisible(false)]
2156 public static unsafe String ToBase64String(byte[] inArray, int offset, int length, Base64FormattingOptions options) {
2157 //Do data verfication
2159 throw new ArgumentNullException("inArray");
2161 throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2163 throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
2164 if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
2165 throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options));
2166 Contract.Ensures(Contract.Result<string>() != null);
2167 Contract.EndContractBlock();
2172 inArrayLength = inArray.Length;
2173 if (offset > (inArrayLength - length))
2174 throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
2176 if (inArrayLength == 0)
2177 return String.Empty;
2179 bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
2180 //Create the new string. This is the maximally required length.
2181 stringLength = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
2183 string returnString = string.FastAllocateString(stringLength);
2184 fixed (char* outChars = returnString){
2185 fixed (byte* inData = inArray) {
2186 int j = ConvertToBase64Array(outChars,inData,offset,length, insertLineBreaks);
2187 BCLDebug.Assert(returnString.Length == j, "returnString.Length == j");
2188 return returnString;
2193 public static int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut) {
2194 Contract.Ensures(Contract.Result<int>() >= 0);
2195 Contract.Ensures(Contract.Result<int>() <= outArray.Length);
2196 Contract.EndContractBlock();
2198 return ToBase64CharArray(inArray, offsetIn, length, outArray, offsetOut, Base64FormattingOptions.None);
2201 [System.Security.SecuritySafeCritical] // auto-generated
2202 [System.Runtime.InteropServices.ComVisible(false)]
2203 public static unsafe int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut, Base64FormattingOptions options) {
2204 //Do data verfication
2206 throw new ArgumentNullException("inArray");
2208 throw new ArgumentNullException("outArray");
2210 throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2212 throw new ArgumentOutOfRangeException("offsetIn", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
2214 throw new ArgumentOutOfRangeException("offsetOut", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
2216 if( options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks) {
2217 throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options));
2219 Contract.Ensures(Contract.Result<int>() >= 0);
2220 Contract.Ensures(Contract.Result<int>() <= outArray.Length);
2221 Contract.EndContractBlock();
2228 int numElementsToCopy;
2230 inArrayLength = inArray.Length;
2232 if (offsetIn > (int)(inArrayLength - length))
2233 throw new ArgumentOutOfRangeException("offsetIn", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
2235 if (inArrayLength == 0)
2238 bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
2239 //This is the maximally required length that must be available in the char array
2240 outArrayLength = outArray.Length;
2242 // Length of the char buffer required
2243 numElementsToCopy = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
2245 if (offsetOut > (int)(outArrayLength - numElementsToCopy))
2246 throw new ArgumentOutOfRangeException("offsetOut", Environment.GetResourceString("ArgumentOutOfRange_OffsetOut"));
2248 fixed (char* outChars = &outArray[offsetOut]) {
2249 fixed (byte* inData = inArray) {
2250 retVal = ConvertToBase64Array(outChars,inData,offsetIn,length, insertLineBreaks);
2257 [System.Security.SecurityCritical] // auto-generated
2258 private static unsafe int ConvertToBase64Array(char* outChars, byte* inData, int offset, int length, bool insertLineBreaks) {
2259 int lengthmod3 = length%3;
2260 int calcLength = offset + (length - lengthmod3);
2263 //Convert three bytes at a time to base64 notation. This will consume 4 chars.
2266 // get a pointer to the base64Table to avoid unnecessary range checking
2267 fixed(char* base64 = base64Table) {
2268 for (i=offset; i<calcLength; i+=3)
2270 if (insertLineBreaks) {
2271 if (charcount == base64LineBreakPosition) {
2272 outChars[j++] = '\r';
2273 outChars[j++] = '\n';
2278 outChars[j] = base64[(inData[i]&0xfc)>>2];
2279 outChars[j+1] = base64[((inData[i]&0x03)<<4) | ((inData[i+1]&0xf0)>>4)];
2280 outChars[j+2] = base64[((inData[i+1]&0x0f)<<2) | ((inData[i+2]&0xc0)>>6)];
2281 outChars[j+3] = base64[(inData[i+2]&0x3f)];
2285 //Where we left off before
2288 if (insertLineBreaks && (lengthmod3 !=0) && (charcount == base64LineBreakPosition)) {
2289 outChars[j++] = '\r';
2290 outChars[j++] = '\n';
2295 case 2: //One character padding needed
2296 outChars[j] = base64[(inData[i]&0xfc)>>2];
2297 outChars[j+1] = base64[((inData[i]&0x03)<<4)|((inData[i+1]&0xf0)>>4)];
2298 outChars[j+2] = base64[(inData[i+1]&0x0f)<<2];
2299 outChars[j+3] = base64[64]; //Pad
2302 case 1: // Two character padding needed
2303 outChars[j] = base64[(inData[i]&0xfc)>>2];
2304 outChars[j+1] = base64[(inData[i]&0x03)<<4];
2305 outChars[j+2] = base64[64]; //Pad
2306 outChars[j+3] = base64[64]; //Pad
2315 private static int ToBase64_CalculateAndValidateOutputLength(int inputLength, bool insertLineBreaks) {
2316 long outlen = ((long)inputLength) / 3 * 4; // the base length - we want integer division here.
2317 outlen += ((inputLength % 3) != 0) ? 4 : 0; // at most 4 more chars for the remainder
2322 if (insertLineBreaks) {
2323 long newLines = outlen / base64LineBreakPosition;
2324 if ((outlen % base64LineBreakPosition) == 0) {
2327 outlen += newLines * 2; // the number of line break chars we'll add, "\r\n"
2330 // If we overflow an int then we cannot allocate enough
2331 // memory to output the value so throw
2332 if (outlen > int.MaxValue)
2333 throw new OutOfMemoryException();
2340 /// Converts the specified string, which encodes binary data as Base64 digits, to the equivalent byte array.
2342 /// <param name="s">The string to convert</param>
2343 /// <returns>The array of bytes represented by the specifed Base64 string.</returns>
2344 [SecuritySafeCritical]
2345 public static Byte[] FromBase64String(String s) {
2347 // "s" is an unfortunate parameter name, but we need to keep it for backward compat.
2350 throw new ArgumentNullException("s");
2352 Contract.EndContractBlock();
2355 fixed (Char* sPtr = s) {
2357 return FromBase64CharPtr(sPtr, s.Length);
2364 /// Converts the specified range of a Char array, which encodes binary data as Base64 digits, to the equivalent byte array.
2366 /// <param name="inArray">Chars representing Base64 encoding characters</param>
2367 /// <param name="offset">A position within the input array.</param>
2368 /// <param name="length">Number of element to convert.</param>
2369 /// <returns>The array of bytes represented by the specified Base64 encoding characters.</returns>
2370 [SecuritySafeCritical]
2371 public static Byte[] FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length) {
2373 if (inArray == null)
2374 throw new ArgumentNullException("inArray");
2376 #if FEATURE_LEGACYNETCF
2377 Contract.EndContractBlock();
2379 // throw FormatException, to ensure compatibility with Mango Apps.
2380 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
2381 if(inArray.Length == 0) {
2382 throw new FormatException();
2388 throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2391 throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
2393 if (offset > inArray.Length - length)
2394 throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
2396 #if !FEATURE_LEGACYNETCF // Our compat hack above breaks CCRewrite's rules on valid contracts.
2397 Contract.EndContractBlock();
2401 fixed (Char* inArrayPtr = inArray) {
2403 return FromBase64CharPtr(inArrayPtr + offset, length);
2411 /// Convert Base64 encoding characters to bytes:
2412 /// - Compute result length exactly by actually walking the input;
2413 /// - Allocate new result array based on computation;
2414 /// - Decode input into the new array;
2416 /// <param name="inputPtr">Pointer to the first input char</param>
2417 /// <param name="inputLength">Number of input chars</param>
2418 /// <returns></returns>
2420 private static unsafe Byte[] FromBase64CharPtr(Char* inputPtr, Int32 inputLength) {
2422 // The validity of parameters much be checked by callers, thus we are Critical here.
2424 Contract.Assert(0 <= inputLength);
2426 // We need to get rid of any trailing white spaces.
2427 // Otherwise we would be rejecting input such as "abc= ":
2428 while (inputLength > 0)
2430 Int32 lastChar = inputPtr[inputLength - 1];
2431 if (lastChar != (Int32) ' ' && lastChar != (Int32) '\n' && lastChar != (Int32) '\r' && lastChar != (Int32) '\t')
2436 // Compute the output length:
2437 Int32 resultLength = FromBase64_ComputeResultLength(inputPtr, inputLength);
2439 Contract.Assert(0 <= resultLength);
2441 // resultLength can be zero. We will still enter FromBase64_Decode and process the input.
2442 // It may either simply write no bytes (e.g. input = " ") or throw (e.g. input = "ab").
2444 // Create result byte blob:
2445 Byte[] decodedBytes = new Byte[resultLength];
2447 // Convert Base64 chars into bytes:
2448 fixed (Byte* decodedBytesPtr = decodedBytes)
2449 FromBase64_Decode(inputPtr, inputLength, decodedBytesPtr, resultLength);
2451 // Note that actualResultLength can differ from resultLength if the caller is modifying the array
2452 // as it is being converted. Silently ignore the failure.
2453 // Consider throwing exception in an non in-place release.
2456 return decodedBytes;
2461 /// Decode characters representing a Base64 encoding into bytes:
2462 /// Walk the input. Every time 4 chars are read, convert them to the 3 corresponding output bytes.
2463 /// This method is a bit lengthy on purpose. We are trying to avoid jumps to helpers in the loop
2464 /// to aid performance.
2466 /// <param name="inputPtr">Pointer to first input char</param>
2467 /// <param name="inputLength">Number of input chars</param>
2468 /// <param name="destPtr">Pointer to location for teh first result byte</param>
2469 /// <param name="destLength">Max length of the preallocated result buffer</param>
2470 /// <returns>If the result buffer was not large enough to write all result bytes, return -1;
2471 /// Otherwise return the number of result bytes actually produced.</returns>
2473 private static unsafe Int32 FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength) {
2475 // You may find this method weird to look at. It
\92s written for performance, not aesthetics.
2476 // You will find unrolled loops label jumps and bit manipulations.
2478 const UInt32 intA = (UInt32) 'A';
2479 const UInt32 inta = (UInt32) 'a';
2480 const UInt32 int0 = (UInt32) '0';
2481 const UInt32 intEq = (UInt32) '=';
2482 const UInt32 intPlus = (UInt32) '+';
2483 const UInt32 intSlash = (UInt32) '/';
2484 const UInt32 intSpace = (UInt32) ' ';
2485 const UInt32 intTab = (UInt32) '\t';
2486 const UInt32 intNLn = (UInt32) '\n';
2487 const UInt32 intCRt = (UInt32) '\r';
2488 const UInt32 intAtoZ = (UInt32) ('Z' - 'A'); // = ('z' - 'a')
2489 const UInt32 int0to9 = (UInt32) ('9' - '0');
2491 Char* inputPtr = startInputPtr;
2492 Byte* destPtr = startDestPtr;
2494 // Pointers to the end of input and output:
2495 Char* endInputPtr = inputPtr + inputLength;
2496 Byte* endDestPtr = destPtr + destLength;
2498 // Current char code/value:
2501 // This 4-byte integer will contain the 4 codes of the current 4-char group.
2502 // Eeach char codes for 6 bits = 24 bits.
2503 // The remaining byte will be FF, we use it as a marker when 4 chars have been processed.
2504 UInt32 currBlockCodes = 0x000000FFu;
2506 unchecked { while (true) {
2509 if (inputPtr >= endInputPtr)
2510 goto _AllInputConsumed;
2512 // Get current char:
2513 currCode = (UInt32) (*inputPtr);
2516 // Determine current char code:
2518 if (currCode - intA <= intAtoZ)
2521 else if (currCode - inta <= intAtoZ)
2522 currCode -= (inta - 26u);
2524 else if (currCode - int0 <= int0to9)
2525 currCode -= (int0 - 52u);
2528 // Use the slower switch for less common cases:
2531 // Significant chars:
2532 case intPlus: currCode = 62u;
2535 case intSlash: currCode = 63u;
2538 // Legal no-value chars (we ignore these):
2539 case intCRt: case intNLn: case intSpace: case intTab:
2542 // The equality char is only legal at the end of the input.
2543 // Jump after the loop to make it easier for the JIT register predictor to do a good job for the loop itself:
2545 goto _EqualityCharEncountered;
2547 // Other chars are illegal:
2549 throw new FormatException(Environment.GetResourceString("Format_BadBase64Char"));
2553 // Ok, we got the code. Save it:
2554 currBlockCodes = (currBlockCodes << 6) | currCode;
2556 // Last bit in currBlockCodes will be on after in shifted right 4 times:
2557 if ((currBlockCodes & 0x80000000u) != 0u) {
2559 if ((Int32) (endDestPtr - destPtr) < 3)
2562 *(destPtr) = (Byte) (currBlockCodes >> 16);
2563 *(destPtr + 1) = (Byte) (currBlockCodes >> 8);
2564 *(destPtr + 2) = (Byte) (currBlockCodes);
2567 currBlockCodes = 0x000000FFu;
2570 }} // unchecked while
2572 // 'd be nice to have an assert that we never get here, but CS0162: Unreachable code detected.
2573 // Contract.Assert(false, "We only leave the above loop by jumping; should never get here.");
2575 // We jump here out of the loop if we hit an '=':
2576 _EqualityCharEncountered:
2578 Contract.Assert(currCode == intEq);
2580 // Recall that inputPtr is now one position past where '=' was read.
2581 // '=' can only be at the last input pos:
2582 if (inputPtr == endInputPtr) {
2584 // Code is zero for trailing '=':
2585 currBlockCodes <<= 6;
2587 // The '=' did not complete a 4-group. The input must be bad:
2588 if ((currBlockCodes & 0x80000000u) == 0u)
2589 throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
2591 if ((int)(endDestPtr - destPtr) < 2) // Autch! We underestimated the output length!
2594 // We are good, store bytes form this past group. We had a single "=", so we take two bytes:
2595 *(destPtr++) = (Byte) (currBlockCodes >> 16);
2596 *(destPtr++) = (Byte) (currBlockCodes >> 8);
2598 currBlockCodes = 0x000000FFu;
2600 } else { // '=' can also be at the pre-last position iff the last is also a '=' excluding the white spaces:
2602 // We need to get rid of any intermediate white spaces.
2603 // Otherwise we would be rejecting input such as "abc= =":
2604 while (inputPtr < (endInputPtr - 1))
2606 Int32 lastChar = *(inputPtr);
2607 if (lastChar != (Int32) ' ' && lastChar != (Int32) '\n' && lastChar != (Int32) '\r' && lastChar != (Int32) '\t')
2612 if (inputPtr == (endInputPtr - 1) && *(inputPtr) == '=') {
2614 // Code is zero for each of the two '=':
2615 currBlockCodes <<= 12;
2617 // The '=' did not complete a 4-group. The input must be bad:
2618 if ((currBlockCodes & 0x80000000u) == 0u)
2619 throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
2621 if ((Int32) (endDestPtr - destPtr) < 1) // Autch! We underestimated the output length!
2624 // We are good, store bytes form this past group. We had a "==", so we take only one byte:
2625 *(destPtr++) = (Byte) (currBlockCodes >> 16);
2627 currBlockCodes = 0x000000FFu;
2629 } else // '=' is not ok at places other than the end:
2630 throw new FormatException(Environment.GetResourceString("Format_BadBase64Char"));
2634 // We get here either from above or by jumping out of the loop:
2637 // The last block of chars has less than 4 items
2638 if (currBlockCodes != 0x000000FFu)
2639 throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
2641 // Return how many bytes were actually recovered:
2642 return (Int32) (destPtr - startDestPtr);
2644 } // Int32 FromBase64_Decode(...)
2648 /// Compute the number of bytes encoded in the specified Base 64 char array:
2649 /// Walk the entire input counting white spaces and padding chars, then compute result length
2650 /// based on 3 bytes per 4 chars.
2653 private static unsafe Int32 FromBase64_ComputeResultLength(Char* inputPtr, Int32 inputLength) {
2655 const UInt32 intEq = (UInt32) '=';
2656 const UInt32 intSpace = (UInt32) ' ';
2658 Contract.Assert(0 <= inputLength);
2660 Char* inputEndPtr = inputPtr + inputLength;
2661 Int32 usefulInputLength = inputLength;
2664 while (inputPtr < inputEndPtr) {
2666 UInt32 c = (UInt32) (*inputPtr);
2669 // We want to be as fast as possible and filter out spaces with as few comparisons as possible.
2670 // We end up accepting a number of illegal chars as legal white-space chars.
2671 // This is ok: as soon as we hit them during actual decode we will recognise them as illegal and throw.
2673 usefulInputLength--;
2675 else if (c == intEq) {
2676 usefulInputLength--;
2681 Contract.Assert(0 <= usefulInputLength);
2683 // For legal input, we can assume that 0 <= padding < 3. But it may be more for illegal input.
2684 // We will notice it at decode when we see a '=' at the wrong place.
2685 Contract.Assert(0 <= padding);
2687 // Perf: reuse the variable that stored the number of '=' to store the number of bytes encoded by the
2688 // last group that contains the '=':
2693 else if (padding == 2)
2696 throw new FormatException(Environment.GetResourceString("Format_BadBase64Char"));
2700 return (usefulInputLength / 4) * 3 + padding;