Esempio n. 1
0
        public void ReflectionWriteCollection(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContextComplexJson context, CollectionDataContract collectionContract)
        {
            JsonWriterDelegator?jsonWriter = xmlWriter as JsonWriterDelegator;

            if (jsonWriter == null)
            {
                throw new ArgumentException(nameof(xmlWriter));
            }

            XmlDictionaryString itemName = context.CollectionItemName;

            if (collectionContract.Kind == CollectionKind.Array)
            {
                context.IncrementArrayCount(jsonWriter, (Array)obj);
                Type itemType = collectionContract.ItemType;
                if (!ReflectionTryWritePrimitiveArray(jsonWriter, obj, collectionContract.UnderlyingType, itemType, itemName))
                {
                    ReflectionWriteArrayAttribute(jsonWriter);

                    Array array = (Array)obj;
                    PrimitiveDataContract?primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(itemType);
                    for (int i = 0; i < array.Length; ++i)
                    {
                        _reflectionClassWriter.ReflectionWriteStartElement(jsonWriter, itemName);
                        _reflectionClassWriter.ReflectionWriteValue(jsonWriter, context, itemType, array.GetValue(i), false, primitiveContract);
                        _reflectionClassWriter.ReflectionWriteEndElement(jsonWriter);
                    }
                }
            }
            else
            {
                collectionContract.IncrementCollectionCount(jsonWriter, obj, context);

                IEnumerator enumerator = collectionContract.GetEnumeratorForCollection(obj);

                bool canWriteSimpleDictionary = collectionContract.Kind == CollectionKind.GenericDictionary ||
                                                collectionContract.Kind == CollectionKind.Dictionary;

                bool useSimpleDictionaryFormat = context.UseSimpleDictionaryFormat;

                if (canWriteSimpleDictionary && useSimpleDictionaryFormat)
                {
                    ReflectionWriteObjectAttribute(jsonWriter);
                    Type[] itemTypeGenericArguments = collectionContract.ItemType.GetGenericArguments();
                    Type?  dictionaryValueType      = itemTypeGenericArguments.Length == 2 ? itemTypeGenericArguments[1] : null;

                    while (enumerator.MoveNext())
                    {
                        object current = enumerator.Current;
                        object key     = ((IKeyValue)current).Key !;
                        object value   = ((IKeyValue)current).Value !;
                        _reflectionClassWriter.ReflectionWriteStartElement(jsonWriter, key.ToString() !);
                        _reflectionClassWriter.ReflectionWriteValue(jsonWriter, context, dictionaryValueType ?? value.GetType(), value, false, primitiveContractForParamType: null);
                        _reflectionClassWriter.ReflectionWriteEndElement(jsonWriter);
                    }
                }
                else
                {
                    ReflectionWriteArrayAttribute(jsonWriter);

                    PrimitiveDataContract?primitiveContractForType = PrimitiveDataContract.GetPrimitiveDataContract(collectionContract.UnderlyingType);
                    if (primitiveContractForType != null && primitiveContractForType.UnderlyingType != Globals.TypeOfObject)
                    {
                        while (enumerator.MoveNext())
                        {
                            object current = enumerator.Current;
                            context.IncrementItemCount(1);
                            primitiveContractForType.WriteXmlElement(jsonWriter, current, context, itemName, null /*namespace*/);
                        }
                    }
                    else
                    {
                        Type elementType  = collectionContract.GetCollectionElementType();
                        bool isDictionary = collectionContract.Kind == CollectionKind.Dictionary || collectionContract.Kind == CollectionKind.GenericDictionary;

                        DataContract?    itemContract     = null;
                        JsonDataContract?jsonDataContract = null;
                        if (isDictionary)
                        {
                            itemContract     = XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract(collectionContract.ItemContract);
                            jsonDataContract = JsonDataContract.GetJsonDataContract(itemContract);
                        }

                        while (enumerator.MoveNext())
                        {
                            object current = enumerator.Current;
                            context.IncrementItemCount(1);
                            _reflectionClassWriter.ReflectionWriteStartElement(jsonWriter, itemName);
                            if (isDictionary)
                            {
                                jsonDataContract !.WriteJsonValue(jsonWriter, current, context, collectionContract.ItemType.TypeHandle);
                            }
                            else
                            {
                                _reflectionClassWriter.ReflectionWriteValue(jsonWriter, context, elementType, current, false, primitiveContractForParamType: null);
                            }

                            _reflectionClassWriter.ReflectionWriteEndElement(jsonWriter);
                        }
                    }
                }
            }
        }
            private void WriteValue(LocalBuilder memberValue)
            {
                Type memberType    = memberValue.LocalType;
                bool isNullableOfT = (memberType.IsGenericType &&
                                      memberType.GetGenericTypeDefinition() == Globals.TypeOfNullable);

                if (memberType.IsValueType && !isNullableOfT)
                {
                    PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(memberType);
                    if (primitiveContract != null)
                    {
                        _ilg.Call(_xmlWriterArg, primitiveContract.XmlFormatContentWriterMethod, memberValue);
                    }
                    else
                    {
                        InternalSerialize(XmlFormatGeneratorStatics.InternalSerializeMethod, memberValue, memberType, false /* writeXsiType */);
                    }
                }
                else
                {
                    if (isNullableOfT)
                    {
                        memberValue = UnwrapNullableObject(memberValue); //Leaves !HasValue on stack
                        memberType  = memberValue.LocalType;
                    }
                    else
                    {
                        _ilg.Load(memberValue);
                        _ilg.Load(null);
                        _ilg.Ceq();
                    }
                    _ilg.If();
                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.WriteNullMethod, _xmlWriterArg, memberType, DataContract.IsTypeSerializable(memberType));
                    _ilg.Else();
                    PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(memberType);
                    if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject)
                    {
                        if (isNullableOfT)
                        {
                            _ilg.Call(_xmlWriterArg, primitiveContract.XmlFormatContentWriterMethod, memberValue);
                        }
                        else
                        {
                            _ilg.Call(_contextArg, primitiveContract.XmlFormatContentWriterMethod, _xmlWriterArg, memberValue);
                        }
                    }
                    else
                    {
                        if (memberType == Globals.TypeOfObject || //boxed Nullable<T>
                            memberType == Globals.TypeOfValueType ||
                            ((IList)Globals.TypeOfNullable.GetInterfaces()).Contains(memberType))
                        {
                            _ilg.Load(memberValue);
                            _ilg.ConvertValue(memberValue.LocalType, Globals.TypeOfObject);
                            memberValue = _ilg.DeclareLocal(Globals.TypeOfObject, "unwrappedMemberValue");
                            memberType  = memberValue.LocalType;
                            _ilg.Stloc(memberValue);
                            _ilg.If(memberValue, Cmp.EqualTo, null);
                            _ilg.Call(_contextArg, XmlFormatGeneratorStatics.WriteNullMethod, _xmlWriterArg, memberType, DataContract.IsTypeSerializable(memberType));
                            _ilg.Else();
                        }
                        InternalSerialize((isNullableOfT ? XmlFormatGeneratorStatics.InternalSerializeMethod : XmlFormatGeneratorStatics.InternalSerializeReferenceMethod),
                                          memberValue, memberType, false /* writeXsiType */);

                        if (memberType == Globals.TypeOfObject) //boxed Nullable<T>
                        {
                            _ilg.EndIf();
                        }
                    }
                    _ilg.EndIf();
                }
            }
            private LocalBuilder ReadValue(Type type, string name)
            {
                LocalBuilder value         = _ilg.DeclareLocal(type, "valueRead");
                LocalBuilder nullableValue = null;
                int          nullables     = 0;

                while (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == Globals.TypeOfNullable)
                {
                    nullables++;
                    type = type.GetGenericArguments()[0];
                }

                PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(type);

                if ((primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject) || nullables != 0 || type.GetTypeInfo().IsValueType)
                {
                    LocalBuilder objectId = _ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead");
                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.ReadAttributesMethod, _xmlReaderArg);
                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.ReadIfNullOrRefMethod, _xmlReaderArg, type, DataContract.IsTypeSerializable(type));
                    _ilg.Stloc(objectId);
                    // Deserialize null
                    _ilg.If(objectId, Cmp.EqualTo, Globals.NullObjectId);
                    if (nullables != 0)
                    {
                        _ilg.LoadAddress(value);
                        _ilg.InitObj(value.LocalType);
                    }
                    else if (type.GetTypeInfo().IsValueType)
                    {
                        ThrowSerializationException(SR.Format(SR.ValueTypeCannotBeNull, DataContract.GetClrTypeFullName(type)));
                    }
                    else
                    {
                        _ilg.Load(null);
                        _ilg.Stloc(value);
                    }

                    // Deserialize value

                    // Compare against Globals.NewObjectId, which is set to string.Empty
                    _ilg.ElseIfIsEmptyString(objectId);
                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod);
                    _ilg.Stloc(objectId);
                    if (type.GetTypeInfo().IsValueType)
                    {
                        _ilg.IfNotIsEmptyString(objectId);
                        ThrowSerializationException(SR.Format(SR.ValueTypeCannotHaveId, DataContract.GetClrTypeFullName(type)));
                        _ilg.EndIf();
                    }
                    if (nullables != 0)
                    {
                        nullableValue = value;
                        value         = _ilg.DeclareLocal(type, "innerValueRead");
                    }

                    if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject)
                    {
                        _ilg.Call(_xmlReaderArg, primitiveContract.XmlFormatReaderMethod);
                        _ilg.Stloc(value);
                        if (!type.GetTypeInfo().IsValueType)
                        {
                            _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, value);
                        }
                    }
                    else
                    {
                        InternalDeserialize(value, type, name);
                    }
                    // Deserialize ref
                    _ilg.Else();
                    if (type.GetTypeInfo().IsValueType)
                    {
                        ThrowSerializationException(SR.Format(SR.ValueTypeCannotHaveRef, DataContract.GetClrTypeFullName(type)));
                    }
                    else
                    {
                        _ilg.Call(_contextArg, XmlFormatGeneratorStatics.GetExistingObjectMethod, objectId, type, name, string.Empty);
                        _ilg.ConvertValue(Globals.TypeOfObject, type);
                        _ilg.Stloc(value);
                    }
                    _ilg.EndIf();

                    if (nullableValue != null)
                    {
                        _ilg.If(objectId, Cmp.NotEqualTo, Globals.NullObjectId);
                        WrapNullableObject(value, nullableValue, nullables);
                        _ilg.EndIf();
                        value = nullableValue;
                    }
                }
                else
                {
                    InternalDeserialize(value, type, name);
                }

                return(value);
            }
