Exemplo n.º 1
0
        private void WriteMemberSetup(WriteObjectInfo objectInfo,
                                      NameInfo memberNameInfo,
                                      NameInfo typeNameInfo,
                                      string memberName,
                                      Type memberType,
                                      object?memberData,
                                      WriteObjectInfo?memberObjectInfo)
        {
            NameInfo newMemberNameInfo = MemberToNameInfo(memberName); // newMemberNameInfo contains the member type

            if (memberObjectInfo != null)
            {
                newMemberNameInfo._assemId = memberObjectInfo._assemId;
            }
            newMemberNameInfo._type = memberType;

            // newTypeNameInfo contains the data type
            NameInfo newTypeNameInfo;

            if (memberObjectInfo == null)
            {
                newTypeNameInfo = TypeToNameInfo(memberType);
            }
            else
            {
                newTypeNameInfo = TypeToNameInfo(memberObjectInfo);
            }

            newMemberNameInfo._transmitTypeOnObject = memberNameInfo._transmitTypeOnObject;
            newMemberNameInfo._isParentTypeOnObject = memberNameInfo._isParentTypeOnObject;
            WriteMembers(newMemberNameInfo, newTypeNameInfo, memberData, objectInfo, typeNameInfo, memberObjectInfo);
            PutNameInfo(newMemberNameInfo);
            PutNameInfo(newTypeNameInfo);
        }
Exemplo n.º 2
0
        internal void Serialize(object graph, BinaryFormatterWriter serWriter)
        {
            if (graph == null)
            {
                throw new ArgumentNullException(nameof(graph));
            }
            if (serWriter == null)
            {
                throw new ArgumentNullException(nameof(serWriter));
            }

            _serWriter = serWriter;

            serWriter.WriteBegin();
            long   headerId = 0;
            object?obj;
            bool   isNew;

            // allocations if methodCall or methodResponse and no graph
            _idGenerator        = new ObjectIDGenerator();
            _objectQueue        = new Queue <object>();
            _formatterConverter = new FormatterConverter();
            _serObjectInfoInit  = new SerObjectInfoInit();

            _topId   = InternalGetId(graph, false, null, out isNew);
            headerId = -1;
            WriteSerializedStreamHeader(_topId, headerId);

            _objectQueue.Enqueue(graph);
            while ((obj = GetNext(out long objectId)) != null)
            {
                WriteObjectInfo?objectInfo = null;

                // GetNext will return either an object or a WriteObjectInfo.
                // A WriteObjectInfo is returned if this object was member of another object
                if (obj is WriteObjectInfo)
                {
                    objectInfo = (WriteObjectInfo)obj;
                }
                else
                {
                    objectInfo          = WriteObjectInfo.Serialize(obj, _surrogates, _context, _serObjectInfoInit, _formatterConverter, this, _binder);
                    objectInfo._assemId = GetAssemblyId(objectInfo);
                }

                objectInfo._objectId = objectId;
                NameInfo typeNameInfo = TypeToNameInfo(objectInfo);
                Write(objectInfo, typeNameInfo, typeNameInfo);
                PutNameInfo(typeNameInfo);
                objectInfo.ObjectEnd();
            }

            serWriter.WriteSerializationHeaderEnd();
            serWriter.WriteEnd();

            // Invoke OnSerialized Event
            _objectManager.RaiseOnSerializedEvent();
        }
Exemplo n.º 3
0
        // From the type create the BinaryTypeEnum and typeInformation which describes the type on the wire
        internal static BinaryTypeEnum GetBinaryTypeInfo(Type type, WriteObjectInfo?objectInfo, string?typeName, ObjectWriter objectWriter, out object?typeInformation, out int assemId)
        {
            BinaryTypeEnum binaryTypeEnum;

            assemId         = 0;
            typeInformation = null;

            if (ReferenceEquals(type, Converter.s_typeofString))
            {
                binaryTypeEnum = BinaryTypeEnum.String;
            }
            else if (((objectInfo == null) || ((objectInfo != null) && !objectInfo._isSi)) && (ReferenceEquals(type, Converter.s_typeofObject)))
            {
                // If objectInfo.Si then can be a surrogate which will change the type
                binaryTypeEnum = BinaryTypeEnum.Object;
            }
            else if (ReferenceEquals(type, Converter.s_typeofStringArray))
            {
                binaryTypeEnum = BinaryTypeEnum.StringArray;
            }
            else if (ReferenceEquals(type, Converter.s_typeofObjectArray))
            {
                binaryTypeEnum = BinaryTypeEnum.ObjectArray;
            }
            else if (Converter.IsPrimitiveArray(type, out typeInformation))
            {
                binaryTypeEnum = BinaryTypeEnum.PrimitiveArray;
            }
            else
            {
                InternalPrimitiveTypeE primitiveTypeEnum = objectWriter.ToCode(type);
                switch (primitiveTypeEnum)
                {
                case InternalPrimitiveTypeE.Invalid:
                    string?assembly = null;
                    if (objectInfo == null)
                    {
                        assembly        = type.Assembly.FullName;
                        typeInformation = type.FullName;
                    }
                    else
                    {
                        assembly        = objectInfo.GetAssemblyString();
                        typeInformation = objectInfo.GetTypeFullName();
                    }

                    Debug.Assert(assembly != null);
                    if (assembly.Equals(Converter.s_urtAssemblyString) || assembly.Equals(Converter.s_urtAlternativeAssemblyString))
                    {
                        binaryTypeEnum = BinaryTypeEnum.ObjectUrt;
                        assemId        = 0;
                    }
                    else
                    {
                        binaryTypeEnum = BinaryTypeEnum.ObjectUser;
                        Debug.Assert(objectInfo != null, "[BinaryConverter.GetBinaryTypeInfo]objectInfo null for user object");
                        assemId = (int)objectInfo._assemId;
                        if (assemId == 0)
                        {
                            throw new SerializationException(SR.Format(SR.Serialization_AssemblyId, typeInformation));
                        }
                    }
                    break;

                default:
                    binaryTypeEnum  = BinaryTypeEnum.Primitive;
                    typeInformation = primitiveTypeEnum;
                    break;
                }
            }

            return(binaryTypeEnum);
        }
