1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 using System.Globalization;
7 using System.Threading;
8 using System.Reflection;
9 using System.Runtime.CompilerServices;
10 using System.Runtime.InteropServices;
11 using System.Runtime.Versioning;
12 using System.Security;
13 using System.Diagnostics;
18 public enum Base64FormattingOptions
24 // Returns the type code of this object. An implementation of this method
25 // must not return TypeCode.Empty (which represents a null reference) or
26 // TypeCode.Object (which represents an object that doesn't implement the
27 // IConvertible interface). An implementation of this method should return
28 // TypeCode.DBNull if the value of this object is a database null. For
29 // example, a nullable integer type should return TypeCode.DBNull if the
30 // value of the object is the database null. Otherwise, an implementation
31 // of this method should return the TypeCode that best describes the
32 // internal representation of the object.
33 // The Value class provides conversion and querying methods for values. The
34 // Value class contains static members only, and it is not possible to create
35 // instances of the class.
37 // The statically typed conversion methods provided by the Value class are all
40 // public static XXX ToXXX(YYY value)
42 // where XXX is the target type and YYY is the source type. The matrix below
43 // shows the set of supported conversions. The set of conversions is symmetric
44 // such that for every ToXXX(YYY) there is also a ToYYY(XXX).
46 // From: To: Bol Chr SBy Byt I16 U16 I32 U32 I64 U64 Sgl Dbl Dec Dat Str
47 // ----------------------------------------------------------------------
48 // Boolean x x x x x x x x x x x x x
49 // Char x x x x x x x x x x
50 // SByte x x x x x x x x x x x x x x
51 // Byte x x x x x x x x x x x x x x
52 // Int16 x x x x x x x x x x x x x x
53 // UInt16 x x x x x x x x x x x x x x
54 // Int32 x x x x x x x x x x x x x x
55 // UInt32 x x x x x x x x x x x x x x
56 // Int64 x x x x x x x x x x x x x x
57 // UInt64 x x x x x x x x x x x x x x
58 // Single x x x x x x x x x x x x x
59 // Double x x x x x x x x x x x x x
60 // Decimal x x x x x x x x x x x x x
62 // String x x x x x x x x x x x x x x x
63 // ----------------------------------------------------------------------
65 // For dynamic conversions, the Value class provides a set of methods of the
68 // public static XXX ToXXX(object value)
70 // where XXX is the target type (Boolean, Char, SByte, Byte, Int16, UInt16,
71 // Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime,
72 // or String). The implementations of these methods all take the form:
74 // public static XXX toXXX(object value) {
75 // return value == null? XXX.Default: ((IConvertible)value).ToXXX();
78 // The code first checks if the given value is a null reference (which is the
79 // same as Value.Empty), in which case it returns the default value for type
80 // XXX. Otherwise, a cast to IConvertible is performed, and the appropriate ToXXX()
81 // method is invoked on the object. An InvalidCastException is thrown if the
82 // cast to IConvertible fails, and that exception is simply allowed to propagate out
83 // of the conversion method.
85 // Constant representing the database null value. This value is used in
86 // database applications to indicate the absence of a known value. Note
87 // that Value.DBNull is NOT the same as a null object reference, which is
88 // represented by Value.Empty.
90 // The Equals() method of DBNull always returns false, even when the
91 // argument is itself DBNull.
93 // When passed Value.DBNull, the Value.GetTypeCode() method returns
96 // When passed Value.DBNull, the Value.ToXXX() methods all throw an
97 // InvalidCastException.
99 public static class Convert
101 //A typeof operation is fairly expensive (does a system call), so we'll cache these here
102 //statically. These are exactly lined up with the TypeCode, eg. ConvertType[TypeCode.Int16]
103 //will give you the type of an Int16.
104 internal static readonly Type[] ConvertTypes = {
105 typeof(System.Empty),
107 typeof(System.DBNull),
122 typeof(Object), //TypeCode is discontinuous so we need a placeholder.
126 // Need to special case Enum because typecode will be underlying type, e.g. Int32
127 private static readonly Type EnumType = typeof(Enum);
129 internal static readonly char[] base64Table = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
130 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
131 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
132 't','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
133 '8','9','+','/','=' };
135 private const Int32 base64LineBreakPosition = 76;
138 private static bool TriggerAsserts = DoAsserts();
139 private static bool DoAsserts()
141 Debug.Assert(ConvertTypes != null, "[Convert.cctor]ConvertTypes!=null");
142 Debug.Assert(ConvertTypes.Length == ((int)TypeCode.String + 1), "[Convert.cctor]ConvertTypes.Length == ((int)TypeCode.String + 1)");
143 Debug.Assert(ConvertTypes[(int)TypeCode.Empty] == typeof(System.Empty),
144 "[Convert.cctor]ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty)");
145 Debug.Assert(ConvertTypes[(int)TypeCode.String] == typeof(String),
146 "[Convert.cctor]ConvertTypes[(int)TypeCode.String]==typeof(System.String)");
147 Debug.Assert(ConvertTypes[(int)TypeCode.Int32] == typeof(int),
148 "[Convert.cctor]ConvertTypes[(int)TypeCode.Int32]==typeof(int)");
153 public static readonly Object DBNull = System.DBNull.Value;
155 // Returns the type code for the given object. If the argument is null,
156 // the result is TypeCode.Empty. If the argument is not a value (i.e. if
157 // the object does not implement IConvertible), the result is TypeCode.Object.
158 // Otherwise, the result is the type code of the object, as determined by
159 // the object's implementation of IConvertible.
160 public static TypeCode GetTypeCode(object value)
162 if (value == null) return TypeCode.Empty;
163 IConvertible temp = value as IConvertible;
166 return temp.GetTypeCode();
168 return TypeCode.Object;
171 // Returns true if the given object is a database null. This operation
172 // corresponds to "value.GetTypeCode() == TypeCode.DBNull".
173 public static bool IsDBNull(object value)
175 if (value == System.DBNull.Value) return true;
176 IConvertible convertible = value as IConvertible;
177 return convertible != null ? convertible.GetTypeCode() == TypeCode.DBNull : false;
180 // Converts the given object to the given type. In general, this method is
181 // equivalent to calling the Value.ToXXX(value) method for the given
182 // typeCode and boxing the result.
184 // The method first checks if the given object implements IConvertible. If not,
185 // the only permitted conversion is from a null to TypeCode.Empty, the
186 // result of which is null.
188 // If the object does implement IConvertible, a check is made to see if the
189 // object already has the given type code, in which case the object is
190 // simply returned. Otherwise, the appropriate ToXXX() is invoked on the
191 // object's implementation of IConvertible.
192 public static Object ChangeType(Object value, TypeCode typeCode)
194 return ChangeType(value, typeCode, CultureInfo.CurrentCulture);
197 public static Object ChangeType(Object value, TypeCode typeCode, IFormatProvider provider)
199 if (value == null && (typeCode == TypeCode.Empty || typeCode == TypeCode.String || typeCode == TypeCode.Object))
204 IConvertible v = value as IConvertible;
207 throw new InvalidCastException(SR.InvalidCast_IConvertible);
210 // This line is invalid for things like Enums that return a TypeCode
211 // of Int32, but the object can't actually be cast to an Int32.
212 // if (v.GetTypeCode() == typeCode) return value;
215 case TypeCode.Boolean:
216 return v.ToBoolean(provider);
218 return v.ToChar(provider);
220 return v.ToSByte(provider);
222 return v.ToByte(provider);
224 return v.ToInt16(provider);
225 case TypeCode.UInt16:
226 return v.ToUInt16(provider);
228 return v.ToInt32(provider);
229 case TypeCode.UInt32:
230 return v.ToUInt32(provider);
232 return v.ToInt64(provider);
233 case TypeCode.UInt64:
234 return v.ToUInt64(provider);
235 case TypeCode.Single:
236 return v.ToSingle(provider);
237 case TypeCode.Double:
238 return v.ToDouble(provider);
239 case TypeCode.Decimal:
240 return v.ToDecimal(provider);
241 case TypeCode.DateTime:
242 return v.ToDateTime(provider);
243 case TypeCode.String:
244 return v.ToString(provider);
245 case TypeCode.Object:
247 case TypeCode.DBNull:
248 throw new InvalidCastException(SR.InvalidCast_DBNull);
250 throw new InvalidCastException(SR.InvalidCast_Empty);
252 throw new ArgumentException(SR.Arg_UnknownTypeCode);
256 internal static Object DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
258 Debug.Assert(value != null, "[Convert.DefaultToType]value!=null");
259 if (targetType == null)
261 throw new ArgumentNullException(nameof(targetType));
264 if (ReferenceEquals(value.GetType(), targetType))
269 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Boolean]))
270 return value.ToBoolean(provider);
271 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Char]))
272 return value.ToChar(provider);
273 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.SByte]))
274 return value.ToSByte(provider);
275 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Byte]))
276 return value.ToByte(provider);
277 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int16]))
278 return value.ToInt16(provider);
279 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt16]))
280 return value.ToUInt16(provider);
281 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int32]))
282 return value.ToInt32(provider);
283 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt32]))
284 return value.ToUInt32(provider);
285 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int64]))
286 return value.ToInt64(provider);
287 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt64]))
288 return value.ToUInt64(provider);
289 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Single]))
290 return value.ToSingle(provider);
291 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Double]))
292 return value.ToDouble(provider);
293 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Decimal]))
294 return value.ToDecimal(provider);
295 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.DateTime]))
296 return value.ToDateTime(provider);
297 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.String]))
298 return value.ToString(provider);
299 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Object]))
300 return (Object)value;
301 // Need to special case Enum because typecode will be underlying type, e.g. Int32
302 if (ReferenceEquals(targetType, EnumType))
304 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.DBNull]))
305 throw new InvalidCastException(SR.InvalidCast_DBNull);
306 if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Empty]))
307 throw new InvalidCastException(SR.InvalidCast_Empty);
309 throw new InvalidCastException(string.Format(SR.InvalidCast_FromTo, value.GetType().FullName, targetType.FullName));
312 public static Object ChangeType(Object value, Type conversionType)
314 return ChangeType(value, conversionType, CultureInfo.CurrentCulture);
317 public static Object ChangeType(Object value, Type conversionType, IFormatProvider provider)
319 if (ReferenceEquals(conversionType, null))
321 throw new ArgumentNullException(nameof(conversionType));
326 if (conversionType.IsValueType)
328 throw new InvalidCastException(SR.InvalidCast_CannotCastNullToValueType);
333 IConvertible ic = value as IConvertible;
336 if (value.GetType() == conversionType)
340 throw new InvalidCastException(SR.InvalidCast_IConvertible);
343 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Boolean]))
344 return ic.ToBoolean(provider);
345 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Char]))
346 return ic.ToChar(provider);
347 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.SByte]))
348 return ic.ToSByte(provider);
349 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Byte]))
350 return ic.ToByte(provider);
351 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int16]))
352 return ic.ToInt16(provider);
353 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt16]))
354 return ic.ToUInt16(provider);
355 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int32]))
356 return ic.ToInt32(provider);
357 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt32]))
358 return ic.ToUInt32(provider);
359 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int64]))
360 return ic.ToInt64(provider);
361 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt64]))
362 return ic.ToUInt64(provider);
363 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Single]))
364 return ic.ToSingle(provider);
365 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Double]))
366 return ic.ToDouble(provider);
367 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Decimal]))
368 return ic.ToDecimal(provider);
369 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.DateTime]))
370 return ic.ToDateTime(provider);
371 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.String]))
372 return ic.ToString(provider);
373 if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Object]))
374 return (Object)value;
376 return ic.ToType(conversionType, provider);
379 [MethodImpl(MethodImplOptions.NoInlining)]
380 private static void ThrowCharOverflowException() { throw new OverflowException(SR.Overflow_Char); }
382 [MethodImpl(MethodImplOptions.NoInlining)]
383 private static void ThrowByteOverflowException() { throw new OverflowException(SR.Overflow_Byte); }
385 [MethodImpl(MethodImplOptions.NoInlining)]
386 private static void ThrowSByteOverflowException() { throw new OverflowException(SR.Overflow_SByte); }
388 [MethodImpl(MethodImplOptions.NoInlining)]
389 private static void ThrowInt16OverflowException() { throw new OverflowException(SR.Overflow_Int16); }
391 [MethodImpl(MethodImplOptions.NoInlining)]
392 private static void ThrowUInt16OverflowException() { throw new OverflowException(SR.Overflow_UInt16); }
394 [MethodImpl(MethodImplOptions.NoInlining)]
395 private static void ThrowInt32OverflowException() { throw new OverflowException(SR.Overflow_Int32); }
397 [MethodImpl(MethodImplOptions.NoInlining)]
398 private static void ThrowUInt32OverflowException() { throw new OverflowException(SR.Overflow_UInt32); }
400 [MethodImpl(MethodImplOptions.NoInlining)]
401 private static void ThrowInt64OverflowException() { throw new OverflowException(SR.Overflow_Int64); }
403 [MethodImpl(MethodImplOptions.NoInlining)]
404 private static void ThrowUInt64OverflowException() { throw new OverflowException(SR.Overflow_UInt64); }
406 // Conversions to Boolean
407 public static bool ToBoolean(Object value)
409 return value == null ? false : ((IConvertible)value).ToBoolean(null);
412 public static bool ToBoolean(Object value, IFormatProvider provider)
414 return value == null ? false : ((IConvertible)value).ToBoolean(provider);
418 public static bool ToBoolean(bool value)
423 [CLSCompliant(false)]
424 public static bool ToBoolean(sbyte value)
429 // To be consistent with IConvertible in the base data types else we get different semantics
430 // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
431 public static bool ToBoolean(char value)
433 return ((IConvertible)value).ToBoolean(null);
436 public static bool ToBoolean(byte value)
442 public static bool ToBoolean(short value)
447 [CLSCompliant(false)]
448 public static bool ToBoolean(ushort value)
453 public static bool ToBoolean(int value)
458 [CLSCompliant(false)]
459 public static bool ToBoolean(uint value)
464 public static bool ToBoolean(long value)
469 [CLSCompliant(false)]
470 public static bool ToBoolean(ulong value)
475 public static bool ToBoolean(String value)
479 return Boolean.Parse(value);
482 public static bool ToBoolean(String value, IFormatProvider provider)
486 return Boolean.Parse(value);
489 public static bool ToBoolean(float value)
494 public static bool ToBoolean(double value)
499 public static bool ToBoolean(decimal value)
504 public static bool ToBoolean(DateTime value)
506 return ((IConvertible)value).ToBoolean(null);
509 // Disallowed conversions to Boolean
510 // public static bool ToBoolean(TimeSpan value)
512 // Conversions to Char
515 public static char ToChar(object value)
517 return value == null ? (char)0 : ((IConvertible)value).ToChar(null);
520 public static char ToChar(object value, IFormatProvider provider)
522 return value == null ? (char)0 : ((IConvertible)value).ToChar(provider);
525 public static char ToChar(bool value)
527 return ((IConvertible)value).ToChar(null);
530 public static char ToChar(char value)
535 [CLSCompliant(false)]
536 public static char ToChar(sbyte value)
538 if (value < 0) ThrowCharOverflowException();
542 public static char ToChar(byte value)
547 public static char ToChar(short value)
549 if (value < 0) ThrowCharOverflowException();
553 [CLSCompliant(false)]
554 public static char ToChar(ushort value)
559 public static char ToChar(int value)
561 if (value < 0 || value > Char.MaxValue) ThrowCharOverflowException();
565 [CLSCompliant(false)]
566 public static char ToChar(uint value)
568 if (value > Char.MaxValue) ThrowCharOverflowException();
572 public static char ToChar(long value)
574 if (value < 0 || value > Char.MaxValue) ThrowCharOverflowException();
578 [CLSCompliant(false)]
579 public static char ToChar(ulong value)
581 if (value > Char.MaxValue) ThrowCharOverflowException();
587 // Remove FormatExceptions;
589 public static char ToChar(String value)
591 return ToChar(value, null);
594 public static char ToChar(String value, IFormatProvider provider)
597 throw new ArgumentNullException(nameof(value));
599 if (value.Length != 1)
600 throw new FormatException(SR.Format_NeedSingleChar);
605 // To be consistent with IConvertible in the base data types else we get different semantics
606 // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
607 public static char ToChar(float value)
609 return ((IConvertible)value).ToChar(null);
612 // To be consistent with IConvertible in the base data types else we get different semantics
613 // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
614 public static char ToChar(double value)
616 return ((IConvertible)value).ToChar(null);
619 // To be consistent with IConvertible in the base data types else we get different semantics
620 // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
621 public static char ToChar(decimal value)
623 return ((IConvertible)value).ToChar(null);
626 public static char ToChar(DateTime value)
628 return ((IConvertible)value).ToChar(null);
632 // Disallowed conversions to Char
633 // public static char ToChar(TimeSpan value)
635 // Conversions to SByte
637 [CLSCompliant(false)]
638 public static sbyte ToSByte(object value)
640 return value == null ? (sbyte)0 : ((IConvertible)value).ToSByte(null);
643 [CLSCompliant(false)]
644 public static sbyte ToSByte(object value, IFormatProvider provider)
646 return value == null ? (sbyte)0 : ((IConvertible)value).ToSByte(provider);
649 [CLSCompliant(false)]
650 public static sbyte ToSByte(bool value)
652 return value ? (sbyte)Boolean.True : (sbyte)Boolean.False;
655 [CLSCompliant(false)]
656 public static sbyte ToSByte(sbyte value)
661 [CLSCompliant(false)]
662 public static sbyte ToSByte(char value)
664 if (value > SByte.MaxValue) ThrowSByteOverflowException();
668 [CLSCompliant(false)]
669 public static sbyte ToSByte(byte value)
671 if (value > SByte.MaxValue) ThrowSByteOverflowException();
675 [CLSCompliant(false)]
676 public static sbyte ToSByte(short value)
678 if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
682 [CLSCompliant(false)]
683 public static sbyte ToSByte(ushort value)
685 if (value > SByte.MaxValue) ThrowSByteOverflowException();
689 [CLSCompliant(false)]
690 public static sbyte ToSByte(int value)
692 if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
696 [CLSCompliant(false)]
697 public static sbyte ToSByte(uint value)
699 if (value > SByte.MaxValue) ThrowSByteOverflowException();
703 [CLSCompliant(false)]
704 public static sbyte ToSByte(long value)
706 if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
710 [CLSCompliant(false)]
711 public static sbyte ToSByte(ulong value)
713 if (value > (ulong)SByte.MaxValue) ThrowSByteOverflowException();
717 [CLSCompliant(false)]
718 public static sbyte ToSByte(float value)
720 return ToSByte((double)value);
723 [CLSCompliant(false)]
724 public static sbyte ToSByte(double value)
726 return ToSByte(ToInt32(value));
729 [CLSCompliant(false)]
730 public static sbyte ToSByte(decimal value)
732 return Decimal.ToSByte(Decimal.Round(value, 0));
735 [CLSCompliant(false)]
736 public static sbyte ToSByte(String value)
740 return SByte.Parse(value, CultureInfo.CurrentCulture);
743 [CLSCompliant(false)]
744 public static sbyte ToSByte(String value, IFormatProvider provider)
746 return SByte.Parse(value, NumberStyles.Integer, provider);
749 [CLSCompliant(false)]
750 public static sbyte ToSByte(DateTime value)
752 return ((IConvertible)value).ToSByte(null);
755 // Disallowed conversions to SByte
756 // public static sbyte ToSByte(TimeSpan value)
758 // Conversions to Byte
760 public static byte ToByte(object value)
762 return value == null ? (byte)0 : ((IConvertible)value).ToByte(null);
765 public static byte ToByte(object value, IFormatProvider provider)
767 return value == null ? (byte)0 : ((IConvertible)value).ToByte(provider);
770 public static byte ToByte(bool value)
772 return value ? (byte)Boolean.True : (byte)Boolean.False;
775 public static byte ToByte(byte value)
780 public static byte ToByte(char value)
782 if (value > Byte.MaxValue) ThrowByteOverflowException();
786 [CLSCompliant(false)]
787 public static byte ToByte(sbyte value)
789 if (value < Byte.MinValue) ThrowByteOverflowException();
793 public static byte ToByte(short value)
795 if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
799 [CLSCompliant(false)]
800 public static byte ToByte(ushort value)
802 if (value > Byte.MaxValue) ThrowByteOverflowException();
806 public static byte ToByte(int value)
808 if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
812 [CLSCompliant(false)]
813 public static byte ToByte(uint value)
815 if (value > Byte.MaxValue) ThrowByteOverflowException();
819 public static byte ToByte(long value)
821 if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
825 [CLSCompliant(false)]
826 public static byte ToByte(ulong value)
828 if (value > Byte.MaxValue) ThrowByteOverflowException();
832 public static byte ToByte(float value)
834 return ToByte((double)value);
837 public static byte ToByte(double value)
839 return ToByte(ToInt32(value));
842 public static byte ToByte(decimal value)
844 return Decimal.ToByte(Decimal.Round(value, 0));
847 public static byte ToByte(String value)
851 return Byte.Parse(value, CultureInfo.CurrentCulture);
854 public static byte ToByte(String value, IFormatProvider provider)
858 return Byte.Parse(value, NumberStyles.Integer, provider);
861 public static byte ToByte(DateTime value)
863 return ((IConvertible)value).ToByte(null);
867 // Disallowed conversions to Byte
868 // public static byte ToByte(TimeSpan value)
870 // Conversions to Int16
872 public static short ToInt16(object value)
874 return value == null ? (short)0 : ((IConvertible)value).ToInt16(null);
877 public static short ToInt16(object value, IFormatProvider provider)
879 return value == null ? (short)0 : ((IConvertible)value).ToInt16(provider);
882 public static short ToInt16(bool value)
884 return value ? (short)Boolean.True : (short)Boolean.False;
887 public static short ToInt16(char value)
889 if (value > Int16.MaxValue) ThrowInt16OverflowException();
893 [CLSCompliant(false)]
894 public static short ToInt16(sbyte value)
899 public static short ToInt16(byte value)
904 [CLSCompliant(false)]
905 public static short ToInt16(ushort value)
907 if (value > Int16.MaxValue) ThrowInt16OverflowException();
911 public static short ToInt16(int value)
913 if (value < Int16.MinValue || value > Int16.MaxValue) ThrowInt16OverflowException();
917 [CLSCompliant(false)]
918 public static short ToInt16(uint value)
920 if (value > Int16.MaxValue) ThrowInt16OverflowException();
924 public static short ToInt16(short value)
929 public static short ToInt16(long value)
931 if (value < Int16.MinValue || value > Int16.MaxValue) ThrowInt16OverflowException();
935 [CLSCompliant(false)]
936 public static short ToInt16(ulong value)
938 if (value > (ulong)Int16.MaxValue) ThrowInt16OverflowException();
942 public static short ToInt16(float value)
944 return ToInt16((double)value);
947 public static short ToInt16(double value)
949 return ToInt16(ToInt32(value));
952 public static short ToInt16(decimal value)
954 return Decimal.ToInt16(Decimal.Round(value, 0));
957 public static short ToInt16(String value)
961 return Int16.Parse(value, CultureInfo.CurrentCulture);
964 public static short ToInt16(String value, IFormatProvider provider)
968 return Int16.Parse(value, NumberStyles.Integer, provider);
971 public static short ToInt16(DateTime value)
973 return ((IConvertible)value).ToInt16(null);
977 // Disallowed conversions to Int16
978 // public static short ToInt16(TimeSpan value)
980 // Conversions to UInt16
982 [CLSCompliant(false)]
983 public static ushort ToUInt16(object value)
985 return value == null ? (ushort)0 : ((IConvertible)value).ToUInt16(null);
988 [CLSCompliant(false)]
989 public static ushort ToUInt16(object value, IFormatProvider provider)
991 return value == null ? (ushort)0 : ((IConvertible)value).ToUInt16(provider);
995 [CLSCompliant(false)]
996 public static ushort ToUInt16(bool value)
998 return value ? (ushort)Boolean.True : (ushort)Boolean.False;
1001 [CLSCompliant(false)]
1002 public static ushort ToUInt16(char value)
1007 [CLSCompliant(false)]
1008 public static ushort ToUInt16(sbyte value)
1010 if (value < 0) ThrowUInt16OverflowException();
1011 return (ushort)value;
1014 [CLSCompliant(false)]
1015 public static ushort ToUInt16(byte value)
1020 [CLSCompliant(false)]
1021 public static ushort ToUInt16(short value)
1023 if (value < 0) ThrowUInt16OverflowException();
1024 return (ushort)value;
1027 [CLSCompliant(false)]
1028 public static ushort ToUInt16(int value)
1030 if (value < 0 || value > UInt16.MaxValue) ThrowUInt16OverflowException();
1031 return (ushort)value;
1034 [CLSCompliant(false)]
1035 public static ushort ToUInt16(ushort value)
1040 [CLSCompliant(false)]
1041 public static ushort ToUInt16(uint value)
1043 if (value > UInt16.MaxValue) ThrowUInt16OverflowException();
1044 return (ushort)value;
1048 [CLSCompliant(false)]
1049 public static ushort ToUInt16(long value)
1051 if (value < 0 || value > UInt16.MaxValue) ThrowUInt16OverflowException();
1052 return (ushort)value;
1055 [CLSCompliant(false)]
1056 public static ushort ToUInt16(ulong value)
1058 if (value > UInt16.MaxValue) ThrowUInt16OverflowException();
1059 return (ushort)value;
1062 [CLSCompliant(false)]
1063 public static ushort ToUInt16(float value)
1065 return ToUInt16((double)value);
1068 [CLSCompliant(false)]
1069 public static ushort ToUInt16(double value)
1071 return ToUInt16(ToInt32(value));
1074 [CLSCompliant(false)]
1075 public static ushort ToUInt16(decimal value)
1077 return Decimal.ToUInt16(Decimal.Round(value, 0));
1080 [CLSCompliant(false)]
1081 public static ushort ToUInt16(String value)
1085 return UInt16.Parse(value, CultureInfo.CurrentCulture);
1088 [CLSCompliant(false)]
1089 public static ushort ToUInt16(String value, IFormatProvider provider)
1093 return UInt16.Parse(value, NumberStyles.Integer, provider);
1096 [CLSCompliant(false)]
1097 public static ushort ToUInt16(DateTime value)
1099 return ((IConvertible)value).ToUInt16(null);
1102 // Disallowed conversions to UInt16
1103 // public static ushort ToUInt16(TimeSpan value)
1105 // Conversions to Int32
1107 public static int ToInt32(object value)
1109 return value == null ? 0 : ((IConvertible)value).ToInt32(null);
1112 public static int ToInt32(object value, IFormatProvider provider)
1114 return value == null ? 0 : ((IConvertible)value).ToInt32(provider);
1118 public static int ToInt32(bool value)
1120 return value ? Boolean.True : Boolean.False;
1123 public static int ToInt32(char value)
1128 [CLSCompliant(false)]
1129 public static int ToInt32(sbyte value)
1134 public static int ToInt32(byte value)
1139 public static int ToInt32(short value)
1144 [CLSCompliant(false)]
1145 public static int ToInt32(ushort value)
1150 [CLSCompliant(false)]
1151 public static int ToInt32(uint value)
1153 if (value > Int32.MaxValue) ThrowInt32OverflowException();
1157 public static int ToInt32(int value)
1162 public static int ToInt32(long value)
1164 if (value < Int32.MinValue || value > Int32.MaxValue) ThrowInt32OverflowException();
1168 [CLSCompliant(false)]
1169 public static int ToInt32(ulong value)
1171 if (value > Int32.MaxValue) ThrowInt32OverflowException();
1175 public static int ToInt32(float value)
1177 return ToInt32((double)value);
1180 public static int ToInt32(double value)
1184 if (value < 2147483647.5)
1186 int result = (int)value;
1187 double dif = value - result;
1188 if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
1194 if (value >= -2147483648.5)
1196 int result = (int)value;
1197 double dif = value - result;
1198 if (dif < -0.5 || dif == -0.5 && (result & 1) != 0) result--;
1202 throw new OverflowException(SR.Overflow_Int32);
1205 public static int ToInt32(decimal value)
1207 return Decimal.ToInt32(Decimal.Round(value, 0));
1210 public static int ToInt32(String value)
1214 return Int32.Parse(value, CultureInfo.CurrentCulture);
1217 public static int ToInt32(String value, IFormatProvider provider)
1221 return Int32.Parse(value, NumberStyles.Integer, provider);
1224 public static int ToInt32(DateTime value)
1226 return ((IConvertible)value).ToInt32(null);
1230 // Disallowed conversions to Int32
1231 // public static int ToInt32(TimeSpan value)
1233 // Conversions to UInt32
1235 [CLSCompliant(false)]
1236 public static uint ToUInt32(object value)
1238 return value == null ? 0 : ((IConvertible)value).ToUInt32(null);
1241 [CLSCompliant(false)]
1242 public static uint ToUInt32(object value, IFormatProvider provider)
1244 return value == null ? 0 : ((IConvertible)value).ToUInt32(provider);
1248 [CLSCompliant(false)]
1249 public static uint ToUInt32(bool value)
1251 return value ? (uint)Boolean.True : (uint)Boolean.False;
1254 [CLSCompliant(false)]
1255 public static uint ToUInt32(char value)
1260 [CLSCompliant(false)]
1261 public static uint ToUInt32(sbyte value)
1263 if (value < 0) ThrowUInt32OverflowException();
1267 [CLSCompliant(false)]
1268 public static uint ToUInt32(byte value)
1273 [CLSCompliant(false)]
1274 public static uint ToUInt32(short value)
1276 if (value < 0) ThrowUInt32OverflowException();
1280 [CLSCompliant(false)]
1281 public static uint ToUInt32(ushort value)
1286 [CLSCompliant(false)]
1287 public static uint ToUInt32(int value)
1289 if (value < 0) ThrowUInt32OverflowException();
1293 [CLSCompliant(false)]
1294 public static uint ToUInt32(uint value)
1299 [CLSCompliant(false)]
1300 public static uint ToUInt32(long value)
1302 if (value < 0 || value > UInt32.MaxValue) ThrowUInt32OverflowException();
1306 [CLSCompliant(false)]
1307 public static uint ToUInt32(ulong value)
1309 if (value > UInt32.MaxValue) ThrowUInt32OverflowException();
1313 [CLSCompliant(false)]
1314 public static uint ToUInt32(float value)
1316 return ToUInt32((double)value);
1319 [CLSCompliant(false)]
1320 public static uint ToUInt32(double value)
1322 if (value >= -0.5 && value < 4294967295.5)
1324 uint result = (uint)value;
1325 double dif = value - result;
1326 if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
1329 throw new OverflowException(SR.Overflow_UInt32);
1332 [CLSCompliant(false)]
1333 public static uint ToUInt32(decimal value)
1335 return Decimal.ToUInt32(Decimal.Round(value, 0));
1338 [CLSCompliant(false)]
1339 public static uint ToUInt32(String value)
1343 return UInt32.Parse(value, CultureInfo.CurrentCulture);
1346 [CLSCompliant(false)]
1347 public static uint ToUInt32(String value, IFormatProvider provider)
1351 return UInt32.Parse(value, NumberStyles.Integer, provider);
1354 [CLSCompliant(false)]
1355 public static uint ToUInt32(DateTime value)
1357 return ((IConvertible)value).ToUInt32(null);
1360 // Disallowed conversions to UInt32
1361 // public static uint ToUInt32(TimeSpan value)
1363 // Conversions to Int64
1365 public static long ToInt64(object value)
1367 return value == null ? 0 : ((IConvertible)value).ToInt64(null);
1370 public static long ToInt64(object value, IFormatProvider provider)
1372 return value == null ? 0 : ((IConvertible)value).ToInt64(provider);
1376 public static long ToInt64(bool value)
1378 return value ? Boolean.True : Boolean.False;
1381 public static long ToInt64(char value)
1386 [CLSCompliant(false)]
1387 public static long ToInt64(sbyte value)
1392 public static long ToInt64(byte value)
1397 public static long ToInt64(short value)
1402 [CLSCompliant(false)]
1403 public static long ToInt64(ushort value)
1408 public static long ToInt64(int value)
1413 [CLSCompliant(false)]
1414 public static long ToInt64(uint value)
1419 [CLSCompliant(false)]
1420 public static long ToInt64(ulong value)
1422 if (value > Int64.MaxValue) ThrowInt64OverflowException();
1426 public static long ToInt64(long value)
1432 public static long ToInt64(float value)
1434 return ToInt64((double)value);
1437 public static long ToInt64(double value)
1439 return checked((long)Math.Round(value));
1442 public static long ToInt64(decimal value)
1444 return Decimal.ToInt64(Decimal.Round(value, 0));
1447 public static long ToInt64(string value)
1451 return Int64.Parse(value, CultureInfo.CurrentCulture);
1454 public static long ToInt64(String value, IFormatProvider provider)
1458 return Int64.Parse(value, NumberStyles.Integer, provider);
1461 public static long ToInt64(DateTime value)
1463 return ((IConvertible)value).ToInt64(null);
1466 // Disallowed conversions to Int64
1467 // public static long ToInt64(TimeSpan value)
1469 // Conversions to UInt64
1471 [CLSCompliant(false)]
1472 public static ulong ToUInt64(object value)
1474 return value == null ? 0 : ((IConvertible)value).ToUInt64(null);
1477 [CLSCompliant(false)]
1478 public static ulong ToUInt64(object value, IFormatProvider provider)
1480 return value == null ? 0 : ((IConvertible)value).ToUInt64(provider);
1483 [CLSCompliant(false)]
1484 public static ulong ToUInt64(bool value)
1486 return value ? (ulong)Boolean.True : (ulong)Boolean.False;
1489 [CLSCompliant(false)]
1490 public static ulong ToUInt64(char value)
1496 [CLSCompliant(false)]
1497 public static ulong ToUInt64(sbyte value)
1499 if (value < 0) ThrowUInt64OverflowException();
1500 return (ulong)value;
1503 [CLSCompliant(false)]
1504 public static ulong ToUInt64(byte value)
1509 [CLSCompliant(false)]
1510 public static ulong ToUInt64(short value)
1512 if (value < 0) ThrowUInt64OverflowException();
1513 return (ulong)value;
1516 [CLSCompliant(false)]
1517 public static ulong ToUInt64(ushort value)
1522 [CLSCompliant(false)]
1523 public static ulong ToUInt64(int value)
1525 if (value < 0) ThrowUInt64OverflowException();
1526 return (ulong)value;
1529 [CLSCompliant(false)]
1530 public static ulong ToUInt64(uint value)
1535 [CLSCompliant(false)]
1536 public static ulong ToUInt64(long value)
1538 if (value < 0) ThrowUInt64OverflowException();
1539 return (ulong)value;
1542 [CLSCompliant(false)]
1543 public static ulong ToUInt64(UInt64 value)
1548 [CLSCompliant(false)]
1549 public static ulong ToUInt64(float value)
1551 return ToUInt64((double)value);
1554 [CLSCompliant(false)]
1555 public static ulong ToUInt64(double value)
1557 return checked((ulong)Math.Round(value));
1560 [CLSCompliant(false)]
1561 public static ulong ToUInt64(decimal value)
1563 return Decimal.ToUInt64(Decimal.Round(value, 0));
1566 [CLSCompliant(false)]
1567 public static ulong ToUInt64(String value)
1571 return UInt64.Parse(value, CultureInfo.CurrentCulture);
1574 [CLSCompliant(false)]
1575 public static ulong ToUInt64(String value, IFormatProvider provider)
1579 return UInt64.Parse(value, NumberStyles.Integer, provider);
1582 [CLSCompliant(false)]
1583 public static ulong ToUInt64(DateTime value)
1585 return ((IConvertible)value).ToUInt64(null);
1588 // Disallowed conversions to UInt64
1589 // public static ulong ToUInt64(TimeSpan value)
1591 // Conversions to Single
1593 public static float ToSingle(object value)
1595 return value == null ? 0 : ((IConvertible)value).ToSingle(null);
1598 public static float ToSingle(object value, IFormatProvider provider)
1600 return value == null ? 0 : ((IConvertible)value).ToSingle(provider);
1603 [CLSCompliant(false)]
1604 public static float ToSingle(sbyte value)
1609 public static float ToSingle(byte value)
1614 public static float ToSingle(char value)
1616 return ((IConvertible)value).ToSingle(null);
1619 public static float ToSingle(short value)
1624 [CLSCompliant(false)]
1625 public static float ToSingle(ushort value)
1630 public static float ToSingle(int value)
1635 [CLSCompliant(false)]
1636 public static float ToSingle(uint value)
1641 public static float ToSingle(long value)
1646 [CLSCompliant(false)]
1647 public static float ToSingle(ulong value)
1652 public static float ToSingle(float value)
1657 public static float ToSingle(double value)
1659 return (float)value;
1662 public static float ToSingle(decimal value)
1664 return (float)value;
1667 public static float ToSingle(String value)
1671 return Single.Parse(value, CultureInfo.CurrentCulture);
1674 public static float ToSingle(String value, IFormatProvider provider)
1678 return Single.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
1682 public static float ToSingle(bool value)
1684 return value ? Boolean.True : Boolean.False;
1687 public static float ToSingle(DateTime value)
1689 return ((IConvertible)value).ToSingle(null);
1692 // Disallowed conversions to Single
1693 // public static float ToSingle(TimeSpan value)
1695 // Conversions to Double
1697 public static double ToDouble(object value)
1699 return value == null ? 0 : ((IConvertible)value).ToDouble(null);
1702 public static double ToDouble(object value, IFormatProvider provider)
1704 return value == null ? 0 : ((IConvertible)value).ToDouble(provider);
1708 [CLSCompliant(false)]
1709 public static double ToDouble(sbyte value)
1714 public static double ToDouble(byte value)
1719 public static double ToDouble(short value)
1724 public static double ToDouble(char value)
1726 return ((IConvertible)value).ToDouble(null);
1729 [CLSCompliant(false)]
1730 public static double ToDouble(ushort value)
1735 public static double ToDouble(int value)
1740 [CLSCompliant(false)]
1741 public static double ToDouble(uint value)
1746 public static double ToDouble(long value)
1751 [CLSCompliant(false)]
1752 public static double ToDouble(ulong value)
1757 public static double ToDouble(float value)
1762 public static double ToDouble(double value)
1767 public static double ToDouble(decimal value)
1769 return (double)value;
1772 public static double ToDouble(String value)
1776 return Double.Parse(value, CultureInfo.CurrentCulture);
1779 public static double ToDouble(String value, IFormatProvider provider)
1783 return Double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
1786 public static double ToDouble(bool value)
1788 return value ? Boolean.True : Boolean.False;
1791 public static double ToDouble(DateTime value)
1793 return ((IConvertible)value).ToDouble(null);
1796 // Disallowed conversions to Double
1797 // public static double ToDouble(TimeSpan value)
1799 // Conversions to Decimal
1801 public static decimal ToDecimal(object value)
1803 return value == null ? 0 : ((IConvertible)value).ToDecimal(null);
1806 public static decimal ToDecimal(object value, IFormatProvider provider)
1808 return value == null ? 0 : ((IConvertible)value).ToDecimal(provider);
1811 [CLSCompliant(false)]
1812 public static decimal ToDecimal(sbyte value)
1817 public static decimal ToDecimal(byte value)
1822 public static decimal ToDecimal(char value)
1824 return ((IConvertible)value).ToDecimal(null);
1827 public static decimal ToDecimal(short value)
1832 [CLSCompliant(false)]
1833 public static decimal ToDecimal(ushort value)
1838 public static decimal ToDecimal(int value)
1843 [CLSCompliant(false)]
1844 public static decimal ToDecimal(uint value)
1849 public static decimal ToDecimal(long value)
1854 [CLSCompliant(false)]
1855 public static decimal ToDecimal(ulong value)
1860 public static decimal ToDecimal(float value)
1862 return (decimal)value;
1865 public static decimal ToDecimal(double value)
1867 return (decimal)value;
1870 public static decimal ToDecimal(String value)
1874 return Decimal.Parse(value, CultureInfo.CurrentCulture);
1877 public static Decimal ToDecimal(String value, IFormatProvider provider)
1881 return Decimal.Parse(value, NumberStyles.Number, provider);
1884 public static decimal ToDecimal(decimal value)
1889 public static decimal ToDecimal(bool value)
1891 return value ? Boolean.True : Boolean.False;
1894 public static decimal ToDecimal(DateTime value)
1896 return ((IConvertible)value).ToDecimal(null);
1899 // Disallowed conversions to Decimal
1900 // public static decimal ToDecimal(TimeSpan value)
1902 // Conversions to DateTime
1904 public static DateTime ToDateTime(DateTime value)
1909 public static DateTime ToDateTime(object value)
1911 return value == null ? DateTime.MinValue : ((IConvertible)value).ToDateTime(null);
1914 public static DateTime ToDateTime(object value, IFormatProvider provider)
1916 return value == null ? DateTime.MinValue : ((IConvertible)value).ToDateTime(provider);
1919 public static DateTime ToDateTime(String value)
1922 return new DateTime(0);
1923 return DateTime.Parse(value, CultureInfo.CurrentCulture);
1926 public static DateTime ToDateTime(String value, IFormatProvider provider)
1929 return new DateTime(0);
1930 return DateTime.Parse(value, provider);
1933 [CLSCompliant(false)]
1934 public static DateTime ToDateTime(sbyte value)
1936 return ((IConvertible)value).ToDateTime(null);
1939 public static DateTime ToDateTime(byte value)
1941 return ((IConvertible)value).ToDateTime(null);
1944 public static DateTime ToDateTime(short value)
1946 return ((IConvertible)value).ToDateTime(null);
1949 [CLSCompliant(false)]
1950 public static DateTime ToDateTime(ushort value)
1952 return ((IConvertible)value).ToDateTime(null);
1955 public static DateTime ToDateTime(int value)
1957 return ((IConvertible)value).ToDateTime(null);
1960 [CLSCompliant(false)]
1961 public static DateTime ToDateTime(uint value)
1963 return ((IConvertible)value).ToDateTime(null);
1966 public static DateTime ToDateTime(long value)
1968 return ((IConvertible)value).ToDateTime(null);
1971 [CLSCompliant(false)]
1972 public static DateTime ToDateTime(ulong value)
1974 return ((IConvertible)value).ToDateTime(null);
1977 public static DateTime ToDateTime(bool value)
1979 return ((IConvertible)value).ToDateTime(null);
1982 public static DateTime ToDateTime(char value)
1984 return ((IConvertible)value).ToDateTime(null);
1987 public static DateTime ToDateTime(float value)
1989 return ((IConvertible)value).ToDateTime(null);
1992 public static DateTime ToDateTime(double value)
1994 return ((IConvertible)value).ToDateTime(null);
1997 public static DateTime ToDateTime(decimal value)
1999 return ((IConvertible)value).ToDateTime(null);
2002 // Disallowed conversions to DateTime
2003 // public static DateTime ToDateTime(TimeSpan value)
2005 // Conversions to String
2007 public static string ToString(Object value)
2009 return ToString(value, null);
2012 public static string ToString(Object value, IFormatProvider provider)
2014 IConvertible ic = value as IConvertible;
2016 return ic.ToString(provider);
2017 IFormattable formattable = value as IFormattable;
2018 if (formattable != null)
2019 return formattable.ToString(null, provider);
2020 return value == null ? String.Empty : value.ToString();
2023 public static string ToString(bool value)
2025 return value.ToString();
2028 public static string ToString(bool value, IFormatProvider provider)
2030 return value.ToString();
2033 public static string ToString(char value)
2035 return Char.ToString(value);
2038 public static string ToString(char value, IFormatProvider provider)
2040 return value.ToString();
2043 [CLSCompliant(false)]
2044 public static string ToString(sbyte value)
2046 return value.ToString(CultureInfo.CurrentCulture);
2049 [CLSCompliant(false)]
2050 public static string ToString(sbyte value, IFormatProvider provider)
2052 return value.ToString(provider);
2055 public static string ToString(byte value)
2057 return value.ToString(CultureInfo.CurrentCulture);
2060 public static string ToString(byte value, IFormatProvider provider)
2062 return value.ToString(provider);
2065 public static string ToString(short value)
2067 return value.ToString(CultureInfo.CurrentCulture);
2070 public static string ToString(short value, IFormatProvider provider)
2072 return value.ToString(provider);
2075 [CLSCompliant(false)]
2076 public static string ToString(ushort value)
2078 return value.ToString(CultureInfo.CurrentCulture);
2081 [CLSCompliant(false)]
2082 public static string ToString(ushort value, IFormatProvider provider)
2084 return value.ToString(provider);
2087 public static string ToString(int value)
2089 return value.ToString(CultureInfo.CurrentCulture);
2092 public static string ToString(int value, IFormatProvider provider)
2094 return value.ToString(provider);
2097 [CLSCompliant(false)]
2098 public static string ToString(uint value)
2100 return value.ToString(CultureInfo.CurrentCulture);
2103 [CLSCompliant(false)]
2104 public static string ToString(uint value, IFormatProvider provider)
2106 return value.ToString(provider);
2109 public static string ToString(long value)
2111 return value.ToString(CultureInfo.CurrentCulture);
2114 public static string ToString(long value, IFormatProvider provider)
2116 return value.ToString(provider);
2119 [CLSCompliant(false)]
2120 public static string ToString(ulong value)
2122 return value.ToString(CultureInfo.CurrentCulture);
2125 [CLSCompliant(false)]
2126 public static string ToString(ulong value, IFormatProvider provider)
2128 return value.ToString(provider);
2131 public static string ToString(float value)
2133 return value.ToString(CultureInfo.CurrentCulture);
2136 public static string ToString(float value, IFormatProvider provider)
2138 return value.ToString(provider);
2141 public static string ToString(double value)
2143 return value.ToString(CultureInfo.CurrentCulture);
2146 public static string ToString(double value, IFormatProvider provider)
2148 return value.ToString(provider);
2151 public static string ToString(decimal value)
2153 return value.ToString(CultureInfo.CurrentCulture);
2156 public static string ToString(Decimal value, IFormatProvider provider)
2158 return value.ToString(provider);
2161 public static string ToString(DateTime value)
2163 return value.ToString();
2166 public static string ToString(DateTime value, IFormatProvider provider)
2168 return value.ToString(provider);
2171 public static String ToString(String value)
2176 public static String ToString(String value, IFormatProvider provider)
2178 return value; // avoid the null check
2183 // Conversions which understand Base XXX numbers.
2185 // Parses value in base base. base can only
2186 // be 2, 8, 10, or 16. If base is 16, the number may be preceded
2187 // by 0x; any other leading or trailing characters cause an error.
2189 public static byte ToByte(String value, int fromBase)
2191 if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
2193 throw new ArgumentException(SR.Arg_InvalidBase);
2201 int r = ParseNumbers.StringToInt(value.AsSpan(), fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
2202 if (r < Byte.MinValue || r > Byte.MaxValue)
2203 ThrowByteOverflowException();
2207 // Parses value in base fromBase. fromBase can only
2208 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2209 // by 0x; any other leading or trailing characters cause an error.
2211 [CLSCompliant(false)]
2212 public static sbyte ToSByte(String value, int fromBase)
2214 if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
2216 throw new ArgumentException(SR.Arg_InvalidBase);
2224 int r = ParseNumbers.StringToInt(value.AsSpan(), fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsI1);
2225 if (fromBase != 10 && r <= Byte.MaxValue)
2228 if (r < SByte.MinValue || r > SByte.MaxValue)
2229 ThrowSByteOverflowException();
2233 // Parses value in base fromBase. fromBase can only
2234 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2235 // by 0x; any other leading or trailing characters cause an error.
2237 public static short ToInt16(String value, int fromBase)
2239 if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
2241 throw new ArgumentException(SR.Arg_InvalidBase);
2249 int r = ParseNumbers.StringToInt(value.AsSpan(), fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsI2);
2250 if (fromBase != 10 && r <= UInt16.MaxValue)
2253 if (r < Int16.MinValue || r > Int16.MaxValue)
2254 ThrowInt16OverflowException();
2258 // Parses value in base fromBase. fromBase can only
2259 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2260 // by 0x; any other leading or trailing characters cause an error.
2262 [CLSCompliant(false)]
2263 public static ushort ToUInt16(String value, int fromBase)
2265 if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
2267 throw new ArgumentException(SR.Arg_InvalidBase);
2275 int r = ParseNumbers.StringToInt(value.AsSpan(), fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
2276 if (r < UInt16.MinValue || r > UInt16.MaxValue)
2277 ThrowUInt16OverflowException();
2281 // Parses value in base fromBase. fromBase can only
2282 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2283 // by 0x; any other leading or trailing characters cause an error.
2285 public static int ToInt32(String value, int fromBase)
2287 if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
2289 throw new ArgumentException(SR.Arg_InvalidBase);
2291 return value != null ?
2292 ParseNumbers.StringToInt(value.AsSpan(), fromBase, ParseNumbers.IsTight) :
2296 // Parses value in base fromBase. fromBase can only
2297 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2298 // by 0x; any other leading or trailing characters cause an error.
2300 [CLSCompliant(false)]
2301 public static uint ToUInt32(String value, int fromBase)
2303 if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
2305 throw new ArgumentException(SR.Arg_InvalidBase);
2307 return value != null ?
2308 (uint)ParseNumbers.StringToInt(value.AsSpan(), fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight) :
2312 // Parses value in base fromBase. fromBase can only
2313 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2314 // by 0x; any other leading or trailing characters cause an error.
2316 public static long ToInt64(String value, int fromBase)
2318 if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
2320 throw new ArgumentException(SR.Arg_InvalidBase);
2322 return value != null ?
2323 ParseNumbers.StringToLong(value.AsSpan(), fromBase, ParseNumbers.IsTight) :
2327 // Parses value in base fromBase. fromBase can only
2328 // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
2329 // by 0x; any other leading or trailing characters cause an error.
2331 [CLSCompliant(false)]
2332 public static ulong ToUInt64(String value, int fromBase)
2334 if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
2336 throw new ArgumentException(SR.Arg_InvalidBase);
2338 return value != null ?
2339 (ulong)ParseNumbers.StringToLong(value.AsSpan(), fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight) :
2343 // Convert the byte value to a string in base fromBase
2344 public static String ToString(byte value, int toBase)
2346 if (toBase != 2 && toBase != 8 && toBase != 10 && toBase != 16)
2348 throw new ArgumentException(SR.Arg_InvalidBase);
2350 return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI1);
2353 // Convert the Int16 value to a string in base fromBase
2354 public static String ToString(short value, int toBase)
2356 if (toBase != 2 && toBase != 8 && toBase != 10 && toBase != 16)
2358 throw new ArgumentException(SR.Arg_InvalidBase);
2360 return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI2);
2363 // Convert the Int32 value to a string in base toBase
2364 public static String ToString(int value, int toBase)
2366 if (toBase != 2 && toBase != 8 && toBase != 10 && toBase != 16)
2368 throw new ArgumentException(SR.Arg_InvalidBase);
2370 return ParseNumbers.IntToString(value, toBase, -1, ' ', 0);
2373 // Convert the Int64 value to a string in base toBase
2374 public static String ToString(long value, int toBase)
2376 if (toBase != 2 && toBase != 8 && toBase != 10 && toBase != 16)
2378 throw new ArgumentException(SR.Arg_InvalidBase);
2380 return ParseNumbers.LongToString(value, toBase, -1, ' ', 0);
2383 public static String ToBase64String(byte[] inArray)
2385 if (inArray == null)
2387 throw new ArgumentNullException(nameof(inArray));
2389 return ToBase64String(new ReadOnlySpan<byte>(inArray), Base64FormattingOptions.None);
2392 public static String ToBase64String(byte[] inArray, Base64FormattingOptions options)
2394 if (inArray == null)
2396 throw new ArgumentNullException(nameof(inArray));
2398 return ToBase64String(new ReadOnlySpan<byte>(inArray), options);
2401 public static String ToBase64String(byte[] inArray, int offset, int length)
2403 return ToBase64String(inArray, offset, length, Base64FormattingOptions.None);
2406 public static String ToBase64String(byte[] inArray, int offset, int length, Base64FormattingOptions options)
2408 if (inArray == null)
2409 throw new ArgumentNullException(nameof(inArray));
2411 throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index);
2413 throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_GenericPositive);
2414 if (offset > (inArray.Length - length))
2415 throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_OffsetLength);
2417 return ToBase64String(new ReadOnlySpan<byte>(inArray, offset, length), options);
2420 public static string ToBase64String(ReadOnlySpan<byte> bytes, Base64FormattingOptions options = Base64FormattingOptions.None)
2422 if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
2424 throw new ArgumentException(string.Format(SR.Arg_EnumIllegalVal, (int)options), nameof(options));
2427 if (bytes.Length == 0)
2429 return string.Empty;
2432 bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
2433 string result = string.FastAllocateString(ToBase64_CalculateAndValidateOutputLength(bytes.Length, insertLineBreaks));
2437 fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes))
2438 fixed (char* charsPtr = result)
2440 int charsWritten = ConvertToBase64Array(charsPtr, bytesPtr, 0, bytes.Length, insertLineBreaks);
2441 Debug.Assert(result.Length == charsWritten, $"Expected {result.Length} == {charsWritten}");
2448 public static int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut)
2450 return ToBase64CharArray(inArray, offsetIn, length, outArray, offsetOut, Base64FormattingOptions.None);
2453 public static unsafe int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut, Base64FormattingOptions options)
2455 //Do data verfication
2456 if (inArray == null)
2457 throw new ArgumentNullException(nameof(inArray));
2458 if (outArray == null)
2459 throw new ArgumentNullException(nameof(outArray));
2461 throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index);
2463 throw new ArgumentOutOfRangeException(nameof(offsetIn), SR.ArgumentOutOfRange_GenericPositive);
2465 throw new ArgumentOutOfRangeException(nameof(offsetOut), SR.ArgumentOutOfRange_GenericPositive);
2467 if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
2469 throw new ArgumentException(string.Format(SR.Arg_EnumIllegalVal, (int)options), nameof(options));
2477 int numElementsToCopy;
2479 inArrayLength = inArray.Length;
2481 if (offsetIn > (int)(inArrayLength - length))
2482 throw new ArgumentOutOfRangeException(nameof(offsetIn), SR.ArgumentOutOfRange_OffsetLength);
2484 if (inArrayLength == 0)
2487 bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
2488 //This is the maximally required length that must be available in the char array
2489 outArrayLength = outArray.Length;
2491 // Length of the char buffer required
2492 numElementsToCopy = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
2494 if (offsetOut > (int)(outArrayLength - numElementsToCopy))
2495 throw new ArgumentOutOfRangeException(nameof(offsetOut), SR.ArgumentOutOfRange_OffsetOut);
2497 fixed (char* outChars = &outArray[offsetOut])
2499 fixed (byte* inData = &inArray[0])
2501 retVal = ConvertToBase64Array(outChars, inData, offsetIn, length, insertLineBreaks);
2508 public static unsafe bool TryToBase64Chars(ReadOnlySpan<byte> bytes, Span<char> chars, out int charsWritten, Base64FormattingOptions options = Base64FormattingOptions.None)
2510 if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
2512 throw new ArgumentException(string.Format(SR.Arg_EnumIllegalVal, (int)options), nameof(options));
2515 if (bytes.Length == 0)
2521 bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
2523 int charLengthRequired = ToBase64_CalculateAndValidateOutputLength(bytes.Length, insertLineBreaks);
2524 if (charLengthRequired > chars.Length)
2530 fixed (char* outChars = &MemoryMarshal.GetReference(chars))
2531 fixed (byte* inData = &MemoryMarshal.GetReference(bytes))
2533 charsWritten = ConvertToBase64Array(outChars, inData, 0, bytes.Length, insertLineBreaks);
2538 private static unsafe int ConvertToBase64Array(char* outChars, byte* inData, int offset, int length, bool insertLineBreaks)
2540 int lengthmod3 = length % 3;
2541 int calcLength = offset + (length - lengthmod3);
2544 //Convert three bytes at a time to base64 notation. This will consume 4 chars.
2547 // get a pointer to the base64Table to avoid unnecessary range checking
2548 fixed (char* base64 = &base64Table[0])
2550 for (i = offset; i < calcLength; i += 3)
2552 if (insertLineBreaks)
2554 if (charcount == base64LineBreakPosition)
2556 outChars[j++] = '\r';
2557 outChars[j++] = '\n';
2562 outChars[j] = base64[(inData[i] & 0xfc) >> 2];
2563 outChars[j + 1] = base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
2564 outChars[j + 2] = base64[((inData[i + 1] & 0x0f) << 2) | ((inData[i + 2] & 0xc0) >> 6)];
2565 outChars[j + 3] = base64[(inData[i + 2] & 0x3f)];
2569 //Where we left off before
2572 if (insertLineBreaks && (lengthmod3 != 0) && (charcount == base64LineBreakPosition))
2574 outChars[j++] = '\r';
2575 outChars[j++] = '\n';
2580 case 2: //One character padding needed
2581 outChars[j] = base64[(inData[i] & 0xfc) >> 2];
2582 outChars[j + 1] = base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
2583 outChars[j + 2] = base64[(inData[i + 1] & 0x0f) << 2];
2584 outChars[j + 3] = base64[64]; //Pad
2587 case 1: // Two character padding needed
2588 outChars[j] = base64[(inData[i] & 0xfc) >> 2];
2589 outChars[j + 1] = base64[(inData[i] & 0x03) << 4];
2590 outChars[j + 2] = base64[64]; //Pad
2591 outChars[j + 3] = base64[64]; //Pad
2600 private static int ToBase64_CalculateAndValidateOutputLength(int inputLength, bool insertLineBreaks)
2602 long outlen = ((long)inputLength) / 3 * 4; // the base length - we want integer division here.
2603 outlen += ((inputLength % 3) != 0) ? 4 : 0; // at most 4 more chars for the remainder
2608 if (insertLineBreaks)
2610 long newLines = outlen / base64LineBreakPosition;
2611 if ((outlen % base64LineBreakPosition) == 0)
2615 outlen += newLines * 2; // the number of line break chars we'll add, "\r\n"
2618 // If we overflow an int then we cannot allocate enough
2619 // memory to output the value so throw
2620 if (outlen > int.MaxValue)
2621 throw new OutOfMemoryException();
2628 /// Converts the specified string, which encodes binary data as Base64 digits, to the equivalent byte array.
2630 /// <param name="s">The string to convert</param>
2631 /// <returns>The array of bytes represented by the specified Base64 string.</returns>
2632 public static Byte[] FromBase64String(String s)
2634 // "s" is an unfortunate parameter name, but we need to keep it for backward compat.
2637 throw new ArgumentNullException(nameof(s));
2642 fixed (Char* sPtr = s)
2644 return FromBase64CharPtr(sPtr, s.Length);
2649 public static bool TryFromBase64String(string s, Span<byte> bytes, out int bytesWritten)
2653 throw new ArgumentNullException(nameof(s));
2656 return TryFromBase64Chars(s.AsSpan(), bytes, out bytesWritten);
2659 public static unsafe bool TryFromBase64Chars(ReadOnlySpan<char> chars, Span<byte> bytes, out int bytesWritten)
2661 if (chars.Length == 0)
2667 // We need to get rid of any trailing white spaces.
2668 // Otherwise we would be rejecting input such as "abc= ":
2669 while (chars.Length > 0)
2671 char lastChar = chars[chars.Length - 1];
2672 if (lastChar != ' ' && lastChar != '\n' && lastChar != '\r' && lastChar != '\t')
2676 chars = chars.Slice(0, chars.Length - 1);
2679 fixed (char* charsPtr = &MemoryMarshal.GetReference(chars))
2681 int resultLength = FromBase64_ComputeResultLength(charsPtr, chars.Length);
2682 Debug.Assert(resultLength >= 0);
2683 if (resultLength > bytes.Length)
2689 fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes))
2691 bytesWritten = FromBase64_Decode(charsPtr, chars.Length, bytesPtr, bytes.Length);
2698 /// Converts the specified range of a Char array, which encodes binary data as Base64 digits, to the equivalent byte array.
2700 /// <param name="inArray">Chars representing Base64 encoding characters</param>
2701 /// <param name="offset">A position within the input array.</param>
2702 /// <param name="length">Number of element to convert.</param>
2703 /// <returns>The array of bytes represented by the specified Base64 encoding characters.</returns>
2704 public static Byte[] FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length)
2706 if (inArray == null)
2707 throw new ArgumentNullException(nameof(inArray));
2710 throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index);
2713 throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_GenericPositive);
2715 if (offset > inArray.Length - length)
2716 throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_OffsetLength);
2719 if (inArray.Length == 0)
2721 return Array.Empty<byte>();
2726 fixed (Char* inArrayPtr = &inArray[0])
2728 return FromBase64CharPtr(inArrayPtr + offset, length);
2736 /// Convert Base64 encoding characters to bytes:
2737 /// - Compute result length exactly by actually walking the input;
2738 /// - Allocate new result array based on computation;
2739 /// - Decode input into the new array;
2741 /// <param name="inputPtr">Pointer to the first input char</param>
2742 /// <param name="inputLength">Number of input chars</param>
2743 /// <returns></returns>
2744 private static unsafe Byte[] FromBase64CharPtr(Char* inputPtr, Int32 inputLength)
2746 // The validity of parameters much be checked by callers, thus we are Critical here.
2748 Debug.Assert(0 <= inputLength);
2750 // We need to get rid of any trailing white spaces.
2751 // Otherwise we would be rejecting input such as "abc= ":
2752 while (inputLength > 0)
2754 Int32 lastChar = inputPtr[inputLength - 1];
2755 if (lastChar != (Int32)' ' && lastChar != (Int32)'\n' && lastChar != (Int32)'\r' && lastChar != (Int32)'\t')
2760 // Compute the output length:
2761 Int32 resultLength = FromBase64_ComputeResultLength(inputPtr, inputLength);
2763 Debug.Assert(0 <= resultLength);
2765 // resultLength can be zero. We will still enter FromBase64_Decode and process the input.
2766 // It may either simply write no bytes (e.g. input = " ") or throw (e.g. input = "ab").
2768 // Create result byte blob:
2769 Byte[] decodedBytes = new Byte[resultLength];
2771 // Convert Base64 chars into bytes:
2772 Int32 actualResultLength;
2773 fixed (Byte* decodedBytesPtr = decodedBytes)
2774 actualResultLength = FromBase64_Decode(inputPtr, inputLength, decodedBytesPtr, resultLength);
2776 // Note that actualResultLength can differ from resultLength if the caller is modifying the array
2777 // as it is being converted. Silently ignore the failure.
2778 // Consider throwing exception in an non in-place release.
2781 return decodedBytes;
2786 /// Decode characters representing a Base64 encoding into bytes:
2787 /// Walk the input. Every time 4 chars are read, convert them to the 3 corresponding output bytes.
2788 /// This method is a bit lengthy on purpose. We are trying to avoid jumps to helpers in the loop
2789 /// to aid performance.
2791 /// <param name="inputPtr">Pointer to first input char</param>
2792 /// <param name="inputLength">Number of input chars</param>
2793 /// <param name="destPtr">Pointer to location for the first result byte</param>
2794 /// <param name="destLength">Max length of the preallocated result buffer</param>
2795 /// <returns>If the result buffer was not large enough to write all result bytes, return -1;
2796 /// Otherwise return the number of result bytes actually produced.</returns>
2797 private static unsafe Int32 FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength)
2799 // You may find this method weird to look at. It's written for performance, not aesthetics.
2800 // You will find unrolled loops label jumps and bit manipulations.
2802 const UInt32 intA = (UInt32)'A';
2803 const UInt32 inta = (UInt32)'a';
2804 const UInt32 int0 = (UInt32)'0';
2805 const UInt32 intEq = (UInt32)'=';
2806 const UInt32 intPlus = (UInt32)'+';
2807 const UInt32 intSlash = (UInt32)'/';
2808 const UInt32 intSpace = (UInt32)' ';
2809 const UInt32 intTab = (UInt32)'\t';
2810 const UInt32 intNLn = (UInt32)'\n';
2811 const UInt32 intCRt = (UInt32)'\r';
2812 const UInt32 intAtoZ = (UInt32)('Z' - 'A'); // = ('z' - 'a')
2813 const UInt32 int0to9 = (UInt32)('9' - '0');
2815 Char* inputPtr = startInputPtr;
2816 Byte* destPtr = startDestPtr;
2818 // Pointers to the end of input and output:
2819 Char* endInputPtr = inputPtr + inputLength;
2820 Byte* endDestPtr = destPtr + destLength;
2822 // Current char code/value:
2825 // This 4-byte integer will contain the 4 codes of the current 4-char group.
2826 // Eeach char codes for 6 bits = 24 bits.
2827 // The remaining byte will be FF, we use it as a marker when 4 chars have been processed.
2828 UInt32 currBlockCodes = 0x000000FFu;
2835 if (inputPtr >= endInputPtr)
2836 goto _AllInputConsumed;
2838 // Get current char:
2839 currCode = (UInt32)(*inputPtr);
2842 // Determine current char code:
2844 if (currCode - intA <= intAtoZ)
2847 else if (currCode - inta <= intAtoZ)
2848 currCode -= (inta - 26u);
2850 else if (currCode - int0 <= int0to9)
2851 currCode -= (int0 - 52u);
2855 // Use the slower switch for less common cases:
2858 // Significant chars:
2867 // Legal no-value chars (we ignore these):
2874 // The equality char is only legal at the end of the input.
2875 // Jump after the loop to make it easier for the JIT register predictor to do a good job for the loop itself:
2877 goto _EqualityCharEncountered;
2879 // Other chars are illegal:
2881 throw new FormatException(SR.Format_BadBase64Char);
2885 // Ok, we got the code. Save it:
2886 currBlockCodes = (currBlockCodes << 6) | currCode;
2888 // Last bit in currBlockCodes will be on after in shifted right 4 times:
2889 if ((currBlockCodes & 0x80000000u) != 0u)
2891 if ((Int32)(endDestPtr - destPtr) < 3)
2894 *(destPtr) = (Byte)(currBlockCodes >> 16);
2895 *(destPtr + 1) = (Byte)(currBlockCodes >> 8);
2896 *(destPtr + 2) = (Byte)(currBlockCodes);
2899 currBlockCodes = 0x000000FFu;
2902 } // unchecked while
2904 // 'd be nice to have an assert that we never get here, but CS0162: Unreachable code detected.
2905 // Debug.Fail("We only leave the above loop by jumping; should never get here.");
2907 // We jump here out of the loop if we hit an '=':
2908 _EqualityCharEncountered:
2910 Debug.Assert(currCode == intEq);
2912 // Recall that inputPtr is now one position past where '=' was read.
2913 // '=' can only be at the last input pos:
2914 if (inputPtr == endInputPtr)
2916 // Code is zero for trailing '=':
2917 currBlockCodes <<= 6;
2919 // The '=' did not complete a 4-group. The input must be bad:
2920 if ((currBlockCodes & 0x80000000u) == 0u)
2921 throw new FormatException(SR.Format_BadBase64CharArrayLength);
2923 if ((int)(endDestPtr - destPtr) < 2) // Autch! We underestimated the output length!
2926 // We are good, store bytes form this past group. We had a single "=", so we take two bytes:
2927 *(destPtr++) = (Byte)(currBlockCodes >> 16);
2928 *(destPtr++) = (Byte)(currBlockCodes >> 8);
2930 currBlockCodes = 0x000000FFu;
2933 { // '=' can also be at the pre-last position iff the last is also a '=' excluding the white spaces:
2934 // We need to get rid of any intermediate white spaces.
2935 // Otherwise we would be rejecting input such as "abc= =":
2936 while (inputPtr < (endInputPtr - 1))
2938 Int32 lastChar = *(inputPtr);
2939 if (lastChar != (Int32)' ' && lastChar != (Int32)'\n' && lastChar != (Int32)'\r' && lastChar != (Int32)'\t')
2944 if (inputPtr == (endInputPtr - 1) && *(inputPtr) == '=')
2946 // Code is zero for each of the two '=':
2947 currBlockCodes <<= 12;
2949 // The '=' did not complete a 4-group. The input must be bad:
2950 if ((currBlockCodes & 0x80000000u) == 0u)
2951 throw new FormatException(SR.Format_BadBase64CharArrayLength);
2953 if ((Int32)(endDestPtr - destPtr) < 1) // Autch! We underestimated the output length!
2956 // We are good, store bytes form this past group. We had a "==", so we take only one byte:
2957 *(destPtr++) = (Byte)(currBlockCodes >> 16);
2959 currBlockCodes = 0x000000FFu;
2961 else // '=' is not ok at places other than the end:
2962 throw new FormatException(SR.Format_BadBase64Char);
2965 // We get here either from above or by jumping out of the loop:
2968 // The last block of chars has less than 4 items
2969 if (currBlockCodes != 0x000000FFu)
2970 throw new FormatException(SR.Format_BadBase64CharArrayLength);
2972 // Return how many bytes were actually recovered:
2973 return (Int32)(destPtr - startDestPtr);
2974 } // Int32 FromBase64_Decode(...)
2978 /// Compute the number of bytes encoded in the specified Base 64 char array:
2979 /// Walk the entire input counting white spaces and padding chars, then compute result length
2980 /// based on 3 bytes per 4 chars.
2982 private static unsafe Int32 FromBase64_ComputeResultLength(Char* inputPtr, Int32 inputLength)
2984 const UInt32 intEq = (UInt32)'=';
2985 const UInt32 intSpace = (UInt32)' ';
2987 Debug.Assert(0 <= inputLength);
2989 Char* inputEndPtr = inputPtr + inputLength;
2990 Int32 usefulInputLength = inputLength;
2993 while (inputPtr < inputEndPtr)
2995 UInt32 c = (UInt32)(*inputPtr);
2998 // We want to be as fast as possible and filter out spaces with as few comparisons as possible.
2999 // We end up accepting a number of illegal chars as legal white-space chars.
3000 // This is ok: as soon as we hit them during actual decode we will recognise them as illegal and throw.
3002 usefulInputLength--;
3004 else if (c == intEq)
3006 usefulInputLength--;
3011 Debug.Assert(0 <= usefulInputLength);
3013 // For legal input, we can assume that 0 <= padding < 3. But it may be more for illegal input.
3014 // We will notice it at decode when we see a '=' at the wrong place.
3015 Debug.Assert(0 <= padding);
3017 // Perf: reuse the variable that stored the number of '=' to store the number of bytes encoded by the
3018 // last group that contains the '=':
3023 else if (padding == 2)
3026 throw new FormatException(SR.Format_BadBase64Char);
3030 return (usefulInputLength / 4) * 3 + padding;