Ejemplo n.º 1
0
            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);
            }