private static unsafe void FormatFixed(StringBuilder sb, NumberBuffer number, int nMinDigits, int nMaxDigits, NumberFormatInfo info, int[] groupDigits, string sDecimal, string sGroup)
{
int digPos = number.scale;
char* dig = number.digits;
int digLength = wcslen(dig);
if (digPos > 0)
{
if (groupDigits != null)
{
int groupSizeIndex = 0; // Index into the groupDigits array.
int groupSizeCount = groupDigits[groupSizeIndex]; // The current total of group size.
int groupSizeLen = groupDigits.Length; // The length of groupDigits array.
int bufferSize = digPos; // The length of the result buffer string.
int groupSeparatorLen = sGroup.Length; // The length of the group separator string.
int groupSize = 0; // The current group size.
// Find out the size of the string buffer for the result.
if (groupSizeLen != 0) // You can pass in 0 length arrays
{
while (digPos > groupSizeCount)
{
groupSize = groupDigits[groupSizeIndex];
if (groupSize == 0)
break;
bufferSize += groupSeparatorLen;
if (groupSizeIndex < groupSizeLen - 1)
groupSizeIndex++;
groupSizeCount += groupDigits[groupSizeIndex];
if (groupSizeCount < 0 || bufferSize < 0)
throw new ArgumentOutOfRangeException(); // If we overflow
}
if (groupSizeCount == 0) // If you passed in an array with one entry as 0, groupSizeCount == 0
groupSize = 0;
else
groupSize = groupDigits[0];
}
char* tmpBuffer = stackalloc char[bufferSize];
groupSizeIndex = 0;
int digitCount = 0;
int digStart;
digStart = (digPos < digLength) ? digPos : digLength;
char* p = tmpBuffer + bufferSize - 1;
for (int i = digPos - 1; i >= 0; i--)
{
*(p--) = (i < digStart) ? dig[i] : '0';
if (groupSize > 0)
{
digitCount++;
if ((digitCount == groupSize) && (i != 0))
{
for (int j = groupSeparatorLen - 1; j >= 0; j--)
*(p--) = sGroup[j];
if (groupSizeIndex < groupSizeLen - 1)
{
groupSizeIndex++;
groupSize = groupDigits[groupSizeIndex];
}
digitCount = 0;
}
}
}
sb.Append(tmpBuffer, bufferSize);
dig += digStart;
}
else
{
int digits = Math.Min(digLength, digPos);
sb.Append(dig, digits);
dig += digits;
if (digPos > digLength)
sb.Append('0', digPos - digLength);
}
}
else
{
sb.Append('0');
}
if (nMaxDigits > 0)
{
sb.Append(sDecimal);
if ((digPos < 0) && (nMaxDigits > 0))
{
int zeroes = Math.Min(-digPos, nMaxDigits);
sb.Append('0', zeroes);
digPos += zeroes;
nMaxDigits -= zeroes;
}
while (nMaxDigits > 0)
{
sb.Append((*dig != 0) ? *dig++ : '0');
nMaxDigits--;
}
}
}