in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/schema/XsdDuration.cs [499:680]
internal static Exception TryParse(string s, DurationType durationType, out XsdDuration result)
{
string errorCode;
int length;
int value, pos, numDigits;
Parts parts = Parts.HasNone;
result = new XsdDuration();
s = s.Trim();
length = s.Length;
pos = 0;
numDigits = 0;
if (pos >= length) goto InvalidFormat;
if (s[pos] == '-')
{
pos++;
result._nanoseconds = NegativeBit;
}
else
{
result._nanoseconds = 0;
}
if (pos >= length) goto InvalidFormat;
if (s[pos++] != 'P') goto InvalidFormat;
errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
if (errorCode != null) goto Error;
if (pos >= length) goto InvalidFormat;
if (s[pos] == 'Y')
{
if (numDigits == 0) goto InvalidFormat;
parts |= Parts.HasYears;
result._years = value;
if (++pos == length) goto Done;
errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
if (errorCode != null) goto Error;
if (pos >= length) goto InvalidFormat;
}
if (s[pos] == 'M')
{
if (numDigits == 0) goto InvalidFormat;
parts |= Parts.HasMonths;
result._months = value;
if (++pos == length) goto Done;
errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
if (errorCode != null) goto Error;
if (pos >= length) goto InvalidFormat;
}
if (s[pos] == 'D')
{
if (numDigits == 0) goto InvalidFormat;
parts |= Parts.HasDays;
result._days = value;
if (++pos == length) goto Done;
errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
if (errorCode != null) goto Error;
if (pos >= length) goto InvalidFormat;
}
if (s[pos] == 'T')
{
if (numDigits != 0) goto InvalidFormat;
pos++;
errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
if (errorCode != null) goto Error;
if (pos >= length) goto InvalidFormat;
if (s[pos] == 'H')
{
if (numDigits == 0) goto InvalidFormat;
parts |= Parts.HasHours;
result._hours = value;
if (++pos == length) goto Done;
errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
if (errorCode != null) goto Error;
if (pos >= length) goto InvalidFormat;
}
if (s[pos] == 'M')
{
if (numDigits == 0) goto InvalidFormat;
parts |= Parts.HasMinutes;
result._minutes = value;
if (++pos == length) goto Done;
errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
if (errorCode != null) goto Error;
if (pos >= length) goto InvalidFormat;
}
if (s[pos] == '.')
{
pos++;
parts |= Parts.HasSeconds;
result._seconds = value;
errorCode = TryParseDigits(s, ref pos, true, out value, out numDigits);
if (errorCode != null) goto Error;
if (numDigits == 0)
{ //If there are no digits after the decimal point, assume 0
value = 0;
}
// Normalize to nanosecond intervals
for (; numDigits > 9; numDigits--)
value /= 10;
for (; numDigits < 9; numDigits++)
value *= 10;
result._nanoseconds |= (uint)value;
if (pos >= length) goto InvalidFormat;
if (s[pos] != 'S') goto InvalidFormat;
if (++pos == length) goto Done;
}
else if (s[pos] == 'S')
{
if (numDigits == 0) goto InvalidFormat;
parts |= Parts.HasSeconds;
result._seconds = value;
if (++pos == length) goto Done;
}
}
// Duration cannot end with digits
if (numDigits != 0) goto InvalidFormat;
// No further characters are allowed
if (pos != length) goto InvalidFormat;
Done:
// At least one part must be defined
if (parts == Parts.HasNone) goto InvalidFormat;
if (durationType == DurationType.DayTimeDuration)
{
if ((parts & (Parts.HasYears | Parts.HasMonths)) != 0)
goto InvalidFormat;
}
else if (durationType == DurationType.YearMonthDuration)
{
if ((parts & ~(XsdDuration.Parts.HasYears | XsdDuration.Parts.HasMonths)) != 0)
goto InvalidFormat;
}
return null;
InvalidFormat:
return new FormatException(string.Format(ResXml.XmlConvert_BadFormat, s, durationType));
Error:
return new OverflowException(string.Format(ResXml.XmlConvert_Overflow, s, durationType));
}