internal static Type FormCompoundType(char[] bFormat, Type baseType, int curIndex)
{
// This function takes a string to describe the compound type, such as "[,][]", and a baseType.
//
// Example: [2..4] - one dimension array with lower bound 2 and size of 3
// Example: [3, 5, 6] - three dimension array with lower bound 3, 5, 6
// Example: [-3, ] [] - one dimensional array of two dimensional array (with lower bound -3 for
// the first dimension)
// Example: []* - pointer to a one dimensional array
// Example: *[] - one dimensional array. The element type is a pointer to the baseType
// Example: []& - ByRef of a single dimensional array. Only one & is allowed and it must appear the last!
// Example: [?] - Array with unknown bound
SymbolType symbolType;
int iLowerBound;
int iUpperBound;
if (bFormat == null || curIndex == bFormat.Length)
{
// we have consumed all of the format string
return baseType;
}
if (bFormat[curIndex] == '&')
{
// ByRef case
symbolType = new SymbolType(TypeKind.IsByRef);
symbolType.SetFormat(bFormat, curIndex, 1);
curIndex++;
if (curIndex != bFormat.Length)
// ByRef has to be the last char!!
throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
symbolType.SetElementType(baseType);
return symbolType;
}
if (bFormat[curIndex] == '[')
{
// Array type.
symbolType = new SymbolType(TypeKind.IsArray);
int startIndex = curIndex;
curIndex++;
iLowerBound = 0;
iUpperBound = -1;
// Example: [2..4] - one dimension array with lower bound 2 and size of 3
// Example: [3, 5, 6] - three dimension array with lower bound 3, 5, 6
// Example: [-3, ] [] - one dimensional array of two dimensional array (with lower bound -3 sepcified)
while (bFormat[curIndex] != ']')
{
if (bFormat[curIndex] == '*')
{
symbolType.m_isSzArray = false;
curIndex++;
}
// consume, one dimension at a time
if ((bFormat[curIndex] >= '0' && bFormat[curIndex] <= '9') || bFormat[curIndex] == '-')
{
bool isNegative = false;
if (bFormat[curIndex] == '-')
{
isNegative = true;
curIndex++;
}
// lower bound is specified. Consume the low bound
while (bFormat[curIndex] >= '0' && bFormat[curIndex] <= '9')
{
iLowerBound = iLowerBound * 10;
iLowerBound += bFormat[curIndex] - '0';
curIndex++;
}
if (isNegative)
{
iLowerBound = 0 - iLowerBound;
}
// set the upper bound to be less than LowerBound to indicate that upper bound it not specified yet!
iUpperBound = iLowerBound - 1;
}
if (bFormat[curIndex] == '.')
{
// upper bound is specified
// skip over ".."
curIndex++;
if (bFormat[curIndex] != '.')
{
// bad format!! Throw exception
throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
}
curIndex++;
// consume the upper bound
if ((bFormat[curIndex] >= '0' && bFormat[curIndex] <= '9') || bFormat[curIndex] == '-')
{
bool isNegative = false;
iUpperBound = 0;
if (bFormat[curIndex] == '-')
{
isNegative = true;
curIndex++;
}
// lower bound is specified. Consume the low bound
while (bFormat[curIndex] >= '0' && bFormat[curIndex] <= '9')
{
iUpperBound = iUpperBound * 10;
iUpperBound += bFormat[curIndex] - '0';
curIndex++;
}
if (isNegative)
{
iUpperBound = 0 - iUpperBound;
}
if (iUpperBound < iLowerBound)
{
// User specified upper bound less than lower bound, this is an error.
// Throw error exception.
throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
}
}
}
if (bFormat[curIndex] == ',')
{
// We have more dimension to deal with.
// now set the lower bound, the size, and increase the dimension count!
curIndex++;
symbolType.SetBounds(iLowerBound, iUpperBound);
// clear the lower and upper bound information for next dimension
iLowerBound = 0;
iUpperBound = -1;
}
else if (bFormat[curIndex] != ']')
{
throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
}
}
// The last dimension information
symbolType.SetBounds(iLowerBound, iUpperBound);
// skip over ']'
curIndex++;
symbolType.SetFormat(bFormat, startIndex, curIndex - startIndex);
// set the base type of array
symbolType.SetElementType(baseType);
return FormCompoundType(bFormat, symbolType, curIndex);
}
else if (bFormat[curIndex] == '*')
{
// pointer type.
symbolType = new SymbolType(TypeKind.IsPointer);
symbolType.SetFormat(bFormat, curIndex, 1);
curIndex++;
symbolType.SetElementType(baseType);
return FormCompoundType(bFormat, symbolType, curIndex);
}
return null;
}