2 // System.Xml.Serialization.SerializationCodeGenerator.cs:
5 // Lluis Sanchez Gual (lluis@ximian.com)
6 // Atsushi Enomoto (atsushi@ximian.com)
8 // (C) 2002, 2003 Ximian, Inc. http://www.ximian.com
9 // Copyright (C) 2006 Novell, Inc.
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Reflection
;
35 using System
.Xml
.Serialization
;
36 using System
.Collections
;
37 using System
.Globalization
;
40 using HookDir
= System
.Xml
.Serialization
.XmlMappingAccess
;
42 namespace System
.Xml
.Serialization
44 internal class SerializationCodeGenerator
47 SerializationFormat _format
;
51 Hashtable _uniqueNames
= new Hashtable();
53 SerializerInfo _config
;
54 ArrayList _mapsToGenerate
= new ArrayList ();
55 ArrayList _fixupCallbacks
;
56 ArrayList _referencedTypes
= new ArrayList ();
57 GenerationResult
[] _results
;
58 GenerationResult _result
;
59 XmlMapping
[] _xmlMaps
;
61 CodeIdentifiers classNames
= new CodeIdentifiers ();
63 public SerializationCodeGenerator (XmlMapping
[] xmlMaps
): this (xmlMaps
, null)
67 public SerializationCodeGenerator (XmlMapping
[] xmlMaps
, SerializerInfo config
)
73 public SerializationCodeGenerator (XmlMapping xmlMap
, SerializerInfo config
)
75 _xmlMaps
= new XmlMapping
[] {xmlMap}
;
79 public static void Generate (string configFileName
, string outputPath
)
81 SerializationCodeGeneratorConfiguration cnf
= null;
82 StreamReader sr
= new StreamReader (configFileName
);
85 XmlReflectionImporter ri
= new XmlReflectionImporter ();
86 ri
.AllowPrivateTypes
= true;
87 XmlSerializer ser
= new XmlSerializer (ri
.ImportTypeMapping (typeof (SerializationCodeGeneratorConfiguration
)));
88 cnf
= (SerializationCodeGeneratorConfiguration
) ser
.Deserialize (sr
);
95 if (outputPath
== null) outputPath
= "";
97 CodeIdentifiers ids
= new CodeIdentifiers ();
98 if (cnf
.Serializers
!= null)
100 foreach (SerializerInfo info
in cnf
.Serializers
)
103 if (info
.Assembly
!= null)
107 asm
= Assembly
.Load (info
.Assembly
);
109 asm
= Assembly
.LoadFrom (info
.Assembly
);
111 type
= asm
.GetType (info
.ClassName
, true);
114 type
= Type
.GetType (info
.ClassName
);
116 if (type
== null) throw new InvalidOperationException ("Type " + info
.ClassName
+ " not found");
118 string file
= info
.OutFileName
;
119 if (file
== null || file
.Length
== 0) {
120 int i
= info
.ClassName
.LastIndexOf (".");
121 if (i
!= -1) file
= info
.ClassName
.Substring (i
+1);
122 else file
= info
.ClassName
;
123 file
= ids
.AddUnique (file
, type
) + "Serializer.cs";
125 StreamWriter writer
= new StreamWriter (Path
.Combine (outputPath
, file
));
131 if (info
.SerializationFormat
== SerializationFormat
.Literal
) {
132 XmlReflectionImporter ri
= new XmlReflectionImporter ();
133 map
= ri
.ImportTypeMapping (type
);
136 SoapReflectionImporter ri
= new SoapReflectionImporter ();
137 map
= ri
.ImportTypeMapping (type
);
140 SerializationCodeGenerator gen
= new SerializationCodeGenerator (map
, info
);
141 gen
.GenerateSerializers (writer
);
151 public void GenerateSerializers (TextWriter writer
)
154 _results
= new GenerationResult
[_xmlMaps
.Length
];
156 WriteLine ("// It is automatically generated");
157 WriteLine ("using System;");
158 WriteLine ("using System.Xml;");
159 WriteLine ("using System.Xml.Schema;");
160 WriteLine ("using System.Xml.Serialization;");
161 WriteLine ("using System.Text;");
162 WriteLine ("using System.Collections;");
163 WriteLine ("using System.Globalization;");
164 if (_config
!= null && _config
.NamespaceImports
!= null && _config
.NamespaceImports
.Length
> 0) {
165 foreach (string ns
in _config
.NamespaceImports
)
166 WriteLine ("using " + ns
+ ";");
170 string readerClassName
= null;
171 string writerClassName
= null;
172 string baseClassName
= null;
173 string implClassName
= null;
174 string namspace
= null;
178 readerClassName
= _config
.ReaderClassName
;
179 writerClassName
= _config
.WriterClassName
;
180 baseClassName
= _config
.BaseSerializerClassName
;
181 implClassName
= _config
.ImplementationClassName
;
182 namspace
= _config
.Namespace
;
185 if (readerClassName
== null || readerClassName
.Length
== 0)
186 readerClassName
= "GeneratedReader";
188 if (writerClassName
== null || writerClassName
.Length
== 0)
189 writerClassName
= "GeneratedWriter";
190 if (baseClassName
== null || baseClassName
.Length
== 0)
191 baseClassName
= "BaseXmlSerializer";
192 if (implClassName
== null || implClassName
.Length
== 0)
193 implClassName
= "XmlSerializerContract";
194 readerClassName
= GetUniqueClassName (readerClassName
);
195 writerClassName
= GetUniqueClassName (writerClassName
);
196 baseClassName
= GetUniqueClassName (baseClassName
);
197 implClassName
= GetUniqueClassName (implClassName
);
198 Hashtable mapsByNamespace
= new Hashtable ();
199 Hashtable generatedMaps
= new Hashtable ();
201 for (int n
=0; n
<_xmlMaps
.Length
; n
++)
203 _typeMap
= _xmlMaps
[n
];
204 if (_typeMap
== null) continue;
206 _result
= generatedMaps
[_typeMap
] as GenerationResult
;
207 if (_result
!= null) {
208 _results
[n
] = _result
;
212 _result
= new GenerationResult ();
213 _results
[n
] = _result
;
215 generatedMaps
[_typeMap
] = _result
;
218 if (_typeMap
is XmlTypeMapping
) typeName
= CodeIdentifier
.MakeValid (((XmlTypeMapping
)_typeMap
).TypeData
.CSharpName
);
219 else typeName
= ((XmlMembersMapping
)_typeMap
).ElementName
;
221 _result
.ReaderClassName
= readerClassName
;
222 _result
.WriterClassName
= writerClassName
;
223 _result
.BaseSerializerClassName
= baseClassName
;
224 _result
.ImplementationClassName
= implClassName
;
226 if (namspace
== null || namspace
.Length
== 0)
227 _result
.Namespace
= "Mono.GeneratedSerializers." + _typeMap
.Format
;
229 _result
.Namespace
= namspace
;
231 _result
.WriteMethodName
= GetUniqueName ("rwo", _typeMap
, "WriteRoot_" + typeName
);
232 _result
.ReadMethodName
= GetUniqueName ("rro", _typeMap
, "ReadRoot_" + typeName
);
234 _result
.Mapping
= _typeMap
;
236 ArrayList maps
= (ArrayList
) mapsByNamespace
[_result
.Namespace
];
238 maps
= new ArrayList ();
239 mapsByNamespace
[_result
.Namespace
] = maps
;
244 foreach (DictionaryEntry entry
in mapsByNamespace
)
246 ArrayList maps
= (ArrayList
) entry
.Value
;
248 WriteLine ("namespace " + entry
.Key
);
251 if (_config
== null || !_config
.NoReader
)
252 GenerateReader (readerClassName
, maps
);
254 if (_config
== null || !_config
.NoWriter
)
255 GenerateWriter (writerClassName
, maps
);
259 GenerateContract (maps
);
267 public GenerationResult
[] GenerationResults
269 get { return _results; }
272 public ArrayList ReferencedTypes
274 get { return _referencedTypes; }
277 void UpdateGeneratedTypes (ArrayList list
)
279 for (int n
=0; n
<list
.Count
; n
++)
281 XmlTypeMapping map
= list
[n
] as XmlTypeMapping
;
282 if (map
!= null && !_referencedTypes
.Contains (map
.TypeData
.Type
))
283 _referencedTypes
.Add (map
.TypeData
.Type
);
287 static string ToCSharpFullName (Type type
)
289 return TypeData
.ToCSharpName (type
, true);
292 #region Writer Generation
294 //*******************************************************
295 // Contract generation
299 public void GenerateContract (ArrayList generatedMaps
)
301 // Write the base serializer
303 if (generatedMaps
.Count
== 0) return;
305 GenerationResult main
= (GenerationResult
) generatedMaps
[0];
307 string baseSerializerName
= main
.BaseSerializerClassName
;
308 string access_mod
= (_config
== null || !_config
.GenerateAsInternal
) ? "public" : "internal";
311 WriteLine (access_mod
+ " class " + baseSerializerName
+ " : System.Xml.Serialization.XmlSerializer");
313 WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationReader CreateReader () {");
314 WriteLine ("return new " + main
.ReaderClassName
+ " ();");
318 WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationWriter CreateWriter () {");
319 WriteLine ("return new " + main
.WriterClassName
+ " ();");
323 WriteLineInd ("public override bool CanDeserialize (System.Xml.XmlReader xmlReader) {");
324 WriteLine ("return true;");
330 // Write a serializer for each imported map
332 foreach (GenerationResult res
in generatedMaps
)
334 res
.SerializerClassName
= GetUniqueClassName (res
.Mapping
.ElementName
+ "Serializer");
336 WriteLine (access_mod
+ " sealed class " + res
.SerializerClassName
+ " : " + baseSerializerName
);
338 WriteLineInd ("protected override void Serialize (object obj, System.Xml.Serialization.XmlSerializationWriter writer) {");
339 WriteLine ("((" + res
.WriterClassName
+ ")writer)." + res
.WriteMethodName
+ "(obj);");
343 WriteLineInd ("protected override object Deserialize (System.Xml.Serialization.XmlSerializationReader reader) {");
344 WriteLine ("return ((" + res
.ReaderClassName
+ ")reader)." + res
.ReadMethodName
+ "();");
351 WriteLine ("#if !TARGET_JVM"); // does it make sense? ;-)
352 WriteLine (access_mod
+ " class " + main
.ImplementationClassName
+ " : System.Xml.Serialization.XmlSerializerImplementation");
355 WriteLine ("System.Collections.Hashtable readMethods = null;");
356 WriteLine ("System.Collections.Hashtable writeMethods = null;");
357 WriteLine ("System.Collections.Hashtable typedSerializers = null;");
360 WriteLineInd ("public override System.Xml.Serialization.XmlSerializationReader Reader {");
361 WriteLineInd ("get {");
362 WriteLine ("return new " + main
.ReaderClassName
+ "();");
367 WriteLineInd ("public override System.Xml.Serialization.XmlSerializationWriter Writer {");
368 WriteLineInd ("get {");
369 WriteLine ("return new " + main
.WriterClassName
+ "();");
374 WriteLineInd ("public override System.Collections.Hashtable ReadMethods {");
375 WriteLineInd ("get {");
376 WriteLineInd ("lock (this) {");
377 WriteLineInd ("if (readMethods == null) {");
378 WriteLine ("readMethods = new System.Collections.Hashtable ();");
379 foreach (GenerationResult res
in generatedMaps
)
380 WriteLine ("readMethods.Add (@\"" + res
.Mapping
.GetKey () + "\", @\"" + res
.ReadMethodName
+ "\");");
382 WriteLine ("return readMethods;");
388 WriteLineInd ("public override System.Collections.Hashtable WriteMethods {");
389 WriteLineInd ("get {");
390 WriteLineInd ("lock (this) {");
391 WriteLineInd ("if (writeMethods == null) {");
392 WriteLine ("writeMethods = new System.Collections.Hashtable ();");
393 foreach (GenerationResult res
in generatedMaps
)
394 WriteLine ("writeMethods.Add (@\"" + res
.Mapping
.GetKey () + "\", @\"" + res
.WriteMethodName
+ "\");");
396 WriteLine ("return writeMethods;");
402 WriteLineInd ("public override System.Collections.Hashtable TypedSerializers {");
403 WriteLineInd ("get {");
404 WriteLineInd ("lock (this) {");
405 WriteLineInd ("if (typedSerializers == null) {");
406 WriteLine ("typedSerializers = new System.Collections.Hashtable ();");
407 foreach (GenerationResult res
in generatedMaps
)
408 WriteLine ("typedSerializers.Add (@\"" + res
.Mapping
.GetKey () + "\", new " + res
.SerializerClassName
+ "());");
410 WriteLine ("return typedSerializers;");
416 WriteLine ("public override XmlSerializer GetSerializer (Type type)");
418 WriteLine ("switch (type.FullName) {");
419 foreach (GenerationResult res
in generatedMaps
) {
420 if (res
.Mapping
is XmlTypeMapping
) {
421 WriteLineInd ("case \"" + ((XmlTypeMapping
) res
.Mapping
).TypeData
.CSharpFullName
+ "\":");
422 WriteLine ("return (XmlSerializer) TypedSerializers [\"" + res
.Mapping
.GetKey () + "\"];");
427 WriteLine ("return base.GetSerializer (type);");
431 WriteLineInd ("public override bool CanSerialize (System.Type type) {");
432 foreach (GenerationResult res
in generatedMaps
) {
433 if (res
.Mapping
is XmlTypeMapping
)
434 WriteLine ("if (type == typeof(" + (res
.Mapping
as XmlTypeMapping
).TypeData
.CSharpFullName
+ ")) return true;");
436 WriteLine ("return false;");
441 WriteLine ("#endif");
446 //*******************************************************
450 public void GenerateWriter (string writerClassName
, ArrayList maps
)
452 _mapsToGenerate
= new ArrayList ();
456 if (_config
== null || !_config
.GenerateAsInternal
)
457 WriteLine ("public class " + writerClassName
+ " : XmlSerializationWriter");
459 WriteLine ("internal class " + writerClassName
+ " : XmlSerializationWriter");
461 WriteLine ("const string xmlNamespace = \"http://www.w3.org/2000/xmlns/\";");
462 // ToBinHexString() is not public, so use reflection here.
463 WriteLine ("static readonly System.Reflection.MethodInfo toBinHexStringMethod = typeof (XmlConvert).GetMethod (\"ToBinHexString\", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new Type [] {typeof (byte [])}, null);");
464 WriteLine ("static string ToBinHexString (byte [] input)");
466 WriteLine ("return input == null ? null : (string) toBinHexStringMethod.Invoke (null, new object [] {input});");
469 for (int n
=0; n
<maps
.Count
; n
++)
471 GenerationResult res
= (GenerationResult
) maps
[n
];
472 _typeMap
= res
.Mapping
;
473 _format
= _typeMap
.Format
;
476 GenerateWriteRoot ();
479 for (int n
=0; n
<_mapsToGenerate
.Count
; n
++)
481 XmlTypeMapping map
= (XmlTypeMapping
) _mapsToGenerate
[n
];
482 GenerateWriteObject (map
);
483 if (map
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
484 GenerateGetXmlEnumValue (map
);
487 GenerateWriteInitCallbacks ();
488 UpdateGeneratedTypes (_mapsToGenerate
);
493 void GenerateWriteRoot ()
495 WriteLine ("public void " +_result
.WriteMethodName
+ " (object o)");
497 WriteLine ("WriteStartDocument ();");
499 if (_typeMap
is XmlTypeMapping
)
501 WriteLine (GetRootTypeName () + " ob = (" + GetRootTypeName () + ") o;");
502 XmlTypeMapping mp
= (XmlTypeMapping
) _typeMap
;
503 if (mp
.TypeData
.SchemaType
== SchemaTypes
.Class
|| mp
.TypeData
.SchemaType
== SchemaTypes
.Array
)
504 WriteLine ("TopLevelElement ();");
506 if (_format
== SerializationFormat
.Literal
) {
507 WriteLine (GetWriteObjectName (mp
) + " (ob, " + GetLiteral(mp
.ElementName
) + ", " + GetLiteral(mp
.Namespace
) + ", true, false, true);");
510 RegisterReferencingMap (mp
);
511 WriteLine ("WritePotentiallyReferencingElement (" + GetLiteral(mp
.ElementName
) + ", " + GetLiteral(mp
.Namespace
) + ", ob, " + GetTypeOf(mp
.TypeData
) + ", true, false);");
514 else if (_typeMap
is XmlMembersMapping
) {
515 WriteLine ("object[] pars = (object[]) o;");
516 GenerateWriteMessage ((XmlMembersMapping
) _typeMap
);
519 throw new InvalidOperationException ("Unknown type map");
521 if (_format
== SerializationFormat
.Encoded
)
522 WriteLine ("WriteReferencedElements ();");
528 void GenerateWriteMessage (XmlMembersMapping membersMap
)
530 if (membersMap
.HasWrapperElement
) {
531 WriteLine ("TopLevelElement ();");
532 WriteLine ("WriteStartElement (" + GetLiteral (membersMap
.ElementName
) + ", " + GetLiteral (membersMap
.Namespace
) + ", (" + GetLiteral(_format
== SerializationFormat
.Encoded
) + "));");
534 /* WriteLineInd ("if (Writer.LookupPrefix (XmlSchema.Namespace) == null)");
535 WriteLine ("WriteAttribute (\"xmlns\",\"xsd\",XmlSchema.Namespace,XmlSchema.Namespace);");
538 WriteLineInd ("if (Writer.LookupPrefix (XmlSchema.InstanceNamespace) == null)");
539 WriteLine ("WriteAttribute (\"xmlns\",\"xsi\",XmlSchema.InstanceNamespace,XmlSchema.InstanceNamespace);");
544 GenerateWriteObjectElement (membersMap
, "pars", true);
546 if (membersMap
.HasWrapperElement
)
547 WriteLine ("WriteEndElement();");
550 void GenerateGetXmlEnumValue (XmlTypeMapping map
)
552 EnumMap emap
= (EnumMap
) map
.ObjectMap
;
554 string xmlNamesArray
= null;
555 string valuesArray
= null;
558 // create static string[] holding XML names of enum constants
559 xmlNamesArray
= GetUniqueName ("gxe", map
, "_xmlNames" + map
.XmlType
);
560 Write ("static readonly string[] " + xmlNamesArray
+ " = { ");
561 for (int i
= 0; i
< emap
.XmlNames
.Length
; i
++) {
565 _writer
.Write (emap
.XmlNames
[i
]);
566 _writer
.Write ('\"');
568 _writer
.WriteLine (" };");
570 // create const long[] holding values of enum constants
571 valuesArray
= GetUniqueName ("gve", map
, "_values" + map
.XmlType
);
572 Write ("static readonly long[] " + valuesArray
+ " = { ");
573 for (int i
= 0; i
< emap
.Values
.Length
; i
++) {
576 _writer
.Write (emap
.Values
[i
].ToString (CultureInfo
.InvariantCulture
));
579 _writer
.WriteLine (" };");
580 WriteLine (string.Empty
);
583 WriteLine ("string " + GetGetEnumValueName (map
) + " (" + map
.TypeData
.CSharpFullName
+ " val)");
587 WriteLineInd ("switch (val) {");
588 for (int i
= 0; i
< emap
.EnumNames
.Length
; i
++)
589 WriteLine ("case " + map
.TypeData
.CSharpFullName
+ ".@" + emap
.EnumNames
[i
] + ": return " + GetLiteral (emap
.XmlNames
[i
]) + ";");
592 WriteLineInd ("default:");
593 // FromEnum actually covers this case too, but we save some cycles here
594 WriteLine ("if (val.ToString () == \"0\") return string.Empty;");
595 Write ("return FromEnum ((long) val, " + xmlNamesArray
+ ", " + valuesArray
);
597 _writer
.Write (", typeof (");
598 _writer
.Write (map
.TypeData
.CSharpFullName
);
599 _writer
.Write (").FullName");
601 _writer
.Write (')'); // close FromEnum method call
602 WriteUni (";"); // end statement
605 WriteLine ("default: throw CreateInvalidEnumValueException ((long) val, typeof (" + map
.TypeData
.CSharpFullName
+ ").FullName);");
607 WriteLine ("default: return ((long)val).ToString(CultureInfo.InvariantCulture);");
617 void GenerateWriteObject (XmlTypeMapping typeMap
)
619 WriteLine ("void " + GetWriteObjectName (typeMap
) + " (" + typeMap
.TypeData
.CSharpFullName
+ " ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)");
624 SetHookVar ("$TYPE", typeMap
.TypeData
.CSharpName
);
625 SetHookVar ("$FULLTYPE", typeMap
.TypeData
.CSharpFullName
);
626 SetHookVar ("$OBJECT", "ob");
627 SetHookVar ("$NULLABLE", "isNullable");
629 if (GenerateWriteHook (HookType
.type
, typeMap
.TypeData
.Type
))
637 if (!typeMap
.TypeData
.IsValueType
)
639 WriteLine ("if (((object)ob) == null)");
641 WriteLineInd ("if (isNullable)");
643 if (_format
== SerializationFormat
.Literal
)
644 WriteLine ("WriteNullTagLiteral(element, namesp);");
646 WriteLine ("WriteNullTagEncoded (element, namesp);");
648 WriteLineUni ("return;");
653 if (typeMap
.TypeData
.SchemaType
== SchemaTypes
.XmlNode
)
655 if (_format
== SerializationFormat
.Literal
)
656 WriteLine ("WriteElementLiteral (ob, \"\", \"\", true, false);");
658 WriteLine ("WriteElementEncoded (ob, \"\", \"\", true, false);");
667 if (typeMap
.TypeData
.SchemaType
== SchemaTypes
.XmlSerializable
)
669 WriteLine ("WriteSerializable (ob, element, namesp, isNullable);");
678 ArrayList types
= typeMap
.DerivedTypes
;
680 WriteLine ("System.Type type = ob.GetType ();");
681 WriteLine ("if (type == typeof(" + typeMap
.TypeData
.CSharpFullName
+ "))");
684 for (int n
=0; n
<types
.Count
; n
++)
686 XmlTypeMapping map
= (XmlTypeMapping
)types
[n
];
688 WriteLineInd ("else if (type == typeof(" + map
.TypeData
.CSharpFullName
+ ")) { ");
689 WriteLine (GetWriteObjectName (map
) + "((" + map
.TypeData
.CSharpFullName
+ ")ob, element, namesp, isNullable, true, writeWrappingElem);");
690 WriteLine ("return;");
694 if (typeMap
.TypeData
.Type
== typeof (object)) {
695 WriteLineInd ("else {");
696 WriteLineInd ("if (ob.GetType().IsArray && typeof(XmlNode).IsAssignableFrom(ob.GetType().GetElementType())) {");
697 WriteLine ("Writer.WriteStartElement (" + GetLiteral (typeMap
.ElementName
) + ", " + GetLiteral (typeMap
.Namespace
) + ");");
698 WriteLineInd ("foreach (XmlNode node in (System.Collections.IEnumerable) ob)");
699 WriteLineUni ("node.WriteTo (Writer);");
700 WriteLineUni ("Writer.WriteEndElement ();");
702 WriteLineInd ("else");
703 WriteLineUni ("WriteTypedPrimitive (element, namesp, ob, true);");
704 WriteLine ("return;");
709 WriteLineInd ("else {");
710 WriteLine ("throw CreateUnknownTypeException (ob);");
714 WriteLineInd ("if (writeWrappingElem) {");
715 if (_format
== SerializationFormat
.Encoded
) WriteLine ("needType = true;");
716 WriteLine ("WriteStartElement (element, namesp, ob);");
720 WriteLine ("if (needType) WriteXsiType(" + GetLiteral(typeMap
.XmlType
) + ", " + GetLiteral(typeMap
.XmlTypeNamespace
) + ");");
723 switch (typeMap
.TypeData
.SchemaType
)
725 case SchemaTypes
.Class
: GenerateWriteObjectElement (typeMap
, "ob", false); break;
726 case SchemaTypes
.Array
: GenerateWriteListElement (typeMap
, "ob"); break;
727 case SchemaTypes
.Primitive
: GenerateWritePrimitiveElement (typeMap
, "ob"); break;
728 case SchemaTypes
.Enum
: GenerateWriteEnumElement (typeMap
, "ob"); break;
731 WriteLine ("if (writeWrappingElem) WriteEndElement (ob);");
740 void GenerateWriteObjectElement (XmlMapping xmlMap
, string ob
, bool isValueList
)
742 XmlTypeMapping typeMap
= xmlMap
as XmlTypeMapping
;
743 Type xmlMapType
= (typeMap
!= null) ? typeMap
.TypeData
.Type
: typeof(object[]);
745 ClassMap map
= (ClassMap
)xmlMap
.ObjectMap
;
746 if (!GenerateWriteHook (HookType
.attributes
, xmlMapType
))
748 if (map
.NamespaceDeclarations
!= null) {
749 WriteLine ("WriteNamespaceDeclarations ((XmlSerializerNamespaces) " + ob
+ ".@" + map
.NamespaceDeclarations
.Name
+ ");");
753 XmlTypeMapMember anyAttrMember
= map
.DefaultAnyAttributeMember
;
754 if (anyAttrMember
!= null)
756 if (!GenerateWriteMemberHook (xmlMapType
, anyAttrMember
))
758 string cond
= GenerateMemberHasValueCondition (anyAttrMember
, ob
, isValueList
);
759 if (cond
!= null) WriteLineInd ("if (" + cond
+ ") {");
761 string tmpVar
= GetObTempVar ();
762 WriteLine ("ICollection " + tmpVar
+ " = " + GenerateGetMemberValue (anyAttrMember
, ob
, isValueList
) + ";");
763 WriteLineInd ("if (" + tmpVar
+ " != null) {");
765 string tmpVar2
= GetObTempVar ();
766 WriteLineInd ("foreach (XmlAttribute " + tmpVar2
+ " in " + tmpVar
+ ")");
767 WriteLineInd ("if (" + tmpVar2
+ ".NamespaceURI != xmlNamespace)");
768 WriteLine ("WriteXmlAttribute (" + tmpVar2
+ ", " + ob
+ ");");
773 if (cond
!= null) WriteLineUni ("}");
779 ICollection attributes
= map
.AttributeMembers
;
780 if (attributes
!= null)
782 foreach (XmlTypeMapMemberAttribute attr
in attributes
)
784 if (GenerateWriteMemberHook (xmlMapType
, attr
)) continue;
786 string val
= GenerateGetMemberValue (attr
, ob
, isValueList
);
787 string cond
= GenerateMemberHasValueCondition (attr
, ob
, isValueList
);
789 if (cond
!= null) WriteLineInd ("if (" + cond
+ ") {");
791 string strVal
= GenerateGetStringValue (attr
.MappedType
, attr
.TypeData
, val
, false);
792 WriteLine ("WriteAttribute (" + GetLiteral(attr
.AttributeName
) + ", " + GetLiteral(attr
.Namespace
) + ", " + strVal
+ ");");
794 if (cond
!= null) WriteLineUni ("}");
802 if (!GenerateWriteHook (HookType
.elements
, xmlMapType
))
804 ICollection members
= map
.ElementMembers
;
807 foreach (XmlTypeMapMemberElement member
in members
)
809 if (GenerateWriteMemberHook (xmlMapType
, member
)) continue;
811 string cond
= GenerateMemberHasValueCondition (member
, ob
, isValueList
);
812 if (cond
!= null) WriteLineInd ("if (" + cond
+ ") {");
814 string memberValue
= GenerateGetMemberValue (member
, ob
, isValueList
);
815 Type memType
= member
.GetType();
817 if (memType
== typeof(XmlTypeMapMemberList
))
819 GenerateWriteMemberElement ((XmlTypeMapElementInfo
) member
.ElementInfo
[0], memberValue
);
821 else if (memType
== typeof(XmlTypeMapMemberFlatList
))
823 WriteLineInd ("if (" + memberValue
+ " != null) {");
824 GenerateWriteListContent (ob
, member
.TypeData
, ((XmlTypeMapMemberFlatList
)member
).ListMap
, memberValue
, false);
827 else if (memType
== typeof(XmlTypeMapMemberAnyElement
))
829 WriteLineInd ("if (" + memberValue
+ " != null) {");
830 GenerateWriteAnyElementContent ((XmlTypeMapMemberAnyElement
)member
, memberValue
);
833 else if (memType
== typeof(XmlTypeMapMemberAnyElement
))
835 WriteLineInd ("if (" + memberValue
+ " != null) {");
836 GenerateWriteAnyElementContent ((XmlTypeMapMemberAnyElement
)member
, memberValue
);
839 else if (memType
== typeof(XmlTypeMapMemberAnyAttribute
))
843 else if (memType
== typeof(XmlTypeMapMemberElement
))
845 if (member
.ElementInfo
.Count
== 1) {
846 GenerateWriteMemberElement ((XmlTypeMapElementInfo
)member
.ElementInfo
[0], memberValue
);
848 else if (member
.ChoiceMember
!= null)
850 string choiceValue
= ob
+ ".@" + member
.ChoiceMember
;
851 foreach (XmlTypeMapElementInfo elem
in member
.ElementInfo
) {
852 WriteLineInd ("if (" + choiceValue
+ " == " + GetLiteral(elem
.ChoiceValue
) + ") {");
853 GenerateWriteMemberElement (elem
, GetCast(elem
.TypeData
, member
.TypeData
, memberValue
));
859 // WriteLineInd ("if (" + memberValue + " == null) {");
860 // GenerateWriteMemberElement ((XmlTypeMapElementInfo)member.ElementInfo[0], memberValue);
861 // WriteLineUni ("}");
864 foreach (XmlTypeMapElementInfo elem
in member
.ElementInfo
)
866 WriteLineInd ((first
?"":"else ") + "if (" + memberValue
+ " is " + elem
.TypeData
.CSharpFullName
+ ") {");
867 GenerateWriteMemberElement (elem
, GetCast(elem
.TypeData
, member
.TypeData
, memberValue
));
874 throw new InvalidOperationException ("Unknown member type");
886 void GenerateWriteMemberElement (XmlTypeMapElementInfo elem
, string memberValue
)
888 switch (elem
.TypeData
.SchemaType
)
890 case SchemaTypes
.XmlNode
:
891 string elemName
= elem
.WrappedElement
? elem
.ElementName
: "";
892 if (_format
== SerializationFormat
.Literal
)
893 WriteMetCall ("WriteElementLiteral", memberValue
, GetLiteral(elemName
), GetLiteral(elem
.Namespace
), GetLiteral(elem
.IsNullable
), "false");
895 WriteMetCall ("WriteElementEncoded", memberValue
, GetLiteral(elemName
), GetLiteral(elem
.Namespace
), GetLiteral(elem
.IsNullable
), "false");
898 case SchemaTypes
.Enum
:
899 case SchemaTypes
.Primitive
:
900 if (_format
== SerializationFormat
.Literal
)
901 GenerateWritePrimitiveValueLiteral (memberValue
, elem
.ElementName
, elem
.Namespace
, elem
.MappedType
, elem
.TypeData
, elem
.WrappedElement
, elem
.IsNullable
);
903 GenerateWritePrimitiveValueEncoded (memberValue
, elem
.ElementName
, elem
.Namespace
, new XmlQualifiedName (elem
.TypeData
.XmlType
, elem
.DataTypeNamespace
), elem
.MappedType
, elem
.TypeData
, elem
.WrappedElement
, elem
.IsNullable
);
906 case SchemaTypes
.Array
:
907 WriteLineInd ("if (" + memberValue
+ " != null) {");
909 if (elem
.MappedType
.MultiReferenceType
) {
910 WriteMetCall ("WriteReferencingElement", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), memberValue
, GetLiteral(elem
.IsNullable
));
911 RegisterReferencingMap (elem
.MappedType
);
914 WriteMetCall ("WriteStartElement", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), memberValue
);
915 GenerateWriteListContent (null, elem
.TypeData
, (ListMap
) elem
.MappedType
.ObjectMap
, memberValue
, false);
916 WriteMetCall ("WriteEndElement", memberValue
);
920 if (elem
.IsNullable
) {
921 WriteLineInd ("else");
922 if (_format
== SerializationFormat
.Literal
)
923 WriteMetCall ("WriteNullTagLiteral", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
));
925 WriteMetCall ("WriteNullTagEncoded", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
));
931 case SchemaTypes
.Class
:
932 if (elem
.MappedType
.MultiReferenceType
) {
933 RegisterReferencingMap (elem
.MappedType
);
934 if (elem
.MappedType
.TypeData
.Type
== typeof(object))
935 WriteMetCall ("WritePotentiallyReferencingElement", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), memberValue
, "null", "false", GetLiteral(elem
.IsNullable
));
937 WriteMetCall ("WriteReferencingElement", GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), memberValue
, GetLiteral(elem
.IsNullable
));
940 WriteMetCall (GetWriteObjectName(elem
.MappedType
), memberValue
, GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), GetLiteral(elem
.IsNullable
), "false", "true");
943 case SchemaTypes
.XmlSerializable
:
944 WriteMetCall ("WriteSerializable", "(" + ToCSharpFullName (elem
.MappedType
.TypeData
.Type
) + ") " + memberValue
, GetLiteral(elem
.ElementName
), GetLiteral(elem
.Namespace
), GetLiteral(elem
.IsNullable
));
948 throw new NotSupportedException ("Invalid value type");
952 void GenerateWriteListElement (XmlTypeMapping typeMap
, string ob
)
954 if (_format
== SerializationFormat
.Encoded
)
957 string itemCount
= GenerateGetListCount (typeMap
.TypeData
, ob
);
958 GenerateGetArrayType ((ListMap
) typeMap
.ObjectMap
, itemCount
, out n
, out ns
);
961 if (ns
!= string.Empty
)
962 arrayType
= "FromXmlQualifiedName (new XmlQualifiedName(" + n
+ "," + ns
+ "))";
964 arrayType
= GetLiteral (n
);
966 WriteMetCall ("WriteAttribute", GetLiteral("arrayType"), GetLiteral(XmlSerializer
.EncodingNamespace
), arrayType
);
968 GenerateWriteListContent (null, typeMap
.TypeData
, (ListMap
) typeMap
.ObjectMap
, ob
, false);
971 void GenerateWriteAnyElementContent (XmlTypeMapMemberAnyElement member
, string memberValue
)
973 bool singleElement
= (member
.TypeData
.Type
== typeof (XmlElement
));
976 var2
= GetObTempVar ();
980 var = GetObTempVar ();
981 WriteLineInd ("foreach (object " + var2
+ " in " + memberValue
+ ") {");
983 WriteLine ("XmlNode " + var + " = " + var2
+ " as XmlNode;");
984 WriteLine ("if (" + var + " == null && " + var2
+ "!= null) throw new InvalidOperationException (\"A member with XmlAnyElementAttribute can only serialize and deserialize certain XmlNode types.");
987 string elem
= GetObTempVar ();
988 WriteLine ("XmlNode " + elem
+ " = " + var + ";");
989 WriteLine ("if (" + elem
+ " is XmlElement) {");
991 if (!member
.IsDefaultAny
) {
992 for (int n
=0; n
<member
.ElementInfo
.Count
; n
++) {
993 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
)member
.ElementInfo
[n
];
994 string txt
= "(" + elem
+ ".LocalName == " + GetLiteral(info
.ElementName
) + " && " + elem
+ ".NamespaceURI == " + GetLiteral(info
.Namespace
) + ")";
995 if (n
== member
.ElementInfo
.Count
-1) txt
+= ") {";
996 if (n
== 0) WriteLineInd ("if (" + txt
);
997 else WriteLine ("|| " + txt
);
1001 WriteLine ("else " + elem
+ ".WriteTo (Writer);");
1003 if (_format
== SerializationFormat
.Literal
)
1004 WriteLine ("WriteElementLiteral (" + elem
+ ", \"\", \"\", false, true);");
1006 WriteLine ("WriteElementEncoded (" + elem
+ ", \"\", \"\", false, true);");
1008 if (!member
.IsDefaultAny
) {
1010 WriteLineInd ("else");
1011 WriteLine ("throw CreateUnknownAnyElementException (" + elem
+ ".Name, " + elem
+ ".NamespaceURI);");
1019 void GenerateWritePrimitiveElement (XmlTypeMapping typeMap
, string ob
)
1021 string strVal
= GenerateGetStringValue (typeMap
, typeMap
.TypeData
, ob
, false);
1022 WriteLine ("Writer.WriteString (" + strVal
+ ");");
1025 void GenerateWriteEnumElement (XmlTypeMapping typeMap
, string ob
)
1027 string strVal
= GenerateGetEnumXmlValue (typeMap
, ob
);
1028 WriteLine ("Writer.WriteString (" + strVal
+ ");");
1031 string GenerateGetStringValue (XmlTypeMapping typeMap
, TypeData type
, string value, bool isNullable
)
1033 if (type
.SchemaType
== SchemaTypes
.Array
) {
1034 string str
= GetStrTempVar ();
1035 WriteLine ("string " + str
+ " = null;");
1036 WriteLineInd ("if (" + value + " != null) {");
1037 string res
= GenerateWriteListContent (null, typeMap
.TypeData
, (ListMap
)typeMap
.ObjectMap
, value, true);
1038 WriteLine (str
+ " = " + res
+ ".ToString ().Trim ();");
1042 else if (type
.SchemaType
== SchemaTypes
.Enum
) {
1044 return "(" + value + ").HasValue ? " + GenerateGetEnumXmlValue (typeMap
, "(" + value + ").Value") + " : null";
1046 return GenerateGetEnumXmlValue (typeMap
, value);
1048 else if (type
.Type
== typeof (XmlQualifiedName
))
1049 return "FromXmlQualifiedName (" + value + ")";
1050 else if (value == null)
1053 return XmlCustomFormatter
.GenerateToXmlString (type
, value);
1056 string GenerateGetEnumXmlValue (XmlTypeMapping typeMap
, string ob
)
1058 return GetGetEnumValueName (typeMap
) + " (" + ob
+ ")";
1061 string GenerateGetListCount (TypeData listType
, string ob
)
1063 if (listType
.Type
.IsArray
)
1069 void GenerateGetArrayType (ListMap map
, string itemCount
, out string localName
, out string ns
)
1072 if (itemCount
!= "") arrayDim
= "";
1073 else arrayDim
= "[]";
1075 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
) map
.ItemInfo
[0];
1076 if (info
.TypeData
.SchemaType
== SchemaTypes
.Array
)
1079 GenerateGetArrayType ((ListMap
)info
.MappedType
.ObjectMap
, "", out nm
, out ns
);
1080 localName
= nm
+ arrayDim
;
1084 if (info
.MappedType
!= null)
1086 localName
= info
.MappedType
.XmlType
+ arrayDim
;
1087 ns
= info
.MappedType
.Namespace
;
1091 localName
= info
.TypeData
.XmlType
+ arrayDim
;
1092 ns
= info
.DataTypeNamespace
;
1095 if (itemCount
!= "") {
1096 localName
= "\"" + localName
+ "[\" + " + itemCount
+ " + \"]\"";
1097 ns
= GetLiteral (ns
);
1101 string GenerateWriteListContent (string container
, TypeData listType
, ListMap map
, string ob
, bool writeToString
)
1103 string targetString
= null;
1107 targetString
= GetStrTempVar ();
1108 WriteLine ("System.Text.StringBuilder " + targetString
+ " = new System.Text.StringBuilder();");
1111 if (listType
.Type
.IsArray
)
1113 string itemVar
= GetNumTempVar ();
1114 WriteLineInd ("for (int "+itemVar
+" = 0; "+itemVar
+" < " + ob
+ ".Length; "+itemVar
+"++) {");
1115 GenerateListLoop (container
, map
, ob
+ "["+itemVar
+"]", itemVar
, listType
.ListItemTypeData
, targetString
);
1118 else if (typeof(ICollection
).IsAssignableFrom (listType
.Type
))
1120 string itemVar
= GetNumTempVar ();
1121 WriteLineInd ("for (int "+itemVar
+" = 0; "+itemVar
+" < " + ob
+ ".Count; "+itemVar
+"++) {");
1122 GenerateListLoop (container
, map
, ob
+ "["+itemVar
+"]", itemVar
, listType
.ListItemTypeData
, targetString
);
1125 else if (typeof(IEnumerable
).IsAssignableFrom (listType
.Type
))
1127 string itemVar
= GetObTempVar ();
1128 WriteLineInd ("foreach (" + listType
.ListItemTypeData
.CSharpFullName
+ " " + itemVar
+ " in " + ob
+ ") {");
1129 GenerateListLoop (container
, map
, itemVar
, null, listType
.ListItemTypeData
, targetString
);
1133 throw new Exception ("Unsupported collection type");
1135 return targetString
;
1138 void GenerateListLoop (string container
, ListMap map
, string item
, string index
, TypeData itemTypeData
, string targetString
)
1140 bool multichoice
= (map
.ItemInfo
.Count
> 1);
1142 if (map
.ChoiceMember
!= null && container
!= null && index
!= null) {
1143 WriteLineInd ("if ((" + container
+ ".@" + map
.ChoiceMember
+ " == null) || (" + index
+ " >= " + container
+ ".@" + map
.ChoiceMember
+ ".Length))");
1144 WriteLine ("throw CreateInvalidChoiceIdentifierValueException (" + container
+ ".GetType().ToString(), \"" + map
.ChoiceMember
+ "\");");
1149 WriteLine ("if (((object)" + item
+ ") == null) { }");
1151 foreach (XmlTypeMapElementInfo info
in map
.ItemInfo
)
1153 if (map
.ChoiceMember
!= null && multichoice
)
1154 WriteLineInd ("else if (" + container
+ ".@" + map
.ChoiceMember
+ "[" + index
+ "] == " + GetLiteral (info
.ChoiceValue
) + ") {");
1155 else if (multichoice
)
1156 WriteLineInd ("else if (" + item
+ ".GetType() == typeof(" + info
.TypeData
.CSharpFullName
+ ")) {");
1158 if (targetString
== null)
1159 GenerateWriteMemberElement (info
, GetCast (info
.TypeData
, itemTypeData
, item
));
1162 string strVal
= GenerateGetStringValue (info
.MappedType
, info
.TypeData
, GetCast (info
.TypeData
, itemTypeData
, item
), false);
1163 WriteLine (targetString
+ ".Append (" + strVal
+ ").Append (\" \");");
1171 WriteLine ("else throw CreateUnknownTypeException (" + item
+ ");");
1174 void GenerateWritePrimitiveValueLiteral (string memberValue
, string name
, string ns
, XmlTypeMapping mappedType
, TypeData typeData
, bool wrapped
, bool isNullable
)
1177 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
, false);
1178 WriteMetCall ("WriteValue", strVal
);
1180 else if (isNullable
) {
1181 if (typeData
.Type
== typeof(XmlQualifiedName
))
1182 WriteMetCall ("WriteNullableQualifiedNameLiteral", GetLiteral(name
), GetLiteral(ns
), memberValue
);
1184 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
, true);
1185 WriteMetCall ("WriteNullableStringLiteral", GetLiteral(name
), GetLiteral(ns
), strVal
);
1189 if (typeData
.Type
== typeof(XmlQualifiedName
))
1190 WriteMetCall ("WriteElementQualifiedName", GetLiteral(name
), GetLiteral(ns
), memberValue
);
1192 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
, false);
1193 WriteMetCall ("WriteElementString", GetLiteral(name
),GetLiteral(ns
), strVal
);
1198 void GenerateWritePrimitiveValueEncoded (string memberValue
, string name
, string ns
, XmlQualifiedName xsiType
, XmlTypeMapping mappedType
, TypeData typeData
, bool wrapped
, bool isNullable
)
1201 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
, false);
1202 WriteMetCall ("WriteValue", strVal
);
1204 else if (isNullable
) {
1205 if (typeData
.Type
== typeof(XmlQualifiedName
))
1206 WriteMetCall ("WriteNullableQualifiedNameEncoded", GetLiteral(name
), GetLiteral(ns
), memberValue
, GetLiteral(xsiType
));
1208 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
, true);
1209 WriteMetCall ("WriteNullableStringEncoded", GetLiteral(name
), GetLiteral(ns
), strVal
, GetLiteral(xsiType
));
1213 if (typeData
.Type
== typeof(XmlQualifiedName
))
1214 WriteMetCall ("WriteElementQualifiedName", GetLiteral(name
), GetLiteral(ns
), memberValue
, GetLiteral(xsiType
));
1216 string strVal
= GenerateGetStringValue (mappedType
, typeData
, memberValue
, false);
1217 WriteMetCall ("WriteElementString", GetLiteral(name
),GetLiteral(ns
), strVal
, GetLiteral(xsiType
));
1222 string GenerateGetMemberValue (XmlTypeMapMember member
, string ob
, bool isValueList
)
1224 if (isValueList
) return GetCast (member
.TypeData
, TypeTranslator
.GetTypeData (typeof(object)), ob
+ "[" + member
.GlobalIndex
+ "]");
1225 else return ob
+ ".@" + member
.Name
;
1228 string GenerateMemberHasValueCondition (XmlTypeMapMember member
, string ob
, bool isValueList
)
1231 return ob
+ ".Length > " + member
.GlobalIndex
;
1233 else if (member
.DefaultValue
!= System
.DBNull
.Value
) {
1234 string mem
= ob
+ ".@" + member
.Name
;
1235 if (member
.DefaultValue
== null)
1236 return mem
+ " != null";
1237 else if (member
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
1238 return mem
+ " != " + GetCast (member
.TypeData
, GetLiteral (member
.DefaultValue
));
1240 return mem
+ " != " + GetLiteral (member
.DefaultValue
);
1242 else if (member
.IsOptionalValueType
)
1243 return ob
+ ".@" + member
.Name
+ "Specified";
1247 void GenerateWriteInitCallbacks ()
1249 WriteLine ("protected override void InitCallbacks ()");
1252 if (_format
== SerializationFormat
.Encoded
)
1254 foreach (XmlMapping xmap
in _mapsToGenerate
) {
1255 XmlTypeMapping map
= xmap
as XmlTypeMapping
;
1257 WriteMetCall ("AddWriteCallback", GetTypeOf(map
.TypeData
), GetLiteral(map
.XmlType
), GetLiteral(map
.Namespace
), "new XmlSerializationWriteCallback (" + GetWriteObjectCallbackName (map
) + ")");
1264 if (_format
== SerializationFormat
.Encoded
)
1266 foreach (XmlTypeMapping xmap
in _mapsToGenerate
) {
1267 XmlTypeMapping map
= xmap
as XmlTypeMapping
;
1268 if (map
== null) continue;
1269 if (map
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
1270 WriteWriteEnumCallback (map
);
1272 WriteWriteObjectCallback (map
);
1277 void WriteWriteEnumCallback (XmlTypeMapping map
)
1279 WriteLine ("void " + GetWriteObjectCallbackName (map
) + " (object ob)");
1281 WriteMetCall (GetWriteObjectName(map
), GetCast (map
.TypeData
, "ob"), GetLiteral(map
.ElementName
), GetLiteral(map
.Namespace
), "false", "true", "false");
1286 void WriteWriteObjectCallback (XmlTypeMapping map
)
1288 WriteLine ("void " + GetWriteObjectCallbackName (map
) + " (object ob)");
1290 WriteMetCall (GetWriteObjectName(map
), GetCast (map
.TypeData
, "ob"), GetLiteral(map
.ElementName
), GetLiteral(map
.Namespace
), "false", "false", "false");
1297 #region Reader Generation
1299 //*******************************************************
1300 // Reader generation
1303 public void GenerateReader (string readerClassName
, ArrayList maps
)
1305 if (_config
== null || !_config
.GenerateAsInternal
)
1306 WriteLine ("public class " + readerClassName
+ " : XmlSerializationReader");
1308 WriteLine ("internal class " + readerClassName
+ " : XmlSerializationReader");
1310 // FromBinHexString() is not public, so use reflection here.
1311 WriteLine ("static readonly System.Reflection.MethodInfo fromBinHexStringMethod = typeof (XmlConvert).GetMethod (\"FromBinHexString\", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new Type [] {typeof (string)}, null);");
1312 WriteLine ("static byte [] FromBinHexString (string input)");
1314 WriteLine ("return input == null ? null : (byte []) fromBinHexStringMethod.Invoke (null, new object [] {input});");
1317 _mapsToGenerate
= new ArrayList ();
1318 _fixupCallbacks
= new ArrayList ();
1321 for (int n
=0; n
<maps
.Count
; n
++)
1323 GenerationResult res
= (GenerationResult
) maps
[n
];
1324 _typeMap
= res
.Mapping
;
1325 _format
= _typeMap
.Format
;
1328 GenerateReadRoot ();
1331 for (int n
=0; n
<_mapsToGenerate
.Count
; n
++)
1333 XmlTypeMapping map
= _mapsToGenerate
[n
] as XmlTypeMapping
;
1334 if (map
== null) continue;
1336 GenerateReadObject (map
);
1337 if (map
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
1338 GenerateGetEnumValueMethod (map
);
1341 GenerateReadInitCallbacks ();
1343 if (_format
== SerializationFormat
.Encoded
)
1345 GenerateFixupCallbacks ();
1346 GenerateFillerCallbacks ();
1350 UpdateGeneratedTypes (_mapsToGenerate
);
1353 void GenerateReadRoot ()
1355 WriteLine ("public object " + _result
.ReadMethodName
+ " ()");
1357 WriteLine ("Reader.MoveToContent();");
1359 if (_typeMap
is XmlTypeMapping
)
1361 XmlTypeMapping typeMap
= (XmlTypeMapping
) _typeMap
;
1363 if (_format
== SerializationFormat
.Literal
)
1365 if (typeMap
.TypeData
.SchemaType
== SchemaTypes
.XmlNode
) {
1366 if (typeMap
.TypeData
.Type
== typeof (XmlDocument
))
1367 WriteLine ("return ReadXmlDocument (false);");
1369 WriteLine ("return ReadXmlNode (false);");
1371 WriteLineInd ("if (Reader.LocalName != " + GetLiteral (typeMap
.ElementName
) + " || Reader.NamespaceURI != " + GetLiteral (typeMap
.Namespace
) + ")");
1372 WriteLine ("throw CreateUnknownNodeException();");
1375 WriteLine ("return " + GetReadObjectCall (typeMap
, GetLiteral(typeMap
.IsNullable
), "true") + ";");
1380 WriteLine ("object ob = null;");
1381 WriteLine ("Reader.MoveToContent();");
1382 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
1384 WriteLineInd ("if (Reader.LocalName == " + GetLiteral(typeMap
.ElementName
) + " && Reader.NamespaceURI == " + GetLiteral (typeMap
.Namespace
) + ")");
1385 WriteLine ("ob = ReadReferencedElement();");
1387 WriteLineInd ("else ");
1388 WriteLine ("throw CreateUnknownNodeException();");
1391 WriteLineInd ("else ");
1392 WriteLine ("UnknownNode(null);");
1395 WriteLine ("ReadReferencedElements();");
1396 WriteLine ("return ob;");
1397 RegisterReferencingMap (typeMap
);
1401 WriteLine ("return " + GenerateReadMessage ((XmlMembersMapping
)_typeMap
) + ";");
1408 string GenerateReadMessage (XmlMembersMapping typeMap
)
1410 WriteLine ("object[] parameters = new object[" + typeMap
.Count
+ "];");
1413 if (typeMap
.HasWrapperElement
)
1415 if (_format
== SerializationFormat
.Encoded
)
1417 WriteLine ("while (Reader.NodeType == System.Xml.XmlNodeType.Element)");
1419 WriteLine ("string root = Reader.GetAttribute (\"root\", " + GetLiteral(XmlSerializer
.EncodingNamespace
) + ");");
1420 WriteLine ("if (root == null || System.Xml.XmlConvert.ToBoolean(root)) break;");
1421 WriteLine ("ReadReferencedElement ();");
1422 WriteLine ("Reader.MoveToContent ();");
1425 WriteLine ("if (Reader.NodeType != System.Xml.XmlNodeType.EndElement)");
1427 WriteLineInd ("if (Reader.IsEmptyElement) {");
1428 WriteLine ("Reader.Skip();");
1429 WriteLine ("Reader.MoveToContent();");
1431 WriteLineInd ("else {");
1432 WriteLine ("Reader.ReadStartElement();");
1433 GenerateReadMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "parameters", true, false);
1434 WriteLine ("ReadEndElement();");
1437 WriteLine ("Reader.MoveToContent();");
1442 // bug #79988: out parameters need to be initialized if
1443 // they are value types
1444 ClassMap classMap
= (ClassMap
) typeMap
.ObjectMap
;
1445 ArrayList members
= classMap
.AllMembers
;
1446 for (int n
= 0; n
< members
.Count
; n
++) {
1447 XmlTypeMapMember mem
= (XmlTypeMapMember
) members
[n
];
1448 if (!mem
.IsReturnValue
&& mem
.TypeData
.IsValueType
)
1449 GenerateSetMemberValueFromAttr (mem
, "parameters",
1450 String
.Format ("({0}) Activator.CreateInstance(typeof({0}), true)", mem
.TypeData
.FullTypeName
), true);
1453 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && Reader.ReadState == ReadState.Interactive)");
1455 WriteLine ("if (Reader.IsStartElement(" + GetLiteral(typeMap
.ElementName
) + ", " + GetLiteral(typeMap
.Namespace
) + "))");
1458 GenerateReadAttributeMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "parameters", true, ref dummy
);
1459 WriteLine ("if (Reader.IsEmptyElement)");
1461 WriteLine ("Reader.Skip(); Reader.MoveToContent(); continue;");
1463 WriteLine ("Reader.ReadStartElement();");
1464 GenerateReadMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "parameters", true, false);
1465 WriteLine ("ReadEndElement();");
1466 WriteLine ("break;");
1468 WriteLineInd ("else ");
1469 WriteLine ("UnknownNode(null);");
1472 WriteLine ("Reader.MoveToContent();");
1477 GenerateReadMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "parameters", true, _format
== SerializationFormat
.Encoded
);
1479 if (_format
== SerializationFormat
.Encoded
)
1480 WriteLine ("ReadReferencedElements();");
1482 return "parameters";
1485 void GenerateReadObject (XmlTypeMapping typeMap
)
1488 if (_format
== SerializationFormat
.Literal
) {
1489 WriteLine ("public " + typeMap
.TypeData
.CSharpFullName
+ " " + GetReadObjectName (typeMap
) + " (bool isNullable, bool checkType)");
1490 isNullable
= "isNullable";
1493 WriteLine ("public object " + GetReadObjectName (typeMap
) + " ()");
1494 isNullable
= "true";
1501 SetHookVar ("$TYPE", typeMap
.TypeData
.CSharpName
);
1502 SetHookVar ("$FULLTYPE", typeMap
.TypeData
.CSharpFullName
);
1503 SetHookVar ("$NULLABLE", "isNullable");
1505 switch (typeMap
.TypeData
.SchemaType
)
1507 case SchemaTypes
.Class
: GenerateReadClassInstance (typeMap
, isNullable
, "checkType"); break;
1508 case SchemaTypes
.Array
:
1509 string list
= GenerateReadListElement (typeMap
, null, isNullable
, true);
1511 WriteLine ("return " + list
+ ";");
1513 case SchemaTypes
.XmlNode
: GenerateReadXmlNodeElement (typeMap
, isNullable
); break;
1514 case SchemaTypes
.Primitive
: GenerateReadPrimitiveElement (typeMap
, isNullable
); break;
1515 case SchemaTypes
.Enum
: GenerateReadEnumElement (typeMap
, isNullable
); break;
1516 case SchemaTypes
.XmlSerializable
: GenerateReadXmlSerializableElement (typeMap
, isNullable
); break;
1517 default: throw new Exception ("Unsupported map type");
1525 void GenerateReadClassInstance (XmlTypeMapping typeMap
, string isNullable
, string checkType
)
1527 SetHookVar ("$OBJECT", "ob");
1528 if (!typeMap
.TypeData
.IsValueType
)
1530 WriteLine (typeMap
.TypeData
.CSharpFullName
+ " ob = null;");
1532 if (GenerateReadHook (HookType
.type
, typeMap
.TypeData
.Type
)) {
1533 WriteLine ("return ob;");
1537 if (_format
== SerializationFormat
.Literal
) {
1538 WriteLine ("if (" + isNullable
+ " && ReadNull()) return null;");
1540 WriteLine ("if (checkType) ");
1544 WriteLine ("if (ReadNull()) return null;");
1550 WriteLine (typeMap
.TypeData
.CSharpFullName
+ String
.Format (" ob = ({0}) Activator.CreateInstance(typeof({0}), true);", typeMap
.TypeData
.CSharpFullName
));
1552 if (GenerateReadHook (HookType
.type
, typeMap
.TypeData
.Type
)) {
1553 WriteLine ("return ob;");
1558 WriteLine ("System.Xml.XmlQualifiedName t = GetXsiType();");
1559 WriteLine ("if (t == null)");
1560 if (typeMap
.TypeData
.Type
!= typeof(object))
1563 WriteLine ("\treturn " + GetCast (typeMap
.TypeData
, "ReadTypedPrimitive (new System.Xml.XmlQualifiedName(\"anyType\", System.Xml.Schema.XmlSchema.Namespace))") + ";");
1565 foreach (XmlTypeMapping realMap
in typeMap
.DerivedTypes
)
1567 WriteLineInd ("else if (t.Name == " + GetLiteral (realMap
.XmlType
) + " && t.Namespace == " + GetLiteral (realMap
.XmlTypeNamespace
) + ")");
1568 WriteLine ("return " + GetReadObjectCall(realMap
, isNullable
, checkType
) + ";");
1572 WriteLine ("else if (t.Name != " + GetLiteral (typeMap
.XmlType
) + " || t.Namespace != " + GetLiteral (typeMap
.XmlTypeNamespace
) + ")");
1573 if (typeMap
.TypeData
.Type
== typeof(object))
1574 WriteLine ("\treturn " + GetCast (typeMap
.TypeData
, "ReadTypedPrimitive (t)") + ";");
1576 WriteLine ("\tthrow CreateUnknownTypeException(t);");
1578 if (!typeMap
.TypeData
.IsValueType
)
1580 if (_format
== SerializationFormat
.Literal
)
1583 if (typeMap
.TypeData
.Type
.IsAbstract
) {
1585 WriteLine ("return ob;");
1590 WriteLine (String
.Format ("ob = ({0}) Activator.CreateInstance(typeof({0}), true);", typeMap
.TypeData
.CSharpFullName
));
1595 WriteLine ("Reader.MoveToElement();");
1598 GenerateReadMembers (typeMap
, (ClassMap
)typeMap
.ObjectMap
, "ob", false, false);
1603 WriteLine ("return ob;");
1606 void GenerateReadMembers (XmlMapping xmlMap
, ClassMap map
, string ob
, bool isValueList
, bool readByOrder
)
1608 XmlTypeMapping typeMap
= xmlMap
as XmlTypeMapping
;
1609 Type xmlMapType
= (typeMap
!= null) ? typeMap
.TypeData
.Type
: typeof(object[]);
1613 GenerateReadAttributeMembers (xmlMap
, map
, ob
, isValueList
, ref first
);
1617 WriteLine ("Reader.MoveToElement();");
1618 WriteLineInd ("if (Reader.IsEmptyElement) {");
1619 WriteLine ("Reader.Skip ();");
1620 GenerateSetListMembersDefaults (typeMap
, map
, ob
, isValueList
);
1621 WriteLine ("return " + ob
+ ";");
1625 WriteLine ("Reader.ReadStartElement();");
1630 WriteLine("Reader.MoveToContent();");
1633 if (!GenerateReadHook (HookType
.elements
, xmlMapType
))
1635 string[] readFlag
= null;
1636 if (map
.ElementMembers
!= null && !readByOrder
)
1638 string readFlagsVars
= string.Empty
;
1639 readFlag
= new string[map
.ElementMembers
.Count
];
1641 foreach (XmlTypeMapMember mem
in map
.ElementMembers
) {
1642 // The text collector doesn't need a flag
1643 if (!((mem
is XmlTypeMapMemberElement
) && ((XmlTypeMapMemberElement
)mem
).IsXmlTextCollector
)) {
1644 readFlag
[n
] = GetBoolTempVar ();
1645 if (readFlagsVars
.Length
> 0) readFlagsVars
+= ", ";
1646 readFlagsVars
+= readFlag
[n
] + "=false";
1650 if (readFlagsVars
.Length
> 0) {
1651 readFlagsVars
= "bool " + readFlagsVars
;
1652 WriteLine (readFlagsVars
+ ";");
1657 string[] indexes
= null;
1658 string[] flatLists
= null;
1659 string[] flatListsChoices
= null;
1661 if (map
.FlatLists
!= null)
1663 indexes
= new string[map
.FlatLists
.Count
];
1664 flatLists
= new string[map
.FlatLists
.Count
];
1666 string code
= "int ";
1667 for (int n
=0; n
<map
.FlatLists
.Count
; n
++)
1669 XmlTypeMapMemberElement mem
= (XmlTypeMapMemberElement
)map
.FlatLists
[n
];
1670 indexes
[n
] = GetNumTempVar ();
1671 if (n
> 0) code
+= ", ";
1672 code
+= indexes
[n
] + "=0";
1673 if (!MemberHasReadReplaceHook (xmlMapType
, mem
)) {
1674 flatLists
[n
] = GetObTempVar ();
1676 WriteLine (mem
.TypeData
.CSharpFullName
+ " " + flatLists
[n
] + ";");
1677 if (IsReadOnly (typeMap
, mem
, mem
.TypeData
, isValueList
)) {
1678 rval
= GenerateGetMemberValue (mem
, ob
, isValueList
);
1679 WriteLine (flatLists
[n
] + " = " + rval
+ ";");
1680 } else if (mem
.TypeData
.Type
.IsArray
) {
1681 rval
= GenerateInitializeList (mem
.TypeData
);
1682 WriteLine (flatLists
[n
] + " = " + rval
+ ";");
1684 WriteLine (flatLists
[n
] + " = " + GenerateGetMemberValue (mem
, ob
, isValueList
) + ";");
1685 WriteLineInd ("if (((object)" + flatLists
[n
] + ") == null) {");
1686 WriteLine (flatLists
[n
] + " = " + GenerateInitializeList (mem
.TypeData
) + ";");
1687 GenerateSetMemberValue (mem
, ob
, flatLists
[n
], isValueList
);
1692 if (mem
.ChoiceMember
!= null) {
1693 if (flatListsChoices
== null)
1694 flatListsChoices
= new string [map
.FlatLists
.Count
];
1695 flatListsChoices
[n
] = GetObTempVar ();
1696 string rval
= GenerateInitializeList (mem
.ChoiceTypeData
);
1697 WriteLine (mem
.ChoiceTypeData
.CSharpFullName
+ " " + flatListsChoices
[n
] + " = " + rval
+ ";");
1700 WriteLine (code
+ ";");
1704 if (_format
== SerializationFormat
.Encoded
&& map
.ElementMembers
!= null)
1706 _fixupCallbacks
.Add (xmlMap
);
1707 WriteLine ("Fixup fixup = new Fixup(" + ob
+ ", new XmlSerializationFixupCallback(" + GetFixupCallbackName (xmlMap
) + "), " + map
.ElementMembers
.Count
+ ");");
1708 WriteLine ("AddFixup (fixup);");
1712 ArrayList infos
= null;
1716 if (map
.ElementMembers
!= null) maxInd
= map
.ElementMembers
.Count
;
1721 infos
= new ArrayList ();
1722 infos
.AddRange (map
.AllElementInfos
);
1723 maxInd
= infos
.Count
;
1725 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
1727 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
1732 for (int ind
= 0; ind
< maxInd
; ind
++)
1734 XmlTypeMapElementInfo info
= readByOrder
? map
.GetElement (ind
) : (XmlTypeMapElementInfo
) infos
[ind
];
1738 if (info
.IsTextElement
|| info
.IsUnnamedAnyElement
) continue;
1739 string elemCond
= first
? "" : "else ";
1741 if (!(info
.Member
.IsReturnValue
&& _format
== SerializationFormat
.Encoded
)) {
1742 elemCond
+= "Reader.LocalName == " + GetLiteral (info
.ElementName
);
1743 if (!map
.IgnoreMemberNamespace
) elemCond
+= " && Reader.NamespaceURI == " + GetLiteral (info
.Namespace
);
1746 elemCond
+= "!" + readFlag
[info
.Member
.Index
] + ") {";
1747 WriteLineInd (elemCond
);
1750 if (info
.Member
.GetType() == typeof (XmlTypeMapMemberList
))
1752 if (_format
== SerializationFormat
.Encoded
&& info
.MultiReferenceType
)
1754 string list
= GetObTempVar ();
1755 WriteLine ("object " + list
+ " = ReadReferencingElement (out fixup.Ids[" + info
.Member
.Index
+ "]);");
1756 RegisterReferencingMap (info
.MappedType
);
1758 WriteLineInd ("if (fixup.Ids[" + info
.Member
.Index
+ "] == null) {"); // Already read
1759 if (IsReadOnly (typeMap
, info
.Member
, info
.TypeData
, isValueList
))
1760 WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral(info
.TypeData
.CSharpFullName
) + ");");
1762 GenerateSetMemberValue (info
.Member
, ob
, GetCast (info
.Member
.TypeData
,list
), isValueList
);
1765 if (!info
.MappedType
.TypeData
.Type
.IsArray
)
1767 WriteLineInd ("else {");
1768 if (IsReadOnly (typeMap
, info
.Member
, info
.TypeData
, isValueList
))
1769 WriteLine (list
+ " = " + GenerateGetMemberValue (info
.Member
, ob
, isValueList
) + ";");
1771 WriteLine (list
+ " = " + GenerateCreateList (info
.MappedType
.TypeData
.Type
) + ";");
1772 GenerateSetMemberValue (info
.Member
, ob
, GetCast (info
.Member
.TypeData
,list
), isValueList
);
1774 WriteLine ("AddFixup (new CollectionFixup (" + list
+ ", new XmlSerializationCollectionFixupCallback (" + GetFillListName(info
.Member
.TypeData
) + "), fixup.Ids[" + info
.Member
.Index
+ "]));");
1775 WriteLine ("fixup.Ids[" + info
.Member
.Index
+ "] = null;"); // The member already has the value, no further fix needed.
1781 if (!GenerateReadMemberHook (xmlMapType
, info
.Member
)) {
1782 if (IsReadOnly (typeMap
, info
.Member
, info
.TypeData
, isValueList
)) {
1783 GenerateReadListElement (info
.MappedType
, GenerateGetMemberValue (info
.Member
, ob
, isValueList
), GetLiteral(info
.IsNullable
), false);
1784 } else if (info
.MappedType
.TypeData
.Type
.IsArray
) {
1785 if (info
.IsNullable
)
1786 GenerateSetMemberValue (info
.Member
, ob
, GenerateReadListElement (info
.MappedType
, null, GetLiteral(info
.IsNullable
), true), isValueList
);
1788 string list
= GetObTempVar ();
1789 WriteLine (info
.MappedType
.TypeData
.CSharpFullName
+ " " + list
+ " = " + GenerateReadListElement (info
.MappedType
, null, GetLiteral(info
.IsNullable
), true) + ";");
1790 WriteLineInd ("if (((object)" + list
+ ") != null) {");
1791 GenerateSetMemberValue (info
.Member
, ob
, list
, isValueList
);
1795 string list
= GetObTempVar ();
1796 WriteLine (info
.MappedType
.TypeData
.CSharpFullName
+ " " + list
+ " = " + GenerateGetMemberValue (info
.Member
, ob
, isValueList
) + ";");
1797 WriteLineInd ("if (((object)" + list
+ ") == null) {");
1798 WriteLine (list
+ " = " + GenerateCreateList (info
.MappedType
.TypeData
.Type
) + ";");
1799 GenerateSetMemberValue (info
.Member
, ob
, list
, isValueList
);
1801 GenerateReadListElement (info
.MappedType
, list
, GetLiteral(info
.IsNullable
), true);
1807 WriteLine (readFlag
[info
.Member
.Index
] + " = true;");
1809 else if (info
.Member
.GetType() == typeof (XmlTypeMapMemberFlatList
))
1811 XmlTypeMapMemberFlatList mem
= (XmlTypeMapMemberFlatList
)info
.Member
;
1812 if (!GenerateReadArrayMemberHook (xmlMapType
, info
.Member
, indexes
[mem
.FlatArrayIndex
])) {
1813 GenerateAddListValue (mem
.TypeData
, flatLists
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], GenerateReadObjectElement (info
), !IsReadOnly (typeMap
, info
.Member
, info
.TypeData
, isValueList
));
1814 if (mem
.ChoiceMember
!= null) {
1815 GenerateAddListValue (mem
.ChoiceTypeData
, flatListsChoices
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], GetLiteral (info
.ChoiceValue
), true);
1819 WriteLine (indexes
[mem
.FlatArrayIndex
] + "++;");
1821 else if (info
.Member
.GetType() == typeof (XmlTypeMapMemberAnyElement
))
1823 XmlTypeMapMemberAnyElement mem
= (XmlTypeMapMemberAnyElement
)info
.Member
;
1824 if (mem
.TypeData
.IsListType
) {
1825 if (!GenerateReadArrayMemberHook (xmlMapType
, info
.Member
, indexes
[mem
.FlatArrayIndex
])) {
1826 GenerateAddListValue (mem
.TypeData
, flatLists
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], GetReadXmlNode (mem
.TypeData
.ListItemTypeData
, false), true);
1829 WriteLine (indexes
[mem
.FlatArrayIndex
] + "++;");
1832 if (!GenerateReadMemberHook (xmlMapType
, info
.Member
)) {
1833 GenerateSetMemberValue (mem
, ob
, GetReadXmlNode(mem
.TypeData
, false), isValueList
);
1838 else if (info
.Member
.GetType() == typeof(XmlTypeMapMemberElement
))
1841 WriteLine (readFlag
[info
.Member
.Index
] + " = true;");
1842 if (_format
== SerializationFormat
.Encoded
)
1844 string val
= GetObTempVar ();
1845 RegisterReferencingMap (info
.MappedType
);
1847 if (info
.Member
.TypeData
.SchemaType
!= SchemaTypes
.Primitive
)
1848 WriteLine ("object " + val
+ " = ReadReferencingElement (out fixup.Ids[" + info
.Member
.Index
+ "]);");
1850 WriteLine ("object " + val
+ " = ReadReferencingElement (" + GetLiteral(info
.Member
.TypeData
.XmlType
) + ", " + GetLiteral(System
.Xml
.Schema
.XmlSchema
.Namespace
) + ", out fixup.Ids[" + info
.Member
.Index
+ "]);");
1852 if (info
.MultiReferenceType
)
1853 WriteLineInd ("if (fixup.Ids[" + info
.Member
.Index
+ "] == null) {"); // already read
1855 WriteLineInd ("if (" + val
+ " != null) {"); // null value
1857 GenerateSetMemberValue (info
.Member
, ob
, GetCast (info
.Member
.TypeData
,val
), isValueList
);
1860 else if (!GenerateReadMemberHook (xmlMapType
, info
.Member
)) {
1861 if (info
.ChoiceValue
!= null) {
1862 XmlTypeMapMemberElement imem
= (XmlTypeMapMemberElement
) info
.Member
;
1863 WriteLine (ob
+ ".@" + imem
.ChoiceMember
+ " = " + GetLiteral(info
.ChoiceValue
) + ";");
1865 GenerateSetMemberValue (info
.Member
, ob
, GenerateReadObjectElement (info
), isValueList
);
1870 throw new InvalidOperationException ("Unknown member type");
1875 WriteLine ("Reader.MoveToContent();");
1881 if (!first
) WriteLineInd ("else {");
1883 if (map
.DefaultAnyElementMember
!= null)
1885 XmlTypeMapMemberAnyElement mem
= map
.DefaultAnyElementMember
;
1886 if (mem
.TypeData
.IsListType
) {
1887 if (!GenerateReadArrayMemberHook (xmlMapType
, mem
, indexes
[mem
.FlatArrayIndex
])) {
1888 GenerateAddListValue (mem
.TypeData
, flatLists
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], GetReadXmlNode(mem
.TypeData
.ListItemTypeData
, false), true);
1891 WriteLine (indexes
[mem
.FlatArrayIndex
] + "++;");
1893 else if (! GenerateReadMemberHook (xmlMapType
, mem
)) {
1894 GenerateSetMemberValue (mem
, ob
, GetReadXmlNode(mem
.TypeData
, false), isValueList
);
1899 if (!GenerateReadHook (HookType
.unknownElement
, xmlMapType
)) {
1900 WriteLine ("UnknownNode (" + ob
+ ");");
1905 if (!first
) WriteLineUni ("}");
1909 if (map
.XmlTextCollector
!= null)
1911 WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text || Reader.NodeType == System.Xml.XmlNodeType.CDATA)");
1914 if (map
.XmlTextCollector
is XmlTypeMapMemberExpandable
)
1916 XmlTypeMapMemberExpandable mem
= (XmlTypeMapMemberExpandable
)map
.XmlTextCollector
;
1917 XmlTypeMapMemberFlatList flatl
= mem
as XmlTypeMapMemberFlatList
;
1918 TypeData itype
= (flatl
== null) ? mem
.TypeData
.ListItemTypeData
: flatl
.ListMap
.FindTextElement().TypeData
;
1920 if (!GenerateReadArrayMemberHook (xmlMapType
, map
.XmlTextCollector
, indexes
[mem
.FlatArrayIndex
])) {
1921 string val
= (itype
.Type
== typeof (string)) ? "Reader.ReadString()" : GetReadXmlNode (itype
, false);
1922 GenerateAddListValue (mem
.TypeData
, flatLists
[mem
.FlatArrayIndex
], indexes
[mem
.FlatArrayIndex
], val
, true);
1925 WriteLine (indexes
[mem
.FlatArrayIndex
] + "++;");
1927 else if (!GenerateReadMemberHook (xmlMapType
, map
.XmlTextCollector
))
1929 XmlTypeMapMemberElement mem
= (XmlTypeMapMemberElement
) map
.XmlTextCollector
;
1930 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
) mem
.ElementInfo
[0];
1931 if (info
.TypeData
.Type
== typeof (string))
1932 GenerateSetMemberValue (mem
, ob
, "ReadString (" + GenerateGetMemberValue (mem
, ob
, isValueList
) + ")", isValueList
);
1935 string str
= GetStrTempVar ();
1936 WriteLine ("string " + str
+ " = Reader.ReadString();");
1937 GenerateSetMemberValue (mem
, ob
, GenerateGetValueFromXmlString (str
, info
.TypeData
, info
.MappedType
, info
.IsNullable
), isValueList
);
1946 WriteLine ("\tUnknownNode(" + ob
+ ");");
1948 WriteLine ("Reader.MoveToContent();");
1952 WriteLine ("Reader.MoveToContent();");
1954 if (flatLists
!= null)
1957 foreach (XmlTypeMapMemberExpandable mem
in map
.FlatLists
)
1959 if (MemberHasReadReplaceHook (xmlMapType
, mem
)) continue;
1961 string list
= flatLists
[mem
.FlatArrayIndex
];
1962 if (mem
.TypeData
.Type
.IsArray
)
1963 WriteLine (list
+ " = (" + mem
.TypeData
.CSharpFullName
+ ") ShrinkArray (" + list
+ ", " + indexes
[mem
.FlatArrayIndex
] + ", " + GetTypeOf(mem
.TypeData
.Type
.GetElementType()) + ", true);");
1964 if (!IsReadOnly (typeMap
, mem
, mem
.TypeData
, isValueList
) && mem
.TypeData
.Type
.IsArray
)
1965 GenerateSetMemberValue (mem
, ob
, list
, isValueList
);
1969 if (flatListsChoices
!= null)
1972 foreach (XmlTypeMapMemberExpandable mem
in map
.FlatLists
)
1974 if (MemberHasReadReplaceHook (xmlMapType
, mem
)) continue;
1975 if (mem
.ChoiceMember
== null) continue;
1977 string list
= flatListsChoices
[mem
.FlatArrayIndex
];
1978 WriteLine (list
+ " = (" + mem
.ChoiceTypeData
.CSharpFullName
+ ") ShrinkArray (" + list
+ ", " + indexes
[mem
.FlatArrayIndex
] + ", " + GetTypeOf(mem
.ChoiceTypeData
.Type
.GetElementType()) + ", true);");
1979 WriteLine (ob
+ ".@" + mem
.ChoiceMember
+ " = " + list
+ ";");
1983 GenerateSetListMembersDefaults (typeMap
, map
, ob
, isValueList
);
1991 WriteLine ("ReadEndElement();");
1995 void GenerateReadAttributeMembers (XmlMapping xmlMap
, ClassMap map
, string ob
, bool isValueList
, ref bool first
)
1997 XmlTypeMapping typeMap
= xmlMap
as XmlTypeMapping
;
1998 Type xmlMapType
= (typeMap
!= null) ? typeMap
.TypeData
.Type
: typeof(object[]);
2000 if (GenerateReadHook (HookType
.attributes
, xmlMapType
))
2003 XmlTypeMapMember anyAttrMember
= map
.DefaultAnyAttributeMember
;
2005 if (anyAttrMember
!= null)
2007 WriteLine ("int anyAttributeIndex = 0;");
2008 WriteLine (anyAttrMember
.TypeData
.CSharpFullName
+ " anyAttributeArray = null;");
2011 WriteLine ("while (Reader.MoveToNextAttribute())");
2014 if (map
.AttributeMembers
!= null) {
2015 foreach (XmlTypeMapMemberAttribute at
in map
.AttributeMembers
)
2017 WriteLineInd ((first
?"":"else ") + "if (Reader.LocalName == " + GetLiteral (at
.AttributeName
) + " && Reader.NamespaceURI == " + GetLiteral (at
.Namespace
) + ") {");
2018 if (!GenerateReadMemberHook (xmlMapType
, at
)) {
2019 GenerateSetMemberValue (at
, ob
, GenerateGetValueFromXmlString ("Reader.Value", at
.TypeData
, at
.MappedType
, false), isValueList
);
2026 WriteLineInd ((first
?"":"else ") + "if (IsXmlnsAttribute (Reader.Name)) {");
2028 // If the map has NamespaceDeclarations,
2029 // then store this xmlns to the given member.
2030 // If the instance doesn't exist, then create.
2032 if (map
.NamespaceDeclarations
!= null) {
2033 if (!GenerateReadMemberHook (xmlMapType
, map
.NamespaceDeclarations
)) {
2034 string nss
= ob
+ ".@" + map
.NamespaceDeclarations
.Name
;
2035 WriteLine ("if (" + nss
+ " == null) " + nss
+ " = new XmlSerializerNamespaces ();");
2036 WriteLineInd ("if (Reader.Prefix == \"xmlns\")");
2037 WriteLine (nss
+ ".Add (Reader.LocalName, Reader.Value);");
2039 WriteLineInd ("else");
2040 WriteLine (nss
+ ".Add (\"\", Reader.Value);");
2047 WriteLineInd ("else {");
2049 if (anyAttrMember
!= null)
2051 if (!GenerateReadArrayMemberHook (xmlMapType
, anyAttrMember
, "anyAttributeIndex")) {
2052 WriteLine ("System.Xml.XmlAttribute attr = (System.Xml.XmlAttribute) Document.ReadNode(Reader);");
2053 if (typeof(System
.Xml
.Schema
.XmlSchemaAnnotated
).IsAssignableFrom (xmlMapType
))
2054 WriteLine ("ParseWsdlArrayType (attr);");
2055 GenerateAddListValue (anyAttrMember
.TypeData
, "anyAttributeArray", "anyAttributeIndex", GetCast (anyAttrMember
.TypeData
.ListItemTypeData
, "attr"), true);
2058 WriteLine ("anyAttributeIndex++;");
2061 if (!GenerateReadHook (HookType
.unknownAttribute
, xmlMapType
)) {
2062 WriteLine ("UnknownNode (" + ob
+ ");");
2070 if (anyAttrMember
!= null && !MemberHasReadReplaceHook (xmlMapType
, anyAttrMember
))
2073 WriteLine("anyAttributeArray = (" + anyAttrMember
.TypeData
.CSharpFullName
+ ") ShrinkArray (anyAttributeArray, anyAttributeIndex, " + GetTypeOf(anyAttrMember
.TypeData
.Type
.GetElementType()) + ", true);");
2074 GenerateSetMemberValue (anyAttrMember
, ob
, "anyAttributeArray", isValueList
);
2077 WriteLine ("Reader.MoveToElement ();");
2082 void GenerateSetListMembersDefaults (XmlTypeMapping typeMap
, ClassMap map
, string ob
, bool isValueList
)
2084 if (map
.ListMembers
!= null)
2086 ArrayList members
= map
.ListMembers
;
2087 for (int n
=0; n
<members
.Count
; n
++) {
2088 XmlTypeMapMember mem
= (XmlTypeMapMember
) members
[n
];
2089 if (IsReadOnly (typeMap
, mem
, mem
.TypeData
, isValueList
))
2091 WriteLineInd ("if (" + GenerateGetMemberValue (mem
, ob
, isValueList
) + " == null) {");
2092 GenerateSetMemberValue (mem
, ob
, GenerateInitializeList (mem
.TypeData
), isValueList
);
2098 bool IsReadOnly (XmlTypeMapping map
, XmlTypeMapMember member
, TypeData memType
, bool isValueList
)
2100 if (isValueList
) return !memType
.HasPublicConstructor
;
2101 else return member
.IsReadOnly (map
.TypeData
.Type
) || !memType
.HasPublicConstructor
;
2104 void GenerateSetMemberValue (XmlTypeMapMember member
, string ob
, string value, bool isValueList
)
2106 if (isValueList
) WriteLine (ob
+ "[" + member
.GlobalIndex
+ "] = " + value + ";");
2108 WriteLine (ob
+ ".@" + member
.Name
+ " = " + value + ";");
2109 if (member
.IsOptionalValueType
)
2110 WriteLine (ob
+ "." + member
.Name
+ "Specified = true;");
2114 void GenerateSetMemberValueFromAttr (XmlTypeMapMember member
, string ob
, string value, bool isValueList
)
2116 // Enumeration values specified in custom attributes are stored as integer
2117 // values if the custom attribute property is of type object. So, it is
2118 // necessary to convert to the enum type before asigning the value to the field.
2120 if (member
.TypeData
.Type
.IsEnum
)
2121 value = GetCast (member
.TypeData
.Type
, value);
2122 GenerateSetMemberValue (member
, ob
, value, isValueList
);
2125 string GenerateReadObjectElement (XmlTypeMapElementInfo elem
)
2127 switch (elem
.TypeData
.SchemaType
)
2129 case SchemaTypes
.XmlNode
:
2130 return GetReadXmlNode (elem
.TypeData
, true);
2132 case SchemaTypes
.Primitive
:
2133 case SchemaTypes
.Enum
:
2134 return GenerateReadPrimitiveValue (elem
);
2136 case SchemaTypes
.Array
:
2137 return GenerateReadListElement (elem
.MappedType
, null, GetLiteral(elem
.IsNullable
), true);
2139 case SchemaTypes
.Class
:
2140 return GetReadObjectCall (elem
.MappedType
, GetLiteral(elem
.IsNullable
), "true");
2142 case SchemaTypes
.XmlSerializable
:
2143 return GetCast (elem
.TypeData
, String
.Format ("({0}) ReadSerializable (({0}) Activator.CreateInstance(typeof({0}), true))", elem
.TypeData
.CSharpFullName
));
2146 throw new NotSupportedException ("Invalid value type");
2150 string GenerateReadPrimitiveValue (XmlTypeMapElementInfo elem
)
2152 if (elem
.TypeData
.Type
== typeof (XmlQualifiedName
)) {
2153 if (elem
.IsNullable
) return "ReadNullableQualifiedName ()";
2154 else return "ReadElementQualifiedName ()";
2156 else if (elem
.IsNullable
) {
2157 string str
= GetStrTempVar ();
2158 WriteLine ("string " + str
+ " = ReadNullableString ();");
2159 return GenerateGetValueFromXmlString (str
, elem
.TypeData
, elem
.MappedType
, true);
2162 string str
= GetStrTempVar ();
2163 WriteLine ("string " + str
+ " = Reader.ReadElementString ();");
2164 return GenerateGetValueFromXmlString (str
, elem
.TypeData
, elem
.MappedType
, false);
2168 string GenerateGetValueFromXmlString (string value, TypeData typeData
, XmlTypeMapping typeMap
, bool isNullable
)
2170 if (typeData
.SchemaType
== SchemaTypes
.Array
)
2171 return GenerateReadListString (typeMap
, value);
2172 else if (typeData
.SchemaType
== SchemaTypes
.Enum
)
2173 return GenerateGetEnumValue (typeMap
, value, isNullable
);
2174 else if (typeData
.Type
== typeof (XmlQualifiedName
))
2175 return "ToXmlQualifiedName (" + value + ")";
2177 return XmlCustomFormatter
.GenerateFromXmlString (typeData
, value);
2180 string GenerateReadListElement (XmlTypeMapping typeMap
, string list
, string isNullable
, bool canCreateInstance
)
2182 Type listType
= typeMap
.TypeData
.Type
;
2183 ListMap listMap
= (ListMap
)typeMap
.ObjectMap
;
2184 bool doNullCheck
= typeMap
.TypeData
.Type
.IsArray
;
2186 if (canCreateInstance
&& typeMap
.TypeData
.HasPublicConstructor
)
2189 list
= GetObTempVar ();
2190 WriteLine (typeMap
.TypeData
.CSharpFullName
+ " " + list
+ " = null;");
2192 WriteLineInd ("if (!ReadNull()) {");
2193 WriteLine (list
+ " = " + GenerateCreateList (listType
) + ";");
2196 WriteLineInd ("if (!ReadNull()) {");
2202 WriteLineInd ("if (((object)" + list
+ ") == null)");
2203 WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap
.TypeData
.CSharpFullName
) + ");");
2205 doNullCheck
= false;
2208 WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap
.TypeData
.CSharpFullName
) + ");");
2213 WriteLineInd ("if (Reader.IsEmptyElement) {");
2214 WriteLine ("Reader.Skip();");
2215 if (listType
.IsArray
)
2216 WriteLine (list
+ " = (" + typeMap
.TypeData
.CSharpFullName
+ ") ShrinkArray (" + list
+ ", 0, " + GetTypeOf(listType
.GetElementType()) + ", false);");
2219 WriteLineInd ("} else {");
2221 string index
= GetNumTempVar ();
2222 WriteLine ("int " + index
+ " = 0;");
2223 WriteLine ("Reader.ReadStartElement();");
2224 WriteLine ("Reader.MoveToContent();");
2227 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
2229 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
2233 foreach (XmlTypeMapElementInfo elemInfo
in listMap
.ItemInfo
)
2235 WriteLineInd ((first
?"":"else ") + "if (Reader.LocalName == " + GetLiteral (elemInfo
.ElementName
) + " && Reader.NamespaceURI == " + GetLiteral (elemInfo
.Namespace
) + ") {");
2236 GenerateAddListValue (typeMap
.TypeData
, list
, index
, GenerateReadObjectElement (elemInfo
), false);
2237 WriteLine (index
+ "++;");
2241 if (!first
) WriteLine ("else UnknownNode (null);");
2242 else WriteLine ("UnknownNode (null);");
2245 WriteLine ("else UnknownNode (null);");
2247 WriteLine ("Reader.MoveToContent();");
2250 WriteLine ("ReadEndElement();");
2252 if (listType
.IsArray
)
2253 WriteLine (list
+ " = (" + typeMap
.TypeData
.CSharpFullName
+ ") ShrinkArray (" + list
+ ", " + index
+ ", " + GetTypeOf(listType
.GetElementType()) + ", false);");
2262 string GenerateReadListString (XmlTypeMapping typeMap
, string values
)
2264 Type listType
= typeMap
.TypeData
.Type
;
2265 ListMap listMap
= (ListMap
)typeMap
.ObjectMap
;
2266 string itemType
= ToCSharpFullName (listType
.GetElementType());
2268 string list
= GetObTempVar ();
2269 WriteLine (itemType
+ "[] " + list
+ ";");
2271 string var = GetStrTempVar ();
2272 WriteLine ("string " + var + " = " + values
+ ".Trim();");
2273 WriteLineInd ("if (" + var + " != string.Empty) {");
2275 string valueArray
= GetObTempVar ();
2276 WriteLine ("string[] " + valueArray
+ " = " + var + ".Split (' ');");
2278 WriteLine (list
+ " = new " + GetArrayDeclaration (listType
, valueArray
+ ".Length") + ";");
2280 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
)listMap
.ItemInfo
[0];
2282 string index
= GetNumTempVar ();
2283 WriteLineInd ("for (int " + index
+ " = 0; " + index
+ " < " + valueArray
+ ".Length; " + index
+ "++)");
2284 WriteLine (list
+ "[" + index
+ "] = " + GenerateGetValueFromXmlString (valueArray
+ "[" + index
+ "]", info
.TypeData
, info
.MappedType
, info
.IsNullable
) + ";");
2288 WriteLine ("\t" + list
+ " = new " + GetArrayDeclaration (listType
, "0") + ";");
2293 string GetArrayDeclaration (Type type
, string length
)
2295 Type t
= type
.GetElementType();
2296 System
.Text
.StringBuilder sb
= new System
.Text
.StringBuilder ();
2297 sb
.Append ('[').Append (length
).Append (']');
2300 t
= t
.GetElementType();
2302 sb
.Insert (0, ToCSharpFullName (t
));
2303 return sb
.ToString ();
2306 void GenerateAddListValue (TypeData listType
, string list
, string index
, string value, bool canCreateInstance
)
2308 Type type
= listType
.Type
;
2311 WriteLine (list
+ " = (" + ToCSharpFullName (type
) + ") EnsureArrayIndex (" + list
+ ", " + index
+ ", " + GetTypeOf(type
.GetElementType()) + ");");
2312 WriteLine (list
+ "[" + index
+ "] = " + value + ";");
2314 else // Must be IEnumerable
2316 WriteLine ("if (((object)" + list
+ ") == null)");
2317 if (canCreateInstance
)
2318 WriteLine ("\t" + list
+ String
.Format (" = ({0}) Activator.CreateInstance(typeof({0}), true);", listType
.CSharpFullName
));
2320 WriteLine ("\tthrow CreateReadOnlyCollectionException (" + GetLiteral (listType
.CSharpFullName
) + ");");
2322 WriteLine (list
+ ".Add (" + value + ");");
2326 string GenerateCreateList (Type listType
)
2328 if (listType
.IsArray
)
2329 return "(" + ToCSharpFullName (listType
) + ") EnsureArrayIndex (null, 0, " + GetTypeOf(listType
.GetElementType()) + ")";
2331 return "new " + ToCSharpFullName (listType
) + "()";
2334 string GenerateInitializeList (TypeData listType
)
2336 if (listType
.Type
.IsArray
)
2339 return "new " + listType
.CSharpFullName
+ "()";
2342 void GenerateFillerCallbacks ()
2344 foreach (TypeData td
in _listsToFill
)
2346 string metName
= GetFillListName (td
);
2347 WriteLine ("void " + metName
+ " (object list, object source)");
2349 WriteLine ("if (((object)list) == null) throw CreateReadOnlyCollectionException (" + GetLiteral (td
.CSharpFullName
) + ");");
2352 WriteLine (td
.CSharpFullName
+ " dest = (" + td
.CSharpFullName
+ ") list;");
2353 WriteLine ("foreach (object ob in (IEnumerable)source)");
2354 WriteLine ("\tdest.Add (" + GetCast (td
.ListItemTypeData
, "ob") + ");");
2360 void GenerateReadXmlNodeElement (XmlTypeMapping typeMap
, string isNullable
)
2362 WriteLine ("return " + GetReadXmlNode (typeMap
.TypeData
, false) + ";");
2365 void GenerateReadPrimitiveElement (XmlTypeMapping typeMap
, string isNullable
)
2367 WriteLine ("XmlQualifiedName t = GetXsiType();");
2368 WriteLine ("if (t == null) t = new XmlQualifiedName (" + GetLiteral(typeMap
.XmlType
) + ", " + GetLiteral(typeMap
.Namespace
) + ");");
2369 WriteLine ("return " + GetCast (typeMap
.TypeData
, "ReadTypedPrimitive (t)") + ";");
2372 void GenerateReadEnumElement (XmlTypeMapping typeMap
, string isNullable
)
2374 WriteLine ("Reader.ReadStartElement ();");
2375 WriteLine (typeMap
.TypeData
.CSharpFullName
+ " res = " + GenerateGetEnumValue (typeMap
, "Reader.ReadString()", false) + ";");
2376 WriteLineInd ("if (Reader.NodeType != XmlNodeType.None)");
2377 WriteLineUni ("Reader.ReadEndElement ();");
2378 WriteLine ("return res;");
2381 string GenerateGetEnumValue (XmlTypeMapping typeMap
, string val
, bool isNullable
)
2384 return "(" + val
+ ") != null ? " + GetGetEnumValueName (typeMap
) + " (" + val
+ ") : (" + typeMap
.TypeData
.CSharpFullName
+ "?) null";
2386 return GetGetEnumValueName (typeMap
) + " (" + val
+ ")";
2389 void GenerateGetEnumValueMethod (XmlTypeMapping typeMap
)
2391 string metName
= GetGetEnumValueName (typeMap
);
2392 EnumMap map
= (EnumMap
) typeMap
.ObjectMap
;
2396 string switchMethod
= metName
+ "_Switch";
2397 WriteLine (typeMap
.TypeData
.CSharpFullName
+ " " + metName
+ " (string xmlName)");
2399 WriteLine ("xmlName = xmlName.Trim();");
2400 WriteLine ("if (xmlName.Length == 0) return (" + typeMap
.TypeData
.CSharpFullName
+ ")0;");
2401 WriteLine (typeMap
.TypeData
.CSharpFullName
+ " sb = (" + typeMap
.TypeData
.CSharpFullName
+ ")0;");
2402 WriteLine ("string[] enumNames = xmlName.Split (null);");
2403 WriteLine ("foreach (string name in enumNames)");
2405 WriteLine ("if (name == string.Empty) continue;");
2406 WriteLine ("sb |= " + switchMethod
+ " (name); ");
2408 WriteLine ("return sb;");
2411 metName
= switchMethod
;
2414 WriteLine (typeMap
.TypeData
.CSharpFullName
+ " " + metName
+ " (string xmlName)");
2416 GenerateGetSingleEnumValue (typeMap
, "xmlName");
2421 void GenerateGetSingleEnumValue (XmlTypeMapping typeMap
, string val
)
2423 EnumMap map
= (EnumMap
) typeMap
.ObjectMap
;
2424 WriteLine ("switch (" + val
+ ")");
2426 foreach (EnumMap
.EnumMapMember mem
in map
.Members
)
2428 WriteLine ("case " + GetLiteral (mem
.XmlName
) + ": return " + typeMap
.TypeData
.CSharpFullName
+ ".@" + mem
.EnumName
+ ";");
2430 WriteLineInd ("default:");
2431 WriteLine ("throw CreateUnknownConstantException (" + val
+ ", typeof(" + typeMap
.TypeData
.CSharpFullName
+ "));");
2436 void GenerateReadXmlSerializableElement (XmlTypeMapping typeMap
, string isNullable
)
2438 WriteLine ("Reader.MoveToContent ();");
2439 WriteLine ("if (Reader.NodeType == XmlNodeType.Element)");
2441 WriteLine ("if (Reader.LocalName == " + GetLiteral (typeMap
.ElementName
) + " && Reader.NamespaceURI == " + GetLiteral (typeMap
.Namespace
) + ")");
2442 WriteLine (String
.Format ("\treturn ({0}) ReadSerializable (({0}) Activator.CreateInstance(typeof({0}), true));", typeMap
.TypeData
.CSharpFullName
));
2444 WriteLine ("\tthrow CreateUnknownNodeException ();");
2446 WriteLine ("else UnknownNode (null);");
2448 WriteLine ("return default (" + typeMap
.TypeData
.CSharpFullName
+ ");");
2451 void GenerateReadInitCallbacks ()
2453 WriteLine ("protected override void InitCallbacks ()");
2456 if (_format
== SerializationFormat
.Encoded
)
2458 foreach (XmlMapping xmap
in _mapsToGenerate
)
2460 XmlTypeMapping map
= xmap
as XmlTypeMapping
;
2461 if (map
== null) continue;
2462 if (map
.TypeData
.SchemaType
== SchemaTypes
.Class
|| map
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
2463 WriteMetCall ("AddReadCallback", GetLiteral (map
.XmlType
), GetLiteral(map
.Namespace
), GetTypeOf(map
.TypeData
.Type
), "new XmlSerializationReadCallback (" + GetReadObjectName (map
) + ")");
2470 WriteLine ("protected override void InitIDs ()");
2476 void GenerateFixupCallbacks ()
2478 foreach (XmlMapping map
in _fixupCallbacks
)
2480 bool isList
= map
is XmlMembersMapping
;
2481 string tname
= !isList
? ((XmlTypeMapping
)map
).TypeData
.CSharpFullName
: "object[]";
2482 WriteLine ("void " + GetFixupCallbackName (map
) + " (object obfixup)");
2484 WriteLine ("Fixup fixup = (Fixup)obfixup;");
2485 WriteLine (tname
+ " source = (" + tname
+ ") fixup.Source;");
2486 WriteLine ("string[] ids = fixup.Ids;");
2489 ClassMap cmap
= (ClassMap
)map
.ObjectMap
;
2490 ICollection members
= cmap
.ElementMembers
;
2491 if (members
!= null) {
2492 foreach (XmlTypeMapMember member
in members
)
2494 WriteLineInd ("if (ids[" + member
.Index
+ "] != null)");
2495 string val
= "GetTarget(ids[" + member
.Index
+ "])";
2496 if (!isList
) val
= GetCast (member
.TypeData
, val
);
2497 GenerateSetMemberValue (member
, "source", val
, isList
);
2506 string GetReadXmlNode (TypeData type
, bool wrapped
)
2508 if (type
.Type
== typeof (XmlDocument
))
2509 return GetCast (type
, TypeTranslator
.GetTypeData (typeof(XmlDocument
)), "ReadXmlDocument (" + GetLiteral(wrapped
) + ")");
2511 return GetCast (type
, TypeTranslator
.GetTypeData (typeof(XmlNode
)), "ReadXmlNode (" + GetLiteral(wrapped
) + ")");
2516 #region Helper methods
2518 //*******************************************************
2522 ArrayList _listsToFill
= new ArrayList ();
2523 Hashtable _hookVariables
;
2524 Stack _hookContexts
;
2525 Stack _hookOpenHooks
;
2528 public HookType HookType
;
2530 public string Member
;
2531 public HookDir Direction
;
2536 _hookContexts
= new Stack ();
2537 _hookOpenHooks
= new Stack ();
2538 _hookVariables
= new Hashtable ();
2541 void PushHookContext ()
2543 _hookContexts
.Push (_hookVariables
);
2544 _hookVariables
= (Hashtable
) _hookVariables
.Clone ();
2547 void PopHookContext ()
2549 _hookVariables
= (Hashtable
) _hookContexts
.Pop ();
2552 void SetHookVar (string var, string value)
2554 _hookVariables
[var] = value;
2557 bool GenerateReadHook (HookType hookType
, Type type
)
2559 return GenerateHook (hookType
, HookDir
.Read
, type
, null);
2562 bool GenerateWriteHook (HookType hookType
, Type type
)
2564 return GenerateHook (hookType
, HookDir
.Write
, type
, null);
2567 bool GenerateWriteMemberHook (Type type
, XmlTypeMapMember member
)
2569 SetHookVar ("$MEMBER", member
.Name
);
2570 return GenerateHook (HookType
.member
, HookDir
.Write
, type
, member
.Name
);
2573 bool GenerateReadMemberHook (Type type
, XmlTypeMapMember member
)
2575 SetHookVar ("$MEMBER", member
.Name
);
2576 return GenerateHook (HookType
.member
, HookDir
.Read
, type
, member
.Name
);
2579 bool GenerateReadArrayMemberHook (Type type
, XmlTypeMapMember member
, string index
)
2581 SetHookVar ("$INDEX", index
);
2582 return GenerateReadMemberHook (type
, member
);
2585 bool MemberHasReadReplaceHook (Type type
, XmlTypeMapMember member
)
2587 if (_config
== null) return false;
2588 return _config
.GetHooks (HookType
.member
, HookDir
.Read
, HookAction
.Replace
, type
, member
.Name
).Count
> 0;
2591 bool GenerateHook (HookType hookType
, HookDir dir
, Type type
, string member
)
2593 GenerateHooks (hookType
, dir
, type
, null, HookAction
.InsertBefore
);
2594 if (GenerateHooks (hookType
, dir
, type
, null, HookAction
.Replace
))
2596 GenerateHooks (hookType
, dir
, type
, null, HookAction
.InsertAfter
);
2601 HookInfo hi
= new HookInfo ();
2602 hi
.HookType
= hookType
;
2606 _hookOpenHooks
.Push (hi
);
2611 void GenerateEndHook ()
2613 HookInfo hi
= (HookInfo
) _hookOpenHooks
.Pop();
2614 GenerateHooks (hi
.HookType
, hi
.Direction
, hi
.Type
, hi
.Member
, HookAction
.InsertAfter
);
2617 bool GenerateHooks (HookType hookType
, HookDir dir
, Type type
, string member
, HookAction action
)
2619 if (_config
== null) return false;
2620 ArrayList hooks
= _config
.GetHooks (hookType
, dir
, action
, type
, null);
2621 if (hooks
.Count
== 0) return false;
2622 foreach (Hook hook
in hooks
)
2624 string code
= hook
.GetCode (action
);
2625 foreach (DictionaryEntry de
in _hookVariables
)
2626 code
= code
.Replace ((string)de
.Key
, (string)de
.Value
);
2627 WriteMultilineCode (code
);
2632 string GetRootTypeName ()
2634 if (_typeMap
is XmlTypeMapping
) return ((XmlTypeMapping
)_typeMap
).TypeData
.CSharpFullName
;
2635 else return "object[]";
2638 string GetNumTempVar ()
2640 return "n" + (_tempVarId
++);
2643 string GetObTempVar ()
2645 return "o" + (_tempVarId
++);
2648 string GetStrTempVar ()
2650 return "s" + (_tempVarId
++);
2653 string GetBoolTempVar ()
2655 return "b" + (_tempVarId
++);
2658 string GetUniqueName (string uniqueGroup
, object ob
, string name
)
2660 name
= CodeIdentifier
.MakeValid (name
.Replace ("[]","_array"));
2661 Hashtable names
= (Hashtable
) _uniqueNames
[uniqueGroup
];
2662 if (names
== null) {
2663 names
= new Hashtable ();
2664 _uniqueNames
[uniqueGroup
] = names
;
2667 string res
= (string) names
[ob
];
2668 if (res
!= null) return res
;
2670 foreach (string n
in names
.Values
)
2671 if (n
== name
) return GetUniqueName (uniqueGroup
, ob
, name
+ (_methodId
++));
2677 void RegisterReferencingMap (XmlTypeMapping typeMap
)
2679 if (typeMap
!= null && !_mapsToGenerate
.Contains (typeMap
))
2680 _mapsToGenerate
.Add (typeMap
);
2683 string GetWriteObjectName (XmlTypeMapping typeMap
)
2685 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2686 return GetUniqueName ("rw", typeMap
, "WriteObject_" + typeMap
.XmlType
);
2689 string GetReadObjectName (XmlTypeMapping typeMap
)
2691 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2692 return GetUniqueName ("rr", typeMap
, "ReadObject_" + typeMap
.XmlType
);
2695 string GetGetEnumValueName (XmlTypeMapping typeMap
)
2697 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2698 return GetUniqueName ("ge", typeMap
, "GetEnumValue_" + typeMap
.XmlType
);
2701 string GetWriteObjectCallbackName (XmlTypeMapping typeMap
)
2703 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2704 return GetUniqueName ("wc", typeMap
, "WriteCallback_" + typeMap
.XmlType
);
2707 string GetFixupCallbackName (XmlMapping typeMap
)
2709 if (!_mapsToGenerate
.Contains (typeMap
)) _mapsToGenerate
.Add (typeMap
);
2711 if (typeMap
is XmlTypeMapping
)
2712 return GetUniqueName ("fc", typeMap
, "FixupCallback_" + ((XmlTypeMapping
)typeMap
).XmlType
);
2714 return GetUniqueName ("fc", typeMap
, "FixupCallback__Message");
2717 string GetUniqueClassName (string s
)
2719 return classNames
.AddUnique (CodeIdentifier
.MakeValid (s
), null);
2722 string GetReadObjectCall (XmlTypeMapping typeMap
, string isNullable
, string checkType
)
2724 if (_format
== SerializationFormat
.Literal
)
2725 return GetReadObjectName (typeMap
) + " (" + isNullable
+ ", " + checkType
+ ")";
2727 return GetCast (typeMap
.TypeData
, GetReadObjectName (typeMap
) + " ()");
2730 string GetFillListName (TypeData td
)
2732 if (!_listsToFill
.Contains (td
)) _listsToFill
.Add (td
);
2733 return GetUniqueName ("fl", td
, "Fill_" + CodeIdentifier
.MakeValid (td
.CSharpName
));
2736 string GetCast (TypeData td
, TypeData tdval
, string val
)
2738 if (td
.CSharpFullName
== tdval
.CSharpFullName
) return val
;
2739 else return GetCast (td
, val
);
2742 string GetCast (TypeData td
, string val
)
2744 return "((" + td
.CSharpFullName
+ ") " + val
+ ")";
2747 string GetCast (Type td
, string val
)
2749 return "((" + ToCSharpFullName (td
) + ") " + val
+ ")";
2752 string GetTypeOf (TypeData td
)
2754 return "typeof(" + td
.CSharpFullName
+ ")";
2757 string GetTypeOf (Type td
)
2759 return "typeof(" + ToCSharpFullName (td
) + ")";
2762 string GetLiteral (object ob
)
2764 if (ob
== null) return "null";
2765 if (ob
is string) return "\"" + ob
.ToString().Replace("\"","\"\"") + "\"";
2766 if (ob
is DateTime
) return "new DateTime (" + ((DateTime
) ob
).Ticks
+ ")";
2768 if (ob
is DateTimeOffset
) return "new DateTimeOffset (" + ((DateTimeOffset
) ob
).Ticks
+ ")";
2770 if (ob
is TimeSpan
) return "new TimeSpan (" + ((TimeSpan
) ob
).Ticks
+ ")";
2771 if (ob
is bool) return ((bool)ob
) ? "true" : "false";
2772 if (ob
is XmlQualifiedName
) {
2773 XmlQualifiedName qn
= (XmlQualifiedName
)ob
;
2774 return "new XmlQualifiedName (" + GetLiteral(qn
.Name
) + "," + GetLiteral(qn
.Namespace
) + ")";
2777 string typeName
= ToCSharpFullName (ob
.GetType ());
2778 StringBuilder sb
= new StringBuilder ();
2779 string namedValue
= Enum
.Format (ob
.GetType (), ob
, "g");
2780 string[] names
= namedValue
.Split (',');
2781 foreach (string name
in names
) {
2782 // individual named constants can be seperated by a comma
2783 // combined with some additional whitespace characters
2784 string cleanName
= name
.Trim ();
2785 if (cleanName
.Length
== 0)
2791 sb
.Append (typeName
);
2793 sb
.Append (cleanName
);
2795 return sb
.ToString ();
2798 return (ob
is IFormattable
) ? ((IFormattable
) ob
).ToString (null, CultureInfo
.InvariantCulture
) : ob
.ToString ();
2801 void WriteLineInd (string code
)
2807 void WriteLineUni (string code
)
2809 if (_indent
> 0) _indent
--;
2813 void Write (string code
)
2815 if (code
.Length
> 0)
2816 _writer
.Write (new String ('\t', _indent
));
2817 _writer
.Write (code
);
2820 void WriteUni (string code
)
2822 if (_indent
> 0) _indent
--;
2823 _writer
.Write (code
);
2824 _writer
.WriteLine (string.Empty
);
2827 void WriteLine (string code
)
2829 if (code
.Length
> 0)
2830 _writer
.Write (new String ('\t',_indent
));
2831 _writer
.WriteLine (code
);
2834 void WriteMultilineCode (string code
)
2836 string tabs
= new string ('\t',_indent
);
2837 code
= code
.Replace ("\r","");
2838 code
= code
.Replace ("\t","");
2839 while (code
.StartsWith ("\n")) code
= code
.Substring (1);
2840 while (code
.EndsWith ("\n")) code
= code
.Substring (0, code
.Length
- 1);
2841 code
= code
.Replace ("\n", "\n" + tabs
);
2845 string Params (params string[] pars
)
2848 foreach (string p
in pars
)
2850 if (res
!= "") res
+= ", ";
2856 void WriteMetCall (string method
, params string[] pars
)
2858 WriteLine (method
+ " (" + Params (pars
) + ");");
2870 internal class GenerationResult
2872 public XmlMapping Mapping
;
2873 public string ReaderClassName
;
2874 public string ReadMethodName
;
2875 public string WriterClassName
;
2876 public string WriteMethodName
;
2877 public string Namespace
;
2879 public string SerializerClassName
;
2881 public string BaseSerializerClassName
;
2882 public string ImplementationClassName
;