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]]];
*/
}