Skip to content

Commit

Permalink
Fix bug #703910 - implement Order support in XmlSerializer.
Browse files Browse the repository at this point in the history
  • Loading branch information
Atsushi Eno committed Jul 20, 2011
1 parent c5302ba commit d68521e
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 58 deletions.
Expand Up @@ -1606,7 +1606,7 @@ void GenerateReadClassInstance (XmlTypeMapping typeMap, string isNullable, strin
WriteLine ("return ob;");
}

void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isValueList, bool readByOrder)
void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isValueList, bool readBySoapOrder)
{
XmlTypeMapping typeMap = xmlMap as XmlTypeMapping;
Type xmlMapType = (typeMap != null) ? typeMap.TypeData.Type : typeof(object[]);
Expand Down Expand Up @@ -1636,7 +1636,7 @@ void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isVal
if (!GenerateReadHook (HookType.elements, xmlMapType))
{
string[] readFlag = null;
if (map.ElementMembers != null && !readByOrder)
if (map.ElementMembers != null && !readBySoapOrder)
{
string readFlagsVars = string.Empty;
readFlag = new string[map.ElementMembers.Count];
Expand All @@ -1654,6 +1654,11 @@ void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isVal
readFlagsVars = "bool " + readFlagsVars;
WriteLine (readFlagsVars + ";");
}
foreach (XmlTypeMapElementInfo info in map.AllElementInfos)
if (info.ExplicitOrder >= 0) {
WriteLine ("int idx = -1;");
break;
}
WriteLine ("");
}

Expand Down Expand Up @@ -1715,7 +1720,7 @@ void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isVal
ArrayList infos = null;

int maxInd;
if (readByOrder) {
if (readBySoapOrder) {
if (map.ElementMembers != null) maxInd = map.ElementMembers.Count;
else maxInd = 0;
}
Expand All @@ -1734,13 +1739,15 @@ void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isVal
first = true;
for (int ind = 0; ind < maxInd; ind++)
{
XmlTypeMapElementInfo info = readByOrder ? map.GetElement (ind) : (XmlTypeMapElementInfo) infos [ind];
XmlTypeMapElementInfo info = readBySoapOrder ? map.GetElement (ind) : (XmlTypeMapElementInfo) infos [ind];

if (!readByOrder)
if (!readBySoapOrder)
{
if (info.IsTextElement || info.IsUnnamedAnyElement) continue;
string elemCond = first ? "" : "else ";
elemCond += "if (";
if (info.ExplicitOrder >= 0)
elemCond += "idx < " + info.ExplicitOrder + "&& ";
if (!(info.Member.IsReturnValue && _format == SerializationFormat.Encoded)) {
elemCond += "Reader.LocalName == " + GetLiteral (info.ElementName);
if (!map.IgnoreMemberNamespace) elemCond += " && Reader.NamespaceURI == " + GetLiteral (info.Namespace);
Expand Down Expand Up @@ -1809,7 +1816,7 @@ void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isVal
GenerateEndHook ();
}
}
if (!readByOrder)
if (!readBySoapOrder)
WriteLine (readFlag[info.Member.Index] + " = true;");
}
else if (info.Member.GetType() == typeof (XmlTypeMapMemberFlatList))
Expand Down Expand Up @@ -1843,8 +1850,10 @@ void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isVal
}
else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement))
{
if (!readByOrder)
if (!readBySoapOrder)
WriteLine (readFlag[info.Member.Index] + " = true;");
if (info.ExplicitOrder >= 0)
WriteLine ("idx = " + info.ExplicitOrder + ";");
if (_format == SerializationFormat.Encoded)
{
string val = GetObTempVar ();
Expand Down Expand Up @@ -1875,14 +1884,14 @@ void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isVal
else
throw new InvalidOperationException ("Unknown member type");

if (!readByOrder)
if (!readBySoapOrder)
WriteLineUni ("}");
else
WriteLine ("Reader.MoveToContent();");
first = false;
}

if (!readByOrder)
if (!readBySoapOrder)
{
if (!first) WriteLineInd ("else {");

Expand Down
Expand Up @@ -43,9 +43,7 @@ public class XmlAnyElementAttribute : Attribute
private string elementName;
private string ns;
private bool isNamespaceSpecified;
#if NET_2_0
private int order = -1;
#endif

public XmlAnyElementAttribute ()
{
Expand Down Expand Up @@ -87,13 +85,12 @@ public XmlAnyElementAttribute (string name, string ns)
#if NET_2_0
[MonoTODO]
internal bool IsNullableSpecified { get; set; }
#endif

[MonoTODO]
public int Order {
get { return order; }
set { order = value; }
}
#endif

internal void AddKeyHash (System.Text.StringBuilder sb)
{
Expand Down
Expand Up @@ -92,5 +92,14 @@ internal void AddKeyHash (System.Text.StringBuilder sb)
this[n].AddKeyHash (sb);
sb.Append ('|');
}

internal int Order {
get {
foreach (XmlAnyElementAttribute e in this)
if (e.Order >= 0)
return e.Order;
return -1;
}
}
}
}
Expand Up @@ -44,9 +44,7 @@ public class XmlArrayAttribute : Attribute
private XmlSchemaForm form;
private bool isNullable;
private string ns;
#if NET_2_0
private int order = -1;
#endif

public XmlArrayAttribute()
{
Expand Down Expand Up @@ -100,13 +98,10 @@ public string Namespace
}
}

#if NET_2_0
[MonoTODO]
public int Order {
get { return order; }
set { order = value; }
}
#endif