Esempio n. 4
0
        protected override int ReflectionWriteMembers(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context, ClassDataContract classContract, ClassDataContract derivedMostClassContract, int childElementIndex, XmlDictionaryString[] memberNames)
        {
            int memberCount = (classContract.BaseContract == null) ? 0 :
                              ReflectionWriteMembers(xmlWriter, obj, context, classContract.BaseContract, derivedMostClassContract, childElementIndex, memberNames);

            childElementIndex += memberCount;

            Type classType = classContract.UnadaptedClassType;

            context.IncrementItemCount(classContract.Members.Count);
            for (int i = 0; i < classContract.Members.Count; i++, memberCount++)
            {
                DataMember member     = classContract.Members[i];
                Type       memberType = member.MemberType;
                if (member.IsGetOnlyCollection)
                {
                    context.StoreIsGetOnlyCollection();
                }


                bool   shouldWriteValue = true;
                object memberValue      = null;
                if (!member.EmitDefaultValue)
                {
                    memberValue = ReflectionGetMemberValue(obj, member);
                    object defaultValue = XmlFormatGeneratorStatics.GetDefaultValue(memberType);
                    if ((memberValue == null && defaultValue == null) ||
                        (memberValue != null && memberValue.Equals(defaultValue)))
                    {
                        shouldWriteValue = false;

                        if (member.IsRequired)
                        {
                            XmlObjectSerializerWriteContext.ThrowRequiredMemberMustBeEmitted(member.Name, classContract.UnderlyingType);
                        }
                    }
                }

                if (shouldWriteValue)
                {
                    if (memberValue == null)
                    {
                        memberValue = ReflectionGetMemberValue(obj, member);
                    }
                    bool requiresNameAttribute = DataContractJsonSerializerImpl.CheckIfXmlNameRequiresMapping(classContract.MemberNames[i]);
                    PrimitiveDataContract primitiveContract = member.MemberPrimitiveContract;
                    if (requiresNameAttribute || !ReflectionTryWritePrimitive(xmlWriter, context, memberType, memberValue, memberNames[i + childElementIndex] /*name*/, null /*ns*/, primitiveContract))
                    {
                        // Note: DataContractSerializer has member-conflict logic here to deal with the schema export
                        //       requirement that the same member can't be of two different types.
                        if (requiresNameAttribute)
                        {
                            XmlObjectSerializerWriteContextComplexJson.WriteJsonNameWithMapping(xmlWriter, memberNames, i + childElementIndex);
                        }
                        else
                        {
                            ReflectionWriteStartElement(xmlWriter, memberNames[i + childElementIndex]);
                        }

                        ReflectionWriteValue(xmlWriter, context, memberType, memberValue, false /*writeXsiType*/, primitiveContractForParamType: null);
                        ReflectionWriteEndElement(xmlWriter);
                    }

                    if (classContract.HasExtensionData)
                    {
                        context.WriteExtensionData(xmlWriter, ((IExtensibleDataObject)obj).ExtensionData, memberCount);
                    }
                }
            }

            return(memberCount);
        }
