2 // System.Xml.Serialization.SerializationCodeGenerator.cs:
5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // (C) 2002, 2003 Ximian, Inc. http://www.ximian.com
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System
.Reflection
;
33 using System
.Xml
.Serialization
;
34 using System
.Collections
;
35 using System
.Globalization
;
37 namespace System
.Xml
.Serialization
39 internal class SerializationCodeGenerator
42 SerializationFormat _format
;
46 Hashtable _uniqueNames
= new Hashtable();
48 SerializerInfo _config
;
49 ArrayList _mapsToGenerate
= new ArrayList ();
50 ArrayList _fixupCallbacks
;
51 ArrayList _referencedTypes
= new ArrayList ();
52 GenerationResult
[] _results
;
53 GenerationResult _result
;
54 XmlMapping
[] _xmlMaps
;
56 CodeIdentifiers classNames
= new CodeIdentifiers ();
58 public SerializationCodeGenerator (XmlMapping
[] xmlMaps
): this (xmlMaps
, null)
62 public SerializationCodeGenerator (XmlMapping
[] xmlMaps
, SerializerInfo config
)
68 public SerializationCodeGenerator (XmlMapping xmlMap
, SerializerInfo config
)
70 _xmlMaps
= new XmlMapping
[] {xmlMap}
;
74 public static void Generate (string configFileName
, string outputPath
)
76 SerializationCodeGeneratorConfiguration cnf
= null;
77 StreamReader sr
= new StreamReader (configFileName
);
80 XmlReflectionImporter ri
= new XmlReflectionImporter ();
81 ri
.AllowPrivateTypes
= true;
82 XmlSerializer ser
= new XmlSerializer (ri
.ImportTypeMapping (typeof (SerializationCodeGeneratorConfiguration
)));
83 cnf
= (SerializationCodeGeneratorConfiguration
) ser
.Deserialize (sr
);
90 if (outputPath
== null) outputPath
= "";
92 CodeIdentifiers ids
= new CodeIdentifiers ();
93 if (cnf
.Serializers
!= null)
95 foreach (SerializerInfo info
in cnf
.Serializers
)
98 if (info
.Assembly
!= null)
102 asm
= Assembly
.Load (info
.Assembly
);
104 asm
= Assembly
.LoadFrom (info
.Assembly
);
106 type
= asm
.GetType (info
.ClassName
, true);
109 type
= Type
.GetType (info
.ClassName
);
111 if (type
== null) throw new InvalidOperationException ("Type " + info
.ClassName
+ " not found");
113 string file
= info
.OutFileName
;
114 if (file
== null || file
== "") {
115 int i
= info
.ClassName
.LastIndexOf (".");
116 if (i
!= -1) file
= info
.ClassName
.Substring (i
+1);
117 else file
= info
.ClassName
;
118 file
= ids
.AddUnique (file
, type
) + "Serializer.cs";
120 StreamWriter writer
= new StreamWriter (Path
.Combine (outputPath
, file
));
126 if (info
.SerializationFormat
== SerializationFormat
.Literal
) {
127 XmlReflectionImporter ri
= new XmlReflectionImporter ();
128 map
= ri
.ImportTypeMapping (type
);
131 SoapReflectionImporter ri
= new SoapReflectionImporter ();
132 map
= ri
.ImportTypeMapping (type
);
135 SerializationCodeGenerator gen
= new SerializationCodeGenerator (map
, info
);
136 gen
.GenerateSerializers (writer
);
146 public void GenerateSerializers (TextWriter writer
)
149 _results
= new GenerationResult
[_xmlMaps
.Length
];
151 WriteLine ("using System;");
152 WriteLine ("using System.Xml;");
153 WriteLine ("using System.Xml.Schema;");
154 WriteLine ("using System.Xml.Serialization;");
155 WriteLine ("using System.Text;");
156 WriteLine ("using System.Collections;");
157 WriteLine ("using System.Globalization;");
158 if (_config
!= null && _config
.NamespaceImports
!= null && _config
.NamespaceImports
.Length
> 0) {
159 foreach (string ns
in _config
.NamespaceImports
)
160 WriteLine ("using " + ns
+ ";");
164 string readerClassName
= null;
165 string writerClassName
= null;
166 string namspace
= null;
170 readerClassName
= _config
.ReaderClassName
;
171 writerClassName
= _config
.WriterClassName
;
172 namspace
= _config
.Namespace
;
175 if (readerClassName
== null || readerClassName
== "")
176 readerClassName
= "GeneratedReader";
178 if (writerClassName
== null || writerClassName
== "")
179 writerClassName
= "GeneratedWriter";
181 readerClassName
= GetUniqueClassName (readerClassName
);
182 writerClassName
= GetUniqueClassName (writerClassName
);
184 Hashtable mapsByNamespace
= new Hashtable ();
185 Hashtable generatedMaps
= new Hashtable ();
187 for (int n
=0; n
<_xmlMaps
.Length
; n
++)
189 _typeMap
= _xmlMaps
[n
];
190 if (_typeMap
== null) continue;
192 _result
= generatedMaps
[_typeMap
] as GenerationResult
;
193 if (_result
!= null) {
194 _results
[n
] = _result
;
198 _result
= new GenerationResult ();
199 _results
[n
] = _result
;
201 generatedMaps
[_typeMap
] = _result
;
204 if (_typeMap
is XmlTypeMapping
) typeName
= ((XmlTypeMapping
)_typeMap
).TypeName
;
205 else typeName
= ((XmlMembersMapping
)_typeMap
).ElementName
;
207 _result
.ReaderClassName
= readerClassName
;
208 _result
.WriterClassName
= writerClassName
;
210 if (namspace
== null || namspace
== "")
211 _result
.Namespace
= "Mono.GeneratedSerializers." + _typeMap
.Format
;
213 _result
.Namespace
= namspace
;
215 _result
.WriteMethodName
= GetUniqueName ("rwo", _typeMap
, "WriteRoot_" + typeName
);
216 _result
.ReadMethodName
= GetUniqueName ("rro", _typeMap
, "ReadRoot_" + typeName
);
218 _result
.Mapping
= _typeMap
;
220 ArrayList maps
= (ArrayList
) mapsByNamespace
[_result
.Namespace
];
222 maps
= new ArrayList ();
223 mapsByNamespace
[_result
.Namespace
] = maps
;
228 foreach (DictionaryEntry entry
in mapsByNamespace
)
230 ArrayList maps
= (ArrayList
) entry
.Value
;
232 WriteLine ("namespace " + entry
.Key
);
235 GenerateReader (readerClassName
, maps
);
237 GenerateWriter (writerClassName
, maps
);
241 GenerateContract (maps
);
249 public GenerationResult
[] GenerationResults
251 get { return _results; }
254 public ArrayList ReferencedTypes
256 get { return _referencedTypes; }
259 void UpdateGeneratedTypes (ArrayList list
)
261 for (int n
=0; n
<list
.Count
; n
++)
263 XmlTypeMapping map
= list
[n
] as XmlTypeMapping
;
264 if (map
!= null && !_referencedTypes
.Contains (map
.TypeData
.Type
))
265 _referencedTypes
.Add (map
.TypeData
.Type
);
269 #region Writer Generation
271 //*******************************************************
272 // Contract generation
276 public void GenerateContract (ArrayList generatedMaps
)
278 // Write the base serializer
280 if (generatedMaps
.Count
== 0) return;
282 GenerationResult main
= (GenerationResult
) generatedMaps
[0];
284 string baseSerializerName
= GetUniqueClassName ("BaseXmlSerializer");
287 WriteLine ("public class " + baseSerializerName
+ " : System.Xml.Serialization.XmlSerializer");
289 WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationReader CreateReader () {");
290 WriteLine ("return new " + main
.ReaderClassName
+ " ();");
294 WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationWriter CreateWriter () {");
295 WriteLine ("return new " + main
.WriterClassName
+ " ();");
299 WriteLineInd ("public override bool CanDeserialize (System.Xml.XmlReader xmlReader) {");
300 WriteLine ("return true;");
306 // Write a serializer for each imported map
308 foreach (GenerationResult res
in generatedMaps
)
310 res
.SerializerClassName
= GetUniqueClassName (res
.Mapping
.ElementName
+ "Serializer");
312 WriteLine ("public sealed class " + res
.SerializerClassName
+ " : " + baseSerializerName
);
314 WriteLineInd ("protected override void Serialize (object obj, System.Xml.Serialization.XmlSerializationWriter writer) {");
315 WriteLine ("((" + res
.WriterClassName
+ ")writer)." + res
.WriteMethodName
+ "(obj);");
319 WriteLineInd ("protected override object Deserialize (System.Xml.Serialization.XmlSerializationReader reader) {");
320 WriteLine ("return ((" + res
.ReaderClassName
+ ")reader)." + res
.ReadMethodName
+ "();");
327 WriteLine ("public class XmlSerializerContract : System.Xml.Serialization.IXmlSerializerImplementation");
330 WriteLine ("System.Collections.Hashtable readMethods = null;");
331 WriteLine ("System.Collections.Hashtable writeMethods = null;");
332 WriteLine ("System.Collections.Hashtable typedSerializers = null;");
335 WriteLineInd ("public System.Xml.Serialization.XmlSerializationReader Reader {");
336 WriteLineInd ("get {");
337 WriteLine ("return new " + main
.ReaderClassName
+ "();");
342 WriteLineInd ("public System.Xml.Serialization.XmlSerializationWriter Writer {");
343 WriteLineInd ("get {");
344 WriteLine ("return new " + main
.WriterClassName
+ "();");
349 WriteLineInd ("public System.Collections.Hashtable ReadMethods {");
350 WriteLineInd ("get {");
351 WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
352 WriteLineInd ("if (readMethods == null) {");
353 WriteLine ("readMethods = new System.Collections.Hashtable ();");
354 foreach (GenerationResult res
in generatedMaps
)
355 WriteLine ("readMethods.Add (@\"" + res
.Mapping
.GetKey () + "\", @\"" + res
.ReadMethodName
+ "\");");
357 WriteLine ("return readMethods;");
363 WriteLineInd ("public System.Collections.Hashtable WriteMethods {");
364 WriteLineInd ("get {");
365 WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
366 WriteLineInd ("if (writeMethods == null) {");
367 WriteLine ("writeMethods = new System.Collections.Hashtable ();");
368 foreach (GenerationResult res
in generatedMaps
)
369 WriteLine ("writeMethods.Add (@\"" + res
.Mapping
.GetKey () + "\", @\"" + res
.WriteMethodName
+ "\");");
371 WriteLine ("return writeMethods;");
377 WriteLineInd ("public System.Collections.Hashtable TypedSerializers {");
378 WriteLineInd ("get {");
379 WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
380 WriteLineInd ("if (typedSerializers == null) {");
381 WriteLine ("typedSerializers = new System.Collections.Hashtable ();");
382 foreach (GenerationResult res
in generatedMaps
)
383 WriteLine ("typedSerializers.Add (@\"" + res
.Mapping
.GetKey () + "\", new " + res
.SerializerClassName
+ "());");
385 WriteLine ("return typedSerializers;");
390 WriteLineInd ("public bool CanSerialize (System.Type type) {");
391 foreach (GenerationResult res
in generatedMaps
) {
392 if (res
.Mapping
is XmlTypeMapping
)
393 WriteLine ("if (type == typeof(" + (res
.Mapping
as XmlTypeMapping
).TypeData
.FullTypeName
+ ")) return true;");
395 WriteLine ("return false;");
404 //*******************************************************
408 public void GenerateWriter (string writerClassName
, ArrayList maps
)
410 _mapsToGenerate
= new ArrayList ();
414 WriteLine ("public class " + writerClassName
+ " : XmlSerializationWriter");
417 for (int n
=0; n
<maps
.Count
; n
++)
419 GenerationResult res
= (GenerationResult
) maps
[n
];
420 _typeMap
= res
.Mapping
;
421 _format
= _typeMap
.Format
;
424 GenerateWriteRoot ();
427 for (int n
=0; n
<_mapsToGenerate
.Count
; n
++)
429 XmlTypeMapping map
= (XmlTypeMapping
) _mapsToGenerate
[n
];
430 GenerateWriteObject (map
);
431 if (map
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
432 GenerateGetXmlEnumValue (map
);
435 GenerateWriteInitCallbacks ();
436 UpdateGeneratedTypes (_mapsToGenerate
);
441 void GenerateWriteRoot ()
443 WriteLine ("public void " +_result
.WriteMethodName
+ " (object o)");
445 WriteLine ("WriteStartDocument ();");
447 if (_typeMap
is XmlTypeMapping
)
449 WriteLine (GetRootTypeName () + " ob = (" + GetRootTypeName () + ") o;");
450 XmlTypeMapping mp
= (XmlTypeMapping
) _typeMap
;
451 if (mp
.TypeData
.SchemaType
== SchemaTypes
.Class
|| mp
.TypeData
.SchemaType
== SchemaTypes
.Array
)
452 WriteLine ("TopLevelElement ();");
454 if (_format
== SerializationFormat
.Literal
) {
455 WriteLine (GetWriteObjectName (mp
) + " (ob, " + GetLiteral(mp
.ElementName
) + ", " + GetLiteral(mp
.Namespace
) + ", true, false, true);");
458 RegisterReferencingMap (mp
);
459 WriteLine ("WritePotentiallyReferencingElement (" + GetLiteral(mp
.ElementName
) + ", " + GetLiteral(mp
.Namespace
) + ", ob, " + GetTypeOf(mp
.TypeData
) + ", true, false);");
462 else if (_typeMap
is XmlMembersMapping
) {
463 WriteLine ("object[] pars = (object[]) o;");
464 GenerateWriteMessage ((XmlMembersMapping
) _typeMap
);
467 throw new InvalidOperationException ("Unknown type map");
469 if (_format
== SerializationFormat
.Encoded
)
470 WriteLine ("WriteReferencedElements ();");
476 void GenerateWriteMessage (XmlMembersMapping membersMap
)
478 if (membersMap
.HasWrapperElement
) {
479 WriteLine ("TopLevelElement ();");
480 WriteLine ("WriteStartElement (" + GetLiteral (membersMap
.ElementName
) + ", " + GetLiteral (membersMap
.Namespace
) + ", (" + GetLiteral(_format
== SerializationFormat
.Encoded
) + "));");
482 /* WriteLineInd ("if (Writer.LookupPrefix (XmlSchema.Namespace) == null)");
483 WriteLine ("WriteAttribute (\"xmlns\",\"xsd\",XmlSchema.Namespace,XmlSchema.Namespace);");
486 WriteLineInd ("if (Writer.LookupPrefix (XmlSchema.InstanceNamespace) == null)");
487 WriteLine ("WriteAttribute (\"xmlns\",\"xsi\",XmlSchema.InstanceNamespace,XmlSchema.InstanceNamespace);");
492 GenerateWriteObjectElement (membersMap
, "pars", true);
494 if (membersMap
.HasWrapperElement
)
495 WriteLine ("WriteEndElement();");
498 void GenerateGetXmlEnumValue (XmlTypeMapping map
)
500 EnumMap emap
= (EnumMap
) map
.ObjectMap
;
502 WriteLine ("string " + GetGetEnumValueName (map
) + " (" + map
.TypeFullName
+ " val)");
505 WriteLine ("switch (val)");
507 foreach (EnumMap
.EnumMapMember mem
in emap
.Members
)
508 WriteLine ("case " + map
.TypeFullName
+ "." + mem
.EnumName
+ ": return " + GetLiteral (mem
.XmlName
) + ";");
512 WriteLineInd ("default:");
513 WriteLine ("System.Text.StringBuilder sb = new System.Text.StringBuilder ();");
514 WriteLine ("string[] enumNames = val.ToString().Split (',');");
515 WriteLine ("foreach (string name in enumNames)");
517 WriteLine ("switch (name.Trim())");
520 foreach (EnumMap
.EnumMapMember mem
in emap
.Members
)
521 WriteLine ("case " + GetLiteral(mem
.EnumName
) + ": sb.Append (" + GetLiteral(mem
.XmlName
) + ").Append (' '); break; ");
523 WriteLine ("default: sb.Append (name.Trim()).Append (' '); break; ");
526 WriteLine ("return sb.ToString ().Trim();");
530 WriteLine ("default: return ((long)val).ToString(CultureInfo.InvariantCulture);");
538 void GenerateWriteObject (XmlTypeMapping typeMap
)
540 WriteLine ("void " + GetWriteObjectName (typeMap
) + " (" + typeMap
.TypeFullName
+ " ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)");
545 SetHookVar ("$TYPE", typeMap
.TypeName
);
546 SetHookVar ("$FULLTYPE", typeMap
.TypeFullName
);
547 SetHookVar ("$OBJECT", "ob");
548 SetHookVar ("$ELEMENT", "element");
549 SetHookVar ("$NAMESPACE", "namesp");
550 SetHookVar ("$NULLABLE", "isNullable");
552 if (GenerateWriteHook (HookType
.type
, typeMap
.TypeData
.Type
))
560 if (!typeMap
.TypeData
.IsValueType
)
562 WriteLine ("if (ob == null)");
564 WriteLineInd ("if (isNullable)");
566 if (_format
== SerializationFormat
.Literal
)
567 WriteLine ("WriteNullTagLiteral(element, namesp);");
569 WriteLine ("WriteNullTagEncoded (element, namesp);");
571 WriteLineUni ("return;");
576 if (typeMap
.TypeData
.SchemaType
== SchemaTypes
.XmlNode
)
578 if (_format
== SerializationFormat
.Literal
)
579 WriteLine ("WriteElementLiteral (ob, \"\", \"\", true, false);");
581 WriteLine ("WriteElementEncoded (ob, \"\", \"\", true, false);");
590 if (typeMap
.TypeData
.SchemaType
== SchemaTypes
.XmlSerializable
)
592 WriteLine ("WriteSerializable (ob, element, namesp, isNullable);");
601 ArrayList types
= typeMap
.DerivedTypes
;
603 WriteLine ("System.Type type = ob.GetType ();");
604 WriteLine ("if (type == typeof(" + typeMap
.TypeFullName
+ "))");
607 for (int n
=0; n
<types
.Count
; n
++)
609 XmlTypeMapping map
= (XmlTypeMapping
)types
[n
];
611 WriteLineInd ("else if (type == typeof(" + map
.TypeFullName
+ ")) { ");
612 WriteLine (GetWriteObjectName (map
) + "((" + map
.TypeFullName
+ ")ob, element, namesp, isNullable, true, writeWrappingElem);");
613 WriteLine ("return;");
617 if (typeMap
.TypeData
.Type
== typeof (object)) {
618 WriteLineInd ("else {");
619 WriteLine ("WriteTypedPrimitive (element, namesp, ob, true);");
620 WriteLine ("return;");
625 WriteLineInd ("else {");
626 WriteLine ("throw CreateUnknownTypeException (ob);");
630 WriteLineInd ("if (writeWrappingElem) {");
631 if (_format
== SerializationFormat
.Encoded
) WriteLine ("needType = true;");
632 WriteLine ("WriteStartElement (element, namesp, ob);");
636 WriteLine ("if (needType) WriteXsiType(" + GetLiteral(typeMap
.XmlType
) + ", " + GetLiteral(typeMap
.XmlTypeNamespace
) + ");");
639 switch (typeMap
.TypeData
.SchemaType
)
641 case SchemaTypes
.Class
: GenerateWriteObjectElement (typeMap
, "ob", false); break;
642 case SchemaTypes
.Array
: GenerateWriteListElement (typeMap
, "ob"); break;
643 case SchemaTypes
.Primitive
: GenerateWritePrimitiveElement (typeMap
, "ob"); break;
644 case SchemaTypes
.Enum
: GenerateWriteEnumElement (typeMap
, "ob"); break;
647 WriteLine ("if (writeWrappingElem) WriteEndElement (ob);");
656 void GenerateWriteObjectElement (XmlMapping xmlMap
, string ob
, bool isValueList
)
658 XmlTypeMapping typeMap
= xmlMap
as XmlTypeMapping
;
659 Type xmlMapType
= (typeMap
!= null) ? typeMap
.TypeData
.Type
: typeof(object[]);
661 ClassMap map
= (ClassMap
)xmlMap
.ObjectMap
;
662 if (!GenerateWriteHook (HookType
.attributes
, xmlMapType
))
664 if (map
.NamespaceDeclarations
!= null) {
665 WriteLine ("WriteNamespaceDeclarations ((XmlSerializerNamespaces) " + ob
+ ".@" + map
.NamespaceDeclarations
.Name
+ ");");
669 ICollection attributes
= map
.AttributeMembers
;
670 if (attributes
!= null)
672 foreach (XmlTypeMapMemberAttribute attr
in attributes
)
674 if (GenerateWriteMemberHook (xmlMapType
, attr
)) continue;
676 string val
= GenerateGetMemberValue (attr
, ob
, isValueList
);
677 string cond
= GenerateMemberHasValueCondition (attr
, ob
, isValueList
);
679 if (cond
!= null) WriteLineInd ("if (" + cond
+ ") {");
681 string strVal
= GenerateGetStringValue (attr
.MappedType
, attr
.TypeData
, val
);
682 WriteLine ("WriteAttribute (" + GetLiteral(attr
.AttributeName
) + ", " + GetLiteral(attr
.Namespace
) + ", " + strVal
+ ");");
684 if (cond
!= null) WriteLineUni ("}");
690 XmlTypeMapMember anyAttrMember
= map
.DefaultAnyAttributeMember
;
691 if (anyAttrMember
!= null)
693 if (!GenerateWriteMemberHook (xmlMapType
, anyAttrMember
))
695 string cond
= GenerateMemberHasValueCondition (anyAttrMember
, ob
, isValueList
);
696 if (cond
!= null) WriteLineInd ("if (" + cond
+ ") {");
698 string tmpVar
= GetObTempVar ();
699 WriteLine ("ICollection " + tmpVar
+ " = " + GenerateGetMemberValue (anyAttrMember
, ob
, isValueList
) + ";");
700 WriteLineInd ("if (" + tmpVar
+ " != null) {");
702 string tmpVar2
= GetObTempVar ();
703 WriteLineInd ("foreach (XmlAttribute " + tmpVar2
+ " in " + tmpVar
+ ")");
704 WriteLine ("WriteXmlAttribute (" + tmpVar2
+ ", " + ob
+ ");");
708 if (cond
!= null) WriteLineUni ("}");
716 if (!GenerateWriteHook (HookType
.elements
, xmlMapType
))
718 ICollection members
= map
.ElementMembers
;
721 foreach (XmlTypeMapMemberElement member
in members
)
723 if (GenerateWriteMemberHook (xmlMapType
, member
)) continue;
725 string cond
= GenerateMemberHasValueCondition (member
, ob
, isValueList
);
726 if (cond
!= null) WriteLineInd ("if (" + cond
+ ") {");
728 string memberValue
= GenerateGetMemberValue (member
, ob
, isValueList
);
729 Type memType
= member
.GetType();
731 if (memType
== typeof(XmlTypeMapMemberList
))
733 GenerateWriteMemberElement ((XmlTypeMapElementInfo
) member
.ElementInfo
[0], memberValue
);
735 else if (memType
== typeof(XmlTypeMapMemberFlatList
))
737 WriteLineInd ("if (" + memberValue
+ " != null) {");
738 GenerateWriteListContent (member
.TypeData
, ((XmlTypeMapMemberFlatList
)member
).ListMap
, memberValue
, false);
741 else if (memType
== typeof(XmlTypeMapMemberAnyElement
))
743 WriteLineInd ("if (" + memberValue
+ " != null) {");
744 GenerateWriteAnyElementContent ((XmlTypeMapMemberAnyElement
)member
, memberValue
);
747 else if (memType
== typeof(XmlTypeMapMemberAnyElement
))
749 WriteLineInd ("if (" + memberValue
+ " != null) {");
750 GenerateWriteAnyElementContent ((XmlTypeMapMemberAnyElement
)member
, memberValue
);
753 else if (memType
== typeof(XmlTypeMapMemberAnyAttribute
))
757 else if (memType
== typeof(XmlTypeMapMemberElement
))
759 if (member
.ElementInfo
.Count
== 1) {
760 GenerateWriteMemberElement ((XmlTypeMapElementInfo
)member
.ElementInfo
[0], memberValue
);
762 else if (member
.ChoiceMember
!= null)
764 string choiceValue
= ob
+ ".@" + member
.ChoiceMember
;
765 foreach (XmlTypeMapElementInfo elem
in member
.ElementInfo
) {
766 WriteLineInd ("if (" + choiceValue
+ " == " + GetLiteral(elem
.ChoiceValue
) + ") {");
767 GenerateWriteMemberElement (elem
, GetCast(elem
.TypeData
, member
.TypeData
, memberValue
));
773 // WriteLineInd ("if (" + memberValue + " == null) {");
774 // GenerateWriteMemberElement ((XmlTypeMapElementInfo)member.ElementInfo[0], memberValue);
775 // WriteLineUni ("}");
778 Type type
= memberValue
.GetType();
779 foreach (XmlTypeMapElementInfo elem
in member
.ElementInfo
)
781 WriteLineInd ((first
?"":"else ") + "if (" + memberValue
+ " is " + elem
.TypeData
.FullTypeName
+ ") {");
782 GenerateWriteMemberElement (elem
, GetCast(elem
.TypeData
, member
.TypeData
, memberValue
));
789 throw new InvalidOperationException ("Unknown member type");
801 void GenerateWriteMemberElement (XmlTypeMapElementInfo elem
, string memberValue
)
803 switch (elem
.TypeData
.SchemaType
)
805 case SchemaTypes
.XmlNode
:
806 string elemName
= elem
.WrappedElement
? elem
.ElementName
: "";
807 if (_format
== SerializationFormat
.Literal
)
808 WriteMetCall ("WriteElementLiteral", memberValue
, GetLiteral(elemName
), GetLiteral(elem
.Namespace
), GetLiteral(elem
.IsNullable
), "false");
810 WriteMetCall ("WriteElementEncoded", memberValue
, GetLiteral(elemName
), GetLiteral(elem
.Namespace
), GetLiteral(elem
.IsNullable
), "false");
813 case SchemaTypes
.Enum
:
814 case SchemaTypes
.Primitive
:
815 if (_format
== SerializationFormat
.Literal
)
816 GenerateWritePrimitiveValueLiteral (memberValue
, elem
.ElementName
, elem
.Namespace
, elem
.MappedType
, elem
.TypeData
, elem
.WrappedElement
, elem
.IsNullable
);
818 GenerateWritePrimitiveValueEncoded (memberValue
, elem
.ElementName
, elem
.Namespace
, new XmlQualifiedName (elem
.TypeData
.XmlType
, elem
.DataTypeNamespace
), elem
.MappedType
, elem
.TypeData
, elem
.WrappedElement
, elem
.IsNullable
);
821 case SchemaTypes
.Array
:
822 WriteLineInd ("if (" + memberValue
+ " != null) {");
824 if (elem
.MappedType
.MultiReferenceType
) {
825 WriteMetCall ("WriteReferencingElement", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), memberValue
, GetLiteral(elem
.IsNullable
));
826 RegisterReferencingMap (elem
.MappedType
);
829 WriteMetCall ("WriteStartElement", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), memberValue
);
830 GenerateWriteListContent (elem
.TypeData
, (ListMap
) elem
.MappedType
.ObjectMap
, memberValue
, false);
831 WriteMetCall ("WriteEndElement", memberValue
);
835 if (elem
.IsNullable
) {
836 WriteLineInd ("else");
837 if (_format
== SerializationFormat
.Literal
)
838 WriteMetCall ("WriteNullTagLiteral", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
));
840 WriteMetCall ("WriteNullTagEncoded", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
));
846 case SchemaTypes
.Class
:
847 if (elem
.MappedType
.MultiReferenceType
) {
848 RegisterReferencingMap (elem
.MappedType
);
849 if (elem
.MappedType
.TypeData
.Type
== typeof(object))
850 WriteMetCall ("WritePotentiallyReferencingElement", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), memberValue
, "null", "false", GetLiteral(elem
.IsNullable
));
852 WriteMetCall ("WriteReferencingElement", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), memberValue
, GetLiteral(elem
.IsNullable
));
855 WriteMetCall (GetWriteObjectName(elem
.MappedType
), memberValue
, GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), GetLiteral(elem
.IsNullable
), "false", "true");
858 case SchemaTypes
.XmlSerializable
:
859 WriteMetCall ("WriteSerializable", memberValue
, GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), GetLiteral(elem
.IsNullable
));
863 throw new NotSupportedException ("Invalid value type");
867 void GenerateWriteListElement (XmlTypeMapping typeMap
, string ob
)
869 if (_format
== SerializationFormat
.Encoded
)
872 string itemCount
= GenerateGetListCount (typeMap
.TypeData
, ob
);
873 GenerateGetArrayType ((ListMap
) typeMap
.ObjectMap
, itemCount
, out n
, out ns
);
876 if (ns
!= string.Empty
)
877 arrayType
= "FromXmlQualifiedName (new XmlQualifiedName(" + n
+ "," + ns
+ "))";
879 arrayType
= GetLiteral (n
);
881 WriteMetCall ("WriteAttribute", GetLiteral("arrayType"), GetLiteral(XmlSerializer
.EncodingNamespace
), arrayType
);
883 GenerateWriteListContent (typeMap
.TypeData
, (ListMap
) typeMap
.ObjectMap
, ob
, false);
886 void GenerateWriteAnyElementContent (XmlTypeMapMemberAnyElement member
, string memberValue
)
888 bool singleElement
= (member
.TypeData
.Type
== typeof (XmlElement
));
894 var = GetObTempVar ();
895 WriteLineInd ("foreach (XmlNode " + var + " in " + memberValue
+ ") {");
898 string elem
= GetObTempVar ();
899 WriteLine ("XmlElement " + elem
+ " = " + var + " as XmlElement;");
900 WriteLine ("if (" + elem
+ " == null) throw CreateUnknownTypeException (" + elem
+ ");");
902 if (!member
.IsDefaultAny
) {
903 for (int n
=0; n
<member
.ElementInfo
.Count
; n
++) {
904 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
)member
.ElementInfo
[n
];
905 string txt
= "(" + elem
+ ".Name == " + GetLiteral(info
.ElementName
) + " && " + elem
+ ".NamespaceURI == " + GetLiteral(info
.Namespace
) + ")";
906 if (n
== member
.ElementInfo
.Count
-1) txt
+= ") {";
907 if (n
== 0) WriteLineInd ("if (" + txt
);
908 else WriteLine ("|| " + txt
);
912 if (_format
== SerializationFormat
.Literal
)
913 WriteLine ("WriteElementLiteral (" + elem
+ ", \"\", \"\", false, true);");
915 WriteLine ("WriteElementEncoded (" + elem
+ ", \"\", \"\", false, true);");
917 if (!member
.IsDefaultAny
) {
919 WriteLineInd ("else");
920 WriteLine ("throw CreateUnknownAnyElementException (" + elem
+ ".Name, " + elem
+ ".NamespaceURI);");
928 void GenerateWritePrimitiveElement (XmlTypeMapping typeMap
, string ob
)
930 string strVal
= GenerateGetStringValue (typeMap
, typeMap
.TypeData
, ob
);
931 WriteLine ("Writer.WriteString (" + strVal
+ ");");
934 void GenerateWriteEnumElement (XmlTypeMapping typeMap
, string ob
)
936 string strVal
= GenerateGetEnumXmlValue (typeMap
, ob
);
937 WriteLine ("Writer.WriteString (" + strVal
+ ");");
940 string GenerateGetStringValue (XmlTypeMapping typeMap
, TypeData type
, string value)
942 if (type
.SchemaType
== SchemaTypes
.Array
) {
943 string str
= GetStrTempVar ();
944 WriteLine ("string " + str
+ " = null;");
945 WriteLineInd ("if (" + value + " != null) {");
946 string res
= GenerateWriteListContent (typeMap
.TypeData
, (ListMap
)typeMap
.ObjectMap
, value, true);
947 WriteLine (str
+ " = " + res
+ ".ToString ().Trim ();");
951 else if (type
.SchemaType
== SchemaTypes
.Enum
) {
952 return GenerateGetEnumXmlValue (typeMap
, value);
954 else if (type
.Type
== typeof (XmlQualifiedName
))
955 return "FromXmlQualifiedName (" + value + ")";
956 else if (value == null)
959 return XmlCustomFormatter
.GenerateToXmlString (type
, value);
962 string GenerateGetEnumXmlValue (XmlTypeMapping typeMap
, string ob
)
964 return GetGetEnumValueName (typeMap
) + " (" + ob
+ ")";
967 string GenerateGetListCount (TypeData listType
, string ob
)
969 if (listType
.Type
.IsArray
)
975 void GenerateGetArrayType (ListMap map
, string itemCount
, out string localName
, out string ns
)
978 if (itemCount
!= "") arrayDim
= "";
979 else arrayDim
= "[]";
981 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
) map
.ItemInfo
[0];
982 if (info
.TypeData
.SchemaType
== SchemaTypes
.Array
)
985 GenerateGetArrayType ((ListMap
)info
.MappedType
.ObjectMap
, "", out nm
, out ns
);
986 localName
= nm
+ arrayDim
;
990 if (info
.MappedType
!= null)
992 localName
= info
.MappedType
.XmlType
+ arrayDim
;
993 ns
= info
.MappedType
.Namespace
;
997 localName
= info
.TypeData
.XmlType
+ arrayDim
;
998 ns
= info
.DataTypeNamespace
;
1001 if (itemCount
!= "") {
1002 localName
= "\"" + localName
+ "[\" + " + itemCount
+ " + \"]\"";
1003 ns
= GetLiteral (ns
);
1007 string GenerateWriteListContent (TypeData listType
, ListMap map
, string ob
, bool writeToString
)
1009 string targetString
= null;
1013 targetString
= GetStrTempVar ();
1014 WriteLine ("System.Text.StringBuilder " + targetString
+ " = new System.Text.StringBuilder();");
1017 if (listType
.Type
.IsArray
)
1019 string itemVar
= GetNumTempVar ();
1020 WriteLineInd ("for (int "+itemVar
+" = 0; "+itemVar
+" < " + ob
+ ".Length; "+itemVar
+"++) {");
1021 GenerateListLoop (map
, ob
+ "["+itemVar
+"]", listType
.ListItemTypeData
, targetString
);
1024 else if (typeof(ICollection
).IsAssignableFrom (listType
.Type
))
1026 string itemVar
= GetNumTempVar ();
1027 WriteLineInd ("for (int "+itemVar
+" = 0; "+itemVar
+" < " + ob
+ ".Count; "+itemVar
+"++) {");
1028 GenerateListLoop (map
, ob
+ "["+itemVar
+"]", listType
.ListItemTypeData
, targetString
);
1031 else if (typeof(IEnumerable
).IsAssignableFrom (listType
.Type
))
1033 string itemVar
= GetObTempVar ();
1034 WriteLineInd ("foreach (" + listType
.ListItemTypeData
.FullTypeName
+ " " + itemVar
+ " in " + ob
+ ") {");
1035 GenerateListLoop (map
, itemVar
, listType
.ListItemTypeData
, targetString
);
1039 throw new Exception ("Unsupported collection type");
1041 return targetString
;
1044 void GenerateListLoop (ListMap map
, string item
, TypeData itemTypeData
, string targetString
)
1046 bool multichoice
= (map
.ItemInfo
.Count
> 1);
1049 WriteLine ("if (" + item
+ " == null) { }");
1051 foreach (XmlTypeMapElementInfo info
in map
.ItemInfo
)
1054 WriteLineInd ("else if (" + item
+ ".GetType() == typeof(" + info
.TypeData
.FullTypeName
+ ")) {");
1056 if (targetString
== null)
1057 GenerateWriteMemberElement (info
, GetCast (info
.TypeData
, itemTypeData
, item
));
1060 string strVal
= GenerateGetStringValue (info
.MappedType
, info
.TypeData
, GetCast (info
.TypeData
, itemTypeData
, item
));
1061 WriteLine (targetString
+ ".Append (" + strVal
+ ").Append (\" \");");
1069 WriteLine ("else throw CreateUnknownTypeException (" + item
+ ");");
1072 void GenerateWritePrimitiveValueLiteral (string memberValue
, string name
, string ns
, XmlTypeMapping mappedType
, TypeData typeData
, bool wrapped
, bool isNullable
)
1075 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
);
1076 WriteMetCall ("WriteValue", strVal
);
1078 else if (isNullable
) {
1079 if (typeData
.Type
== typeof(XmlQualifiedName
))
1080 WriteMetCall ("WriteNullableQualifiedNameLiteral", GetLiteral(name
), GetLiteral(ns
), memberValue
);
1082 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
);
1083 WriteMetCall ("WriteNullableStringLiteral", GetLiteral(name
), GetLiteral(ns
), strVal
);
1087 if (typeData
.Type
== typeof(XmlQualifiedName
))
1088 WriteMetCall ("WriteElementQualifiedName", GetLiteral(name
), GetLiteral(ns
), memberValue
);
1090 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
);
1091 WriteMetCall ("WriteElementString", GetLiteral(name
),GetLiteral(ns
), strVal
);
1096 void GenerateWritePrimitiveValueEncoded (string memberValue
, string name
, string ns
, XmlQualifiedName xsiType
, XmlTypeMapping mappedType
, TypeData typeData
, bool wrapped
, bool isNullable
)
1099 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
);
1100 WriteMetCall ("WriteValue", strVal
);
1102 else if (isNullable
) {
1103 if (typeData
.Type
== typeof(XmlQualifiedName
))
1104 WriteMetCall ("WriteNullableQualifiedNameEncoded", GetLiteral(name
), GetLiteral(ns
), memberValue
, GetLiteral(xsiType
));
1106 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
);
1107 WriteMetCall ("WriteNullableStringEncoded", GetLiteral(name
), GetLiteral(ns
), strVal
, GetLiteral(xsiType
));
1111 if (typeData
.Type
== typeof(XmlQualifiedName
))
1112 WriteMetCall ("WriteElementQualifiedName", GetLiteral(name
), GetLiteral(ns
), memberValue
, GetLiteral(xsiType
));
1114 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
);
1115 WriteMetCall ("WriteElementString", GetLiteral(name
),GetLiteral(ns
), strVal
, GetLiteral(xsiType
));
1120 string GenerateGetMemberValue (XmlTypeMapMember member
, string ob
, bool isValueList
)
1122 if (isValueList
) return GetCast (member
.TypeData
, TypeTranslator
.GetTypeData (typeof(object)), ob
+ "[" + member
.Index
+ "]");
1123 else return ob
+ ".@" + member
.Name
;
1126 string GenerateMemberHasValueCondition (XmlTypeMapMember member
, string ob
, bool isValueList
)
1129 return ob
+ ".Length > " + member
.Index
;
1131 else if (member
.DefaultValue
!= System
.DBNull
.Value
) {
1132 string mem
= ob
+ ".@" + member
.Name
;
1133 if (member
.DefaultValue
== null)
1134 return mem
+ " != null";
1135 else if (member
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
1136 return mem
+ " != " + GetCast (member
.TypeData
, GetLiteral (member
.DefaultValue
));
1138 return mem
+ " != " + GetLiteral (member
.DefaultValue
);
1140 else if (member
.IsOptionalValueType
)
1141 return ob
+ ".@" + member
.Name
+ "Specified";
1145 void GenerateWriteInitCallbacks ()
1147 WriteLine ("protected override void InitCallbacks ()");
1150 if (_format
== SerializationFormat
.Encoded
)
1152 foreach (XmlMapping xmap
in _mapsToGenerate
) {
1153 XmlTypeMapping map
= xmap
as XmlTypeMapping
;
1155 WriteMetCall ("AddWriteCallback", GetTypeOf(map
.TypeData
), GetLiteral(map
.XmlType
), GetLiteral(map
.Namespace
), "new XmlSerializationWriteCallback (" + GetWriteObjectCallbackName (map
) + ")");
1162 if (_format
== SerializationFormat
.Encoded
)
1164 foreach (XmlTypeMapping xmap
in _mapsToGenerate
) {
1165 XmlTypeMapping map
= xmap
as XmlTypeMapping
;
1166 if (map
== null) continue;
1167 if (map
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
1168 WriteWriteEnumCallback (map
);
1170 WriteWriteObjectCallback (map
);
1175 void WriteWriteEnumCallback (XmlTypeMapping map
)
1177 WriteLine ("void " + GetWriteObjectCallbackName (map
) + " (object ob)");
1179 WriteMetCall (GetWriteObjectName(map
), GetCast (map
.TypeData
, "ob"), GetLiteral(map
.ElementName
), GetLiteral(map
.Namespace
), "false", "true", "false");
1184 void WriteWriteObjectCallback (XmlTypeMapping map
)
1186 WriteLine ("void " + GetWriteObjectCallbackName (map
) + " (object ob)");
1188 WriteMetCall (GetWriteObjectName(map
), GetCast (map
.TypeData
, "ob"), GetLiteral(map
.ElementName
), GetLiteral(map
.Namespace
), "false", "false", "false");
1195 #region Reader Generation
1197 //*******************************************************
1198 // Reader generation
1201 public void GenerateReader (string readerClassName
, ArrayList maps
)
1203 WriteLine ("public class " + readerClassName
+ " : XmlSerializationReader");
1206 _mapsToGenerate
= new ArrayList ();
1207 _fixupCallbacks
= new ArrayList ();
1210 for (int n
=0; n
<maps
.Count
; n
++)
1212 GenerationResult res
= (GenerationResult
) maps
[n
];
1213 _typeMap
= res
.Mapping
;
1214 _format
= _typeMap
.Format
;
1217 GenerateReadRoot ();
1220 for (int n
=0; n
<_mapsToGenerate
.Count
; n
++)
1222 XmlTypeMapping map
= _mapsToGenerate
[n
] as XmlTypeMapping
;
1223 if (map
== null) continue;
1225 GenerateReadObject (map
);
1226 if (map
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
1227 GenerateGetEnumValue (map
);
1230 GenerateReadInitCallbacks ();
1232 if (_format
== SerializationFormat
.Encoded
)
1234 GenerateFixupCallbacks ();
1235 GenerateFillerCallbacks ();
1239 UpdateGeneratedTypes (_mapsToGenerate
);
1242 void GenerateReadRoot ()
1244 WriteLine ("public object " + _result
.ReadMethodName
+ " ()");
1246 WriteLine ("Reader.MoveToContent();");
1248 if (_typeMap
is XmlTypeMapping
)
1250 XmlTypeMapping typeMap
= (XmlTypeMapping
) _typeMap
;
1251 // Console.WriteLine ("> " + typeMap.TypeName);
1253 if (_format
== SerializationFormat
.Literal
)
1255 if (typeMap
.TypeData
.SchemaType
== SchemaTypes
.XmlNode
)
1256 throw new Exception ("Not supported for XmlNode types");
1258 // Console.WriteLine ("This should be string:" + typeMap.ElementName.GetType());
1259 WriteLineInd ("if (Reader.LocalName != " + GetLiteral (typeMap
.ElementName
) + " || Reader.NamespaceURI != " + GetLiteral (typeMap
.Namespace
) + ")");
1260 WriteLine ("throw CreateUnknownNodeException();");
1263 WriteLine ("return " + GetReadObjectCall (typeMap
, "true", "true") + ";");
1267 WriteLine ("object ob = null;");
1268 WriteLine ("Reader.MoveToContent();");
1269 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
1271 WriteLineInd ("if (Reader.LocalName == " + GetLiteral(typeMap
.ElementName
) + " && Reader.NamespaceURI == " + GetLiteral (typeMap
.Namespace
) + ")");
1272 WriteLine ("ob = ReadReferencedElement();");
1274 WriteLineInd ("else ");
1275 WriteLine ("throw CreateUnknownNodeException();");
1278 WriteLineInd ("else ");
1279 WriteLine ("UnknownNode(null);");
1282 WriteLine ("ReadReferencedElements();");
1283 WriteLine ("return ob;");
1284 RegisterReferencingMap (typeMap
);
1288 WriteLine ("return " + GenerateReadMessage ((XmlMembersMapping
)_typeMap
) + ";");
1295 string GenerateReadMessage (XmlMembersMapping typeMap
)
1297 WriteLine ("object[] parameters = new object[" + typeMap
.Count
+ "];");
1300 if (typeMap
.HasWrapperElement
)
1302 if (_format
== SerializationFormat
.Encoded
)
1304 WriteLine ("while (Reader.NodeType == System.Xml.XmlNodeType.Element)");
1306 WriteLine ("string root = Reader.GetAttribute (\"root\", " + GetLiteral(XmlSerializer
.EncodingNamespace
) + ");");
1307 WriteLine ("if (root == null || System.Xml.XmlConvert.ToBoolean(root)) break;");
1308 WriteLine ("ReadReferencedElement ();");
1309 WriteLine ("Reader.MoveToContent ();");
1312 WriteLine ("if (Reader.NodeType != System.Xml.XmlNodeType.EndElement)");
1314 WriteLineInd ("if (Reader.IsEmptyElement) {");
1315 WriteLine ("Reader.Skip();");
1317 WriteLineInd ("else {");
1318 WriteLine ("Reader.ReadStartElement();");
1319 GenerateReadMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "parameters", true, false);
1320 WriteLine ("ReadEndElement();");
1323 WriteLine ("Reader.MoveToContent();");
1328 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement)");
1330 WriteLine ("if (Reader.IsStartElement(" + GetLiteral(typeMap
.ElementName
) + ", " + GetLiteral(typeMap
.Namespace
) + "))");
1332 WriteLine ("if (Reader.IsEmptyElement) { Reader.Skip(); Reader.MoveToContent(); continue; }");
1333 WriteLine ("Reader.ReadStartElement();");
1334 GenerateReadMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "parameters", true, false);
1335 WriteLine ("ReadEndElement();");
1336 WriteLine ("break;");
1338 WriteLineInd ("else ");
1339 WriteLine ("UnknownNode(null);");
1342 WriteLine ("Reader.MoveToContent();");
1347 GenerateReadMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "parameters", true, _format
== SerializationFormat
.Encoded
);
1349 if (_format
== SerializationFormat
.Encoded
)
1350 WriteLine ("ReadReferencedElements();");
1352 return "parameters";
1355 void GenerateReadObject (XmlTypeMapping typeMap
)
1358 if (_format
== SerializationFormat
.Literal
) {
1359 WriteLine ("public " + typeMap
.TypeFullName
+ " " + GetReadObjectName (typeMap
) + " (bool isNullable, bool checkType)");
1360 isNullable
= "isNullable";
1363 WriteLine ("public object " + GetReadObjectName (typeMap
) + " ()");
1364 isNullable
= "true";
1371 SetHookVar ("$TYPE", typeMap
.TypeName
);
1372 SetHookVar ("$FULLTYPE", typeMap
.TypeFullName
);
1373 SetHookVar ("$NULLABLE", "isNullable");
1375 switch (typeMap
.TypeData
.SchemaType
)
1377 case SchemaTypes
.Class
: GenerateReadClassInstance (typeMap
, isNullable
, "checkType"); break;
1378 case SchemaTypes
.Array
:
1379 WriteLine ("return " + GenerateReadListElement (typeMap
, null, isNullable
, true) + ";");
1381 case SchemaTypes
.XmlNode
: GenerateReadXmlNodeElement (typeMap
, isNullable
); break;
1382 case SchemaTypes
.Primitive
: GenerateReadPrimitiveElement (typeMap
, isNullable
); break;
1383 case SchemaTypes
.Enum
: GenerateReadEnumElement (typeMap
, isNullable
); break;
1384 case SchemaTypes
.XmlSerializable
: GenerateReadXmlSerializableElement (typeMap
, isNullable
); break;
1385 default: throw new Exception ("Unsupported map type");
1393 void GenerateReadClassInstance (XmlTypeMapping typeMap
, string isNullable
, string checkType
)
1395 SetHookVar ("$OBJECT", "ob");
1396 if (!typeMap
.TypeData
.IsValueType
)
1398 WriteLine (typeMap
.TypeFullName
+ " ob = null;");
1400 if (GenerateReadHook (HookType
.type
, typeMap
.TypeData
.Type
)) {
1401 WriteLine ("return ob;");
1405 if (_format
== SerializationFormat
.Literal
) {
1406 WriteLine ("if (" + isNullable
+ " && ReadNull()) return null;");
1408 WriteLine ("if (checkType) ");
1412 WriteLine ("if (ReadNull()) return null;");
1418 WriteLine (typeMap
.TypeFullName
+ " ob = new " + typeMap
.TypeFullName
+ " ();");
1420 if (GenerateReadHook (HookType
.type
, typeMap
.TypeData
.Type
)) {
1421 WriteLine ("return ob;");
1426 WriteLine ("System.Xml.XmlQualifiedName t = GetXsiType();");
1427 WriteLine ("if (t == null)");
1428 if (typeMap
.TypeData
.Type
!= typeof(object))
1431 WriteLine ("\treturn " + GetCast (typeMap
.TypeData
, "ReadTypedPrimitive (new System.Xml.XmlQualifiedName(\"anyType\", System.Xml.Schema.XmlSchema.Namespace))") + ";");
1433 foreach (XmlTypeMapping realMap
in typeMap
.DerivedTypes
)
1435 WriteLineInd ("else if (t.Name == " + GetLiteral (realMap
.XmlType
) + " && t.Namespace == " + GetLiteral (realMap
.XmlTypeNamespace
) + ")");
1436 WriteLine ("return " + GetReadObjectCall(realMap
, isNullable
, checkType
) + ";");
1440 WriteLine ("else if (t.Name != " + GetLiteral (typeMap
.XmlType
) + " || t.Namespace != " + GetLiteral (typeMap
.XmlTypeNamespace
) + ")");
1441 if (typeMap
.TypeData
.Type
== typeof(object))
1442 WriteLine ("\treturn " + GetCast (typeMap
.TypeData
, "ReadTypedPrimitive (t)") + ";");
1444 WriteLine ("\tthrow CreateUnknownTypeException(t);");
1446 if (!typeMap
.TypeData
.IsValueType
)
1448 if (_format
== SerializationFormat
.Literal
)
1451 if (typeMap
.TypeData
.Type
.IsAbstract
) {
1453 WriteLine ("return ob;");
1458 WriteLine ("ob = new " + typeMap
.TypeFullName
+ " ();");
1463 WriteLine ("Reader.MoveToElement();");
1466 GenerateReadMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "ob", false, false);
1471 WriteLine ("return ob;");
1474 void GenerateReadMembers (XmlMapping xmlMap
, ClassMap map
, string ob
, bool isValueList
, bool readByOrder
)
1476 XmlTypeMapping typeMap
= xmlMap
as XmlTypeMapping
;
1477 Type xmlMapType
= (typeMap
!= null) ? typeMap
.TypeData
.Type
: typeof(object[]);
1479 // Load the default value of members
1480 if (map
.MembersWithDefault
!= null)
1482 ArrayList members
= map
.MembersWithDefault
;
1483 for (int n
=0; n
<members
.Count
; n
++) {
1484 XmlTypeMapMember mem
= (XmlTypeMapMember
) members
[n
];
1485 GenerateSetMemberValueFromAttr (mem
, ob
, GetLiteral (mem
.DefaultValue
), isValueList
);
1489 // A value list cannot have attributes
1492 if (!isValueList
&& !GenerateReadHook (HookType
.attributes
, xmlMapType
))
1496 XmlTypeMapMember anyAttrMember
= map
.DefaultAnyAttributeMember
;
1498 if (anyAttrMember
!= null)
1500 WriteLine ("int anyAttributeIndex = 0;");
1501 WriteLine (anyAttrMember
.TypeData
.FullTypeName
+ " anyAttributeArray = null;");
1504 WriteLine ("while (Reader.MoveToNextAttribute())");
1507 if (map
.AttributeMembers
!= null) {
1508 foreach (XmlTypeMapMemberAttribute at
in map
.AttributeMembers
)
1510 WriteLineInd ((first
?"":"else ") + "if (Reader.LocalName == " + GetLiteral (at
.AttributeName
) + " && Reader.NamespaceURI == " + GetLiteral (at
.Namespace
) + ") {");
1511 if (!GenerateReadMemberHook (xmlMapType
, at
)) {
1512 GenerateSetMemberValue (at
, ob
, GenerateGetValueFromXmlString ("Reader.Value", at
.TypeData
, at
.MappedType
), isValueList
);
1519 WriteLineInd ((first
?"":"else ") + "if (IsXmlnsAttribute (Reader.Name)) {");
1521 // If the map has NamespaceDeclarations,
1522 // then store this xmlns to the given member.
1523 // If the instance doesn't exist, then create.
1525 if (map
.NamespaceDeclarations
!= null) {
1526 if (!GenerateReadMemberHook (xmlMapType
, map
.NamespaceDeclarations
)) {
1527 string nss
= ob
+ ".@" + map
.NamespaceDeclarations
.Name
;
1528 WriteLine ("if (" + nss
+ " == null) " + nss
+ " = new XmlSerializerNamespaces ();");
1529 WriteLineInd ("if (Reader.Prefix == \"xmlns\")");
1530 WriteLine (nss
+ ".Add (Reader.LocalName, Reader.Value);");
1532 WriteLineInd ("else");
1533 WriteLine (nss
+ ".Add (\"\", Reader.Value);");
1540 WriteLineInd ("else {");
1542 if (anyAttrMember
!= null)
1544 if (!GenerateReadArrayMemberHook (xmlMapType
, anyAttrMember
, "anyAttributeIndex")) {
1545 WriteLine ("System.Xml.XmlAttribute attr = (System.Xml.XmlAttribute) Document.ReadNode(Reader);");
1546 if (typeof(System
.Xml
.Schema
.XmlSchemaAnnotated
).IsAssignableFrom (xmlMapType
))
1547 WriteLine ("ParseWsdlArrayType (attr);");
1548 GenerateAddListValue (anyAttrMember
.TypeData
, "anyAttributeArray", "anyAttributeIndex", GetCast (anyAttrMember
.TypeData
.ListItemTypeData
, "attr"), true);
1551 WriteLine ("anyAttributeIndex++;");
1554 if (!GenerateReadHook (HookType
.unknownAttribute
, xmlMapType
)) {
1555 WriteLine ("UnknownNode (" + ob
+ ");");
1563 if (anyAttrMember
!= null && !MemberHasReadReplaceHook (xmlMapType
, anyAttrMember
))
1566 WriteLine("anyAttributeArray = (" + anyAttrMember
.TypeData
.FullTypeName
+ ") ShrinkArray (anyAttributeArray, anyAttributeIndex, " + GetTypeOf(anyAttrMember
.TypeData
.Type
.GetElementType()) + ", true);");
1567 GenerateSetMemberValue (anyAttrMember
, ob
, "anyAttributeArray", isValueList
);
1576 WriteLine ("Reader.MoveToElement();");
1577 WriteLineInd ("if (Reader.IsEmptyElement) {");
1578 WriteLine ("Reader.Skip ();");
1579 WriteLine ("return " + ob
+ ";");
1583 WriteLine ("Reader.ReadStartElement();");
1588 WriteLine("Reader.MoveToContent();");
1591 if (!GenerateReadHook (HookType
.elements
, xmlMapType
))
1593 string[] readFlag
= null;
1594 if (map
.ElementMembers
!= null && !readByOrder
)
1596 string readFlagsVars
= "bool ";
1597 readFlag
= new string[map
.ElementMembers
.Count
];
1598 for (int n
=0; n
<map
.ElementMembers
.Count
; n
++) {
1599 readFlag
[n
] = GetBoolTempVar ();
1600 if (n
> 0) readFlagsVars
+= ", ";
1601 readFlagsVars
+= readFlag
[n
] + "=false";
1603 if (map
.ElementMembers
.Count
> 0) WriteLine (readFlagsVars
+ ";");
1607 string[] indexes
= null;
1608 string[] flatLists
= null;
1610 if (map
.FlatLists
!= null)
1612 indexes
= new string[map
.FlatLists
.Count
];
1613 flatLists
= new string[map
.FlatLists
.Count
];
1615 string code
= "int ";
1616 for (int n
=0; n
<map
.FlatLists
.Count
; n
++)
1618 XmlTypeMapMember mem
= (XmlTypeMapMember
)map
.FlatLists
[n
];
1619 indexes
[n
] = GetNumTempVar ();
1620 if (n
> 0) code
+= ", ";
1621 code
+= indexes
[n
] + "=0";
1622 if (!MemberHasReadReplaceHook (xmlMapType
, mem
)) {
1623 flatLists
[n
] = GetObTempVar ();
1624 string rval
= "null";
1625 if (IsReadOnly (typeMap
, mem
, mem
.TypeData
, isValueList
)) rval
= ob
+ ".@" + mem
.Name
;
1626 WriteLine (mem
.TypeData
.FullTypeName
+ " " + flatLists
[n
] + " = " + rval
+ ";");
1629 WriteLine (code
+ ";");
1633 if (_format
== SerializationFormat
.Encoded
&& map
.ElementMembers
!= null)
1635 _fixupCallbacks
.Add (xmlMap
);
1636 WriteLine ("Fixup fixup = new Fixup(" + ob
+ ", new XmlSerializationFixupCallback(" + GetFixupCallbackName (xmlMap
) + "), " + map
.ElementMembers
.Count
+ ");");
1637 WriteLine ("AddFixup (fixup);");
1641 ArrayList infos
= null;
1645 if (map
.ElementMembers
!= null) maxInd
= map
.ElementMembers
.Count
;
1650 infos
= new ArrayList ();
1651 infos
.AddRange (map
.AllElementInfos
);
1652 maxInd
= infos
.Count
;
1654 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
1656 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
1661 for (int ind
= 0; ind
< maxInd
; ind
++)
1663 XmlTypeMapElementInfo info
= readByOrder
? map
.GetElement (ind
) : (XmlTypeMapElementInfo
) infos
[ind
];
1667 if (info
.IsTextElement
|| info
.IsUnnamedAnyElement
) continue;
1668 string elemCond
= first
? "" : "else ";
1670 if (!(info
.Member
.IsReturnValue
&& _format
== SerializationFormat
.Encoded
)) {
1671 elemCond
+= "Reader.LocalName == " + GetLiteral (info
.ElementName
);
1672 if (!map
.IgnoreMemberNamespace
) elemCond
+= " && Reader.NamespaceURI == " + GetLiteral (info
.Namespace
);
1675 elemCond
+= "!" + readFlag
[info
.Member
.Index
] + ") {";
1676 WriteLineInd (elemCond
);
1679 if (info
.Member
.GetType() == typeof (XmlTypeMapMemberList
))
1681 if (_format
== SerializationFormat
.Encoded
&& info
.MultiReferenceType
)
1683 string list
= GetObTempVar ();
1684 WriteLine ("object " + list
+ " = ReadReferencingElement (out fixup.Ids[" + info
.Member
.Index
+ "]);");
1685 RegisterReferencingMap (info
.MappedType
);
1687 WriteLineInd ("if (fixup.Ids[" + info
.Member
.Index
+ "] == null) {"); // Already read
1688 if (IsReadOnly (typeMap
, info
.Member
, info
.TypeData
, isValueList
))
1689 WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral(info
.TypeData
.FullTypeName
) + ");");
1691 GenerateSetMemberValue (info
.Member
, ob
, GetCast (info
.Member
.TypeData
,list
), isValueList
);
1694 if (!info
.MappedType
.TypeData
.Type
.IsArray
)
1696 WriteLineInd ("else {");
1697 if (IsReadOnly (typeMap
, info
.Member
, info
.TypeData
, isValueList
))
1698 WriteLine (list
+ " = " + GenerateGetMemberValue (info
.Member
, ob
, isValueList
) + ";");
1700 WriteLine (list
+ " = " + GenerateCreateList (info
.MappedType
.TypeData
.Type
) + ";");
1701 GenerateSetMemberValue (info
.Member
, ob
, GetCast (info
.Member
.TypeData
,list
), isValueList
);
1703 WriteLine ("AddFixup (new CollectionFixup (" + list
+ ", new XmlSerializationCollectionFixupCallback (" + GetFillListName(info
.Member
.TypeData
) + "), fixup.Ids[" + info
.Member
.Index
+ "]));");
1704 WriteLine ("fixup.Ids[" + info
.Member
.Index
+ "] = null;"); // The member already has the value, no further fix needed.
1710 if (!GenerateReadMemberHook (xmlMapType
, info
.Member
)) {
1711 if (IsReadOnly (typeMap
, info
.Member
, info
.TypeData
, isValueList
)) GenerateReadListElement (info
.MappedType
, GenerateGetMemberValue (info
.Member
, ob
, isValueList
), GetLiteral(info
.IsNullable
), false);
1712 else GenerateSetMemberValue (info
.Member
, ob
, GenerateReadListElement (info
.MappedType
, null, GetLiteral(info
.IsNullable
), true), isValueList
);
1717 WriteLine (readFlag
[info
.Member
.Index
] + " = true;");
1719 else if (info
.Member
.GetType() == typeof (XmlTypeMapMemberFlatList
))
1721 XmlTypeMapMemberFlatList mem
= (XmlTypeMapMemberFlatList
)info
.Member
;
1722 if (!GenerateReadArrayMemberHook (xmlMapType
, info
.Member
, indexes
[mem
.FlatArrayIndex
])) {
1723 GenerateAddListValue (mem
.TypeData
, flatLists
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], GenerateReadObjectElement (info
), !IsReadOnly (typeMap
, info
.Member
, info
.TypeData
, isValueList
));
1726 WriteLine (indexes
[mem
.FlatArrayIndex
] + "++;");
1728 else if (info
.Member
.GetType() == typeof (XmlTypeMapMemberAnyElement
))
1730 XmlTypeMapMemberAnyElement mem
= (XmlTypeMapMemberAnyElement
)info
.Member
;
1731 if (mem
.TypeData
.IsListType
) {
1732 if (!GenerateReadArrayMemberHook (xmlMapType
, info
.Member
, indexes
[mem
.FlatArrayIndex
])) {
1733 GenerateAddListValue (mem
.TypeData
, flatLists
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], GetReadXmlNode (mem
.TypeData
.ListItemTypeData
, false), true);
1736 WriteLine (indexes
[mem
.FlatArrayIndex
] + "++;");
1739 if (!GenerateReadMemberHook (xmlMapType
, info
.Member
)) {
1740 GenerateSetMemberValue (mem
, ob
, GetReadXmlNode(mem
.TypeData
, false), isValueList
);
1745 else if (info
.Member
.GetType() == typeof(XmlTypeMapMemberElement
))
1748 WriteLine (readFlag
[info
.Member
.Index
] + " = true;");
1749 if (_format
== SerializationFormat
.Encoded
)
1751 string val
= GetObTempVar ();
1752 RegisterReferencingMap (info
.MappedType
);
1754 if (info
.Member
.TypeData
.SchemaType
!= SchemaTypes
.Primitive
)
1755 WriteLine ("object " + val
+ " = ReadReferencingElement (out fixup.Ids[" + info
.Member
.Index
+ "]);");
1757 WriteLine ("object " + val
+ " = ReadReferencingElement (" + GetLiteral(info
.Member
.TypeData
.XmlType
) + ", " + GetLiteral(System
.Xml
.Schema
.XmlSchema
.Namespace
) + ", out fixup.Ids[" + info
.Member
.Index
+ "]);");
1759 if (info
.MultiReferenceType
)
1760 WriteLineInd ("if (fixup.Ids[" + info
.Member
.Index
+ "] == null) {"); // already read
1762 WriteLineInd ("if (" + val
+ " != null) {"); // null value
1764 GenerateSetMemberValue (info
.Member
, ob
, GetCast (info
.Member
.TypeData
,val
), isValueList
);
1767 else if (!GenerateReadMemberHook (xmlMapType
, info
.Member
)) {
1768 GenerateSetMemberValue (info
.Member
, ob
, GenerateReadObjectElement (info
), isValueList
);
1773 throw new InvalidOperationException ("Unknown member type");
1782 if (!first
) WriteLineInd ("else {");
1784 if (map
.DefaultAnyElementMember
!= null)
1786 XmlTypeMapMemberAnyElement mem
= map
.DefaultAnyElementMember
;
1787 if (mem
.TypeData
.IsListType
) {
1788 if (!GenerateReadArrayMemberHook (xmlMapType
, mem
, indexes
[mem
.FlatArrayIndex
])) {
1789 GenerateAddListValue (mem
.TypeData
, flatLists
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], GetReadXmlNode(mem
.TypeData
.ListItemTypeData
, false), true);
1792 WriteLine (indexes
[mem
.FlatArrayIndex
] + "++;");
1794 else if (! GenerateReadMemberHook (xmlMapType
, mem
)) {
1795 GenerateSetMemberValue (mem
, ob
, GetReadXmlNode(mem
.TypeData
, false), isValueList
);
1800 if (!GenerateReadHook (HookType
.unknownElement
, xmlMapType
)) {
1801 WriteLine ("UnknownNode (" + ob
+ ");");
1806 if (!first
) WriteLineUni ("}");
1810 if (map
.XmlTextCollector
!= null)
1812 WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text)");
1815 if (map
.XmlTextCollector
is XmlTypeMapMemberExpandable
)
1817 XmlTypeMapMemberExpandable mem
= (XmlTypeMapMemberExpandable
)map
.XmlTextCollector
;
1818 XmlTypeMapMemberFlatList flatl
= mem
as XmlTypeMapMemberFlatList
;
1819 TypeData itype
= (flatl
== null) ? mem
.TypeData
.ListItemTypeData
: flatl
.ListMap
.FindTextElement().TypeData
;
1821 if (!GenerateReadArrayMemberHook (xmlMapType
, map
.XmlTextCollector
, indexes
[mem
.FlatArrayIndex
])) {
1822 string val
= (itype
.Type
== typeof (string)) ? "Reader.ReadString()" : GetReadXmlNode (itype
, false);
1823 GenerateAddListValue (mem
.TypeData
, flatLists
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], val
, true);
1826 WriteLine (indexes
[mem
.FlatArrayIndex
] + "++;");
1828 else if (!GenerateReadMemberHook (xmlMapType
, map
.XmlTextCollector
))
1830 XmlTypeMapMemberElement mem
= (XmlTypeMapMemberElement
) map
.XmlTextCollector
;
1831 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
) mem
.ElementInfo
[0];
1832 if (info
.TypeData
.Type
== typeof (string))
1833 GenerateSetMemberValue (mem
, ob
, "ReadString (" + GenerateGetMemberValue (mem
, ob
, isValueList
) + ")", isValueList
);
1835 GenerateSetMemberValue (mem
, ob
, GenerateGetValueFromXmlString ("Reader.ReadString()", info
.TypeData
, info
.MappedType
), isValueList
);
1842 WriteLine ("\tUnknownNode(" + ob
+ ");");
1844 WriteLine ("Reader.MoveToContent();");
1848 WriteLine ("Reader.MoveToContent();");
1850 if (flatLists
!= null)
1853 foreach (XmlTypeMapMemberExpandable mem
in map
.FlatLists
)
1855 if (MemberHasReadReplaceHook (xmlMapType
, mem
)) continue;
1857 string list
= flatLists
[mem
.FlatArrayIndex
];
1858 if (mem
.TypeData
.Type
.IsArray
)
1859 WriteLine (list
+ " = (" + mem
.TypeData
.FullTypeName
+ ") ShrinkArray (" + list
+ ", " + indexes
[mem
.FlatArrayIndex
] + ", " + GetTypeOf(mem
.TypeData
.Type
.GetElementType()) + ", true);");
1860 if (!IsReadOnly (typeMap
, mem
, mem
.TypeData
, isValueList
))
1861 GenerateSetMemberValue (mem
, ob
, list
, isValueList
);
1870 WriteLine ("ReadEndElement();");
1874 bool IsReadOnly (XmlTypeMapping map
, XmlTypeMapMember member
, TypeData memType
, bool isValueList
)
1876 if (isValueList
) return !memType
.HasPublicConstructor
;
1877 else return member
.IsReadOnly (map
.TypeData
.Type
) || !memType
.HasPublicConstructor
;
1880 void GenerateSetMemberValue (XmlTypeMapMember member
, string ob
, string value, bool isValueList
)
1882 if (isValueList
) WriteLine (ob
+ "[" + member
.Index
+ "] = " + value + ";");
1884 WriteLine (ob
+ ".@" + member
.Name
+ " = " + value + ";");
1885 if (member
.IsOptionalValueType
)
1886 WriteLine (ob
+ "." + member
.Name
+ "Specified = true;");
1890 void GenerateSetMemberValueFromAttr (XmlTypeMapMember member
, string ob
, string value, bool isValueList
)
1892 // Enumeration values specified in custom attributes are stored as integer
1893 // values if the custom attribute property is of type object. So, it is
1894 // necessary to convert to the enum type before asigning the value to the field.
1896 if (member
.TypeData
.Type
.IsEnum
)
1897 value = GetCast (member
.TypeData
.Type
, value);
1898 GenerateSetMemberValue (member
, ob
, value, isValueList
);
1901 object GenerateGetMemberValue (XmlTypeMapMember member
, object ob
, bool isValueList
)
1903 if (isValueList
) return ob
+ "[" + member
.Index
+ "]";
1904 else return ob
+ ".@" + member
.Name
;
1907 string GenerateReadObjectElement (XmlTypeMapElementInfo elem
)
1909 switch (elem
.TypeData
.SchemaType
)
1911 case SchemaTypes
.XmlNode
:
1912 return GetReadXmlNode (elem
.TypeData
, true);
1914 case SchemaTypes
.Primitive
:
1915 case SchemaTypes
.Enum
:
1916 return GenerateReadPrimitiveValue (elem
);
1918 case SchemaTypes
.Array
:
1919 return GenerateReadListElement (elem
.MappedType
, null, GetLiteral(elem
.IsNullable
), true);
1921 case SchemaTypes
.Class
:
1922 return GetReadObjectCall (elem
.MappedType
, GetLiteral(elem
.IsNullable
), "true");
1924 case SchemaTypes
.XmlSerializable
:
1925 return GetCast (elem
.TypeData
, "ReadSerializable (new " + elem
.TypeData
.FullTypeName
+ " ())");
1928 throw new NotSupportedException ("Invalid value type");
1932 string GenerateReadPrimitiveValue (XmlTypeMapElementInfo elem
)
1934 if (elem
.TypeData
.Type
== typeof (XmlQualifiedName
)) {
1935 if (elem
.IsNullable
) return "ReadNullableQualifiedName ()";
1936 else return "ReadElementQualifiedName ()";
1938 else if (elem
.IsNullable
)
1939 return GenerateGetValueFromXmlString ("ReadNullableString ()", elem
.TypeData
, elem
.MappedType
);
1941 return GenerateGetValueFromXmlString ("Reader.ReadElementString ()", elem
.TypeData
, elem
.MappedType
);
1944 string GenerateGetValueFromXmlString (string value, TypeData typeData
, XmlTypeMapping typeMap
)
1946 if (typeData
.SchemaType
== SchemaTypes
.Array
)
1947 return GenerateReadListString (typeMap
, value);
1948 else if (typeData
.SchemaType
== SchemaTypes
.Enum
)
1949 return GenerateGetEnumValue (typeMap
, value);
1950 else if (typeData
.Type
== typeof (XmlQualifiedName
))
1951 return "ToXmlQualifiedName (" + value + ")";
1953 return XmlCustomFormatter
.GenerateFromXmlString (typeData
, value);
1956 string GenerateReadListElement (XmlTypeMapping typeMap
, string list
, string isNullable
, bool canCreateInstance
)
1958 Type listType
= typeMap
.TypeData
.Type
;
1959 ListMap listMap
= (ListMap
)typeMap
.ObjectMap
;
1961 if (canCreateInstance
&& typeMap
.TypeData
.HasPublicConstructor
)
1963 list
= GetObTempVar ();
1964 WriteLine (typeMap
.TypeFullName
+ " " + list
+ " = null;");
1965 WriteLineInd ("if (!ReadNull()) {");
1966 WriteLine (list
+ " = " + GenerateCreateList (listType
) + ";");
1971 WriteLineInd ("if (" + list
+ " == null)");
1972 WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap
.TypeFullName
) + ");");
1974 WriteLineInd ("if (!ReadNull()) {");
1977 list
= GetObTempVar ();
1978 WriteLine (typeMap
.TypeFullName
+ " " + list
+ " = null;");
1979 WriteLineInd ("if (" + list
+ " == null)");
1980 WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap
.TypeFullName
) + ");");
1986 WriteLineInd ("if (Reader.IsEmptyElement) {");
1987 WriteLine ("Reader.Skip();");
1988 if (listType
.IsArray
)
1989 WriteLine (list
+ " = (" + typeMap
.TypeFullName
+ ") ShrinkArray (" + list
+ ", 0, " + GetTypeOf(listType
.GetElementType()) + ", " + isNullable
+ ");");
1992 WriteLineInd ("} else {");
1994 string index
= GetNumTempVar ();
1995 WriteLine ("int " + index
+ " = 0;");
1996 WriteLine ("Reader.ReadStartElement();");
1997 WriteLine ("Reader.MoveToContent();");
2000 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
2002 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
2006 foreach (XmlTypeMapElementInfo elemInfo
in listMap
.ItemInfo
)
2008 WriteLineInd ((first
?"":"else ") + "if (Reader.LocalName == " + GetLiteral (elemInfo
.ElementName
) + " && Reader.NamespaceURI == " + GetLiteral (elemInfo
.Namespace
) + ") {");
2009 GenerateAddListValue (typeMap
.TypeData
, list
, index
, GenerateReadObjectElement (elemInfo
), false);
2010 WriteLine (index
+ "++;");
2014 if (!first
) WriteLine ("else UnknownNode (null);");
2015 else WriteLine ("UnknownNode (null);");
2018 WriteLine ("else UnknownNode (null);");
2020 WriteLine ("Reader.MoveToContent();");
2023 WriteLine ("ReadEndElement();");
2025 if (listType
.IsArray
)
2026 WriteLine (list
+ " = (" + typeMap
.TypeFullName
+ ") ShrinkArray (" + list
+ ", " + index
+ ", " + GetTypeOf(listType
.GetElementType()) + ", " + isNullable
+ ");");
2034 string GenerateReadListString (XmlTypeMapping typeMap
, string values
)
2036 Type listType
= typeMap
.TypeData
.Type
;
2037 ListMap listMap
= (ListMap
)typeMap
.ObjectMap
;
2038 string itemType
= listType
.GetElementType().FullName
;
2040 string list
= GetObTempVar ();
2041 WriteLine (itemType
+ "[] " + list
+ ";");
2043 string var = GetStrTempVar ();
2044 WriteLine ("string " + var + " = " + values
+ ".Trim();");
2045 WriteLineInd ("if (" + var + " != string.Empty) {");
2047 string valueArray
= GetObTempVar ();
2048 WriteLine ("string[] " + valueArray
+ " = " + var + ".Split (' ');");
2050 WriteLine (list
+ " = new " + itemType
+ " [" + valueArray
+ ".Length];");
2052 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
)listMap
.ItemInfo
[0];
2054 string index
= GetNumTempVar ();
2055 WriteLineInd ("for (int " + index
+ " = 0; " + index
+ " < " + valueArray
+ ".Length; " + index
+ "++)");
2056 WriteLine (list
+ "[" + index
+ "] = " + GenerateGetValueFromXmlString (valueArray
+ "[" + index
+ "]", info
.TypeData
, info
.MappedType
) + ";");
2060 WriteLine ("\t" + list
+ " = new " + itemType
+ " [0];");
2065 void GenerateAddListValue (TypeData listType
, string list
, string index
, string value, bool canCreateInstance
)
2067 Type type
= listType
.Type
;
2070 WriteLine (list
+ " = (" + type
.FullName
+ ") EnsureArrayIndex (" + list
+ ", " + index
+ ", " + GetTypeOf(type
.GetElementType()) + ");");
2071 WriteLine (list
+ "[" + index
+ "] = " + value + ";");
2073 else // Must be IEnumerable
2075 WriteLine ("if (" + list
+ " == null)");
2076 if (canCreateInstance
)
2077 WriteLine ("\t" + list
+ " = new " + listType
.FullTypeName
+ "();");
2079 WriteLine ("\tthrow CreateReadOnlyCollectionException (" + GetLiteral (listType
.FullTypeName
) + ");");
2081 WriteLine (list
+ ".Add (" + value + ");");
2085 string GenerateCreateList (Type listType
)
2087 if (listType
.IsArray
)
2088 return "(" + listType
.FullName
+ ") EnsureArrayIndex (null, 0, " + GetTypeOf(listType
.GetElementType()) + ")";
2090 return "new " + listType
.FullName
+ "()";
2093 void GenerateFillerCallbacks ()
2095 foreach (TypeData td
in _listsToFill
)
2097 string metName
= GetFillListName (td
);
2098 WriteLine ("void " + metName
+ " (object list, object source)");
2100 WriteLine ("if (list == null) throw CreateReadOnlyCollectionException (" + GetLiteral (td
.FullTypeName
) + ");");
2103 WriteLine (td
.FullTypeName
+ " dest = (" + td
.FullTypeName
+ ") list;");
2104 WriteLine ("foreach (object ob in (IEnumerable)source)");
2105 WriteLine ("\tdest.Add (" + GetCast (td
.ListItemTypeData
, "ob") + ");");
2111 void GenerateReadXmlNodeElement (XmlTypeMapping typeMap
, string isNullable
)
2113 WriteLine ("return " + GetReadXmlNode (typeMap
.TypeData
, false) + ";");
2116 void GenerateReadPrimitiveElement (XmlTypeMapping typeMap
, string isNullable
)
2118 WriteLine ("XmlQualifiedName t = GetXsiType();");
2119 WriteLine ("if (t == null) t = new XmlQualifiedName (" + GetLiteral(typeMap
.XmlType
) + ", " + GetLiteral(typeMap
.Namespace
) + ");");
2120 WriteLine ("return " + GetCast (typeMap
.TypeData
, "ReadTypedPrimitive (t)") + ";");
2123 void GenerateReadEnumElement (XmlTypeMapping typeMap
, string isNullable
)
2125 WriteLine ("Reader.ReadStartElement ();");
2126 WriteLine (typeMap
.TypeFullName
+ " res = " + GenerateGetEnumValue (typeMap
, "Reader.ReadString()") + ";");
2127 WriteLine ("Reader.ReadEndElement ();");
2128 WriteLine ("return res;");
2131 string GenerateGetEnumValue (XmlTypeMapping typeMap
, string val
)
2133 return GetGetEnumValueName (typeMap
) + " (" + val
+ ")";
2136 void GenerateGetEnumValue (XmlTypeMapping typeMap
)
2138 string metName
= GetGetEnumValueName (typeMap
);
2139 EnumMap map
= (EnumMap
) typeMap
.ObjectMap
;
2143 string switchMethod
= metName
+ "_Switch";
2144 WriteLine (typeMap
.TypeFullName
+ " " + metName
+ " (string xmlName)");
2146 WriteLine ("xmlName = xmlName.Trim();");
2147 WriteLine ("if (xmlName.Length == 0) return (" + typeMap
.TypeFullName
+ ")0;");
2148 WriteLine ("if (xmlName.IndexOf (' ') != -1)");
2150 WriteLine (typeMap
.TypeFullName
+ " sb = (" + typeMap
.TypeFullName
+ ")0;");
2151 WriteLine ("string[] enumNames = xmlName.ToString().Split (' ');");
2152 WriteLine ("foreach (string name in enumNames)");
2154 WriteLine ("if (name == string.Empty) continue;");
2155 WriteLine ("sb |= " + switchMethod
+ " (name); ");
2157 WriteLine ("return sb;");
2160 WriteLine ("\treturn " + switchMethod
+ " (xmlName);");
2162 metName
= switchMethod
;
2165 WriteLine (typeMap
.TypeFullName
+ " " + metName
+ " (string xmlName)");
2167 GenerateGetSingleEnumValue (typeMap
, "xmlName");
2172 void GenerateGetSingleEnumValue (XmlTypeMapping typeMap
, string val
)
2174 EnumMap map
= (EnumMap
) typeMap
.ObjectMap
;
2175 WriteLine ("switch (" + val
+ ")");
2177 foreach (EnumMap
.EnumMapMember mem
in map
.Members
)
2179 WriteLine ("case " + GetLiteral (mem
.XmlName
) + ": return " + typeMap
.TypeFullName
+ "." + mem
.EnumName
+ ";");
2181 WriteLineInd ("default:");
2182 WriteLineInd ("try {");
2183 WriteLine ("return (" + typeMap
.TypeFullName
+ ") Int64.Parse (" + val
+ ", CultureInfo.InvariantCulture);");
2185 WriteLineInd ("catch {");
2186 WriteLine ("throw CreateUnknownConstantException (" + val
+ ", typeof(" + typeMap
.TypeFullName
+ "));");
2192 void GenerateReadXmlSerializableElement (XmlTypeMapping typeMap
, string isNullable
)
2194 WriteLine ("Reader.MoveToContent ();");
2195 WriteLine ("if (Reader.NodeType == XmlNodeType.Element)");
2197 WriteLine ("if (Reader.LocalName == " + GetLiteral (typeMap
.ElementName
) + " && Reader.NamespaceURI == " + GetLiteral (typeMap
.Namespace
) + ")");
2198 WriteLine ("\treturn ReadSerializable (new " + typeMap
.TypeData
.FullTypeName
+ "());");
2200 WriteLine ("\tthrow CreateUnknownNodeException ();");
2202 WriteLine ("else UnknownNode (null);");
2204 WriteLine ("return null;");
2207 void GenerateReadInitCallbacks ()
2209 WriteLine ("protected override void InitCallbacks ()");
2212 if (_format
== SerializationFormat
.Encoded
)
2214 foreach (XmlMapping xmap
in _mapsToGenerate
)
2216 XmlTypeMapping map
= xmap
as XmlTypeMapping
;
2217 if (map
== null) continue;
2218 if (map
.TypeData
.SchemaType
== SchemaTypes
.Class
|| map
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
2219 WriteMetCall ("AddReadCallback", GetLiteral (map
.XmlType
), GetLiteral(map
.Namespace
), GetTypeOf(map
.TypeData
.Type
), "new XmlSerializationReadCallback (" + GetReadObjectName (map
) + ")");
2226 WriteLine ("protected override void InitIDs ()");
2232 void GenerateFixupCallbacks ()
2234 foreach (XmlMapping map
in _fixupCallbacks
)
2236 bool isList
= map
is XmlMembersMapping
;
2237 string tname
= !isList
? ((XmlTypeMapping
)map
).TypeFullName
: "object[]";
2238 WriteLine ("void " + GetFixupCallbackName (map
) + " (object obfixup)");
2240 WriteLine ("Fixup fixup = (Fixup)obfixup;");
2241 WriteLine (tname
+ " source = (" + tname
+ ") fixup.Source;");
2242 WriteLine ("string[] ids = fixup.Ids;");
2245 ClassMap cmap
= (ClassMap
)map
.ObjectMap
;
2246 ICollection members
= cmap
.ElementMembers
;
2247 if (members
!= null) {
2248 foreach (XmlTypeMapMember member
in members
)
2250 WriteLineInd ("if (ids[" + member
.Index
+ "] != null)");
2251 GenerateSetMemberValue (member
, "source", GetCast (member
.TypeData
, "GetTarget(ids[" + member
.Index
+ "])"), isList
);
2260 string GetReadXmlNode (TypeData type
, bool wrapped
)
2262 if (type
.Type
== typeof (XmlDocument
))
2263 return GetCast (type
, TypeTranslator
.GetTypeData (typeof(XmlDocument
)), "ReadXmlDocument (" + GetLiteral(wrapped
) + ")");
2265 return GetCast (type
, TypeTranslator
.GetTypeData (typeof(XmlNode
)), "ReadXmlNode (" + GetLiteral(wrapped
) + ")");
2270 #region Helper methods
2272 //*******************************************************
2276 ArrayList _listsToFill
= new ArrayList ();
2278 Hashtable _hookVariables
;
2279 Stack _hookContexts
;
2280 Stack _hookOpenHooks
;
2283 public HookType HookType
;
2285 public string Member
;
2286 public HookDir Direction
;
2291 _hookContexts
= new Stack ();
2292 _hookOpenHooks
= new Stack ();
2293 _hookVariables
= new Hashtable ();
2294 _hooks
= new Hashtable ();
2297 void PushHookContext ()
2299 _hookContexts
.Push (_hookVariables
);
2300 _hookVariables
= (Hashtable
) _hookVariables
.Clone ();
2303 void PopHookContext ()
2305 _hookVariables
= (Hashtable
) _hookContexts
.Pop ();
2308 void SetHookVar (string var, string value)
2310 _hookVariables
[var] = value;
2313 bool GenerateReadHook (HookType hookType
, Type type
)
2315 return GenerateHook (hookType
, HookDir
.Read
, type
, null);
2318 bool GenerateWriteHook (HookType hookType
, Type type
)
2320 return GenerateHook (hookType
, HookDir
.Write
, type
, null);
2323 bool GenerateWriteMemberHook (Type type
, XmlTypeMapMember member
)
2325 SetHookVar ("$MEMBER", member
.Name
);
2326 return GenerateHook (HookType
.member
, HookDir
.Write
, type
, member
.Name
);
2329 bool GenerateReadMemberHook (Type type
, XmlTypeMapMember member
)
2331 SetHookVar ("$MEMBER", member
.Name
);
2332 return GenerateHook (HookType
.member
, HookDir
.Read
, type
, member
.Name
);
2335 bool GenerateReadArrayMemberHook (Type type
, XmlTypeMapMember member
, string index
)
2337 SetHookVar ("$INDEX", index
);
2338 return GenerateReadMemberHook (type
, member
);
2341 bool MemberHasReadReplaceHook (Type type
, XmlTypeMapMember member
)
2343 if (_config
== null) return false;
2344 return _config
.GetHooks (HookType
.member
, HookDir
.Read
, HookAction
.Replace
, type
, member
.Name
).Count
> 0;
2347 bool GenerateHook (HookType hookType
, HookDir dir
, Type type
, string member
)
2349 GenerateHooks (hookType
, dir
, type
, null, HookAction
.InsertBefore
);
2350 if (GenerateHooks (hookType
, dir
, type
, null, HookAction
.Replace
))
2352 GenerateHooks (hookType
, dir
, type
, null, HookAction
.InsertAfter
);
2357 HookInfo hi
= new HookInfo ();
2358 hi
.HookType
= hookType
;
2362 _hookOpenHooks
.Push (hi
);
2367 void GenerateEndHook ()
2369 HookInfo hi
= (HookInfo
) _hookOpenHooks
.Pop();
2370 GenerateHooks (hi
.HookType
, hi
.Direction
, hi
.Type
, hi
.Member
, HookAction
.InsertAfter
);
2373 bool GenerateHooks (HookType hookType
, HookDir dir
, Type type
, string member
, HookAction action
)
2375 if (_config
== null) return false;
2376 ArrayList hooks
= _config
.GetHooks (hookType
, dir
, action
, type
, null);
2377 if (hooks
.Count
== 0) return false;
2378 foreach (Hook hook
in hooks
)
2380 string code
= hook
.GetCode (action
);
2381 foreach (DictionaryEntry de
in _hookVariables
)
2382 code
= code
.Replace ((string)de
.Key
, (string)de
.Value
);
2383 WriteMultilineCode (code
);
2388 string GetRootTypeName ()
2390 if (_typeMap
is XmlTypeMapping
) return ((XmlTypeMapping
)_typeMap
).TypeFullName
;
2391 else return "object[]";
2394 string GetNumTempVar ()
2396 return "n" + (_tempVarId
++);
2399 string GetObTempVar ()
2401 return "o" + (_tempVarId
++);
2404 string GetStrTempVar ()
2406 return "s" + (_tempVarId
++);
2409 string GetBoolTempVar ()
2411 return "b" + (_tempVarId
++);
2414 string GetUniqueName (string uniqueGroup
, object ob
, string name
)
2416 name
= name
.Replace ("[]","_array");
2417 Hashtable names
= (Hashtable
) _uniqueNames
[uniqueGroup
];
2418 if (names
== null) {
2419 names
= new Hashtable ();
2420 _uniqueNames
[uniqueGroup
] = names
;
2423 string res
= (string) names
[ob
];
2424 if (res
!= null) return res
;
2426 foreach (string n
in names
.Values
)
2427 if (n
== name
) return GetUniqueName (uniqueGroup
, ob
, name
+ (_methodId
++));
2433 void RegisterReferencingMap (XmlTypeMapping typeMap
)
2435 if (typeMap
!= null && !_mapsToGenerate
.Contains (typeMap
))
2436 _mapsToGenerate
.Add (typeMap
);
2439 string GetWriteObjectName (XmlTypeMapping typeMap
)
2441 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2442 return GetUniqueName ("rw", typeMap
, "WriteObject_" + typeMap
.XmlType
);
2445 string GetReadObjectName (XmlTypeMapping typeMap
)
2447 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2448 return GetUniqueName ("rr", typeMap
, "ReadObject_" + typeMap
.XmlType
);
2451 string GetGetEnumValueName (XmlTypeMapping typeMap
)
2453 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2454 return GetUniqueName ("ge", typeMap
, "GetEnumValue_" + typeMap
.XmlType
);
2457 string GetWriteObjectCallbackName (XmlTypeMapping typeMap
)
2459 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2460 return GetUniqueName ("wc", typeMap
, "WriteCallback_" + typeMap
.XmlType
);
2463 string GetFixupCallbackName (XmlMapping typeMap
)
2465 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2467 if (typeMap
is XmlTypeMapping
)
2468 return GetUniqueName ("fc", typeMap
, "FixupCallback_" + ((XmlTypeMapping
)typeMap
).XmlType
);
2470 return GetUniqueName ("fc", typeMap
, "FixupCallback__Message");
2473 string GetUniqueClassName (string s
)
2475 return classNames
.AddUnique (s
, null);
2478 string GetReadObjectCall (XmlTypeMapping typeMap
, string isNullable
, string checkType
)
2480 if (_format
== SerializationFormat
.Literal
)
2481 return GetReadObjectName (typeMap
) + " (" + isNullable
+ ", " + checkType
+ ")";
2483 return GetCast (typeMap
.TypeData
, GetReadObjectName (typeMap
) + " ()");
2486 string GetFillListName (TypeData td
)
2488 if (!_listsToFill
.Contains (td
)) _listsToFill
.Add (td
);
2489 return GetUniqueName ("fl", td
, "Fill_" + td
.TypeName
);
2492 string GetCast (TypeData td
, TypeData tdval
, string val
)
2494 if (td
.FullTypeName
== tdval
.FullTypeName
) return val
;
2495 else return GetCast (td
, val
);
2498 string GetCast (TypeData td
, string val
)
2500 return "((" + td
.FullTypeName
+ ") " + val
+ ")";
2503 string GetCast (Type td
, string val
)
2505 return "((" + td
.FullName
+ ") " + val
+ ")";
2508 string GetTypeOf (TypeData td
)
2510 return "typeof(" + td
.FullTypeName
+ ")";
2513 string GetTypeOf (Type td
)
2515 return "typeof(" + td
.FullName
+ ")";
2518 string GetString (string str
)
2520 return "\"" + str
+ "\"";
2523 string GetLiteral (object ob
)
2525 if (ob
== null) return "null";
2526 if (ob
is string) return "\"" + ob
.ToString().Replace("\"","\"\"") + "\"";
2527 if (ob
is bool) return ((bool)ob
) ? "true" : "false";
2528 if (ob
is XmlQualifiedName
) {
2529 XmlQualifiedName qn
= (XmlQualifiedName
)ob
;
2530 return "new XmlQualifiedName (" + GetLiteral(qn
.Name
) + "," + GetLiteral(qn
.Namespace
) + ")";
2532 else return (ob
is IFormattable
) ? ((IFormattable
) ob
).ToString (null, CultureInfo
.InvariantCulture
) : ob
.ToString ();
2535 void WriteLineInd (string code
)
2541 void WriteLineUni (string code
)
2543 if (_indent
> 0) _indent
--;
2547 void WriteLine (string code
)
2549 if (code
!= "") _writer
.Write (new String ('\t',_indent
));
2550 _writer
.WriteLine (code
);
2553 void WriteMultilineCode (string code
)
2555 string tabs
= new string ('\t',_indent
);
2556 code
= code
.Replace ("\r","");
2557 code
= code
.Replace ("\t","");
2558 while (code
.StartsWith ("\n")) code
= code
.Substring (1);
2559 while (code
.EndsWith ("\n")) code
= code
.Substring (0, code
.Length
- 1);
2560 code
= code
.Replace ("\n", "\n" + tabs
);
2564 string Params (params string[] pars
)
2567 foreach (string p
in pars
)
2569 if (res
!= "") res
+= ", ";
2575 void WriteMetCall (string method
, params string[] pars
)
2577 WriteLine (method
+ " (" + Params (pars
) + ");");
2594 internal class GenerationResult
2596 public XmlMapping Mapping
;
2597 public string ReaderClassName
;
2598 public string ReadMethodName
;
2599 public string WriterClassName
;
2600 public string WriteMethodName
;
2601 public string Namespace
;
2602 public string SerializerClassName
;