2010-05-31 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Mon, 31 May 2010 11:31:04 +0000 (11:31 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Mon, 31 May 2010 11:31:04 +0000 (11:31 -0000)
* SerializationMap.cs, XmlFormatterSerializer.cs,
  DataContractSerializer.cs :
  support DataContractSerializer.PreserveObjectReferences. z:Ref
  attributes are used not only for objects with IsReference=true.
  Fixed bug #610036.

* XmlObjectSerializerTest.cs : test PreserveObjectReferences too.

svn path=/trunk/mcs/; revision=158201

mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/ChangeLog
mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs
mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs
mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterSerializer.cs
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/ChangeLog
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/XmlObjectSerializerTest.cs

index 1d1951318614ec596fefc737936a82359e74fda1..b6488a4850201aebaa755701f15dce890284573b 100755 (executable)
@@ -1,3 +1,11 @@
+2010-05-31  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * SerializationMap.cs, XmlFormatterSerializer.cs,
+         DataContractSerializer.cs :
+         support DataContractSerializer.PreserveObjectReferences. z:Ref
+         attributes are used not only for objects with IsReference=true.
+         Fixed bug #610036.
+
 2010-05-31  Atsushi Enomoto  <atsushi@ximian.com>
 
        * SerializationMap.cs, KnownTypeCollection.cs : contract namespace
index 44ab29d185956a975080389b768dceec13228a0b..3624a13581ef78c5960a5f154a0f788bfe853bef 100644 (file)
@@ -322,7 +322,7 @@ namespace System.Runtime.Serialization
 
                        XmlFormatterSerializer.Serialize (writer, graph,
                                known_types,
-                               ignore_ext, max_items, root_ns.Value);
+                               ignore_ext, max_items, root_ns.Value, preserve_refs);
 
                        // remove temporarily-added known types for
                        // rootType and object graph type.
index b38e2ec3cfba63a3f9fee0703b2797a941e8c53f..a8d3c3fcbf10dc77625efee0457bd9e27aca5597 100644 (file)
@@ -296,16 +296,9 @@ namespace System.Runtime.Serialization
                public virtual void Serialize (object graph,
                        XmlFormatterSerializer serializer)
                {
-                       string label = null;
-                       if (IsReference) {
-                               label = (string) serializer.References [graph];
-                               if (label != null) {
-                                       serializer.Writer.WriteAttributeString ("z", "Ref", KnownTypeCollection.MSSimpleNamespace, label);
-                                       return;
-                               }
-                               label = "i" + (serializer.References.Count + 1);
-                               serializer.References.Add (graph, label);
-                       }
+                       string label;
+                       if (serializer.TrySerializeAsReference (IsReference, graph, out label))
+                               return;
                        else if (serializer.SerializingObjects.Contains (graph))
                                throw new SerializationException (String.Format ("Circular reference of an object in the object graph was found: '{0}' of type {1}", graph, graph.GetType ()));
                        serializer.SerializingObjects.Add (graph);
index 7a3ca9b135c9696d5f368867298f854da777ac65..3506f7ea6448460dd0e8ebc353bfe075a0044b4a 100644 (file)
@@ -54,22 +54,25 @@ namespace System.Runtime.Serialization
 
                public static void Serialize (XmlDictionaryWriter writer, object graph,
                        KnownTypeCollection types,
-                       bool ignoreUnknown, int maxItems, string root_ns)
+                       bool ignoreUnknown, int maxItems, string root_ns, bool preserveObjectReferences)
                {
-                       new XmlFormatterSerializer (writer, types, ignoreUnknown, maxItems, root_ns)
+                       new XmlFormatterSerializer (writer, types, ignoreUnknown, maxItems, root_ns, preserveObjectReferences)
                                .Serialize (graph != null ? graph.GetType () : null, graph);
                }
 
                public XmlFormatterSerializer (XmlDictionaryWriter writer,
                        KnownTypeCollection types,
-                       bool ignoreUnknown, int maxItems, string root_ns)
+                       bool ignoreUnknown, int maxItems, string root_ns, bool preserveObjectReferences)
                {
                        this.writer = writer;
                        this.types = types;
                        ignore_unknown = ignoreUnknown;
                        max_items = maxItems;
+                       PreserveObjectReferences = preserveObjectReferences;
                }
 
+               public bool PreserveObjectReferences { get; private set; }
+
                public ArrayList SerializingObjects {
                        get { return objects; }
                }
@@ -127,6 +130,12 @@ namespace System.Runtime.Serialization
 
                public void SerializePrimitive (Type type, object graph, QName qname)
                {
+                       string label;
+                       if (TrySerializeAsReference (false, graph, out label))
+                               return;
+                       if (label != null)
+                               Writer.WriteAttributeString ("z", "Id", KnownTypeCollection.MSSimpleNamespace, label);
+
 //                     writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace);
 //                     writer.WriteQualifiedName (qname.Name, qname.Namespace);
 //                     writer.WriteEndAttribute ();
@@ -144,6 +153,27 @@ namespace System.Runtime.Serialization
                {
                        writer.WriteEndElement ();
                }
+
+               // returned bool: whether z:Ref is written or not.
+               // out label: object label either in use or newly allocated.
+               public bool TrySerializeAsReference (bool isMapReference, object graph, out string label)
+               {
+                       label = null;
+                       if (!isMapReference && (!PreserveObjectReferences || graph == null || graph.GetType ().IsValueType))
+                               return false;
+
+                       label = (string) References [graph];
+                       if (label != null) {
+                               Writer.WriteAttributeString ("z", "Ref", KnownTypeCollection.MSSimpleNamespace, label);
+                               label = null; // do not write label
+                               return true;
+                       }
+
+                       label = "i" + (References.Count + 1);
+                       References.Add (graph, label);
+
+                       return false;
+               }
        }
 }
 #endif
index 61c30a06f45e4f3d921be4b9cbc03dbfd75aa4be..4ea324bd0e55dbe8a66a3724dfb296f206f05c96 100644 (file)
@@ -1,3 +1,7 @@
+2010-05-31  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XmlObjectSerializerTest.cs : test PreserveObjectReferences too.
+
 2010-05-31  Atsushi Enomoto  <atsushi@ximian.com>
 
        * XmlObjectSerializerTest.cs : add test for bug #610036.
index a348430caa7ea1e198810ff3e60d761cd34491c4..8f5014ccca973b2a9eafb7a6f1376ecdecf35678 100644 (file)
@@ -1414,12 +1414,17 @@ namespace MonoTests.System.Runtime.Serialization
                        root.FDict.Add (foo2);
 
                        ds.WriteObject (ms, root);
-                       Console.WriteLine (Encoding.UTF8.GetString (ms.ToArray ()));
+                       string result = Encoding.UTF8.GetString (ms.ToArray ());
                        ms.Position = 0;
 
                        root = (Root) ds.ReadObject (ms);
 
                        Assert.AreEqual (2, root.FDict.Count, "#1");
+                       int idx = result.IndexOf ("foo1");
+                       Assert.IsTrue (idx >= 0, "#2");
+                       // since "foo1" is stored as z:Ref for string, it must not occur twice.
+                       int idx2 = result.IndexOf ("foo1", idx + 1);
+                       Assert.IsTrue (idx2 < 0, "idx2 should not occur at " + idx2);
                }
        }