Esempio n. 5
0
        object ReadValue(Type type, string name)
        {
            var    valueType = type;
            object value     = null;
            bool   shouldAssignNullableValue = false;
            int    nullables = 0;

            while (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable)
            {
                nullables++;
                type = type.GetGenericArguments() [0];
            }

            PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(type);

            if ((primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject) || nullables != 0 || type.IsValueType)
            {
                context.ReadAttributes(xmlReader);
                string objectId = context.ReadIfNullOrRef(xmlReader, type, DataContract.IsTypeSerializable(type));
                // Deserialize null
                if (objectId == Globals.NullObjectId)
                {
                    if (nullables != 0)
                    {
                        value = Activator.CreateInstance(valueType);
                    }
                    else if (type.IsValueType)
                    {
                        throw new SerializationException(SR.GetString(SR.ValueTypeCannotBeNull, DataContract.GetClrTypeFullName(type)));
                    }
                    else
                    {
                        value = null;
                    }
                }
                else if (objectId == string.Empty)
                {
                    // Deserialize value

                    // Compare against Globals.NewObjectId, which is set to string.Empty

                    objectId = context.GetObjectId();

                    if (type.IsValueType)
                    {
                        if (!string.IsNullOrEmpty(objectId))
                        {
                            throw new SerializationException(SR.GetString(SR.ValueTypeCannotHaveId, DataContract.GetClrTypeFullName(type)));
                        }
                    }
                    object innerValueRead = null;
                    if (nullables != 0)
                    {
                        shouldAssignNullableValue = true;
                    }

                    if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject)
                    {
                        value = primitiveContract.XmlFormatReaderMethod.Invoke(xmlReader, new object [0]);
                        if (!type.IsValueType)
                        {
                            context.AddNewObject(value);
                        }
                    }
                    else
                    {
                        value = InternalDeserialize(type, name);
                    }
                }
                else
                {
                    // Deserialize ref
                    if (type.IsValueType)
                    {
                        throw new SerializationException(SR.GetString(SR.ValueTypeCannotHaveRef, DataContract.GetClrTypeFullName(type)));
                    }
                    else
                    {
                        value = CodeInterpreter.ConvertValue(context.GetExistingObject(objectId, type, name, string.Empty), Globals.TypeOfObject, type);
                    }
                }

                if (shouldAssignNullableValue)
                {
                    if (objectId != Globals.NullObjectId)
                    {
                        value = WrapNullableObject(type, value, valueType, nullables);
                    }
                }
            }
            else
            {
                value = InternalDeserialize(type, name);
            }

            return(value);
        }
        void WriteValue(Type memberType, object memberValue)
        {
            Pointer memberValueRefPointer = null;

            if (memberType.IsPointer)
            {
                memberValueRefPointer = (Pointer)JsonFormatGeneratorStatics.BoxPointer.Invoke(null, new object [] { memberValue, memberType });
            }
            bool isNullableOfT = (memberType.IsGenericType &&
                                  memberType.GetGenericTypeDefinition() == Globals.TypeOfNullable);

            if (memberType.IsValueType && !isNullableOfT)
            {
                PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(memberType);
                if (primitiveContract != null)
                {
                    primitiveContract.XmlFormatContentWriterMethod.Invoke(writer, new object [] { memberValue });
                }
                else
                {
                    InternalSerialize(XmlFormatGeneratorStatics.InternalSerializeMethod, () => memberValue, memberType, false);
                }
            }
            else
            {
                bool isNull;
                if (isNullableOfT)
                {
                    memberValue = UnwrapNullableObject(() => memberValue, ref memberType, out isNull);                     //Leaves !HasValue on stack
                }
                else
                {
                    isNull = memberValue == null;
                }
                if (isNull)
                {
                    XmlFormatGeneratorStatics.WriteNullMethod.Invoke(context, new object [] { writer, memberType, DataContract.IsTypeSerializable(memberType) });
                }
                else
                {
                    PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(memberType);
                    if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject)
                    {
                        if (isNullableOfT)
                        {
                            primitiveContract.XmlFormatContentWriterMethod.Invoke(writer, new object [] { memberValue });
                        }
                        else
                        {
                            primitiveContract.XmlFormatContentWriterMethod.Invoke(context, new object [] { writer, memberValue });
                        }
                    }
                    else
                    {
                        bool isNull2 = false;
                        if (memberType == Globals.TypeOfObject ||                         //boxed Nullable<T>
                            memberType == Globals.TypeOfValueType ||
                            ((IList)Globals.TypeOfNullable.GetInterfaces()).Contains(memberType))
                        {
                            var unwrappedMemberValue = CodeInterpreter.ConvertValue(memberValue, memberType.GetType(), Globals.TypeOfObject);
                            memberValue = unwrappedMemberValue;
                            isNull2     = memberValue == null;
                        }
                        if (isNull2)
                        {
                            XmlFormatGeneratorStatics.WriteNullMethod.Invoke(context, new object [] { writer, memberType, DataContract.IsTypeSerializable(memberType) });
                        }
                        else
                        {
                            InternalSerialize((isNullableOfT ? XmlFormatGeneratorStatics.InternalSerializeMethod : XmlFormatGeneratorStatics.InternalSerializeReferenceMethod),
                                              () => memberValue, memberType, false);
                        }
                    }
                }
            }
        }