private void ParseArrayMember(ParseRecord pr)
{
ParseRecord objectPr = (ParseRecord)_stack.Peek();
// Set up for inserting value into correct array position
if (objectPr._arrayTypeEnum == InternalArrayTypeE.Rectangular)
{
if (objectPr._memberIndex > 0)
{
NextRectangleMap(objectPr); // Rectangle array, calculate position in array
}
if (objectPr._isLowerBound)
{
for (int i = 0; i < objectPr._rank; i++)
{
objectPr._indexMap[i] = objectPr._rectangularMap[i] + objectPr._lowerBoundA[i];
}
}
}
else
{
objectPr._indexMap[0] = !objectPr._isLowerBound ?
objectPr._memberIndex : // Zero based array
objectPr._lowerBoundA[0] + objectPr._memberIndex; // Lower Bound based array
}
// Set Array element according to type of element
if (pr._memberValueEnum == InternalMemberValueE.Reference)
{
// Object Reference
// See if object has already been instantiated
object refObj = _objectManager.GetObject(pr._idRef);
if (refObj == null)
{
// Object not instantiated
// Array fixup manager
int[] fixupIndex = new int[objectPr._rank];
Array.Copy(objectPr._indexMap, 0, fixupIndex, 0, objectPr._rank);
_objectManager.RecordArrayElementFixup(objectPr._objectId, fixupIndex, pr._idRef);
}
else
{
if (objectPr._objectA != null)
{
objectPr._objectA[objectPr._indexMap[0]] = refObj;
}
else
{
((Array)objectPr._newObj).SetValue(refObj, objectPr._indexMap); // Object has been instantiated
}
}
}
else if (pr._memberValueEnum == InternalMemberValueE.Nested)
{
//Set up dtType for ParseObject
if (pr._dtType == null)
{
pr._dtType = objectPr._arrayElementType;
}
ParseObject(pr);
_stack.Push(pr);
if (objectPr._arrayElementType != null)
{
if ((objectPr._arrayElementType.IsValueType) && (pr._arrayElementTypeCode == InternalPrimitiveTypeE.Invalid))
{
pr._isValueTypeFixup = true; //Valuefixup
ValueFixupStack.Push(new ValueFixup((Array)objectPr._newObj, objectPr._indexMap)); //valuefixup
}
else
{
if (objectPr._objectA != null)
{
objectPr._objectA[objectPr._indexMap[0]] = pr._newObj;
}
else
{
((Array)objectPr._newObj).SetValue(pr._newObj, objectPr._indexMap);
}
}
}
}
else if (pr._memberValueEnum == InternalMemberValueE.InlineValue)
{
if ((ReferenceEquals(objectPr._arrayElementType, Converter.s_typeofString)) || (ReferenceEquals(pr._dtType, Converter.s_typeofString)))
{
// String in either a string array, or a string element of an object array
ParseString(pr, objectPr);
if (objectPr._objectA != null)
{
objectPr._objectA[objectPr._indexMap[0]] = pr._value;
}
else
{
((Array)objectPr._newObj).SetValue(pr._value, objectPr._indexMap);
}
}
else if (objectPr._isArrayVariant)
{
// Array of type object
if (pr._keyDt == null)
{
throw new SerializationException(SR.Serialization_ArrayTypeObject);
}
object var = null;
if (ReferenceEquals(pr._dtType, Converter.s_typeofString))
{
ParseString(pr, objectPr);
var = pr._value;
}
else if (ReferenceEquals(pr._dtTypeCode, InternalPrimitiveTypeE.Invalid))
{
CheckSerializable(pr._dtType);
// Not nested and invalid, so it is an empty object
var = FormatterServices.GetUninitializedObject(pr._dtType);
}
else
{
var = pr._varValue != null ?
pr._varValue :
Converter.FromString(pr._value, pr._dtTypeCode);
}
if (objectPr._objectA != null)
{
objectPr._objectA[objectPr._indexMap[0]] = var;
}
else
{
((Array)objectPr._newObj).SetValue(var, objectPr._indexMap); // Primitive type
}
}
else
{
// Primitive type
if (objectPr._primitiveArray != null)
{
// Fast path for Soap primitive arrays. Binary was handled in the BinaryParser
objectPr._primitiveArray.SetValue(pr._value, objectPr._indexMap[0]);
}
else
{
object var = pr._varValue != null ?
pr._varValue :
Converter.FromString(pr._value, objectPr._arrayElementTypeCode);
if (objectPr._objectA != null)
{
objectPr._objectA[objectPr._indexMap[0]] = var;
}
else
{
((Array)objectPr._newObj).SetValue(var, objectPr._indexMap); // Primitive type
}
}
}
}
else if (pr._memberValueEnum == InternalMemberValueE.Null)
{
objectPr._memberIndex += pr._consecutiveNullArrayEntryCount - 1; //also incremented again below
}
else
{
ParseError(pr, objectPr);
}
objectPr._memberIndex++;
}