**** Merged from MCS ****
[mono-project.git] / mcs / class / System.XML / System.Xml.Serialization / SerializationCodeGenerator.cs
blob488901918195bc0830d64ecd7fad290b4a4d4f25
1 //
2 // System.Xml.Serialization.SerializationCodeGenerator.cs:
3 //
4 // Author:
5 // Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // (C) 2002, 2003 Ximian, Inc. http://www.ximian.com
8 //
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:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
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.
31 using System.IO;
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
41 XmlMapping _typeMap;
42 SerializationFormat _format;
43 TextWriter _writer;
44 int _tempVarId = 0;
45 int _indent = 0;
46 Hashtable _uniqueNames = new Hashtable();
47 int _methodId = 0;
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)
64 _xmlMaps = xmlMaps;
65 _config = config;
68 public SerializationCodeGenerator (XmlMapping xmlMap, SerializerInfo config)
70 _xmlMaps = new XmlMapping [] {xmlMap};
71 _config = config;
74 public static void Generate (string configFileName, string outputPath)
76 SerializationCodeGeneratorConfiguration cnf = null;
77 StreamReader sr = new StreamReader (configFileName);
78 try
80 XmlReflectionImporter ri = new XmlReflectionImporter ();
81 ri.AllowPrivateTypes = true;
82 XmlSerializer ser = new XmlSerializer (ri.ImportTypeMapping (typeof (SerializationCodeGeneratorConfiguration)));
83 cnf = (SerializationCodeGeneratorConfiguration) ser.Deserialize (sr);
85 finally
87 sr.Close ();
90 if (outputPath == null) outputPath = "";
92 CodeIdentifiers ids = new CodeIdentifiers ();
93 if (cnf.Serializers != null)
95 foreach (SerializerInfo info in cnf.Serializers)
97 Type type;
98 if (info.Assembly != null)
100 Assembly asm;
101 try {
102 asm = Assembly.Load (info.Assembly);
103 } catch {
104 asm = Assembly.LoadFrom (info.Assembly);
106 type = asm.GetType (info.ClassName, true);
108 else
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));
124 XmlTypeMapping map;
126 if (info.SerializationFormat == SerializationFormat.Literal) {
127 XmlReflectionImporter ri = new XmlReflectionImporter ();
128 map = ri.ImportTypeMapping (type);
130 else {
131 SoapReflectionImporter ri = new SoapReflectionImporter ();
132 map = ri.ImportTypeMapping (type);
135 SerializationCodeGenerator gen = new SerializationCodeGenerator (map, info);
136 gen.GenerateSerializers (writer);
138 finally
140 writer.Close ();
146 public void GenerateSerializers (TextWriter writer)
148 _writer = 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 + ";");
162 WriteLine ("");
164 string readerClassName = null;
165 string writerClassName = null;
166 string namspace = null;
168 if (_config != 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;
195 continue;
198 _result = new GenerationResult ();
199 _results[n] = _result;
201 generatedMaps [_typeMap] = _result;
203 string typeName;
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;
212 else
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];
221 if (maps == null) {
222 maps = new ArrayList ();
223 mapsByNamespace [_result.Namespace] = maps;
225 maps.Add (_result);
228 foreach (DictionaryEntry entry in mapsByNamespace)
230 ArrayList maps = (ArrayList) entry.Value;
232 WriteLine ("namespace " + entry.Key);
233 WriteLineInd ("{");
235 GenerateReader (readerClassName, maps);
236 WriteLine ("");
237 GenerateWriter (writerClassName, maps);
238 WriteLine ("");
240 #if NET_2_0
241 GenerateContract (maps);
242 #endif
244 WriteLineUni ("}");
245 WriteLine ("");
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
275 #if NET_2_0
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");
286 WriteLine ("");
287 WriteLine ("public class " + baseSerializerName + " : System.Xml.Serialization.XmlSerializer");
288 WriteLineInd ("{");
289 WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationReader CreateReader () {");
290 WriteLine ("return new " + main.ReaderClassName + " ();");
291 WriteLineUni ("}");
292 WriteLine ("");
294 WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationWriter CreateWriter () {");
295 WriteLine ("return new " + main.WriterClassName + " ();");
296 WriteLineUni ("}");
297 WriteLine ("");
299 WriteLineInd ("public override bool CanDeserialize (System.Xml.XmlReader xmlReader) {");
300 WriteLine ("return true;");
301 WriteLineUni ("}");
303 WriteLineUni ("}");
304 WriteLine ("");
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);
313 WriteLineInd ("{");
314 WriteLineInd ("protected override void Serialize (object obj, System.Xml.Serialization.XmlSerializationWriter writer) {");
315 WriteLine ("((" + res.WriterClassName + ")writer)." + res.WriteMethodName + "(obj);");
316 WriteLineUni ("}");
317 WriteLine ("");
319 WriteLineInd ("protected override object Deserialize (System.Xml.Serialization.XmlSerializationReader reader) {");
320 WriteLine ("return ((" + res.ReaderClassName + ")reader)." + res.ReadMethodName + "();");
321 WriteLineUni ("}");
323 WriteLineUni ("}");
324 WriteLine ("");
327 WriteLine ("public class XmlSerializerContract : System.Xml.Serialization.IXmlSerializerImplementation");
328 WriteLineInd ("{");
330 WriteLine ("System.Collections.Hashtable readMethods = null;");
331 WriteLine ("System.Collections.Hashtable writeMethods = null;");
332 WriteLine ("System.Collections.Hashtable typedSerializers = null;");
333 WriteLine ("");
335 WriteLineInd ("public System.Xml.Serialization.XmlSerializationReader Reader {");
336 WriteLineInd ("get {");
337 WriteLine ("return new " + main.ReaderClassName + "();");
338 WriteLineUni ("}");
339 WriteLineUni ("}");
340 WriteLine ("");
342 WriteLineInd ("public System.Xml.Serialization.XmlSerializationWriter Writer {");
343 WriteLineInd ("get {");
344 WriteLine ("return new " + main.WriterClassName + "();");
345 WriteLineUni ("}");
346 WriteLineUni ("}");
347 WriteLine ("");
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 + "\");");
356 WriteLineUni ("}");
357 WriteLine ("return readMethods;");
358 WriteLineUni ("}");
359 WriteLineUni ("}");
360 WriteLineUni ("}");
361 WriteLine ("");
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 + "\");");
370 WriteLineUni ("}");
371 WriteLine ("return writeMethods;");
372 WriteLineUni ("}");
373 WriteLineUni ("}");
374 WriteLineUni ("}");
375 WriteLine ("");
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 + "());");
384 WriteLineUni ("}");
385 WriteLine ("return typedSerializers;");
386 WriteLineUni ("}");
387 WriteLineUni ("}");
388 WriteLineUni ("}");
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;");
396 WriteLineUni ("}");
398 WriteLineUni ("}");
399 WriteLine ("");
401 #endif
404 //*******************************************************
405 // Writer generation
408 public void GenerateWriter (string writerClassName, ArrayList maps)
410 _mapsToGenerate = new ArrayList ();
412 InitHooks ();
414 WriteLine ("public class " + writerClassName + " : XmlSerializationWriter");
415 WriteLineInd ("{");
417 for (int n=0; n<maps.Count; n++)
419 GenerationResult res = (GenerationResult) maps [n];
420 _typeMap = res.Mapping;
421 _format = _typeMap.Format;
422 _result = res;
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);
438 WriteLineUni ("}");
441 void GenerateWriteRoot ()
443 WriteLine ("public void " +_result.WriteMethodName + " (object o)");
444 WriteLineInd ("{");
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);");
457 else {
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);
466 else
467 throw new InvalidOperationException ("Unknown type map");
469 if (_format == SerializationFormat.Encoded)
470 WriteLine ("WriteReferencedElements ();");
472 WriteLineUni ("}");
473 WriteLine ("");
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);");
484 Unindent ();
486 WriteLineInd ("if (Writer.LookupPrefix (XmlSchema.InstanceNamespace) == null)");
487 WriteLine ("WriteAttribute (\"xmlns\",\"xsi\",XmlSchema.InstanceNamespace,XmlSchema.InstanceNamespace);");
488 Unindent ();
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)");
503 WriteLineInd ("{");
505 WriteLine ("switch (val)");
506 WriteLineInd ("{");
507 foreach (EnumMap.EnumMapMember mem in emap.Members)
508 WriteLine ("case " + map.TypeFullName + "." + mem.EnumName + ": return " + GetLiteral (mem.XmlName) + ";");
510 if (emap.IsFlags)
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)");
516 WriteLineInd ("{");
517 WriteLine ("switch (name.Trim())");
518 WriteLineInd ("{");
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; ");
524 WriteLineUni ("}");
525 WriteLineUni ("}");
526 WriteLine ("return sb.ToString ().Trim();");
527 Unindent ();
529 else
530 WriteLine ("default: return ((long)val).ToString(CultureInfo.InvariantCulture);");
532 WriteLineUni ("}");
534 WriteLineUni ("}");
535 WriteLine ("");
538 void GenerateWriteObject (XmlTypeMapping typeMap)
540 WriteLine ("void " + GetWriteObjectName (typeMap) + " (" + typeMap.TypeFullName + " ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)");
541 WriteLineInd ("{");
543 PushHookContext ();
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))
554 WriteLineUni ("}");
555 WriteLine ("");
556 PopHookContext ();
557 return;
560 if (!typeMap.TypeData.IsValueType)
562 WriteLine ("if (ob == null)");
563 WriteLineInd ("{");
564 WriteLineInd ("if (isNullable)");
566 if (_format == SerializationFormat.Literal)
567 WriteLine ("WriteNullTagLiteral(element, namesp);");
568 else
569 WriteLine ("WriteNullTagEncoded (element, namesp);");
571 WriteLineUni ("return;");
572 WriteLineUni ("}");
573 WriteLine ("");
576 if (typeMap.TypeData.SchemaType == SchemaTypes.XmlNode)
578 if (_format == SerializationFormat.Literal)
579 WriteLine ("WriteElementLiteral (ob, \"\", \"\", true, false);");
580 else
581 WriteLine ("WriteElementEncoded (ob, \"\", \"\", true, false);");
583 GenerateEndHook ();
584 WriteLineUni ("}");
585 WriteLine ("");
586 PopHookContext ();
587 return;
590 if (typeMap.TypeData.SchemaType == SchemaTypes.XmlSerializable)
592 WriteLine ("WriteSerializable (ob, element, namesp, isNullable);");
594 GenerateEndHook ();
595 WriteLineUni ("}");
596 WriteLine ("");
597 PopHookContext ();
598 return;
601 ArrayList types = typeMap.DerivedTypes;
603 WriteLine ("System.Type type = ob.GetType ();");
604 WriteLine ("if (type == typeof(" + typeMap.TypeFullName + "))");
605 WriteLine ("\t;");
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;");
614 WriteLineUni ("}");
617 if (typeMap.TypeData.Type == typeof (object)) {
618 WriteLineInd ("else {");
619 WriteLine ("WriteTypedPrimitive (element, namesp, ob, true);");
620 WriteLine ("return;");
621 WriteLineUni ("}");
623 else
625 WriteLineInd ("else {");
626 WriteLine ("throw CreateUnknownTypeException (ob);");
627 WriteLineUni ("}");
628 WriteLine ("");
630 WriteLineInd ("if (writeWrappingElem) {");
631 if (_format == SerializationFormat.Encoded) WriteLine ("needType = true;");
632 WriteLine ("WriteStartElement (element, namesp, ob);");
633 WriteLineUni ("}");
634 WriteLine ("");
636 WriteLine ("if (needType) WriteXsiType(" + GetLiteral(typeMap.XmlType) + ", " + GetLiteral(typeMap.XmlTypeNamespace) + ");");
637 WriteLine ("");
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);");
650 GenerateEndHook ();
651 WriteLineUni ("}");
652 WriteLine ("");
653 PopHookContext ();
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 + ");");
666 WriteLine ("");
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 ("}");
685 GenerateEndHook ();
687 WriteLine ("");
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 + ");");
705 Unindent ();
706 WriteLineUni ("}");
708 if (cond != null) WriteLineUni ("}");
709 WriteLine ("");
710 GenerateEndHook ();
713 GenerateEndHook ();
716 if (!GenerateWriteHook (HookType.elements, xmlMapType))
718 ICollection members = map.ElementMembers;
719 if (members != null)
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);
739 WriteLineUni ("}");
741 else if (memType == typeof(XmlTypeMapMemberAnyElement))
743 WriteLineInd ("if (" + memberValue + " != null) {");
744 GenerateWriteAnyElementContent ((XmlTypeMapMemberAnyElement)member, memberValue);
745 WriteLineUni ("}");
747 else if (memType == typeof(XmlTypeMapMemberAnyElement))
749 WriteLineInd ("if (" + memberValue + " != null) {");
750 GenerateWriteAnyElementContent ((XmlTypeMapMemberAnyElement)member, memberValue);
751 WriteLineUni ("}");
753 else if (memType == typeof(XmlTypeMapMemberAnyAttribute))
755 // Ignore
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));
768 WriteLineUni ("}");
771 else
773 // WriteLineInd ("if (" + memberValue + " == null) {");
774 // GenerateWriteMemberElement ((XmlTypeMapElementInfo)member.ElementInfo[0], memberValue);
775 // WriteLineUni ("}");
777 bool first = true;
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));
783 WriteLineUni ("}");
784 first = false;
788 else
789 throw new InvalidOperationException ("Unknown member type");
791 if (cond != null)
792 WriteLineUni ("}");
794 GenerateEndHook ();
797 GenerateEndHook ();
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");
809 else
810 WriteMetCall ("WriteElementEncoded", memberValue, GetLiteral(elemName), GetLiteral(elem.Namespace), GetLiteral(elem.IsNullable), "false");
811 break;
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);
817 else
818 GenerateWritePrimitiveValueEncoded (memberValue, elem.ElementName, elem.Namespace, new XmlQualifiedName (elem.TypeData.XmlType, elem.DataTypeNamespace), elem.MappedType, elem.TypeData, elem.WrappedElement, elem.IsNullable);
819 break;
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);
828 else {
829 WriteMetCall ("WriteStartElement", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), memberValue);
830 GenerateWriteListContent (elem.TypeData, (ListMap) elem.MappedType.ObjectMap, memberValue, false);
831 WriteMetCall ("WriteEndElement", memberValue);
833 WriteLineUni ("}");
835 if (elem.IsNullable) {
836 WriteLineInd ("else");
837 if (_format == SerializationFormat.Literal)
838 WriteMetCall ("WriteNullTagLiteral", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace));
839 else
840 WriteMetCall ("WriteNullTagEncoded", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace));
841 Unindent ();
844 break;
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));
851 else
852 WriteMetCall ("WriteReferencingElement", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), memberValue, GetLiteral(elem.IsNullable));
854 else
855 WriteMetCall (GetWriteObjectName(elem.MappedType), memberValue, GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), GetLiteral(elem.IsNullable), "false", "true");
856 break;
858 case SchemaTypes.XmlSerializable:
859 WriteMetCall ("WriteSerializable", memberValue, GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), GetLiteral(elem.IsNullable));
860 break;
862 default:
863 throw new NotSupportedException ("Invalid value type");
867 void GenerateWriteListElement (XmlTypeMapping typeMap, string ob)
869 if (_format == SerializationFormat.Encoded)
871 string n, ns;
872 string itemCount = GenerateGetListCount (typeMap.TypeData, ob);
873 GenerateGetArrayType ((ListMap) typeMap.ObjectMap, itemCount, out n, out ns);
875 string arrayType;
876 if (ns != string.Empty)
877 arrayType = "FromXmlQualifiedName (new XmlQualifiedName(" + n + "," + ns + "))";
878 else
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));
889 string var;
891 if (singleElement)
892 var = memberValue;
893 else {
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);");
914 else
915 WriteLine ("WriteElementEncoded (" + elem + ", \"\", \"\", false, true);");
917 if (!member.IsDefaultAny) {
918 WriteLineUni ("}");
919 WriteLineInd ("else");
920 WriteLine ("throw CreateUnknownAnyElementException (" + elem + ".Name, " + elem + ".NamespaceURI);");
921 Unindent ();
924 if (!singleElement)
925 WriteLineUni ("}");
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 ();");
948 WriteLineUni ("}");
949 return str;
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)
957 return null;
958 else
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)
970 return "ob.Length";
971 else
972 return "ob.Count";
975 void GenerateGetArrayType (ListMap map, string itemCount, out string localName, out string ns)
977 string arrayDim;
978 if (itemCount != "") arrayDim = "";
979 else arrayDim = "[]";
981 XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) map.ItemInfo[0];
982 if (info.TypeData.SchemaType == SchemaTypes.Array)
984 string nm;
985 GenerateGetArrayType ((ListMap)info.MappedType.ObjectMap, "", out nm, out ns);
986 localName = nm + arrayDim;
988 else
990 if (info.MappedType != null)
992 localName = info.MappedType.XmlType + arrayDim;
993 ns = info.MappedType.Namespace;
995 else
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;
1011 if (writeToString)
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);
1022 WriteLineUni ("}");
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);
1029 WriteLineUni ("}");
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);
1036 WriteLineUni ("}");
1038 else
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);
1048 if (multichoice)
1049 WriteLine ("if (" + item + " == null) { }");
1051 foreach (XmlTypeMapElementInfo info in map.ItemInfo)
1053 if (multichoice)
1054 WriteLineInd ("else if (" + item + ".GetType() == typeof(" + info.TypeData.FullTypeName + ")) {");
1056 if (targetString == null)
1057 GenerateWriteMemberElement (info, GetCast (info.TypeData, itemTypeData, item));
1058 else
1060 string strVal = GenerateGetStringValue (info.MappedType, info.TypeData, GetCast (info.TypeData, itemTypeData, item));
1061 WriteLine (targetString + ".Append (" + strVal + ").Append (\" \");");
1064 if (multichoice)
1065 WriteLineUni ("}");
1068 if (multichoice)
1069 WriteLine ("else throw CreateUnknownTypeException (" + item + ");");
1072 void GenerateWritePrimitiveValueLiteral (string memberValue, string name, string ns, XmlTypeMapping mappedType, TypeData typeData, bool wrapped, bool isNullable)
1074 if (!wrapped) {
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);
1081 else {
1082 string strVal = GenerateGetStringValue (mappedType, typeData, memberValue);
1083 WriteMetCall ("WriteNullableStringLiteral", GetLiteral(name), GetLiteral(ns), strVal);
1086 else {
1087 if (typeData.Type == typeof(XmlQualifiedName))
1088 WriteMetCall ("WriteElementQualifiedName", GetLiteral(name), GetLiteral(ns), memberValue);
1089 else {
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)
1098 if (!wrapped) {
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));
1105 else {
1106 string strVal = GenerateGetStringValue (mappedType, typeData, memberValue);
1107 WriteMetCall ("WriteNullableStringEncoded", GetLiteral(name), GetLiteral(ns), strVal, GetLiteral(xsiType));
1110 else {
1111 if (typeData.Type == typeof(XmlQualifiedName))
1112 WriteMetCall ("WriteElementQualifiedName", GetLiteral(name), GetLiteral(ns), memberValue, GetLiteral(xsiType));
1113 else {
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)
1128 if (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));
1137 else
1138 return mem + " != " + GetLiteral (member.DefaultValue);
1140 else if (member.IsOptionalValueType)
1141 return ob + ".@" + member.Name + "Specified";
1142 return null;
1145 void GenerateWriteInitCallbacks ()
1147 WriteLine ("protected override void InitCallbacks ()");
1148 WriteLineInd ("{");
1150 if (_format == SerializationFormat.Encoded)
1152 foreach (XmlMapping xmap in _mapsToGenerate) {
1153 XmlTypeMapping map = xmap as XmlTypeMapping;
1154 if (map != null)
1155 WriteMetCall ("AddWriteCallback", GetTypeOf(map.TypeData), GetLiteral(map.XmlType), GetLiteral(map.Namespace), "new XmlSerializationWriteCallback (" + GetWriteObjectCallbackName (map) + ")");
1159 WriteLineUni ("}");
1160 WriteLine ("");
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);
1169 else
1170 WriteWriteObjectCallback (map);
1175 void WriteWriteEnumCallback (XmlTypeMapping map)
1177 WriteLine ("void " + GetWriteObjectCallbackName (map) + " (object ob)");
1178 WriteLineInd ("{");
1179 WriteMetCall (GetWriteObjectName(map), GetCast (map.TypeData, "ob"), GetLiteral(map.ElementName), GetLiteral(map.Namespace), "false", "true", "false");
1180 WriteLineUni ("}");
1181 WriteLine ("");
1184 void WriteWriteObjectCallback (XmlTypeMapping map)
1186 WriteLine ("void " + GetWriteObjectCallbackName (map) + " (object ob)");
1187 WriteLineInd ("{");
1188 WriteMetCall (GetWriteObjectName(map), GetCast (map.TypeData, "ob"), GetLiteral(map.ElementName), GetLiteral(map.Namespace), "false", "false", "false");
1189 WriteLineUni ("}");
1190 WriteLine ("");
1193 #endregion
1195 #region Reader Generation
1197 //*******************************************************
1198 // Reader generation
1201 public void GenerateReader (string readerClassName, ArrayList maps)
1203 WriteLine ("public class " + readerClassName + " : XmlSerializationReader");
1204 WriteLineInd ("{");
1206 _mapsToGenerate = new ArrayList ();
1207 _fixupCallbacks = new ArrayList ();
1208 InitHooks ();
1210 for (int n=0; n<maps.Count; n++)
1212 GenerationResult res = (GenerationResult) maps [n];
1213 _typeMap = res.Mapping;
1214 _format = _typeMap.Format;
1215 _result = res;
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 ();
1238 WriteLineUni ("}");
1239 UpdateGeneratedTypes (_mapsToGenerate);
1242 void GenerateReadRoot ()
1244 WriteLine ("public object " + _result.ReadMethodName + " ()");
1245 WriteLineInd ("{");
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();");
1261 Unindent ();
1263 WriteLine ("return " + GetReadObjectCall (typeMap, "true", "true") + ";");
1265 else
1267 WriteLine ("object ob = null;");
1268 WriteLine ("Reader.MoveToContent();");
1269 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
1270 WriteLineInd ("{");
1271 WriteLineInd ("if (Reader.LocalName == " + GetLiteral(typeMap.ElementName) + " && Reader.NamespaceURI == " + GetLiteral (typeMap.Namespace) + ")");
1272 WriteLine ("ob = ReadReferencedElement();");
1273 Unindent ();
1274 WriteLineInd ("else ");
1275 WriteLine ("throw CreateUnknownNodeException();");
1276 Unindent ();
1277 WriteLineUni ("}");
1278 WriteLineInd ("else ");
1279 WriteLine ("UnknownNode(null);");
1280 Unindent ();
1281 WriteLine ("");
1282 WriteLine ("ReadReferencedElements();");
1283 WriteLine ("return ob;");
1284 RegisterReferencingMap (typeMap);
1287 else {
1288 WriteLine ("return " + GenerateReadMessage ((XmlMembersMapping)_typeMap) + ";");
1291 WriteLineUni ("}");
1292 WriteLine ("");
1295 string GenerateReadMessage (XmlMembersMapping typeMap)
1297 WriteLine ("object[] parameters = new object[" + typeMap.Count + "];");
1298 WriteLine ("");
1300 if (typeMap.HasWrapperElement)
1302 if (_format == SerializationFormat.Encoded)
1304 WriteLine ("while (Reader.NodeType == System.Xml.XmlNodeType.Element)");
1305 WriteLineInd ("{");
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 ();");
1310 WriteLineUni ("}");
1311 WriteLine ("");
1312 WriteLine ("if (Reader.NodeType != System.Xml.XmlNodeType.EndElement)");
1313 WriteLineInd ("{");
1314 WriteLineInd ("if (Reader.IsEmptyElement) {");
1315 WriteLine ("Reader.Skip();");
1316 WriteLineUni ("}");
1317 WriteLineInd ("else {");
1318 WriteLine ("Reader.ReadStartElement();");
1319 GenerateReadMembers (typeMap, (ClassMap)typeMap.ObjectMap, "parameters", true, false);
1320 WriteLine ("ReadEndElement();");
1321 WriteLineUni ("}");
1322 WriteLine ("");
1323 WriteLine ("Reader.MoveToContent();");
1324 WriteLineUni ("}");
1326 else
1328 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement)");
1329 WriteLineInd ("{");
1330 WriteLine ("if (Reader.IsStartElement(" + GetLiteral(typeMap.ElementName) + ", " + GetLiteral(typeMap.Namespace) + "))");
1331 WriteLineInd ("{");
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;");
1337 WriteLineUni ("}");
1338 WriteLineInd ("else ");
1339 WriteLine ("UnknownNode(null);");
1340 Unindent ();
1341 WriteLine ("");
1342 WriteLine ("Reader.MoveToContent();");
1343 WriteLineUni ("}");
1346 else
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)
1357 string isNullable;
1358 if (_format == SerializationFormat.Literal) {
1359 WriteLine ("public " + typeMap.TypeFullName + " " + GetReadObjectName (typeMap) + " (bool isNullable, bool checkType)");
1360 isNullable = "isNullable";
1362 else {
1363 WriteLine ("public object " + GetReadObjectName (typeMap) + " ()");
1364 isNullable = "true";
1367 WriteLineInd ("{");
1369 PushHookContext ();
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) + ";");
1380 break;
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");
1388 WriteLineUni ("}");
1389 WriteLine ("");
1390 PopHookContext ();
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;");
1402 return;
1405 if (_format == SerializationFormat.Literal) {
1406 WriteLine ("if (" + isNullable + " && ReadNull()) return null;");
1407 WriteLine ("");
1408 WriteLine ("if (checkType) ");
1409 WriteLineInd ("{");
1411 else {
1412 WriteLine ("if (ReadNull()) return null;");
1413 WriteLine ("");
1416 else
1418 WriteLine (typeMap.TypeFullName + " ob = new " + typeMap.TypeFullName + " ();");
1420 if (GenerateReadHook (HookType.type, typeMap.TypeData.Type)) {
1421 WriteLine ("return ob;");
1422 return;
1426 WriteLine ("System.Xml.XmlQualifiedName t = GetXsiType();");
1427 WriteLine ("if (t == null)");
1428 if (typeMap.TypeData.Type != typeof(object))
1429 WriteLine ("\t;");
1430 else
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) + ";");
1437 Unindent ();
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)") + ";");
1443 else
1444 WriteLine ("\tthrow CreateUnknownTypeException(t);");
1446 if (!typeMap.TypeData.IsValueType)
1448 if (_format == SerializationFormat.Literal)
1449 WriteLineUni ("}");
1451 if (typeMap.TypeData.Type.IsAbstract) {
1452 GenerateEndHook ();
1453 WriteLine ("return ob;");
1454 return;
1457 WriteLine ("");
1458 WriteLine ("ob = new " + typeMap.TypeFullName + " ();");
1461 WriteLine ("");
1463 WriteLine ("Reader.MoveToElement();");
1464 WriteLine ("");
1466 GenerateReadMembers (typeMap, (ClassMap)typeMap.ObjectMap, "ob", false, false);
1468 WriteLine ("");
1470 GenerateEndHook ();
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
1491 bool first;
1492 if (!isValueList && !GenerateReadHook (HookType.attributes, xmlMapType))
1494 // Reads attributes
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())");
1505 WriteLineInd ("{");
1506 first = true;
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);
1513 GenerateEndHook ();
1515 WriteLineUni ("}");
1516 first = false;
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);");
1531 Unindent ();
1532 WriteLineInd ("else");
1533 WriteLine (nss + ".Add (\"\", Reader.Value);");
1534 Unindent ();
1535 GenerateEndHook ();
1539 WriteLineUni ("}");
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);
1549 GenerateEndHook ();
1551 WriteLine ("anyAttributeIndex++;");
1553 else {
1554 if (!GenerateReadHook (HookType.unknownAttribute, xmlMapType)) {
1555 WriteLine ("UnknownNode (" + ob + ");");
1556 GenerateEndHook ();
1560 WriteLineUni ("}");
1561 WriteLineUni ("}");
1563 if (anyAttrMember != null && !MemberHasReadReplaceHook (xmlMapType, anyAttrMember))
1565 WriteLine ("");
1566 WriteLine("anyAttributeArray = (" + anyAttrMember.TypeData.FullTypeName + ") ShrinkArray (anyAttributeArray, anyAttributeIndex, " + GetTypeOf(anyAttrMember.TypeData.Type.GetElementType()) + ", true);");
1567 GenerateSetMemberValue (anyAttrMember, ob, "anyAttributeArray", isValueList);
1569 WriteLine ("");
1571 GenerateEndHook ();
1574 if (!isValueList)
1576 WriteLine ("Reader.MoveToElement();");
1577 WriteLineInd ("if (Reader.IsEmptyElement) {");
1578 WriteLine ("Reader.Skip ();");
1579 WriteLine ("return " + ob + ";");
1580 WriteLineUni ("}");
1581 WriteLine ("");
1583 WriteLine ("Reader.ReadStartElement();");
1586 // Reads elements
1588 WriteLine("Reader.MoveToContent();");
1589 WriteLine ("");
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 + ";");
1604 WriteLine ("");
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 + ";");
1630 WriteLine ("");
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);");
1638 WriteLine ("");
1641 ArrayList infos = null;
1643 int maxInd;
1644 if (readByOrder) {
1645 if (map.ElementMembers != null) maxInd = map.ElementMembers.Count;
1646 else maxInd = 0;
1648 else
1650 infos = new ArrayList ();
1651 infos.AddRange (map.AllElementInfos);
1652 maxInd = infos.Count;
1654 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
1655 WriteLineInd ("{");
1656 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
1657 WriteLineInd ("{");
1660 first = true;
1661 for (int ind = 0; ind < maxInd; ind++)
1663 XmlTypeMapElementInfo info = readByOrder ? map.GetElement (ind) : (XmlTypeMapElementInfo) infos [ind];
1665 if (!readByOrder)
1667 if (info.IsTextElement || info.IsUnnamedAnyElement) continue;
1668 string elemCond = first ? "" : "else ";
1669 elemCond += "if (";
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);
1673 elemCond += " && ";
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) + ");");
1690 else
1691 GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,list), isValueList);
1692 WriteLineUni ("}");
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) + ";");
1699 else {
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.
1705 WriteLineUni ("}");
1708 else
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);
1713 GenerateEndHook ();
1716 if (!readByOrder)
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));
1724 GenerateEndHook ();
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);
1734 GenerateEndHook ();
1736 WriteLine (indexes[mem.FlatArrayIndex] + "++;");
1738 else {
1739 if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
1740 GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData, false), isValueList);
1741 GenerateEndHook ();
1745 else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement))
1747 if (!readByOrder)
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 + "]);");
1756 else
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
1761 else
1762 WriteLineInd ("if (" + val + " != null) {"); // null value
1764 GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,val), isValueList);
1765 WriteLineUni ("}");
1767 else if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
1768 GenerateSetMemberValue (info.Member, ob, GenerateReadObjectElement (info), isValueList);
1769 GenerateEndHook ();
1772 else
1773 throw new InvalidOperationException ("Unknown member type");
1775 if (!readByOrder)
1776 WriteLineUni ("}");
1777 first = false;
1780 if (!readByOrder)
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);
1790 GenerateEndHook ();
1792 WriteLine (indexes[mem.FlatArrayIndex] + "++;");
1794 else if (! GenerateReadMemberHook (xmlMapType, mem)) {
1795 GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData, false), isValueList);
1796 GenerateEndHook ();
1799 else {
1800 if (!GenerateReadHook (HookType.unknownElement, xmlMapType)) {
1801 WriteLine ("UnknownNode (" + ob + ");");
1802 GenerateEndHook ();
1806 if (!first) WriteLineUni ("}");
1808 WriteLineUni ("}");
1810 if (map.XmlTextCollector != null)
1812 WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text)");
1813 WriteLineInd ("{");
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);
1824 GenerateEndHook ();
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);
1834 else
1835 GenerateSetMemberValue (mem, ob, GenerateGetValueFromXmlString ("Reader.ReadString()", info.TypeData, info.MappedType), isValueList);
1836 GenerateEndHook ();
1838 WriteLineUni ("}");
1841 WriteLine ("else");
1842 WriteLine ("\tUnknownNode(" + ob + ");");
1843 WriteLine ("");
1844 WriteLine ("Reader.MoveToContent();");
1845 WriteLineUni ("}");
1847 else
1848 WriteLine ("Reader.MoveToContent();");
1850 if (flatLists != null)
1852 WriteLine ("");
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);
1864 GenerateEndHook ();
1867 if (!isValueList)
1869 WriteLine ("");
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 + ";");
1883 else {
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 + " ())");
1927 default:
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);
1940 else
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 + ")";
1952 else
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) + ";");
1968 else
1970 if (list != null) {
1971 WriteLineInd ("if (" + list + " == null)");
1972 WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap.TypeFullName) + ");");
1973 Unindent ();
1974 WriteLineInd ("if (!ReadNull()) {");
1976 else {
1977 list = GetObTempVar ();
1978 WriteLine (typeMap.TypeFullName + " " + list + " = null;");
1979 WriteLineInd ("if (" + list + " == null)");
1980 WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap.TypeFullName) + ");");
1981 Unindent ();
1982 return list;
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 + ");");
1991 Unindent ();
1992 WriteLineInd ("} else {");
1994 string index = GetNumTempVar ();
1995 WriteLine ("int " + index + " = 0;");
1996 WriteLine ("Reader.ReadStartElement();");
1997 WriteLine ("Reader.MoveToContent();");
1998 WriteLine ("");
2000 WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
2001 WriteLineInd ("{");
2002 WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
2003 WriteLineInd ("{");
2005 bool first = true;
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 + "++;");
2011 WriteLineUni ("}");
2012 first = false;
2014 if (!first) WriteLine ("else UnknownNode (null);");
2015 else WriteLine ("UnknownNode (null);");
2017 WriteLineUni ("}");
2018 WriteLine ("else UnknownNode (null);");
2019 WriteLine ("");
2020 WriteLine ("Reader.MoveToContent();");
2021 WriteLineUni ("}");
2023 WriteLine ("ReadEndElement();");
2025 if (listType.IsArray)
2026 WriteLine (list + " = (" + typeMap.TypeFullName + ") ShrinkArray (" + list + ", " + index + ", " + GetTypeOf(listType.GetElementType()) + ", " + isNullable + ");");
2028 WriteLineUni ("}");
2029 WriteLineUni ("}");
2031 return list;
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) + ";");
2057 Unindent ();
2058 WriteLineUni ("}");
2059 WriteLine ("else");
2060 WriteLine ("\t" + list + " = new " + itemType + " [0];");
2062 return list;
2065 void GenerateAddListValue (TypeData listType, string list, string index, string value, bool canCreateInstance)
2067 Type type = listType.Type;
2068 if (type.IsArray)
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 + "();");
2078 else
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()) + ")";
2089 else
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)");
2099 WriteLineInd ("{");
2100 WriteLine ("if (list == null) throw CreateReadOnlyCollectionException (" + GetLiteral (td.FullTypeName) + ");");
2101 WriteLine ("");
2103 WriteLine (td.FullTypeName + " dest = (" + td.FullTypeName + ") list;");
2104 WriteLine ("foreach (object ob in (IEnumerable)source)");
2105 WriteLine ("\tdest.Add (" + GetCast (td.ListItemTypeData, "ob") + ");");
2106 WriteLineUni ("}");
2107 WriteLine ("");
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;
2141 if (map.IsFlags)
2143 string switchMethod = metName + "_Switch";
2144 WriteLine (typeMap.TypeFullName + " " + metName + " (string xmlName)");
2145 WriteLineInd ("{");
2146 WriteLine ("xmlName = xmlName.Trim();");
2147 WriteLine ("if (xmlName.Length == 0) return (" + typeMap.TypeFullName + ")0;");
2148 WriteLine ("if (xmlName.IndexOf (' ') != -1)");
2149 WriteLineInd ("{");
2150 WriteLine (typeMap.TypeFullName + " sb = (" + typeMap.TypeFullName + ")0;");
2151 WriteLine ("string[] enumNames = xmlName.ToString().Split (' ');");
2152 WriteLine ("foreach (string name in enumNames)");
2153 WriteLineInd ("{");
2154 WriteLine ("if (name == string.Empty) continue;");
2155 WriteLine ("sb |= " + switchMethod + " (name); ");
2156 WriteLineUni ("}");
2157 WriteLine ("return sb;");
2158 WriteLineUni ("}");
2159 WriteLine ("else");
2160 WriteLine ("\treturn " + switchMethod + " (xmlName);");
2161 WriteLineUni ("}");
2162 metName = switchMethod;
2165 WriteLine (typeMap.TypeFullName + " " + metName + " (string xmlName)");
2166 WriteLineInd ("{");
2167 GenerateGetSingleEnumValue (typeMap, "xmlName");
2168 WriteLineUni ("}");
2169 WriteLine ("");
2172 void GenerateGetSingleEnumValue (XmlTypeMapping typeMap, string val)
2174 EnumMap map = (EnumMap) typeMap.ObjectMap;
2175 WriteLine ("switch (" + val + ")");
2176 WriteLineInd ("{");
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);");
2184 WriteLineUni ("}");
2185 WriteLineInd ("catch {");
2186 WriteLine ("throw CreateUnknownConstantException (" + val + ", typeof(" + typeMap.TypeFullName + "));");
2187 WriteLineUni ("}");
2188 Unindent ();
2189 WriteLineUni ("}");
2192 void GenerateReadXmlSerializableElement (XmlTypeMapping typeMap, string isNullable)
2194 WriteLine ("Reader.MoveToContent ();");
2195 WriteLine ("if (Reader.NodeType == XmlNodeType.Element)");
2196 WriteLineInd ("{");
2197 WriteLine ("if (Reader.LocalName == " + GetLiteral (typeMap.ElementName) + " && Reader.NamespaceURI == " + GetLiteral (typeMap.Namespace) + ")");
2198 WriteLine ("\treturn ReadSerializable (new " + typeMap.TypeData.FullTypeName + "());");
2199 WriteLine ("else");
2200 WriteLine ("\tthrow CreateUnknownNodeException ();");
2201 WriteLineUni ("}");
2202 WriteLine ("else UnknownNode (null);");
2203 WriteLine ("");
2204 WriteLine ("return null;");
2207 void GenerateReadInitCallbacks ()
2209 WriteLine ("protected override void InitCallbacks ()");
2210 WriteLineInd ("{");
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) + ")");
2223 WriteLineUni ("}");
2224 WriteLine ("");
2226 WriteLine ("protected override void InitIDs ()");
2227 WriteLine ("{");
2228 WriteLine ("}");
2229 WriteLine ("");
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)");
2239 WriteLineInd ("{");
2240 WriteLine ("Fixup fixup = (Fixup)obfixup;");
2241 WriteLine (tname + " source = (" + tname + ") fixup.Source;");
2242 WriteLine ("string[] ids = fixup.Ids;");
2243 WriteLine ("");
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);
2252 Unindent ();
2255 WriteLineUni ("}");
2256 WriteLine ("");
2260 string GetReadXmlNode (TypeData type, bool wrapped)
2262 if (type.Type == typeof (XmlDocument))
2263 return GetCast (type, TypeTranslator.GetTypeData (typeof(XmlDocument)), "ReadXmlDocument (" + GetLiteral(wrapped) + ")");
2264 else
2265 return GetCast (type, TypeTranslator.GetTypeData (typeof(XmlNode)), "ReadXmlNode (" + GetLiteral(wrapped) + ")");
2268 #endregion
2270 #region Helper methods
2272 //*******************************************************
2273 // Helper methods
2276 ArrayList _listsToFill = new ArrayList ();
2277 Hashtable _hooks;
2278 Hashtable _hookVariables;
2279 Stack _hookContexts;
2280 Stack _hookOpenHooks;
2282 class HookInfo {
2283 public HookType HookType;
2284 public Type Type;
2285 public string Member;
2286 public HookDir Direction;
2289 void InitHooks ()
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);
2353 return true;
2355 else
2357 HookInfo hi = new HookInfo ();
2358 hi.HookType = hookType;
2359 hi.Type = type;
2360 hi.Member = member;
2361 hi.Direction = dir;
2362 _hookOpenHooks.Push (hi);
2363 return false;
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);
2385 return true;
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++));
2429 names [ob] = name;
2430 return name;
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);
2469 else
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 + ")";
2482 else
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)
2537 WriteLine (code);
2538 _indent++;
2541 void WriteLineUni (string code)
2543 if (_indent > 0) _indent--;
2544 WriteLine (code);
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);
2561 WriteLine (code);
2564 string Params (params string[] pars)
2566 string res = "";
2567 foreach (string p in pars)
2569 if (res != "") res += ", ";
2570 res += p;
2572 return res;
2575 void WriteMetCall (string method, params string[] pars)
2577 WriteLine (method + " (" + Params (pars) + ");");
2580 void Indent ()
2582 _indent++;
2585 void Unindent ()
2587 _indent--;
2590 #endregion
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;