예제 #1
0
            private LocalBuilder ReadValue(Type type, string name)
            {
                LocalBuilder value         = _ilg.DeclareLocal(type, "valueRead");
                LocalBuilder nullableValue = null;
                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)
                {
                    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.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.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.IsValueType)
                        {
                            _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, value);
                        }
                    }
                    else
                    {
                        InternalDeserialize(value, type, name);
                    }
                    // Deserialize ref
                    _ilg.Else();
                    if (type.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);
            }
예제 #2
0
            private void WriteValue(LocalBuilder memberValue)
            {
                Type memberType    = memberValue.LocalType;
                bool isNullableOfT = (memberType.GetTypeInfo().IsGenericType&&
                                      memberType.GetGenericTypeDefinition() == Globals.TypeOfNullable);

                if (memberType.GetTypeInfo().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();
                }
            }
        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 LocalBuilder ReadValue(Type type, string name)
            {
                LocalBuilder builder    = this.ilg.DeclareLocal(type, "valueRead");
                LocalBuilder outerValue = null;
                int          nullables  = 0;

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

                if (((primitiveDataContract != null) && (primitiveDataContract.UnderlyingType != Globals.TypeOfObject)) || ((nullables != 0) || type.IsValueType))
                {
                    LocalBuilder local = this.ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead");
                    this.ilg.Call(this.contextArg, XmlFormatGeneratorStatics.ReadAttributesMethod, this.xmlReaderArg);
                    this.ilg.Call(this.contextArg, XmlFormatGeneratorStatics.ReadIfNullOrRefMethod, this.xmlReaderArg, type, DataContract.IsTypeSerializable(type));
                    this.ilg.Stloc(local);
                    this.ilg.If(local, Cmp.EqualTo, null);
                    if (nullables != 0)
                    {
                        this.ilg.LoadAddress(builder);
                        this.ilg.InitObj(builder.LocalType);
                    }
                    else if (type.IsValueType)
                    {
                        this.ThrowValidationException(System.Runtime.Serialization.SR.GetString("ValueTypeCannotBeNull", new object[] { DataContract.GetClrTypeFullName(type) }), new object[0]);
                    }
                    else
                    {
                        this.ilg.Load(null);
                        this.ilg.Stloc(builder);
                    }
                    this.ilg.ElseIfIsEmptyString(local);
                    this.ilg.Call(this.contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod);
                    this.ilg.Stloc(local);
                    if (type.IsValueType)
                    {
                        this.ilg.IfNotIsEmptyString(local);
                        this.ThrowValidationException(System.Runtime.Serialization.SR.GetString("ValueTypeCannotHaveId", new object[] { DataContract.GetClrTypeFullName(type) }), new object[0]);
                        this.ilg.EndIf();
                    }
                    if (nullables != 0)
                    {
                        outerValue = builder;
                        builder    = this.ilg.DeclareLocal(type, "innerValueRead");
                    }
                    if ((primitiveDataContract != null) && (primitiveDataContract.UnderlyingType != Globals.TypeOfObject))
                    {
                        this.ilg.Call(this.xmlReaderArg, primitiveDataContract.XmlFormatReaderMethod);
                        this.ilg.Stloc(builder);
                        if (!type.IsValueType)
                        {
                            this.ilg.Call(this.contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, builder);
                        }
                    }
                    else
                    {
                        this.InternalDeserialize(builder, type, name);
                    }
                    this.ilg.Else();
                    if (type.IsValueType)
                    {
                        this.ThrowValidationException(System.Runtime.Serialization.SR.GetString("ValueTypeCannotHaveRef", new object[] { DataContract.GetClrTypeFullName(type) }), new object[0]);
                    }
                    else
                    {
                        this.ilg.Call(this.contextArg, XmlFormatGeneratorStatics.GetExistingObjectMethod, local, type, name, string.Empty);
                        this.ilg.ConvertValue(Globals.TypeOfObject, type);
                        this.ilg.Stloc(builder);
                    }
                    this.ilg.EndIf();
                    if (outerValue != null)
                    {
                        this.ilg.If(local, Cmp.NotEqualTo, null);
                        this.WrapNullableObject(builder, outerValue, nullables);
                        this.ilg.EndIf();
                        builder = outerValue;
                    }
                    return(builder);
                }
                this.InternalDeserialize(builder, type, name);
                return(builder);
            }
예제 #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);
                        }
                    }
                }
            }
        }