public object Deserialize (Type type, XmlReader reader)
{
QName graph_qname = types.GetQName (type);
string itype = reader.GetAttribute ("type", XmlSchema.InstanceNamespace);
if (itype != null) {
string[] parts = itype.Split (':');
if (parts.Length > 1)
graph_qname = new QName (parts [1], reader.LookupNamespace (reader.NameTable.Get (parts[0])));
else
graph_qname = new QName (itype, reader.NamespaceURI);
}
string label = reader.GetAttribute ("Ref", KnownTypeCollection.MSSimpleNamespace);
if (label != null) {
object o;
if (!references.TryGetValue (label, out o))
throw new SerializationException (String.Format ("Deserialized object with reference Id '{0}' was not found", label));
reader.Skip ();
return o;
}
bool isNil = reader.GetAttribute ("nil", XmlSchema.InstanceNamespace) == "true";
if (isNil) {
reader.Skip ();
if (!type.IsValueType)
return null;
else if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Nullable<>))
return null;
else
throw new SerializationException (String.Format ("Value type {0} cannot be null.", type));
}
if (resolver != null) {
Type t;
if (resolved_qnames.TryGetValue (graph_qname, out t))
type = t;
else { // i.e. resolve name only once.
type = resolver.ResolveName (graph_qname.Name, graph_qname.Namespace, type, default_resolver) ?? type;
resolved_qnames.Add (graph_qname, type);
types.Add (type);
}
}
if (KnownTypeCollection.GetPrimitiveTypeFromName (graph_qname.Name) != null) {
string id = reader.GetAttribute ("Id", KnownTypeCollection.MSSimpleNamespace);
string value;
if (reader.IsEmptyElement) {
reader.Read (); // advance
if (type.IsValueType)
return Activator.CreateInstance (type);
else
// FIXME: Workaround for creating empty objects of the correct type.
value = String.Empty;
}
else
value = reader.ReadElementContentAsString ();
object ret = KnownTypeCollection.PredefinedTypeStringToObject (value, graph_qname.Name, reader);
if (id != null) {
if (references.ContainsKey (id))
throw new InvalidOperationException (String.Format ("Object with Id '{0}' already exists as '{1}'", id, references [id]));
references.Add (id, ret);
}
return ret;
}
return DeserializeByMap (graph_qname, type, reader);
}