Exemplo n.º 4
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)
            {
                Debug.Assert(_serObjectInfoInit != null && _formatterConverter != null);
                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;

            Debug.Assert(_serWriter != null);
            // 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 = (Array)array;
                for (int i = lowerBoundA[0]; i < upperBoundA[0] + 1; i++)
                {
                    WriteArrayMember(objectInfo, arrayElemTypeNameInfo, objectA.GetValue(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);
            }
        }
Exemplo n.º 5
0
        // Writes the members of an object
        private void WriteMembers(NameInfo memberNameInfo,
                                  NameInfo memberTypeNameInfo,
                                  object?memberData,
                                  WriteObjectInfo objectInfo,
                                  NameInfo typeNameInfo,
                                  WriteObjectInfo?memberObjectInfo)
        {
            Type?memberType = memberNameInfo._type;
            bool assignUniqueIdToValueType = false;

            // Types are transmitted for a member as follows:
            // The member is of type object
            // The member object of type is ISerializable and
            //  Binary - Types always transmitted.

            if (ReferenceEquals(memberType, Converter.s_typeofObject) || Nullable.GetUnderlyingType(memberType !) != null)
            {
                memberTypeNameInfo._transmitTypeOnMember = true;
                memberNameInfo._transmitTypeOnMember     = true;
            }

            if (CheckTypeFormat(_formatterEnums._typeFormat, FormatterTypeStyle.TypesAlways) || (objectInfo._isSi))
            {
                memberTypeNameInfo._transmitTypeOnObject = true;
                memberNameInfo._transmitTypeOnObject     = true;
                memberNameInfo._isParentTypeOnObject     = true;
            }

            if (CheckForNull(objectInfo, memberNameInfo, memberTypeNameInfo, memberData))
            {
                return;
            }

            object outObj  = memberData !;
            Type?  outType = null;

            // If member type does not equal data type, transmit type on object.
            if (memberTypeNameInfo._primitiveTypeEnum == InternalPrimitiveTypeE.Invalid)
            {
                outType = GetType(outObj);
                if (!ReferenceEquals(memberType, outType))
                {
                    memberTypeNameInfo._transmitTypeOnMember = true;
                    memberNameInfo._transmitTypeOnMember     = true;
                }
            }

            if (ReferenceEquals(memberType, Converter.s_typeofObject))
            {
                assignUniqueIdToValueType = true;
                memberType = GetType(memberData !);
                if (memberObjectInfo == null)
                {
                    TypeToNameInfo(memberType, memberTypeNameInfo);
                }
                else
                {
                    TypeToNameInfo(memberObjectInfo, memberTypeNameInfo);
                }
            }

            if (memberObjectInfo != null && memberObjectInfo._isArray)
            {
                // outObj is an array. It can never be a value type.
                long arrayId = Schedule(outObj, false, null, memberObjectInfo);
                if (arrayId > 0)
                {
                    // Array as object
                    memberNameInfo._objectId = arrayId;
                    WriteObjectRef(memberNameInfo, arrayId);
                }
                else
                {
                    Debug.Assert(_serWriter != null);
                    // Nested Array
                    _serWriter.WriteMemberNested(memberNameInfo);

                    memberObjectInfo._objectId = arrayId;
                    memberNameInfo._objectId   = arrayId;
                    WriteArray(memberObjectInfo, memberNameInfo, memberObjectInfo);
                    objectInfo.ObjectEnd();
                }
                return;
            }

            if (!WriteKnownValueClass(memberNameInfo, memberTypeNameInfo, memberData !))
            {
                if (outType == null)
                {
                    outType = GetType(outObj);
                }

                long memberObjectId = Schedule(outObj, assignUniqueIdToValueType, outType, memberObjectInfo);
                if (memberObjectId < 0)
                {
                    Debug.Assert(memberObjectInfo != null);
                    // Nested object
                    memberObjectInfo._objectId = memberObjectId;
                    NameInfo newTypeNameInfo = TypeToNameInfo(memberObjectInfo);
                    newTypeNameInfo._objectId = memberObjectId;
                    Write(memberObjectInfo, memberNameInfo, newTypeNameInfo);
                    PutNameInfo(newTypeNameInfo);
                    memberObjectInfo.ObjectEnd();
                }
                else
                {
                    // Object reference
                    memberNameInfo._objectId = memberObjectId;
                    WriteObjectRef(memberNameInfo, memberObjectId);
                }
            }
        }
 internal void WriteObjectByteArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo?objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, byte[] byteA)
 {
     InternalWriteItemNull();
     WriteSingleArray(memberNameInfo, arrayNameInfo, objectInfo, arrayElemTypeNameInfo, length, lowerBound, byteA);
 }
        internal void WriteRectangleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo?objectInfo, NameInfo arrayElemTypeNameInfo, int rank, int[] lengthA, int[] lowerBoundA)
        {
            InternalWriteItemNull();

            BinaryArrayTypeEnum binaryArrayTypeEnum = BinaryArrayTypeEnum.Rectangular;
            object?        typeInformation          = null;
            int            assemId        = 0;
            BinaryTypeEnum binaryTypeEnum = BinaryTypeConverter.GetBinaryTypeInfo(arrayElemTypeNameInfo._type !, objectInfo, arrayElemTypeNameInfo.NIname, _objectWriter, out typeInformation, out assemId);

            if (_binaryArray == null)
            {
                _binaryArray = new BinaryArray();
            }

            for (int i = 0; i < rank; i++)
            {
                if (lowerBoundA[i] != 0)
                {
                    binaryArrayTypeEnum = BinaryArrayTypeEnum.RectangularOffset;
                    break;
                }
            }

            _binaryArray.Set((int)arrayNameInfo._objectId, rank, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);
            _binaryArray.Write(this);
        }
        internal void WriteJaggedArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo?objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound)
        {
            InternalWriteItemNull();
            BinaryArrayTypeEnum binaryArrayTypeEnum;
            var lengthA = new int[1];

            lengthA[0]         = length;
            int[]? lowerBoundA = null;
            object?typeInformation = null;
            int    assemId         = 0;

            if (lowerBound == 0)
            {
                binaryArrayTypeEnum = BinaryArrayTypeEnum.Jagged;
            }
            else
            {
                binaryArrayTypeEnum = BinaryArrayTypeEnum.JaggedOffset;
                lowerBoundA         = new int[1];
                lowerBoundA[0]      = lowerBound;
            }

            BinaryTypeEnum binaryTypeEnum = BinaryTypeConverter.GetBinaryTypeInfo(arrayElemTypeNameInfo._type !, objectInfo, arrayElemTypeNameInfo.NIname, _objectWriter, out typeInformation, out assemId);

            if (_binaryArray == null)
            {
                _binaryArray = new BinaryArray();
            }
            _binaryArray.Set((int)arrayNameInfo._objectId, 1, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);

            _binaryArray.Write(this);
        }
        internal void WriteSingleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo?objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, Array array)
        {
            InternalWriteItemNull();
            BinaryArrayTypeEnum binaryArrayTypeEnum;
            var lengthA = new int[1];

            lengthA[0]         = length;
            int[]? lowerBoundA = null;
            object?typeInformation = null;

            if (lowerBound == 0)
            {
                binaryArrayTypeEnum = BinaryArrayTypeEnum.Single;
            }
            else
            {
                binaryArrayTypeEnum = BinaryArrayTypeEnum.SingleOffset;
                lowerBoundA         = new int[1];
                lowerBoundA[0]      = lowerBound;
            }

            int            assemId;
            BinaryTypeEnum binaryTypeEnum = BinaryTypeConverter.GetBinaryTypeInfo(
                arrayElemTypeNameInfo._type !, objectInfo, arrayElemTypeNameInfo.NIname, _objectWriter, out typeInformation, out assemId);

            if (_binaryArray == null)
            {
                _binaryArray = new BinaryArray();
            }
            _binaryArray.Set((int)arrayNameInfo._objectId, 1, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);

            _binaryArray.Write(this);

            if (Converter.IsWriteAsByteArray(arrayElemTypeNameInfo._primitiveTypeEnum) && (lowerBound == 0))
            {
                //array is written out as an array of bytes
                if (arrayElemTypeNameInfo._primitiveTypeEnum == InternalPrimitiveTypeE.Byte)
                {
                    WriteBytes((byte[])array);
                }
                else if (arrayElemTypeNameInfo._primitiveTypeEnum == InternalPrimitiveTypeE.Char)
                {
                    WriteChars((char[])array);
                }
                else
                {
                    WriteArrayAsBytes(array, Converter.TypeLength(arrayElemTypeNameInfo._primitiveTypeEnum));
                }
            }
        }