private void WriteValue(LocalBuilder memberValue, bool writeXsiType)
{
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 && !writeXsiType)
_ilg.Call(_xmlWriterArg, primitiveContract.XmlFormatContentWriterMethod, memberValue);
else
InternalSerialize(XmlFormatGeneratorStatics.InternalSerializeMethod, memberValue, memberType, 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 && !writeXsiType)
{
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, writeXsiType);
if (memberType == Globals.TypeOfObject) //boxed Nullable<T>
_ilg.EndIf();
}
_ilg.EndIf();
}
}