[Mono-devel-list] Patch to mimic MS.Net remoting name mangling
Luke Ravitch
ravitch at nrtc.northrop.com
Mon May 2 15:17:06 EDT 2005
I put together a little patch to improve Mono-MS.Net remoting
compatibility. Basically, MS.Net mangles the names of private
inherited fields for SOAP-serialized objects. I've opened a bug
(#74760) to track the issue...
http://bugs.ximian.com/show_bug.cgi?id=74760
Please see it for a more detailed description of the issue.
Attached here is the patch (also with the bug report). Does it look
reasonable?
Because it looked like it belongs in the same place, I also added
support for the SoapFieldAttribute.XmlFieldName in the serializer.
(The attribute was implemented, but the SOAP serialization stuff
didn't use it.) Of course, that's still only a very partial
implementation of the SoapFieldAttribute stuff.
I wasn't sure where to put the name mangling routine because both
SoapReader and SoapWriter need to use it. So I just picked one and
went with it.
--
Luke Ravitch <ravitch at nrtc.northrop.com> Telephone: 310-864-7478
Software Engr., Advanced Software Sys. | One Hornet Way, MS 9M52/W6
Northrop Grumman Integrated Systems | El Segundo, CA 90245-23804
-------------- next part --------------
Index: mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs
===================================================================
--- mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs (revision 43735)
+++ mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs (working copy)
@@ -391,6 +391,8 @@
// bool specifyEncoding = false;
// if(objectData[i] != null)
// specifyEncoding = (objectData[i].GetType() != fieldInfo.FieldType);
+
+ string name = SoapReader.GetFieldName (fieldInfo, currentType);
_xmlWriter.WriteStartElement(fieldInfo.Name);
SerializeComponent(
objectData[i],
Index: mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs
===================================================================
--- mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs (revision 43735)
+++ mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs (working copy)
@@ -729,7 +729,39 @@
indices);
}
}
-
+
+ // MS.Net uses "_x002B_" in serialization to delimit base class from field name for
+ // private inherited fields (see GetFieldName below). Any instances of "_x002B_"
+ // in the original field name are escaped with "_x005F_", as are any prior instances
+ // of "_x005F_". This function performs that escaping.
+
+ static private string EscapeName (string s)
+ {
+ return (s.Replace ("_x005F_", "_x005F_x005F_")).Replace ("_x002B_", "_x005F_x002B_");
+ }
+
+ static public string GetFieldName (FieldInfo info, Type type)
+ {
+ string name;
+ Type attr_t = typeof (SoapFieldAttribute);
+ SoapFieldAttribute soapAttr = Attribute.GetCustomAttribute (info, attr_t) as SoapFieldAttribute;
+
+ if ((soapAttr != null) && (soapAttr.XmlElementName != null)) {
+ name = EscapeName (soapAttr.XmlElementName);
+ } else {
+ name = EscapeName (info.Name);
+ // To maintain compatibility with MS.Net, we need to mangle the names
+ // of any private inherited members that don't have XmlElementName set
+ // in a SoapFieldAttribute. MS.Net prepends the base class name to
+ // the field name, using "_x002B_" as a delimiter.
+ if (info.IsPrivate && (info.DeclaringType != type)) {
+ name = EscapeName (info.DeclaringType.Name) + "_x002B_" + name;
+ }
+ }
+
+ return name;
+ }
+
TypeMetadata GetTypeMetadata (Type type)
{
TypeMetadata tm = _fieldIndices[type] as TypeMetadata;
@@ -738,10 +770,14 @@
tm = new TypeMetadata ();
tm.MemberInfos = FormatterServices.GetSerializableMembers (type, _context);
- tm.Indices = new Hashtable();
- for(int i = 0; i < tm.MemberInfos.Length; i++)
- tm.Indices.Add (tm.MemberInfos[i].Name, i);
-
+ tm.Indices = new Hashtable();
+ for (int i = 0; i < tm.MemberInfos.Length; i++) {
+ // Only fields should be serializable, so this should never be null.
+ FieldInfo fieldInfo = tm.MemberInfos[i] as FieldInfo;
+
+ tm.Indices.Add (GetFieldName (fieldInfo, type), i);
+ }
+
_fieldIndices[type] = tm;
return tm;
}
More information about the Mono-devel-list
mailing list