internal void AddKeyHash (System.Text.StringBuilder sb)
{
Expand Down
13 changes: 13 additions & 0 deletions mcs/class/System.XML/System.Xml.Serialization/XmlAttributes.cs
Expand Up @@ -278,5 +278,18 @@ internal void AddKeyHash (System.Text.StringBuilder sb)

sb.Append ("|");
}

public int Order {
get {
int order = -1;
if (XmlElements != null)
order = XmlElements.Order;
if (order < 0 && XmlArray != null)
order = XmlArray.Order;
if (order < 0 && XmlAnyElements != null)
order = XmlAnyElements.Order;
return order;
}
}
}
}
Expand Up @@ -46,9 +46,7 @@ public class XmlElementAttribute : Attribute
private string ns;
private bool isNullable, isNullableSpecified;
private Type type;
#if NET_2_0
private int order = -1;
#endif

public XmlElementAttribute ()
{
Expand Down Expand Up @@ -119,13 +117,10 @@ public XmlElementAttribute (string elementName, Type type)
get { return isNullableSpecified; }
}

#if NET_2_0
[MonoTODO]
public int Order {
get { return order; }
set { order = value; }
}
#endif

public Type Type {
get {
Expand Down
Expand Up @@ -86,5 +86,14 @@ internal void AddKeyHash (System.Text.StringBuilder sb)
this[n].AddKeyHash (sb);
sb.Append ('|');
}

internal int Order {
get {
foreach (XmlElementAttribute e in this)
if (e.Order >= 0)
return e.Order;
return -1;
}
}
}
}
Expand Up @@ -32,6 +32,7 @@
//

using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Xml.Schema;
Expand Down Expand Up @@ -343,7 +344,18 @@ XmlTypeMapping ImportClassMapping (TypeData typeData, XmlRootAttribute root, str
ClassMap classMap = new ClassMap ();
map.ObjectMap = classMap;

ICollection members = GetReflectionMembers (type);
var members = GetReflectionMembers (type);
bool? isOrderExplicit = null;
foreach (XmlReflectionMember rmember in members)
{
if (isOrderExplicit == null)
isOrderExplicit = rmember.XmlAttributes.Order >= 0;
else if (isOrderExplicit != (rmember.XmlAttributes.Order >= 0))
throw new InvalidOperationException ("Inconsistent XML sequence was detected. If there are XmlElement/XmlArray/XmlAnyElement attributes with explicit Order, then every other member must have an explicit order too.");
}
if (isOrderExplicit == true)
members.Sort ((m1, m2) => m1.XmlAttributes.Order - m2.XmlAttributes.Order);

foreach (XmlReflectionMember rmember in members)
{
string ns = map.XmlTypeNamespace;
Expand Down Expand Up @@ -671,7 +683,7 @@ void ImportIncludedTypes (Type type, string defaultNamespace)
}
}

ICollection GetReflectionMembers (Type type)
List<XmlReflectionMember> GetReflectionMembers (Type type)
{
// First we want to find the inheritance hierarchy in reverse order.
Type currentType = type;
Expand Down Expand Up @@ -739,7 +751,7 @@ ICollection GetReflectionMembers (Type type)
propList.Insert(currentIndex++, prop);
}
#endif
ArrayList members = new ArrayList();
var members = new List<XmlReflectionMember>();
int fieldIndex=0;
int propIndex=0;
// We now step through the type hierarchy from the base (object) through
Expand Down Expand Up @@ -785,7 +797,8 @@ ICollection GetReflectionMembers (Type type)
else break;
}
}
return members;

return members;
}

private XmlTypeMapMember CreateMapMember (Type declaringType, XmlReflectionMember rmember, string defaultNamespace)
Expand Down Expand Up @@ -898,6 +911,7 @@ private XmlTypeMapMember CreateMapMember (Type declaringType, XmlReflectionMembe
elem.MappedType = ImportListMapping (rmember.MemberType, null, elem.Namespace, atts, 0);
elem.IsNullable = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false;
elem.Form = (atts.XmlArray != null) ? atts.XmlArray.Form : XmlSchemaForm.Qualified;
elem.ExplicitOrder = (atts.XmlArray != null) ? atts.XmlArray.Order : -1;
// This is a bit tricky, but is done
// after filling descendant members, so
// that array items could be serialized
Expand Down Expand Up @@ -980,6 +994,7 @@ XmlTypeMapElementInfoList ImportElementInfo (Type cls, string defaultName, strin
if (elem.Form != XmlSchemaForm.Unqualified)
elem.Namespace = (att.Namespace != null) ? att.Namespace : defaultNamespace;
elem.IsNullable = att.IsNullable;
elem.ExplicitOrder = att.Order;

if (elem.IsNullable && !elem.TypeData.IsNullable)
throw new InvalidOperationException ("IsNullable may not be 'true' for value type " + elem.TypeData.FullTypeName + " in member '" + defaultName + "'");
Expand Down Expand Up @@ -1044,6 +1059,7 @@ XmlTypeMapElementInfoList ImportAnyElementInfo (string defaultNamespace, XmlRefl
if (att.Namespace != null)
throw new InvalidOperationException ("The element " + rmember.MemberName + " has been attributed with an XmlAnyElementAttribute and a namespace '" + att.Namespace + "', but no name. When a namespace is supplied, a name is also required. Supply a name or remove the namespace.");
}
elem.ExplicitOrder = att.Order;
list.Add (elem);
}
return list;
Expand Down

0 comments on commit d68521e

Please sign in to comment.