private void WriteArray(WriteObjectInfo objectInfo, NameInfo memberNameInfo, WriteObjectInfo memberObjectInfo)
{
bool isAllocatedMemberNameInfo = false;
if (memberNameInfo == null)
{
memberNameInfo = TypeToNameInfo(objectInfo);
isAllocatedMemberNameInfo = true;
}
memberNameInfo._isArray = true;
long objectId = objectInfo._objectId;
memberNameInfo._objectId = objectInfo._objectId;
// Get array type
Array array = (Array)objectInfo._obj;
//Type arrayType = array.GetType();
Type arrayType = objectInfo._objectType;
// Get type of array element
Type arrayElemType = arrayType.GetElementType();
WriteObjectInfo arrayElemObjectInfo = null;
if (!arrayElemType.IsPrimitive)
{
arrayElemObjectInfo = WriteObjectInfo.Serialize(arrayElemType, _surrogates, _context, _serObjectInfoInit, _formatterConverter, _binder);
arrayElemObjectInfo._assemId = GetAssemblyId(arrayElemObjectInfo);
}
NameInfo arrayElemTypeNameInfo = arrayElemObjectInfo == null ?
TypeToNameInfo(arrayElemType) :
TypeToNameInfo(arrayElemObjectInfo);
arrayElemTypeNameInfo._isArray = arrayElemTypeNameInfo._type.IsArray;
NameInfo arrayNameInfo = memberNameInfo;
arrayNameInfo._objectId = objectId;
arrayNameInfo._isArray = true;
arrayElemTypeNameInfo._objectId = objectId;
arrayElemTypeNameInfo._transmitTypeOnMember = memberNameInfo._transmitTypeOnMember;
arrayElemTypeNameInfo._transmitTypeOnObject = memberNameInfo._transmitTypeOnObject;
arrayElemTypeNameInfo._isParentTypeOnObject = memberNameInfo._isParentTypeOnObject;
// Get rank and length information
int rank = array.Rank;
int[] lengthA = new int[rank];
int[] lowerBoundA = new int[rank];
int[] upperBoundA = new int[rank];
for (int i = 0; i < rank; i++)
{
lengthA[i] = array.GetLength(i);
lowerBoundA[i] = array.GetLowerBound(i);
upperBoundA[i] = array.GetUpperBound(i);
}
InternalArrayTypeE arrayEnum;
if (arrayElemTypeNameInfo._isArray)
{
arrayEnum = rank == 1 ? InternalArrayTypeE.Jagged : InternalArrayTypeE.Rectangular;
}
else if (rank == 1)
{
arrayEnum = InternalArrayTypeE.Single;
}
else
{
arrayEnum = InternalArrayTypeE.Rectangular;
}
arrayElemTypeNameInfo._arrayEnum = arrayEnum;
// Byte array
if ((ReferenceEquals(arrayElemType, Converter.s_typeofByte)) && (rank == 1) && (lowerBoundA[0] == 0))
{
_serWriter.WriteObjectByteArray(memberNameInfo, arrayNameInfo, arrayElemObjectInfo, arrayElemTypeNameInfo, lengthA[0], lowerBoundA[0], (byte[])array);
return;
}
if (ReferenceEquals(arrayElemType, Converter.s_typeofObject) || Nullable.GetUnderlyingType(arrayElemType) != null)
{
memberNameInfo._transmitTypeOnMember = true;
arrayElemTypeNameInfo._transmitTypeOnMember = true;
}
if (CheckTypeFormat(_formatterEnums._typeFormat, FormatterTypeStyle.TypesAlways))
{
memberNameInfo._transmitTypeOnObject = true;
arrayElemTypeNameInfo._transmitTypeOnObject = true;
}
if (arrayEnum == InternalArrayTypeE.Single)
{
// Single Dimensional array
// BinaryFormatter array of primitive types is written out in the WriteSingleArray statement
// as a byte buffer
_serWriter.WriteSingleArray(memberNameInfo, arrayNameInfo, arrayElemObjectInfo, arrayElemTypeNameInfo, lengthA[0], lowerBoundA[0], array);
if (!(Converter.IsWriteAsByteArray(arrayElemTypeNameInfo._primitiveTypeEnum) && (lowerBoundA[0] == 0)))
{
object[] objectA = null;
if (!arrayElemType.IsValueType)
{
// Non-primitive type array
objectA = (object[])array;
}
int upperBound = upperBoundA[0] + 1;
for (int i = lowerBoundA[0]; i < upperBound; i++)
{
if (objectA == null)
{
WriteArrayMember(objectInfo, arrayElemTypeNameInfo, array.GetValue(i));
}
else
{
WriteArrayMember(objectInfo, arrayElemTypeNameInfo, objectA[i]);
}
}
_serWriter.WriteItemEnd();
}
}
else if (arrayEnum == InternalArrayTypeE.Jagged)
{
// Jagged Array
arrayNameInfo._objectId = objectId;
_serWriter.WriteJaggedArray(memberNameInfo, arrayNameInfo, arrayElemObjectInfo, arrayElemTypeNameInfo, lengthA[0], lowerBoundA[0]);
var objectA = (object[])array;
for (int i = lowerBoundA[0]; i < upperBoundA[0] + 1; i++)
{
WriteArrayMember(objectInfo, arrayElemTypeNameInfo, objectA[i]);
}
_serWriter.WriteItemEnd();
}
else
{
// Rectangle Array
// Get the length for all the ranks
arrayNameInfo._objectId = objectId;
_serWriter.WriteRectangleArray(memberNameInfo, arrayNameInfo, arrayElemObjectInfo, arrayElemTypeNameInfo, rank, lengthA, lowerBoundA);
// Check for a length of zero
bool bzero = false;
for (int i = 0; i < rank; i++)
{
if (lengthA[i] == 0)
{
bzero = true;
break;
}
}
if (!bzero)
{
WriteRectangle(objectInfo, rank, lengthA, array, arrayElemTypeNameInfo, lowerBoundA);
}
_serWriter.WriteItemEnd();
}
_serWriter.WriteObjectEnd(memberNameInfo, arrayNameInfo);
PutNameInfo(arrayElemTypeNameInfo);
if (isAllocatedMemberNameInfo)
{
PutNameInfo(memberNameInfo);
}
}