//
using System.Globalization;
+using System.Threading;
namespace System {
[CLSCompliant(false)]
+ [Serializable]
public struct UInt32 : IComparable, IFormattable, IConvertible {
public const uint MaxValue = 0xffffffff;
public const uint MinValue = 0;
- public uint value;
+ internal uint value;
public int CompareTo (object v)
{
int len;
int i;
bool digits_seen = false;
+ bool has_negative_sign = false;
if (s == null)
throw new ArgumentNullException (Locale.GetText ("s is null"));
if (s [i] == '+')
i++;
+ else
+ if (s[i] == '-'){
+ i++;
+ has_negative_sign = true;
+ }
for (; i < len; i++){
c = s [i];
if (!digits_seen)
throw new FormatException ();
- return val;
+ if (has_negative_sign)
+ throw new OverflowException ();
+ return val;
}
[CLSCompliant(false)]
return Parse (s, style, null);
}
- [MonoTODO]
+ [CLSCompliant(false)]
public static uint Parse (string s, NumberStyles style, IFormatProvider fp)
{
- // TODO: Implement me
- throw new NotImplementedException ();
+ if (s == null)
+ throw new ArgumentNullException ();
+
+ if (s.Length == 0)
+ throw new FormatException ("Input string was not in the correct format.");
+
+ NumberFormatInfo nfi;
+ if (fp != null) {
+ Type typeNFI = typeof (System.Globalization.NumberFormatInfo);
+ nfi = (NumberFormatInfo) fp.GetFormat (typeNFI);
+ }
+ else
+ nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
+
+ Int32.CheckStyle (style);
+
+ bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
+ bool AllowExponent = (style & NumberStyles.AllowExponent) != 0;
+ bool AllowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0;
+ bool AllowThousands = (style & NumberStyles.AllowThousands) != 0;
+ bool AllowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0;
+ bool AllowParentheses = (style & NumberStyles.AllowParentheses) != 0;
+ bool AllowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0;
+ bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0;
+ bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0;
+ bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0;
+
+ int pos = 0;
+
+ if (AllowLeadingWhite)
+ pos = Int32.JumpOverWhite (pos, s, true);
+
+ bool foundOpenParentheses = false;
+ bool negative = false;
+ bool foundSign = false;
+ bool foundCurrency = false;
+
+ // Pre-number stuff
+ if (AllowParentheses && s [pos] == '(') {
+ foundOpenParentheses = true;
+ foundSign = true;
+ negative = true; // MS always make the number negative when there parentheses
+ // even when NumberFormatInfo.NumberNegativePattern != 0!!!
+ pos++;
+ if (AllowLeadingWhite)
+ pos = Int32.JumpOverWhite (pos, s, true);
+
+ if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
+ throw new FormatException ("Input string was not in the correct format.");
+ if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
+ throw new FormatException ("Input string was not in the correct format.");
+ }
+
+ if (AllowLeadingSign && !foundSign) {
+ // Sign + Currency
+ Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
+ if (foundSign) {
+ if (AllowLeadingWhite)
+ pos = Int32.JumpOverWhite (pos, s, true);
+ if (AllowCurrencySymbol) {
+ Int32.FindCurrency (ref pos, s, nfi,
+ ref foundCurrency);
+ if (foundCurrency && AllowLeadingWhite)
+ pos = Int32.JumpOverWhite (pos, s, true);
+ }
+ }
+ }
+
+ if (AllowCurrencySymbol && !foundCurrency) {
+ // Currency + sign
+ Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
+ if (foundCurrency) {
+ if (AllowLeadingWhite)
+ pos = Int32.JumpOverWhite (pos, s, true);
+ if (foundCurrency) {
+ if (!foundSign && AllowLeadingSign) {
+ Int32.FindSign (ref pos, s, nfi, ref foundSign,
+ ref negative);
+ if (foundSign && AllowLeadingWhite)
+ pos = Int32.JumpOverWhite (pos, s, true);
+ }
+ }
+ }
+ }
+
+ uint number = 0;
+ int nDigits = 0;
+ bool decimalPointFound = false;
+ uint digitValue;
+ char hexDigit;
+
+ // Number stuff
+ // Just the same as Int32, but this one adds instead of substract
+ do {
+
+ if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
+ if (AllowThousands &&
+ Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator))
+ continue;
+ else
+ if (!decimalPointFound && AllowDecimalPoint &&
+ Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
+ decimalPointFound = true;
+ continue;
+ }
+
+ break;
+ }
+ else if (AllowHexSpecifier) {
+ nDigits++;
+ hexDigit = s [pos++];
+ if (Char.IsDigit (hexDigit))
+ digitValue = (uint) (hexDigit - '0');
+ else if (Char.IsLower (hexDigit))
+ digitValue = (uint) (hexDigit - 'a' + 10);
+ else
+ digitValue = (uint) (hexDigit - 'A' + 10);
+
+ number = checked (number * 16 + digitValue);
+ }
+ else if (decimalPointFound) {
+ nDigits++;
+ // Allows decimal point as long as it's only
+ // followed by zeroes.
+ if (s [pos++] != '0')
+ throw new OverflowException ("Value too large or too small.");
+ }
+ else {
+ nDigits++;
+
+ try {
+ number = checked (
+ number * 10 +
+ (uint) (s [pos++] - '0')
+ );
+ } catch (OverflowException) {
+ throw new OverflowException ("Value too large or too small.");
+ }
+ }
+ } while (pos < s.Length);
+
+ // Post number stuff
+ if (nDigits == 0)
+ throw new FormatException ("Input string was not in the correct format.");
+
+ if (AllowTrailingSign && !foundSign) {
+ // Sign + Currency
+ Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
+ if (foundSign) {
+ if (AllowTrailingWhite)
+ pos = Int32.JumpOverWhite (pos, s, true);
+ if (AllowCurrencySymbol)
+ Int32. FindCurrency (ref pos, s, nfi,
+ ref foundCurrency);
+ }
+ }
+
+ if (AllowCurrencySymbol && !foundCurrency) {
+ // Currency + sign
+ Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
+ if (foundCurrency) {
+ if (AllowTrailingWhite)
+ pos = Int32.JumpOverWhite (pos, s, true);
+ if (!foundSign && AllowTrailingSign)
+ Int32.FindSign (ref pos, s, nfi, ref foundSign,
+ ref negative);
+ }
+ }
+
+ if (AllowTrailingWhite && pos < s.Length)
+ pos = Int32.JumpOverWhite (pos, s, false);
+
+ if (foundOpenParentheses) {
+ if (pos >= s.Length || s [pos++] != ')')
+ throw new FormatException ("Input string was not in the correct " +
+ "format.");
+ if (AllowTrailingWhite && pos < s.Length)
+ pos = Int32.JumpOverWhite (pos, s, false);
+ }
+
+ if (pos < s.Length && s [pos] != '\u0000')
+ throw new FormatException ("Input string was not in the correct format.");
+
+ if (negative)
+ throw new OverflowException ( "Value too large or too small.");
+
+ return number;
}
public override string ToString ()
return TypeCode.UInt32;
}
- public bool ToBoolean (IFormatProvider provider)
+ bool IConvertible.ToBoolean (IFormatProvider provider)
{
return System.Convert.ToBoolean (value);
}
- public byte ToByte (IFormatProvider provider)
+ byte IConvertible.ToByte (IFormatProvider provider)
{
return System.Convert.ToByte (value);
}
- public char ToChar (IFormatProvider provider)
+ char IConvertible.ToChar (IFormatProvider provider)
{
return System.Convert.ToChar (value);
}
- public DateTime ToDateTime (IFormatProvider provider)
+ DateTime IConvertible.ToDateTime (IFormatProvider provider)
{
return System.Convert.ToDateTime (value);
}
- public decimal ToDecimal (IFormatProvider provider)
+ decimal IConvertible.ToDecimal (IFormatProvider provider)
{
return System.Convert.ToDecimal (value);
}
- public double ToDouble (IFormatProvider provider)
+ double IConvertible.ToDouble (IFormatProvider provider)
{
return System.Convert.ToDouble (value);
}
- public short ToInt16 (IFormatProvider provider)
+ short IConvertible.ToInt16 (IFormatProvider provider)
{
return System.Convert.ToInt16 (value);
}
- public int ToInt32 (IFormatProvider provider)
+ int IConvertible.ToInt32 (IFormatProvider provider)
{
return System.Convert.ToInt32 (value);
}
- public long ToInt64 (IFormatProvider provider)
+ long IConvertible.ToInt64 (IFormatProvider provider)
{
return System.Convert.ToInt64 (value);
}
[CLSCompliant (false)]
- public sbyte ToSByte (IFormatProvider provider)
+ sbyte IConvertible.ToSByte (IFormatProvider provider)
{
return System.Convert.ToSByte (value);
}
- public float ToSingle (IFormatProvider provider)
+ float IConvertible.ToSingle (IFormatProvider provider)
{
return System.Convert.ToSingle (value);
}
- public object ToType (Type conversionType, IFormatProvider provider)
+ object IConvertible.ToType (Type conversionType, IFormatProvider provider)
{
return System.Convert.ToType (value, conversionType, provider);
}
[CLSCompliant (false)]
- public ushort ToUInt16 (IFormatProvider provider)
+ ushort IConvertible.ToUInt16 (IFormatProvider provider)
{
return System.Convert.ToUInt16 (value);
}
[CLSCompliant (false)]
- public uint ToUInt32 (IFormatProvider provider)
+ uint IConvertible.ToUInt32 (IFormatProvider provider)
{
return System.Convert.ToUInt32 (value);
}
[CLSCompliant (false)]
- public ulong ToUInt64 (IFormatProvider provider)
+ ulong IConvertible.ToUInt64 (IFormatProvider provider)
{
return System.Convert.ToUInt64 (value);
}