internal XmlQualifiedName RefineSimpleType()

in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/schema/Inference/infer.cs [1465:1761]


        internal XmlQualifiedName RefineSimpleType(string s, ref int iTypeFlags)
        {
            bool bNeedsRangeCheck = false;
            s = s.Trim();
            if (iTypeFlags == TF_string || _typeInference == InferenceOption.Relaxed)
                return ST_string;
            iTypeFlags &= InferSimpleType(s, ref bNeedsRangeCheck);
            if (iTypeFlags == TF_string)
                return ST_string;
            if (bNeedsRangeCheck)
            {
                if ((iTypeFlags & TF_byte) != 0)
                {
                    try
                    {
                        XmlConvert.ToSByte(s);
                        //sbyte.Parse(s);
                        if ((iTypeFlags & TF_unsignedByte) != 0)
                            return ST_unsignedByte; //number is positive and fits byte -> it also fits unsignedByte
                        else
                            return ST_byte;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_byte);
                }
                if ((iTypeFlags & TF_unsignedByte) != 0)
                {
                    try
                    {
                        XmlConvert.ToByte(s);
                        //byte.Parse(s);
                        return ST_unsignedByte;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_unsignedByte);
                }
                if ((iTypeFlags & TF_short) != 0)
                {
                    try
                    {
                        XmlConvert.ToInt16(s);
                        //short.Parse(s);
                        if ((iTypeFlags & TF_unsignedShort) != 0)
                            return ST_unsignedShort;    //number is positive and fits short -> it also fits unsignedShort
                        else
                            return ST_short;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_short);
                }
                if ((iTypeFlags & TF_unsignedShort) != 0)
                {
                    try
                    {
                        XmlConvert.ToUInt16(s);
                        //ushort.Parse(s);
                        return ST_unsignedShort;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_unsignedShort);
                }
                if ((iTypeFlags & TF_int) != 0)
                {
                    try
                    {
                        XmlConvert.ToInt32(s);
                        //int.Parse(s);
                        if ((iTypeFlags & TF_unsignedInt) != 0)
                            return ST_unsignedInt;  //number is positive and fits int -> it also fits unsignedInt
                        else
                            return ST_int;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_int);
                }
                if ((iTypeFlags & TF_unsignedInt) != 0)
                {
                    try
                    {
                        XmlConvert.ToUInt32(s);
                        //uint.Parse(s);
                        return ST_unsignedInt;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_unsignedInt);
                }
                if ((iTypeFlags & TF_long) != 0)
                {
                    try
                    {
                        XmlConvert.ToInt64(s);
                        //long.Parse(s);
                        if ((iTypeFlags & TF_unsignedLong) != 0)
                            return ST_unsignedLong; //number is positive and fits long -> it also fits unsignedLong
                        else
                            return ST_long;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_long);
                }
                if ((iTypeFlags & TF_unsignedLong) != 0)
                {
                    try
                    {
                        XmlConvert.ToUInt64(s);
                        //ulong.Parse(s);
                        return ST_unsignedLong;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_unsignedLong);
                }
                if ((iTypeFlags & TF_double) != 0)
                {
                    try
                    {
                        double dbValue = XmlConvert.ToDouble(s);
                        if ((iTypeFlags & TF_integer) != 0)
                            return ST_integer;
                        else if ((iTypeFlags & TF_decimal) != 0)
                            return ST_decimal;
                        else
                        {
                            // The value fits into double, but it could be float as well
                            if ((iTypeFlags & TF_float) != 0)
                            {
                                // We used to default to float in this case, so try to fit it into float first
                                try
                                {
                                    float flValue = XmlConvert.ToSingle(s);
                                    // Compare the float and double values. We can't do simple value comparison
                                    //   as conversion from float to double introduces imprecissions which cause problems.
                                    // Instead we will convert both back to string and compare the strings.
                                    if (string.Compare(XmlConvert.ToString(flValue), XmlConvert.ToString(dbValue),
                                        StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        // If we can convert the original string to the exact same value
                                        //   and it still fits into float then we treat it as float
                                        return ST_float;
                                    }
                                }
                                catch (FormatException)
                                { }
                                catch (OverflowException)
                                { }
                            }
                            iTypeFlags &= (~TF_float);
                            return ST_double;
                        }
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags &= (~TF_double);
                }
                if ((iTypeFlags & TF_float) != 0)
                {
                    try
                    {
                        XmlConvert.ToSingle(s);
                        if ((iTypeFlags & TF_integer) != 0)
                            return ST_integer;
                        else if ((iTypeFlags & TF_decimal) != 0)
                            return ST_decimal;
                        else
                            return ST_float;
                    }
                    catch (FormatException) { }
                    catch (OverflowException) { }
                    iTypeFlags &= (~TF_float);
                }
                if ((iTypeFlags & TF_integer) != 0)
                    return ST_integer;
                else if ((iTypeFlags & TF_decimal) != 0)
                    return ST_decimal;
                else if (iTypeFlags == (TF_gYearMonth | TF_string))
                {
                    try
                    {
                        XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.RoundtripKind);
                        return ST_gYearMonth;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags = TF_string;
                    return ST_string;
                }
                else if (iTypeFlags == (TF_duration | TF_string))
                {
                    try
                    {
                        XmlConvert.ToTimeSpan(s);
                        return ST_duration;
                    }
                    catch (FormatException)
                    { }
                    catch (OverflowException)
                    { }
                    iTypeFlags = TF_string;
                    return ST_string;
                }
                else if (iTypeFlags == (TF_boolean | TF_string))
                {
                    return ST_boolean;
                }
            }

            switch (iTypeFlags)
            {
                case TF_string:
                    return ST_string;
                case TF_boolean:
                    return ST_boolean;
                case TF_byte:
                    return ST_byte;
                case TF_unsignedByte:
                    return ST_unsignedByte;
                case TF_short:
                    return ST_short;
                case TF_unsignedShort:
                    return ST_unsignedShort;
                case TF_int:
                    return ST_int;
                case TF_unsignedInt:
                    return ST_unsignedInt;
                case TF_long:
                    return ST_long;
                case TF_unsignedLong:
                    return ST_unsignedLong;
                case TF_integer:
                    return ST_integer;
                case TF_decimal:
                    return ST_decimal;
                case TF_float:
                    return ST_float;
                case TF_double:
                    return ST_double;
                case TF_duration:
                    return ST_duration;
                case TF_dateTime:
                    return ST_dateTime;
                case TF_time:
                    return ST_time;
                case TF_date:
                    return ST_date;
                case TF_gYearMonth:
                    return ST_gYearMonth;

                case TF_boolean | TF_string:
                    return ST_boolean;
                case TF_dateTime | TF_string:
                    return ST_dateTime;
                case TF_date | TF_string:
                    return ST_date;
                case TF_time | TF_string:
                    return ST_time;
                case TF_float | TF_double | TF_string:
                    return ST_float;
                case TF_double | TF_string:
                    return ST_double;

                default:
                    Debug.Assert(false, "Expected type not matched");
                    return ST_string;
            }
            /*          if (currentType == null)
                            return SimpleTypes[newType];
                        else
                            return SimpleTypes[ST_Map[newType,(short) ST_Codes[currentType]]];
                            */
        }