// Writes out an array 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); } }