private LocalBuilder ReadValue(Type type, string name, string ns)
{
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)
{
ThrowValidationException(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);
ThrowValidationException(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, ns);
}
// Deserialize ref
_ilg.Else();
if (type.IsValueType)
{
ThrowValidationException(SR.Format(SR.ValueTypeCannotHaveRef, DataContract.GetClrTypeFullName(type)));
}
else
{
_ilg.Call(_contextArg, XmlFormatGeneratorStatics.GetExistingObjectMethod, objectId, type, name, ns);
_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, ns);
}
return(value);
}