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); }
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); }
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); } } } } }