Exemplo n.º 1
0
        // 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);
            }
        }