public static SqlDecimal Parse(string s)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
if (s == SQLResource.s_nullString)
return SqlDecimal.Null;
SqlDecimal snResult = SqlDecimal.Null;
char[] rgwchStr = s.ToCharArray();
int cwchStr = rgwchStr.Length;
int iData; //index to string
char usChar; //current value in string
int lDecPnt = -1; //position of decimal point in string
int iCurChar = 0;
//Must initialize precision and scale to valid values
snResult._bPrec = 1;
snResult._bScale = 0;
//Must initialize *this to zero
snResult.SetToZero();
// Trim trailing blanks.
while (cwchStr != 0 && rgwchStr[cwchStr - 1] == ' ')
cwchStr--;
// If string contains only spaces, stop
if (cwchStr == 0)
throw new FormatException(SQLResource.s_formatMessage);
// Trim leading blanks.
while (rgwchStr[iCurChar] == ' ')
{
iCurChar++;
cwchStr--;
}
// Get sign for numeric value.
if (rgwchStr[iCurChar] == '-')
{
snResult.SetSignBit(false);
iCurChar++;
cwchStr--;
}
else
{
snResult.SetSignBit(true);
if (rgwchStr[iCurChar] == '+')
{
iCurChar++;
cwchStr--;
}
}
// Hack: Check for "0.". If so, replace by ".0".
while ((cwchStr > 2) && (rgwchStr[iCurChar] == '0'))
{
iCurChar++;
cwchStr--;
}
if (2 == cwchStr && '0' == rgwchStr[iCurChar] && '.' == rgwchStr[iCurChar + 1])
{
rgwchStr[iCurChar] = '.';
rgwchStr[iCurChar + 1] = '0';
}
// Invalid string?
if (cwchStr == 0 || cwchStr > s_NUMERIC_MAX_PRECISION + 1)
throw new FormatException(SQLResource.s_formatMessage);
// Trim leading zeros. (There shouldn't be any except for floats
// less than 1. e.g. 0.01)
while ((cwchStr > 1) && (rgwchStr[iCurChar] == '0'))
{
iCurChar++;
cwchStr--;
}
// Convert string to numeric value by looping through input string.
for (iData = 0; iData < cwchStr; iData++)
{
usChar = rgwchStr[iCurChar];
iCurChar++;
if (usChar >= '0' && usChar <= '9')
usChar -= '0';
else if (usChar == '.' && lDecPnt < 0)
{
lDecPnt = iData;
continue;
}
else
throw new FormatException(SQLResource.s_formatMessage);
snResult.MultByULong(s_ulBase10);
snResult.AddULong(usChar);
}
// Save precision and scale.
if (lDecPnt < 0)
{
snResult._bPrec = (byte)iData;
snResult._bScale = 0;
}
else
{
snResult._bPrec = (byte)(iData - 1);
snResult._bScale = (byte)(snResult._bPrec - lDecPnt);
}
//Check for overflow condition
if (snResult._bPrec > s_NUMERIC_MAX_PRECISION)
throw new FormatException(SQLResource.s_formatMessage);
// Check for invalid precision for numeric value.
// e.g., when string is ".", precision will be 0
if (snResult._bPrec == 0)
throw new FormatException(SQLResource.s_formatMessage);
// If result is -0, adjust sign to positive.
if (snResult.FZero())
snResult.SetPositive();
snResult.AssertValid();
return snResult;
}