1 //------------------------------------------------------------------------------
2 // <copyright file="XmlSerializationReaderILGen.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">[....]</owner>
6 //------------------------------------------------------------------------------
8 namespace System.Xml.Serialization {
11 using System.Collections;
12 using System.Collections.Generic;
13 using System.Diagnostics;
14 using System.Globalization;
15 using System.Reflection;
16 using System.Reflection.Emit;
17 using System.Security;
18 using System.Text.RegularExpressions;
20 using System.Xml.Schema;
22 internal class XmlSerializationReaderILGen : XmlSerializationILGen {
23 Hashtable idNames = new Hashtable();
24 // Mapping name->id_XXXNN field
25 Dictionary<string, FieldBuilder> idNameFields = new Dictionary<string, FieldBuilder>();
28 int nextWhileLoopIndex = 0;
30 internal Hashtable Enums {
33 enums = new Hashtable();
39 class CreateCollectionInfo {
43 internal CreateCollectionInfo(string name, TypeDesc td) {
47 internal string Name {
51 internal TypeDesc TypeDesc {
59 string choiceArrayName;
61 string choiceArraySource;
62 MemberMapping mapping;
68 string paramsReadSource;
69 string checkSpecifiedSource;
71 internal Member(XmlSerializationReaderILGen outerClass, string source, string arrayName, int i, MemberMapping mapping)
72 : this(outerClass, source, null, arrayName, i, mapping, false, null) {
74 internal Member(XmlSerializationReaderILGen outerClass, string source, string arrayName, int i, MemberMapping mapping, string choiceSource)
75 : this(outerClass, source, null, arrayName, i, mapping, false, choiceSource) {
77 internal Member(XmlSerializationReaderILGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping)
78 : this(outerClass, source, arraySource, arrayName, i, mapping, false, null) {
80 internal Member(XmlSerializationReaderILGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping, string choiceSource)
81 : this(outerClass, source, arraySource, arrayName, i, mapping, false, choiceSource) {
83 internal Member(XmlSerializationReaderILGen outerClass, string source, string arrayName, int i, MemberMapping mapping, bool multiRef)
84 : this(outerClass, source, null, arrayName, i, mapping, multiRef, null) {
86 internal Member(XmlSerializationReaderILGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping, bool multiRef, string choiceSource) {
88 this.arrayName = arrayName + "_" + i.ToString(CultureInfo.InvariantCulture);
89 this.choiceArrayName = "choice_" + this.arrayName;
90 this.choiceSource = choiceSource;
92 if (mapping.TypeDesc.IsArrayLike) {
93 if (arraySource != null)
94 this.arraySource = arraySource;
96 this.arraySource = outerClass.GetArraySource(mapping.TypeDesc, this.arrayName, multiRef);
97 isArray = mapping.TypeDesc.IsArray;
99 if (mapping.ChoiceIdentifier != null) {
100 this.choiceArraySource = outerClass.GetArraySource(mapping.TypeDesc, this.choiceArrayName, multiRef);
102 string a = choiceArrayName;
104 string choiceTypeFullName = mapping.ChoiceIdentifier.Mapping.TypeDesc.CSharpName;
105 string castString = "(" + choiceTypeFullName + "[])";
107 string init = a + " = " + castString +
108 "EnsureArrayIndex(" + a + ", " + c + ", " + outerClass.RaCodeGen.GetStringForTypeof(choiceTypeFullName) + ");";
109 this.choiceArraySource = init + outerClass.RaCodeGen.GetStringForArrayMember(a, c + "++", mapping.ChoiceIdentifier.Mapping.TypeDesc);
112 this.choiceArraySource = this.choiceSource;
116 this.arraySource = arraySource == null ? source : arraySource;
117 this.choiceArraySource = this.choiceSource;
119 this.mapping = mapping;
122 internal MemberMapping Mapping {
123 get { return mapping; }
126 internal string Source {
127 get { return source; }
130 internal string ArrayName {
131 get { return arrayName; }
134 internal string ArraySource {
135 get { return arraySource; }
138 internal bool IsList {
139 get { return isList; }
142 internal bool IsArrayLike {
143 get { return (isArray || isList); }
146 internal bool IsNullable {
147 get { return isNullable; }
148 set { isNullable = value; }
151 internal bool MultiRef {
152 get { return multiRef; }
153 set { multiRef = value; }
156 internal int FixupIndex {
157 get { return fixupIndex; }
158 set { fixupIndex = value; }
161 internal string ParamsReadSource {
162 get { return paramsReadSource; }
163 set { paramsReadSource = value; }
166 internal string CheckSpecifiedSource {
167 get { return checkSpecifiedSource; }
168 set { checkSpecifiedSource = value; }
171 internal string ChoiceSource {
172 get { return choiceSource; }
174 internal string ChoiceArrayName {
175 get { return choiceArrayName; }
177 internal string ChoiceArraySource {
178 get { return choiceArraySource; }
182 internal XmlSerializationReaderILGen(TypeScope[] scopes, string access, string className)
183 : base(scopes, access, className) {
186 internal void GenerateBegin() {
187 this.typeBuilder = CodeGenerator.CreateTypeBuilder(
190 TypeAttributes | TypeAttributes.BeforeFieldInit,
191 typeof(XmlSerializationReader),
192 CodeGenerator.EmptyTypeArray);
193 foreach (TypeScope scope in Scopes) {
194 foreach (TypeMapping mapping in scope.TypeMappings) {
195 if (mapping is StructMapping || mapping is EnumMapping || mapping is NullableMapping)
196 MethodNames.Add(mapping, NextMethodName(mapping.TypeDesc.Name));
198 RaCodeGen.WriteReflectionInit(scope);
202 internal override void GenerateMethod(TypeMapping mapping) {
203 if (GeneratedMethods.Contains(mapping))
206 GeneratedMethods[mapping] = mapping;
207 if (mapping is StructMapping) {
208 WriteStructMethod((StructMapping)mapping);
210 else if (mapping is EnumMapping) {
211 WriteEnumMethod((EnumMapping)mapping);
213 else if (mapping is NullableMapping) {
214 WriteNullableMethod((NullableMapping)mapping);
218 internal void GenerateEnd(string[] methods, XmlMapping[] xmlMappings, Type[] types) {
219 GenerateReferencedMethods();
220 GenerateInitCallbacksMethod();
222 ilg = new CodeGenerator(this.typeBuilder);
223 ilg.BeginMethod(typeof(void), "InitIDs", CodeGenerator.EmptyTypeArray, CodeGenerator.EmptyStringArray,
224 CodeGenerator.ProtectedOverrideMethodAttributes);
225 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
227 CodeGenerator.InstanceBindingFlags,
229 CodeGenerator.EmptyTypeArray,
232 MethodInfo XmlReader_get_NameTable = typeof(XmlReader).GetMethod(
234 CodeGenerator.InstanceBindingFlags,
236 CodeGenerator.EmptyTypeArray,
239 MethodInfo XmlNameTable_Add = typeof(XmlNameTable).GetMethod(
241 CodeGenerator.InstanceBindingFlags,
243 new Type[] { typeof(String) },
246 foreach (string id in idNames.Keys) {
250 ilg.Call(XmlSerializationReader_get_Reader);
251 ilg.Call(XmlReader_get_NameTable);
253 ilg.Call(XmlNameTable_Add);
254 Debug.Assert(idNameFields.ContainsKey(id));
255 ilg.StoreMember(idNameFields[id]);
259 this.typeBuilder.DefineDefaultConstructor(
260 CodeGenerator.PublicMethodAttributes);
261 Type readerType = this.typeBuilder.CreateType();
262 CreatedTypes.Add(readerType.Name, readerType);
265 internal string GenerateElement(XmlMapping xmlMapping) {
266 if (!xmlMapping.IsReadable)
268 if (!xmlMapping.GenerateSerializer)
269 throw new ArgumentException(Res.GetString(Res.XmlInternalError), "xmlMapping");
270 if (xmlMapping is XmlTypeMapping)
271 return GenerateTypeElement((XmlTypeMapping)xmlMapping);
272 else if (xmlMapping is XmlMembersMapping)
273 return GenerateMembersElement((XmlMembersMapping)xmlMapping);
275 throw new ArgumentException(Res.GetString(Res.XmlInternalError), "xmlMapping");
278 void WriteIsStartTag(string name, string ns) {
281 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
283 CodeGenerator.InstanceBindingFlags,
285 CodeGenerator.EmptyTypeArray,
288 MethodInfo XmlReader_IsStartElement = typeof(XmlReader).GetMethod(
290 CodeGenerator.InstanceBindingFlags,
292 new Type[] { typeof(String), typeof(String) },
296 ilg.Call(XmlSerializationReader_get_Reader);
298 ilg.LoadMember(idNameFields[name ?? String.Empty]);
300 ilg.LoadMember(idNameFields[ns ?? String.Empty]);
301 ilg.Call(XmlReader_IsStartElement);
305 void WriteUnknownNode(string func, string node, ElementAccessor e, bool anyIfs) {
309 List<Type> argTypes = new List<Type>();
311 Debug.Assert(node == "null" || node == "(object)p");
315 object pVar = ilg.GetVariable("p");
317 ilg.ConvertValue(ilg.GetVariableType(pVar), typeof(object));
319 argTypes.Add(typeof(object));
321 string expectedElement = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
322 expectedElement += ":";
323 expectedElement += e.Name;
324 ilg.Ldstr(ReflectionAwareILGen.GetCSharpString(expectedElement));
325 argTypes.Add(typeof(string));
327 MethodInfo method = typeof(XmlSerializationReader).GetMethod(
329 CodeGenerator.InstanceBindingFlags,
340 void GenerateInitCallbacksMethod() {
341 ilg = new CodeGenerator(this.typeBuilder);
342 ilg.BeginMethod(typeof(void), "InitCallbacks", CodeGenerator.EmptyTypeArray, CodeGenerator.EmptyStringArray,
343 CodeGenerator.ProtectedOverrideMethodAttributes);
345 string dummyArrayMethodName = NextMethodName("Array");
346 bool needDummyArrayMethod = false;
349 if (needDummyArrayMethod) {
352 GetMethodBuilder(dummyArrayMethodName),
353 CodeGenerator.EmptyTypeArray,
354 CodeGenerator.EmptyStringArray,
355 CodeGenerator.PrivateMethodAttributes);
356 MethodInfo XmlSerializationReader_UnknownNode1 = typeof(XmlSerializationReader).GetMethod(
358 CodeGenerator.InstanceBindingFlags,
360 new Type[] { typeof(object) },
365 ilg.Call(XmlSerializationReader_UnknownNode1);
372 string GenerateMembersElement(XmlMembersMapping xmlMembersMapping) {
373 return GenerateLiteralMembersElement(xmlMembersMapping);
376 string GetChoiceIdentifierSource(MemberMapping[] mappings, MemberMapping member) {
377 string choiceSource = null;
378 if (member.ChoiceIdentifier != null) {
379 for (int j = 0; j < mappings.Length; j++) {
380 if (mappings[j].Name == member.ChoiceIdentifier.MemberName) {
381 choiceSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
386 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
387 if (choiceSource == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Can not find " + member.ChoiceIdentifier.MemberName + " in the members mapping."));
394 string GetChoiceIdentifierSource(MemberMapping mapping, string parent, TypeDesc parentTypeDesc) {
395 if (mapping.ChoiceIdentifier == null) return "";
396 CodeIdentifier.CheckValidIdentifier(mapping.ChoiceIdentifier.MemberName);
397 return RaCodeGen.GetStringForMember(parent, mapping.ChoiceIdentifier.MemberName, parentTypeDesc);
400 string GenerateLiteralMembersElement(XmlMembersMapping xmlMembersMapping) {
401 ElementAccessor element = xmlMembersMapping.Accessor;
402 MemberMapping[] mappings = ((MembersMapping)element.Mapping).Members;
403 bool hasWrapperElement = ((MembersMapping)element.Mapping).HasWrapperElement;
404 string methodName = NextMethodName(element.Name);
405 ilg = new CodeGenerator(this.typeBuilder);
409 CodeGenerator.EmptyTypeArray,
410 CodeGenerator.EmptyStringArray,
411 CodeGenerator.PublicMethodAttributes
414 ilg.Stloc(ilg.ReturnLocal);
415 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
417 CodeGenerator.InstanceBindingFlags,
419 CodeGenerator.EmptyTypeArray,
422 MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
424 CodeGenerator.InstanceBindingFlags,
426 CodeGenerator.EmptyTypeArray,
430 ilg.Call(XmlSerializationReader_get_Reader);
431 ilg.Call(XmlReader_MoveToContent);
434 LocalBuilder localP = ilg.DeclareLocal(typeof(object[]), "p");
435 ilg.NewArray(typeof(object), mappings.Length);
437 InitializeValueTypes("p", mappings);
439 int wrapperLoopIndex = 0;
440 if (hasWrapperElement) {
441 wrapperLoopIndex = WriteWhileNotLoopStart();
442 WriteIsStartTag(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
445 Member anyText = null;
446 Member anyElement = null;
447 Member anyAttribute = null;
449 ArrayList membersList = new ArrayList();
450 ArrayList textOrArrayMembersList = new ArrayList();
451 ArrayList attributeMembersList = new ArrayList();
453 for (int i = 0; i < mappings.Length; i++) {
454 MemberMapping mapping = mappings[i];
455 string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
456 string arraySource = source;
457 if (mapping.Xmlns != null) {
458 arraySource = "((" + mapping.TypeDesc.CSharpName + ")" + source + ")";
460 string choiceSource = GetChoiceIdentifierSource(mappings, mapping);
461 Member member = new Member(this, source, arraySource, "a", i, mapping, choiceSource);
462 Member anyMember = new Member(this, source, null, "a", i, mapping, choiceSource);
463 if (!mapping.IsSequence)
464 member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
465 if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite) {
466 string nameSpecified = mapping.Name + "Specified";
467 for (int j = 0; j < mappings.Length; j++) {
468 if (mappings[j].Name == nameSpecified) {
469 member.CheckSpecifiedSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
474 bool foundAnyElement = false;
475 if (mapping.Text != null) anyText = anyMember;
476 if (mapping.Attribute != null && mapping.Attribute.Any)
477 anyAttribute = anyMember;
478 if (mapping.Attribute != null || mapping.Xmlns != null)
479 attributeMembersList.Add(member);
480 else if (mapping.Text != null)
481 textOrArrayMembersList.Add(member);
483 if (!mapping.IsSequence) {
484 for (int j = 0; j < mapping.Elements.Length; j++) {
485 if (mapping.Elements[j].Any && mapping.Elements[j].Name.Length == 0) {
486 anyElement = anyMember;
487 if (mapping.Attribute == null && mapping.Text == null)
488 textOrArrayMembersList.Add(anyMember);
489 foundAnyElement = true;
494 if (mapping.Attribute != null || mapping.Text != null || foundAnyElement)
495 membersList.Add(anyMember);
496 else if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) {
497 membersList.Add(anyMember);
498 textOrArrayMembersList.Add(anyMember);
501 if (mapping.TypeDesc.IsArrayLike && !mapping.TypeDesc.IsArray)
502 member.ParamsReadSource = null; // collection
503 membersList.Add(member);
506 Member[] members = (Member[])membersList.ToArray(typeof(Member));
507 Member[] textOrArrayMembers = (Member[])textOrArrayMembersList.ToArray(typeof(Member));
509 if (members.Length > 0 && members[0].Mapping.IsReturnValue) {
510 MethodInfo XmlSerializationReader_set_IsReturnValue = typeof(XmlSerializationReader).GetMethod(
512 CodeGenerator.InstanceBindingFlags,
514 new Type[] { typeof(Boolean) },
519 ilg.Call(XmlSerializationReader_set_IsReturnValue);
522 WriteParamsRead(mappings.Length);
524 if (attributeMembersList.Count > 0) {
525 Member[] attributeMembers = (Member[])attributeMembersList.ToArray(typeof(Member));
526 WriteMemberBegin(attributeMembers);
527 WriteAttributes(attributeMembers, anyAttribute, "UnknownNode", localP);
528 WriteMemberEnd(attributeMembers);
529 MethodInfo XmlReader_MoveToElement = typeof(XmlReader).GetMethod(
531 CodeGenerator.InstanceBindingFlags,
533 CodeGenerator.EmptyTypeArray,
537 ilg.Call(XmlSerializationReader_get_Reader);
538 ilg.Call(XmlReader_MoveToElement);
542 WriteMemberBegin(textOrArrayMembers);
544 if (hasWrapperElement) {
545 MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
546 "get_IsEmptyElement",
547 CodeGenerator.InstanceBindingFlags,
549 CodeGenerator.EmptyTypeArray,
553 ilg.Call(XmlSerializationReader_get_Reader);
554 ilg.Call(XmlReader_get_IsEmptyElement);
557 MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
559 CodeGenerator.InstanceBindingFlags,
561 CodeGenerator.EmptyTypeArray,
565 ilg.Call(XmlSerializationReader_get_Reader);
566 ilg.Call(XmlReader_Skip);
568 ilg.Call(XmlSerializationReader_get_Reader);
569 ilg.Call(XmlReader_MoveToContent);
574 MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
576 CodeGenerator.InstanceBindingFlags,
578 CodeGenerator.EmptyTypeArray,
582 ilg.Call(XmlSerializationReader_get_Reader);
583 ilg.Call(XmlReader_ReadStartElement);
585 if (IsSequence(members)) {
587 ilg.Stloc(typeof(Int32), "state");
589 int loopIndex = WriteWhileNotLoopStart();
591 string unknownNode = "UnknownNode((object)p, " + ExpectedElements(members) + ");";
592 WriteMemberElements(members, unknownNode, unknownNode, anyElement, anyText);
595 ilg.Call(XmlSerializationReader_get_Reader);
596 ilg.Call(XmlReader_MoveToContent);
598 WriteWhileLoopEnd(loopIndex);
600 WriteMemberEnd(textOrArrayMembers);
602 if (hasWrapperElement) {
603 MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
605 CodeGenerator.InstanceBindingFlags,
607 CodeGenerator.EmptyTypeArray,
611 ilg.Call(XmlSerializationReader_ReadEndElement);
614 WriteUnknownNode("UnknownNode", "null", element, true);
617 ilg.Call(XmlSerializationReader_get_Reader);
618 ilg.Call(XmlReader_MoveToContent);
620 WriteWhileLoopEnd(wrapperLoopIndex);
623 ilg.Ldloc(ilg.GetLocal("p"));
629 void InitializeValueTypes(string arrayName, MemberMapping[] mappings) {
630 for (int i = 0; i < mappings.Length; i++) {
631 if (!mappings[i].TypeDesc.IsValueType)
633 LocalBuilder arrayLoc = ilg.GetLocal(arrayName);
636 RaCodeGen.ILGenForCreateInstance(ilg, mappings[i].TypeDesc.Type, false, false);
637 ilg.ConvertValue(mappings[i].TypeDesc.Type, typeof(object));
638 ilg.Stelem(arrayLoc.LocalType.GetElementType());
642 string GenerateTypeElement(XmlTypeMapping xmlTypeMapping) {
643 ElementAccessor element = xmlTypeMapping.Accessor;
644 TypeMapping mapping = element.Mapping;
645 string methodName = NextMethodName(element.Name);
646 ilg = new CodeGenerator(this.typeBuilder);
650 CodeGenerator.EmptyTypeArray,
651 CodeGenerator.EmptyStringArray,
652 CodeGenerator.PublicMethodAttributes
654 LocalBuilder oLoc = ilg.DeclareLocal(typeof(object), "o");
657 MemberMapping member = new MemberMapping();
658 member.TypeDesc = mapping.TypeDesc;
659 //member.ReadOnly = !mapping.TypeDesc.HasDefaultConstructor;
660 member.Elements = new ElementAccessor[] { element };
661 Member[] members = new Member[] { new Member(this, "o", "o", "a", 0, member) };
662 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
664 CodeGenerator.InstanceBindingFlags,
666 CodeGenerator.EmptyTypeArray,
669 MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
671 CodeGenerator.InstanceBindingFlags,
673 CodeGenerator.EmptyTypeArray,
677 ilg.Call(XmlSerializationReader_get_Reader);
678 ilg.Call(XmlReader_MoveToContent);
680 string unknownNode = "UnknownNode(null, " + ExpectedElements(members) + ");";
681 WriteMemberElements(members, "throw CreateUnknownNodeException();", unknownNode, element.Any ? members[0] : null, null);
683 // for code compat as compiler does
684 ilg.Stloc(ilg.ReturnLocal);
685 ilg.Ldloc(ilg.ReturnLocal);
690 string NextMethodName(string name) {
691 return "Read" + (++NextMethodNumber).ToString(CultureInfo.InvariantCulture) + "_" + CodeIdentifier.MakeValidInternal(name);
694 string NextIdName(string name) {
695 return "id" + (++nextIdNumber).ToString(CultureInfo.InvariantCulture) + "_" + CodeIdentifier.MakeValidInternal(name);
698 void WritePrimitive(TypeMapping mapping, string source) {
699 System.Diagnostics.Debug.Assert(source == "Reader.ReadElementString()" || source == "Reader.ReadString()"
700 || source == "false" || source == "Reader.Value" || source == "vals[i]");
701 if (mapping is EnumMapping) {
702 string enumMethodName = ReferenceMapping(mapping);
703 if (enumMethodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlMissingMethodEnum, mapping.TypeDesc.Name));
704 // For enum, its read method (eg. Read1_Gender) could be called multiple times
705 // prior to its declaration.
706 MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
708 CodeGenerator.PrivateMethodAttributes,
709 mapping.TypeDesc.Type,
710 new Type[] { typeof(string) }
713 if (source == "Reader.ReadElementString()" || source == "Reader.ReadString()") {
714 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
716 CodeGenerator.InstanceBindingFlags,
718 CodeGenerator.EmptyTypeArray,
721 MethodInfo XmlReader_ReadXXXString = typeof(XmlReader).GetMethod(
722 source == "Reader.ReadElementString()" ? "ReadElementString" : "ReadString",
723 CodeGenerator.InstanceBindingFlags,
725 CodeGenerator.EmptyTypeArray,
729 ilg.Call(XmlSerializationReader_get_Reader);
730 ilg.Call(XmlReader_ReadXXXString);
732 else if (source == "Reader.Value") {
733 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
735 CodeGenerator.InstanceBindingFlags,
737 CodeGenerator.EmptyTypeArray,
740 MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
742 CodeGenerator.InstanceBindingFlags,
744 CodeGenerator.EmptyTypeArray,
748 ilg.Call(XmlSerializationReader_get_Reader);
749 ilg.Call(XmlReader_get_Value);
751 else if (source == "vals[i]") {
752 LocalBuilder locVals = ilg.GetLocal("vals");
753 LocalBuilder locI = ilg.GetLocal("i");
754 ilg.LoadArrayElement(locVals, locI);
756 else if (source == "false") {
760 throw CodeGenerator.NotSupported("Unexpected: " + source);
762 ilg.Call(methodBuilder);
764 else if (mapping.TypeDesc == StringTypeDesc) {
765 if (source == "Reader.ReadElementString()" || source == "Reader.ReadString()") {
766 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
768 CodeGenerator.InstanceBindingFlags,
770 CodeGenerator.EmptyTypeArray,
773 MethodInfo XmlReader_ReadXXXString = typeof(XmlReader).GetMethod(
774 source == "Reader.ReadElementString()" ? "ReadElementString" : "ReadString",
775 CodeGenerator.InstanceBindingFlags,
777 CodeGenerator.EmptyTypeArray,
781 ilg.Call(XmlSerializationReader_get_Reader);
782 ilg.Call(XmlReader_ReadXXXString);
784 else if (source == "Reader.Value") {
785 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
787 CodeGenerator.InstanceBindingFlags,
789 CodeGenerator.EmptyTypeArray,
792 MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
794 CodeGenerator.InstanceBindingFlags,
796 CodeGenerator.EmptyTypeArray,
800 ilg.Call(XmlSerializationReader_get_Reader);
801 ilg.Call(XmlReader_get_Value);
803 else if (source == "vals[i]") {
804 LocalBuilder locVals = ilg.GetLocal("vals");
805 LocalBuilder locI = ilg.GetLocal("i");
806 ilg.LoadArrayElement(locVals, locI);
809 throw CodeGenerator.NotSupported("Unexpected: " + source);
812 else if (mapping.TypeDesc.FormatterName == "String") {
813 if (source == "vals[i]") {
814 if (mapping.TypeDesc.CollapseWhitespace)
816 LocalBuilder locVals = ilg.GetLocal("vals");
817 LocalBuilder locI = ilg.GetLocal("i");
818 ilg.LoadArrayElement(locVals, locI);
819 if (mapping.TypeDesc.CollapseWhitespace) {
820 MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod(
821 "CollapseWhitespace",
822 CodeGenerator.InstanceBindingFlags,
824 new Type[] { typeof(String) },
827 ilg.Call(XmlSerializationReader_CollapseWhitespace);
831 System.Diagnostics.Debug.Assert(source == "Reader.Value" || source == "Reader.ReadElementString()");
832 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
834 CodeGenerator.InstanceBindingFlags,
836 CodeGenerator.EmptyTypeArray,
839 MethodInfo XmlReader_method = typeof(XmlReader).GetMethod(
840 source == "Reader.Value" ? "get_Value" : "ReadElementString",
841 CodeGenerator.InstanceBindingFlags,
843 CodeGenerator.EmptyTypeArray,
846 if (mapping.TypeDesc.CollapseWhitespace)
849 ilg.Call(XmlSerializationReader_get_Reader);
850 ilg.Call(XmlReader_method);
851 if (mapping.TypeDesc.CollapseWhitespace) {
852 MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod(
853 "CollapseWhitespace",
854 CodeGenerator.InstanceBindingFlags,
856 new Type[] { typeof(String) },
859 ilg.Call(XmlSerializationReader_CollapseWhitespace);
864 Type argType = source == "false" ? typeof(Boolean) : typeof(String);
866 if (mapping.TypeDesc.HasCustomFormatter) {
868 // Only these methods below that is non Static and need to ldarg("this") for Call.
869 BindingFlags bindingFlags = CodeGenerator.StaticBindingFlags;
870 if ((mapping.TypeDesc.FormatterName == "ByteArrayBase64" && source == "false")
871 || (mapping.TypeDesc.FormatterName == "ByteArrayHex" && source == "false")
872 || (mapping.TypeDesc.FormatterName == "XmlQualifiedName")) {
873 bindingFlags = CodeGenerator.InstanceBindingFlags;
877 ToXXX = typeof(XmlSerializationReader).GetMethod(
878 "To" + mapping.TypeDesc.FormatterName,
881 new Type[] { argType },
886 ToXXX = typeof(XmlConvert).GetMethod(
887 "To" + mapping.TypeDesc.FormatterName,
888 CodeGenerator.StaticBindingFlags,
890 new Type[] { argType },
894 if (source == "Reader.ReadElementString()" || source == "Reader.ReadString()") {
895 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
897 CodeGenerator.InstanceBindingFlags,
899 CodeGenerator.EmptyTypeArray,
902 MethodInfo XmlReader_ReadXXXString = typeof(XmlReader).GetMethod(
903 source == "Reader.ReadElementString()" ? "ReadElementString" : "ReadString",
904 CodeGenerator.InstanceBindingFlags,
906 CodeGenerator.EmptyTypeArray,
910 ilg.Call(XmlSerializationReader_get_Reader);
911 ilg.Call(XmlReader_ReadXXXString);
913 else if (source == "Reader.Value") {
914 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
916 CodeGenerator.InstanceBindingFlags,
918 CodeGenerator.EmptyTypeArray,
921 MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
923 CodeGenerator.InstanceBindingFlags,
925 CodeGenerator.EmptyTypeArray,
929 ilg.Call(XmlSerializationReader_get_Reader);
930 ilg.Call(XmlReader_get_Value);
932 else if (source == "vals[i]") {
933 LocalBuilder locVals = ilg.GetLocal("vals");
934 LocalBuilder locI = ilg.GetLocal("i");
935 ilg.LoadArrayElement(locVals, locI);
938 System.Diagnostics.Debug.Assert(source == "false");
945 string MakeUnique(EnumMapping mapping, string name) {
946 string uniqueName = name;
947 object m = Enums[uniqueName];
950 // we already have created the hashtable
956 uniqueName = name + i.ToString(CultureInfo.InvariantCulture);
957 m = Enums[uniqueName];
960 Enums.Add(uniqueName, mapping);
964 string WriteHashtable(EnumMapping mapping, string typeName, out MethodBuilder get_TableName) {
965 get_TableName = null;
967 CodeIdentifier.CheckValidIdentifier(typeName);
968 string propName = MakeUnique(mapping, typeName + "Values");
969 if (propName == null) return CodeIdentifier.GetCSharpName(typeName);
970 string memberName = MakeUnique(mapping, "_" + propName);
971 propName = CodeIdentifier.GetCSharpName(propName);
973 FieldBuilder fieldBuilder = this.typeBuilder.DefineField(
976 FieldAttributes.Private
979 PropertyBuilder propertyBuilder = this.typeBuilder.DefineProperty(
981 PropertyAttributes.None,
982 CallingConventions.HasThis,
984 null, null, null, null, null);
986 ilg = new CodeGenerator(this.typeBuilder);
990 CodeGenerator.EmptyTypeArray,
991 CodeGenerator.EmptyStringArray,
992 MethodAttributes.Assembly | MethodAttributes.HideBySig | MethodAttributes.SpecialName);
995 ilg.LoadMember(fieldBuilder);
999 ConstructorInfo Hashtable_ctor = typeof(Hashtable).GetConstructor(
1000 CodeGenerator.InstanceBindingFlags,
1002 CodeGenerator.EmptyTypeArray,
1005 LocalBuilder hLoc = ilg.DeclareLocal(typeof(Hashtable), "h");
1006 ilg.New(Hashtable_ctor);
1009 ConstantMapping[] constants = mapping.Constants;
1010 MethodInfo Hashtable_Add = typeof(Hashtable).GetMethod(
1012 CodeGenerator.InstanceBindingFlags,
1014 new Type[] { typeof(Object), typeof(Object) },
1018 for (int i = 0; i < constants.Length; i++) {
1020 ilg.Ldstr(constants[i].XmlName);
1021 ilg.Ldc(Enum.ToObject(mapping.TypeDesc.Type, constants[i].Value));
1022 ilg.ConvertValue(mapping.TypeDesc.Type, typeof(long));
1023 ilg.ConvertValue(typeof(long), typeof(Object));
1025 ilg.Call(Hashtable_Add);
1030 ilg.StoreMember(fieldBuilder);
1035 ilg.LoadMember(fieldBuilder);
1037 get_TableName = ilg.EndMethod();
1038 propertyBuilder.SetGetMethod(get_TableName);
1043 void WriteEnumMethod(EnumMapping mapping) {
1044 MethodBuilder get_TableName = null;
1045 if (mapping.IsFlags)
1046 WriteHashtable(mapping, mapping.TypeDesc.Name, out get_TableName);
1048 string methodName = (string)MethodNames[mapping];
1049 string fullTypeName = mapping.TypeDesc.CSharpName;
1050 List<Type> argTypes = new List<Type>();
1051 List<string> argNames = new List<string>();
1053 Type underlyingType;
1055 returnType = mapping.TypeDesc.Type;
1056 underlyingType = Enum.GetUnderlyingType(returnType);
1057 argTypes.Add(typeof(string));
1059 ilg = new CodeGenerator(this.typeBuilder);
1062 GetMethodBuilder(methodName),
1065 CodeGenerator.PrivateMethodAttributes);
1067 ConstantMapping[] constants = mapping.Constants;
1068 if (mapping.IsFlags) {
1070 MethodInfo XmlSerializationReader_ToEnum = typeof(XmlSerializationReader).GetMethod(
1072 CodeGenerator.StaticBindingFlags,
1074 new Type[] { typeof(String), typeof(Hashtable), typeof(String) },
1079 Debug.Assert(get_TableName != null);
1080 ilg.Call(get_TableName);
1081 ilg.Ldstr(fullTypeName);
1082 ilg.Call(XmlSerializationReader_ToEnum);
1083 // XmlSerializationReader_ToEnum return long!
1084 if (underlyingType != typeof(long)) {
1085 ilg.ConvertValue(typeof(long), underlyingType);
1087 ilg.Stloc(ilg.ReturnLocal);
1088 ilg.Br(ilg.ReturnLabel);
1092 List<Label> caseLabels = new List<Label>();
1093 List<object> retValues = new List<object>();
1094 Label defaultLabel = ilg.DefineLabel();
1095 Label endSwitchLabel = ilg.DefineLabel();
1096 // This local is necessary; otherwise, it becomes if/else
1097 LocalBuilder localTmp = ilg.GetTempLocal(typeof(string));
1099 ilg.Stloc(localTmp);
1100 ilg.Ldloc(localTmp);
1101 ilg.Brfalse(defaultLabel);
1102 Hashtable cases = new Hashtable();
1103 for (int i = 0; i < constants.Length; i++) {
1104 ConstantMapping c = constants[i];
1106 CodeIdentifier.CheckValidIdentifier(c.Name);
1107 if (cases[c.XmlName] == null) {
1108 cases[c.XmlName] = c.XmlName;
1109 Label caseLabel = ilg.DefineLabel();
1110 ilg.Ldloc(localTmp);
1111 ilg.Ldstr(c.XmlName);
1112 MethodInfo String_op_Equality = typeof(string).GetMethod(
1114 CodeGenerator.StaticBindingFlags,
1116 new Type[] { typeof(string), typeof(string) },
1119 ilg.Call(String_op_Equality);
1120 ilg.Brtrue(caseLabel);
1121 caseLabels.Add(caseLabel);
1122 retValues.Add(Enum.ToObject(mapping.TypeDesc.Type, c.Value));
1126 ilg.Br(defaultLabel);
1128 for (int i = 0; i < caseLabels.Count; i++) {
1129 ilg.MarkLabel(caseLabels[i]);
1130 ilg.Ldc(retValues[i]);
1131 ilg.Stloc(ilg.ReturnLocal);
1132 ilg.Br(ilg.ReturnLabel);
1134 MethodInfo XmlSerializationReader_CreateUnknownConstantException = typeof(XmlSerializationReader).GetMethod(
1135 "CreateUnknownConstantException",
1136 CodeGenerator.InstanceBindingFlags,
1138 new Type[] { typeof(string), typeof(Type) },
1142 ilg.MarkLabel(defaultLabel);
1146 ilg.Ldc(mapping.TypeDesc.Type);
1147 ilg.Call(XmlSerializationReader_CreateUnknownConstantException);
1150 ilg.MarkLabel(endSwitchLabel);
1153 ilg.MarkLabel(ilg.ReturnLabel);
1154 ilg.Ldloc(ilg.ReturnLocal);
1158 void WriteDerivedTypes(StructMapping mapping, bool isTypedReturn, string returnTypeName) {
1160 for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) {
1162 WriteQNameEqual("xsiType", derived.TypeName, derived.Namespace);
1165 string methodName = ReferenceMapping(derived);
1167 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
1168 if (methodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, derived.TypeDesc.Name));
1171 List<Type> argTypes = new List<Type>();
1173 if (derived.TypeDesc.IsNullable) {
1174 ilg.Ldarg("isNullable");
1175 argTypes.Add(typeof(Boolean));
1178 argTypes.Add(typeof(Boolean));
1180 MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
1182 CodeGenerator.PrivateMethodAttributes,
1183 derived.TypeDesc.Type,
1186 ilg.Call(methodBuilder);
1187 ilg.ConvertValue(methodBuilder.ReturnType, ilg.ReturnLocal.LocalType);
1188 ilg.Stloc(ilg.ReturnLocal);
1189 ilg.Br(ilg.ReturnLabel);
1191 WriteDerivedTypes(derived, isTypedReturn, returnTypeName);
1195 void WriteEnumAndArrayTypes() {
1196 foreach (TypeScope scope in Scopes) {
1197 foreach (Mapping m in scope.TypeMappings) {
1198 if (m is EnumMapping) {
1199 EnumMapping mapping = (EnumMapping)m;
1201 WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace);
1203 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
1205 CodeGenerator.InstanceBindingFlags,
1207 CodeGenerator.EmptyTypeArray,
1210 MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
1212 CodeGenerator.InstanceBindingFlags,
1214 CodeGenerator.EmptyTypeArray,
1218 ilg.Call(XmlSerializationReader_get_Reader);
1219 ilg.Call(XmlReader_ReadStartElement);
1220 string methodName = ReferenceMapping(mapping);
1222 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
1223 if (methodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name));
1225 LocalBuilder eLoc = ilg.DeclareOrGetLocal(typeof(object), "e");
1226 MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
1228 CodeGenerator.PrivateMethodAttributes,
1229 mapping.TypeDesc.Type,
1230 new Type[] { typeof(string) }
1232 MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod(
1233 "CollapseWhitespace",
1234 CodeGenerator.InstanceBindingFlags,
1236 new Type[] { typeof(String) },
1239 MethodInfo XmlReader_ReadString = typeof(XmlReader).GetMethod(
1241 CodeGenerator.InstanceBindingFlags,
1243 CodeGenerator.EmptyTypeArray,
1249 ilg.Call(XmlSerializationReader_get_Reader);
1250 ilg.Call(XmlReader_ReadString);
1251 ilg.Call(XmlSerializationReader_CollapseWhitespace);
1252 ilg.Call(methodBuilder);
1253 ilg.ConvertValue(methodBuilder.ReturnType, eLoc.LocalType);
1255 MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
1257 CodeGenerator.InstanceBindingFlags,
1259 CodeGenerator.EmptyTypeArray,
1263 ilg.Call(XmlSerializationReader_ReadEndElement);
1265 ilg.Stloc(ilg.ReturnLocal);
1266 ilg.Br(ilg.ReturnLabel);
1267 // Caller own calling ilg.EndIf();
1269 else if (m is ArrayMapping) {
1270 ArrayMapping mapping = (ArrayMapping)m;
1271 if (mapping.TypeDesc.HasDefaultConstructor) {
1273 WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace);
1276 MemberMapping memberMapping = new MemberMapping();
1277 memberMapping.TypeDesc = mapping.TypeDesc;
1278 memberMapping.Elements = mapping.Elements;
1281 Member member = new Member(this, aVar, zVar, 0, memberMapping);
1283 TypeDesc td = mapping.TypeDesc;
1284 LocalBuilder aLoc = ilg.DeclareLocal(mapping.TypeDesc.Type, aVar);
1285 if (mapping.TypeDesc.IsValueType) {
1286 RaCodeGen.ILGenForCreateInstance(ilg, td.Type, false, false);
1292 WriteArray(member.Source, member.ArrayName, mapping, false, false, -1, 0);
1294 ilg.Stloc(ilg.ReturnLocal);
1295 ilg.Br(ilg.ReturnLabel);
1297 // Caller own calling ilg.EndIf();
1304 void WriteNullableMethod(NullableMapping nullableMapping) {
1305 string methodName = (string)MethodNames[nullableMapping];
1306 ilg = new CodeGenerator(this.typeBuilder);
1308 nullableMapping.TypeDesc.Type,
1309 GetMethodBuilder(methodName),
1310 new Type[] { typeof(Boolean) },
1311 new string[] { "checkType" },
1312 CodeGenerator.PrivateMethodAttributes);
1314 LocalBuilder oLoc = ilg.DeclareLocal(nullableMapping.TypeDesc.Type, "o");
1316 ilg.LoadAddress(oLoc);
1317 ilg.InitObj(nullableMapping.TypeDesc.Type);
1318 MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
1320 CodeGenerator.InstanceBindingFlags,
1322 CodeGenerator.EmptyTypeArray,
1325 ilg.Call(XmlSerializationReader_ReadNull);
1329 ilg.Stloc(ilg.ReturnLocal);
1330 ilg.Br(ilg.ReturnLabel);
1334 ElementAccessor element = new ElementAccessor();
1335 element.Mapping = nullableMapping.BaseMapping;
1336 element.Any = false;
1337 element.IsNullable = nullableMapping.BaseMapping.TypeDesc.IsNullable;
1339 WriteElement("o", null, null, element, null, null, false, false, -1, -1);
1341 ilg.Stloc(ilg.ReturnLocal);
1342 ilg.Br(ilg.ReturnLabel);
1344 ilg.MarkLabel(ilg.ReturnLabel);
1345 ilg.Ldloc(ilg.ReturnLocal);
1349 void WriteStructMethod(StructMapping structMapping) {
1350 WriteLiteralStructMethod(structMapping);
1353 void WriteLiteralStructMethod(StructMapping structMapping) {
1354 string methodName = (string)MethodNames[structMapping];
1355 string typeName = structMapping.TypeDesc.CSharpName;
1356 ilg = new CodeGenerator(this.typeBuilder);
1357 List<Type> argTypes = new List<Type>();
1358 List<string> argNames = new List<string>();
1359 if (structMapping.TypeDesc.IsNullable) {
1360 argTypes.Add(typeof(Boolean));
1361 argNames.Add("isNullable");
1363 argTypes.Add(typeof(Boolean));
1364 argNames.Add("checkType");
1366 structMapping.TypeDesc.Type,
1367 GetMethodBuilder(methodName),
1370 CodeGenerator.PrivateMethodAttributes);
1372 LocalBuilder locXsiType = ilg.DeclareLocal(typeof(XmlQualifiedName), "xsiType");
1373 LocalBuilder locIsNull = ilg.DeclareLocal(typeof(Boolean), "isNull");
1374 MethodInfo XmlSerializationReader_GetXsiType = typeof(XmlSerializationReader).GetMethod(
1376 CodeGenerator.InstanceBindingFlags,
1378 CodeGenerator.EmptyTypeArray,
1381 MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
1383 CodeGenerator.InstanceBindingFlags,
1385 CodeGenerator.EmptyTypeArray,
1388 Label labelTrue = ilg.DefineLabel();
1389 Label labelEnd = ilg.DefineLabel();
1390 ilg.Ldarg("checkType");
1391 ilg.Brtrue(labelTrue);
1394 ilg.MarkLabel(labelTrue);
1396 ilg.Call(XmlSerializationReader_GetXsiType);
1397 ilg.MarkLabel(labelEnd);
1398 ilg.Stloc(locXsiType);
1400 ilg.Stloc(locIsNull);
1401 if (structMapping.TypeDesc.IsNullable) {
1402 ilg.Ldarg("isNullable");
1406 ilg.Call(XmlSerializationReader_ReadNull);
1407 ilg.Stloc(locIsNull);
1412 ilg.Ldarg("checkType");
1413 ilg.If(); // if (checkType)
1414 if (structMapping.TypeDesc.IsRoot) {
1415 ilg.Ldloc(locIsNull);
1417 ilg.Ldloc(locXsiType);
1419 ilg.If(Cmp.NotEqualTo);
1420 MethodInfo XmlSerializationReader_ReadTypedNull = typeof(XmlSerializationReader).GetMethod(
1422 CodeGenerator.InstanceBindingFlags,
1424 new Type[] { locXsiType.LocalType },
1428 ilg.Ldloc(locXsiType);
1429 ilg.Call(XmlSerializationReader_ReadTypedNull);
1430 ilg.Stloc(ilg.ReturnLocal);
1431 ilg.Br(ilg.ReturnLabel);
1433 if (structMapping.TypeDesc.IsValueType) {
1434 throw CodeGenerator.NotSupported("Arg_NeverValueType");
1438 ilg.Stloc(ilg.ReturnLocal);
1439 ilg.Br(ilg.ReturnLabel);
1441 ilg.EndIf(); // if (xsiType != null)
1443 ilg.EndIf(); // if (isNull)
1445 ilg.Ldloc(typeof(XmlQualifiedName), "xsiType");
1448 if (!structMapping.TypeDesc.IsRoot) {
1449 labelTrue = ilg.DefineLabel();
1450 labelEnd = ilg.DefineLabel();
1452 ilg.Brtrue(labelTrue);
1453 WriteQNameEqual("xsiType", structMapping.TypeName, structMapping.Namespace);
1454 // Bool result for WriteQNameEqual is on the stack
1456 ilg.MarkLabel(labelTrue);
1458 ilg.MarkLabel(labelEnd);
1460 ilg.If(); // if (xsiType == null
1461 if (structMapping.TypeDesc.IsRoot) {
1462 ConstructorInfo XmlQualifiedName_ctor = typeof(XmlQualifiedName).GetConstructor(
1463 CodeGenerator.InstanceBindingFlags,
1465 new Type[] { typeof(String), typeof(String) },
1468 MethodInfo XmlSerializationReader_ReadTypedPrimitive = typeof(XmlSerializationReader).GetMethod(
1469 "ReadTypedPrimitive",
1470 CodeGenerator.InstanceBindingFlags,
1472 new Type[] { typeof(XmlQualifiedName) },
1476 ilg.Ldstr(Soap.UrType);
1477 ilg.Ldstr(XmlSchema.Namespace);
1478 ilg.New(XmlQualifiedName_ctor);
1479 ilg.Call(XmlSerializationReader_ReadTypedPrimitive);
1480 ilg.Stloc(ilg.ReturnLocal);
1481 ilg.Br(ilg.ReturnLabel);
1483 WriteDerivedTypes(structMapping, !structMapping.TypeDesc.IsRoot, typeName);
1484 if (structMapping.TypeDesc.IsRoot) WriteEnumAndArrayTypes();
1485 ilg.Else(); // if (xsiType == null
1486 if (structMapping.TypeDesc.IsRoot) {
1487 MethodInfo XmlSerializationReader_ReadTypedPrimitive = typeof(XmlSerializationReader).GetMethod(
1488 "ReadTypedPrimitive",
1489 CodeGenerator.InstanceBindingFlags,
1491 new Type[] { locXsiType.LocalType },
1495 ilg.Ldloc(locXsiType);
1496 ilg.Call(XmlSerializationReader_ReadTypedPrimitive);
1497 ilg.Stloc(ilg.ReturnLocal);
1498 ilg.Br(ilg.ReturnLabel);
1501 MethodInfo XmlSerializationReader_CreateUnknownTypeException = typeof(XmlSerializationReader).GetMethod(
1502 "CreateUnknownTypeException",
1503 CodeGenerator.InstanceBindingFlags,
1505 new Type[] { typeof(XmlQualifiedName) },
1509 ilg.Ldloc(locXsiType);
1510 ilg.Call(XmlSerializationReader_CreateUnknownTypeException);
1513 ilg.EndIf(); // if (xsiType == null
1514 ilg.EndIf(); // checkType
1516 if (structMapping.TypeDesc.IsNullable) {
1517 ilg.Ldloc(typeof(bool), "isNull");
1521 ilg.Stloc(ilg.ReturnLocal);
1522 ilg.Br(ilg.ReturnLabel);
1527 if (structMapping.TypeDesc.IsAbstract) {
1528 MethodInfo XmlSerializationReader_CreateAbstractTypeException = typeof(XmlSerializationReader).GetMethod(
1529 "CreateAbstractTypeException",
1530 CodeGenerator.InstanceBindingFlags,
1532 new Type[] { typeof(String), typeof(String) },
1536 ilg.Ldstr(structMapping.TypeName);
1537 ilg.Ldstr(structMapping.Namespace);
1538 ilg.Call(XmlSerializationReader_CreateAbstractTypeException);
1542 if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type)) {
1543 MethodInfo XmlSerializationReader_set_DecodeName = typeof(XmlSerializationReader).GetMethod(
1545 CodeGenerator.InstanceBindingFlags,
1547 new Type[] { typeof(Boolean) },
1552 ilg.Call(XmlSerializationReader_set_DecodeName);
1554 WriteCreateMapping(structMapping, "o");
1555 LocalBuilder oLoc = ilg.GetLocal("o");
1557 // this method populates the memberInfos dictionary based on the structMapping
1558 MemberMapping[] mappings = TypeScope.GetSettableMembers(structMapping, memberInfos);
1560 Member anyText = null;
1561 Member anyElement = null;
1562 Member anyAttribute = null;
1563 bool isSequence = structMapping.HasExplicitSequence();
1565 ArrayList arraysToDeclareList = new ArrayList(mappings.Length);
1566 ArrayList arraysToSetList = new ArrayList(mappings.Length);
1567 ArrayList allMembersList = new ArrayList(mappings.Length);
1569 for (int i = 0; i < mappings.Length; i++) {
1570 MemberMapping mapping = mappings[i];
1571 CodeIdentifier.CheckValidIdentifier(mapping.Name);
1572 string source = RaCodeGen.GetStringForMember("o", mapping.Name, structMapping.TypeDesc);
1573 Member member = new Member(this, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
1574 if (!mapping.IsSequence)
1575 member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
1576 member.IsNullable = mapping.TypeDesc.IsNullable;
1577 if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite)
1578 member.CheckSpecifiedSource = RaCodeGen.GetStringForMember("o", mapping.Name + "Specified", structMapping.TypeDesc);
1579 if (mapping.Text != null)
1581 if (mapping.Attribute != null && mapping.Attribute.Any)
1582 anyAttribute = member;
1584 // find anyElement if present.
1585 for (int j = 0; j < mapping.Elements.Length; j++) {
1586 if (mapping.Elements[j].Any && (mapping.Elements[j].Name == null || mapping.Elements[j].Name.Length == 0)) {
1587 anyElement = member;
1592 else if (mapping.IsParticle && !mapping.IsSequence) {
1593 StructMapping declaringMapping;
1594 structMapping.FindDeclaringMapping(mapping, out declaringMapping, structMapping.TypeName);
1595 throw new InvalidOperationException(Res.GetString(Res.XmlSequenceHierarchy, structMapping.TypeDesc.FullName, mapping.Name, declaringMapping.TypeDesc.FullName, "Order"));
1597 if (mapping.Attribute == null && mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping) {
1598 Member arrayMember = new Member(this, source, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
1599 arrayMember.CheckSpecifiedSource = member.CheckSpecifiedSource;
1600 allMembersList.Add(arrayMember);
1603 allMembersList.Add(member);
1606 if (mapping.TypeDesc.IsArrayLike) {
1607 arraysToDeclareList.Add(member);
1608 if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) {
1609 member.ParamsReadSource = null; // flat arrays -- don't want to count params read.
1610 if (member != anyText && member != anyElement) {
1611 arraysToSetList.Add(member);
1614 else if (!mapping.TypeDesc.IsArray) {
1615 member.ParamsReadSource = null; // collection
1619 if (anyElement != null) arraysToSetList.Add(anyElement);
1620 if (anyText != null && anyText != anyElement) arraysToSetList.Add(anyText);
1622 Member[] arraysToDeclare = (Member[])arraysToDeclareList.ToArray(typeof(Member));
1623 Member[] arraysToSet = (Member[])arraysToSetList.ToArray(typeof(Member));
1624 Member[] allMembers = (Member[])allMembersList.ToArray(typeof(Member));
1626 WriteMemberBegin(arraysToDeclare);
1627 WriteParamsRead(mappings.Length);
1629 WriteAttributes(allMembers, anyAttribute, "UnknownNode", oLoc);
1630 if (anyAttribute != null)
1631 WriteMemberEnd(arraysToDeclare);
1633 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
1635 CodeGenerator.InstanceBindingFlags,
1637 CodeGenerator.EmptyTypeArray,
1640 MethodInfo XmlReader_MoveToElement = typeof(XmlReader).GetMethod(
1642 CodeGenerator.InstanceBindingFlags,
1644 CodeGenerator.EmptyTypeArray,
1648 ilg.Call(XmlSerializationReader_get_Reader);
1649 ilg.Call(XmlReader_MoveToElement);
1652 MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
1653 "get_IsEmptyElement",
1654 CodeGenerator.InstanceBindingFlags,
1656 CodeGenerator.EmptyTypeArray,
1660 ilg.Call(XmlSerializationReader_get_Reader);
1661 ilg.Call(XmlReader_get_IsEmptyElement);
1663 MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
1665 CodeGenerator.InstanceBindingFlags,
1667 CodeGenerator.EmptyTypeArray,
1671 ilg.Call(XmlSerializationReader_get_Reader);
1672 ilg.Call(XmlReader_Skip);
1673 WriteMemberEnd(arraysToSet);
1675 ilg.Stloc(ilg.ReturnLocal);
1676 ilg.Br(ilg.ReturnLabel);
1679 MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
1681 CodeGenerator.InstanceBindingFlags,
1683 CodeGenerator.EmptyTypeArray,
1687 ilg.Call(XmlSerializationReader_get_Reader);
1688 ilg.Call(XmlReader_ReadStartElement);
1689 if (IsSequence(allMembers)) {
1691 ilg.Stloc(typeof(Int32), "state");
1693 int loopIndex = WriteWhileNotLoopStart();
1694 string unknownNode = "UnknownNode((object)o, " + ExpectedElements(allMembers) + ");";
1695 WriteMemberElements(allMembers, unknownNode, unknownNode, anyElement, anyText);
1696 MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
1698 CodeGenerator.InstanceBindingFlags,
1700 CodeGenerator.EmptyTypeArray,
1704 ilg.Call(XmlSerializationReader_get_Reader);
1705 ilg.Call(XmlReader_MoveToContent);
1708 WriteWhileLoopEnd(loopIndex);
1709 WriteMemberEnd(arraysToSet);
1711 MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
1713 CodeGenerator.InstanceBindingFlags,
1715 CodeGenerator.EmptyTypeArray,
1719 ilg.Call(XmlSerializationReader_ReadEndElement);
1720 ilg.Ldloc(structMapping.TypeDesc.Type, "o");
1721 ilg.Stloc(ilg.ReturnLocal);
1723 ilg.MarkLabel(ilg.ReturnLabel);
1724 ilg.Ldloc(ilg.ReturnLocal);
1728 void WriteQNameEqual(string source, string name, string ns) {
1731 // This api assume the source is local member of XmlQualifiedName type
1732 // It leaves bool result on the stack
1733 MethodInfo XmlQualifiedName_get_Name = typeof(XmlQualifiedName).GetMethod(
1735 CodeGenerator.InstanceBindingFlags,
1737 CodeGenerator.EmptyTypeArray,
1740 MethodInfo XmlQualifiedName_get_Namespace = typeof(XmlQualifiedName).GetMethod(
1742 CodeGenerator.InstanceBindingFlags,
1744 CodeGenerator.EmptyTypeArray,
1747 Label labelEnd = ilg.DefineLabel();
1748 Label labelFalse = ilg.DefineLabel();
1749 LocalBuilder sLoc = ilg.GetLocal(source);
1751 ilg.Call(XmlQualifiedName_get_Name);
1753 ilg.LoadMember(idNameFields[name ?? String.Empty]);
1754 ilg.Bne(labelFalse);
1756 ilg.Call(XmlQualifiedName_get_Namespace);
1758 ilg.LoadMember(idNameFields[ns ?? String.Empty]);
1761 ilg.MarkLabel(labelFalse);
1763 ilg.MarkLabel(labelEnd);
1766 void WriteXmlNodeEqual(string source, string name, string ns) {
1767 WriteXmlNodeEqual(source, name, ns, true);
1769 void WriteXmlNodeEqual(string source, string name, string ns, bool doAndIf) {
1770 bool isNameNullOrEmpty = string.IsNullOrEmpty(name);
1771 if (!isNameNullOrEmpty) {
1775 // Only support Reader and XmlSerializationReaderReader only
1776 System.Diagnostics.Debug.Assert(source == "Reader");
1777 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
1779 CodeGenerator.InstanceBindingFlags,
1781 CodeGenerator.EmptyTypeArray,
1784 MethodInfo XmlReader_get_LocalName = typeof(XmlReader).GetMethod(
1786 CodeGenerator.InstanceBindingFlags,
1788 CodeGenerator.EmptyTypeArray,
1791 MethodInfo XmlReader_get_NamespaceURI = typeof(XmlReader).GetMethod(
1793 CodeGenerator.InstanceBindingFlags,
1795 CodeGenerator.EmptyTypeArray,
1799 Label labelFalse = ilg.DefineLabel();
1800 Label labelEnd = ilg.DefineLabel();
1802 if (!isNameNullOrEmpty) {
1804 ilg.Call(XmlSerializationReader_get_Reader);
1805 ilg.Call(XmlReader_get_LocalName);
1807 ilg.LoadMember(idNameFields[name ?? String.Empty]);
1808 ilg.Bne(labelFalse);
1812 ilg.Call(XmlSerializationReader_get_Reader);
1813 ilg.Call(XmlReader_get_NamespaceURI);
1815 ilg.LoadMember(idNameFields[ns ?? String.Empty]);
1818 if (!isNameNullOrEmpty) {
1820 ilg.MarkLabel(labelFalse);
1822 ilg.MarkLabel(labelEnd);
1828 void WriteID(string name) {
1830 //Writer.Write("null");
1834 string idName = (string)idNames[name];
1835 if (idName == null) {
1836 idName = NextIdName(name);
1837 idNames.Add(name, idName);
1838 idNameFields.Add(name, this.typeBuilder.DefineField(idName, typeof(string), FieldAttributes.Private));
1842 void WriteAttributes(Member[] members, Member anyAttribute, string elseCall, LocalBuilder firstParam) {
1844 Member xmlnsMember = null;
1845 ArrayList attributes = new ArrayList();
1847 // Condition do at the end, so C# looks the same
1848 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
1850 CodeGenerator.InstanceBindingFlags,
1852 CodeGenerator.EmptyTypeArray,
1855 MethodInfo XmlReader_MoveToNextAttribute = typeof(XmlReader).GetMethod(
1856 "MoveToNextAttribute",
1857 CodeGenerator.InstanceBindingFlags,
1859 CodeGenerator.EmptyTypeArray,
1864 for (int i = 0; i < members.Length; i++) {
1865 Member member = (Member)members[i];
1866 if (member.Mapping.Xmlns != null) {
1867 xmlnsMember = member;
1870 if (member.Mapping.Ignore)
1872 AttributeAccessor attribute = member.Mapping.Attribute;
1874 if (attribute == null) continue;
1875 if (attribute.Any) continue;
1877 attributes.Add(attribute);
1884 if (member.ParamsReadSource != null) {
1885 ILGenParamsReadSource(member.ParamsReadSource);
1887 ilg.AndIf(Cmp.EqualTo);
1890 if (attribute.IsSpecialXmlNamespace) {
1891 WriteXmlNodeEqual("Reader", attribute.Name, XmlReservedNs.NsXml);
1894 WriteXmlNodeEqual("Reader", attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "");
1896 WriteAttribute(member);
1904 if (xmlnsMember != null) {
1905 MethodInfo XmlSerializationReader_IsXmlnsAttribute = typeof(XmlSerializationReader).GetMethod(
1907 CodeGenerator.InstanceBindingFlags,
1909 new Type[] { typeof(string) },
1912 MethodInfo XmlReader_get_Name = typeof(XmlReader).GetMethod(
1914 CodeGenerator.InstanceBindingFlags,
1916 CodeGenerator.EmptyTypeArray,
1919 MethodInfo XmlReader_get_LocalName = typeof(XmlReader).GetMethod(
1921 CodeGenerator.InstanceBindingFlags,
1923 CodeGenerator.EmptyTypeArray,
1926 MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
1928 CodeGenerator.InstanceBindingFlags,
1930 CodeGenerator.EmptyTypeArray,
1935 ilg.Call(XmlSerializationReader_get_Reader);
1936 ilg.Call(XmlReader_get_Name);
1937 ilg.Call(XmlSerializationReader_IsXmlnsAttribute);
1939 ilg.AndIf(Cmp.EqualTo);
1941 ILGenLoad(xmlnsMember.Source);
1943 ilg.If(Cmp.EqualTo);
1944 WriteSourceBegin(xmlnsMember.Source);
1945 ConstructorInfo ctor = xmlnsMember.Mapping.TypeDesc.Type.GetConstructor(
1946 CodeGenerator.InstanceBindingFlags,
1948 CodeGenerator.EmptyTypeArray,
1952 WriteSourceEnd(xmlnsMember.Source, xmlnsMember.Mapping.TypeDesc.Type);
1953 ilg.EndIf(); // if (xmlnsMember.Source == null
1955 Label labelEqual5 = ilg.DefineLabel();
1956 Label labelEndLength = ilg.DefineLabel();
1957 MethodInfo Add = xmlnsMember.Mapping.TypeDesc.Type.GetMethod(
1959 CodeGenerator.InstanceBindingFlags,
1961 new Type[] { typeof(String), typeof(String) },
1964 MethodInfo String_get_Length = typeof(String).GetMethod(
1966 CodeGenerator.InstanceBindingFlags,
1968 CodeGenerator.EmptyTypeArray,
1971 ILGenLoad(xmlnsMember.ArraySource, xmlnsMember.Mapping.TypeDesc.Type);
1973 ilg.Call(XmlSerializationReader_get_Reader);
1974 ilg.Call(XmlReader_get_Name);
1975 ilg.Call(String_get_Length);
1977 ilg.Beq(labelEqual5);
1979 ilg.Call(XmlSerializationReader_get_Reader);
1980 ilg.Call(XmlReader_get_LocalName);
1981 ilg.Br(labelEndLength);
1982 ilg.MarkLabel(labelEqual5);
1983 ilg.Ldstr(String.Empty);
1984 ilg.MarkLabel(labelEndLength);
1986 ilg.Call(XmlSerializationReader_get_Reader);
1987 ilg.Call(XmlReader_get_Value);
1993 MethodInfo XmlSerializationReader_IsXmlnsAttribute = typeof(XmlSerializationReader).GetMethod(
1995 CodeGenerator.InstanceBindingFlags,
1997 new Type[] { typeof(string) },
2000 MethodInfo XmlReader_get_Name = typeof(XmlReader).GetMethod(
2002 CodeGenerator.InstanceBindingFlags,
2004 CodeGenerator.EmptyTypeArray,
2009 ilg.Call(XmlSerializationReader_get_Reader);
2010 ilg.Call(XmlReader_get_Name);
2011 ilg.Call(XmlSerializationReader_IsXmlnsAttribute);
2013 ilg.AndIf(Cmp.EqualTo);
2015 if (anyAttribute != null) {
2016 LocalBuilder localAttr = ilg.DeclareOrGetLocal(typeof(XmlAttribute), "attr");
2017 MethodInfo XmlSerializationReader_get_Document = typeof(XmlSerializationReader).GetMethod(
2019 CodeGenerator.InstanceBindingFlags,
2021 CodeGenerator.EmptyTypeArray,
2024 MethodInfo XmlDocument_ReadNode = typeof(XmlDocument).GetMethod(
2026 CodeGenerator.InstanceBindingFlags,
2028 new Type[] { typeof(XmlReader) },
2032 ilg.Call(XmlSerializationReader_get_Document);
2034 ilg.Call(XmlSerializationReader_get_Reader);
2035 ilg.Call(XmlDocument_ReadNode);
2036 ilg.ConvertValue(XmlDocument_ReadNode.ReturnType, localAttr.LocalType);
2037 ilg.Stloc(localAttr);
2038 MethodInfo XmlSerializationReader_ParseWsdlArrayType = typeof(XmlSerializationReader).GetMethod(
2039 "ParseWsdlArrayType",
2040 CodeGenerator.InstanceBindingFlags,
2042 new Type[] { localAttr.LocalType },
2046 ilg.Ldloc(localAttr);
2047 ilg.Call(XmlSerializationReader_ParseWsdlArrayType);
2048 WriteAttribute(anyAttribute);
2051 List<Type> argTypes = new List<Type>();
2053 argTypes.Add(typeof(object));
2054 ilg.Ldloc(firstParam);
2055 ilg.ConvertValue(firstParam.LocalType, typeof(object));
2056 if (attributes.Count > 0) {
2059 for (int i = 0; i < attributes.Count; i++) {
2060 AttributeAccessor attribute = (AttributeAccessor)attributes[i];
2063 qnames += attribute.IsSpecialXmlNamespace ? XmlReservedNs.NsXml : (attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "") + ":" + attribute.Name;
2065 argTypes.Add(typeof(string));
2068 System.Diagnostics.Debug.Assert(elseCall == "UnknownNode");
2069 MethodInfo elseCallMethod = typeof(XmlSerializationReader).GetMethod(
2071 CodeGenerator.InstanceBindingFlags,
2076 ilg.Call(elseCallMethod);
2080 ilg.WhileBeginCondition();
2083 ilg.Call(XmlSerializationReader_get_Reader);
2084 ilg.Call(XmlReader_MoveToNextAttribute);
2086 ilg.WhileEndCondition();
2090 void WriteAttribute(Member member) {
2092 AttributeAccessor attribute = member.Mapping.Attribute;
2094 if (attribute.Mapping is SpecialMapping) {
2095 SpecialMapping special = (SpecialMapping)attribute.Mapping;
2097 if (special.TypeDesc.Kind == TypeKind.Attribute) {
2098 WriteSourceBegin(member.ArraySource);
2100 WriteSourceEnd(member.ArraySource, member.Mapping.TypeDesc.IsArrayLike ? member.Mapping.TypeDesc.ArrayElementTypeDesc.Type : member.Mapping.TypeDesc.Type);
2102 else if (special.TypeDesc.CanBeAttributeValue) {
2103 LocalBuilder attrLoc = ilg.GetLocal("attr");
2105 // to get code compat
2106 if (attrLoc.LocalType == typeof(XmlAttribute)) {
2111 ilg.IsInst(typeof(XmlAttribute));
2113 WriteSourceBegin(member.ArraySource);
2115 ilg.ConvertValue(attrLoc.LocalType, typeof(XmlAttribute));
2116 WriteSourceEnd(member.ArraySource, member.Mapping.TypeDesc.IsArrayLike ? member.Mapping.TypeDesc.ArrayElementTypeDesc.Type : member.Mapping.TypeDesc.Type);
2120 throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
2123 if (attribute.IsList) {
2124 LocalBuilder locListValues = ilg.DeclareOrGetLocal(typeof(string), "listValues");
2125 LocalBuilder locVals = ilg.DeclareOrGetLocal(typeof(string[]), "vals");
2126 MethodInfo String_Split = typeof(String).GetMethod(
2128 CodeGenerator.InstanceBindingFlags,
2130 new Type[] { typeof(Char[]) },
2133 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
2135 CodeGenerator.InstanceBindingFlags,
2137 CodeGenerator.EmptyTypeArray,
2140 MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
2142 CodeGenerator.InstanceBindingFlags,
2144 CodeGenerator.EmptyTypeArray,
2148 ilg.Call(XmlSerializationReader_get_Reader);
2149 ilg.Call(XmlReader_get_Value);
2150 ilg.Stloc(locListValues);
2151 ilg.Ldloc(locListValues);
2153 ilg.Call(String_Split);
2155 LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), "i");
2156 ilg.For(localI, 0, locVals);
2158 string attributeSource = GetArraySource(member.Mapping.TypeDesc, member.ArrayName);
2160 WriteSourceBegin(attributeSource);
2161 WritePrimitive(attribute.Mapping, "vals[i]");
2162 WriteSourceEnd(attributeSource, member.Mapping.TypeDesc.ArrayElementTypeDesc.Type);
2166 WriteSourceBegin(member.ArraySource);
2167 WritePrimitive(attribute.Mapping, attribute.IsList ? "vals[i]" : "Reader.Value");
2168 WriteSourceEnd(member.ArraySource, member.Mapping.TypeDesc.IsArrayLike ? member.Mapping.TypeDesc.ArrayElementTypeDesc.Type : member.Mapping.TypeDesc.Type);
2171 if (member.Mapping.CheckSpecified == SpecifiedAccessor.ReadWrite && member.CheckSpecifiedSource != null && member.CheckSpecifiedSource.Length > 0) {
2172 ILGenSet(member.CheckSpecifiedSource, true);
2174 if (member.ParamsReadSource != null) {
2175 ILGenParamsReadSource(member.ParamsReadSource, true);
2179 void WriteMemberBegin(Member[] members) {
2181 for (int i = 0; i < members.Length; i++) {
2182 Member member = (Member)members[i];
2184 if (member.IsArrayLike) {
2185 string a = member.ArrayName;
2188 TypeDesc typeDesc = member.Mapping.TypeDesc;
2190 if (member.Mapping.TypeDesc.IsArray) {
2191 WriteArrayLocalDecl(typeDesc.CSharpName,
2192 a, "null", typeDesc);
2194 ilg.Stloc(typeof(int), c);
2196 if (member.Mapping.ChoiceIdentifier != null) {
2197 WriteArrayLocalDecl(member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.CSharpName + "[]",
2198 member.ChoiceArrayName, "null",
2199 member.Mapping.ChoiceIdentifier.Mapping.TypeDesc);
2201 ilg.Stloc(typeof(int), "c" + member.ChoiceArrayName);
2206 if (member.Source[member.Source.Length - 1] == '(' || member.Source[member.Source.Length - 1] == '{') {
2207 WriteCreateInstance(a, typeDesc.CannotNew, typeDesc.Type);
2208 WriteSourceBegin(member.Source);
2209 ilg.Ldloc(ilg.GetLocal(a));
2210 WriteSourceEnd(member.Source, typeDesc.Type);
2213 if (member.IsList && !member.Mapping.ReadOnly && member.Mapping.TypeDesc.IsNullable) {
2214 // we need to new the Collections and ArrayLists
2215 ILGenLoad(member.Source, typeof(object));
2217 ilg.If(Cmp.EqualTo);
2218 if (!member.Mapping.TypeDesc.HasDefaultConstructor) {
2219 MethodInfo XmlSerializationReader_CreateReadOnlyCollectionException = typeof(XmlSerializationReader).GetMethod(
2220 "CreateReadOnlyCollectionException",
2221 CodeGenerator.InstanceBindingFlags,
2223 new Type[] { typeof(String) },
2227 ilg.Ldstr(member.Mapping.TypeDesc.CSharpName);
2228 ilg.Call(XmlSerializationReader_CreateReadOnlyCollectionException);
2232 WriteSourceBegin(member.Source);
2233 RaCodeGen.ILGenForCreateInstance(ilg, member.Mapping.TypeDesc.Type, typeDesc.CannotNew, true);
2234 WriteSourceEnd(member.Source, member.Mapping.TypeDesc.Type);
2236 ilg.EndIf(); // if ((object)(member.Source) == null
2238 WriteLocalDecl(a, new SourceInfo(member.Source, member.Source, member.Mapping.MemberInfo, member.Mapping.TypeDesc.Type, ilg));
2245 string ExpectedElements(Member[] members) {
2246 if (IsSequence(members))
2248 string qnames = string.Empty;
2249 bool firstElement = true;
2250 for (int i = 0; i < members.Length; i++) {
2251 Member member = (Member)members[i];
2252 if (member.Mapping.Xmlns != null)
2254 if (member.Mapping.Ignore)
2256 if (member.Mapping.IsText || member.Mapping.IsAttribute)
2259 ElementAccessor[] elements = member.Mapping.Elements;
2261 for (int j = 0; j < elements.Length; j++) {
2262 ElementAccessor e = elements[j];
2263 string ns = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
2264 if (e.Any && (e.Name == null || e.Name.Length == 0)) continue;
2268 qnames += ns + ":" + e.Name;
2269 firstElement = false;
2272 return ReflectionAwareILGen.GetQuotedCSharpString(null, qnames);
2275 void WriteMemberElements(Member[] members, string elementElseString, string elseString, Member anyElement, Member anyText) {
2276 if (anyText != null) {
2278 ilg.Stloc(typeof(string), "tmp");
2281 MethodInfo XmlReader_get_NodeType = typeof(XmlReader).GetMethod(
2283 CodeGenerator.InstanceBindingFlags,
2285 CodeGenerator.EmptyTypeArray,
2288 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
2290 CodeGenerator.InstanceBindingFlags,
2292 CodeGenerator.EmptyTypeArray,
2295 int XmlNodeType_Element = 1;
2297 ilg.Call(XmlSerializationReader_get_Reader);
2298 ilg.Call(XmlReader_get_NodeType);
2299 ilg.Ldc(XmlNodeType_Element);
2300 ilg.If(Cmp.EqualTo);
2302 WriteMemberElementsIf(members, anyElement, elementElseString);
2304 if (anyText != null)
2305 WriteMemberText(anyText, elseString);
2308 ILGenElseString(elseString);
2312 void WriteMemberText(Member anyText, string elseString) {
2314 Label labelTrue = ilg.DefineLabel();
2315 Label labelEnd = ilg.DefineLabel();
2316 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
2318 CodeGenerator.InstanceBindingFlags,
2320 CodeGenerator.EmptyTypeArray,
2323 MethodInfo XmlReader_get_NodeType = typeof(XmlReader).GetMethod(
2325 CodeGenerator.InstanceBindingFlags,
2327 CodeGenerator.EmptyTypeArray,
2331 ilg.Call(XmlSerializationReader_get_Reader);
2332 ilg.Call(XmlReader_get_NodeType);
2333 ilg.Ldc(XmlNodeType.Text);
2335 ilg.Brtrue(labelTrue);
2337 ilg.Call(XmlSerializationReader_get_Reader);
2338 ilg.Call(XmlReader_get_NodeType);
2339 ilg.Ldc(XmlNodeType.CDATA);
2341 ilg.Brtrue(labelTrue);
2343 ilg.Call(XmlSerializationReader_get_Reader);
2344 ilg.Call(XmlReader_get_NodeType);
2345 ilg.Ldc(XmlNodeType.Whitespace);
2347 ilg.Brtrue(labelTrue);
2349 ilg.Call(XmlSerializationReader_get_Reader);
2350 ilg.Call(XmlReader_get_NodeType);
2351 ilg.Ldc(XmlNodeType.SignificantWhitespace);
2354 ilg.MarkLabel(labelTrue);
2356 ilg.MarkLabel(labelEnd);
2359 if (anyText != null) {
2362 Debug.Assert(anyText != null);
2365 void WriteText(Member member) {
2367 TextAccessor text = member.Mapping.Text;
2369 if (text.Mapping is SpecialMapping) {
2370 SpecialMapping special = (SpecialMapping)text.Mapping;
2371 WriteSourceBeginTyped(member.ArraySource, special.TypeDesc);
2372 switch (special.TypeDesc.Kind) {
2374 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
2376 CodeGenerator.InstanceBindingFlags,
2378 CodeGenerator.EmptyTypeArray,
2381 MethodInfo XmlReader_ReadString = typeof(XmlReader).GetMethod(
2383 CodeGenerator.InstanceBindingFlags,
2385 CodeGenerator.EmptyTypeArray,
2388 MethodInfo XmlSerializationReader_get_Document = typeof(XmlSerializationReader).GetMethod(
2390 CodeGenerator.InstanceBindingFlags,
2392 CodeGenerator.EmptyTypeArray,
2395 MethodInfo XmlDocument_CreateTextNode = typeof(XmlDocument).GetMethod(
2397 CodeGenerator.InstanceBindingFlags,
2399 new Type[] { typeof(String) },
2403 ilg.Call(XmlSerializationReader_get_Document);
2405 ilg.Call(XmlSerializationReader_get_Reader);
2406 ilg.Call(XmlReader_ReadString);
2407 ilg.Call(XmlDocument_CreateTextNode);
2410 throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
2412 WriteSourceEnd(member.ArraySource, special.TypeDesc.Type);
2415 if (member.IsArrayLike) {
2416 WriteSourceBegin(member.ArraySource);
2417 if (text.Mapping.TypeDesc.CollapseWhitespace) {
2418 ilg.Ldarg(0); // for calling CollapseWhitespace
2422 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
2424 CodeGenerator.InstanceBindingFlags,
2426 CodeGenerator.EmptyTypeArray,
2429 MethodInfo XmlReader_ReadString = typeof(XmlReader).GetMethod(
2431 CodeGenerator.InstanceBindingFlags,
2433 CodeGenerator.EmptyTypeArray,
2437 ilg.Call(XmlSerializationReader_get_Reader);
2438 ilg.Call(XmlReader_ReadString);
2439 if (text.Mapping.TypeDesc.CollapseWhitespace) {
2440 MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod(
2441 "CollapseWhitespace",
2442 CodeGenerator.InstanceBindingFlags,
2444 new Type[] { typeof(String) },
2447 ilg.Call(XmlSerializationReader_CollapseWhitespace);
2451 if (text.Mapping.TypeDesc == StringTypeDesc || text.Mapping.TypeDesc.FormatterName == "String") {
2452 LocalBuilder tmpLoc = ilg.GetLocal("tmp");
2453 MethodInfo XmlSerializationReader_ReadString = typeof(XmlSerializationReader).GetMethod(
2455 CodeGenerator.InstanceBindingFlags,
2457 new Type[] { typeof(String), typeof(Boolean) },
2462 ilg.Ldc(text.Mapping.TypeDesc.CollapseWhitespace);
2463 ilg.Call(XmlSerializationReader_ReadString);
2466 WriteSourceBegin(member.ArraySource);
2470 WriteSourceBegin(member.ArraySource);
2471 WritePrimitive(text.Mapping, "Reader.ReadString()");
2474 WriteSourceEnd(member.ArraySource, text.Mapping.TypeDesc.Type);
2480 void WriteMemberElementsElse(Member anyElement, string elementElseString) {
2481 if (anyElement != null) {
2482 ElementAccessor[] elements = anyElement.Mapping.Elements;
2483 for (int i = 0; i < elements.Length; i++) {
2484 ElementAccessor element = elements[i];
2485 if (element.Any && element.Name.Length == 0) {
2486 WriteElement(anyElement.ArraySource, anyElement.ArrayName, anyElement.ChoiceArraySource, element, anyElement.Mapping.ChoiceIdentifier, anyElement.Mapping.CheckSpecified == SpecifiedAccessor.ReadWrite ? anyElement.CheckSpecifiedSource : null, false, false, -1, i);
2492 ILGenElementElseString(elementElseString);
2496 bool IsSequence(Member[] members) {
2497 for (int i = 0; i < members.Length; i++) {
2498 if (members[i].Mapping.IsParticle && members[i].Mapping.IsSequence)
2503 void WriteMemberElementsIf(Member[] members, Member anyElement, string elementElseString) {
2506 bool isSequence = IsSequence(members);
2509 for (int i = 0; i < members.Length; i++) {
2510 Member member = (Member)members[i];
2511 if (member.Mapping.Xmlns != null)
2513 if (member.Mapping.Ignore)
2515 if (isSequence && (member.Mapping.IsText || member.Mapping.IsAttribute))
2518 bool firstElement = true;
2519 ChoiceIdentifierAccessor choice = member.Mapping.ChoiceIdentifier;
2520 ElementAccessor[] elements = member.Mapping.Elements;
2522 for (int j = 0; j < elements.Length; j++) {
2523 ElementAccessor e = elements[j];
2524 string ns = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
2525 if (!isSequence && e.Any && (e.Name == null || e.Name.Length == 0)) continue;
2526 if (!firstElement || (!isSequence && count > 0)) {
2529 else if (isSequence) {
2536 ilg.AndIf(Cmp.EqualTo);
2543 firstElement = false;
2544 if (member.ParamsReadSource != null) {
2545 ILGenParamsReadSource(member.ParamsReadSource);
2547 ilg.AndIf(Cmp.EqualTo);
2549 Label labelTrue = ilg.DefineLabel();
2550 Label labelEnd = ilg.DefineLabel();
2551 if (member.Mapping.IsReturnValue) {
2552 MethodInfo XmlSerializationReader_get_IsReturnValue = typeof(XmlSerializationReader).GetMethod(
2553 "get_IsReturnValue",
2554 CodeGenerator.InstanceBindingFlags,
2556 CodeGenerator.EmptyTypeArray,
2560 ilg.Call(XmlSerializationReader_get_IsReturnValue);
2561 ilg.Brtrue(labelTrue);
2563 if (isSequence && e.Any && e.AnyNamespaces == null) {
2567 WriteXmlNodeEqual("Reader", e.Name, ns, false);
2569 if (member.Mapping.IsReturnValue) {
2571 ilg.MarkLabel(labelTrue);
2573 ilg.MarkLabel(labelEnd);
2577 WriteElement(member.ArraySource, member.ArrayName, member.ChoiceArraySource, e, choice, member.Mapping.CheckSpecified == SpecifiedAccessor.ReadWrite ? member.CheckSpecifiedSource : null, member.IsList && member.Mapping.TypeDesc.IsNullable, member.Mapping.ReadOnly, member.FixupIndex, j);
2578 if (member.Mapping.IsReturnValue) {
2579 MethodInfo XmlSerializationReader_set_IsReturnValue = typeof(XmlSerializationReader).GetMethod(
2580 "set_IsReturnValue",
2581 CodeGenerator.InstanceBindingFlags,
2583 new Type[] { typeof(Boolean) },
2588 ilg.Call(XmlSerializationReader_set_IsReturnValue);
2590 if (member.ParamsReadSource != null) {
2591 ILGenParamsReadSource(member.ParamsReadSource, true);
2595 if (member.IsArrayLike) {
2603 ilg.Stloc(ilg.GetLocal("state"));
2604 if (member.IsArrayLike) {
2612 WriteMemberElementsElse(anyElement, elementElseString);
2618 string GetArraySource(TypeDesc typeDesc, string arrayName) {
2619 return GetArraySource(typeDesc, arrayName, false);
2621 string GetArraySource(TypeDesc typeDesc, string arrayName, bool multiRef) {
2622 string a = arrayName;
2627 init = "soap = (System.Object[])EnsureArrayIndex(soap, " + c + "+2, typeof(System.Object)); ";
2629 if (typeDesc.IsArray) {
2630 string arrayTypeFullName = typeDesc.ArrayElementTypeDesc.CSharpName;
2631 string castString = "(" + arrayTypeFullName + "[])";
2632 init = init + a + " = " + castString +
2633 "EnsureArrayIndex(" + a + ", " + c + ", " + RaCodeGen.GetStringForTypeof(arrayTypeFullName) + ");";
2634 string arraySource = RaCodeGen.GetStringForArrayMember(a, c + "++", typeDesc);
2636 init = init + " soap[1] = " + a + ";";
2637 init = init + " if (ReadReference(out soap[" + c + "+2])) " + arraySource + " = null; else ";
2639 return init + arraySource;
2642 return RaCodeGen.GetStringForMethod(arrayName, typeDesc.CSharpName, "Add");
2648 void WriteMemberEnd(Member[] members) {
2649 WriteMemberEnd(members, false);
2652 void WriteMemberEnd(Member[] members, bool soapRefs) {
2653 for (int i = 0; i < members.Length; i++) {
2654 Member member = (Member)members[i];
2656 if (member.IsArrayLike) {
2658 TypeDesc typeDesc = member.Mapping.TypeDesc;
2660 if (typeDesc.IsArray) {
2662 WriteSourceBegin(member.Source);
2664 Debug.Assert(!soapRefs);
2666 string a = member.ArrayName;
2669 MethodInfo XmlSerializationReader_ShrinkArray = typeof(XmlSerializationReader).GetMethod(
2671 CodeGenerator.InstanceBindingFlags,
2673 new Type[] { typeof(Array), typeof(Int32), typeof(Type), typeof(Boolean) },
2677 ilg.Ldloc(ilg.GetLocal(a));
2678 ilg.Ldloc(ilg.GetLocal(c));
2679 ilg.Ldc(typeDesc.ArrayElementTypeDesc.Type);
2680 ilg.Ldc(member.IsNullable);
2681 ilg.Call(XmlSerializationReader_ShrinkArray);
2682 ilg.ConvertValue(XmlSerializationReader_ShrinkArray.ReturnType, typeDesc.Type);
2683 WriteSourceEnd(member.Source, typeDesc.Type);
2685 if (member.Mapping.ChoiceIdentifier != null) {
2686 WriteSourceBegin(member.ChoiceSource);
2687 a = member.ChoiceArrayName;
2691 ilg.Ldloc(ilg.GetLocal(a));
2692 ilg.Ldloc(ilg.GetLocal(c));
2693 ilg.Ldc(member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.Type);
2694 ilg.Ldc(member.IsNullable);
2695 ilg.Call(XmlSerializationReader_ShrinkArray);
2696 ilg.ConvertValue(XmlSerializationReader_ShrinkArray.ReturnType, member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.Type.MakeArrayType());
2697 WriteSourceEnd(member.ChoiceSource, member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.Type.MakeArrayType());
2701 else if (typeDesc.IsValueType) {
2702 LocalBuilder arrayLoc = ilg.GetLocal(member.ArrayName);
2703 WriteSourceBegin(member.Source);
2704 ilg.Ldloc(arrayLoc);
2705 WriteSourceEnd(member.Source, arrayLoc.LocalType);
2711 void WriteSourceBeginTyped(string source, TypeDesc typeDesc) {
2712 WriteSourceBegin(source);
2715 void WriteSourceBegin(string source) {
2717 if (ilg.TryGetVariable(source, out variable)) {
2718 Type varType = ilg.GetVariableType(variable);
2719 if (CodeGenerator.IsNullableGenericType(varType)) {
2720 // local address to invoke ctor on WriteSourceEnd
2721 ilg.LoadAddress(variable);
2726 if (source.StartsWith("o.@", StringComparison.Ordinal)) {
2727 ilg.LdlocAddress(ilg.GetLocal("o"));
2730 // a_0_0 = (global::System.Object[])EnsureArrayIndex(a_0_0, ca_0_0, typeof(global::System.Object));a_0_0[ca_0_0++]
2731 Regex regex = NewRegex("(?<locA1>[^ ]+) = .+EnsureArrayIndex[(](?<locA2>[^,]+), (?<locI1>[^,]+),[^;]+;(?<locA3>[^[]+)[[](?<locI2>[^+]+)[+][+][]]");
2732 Match match = regex.Match(source);
2733 if (match.Success) {
2734 Debug.Assert(match.Groups["locA1"].Value == match.Groups["locA2"].Value);
2735 Debug.Assert(match.Groups["locA1"].Value == match.Groups["locA3"].Value);
2736 Debug.Assert(match.Groups["locI1"].Value == match.Groups["locI2"].Value);
2738 LocalBuilder localA = ilg.GetLocal(match.Groups["locA1"].Value);
2739 LocalBuilder localI = ilg.GetLocal(match.Groups["locI1"].Value);
2740 Type arrayElementType = localA.LocalType.GetElementType();
2741 MethodInfo XmlSerializationReader_EnsureArrayIndex = typeof(XmlSerializationReader).GetMethod(
2743 CodeGenerator.InstanceBindingFlags,
2745 new Type[] { typeof(Array), typeof(Int32), typeof(Type) },
2751 ilg.Ldc(arrayElementType);
2752 ilg.Call(XmlSerializationReader_EnsureArrayIndex);
2753 ilg.Castclass(localA.LocalType);
2763 if (CodeGenerator.IsNullableGenericType(arrayElementType) || arrayElementType.IsValueType) {
2764 ilg.Ldelema(arrayElementType);
2769 if (source.EndsWith(".Add(", StringComparison.Ordinal)) {
2770 int index = source.LastIndexOf(".Add(", StringComparison.Ordinal);
2771 LocalBuilder localA = ilg.GetLocal(source.Substring(0, index));
2772 ilg.LdlocAddress(localA);
2777 regex = NewRegex("(?<a>[^[]+)[[](?<ia>.+)[]]");
2778 match = regex.Match(source);
2779 if (match.Success) {
2780 System.Diagnostics.Debug.Assert(ilg.GetVariableType(ilg.GetVariable(match.Groups["a"].Value)).IsArray);
2781 ilg.Load(ilg.GetVariable(match.Groups["a"].Value));
2782 ilg.Load(ilg.GetVariable(match.Groups["ia"].Value));
2785 throw CodeGenerator.NotSupported("Unexpected: " + source);
2788 void WriteSourceEnd(string source, Type elementType) {
2789 WriteSourceEnd(source, elementType, elementType);
2791 void WriteSourceEnd(string source, Type elementType, Type stackType) {
2793 if (ilg.TryGetVariable(source, out variable)) {
2794 Type varType = ilg.GetVariableType(variable);
2795 if (CodeGenerator.IsNullableGenericType(varType)) {
2796 ilg.Call(varType.GetConstructor(varType.GetGenericArguments()));
2799 Debug.Assert(elementType != null && variable is LocalBuilder);
2800 ilg.ConvertValue(stackType, elementType);
2801 ilg.ConvertValue(elementType, varType);
2802 ilg.Stloc((LocalBuilder)variable);
2807 if (source.StartsWith("o.@", StringComparison.Ordinal)) {
2808 Debug.Assert(memberInfos.ContainsKey(source.Substring(3)));
2809 MemberInfo memInfo = memberInfos[source.Substring(3)];
2810 ilg.ConvertValue(stackType, memInfo.MemberType == MemberTypes.Field ? ((FieldInfo)memInfo).FieldType : ((PropertyInfo)memInfo).PropertyType);
2811 ilg.StoreMember(memInfo);
2814 // a_0_0 = (global::System.Object[])EnsureArrayIndex(a_0_0, ca_0_0, typeof(global::System.Object));a_0_0[ca_0_0++]
2815 Regex regex = NewRegex("(?<locA1>[^ ]+) = .+EnsureArrayIndex[(](?<locA2>[^,]+), (?<locI1>[^,]+),[^;]+;(?<locA3>[^[]+)[[](?<locI2>[^+]+)[+][+][]]");
2816 Match match = regex.Match(source);
2817 if (match.Success) {
2818 object oVar = ilg.GetVariable(match.Groups["locA1"].Value);
2819 Type arrayElementType = ilg.GetVariableType(oVar).GetElementType();
2820 ilg.ConvertValue(elementType, arrayElementType);
2821 if (CodeGenerator.IsNullableGenericType(arrayElementType) || arrayElementType.IsValueType) {
2822 ilg.Stobj(arrayElementType);
2825 ilg.Stelem(arrayElementType);
2830 if (source.EndsWith(".Add(", StringComparison.Ordinal)) {
2831 int index = source.LastIndexOf(".Add(", StringComparison.Ordinal);
2832 LocalBuilder localA = ilg.GetLocal(source.Substring(0, index));
2833 Debug.Assert(!localA.LocalType.IsGenericType || (localA.LocalType.GetGenericArguments().Length == 1 && localA.LocalType.GetGenericArguments()[0].IsAssignableFrom(elementType)));
2834 MethodInfo Add = localA.LocalType.GetMethod(
2836 CodeGenerator.InstanceBindingFlags,
2838 new Type[] { elementType },
2841 Debug.Assert(Add != null);
2842 Type addParameterType = Add.GetParameters()[0].ParameterType;
2843 ilg.ConvertValue(stackType, addParameterType);
2845 if (Add.ReturnType != typeof(void))
2850 regex = NewRegex("(?<a>[^[]+)[[](?<ia>.+)[]]");
2851 match = regex.Match(source);
2852 if (match.Success) {
2853 Type varType = ilg.GetVariableType(ilg.GetVariable(match.Groups["a"].Value));
2854 System.Diagnostics.Debug.Assert(varType.IsArray);
2855 Type varElementType = varType.GetElementType();
2856 ilg.ConvertValue(stackType, varElementType);
2857 ilg.Stelem(varElementType);
2860 throw CodeGenerator.NotSupported("Unexpected: " + source);
2863 void WriteArray(string source, string arrayName, ArrayMapping arrayMapping, bool readOnly, bool isNullable, int fixupIndex, int elementIndex) {
2864 MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
2866 CodeGenerator.InstanceBindingFlags,
2868 CodeGenerator.EmptyTypeArray,
2872 ilg.Call(XmlSerializationReader_ReadNull);
2875 MemberMapping memberMapping = new MemberMapping();
2876 memberMapping.Elements = arrayMapping.Elements;
2877 memberMapping.TypeDesc = arrayMapping.TypeDesc;
2878 memberMapping.ReadOnly = readOnly;
2879 if (source.StartsWith("o.@", StringComparison.Ordinal)) {
2880 Debug.Assert(memberInfos.ContainsKey(source.Substring(3)));
2881 memberMapping.MemberInfo = memberInfos[source.Substring(3)];
2883 Member member = new Member(this, source, arrayName, elementIndex, memberMapping, false);
2884 member.IsNullable = false;//Note, [....]: IsNullable is set to false since null condition (xsi:nil) is already handled by 'ReadNull()'
2886 Member[] members = new Member[] { member };
2887 WriteMemberBegin(members);
2888 Label labelTrue = ilg.DefineLabel();
2889 Label labelEnd = ilg.DefineLabel();
2892 ilg.Load(ilg.GetVariable(member.ArrayName));
2898 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
2900 CodeGenerator.InstanceBindingFlags,
2902 CodeGenerator.EmptyTypeArray,
2905 MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
2906 "get_IsEmptyElement",
2907 CodeGenerator.InstanceBindingFlags,
2909 CodeGenerator.EmptyTypeArray,
2913 ilg.Call(XmlSerializationReader_get_Reader);
2914 ilg.Call(XmlReader_get_IsEmptyElement);
2917 ilg.MarkLabel(labelTrue);
2919 ilg.MarkLabel(labelEnd);
2922 MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
2924 CodeGenerator.InstanceBindingFlags,
2926 CodeGenerator.EmptyTypeArray,
2930 ilg.Call(XmlSerializationReader_get_Reader);
2931 ilg.Call(XmlReader_Skip);
2934 MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
2936 CodeGenerator.InstanceBindingFlags,
2938 CodeGenerator.EmptyTypeArray,
2942 ilg.Call(XmlSerializationReader_get_Reader);
2943 ilg.Call(XmlReader_ReadStartElement);
2944 int loopIndex = WriteWhileNotLoopStart();
2946 string unknownNode = "UnknownNode(null, " + ExpectedElements(members) + ");";
2947 WriteMemberElements(members, unknownNode, unknownNode, null, null);
2948 MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
2950 CodeGenerator.InstanceBindingFlags,
2952 CodeGenerator.EmptyTypeArray,
2956 ilg.Call(XmlSerializationReader_get_Reader);
2957 ilg.Call(XmlReader_MoveToContent);
2960 WriteWhileLoopEnd(loopIndex);
2961 MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
2963 CodeGenerator.InstanceBindingFlags,
2965 CodeGenerator.EmptyTypeArray,
2969 ilg.Call(XmlSerializationReader_ReadEndElement);
2972 WriteMemberEnd(members, false);
2976 member.IsNullable = true;
2977 WriteMemberBegin(members);
2978 WriteMemberEnd(members);
2983 void WriteElement(string source, string arrayName, string choiceSource, ElementAccessor element, ChoiceIdentifierAccessor choice, string checkSpecified, bool checkForNull, bool readOnly, int fixupIndex, int elementIndex) {
2984 if (checkSpecified != null && checkSpecified.Length > 0) {
2985 ILGenSet(checkSpecified, true);
2988 if (element.Mapping is ArrayMapping) {
2989 WriteArray(source, arrayName, (ArrayMapping)element.Mapping, readOnly, element.IsNullable, fixupIndex, elementIndex);
2991 else if (element.Mapping is NullableMapping) {
2992 string methodName = ReferenceMapping(element.Mapping);
2994 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
2995 if (methodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, element.Mapping.TypeDesc.Name));
2997 WriteSourceBegin(source);
3000 MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
3002 CodeGenerator.PrivateMethodAttributes,
3003 // See WriteNullableMethod for different return type logic
3004 element.Mapping.TypeDesc.Type,
3005 new Type[] { typeof(Boolean) }
3007 ilg.Call(methodBuilder);
3008 WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
3010 else if (element.Mapping is PrimitiveMapping) {
3011 bool doEndIf = false;
3012 if (element.IsNullable) {
3013 MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
3015 CodeGenerator.InstanceBindingFlags,
3017 CodeGenerator.EmptyTypeArray,
3021 ilg.Call(XmlSerializationReader_ReadNull);
3023 WriteSourceBegin(source);
3024 if (element.Mapping.TypeDesc.IsValueType) {
3025 throw CodeGenerator.NotSupported("No such condition. PrimitiveMapping && IsNullable = String, XmlQualifiedName and never IsValueType");
3030 WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
3034 if (element.Default != null && element.Default != DBNull.Value && element.Mapping.TypeDesc.IsValueType) {
3035 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
3037 CodeGenerator.InstanceBindingFlags,
3039 CodeGenerator.EmptyTypeArray,
3042 MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
3043 "get_IsEmptyElement",
3044 CodeGenerator.InstanceBindingFlags,
3046 CodeGenerator.EmptyTypeArray,
3050 ilg.Call(XmlSerializationReader_get_Reader);
3051 ilg.Call(XmlReader_get_IsEmptyElement);
3053 MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
3055 CodeGenerator.InstanceBindingFlags,
3057 CodeGenerator.EmptyTypeArray,
3061 ilg.Call(XmlSerializationReader_get_Reader);
3062 ilg.Call(XmlReader_Skip);
3069 WriteSourceBegin(source);
3070 if (element.Mapping.TypeDesc == QnameTypeDesc) {
3071 MethodInfo XmlSerializationReader_ReadElementQualifiedName = typeof(XmlSerializationReader).GetMethod(
3072 "ReadElementQualifiedName",
3073 CodeGenerator.InstanceBindingFlags,
3075 CodeGenerator.EmptyTypeArray,
3079 ilg.Call(XmlSerializationReader_ReadElementQualifiedName);
3083 switch (element.Mapping.TypeDesc.FormatterName) {
3084 case "ByteArrayBase64":
3085 case "ByteArrayHex":
3089 readFunc = "Reader.ReadElementString()";
3092 WritePrimitive(element.Mapping, readFunc);
3095 WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
3099 else if (element.Mapping is StructMapping) {
3100 TypeMapping mapping = element.Mapping;
3101 string methodName = ReferenceMapping(mapping);
3103 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
3104 if (methodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name));
3108 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
3110 CodeGenerator.InstanceBindingFlags,
3112 CodeGenerator.EmptyTypeArray,
3115 MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
3117 CodeGenerator.InstanceBindingFlags,
3119 CodeGenerator.EmptyTypeArray,
3122 ilg.Ldloc(arrayName);
3124 ilg.If(Cmp.EqualTo);
3126 ilg.Call(XmlSerializationReader_get_Reader);
3127 ilg.Call(XmlReader_Skip);
3130 WriteSourceBegin(source);
3131 List<Type> argTypes = new List<Type>();
3133 if (mapping.TypeDesc.IsNullable) {
3134 ilg.Load(element.IsNullable);
3135 argTypes.Add(typeof(Boolean));
3138 argTypes.Add(typeof(Boolean));
3139 MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
3141 CodeGenerator.PrivateMethodAttributes,
3142 mapping.TypeDesc.Type,
3145 ilg.Call(methodBuilder);
3146 WriteSourceEnd(source, mapping.TypeDesc.Type);
3148 // 'If' begins in checkForNull above
3151 else if (element.Mapping is SpecialMapping) {
3152 SpecialMapping special = (SpecialMapping)element.Mapping;
3153 switch (special.TypeDesc.Kind) {
3155 bool isDoc = special.TypeDesc.FullName == typeof(XmlDocument).FullName;
3156 WriteSourceBeginTyped(source, special.TypeDesc);
3157 MethodInfo XmlSerializationReader_ReadXmlXXX = typeof(XmlSerializationReader).GetMethod(
3158 isDoc ? "ReadXmlDocument" : "ReadXmlNode",
3159 CodeGenerator.InstanceBindingFlags,
3161 new Type[] { typeof(Boolean) },
3165 ilg.Ldc(element.Any ? false : true);
3166 ilg.Call(XmlSerializationReader_ReadXmlXXX);
3167 // See logic in WriteSourceBeginTyped whether or not to castclass.
3168 if (special.TypeDesc != null)
3169 ilg.Castclass(special.TypeDesc.Type);
3170 WriteSourceEnd(source, special.TypeDesc.Type);
3172 case TypeKind.Serializable:
3173 SerializableMapping sm = (SerializableMapping)element.Mapping;
3174 // check to see if we need to do the derivation
3175 if (sm.DerivedMappings != null) {
3176 MethodInfo XmlSerializationReader_GetXsiType = typeof(XmlSerializationReader).GetMethod(
3178 CodeGenerator.InstanceBindingFlags,
3180 CodeGenerator.EmptyTypeArray,
3183 Label labelTrue = ilg.DefineLabel();
3184 Label labelEnd = ilg.DefineLabel();
3185 LocalBuilder tserLoc = ilg.DeclareOrGetLocal(typeof(XmlQualifiedName), "tser");
3187 ilg.Call(XmlSerializationReader_GetXsiType);
3192 ilg.Brtrue(labelTrue);
3193 WriteQNameEqual("tser", sm.XsiType.Name, sm.XsiType.Namespace);
3196 ilg.MarkLabel(labelTrue);
3198 ilg.MarkLabel(labelEnd);
3201 WriteSourceBeginTyped(source, sm.TypeDesc);
3202 bool isWrappedAny = !element.Any && IsWildcard(sm);
3203 MethodInfo XmlSerializationReader_ReadSerializable = typeof(XmlSerializationReader).GetMethod(
3205 CodeGenerator.InstanceBindingFlags,
3207 isWrappedAny ? new Type[] { typeof(IXmlSerializable), typeof(Boolean) } : new Type[] { typeof(IXmlSerializable) },
3211 RaCodeGen.ILGenForCreateInstance(ilg, sm.TypeDesc.Type, sm.TypeDesc.CannotNew, false);
3212 if (sm.TypeDesc.CannotNew)
3213 ilg.ConvertValue(typeof(object), typeof(IXmlSerializable));
3216 ilg.Call(XmlSerializationReader_ReadSerializable);
3217 // See logic in WriteSourceBeginTyped whether or not to castclass.
3218 if (sm.TypeDesc != null)
3219 ilg.ConvertValue(typeof(IXmlSerializable), sm.TypeDesc.Type);
3220 WriteSourceEnd(source, sm.TypeDesc.Type);
3221 if (sm.DerivedMappings != null) {
3222 WriteDerivedSerializable(sm, sm, source, isWrappedAny);
3223 WriteUnknownNode("UnknownNode", "null", null, true);
3227 throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
3231 throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
3233 if (choice != null) {
3235 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
3236 if (choiceSource == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "need parent for the " + source));
3239 WriteSourceBegin(choiceSource);
3240 CodeIdentifier.CheckValidIdentifier(choice.MemberIds[elementIndex]);
3241 RaCodeGen.ILGenForEnumMember(ilg, choice.Mapping.TypeDesc.Type, choice.MemberIds[elementIndex]);
3242 WriteSourceEnd(choiceSource, choice.Mapping.TypeDesc.Type);
3246 void WriteDerivedSerializable(SerializableMapping head, SerializableMapping mapping, string source, bool isWrappedAny) {
3247 if (mapping == null)
3249 for (SerializableMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) {
3250 Label labelTrue = ilg.DefineLabel();
3251 Label labelEnd = ilg.DefineLabel();
3252 LocalBuilder tserLoc = ilg.GetLocal("tser");
3257 ilg.Brtrue(labelTrue);
3258 WriteQNameEqual("tser", derived.XsiType.Name, derived.XsiType.Namespace);
3261 ilg.MarkLabel(labelTrue);
3263 ilg.MarkLabel(labelEnd);
3266 if (derived.Type != null) {
3267 if (head.Type.IsAssignableFrom(derived.Type)) {
3268 WriteSourceBeginTyped(source, head.TypeDesc);
3269 MethodInfo XmlSerializationReader_ReadSerializable = typeof(XmlSerializationReader).GetMethod(
3271 CodeGenerator.InstanceBindingFlags,
3273 isWrappedAny ? new Type[] { typeof(IXmlSerializable), typeof(Boolean) } : new Type[] { typeof(IXmlSerializable) },
3277 RaCodeGen.ILGenForCreateInstance(ilg, derived.TypeDesc.Type, derived.TypeDesc.CannotNew, false);
3278 if (derived.TypeDesc.CannotNew)
3279 ilg.ConvertValue(typeof(object), typeof(IXmlSerializable));
3282 ilg.Call(XmlSerializationReader_ReadSerializable);
3283 // See logic in WriteSourceBeginTyped whether or not to castclass.
3284 if (head.TypeDesc != null)
3285 ilg.ConvertValue(typeof(IXmlSerializable), head.TypeDesc.Type);
3286 WriteSourceEnd(source, head.TypeDesc.Type);
3289 MethodInfo XmlSerializationReader_CreateBadDerivationException = typeof(XmlSerializationReader).GetMethod(
3290 "CreateBadDerivationException",
3291 CodeGenerator.InstanceBindingFlags,
3293 new Type[] { typeof(String), typeof(String), typeof(String), typeof(String), typeof(String), typeof(String) },
3297 ilg.Ldstr(derived.XsiType.Name);
3298 ilg.Ldstr(derived.XsiType.Namespace);
3299 ilg.Ldstr(head.XsiType.Name);
3300 ilg.Ldstr(head.XsiType.Namespace);
3301 ilg.Ldstr(derived.Type.FullName);
3302 ilg.Ldstr(head.Type.FullName);
3303 ilg.Call(XmlSerializationReader_CreateBadDerivationException);
3308 MethodInfo XmlSerializationReader_CreateMissingIXmlSerializableType = typeof(XmlSerializationReader).GetMethod(
3309 "CreateMissingIXmlSerializableType",
3310 CodeGenerator.InstanceBindingFlags,
3312 new Type[] { typeof(String), typeof(String), typeof(String) },
3316 ilg.Ldstr(derived.XsiType.Name);
3317 ilg.Ldstr(derived.XsiType.Namespace);
3318 ilg.Ldstr(head.Type.FullName);
3319 ilg.Call(XmlSerializationReader_CreateMissingIXmlSerializableType);
3324 WriteDerivedSerializable(head, derived, source, isWrappedAny);
3328 int WriteWhileNotLoopStart() {
3329 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
3331 CodeGenerator.InstanceBindingFlags,
3333 CodeGenerator.EmptyTypeArray,
3336 MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
3338 CodeGenerator.InstanceBindingFlags,
3340 CodeGenerator.EmptyTypeArray,
3344 ilg.Call(XmlSerializationReader_get_Reader);
3345 ilg.Call(XmlReader_MoveToContent);
3347 int loopIndex = WriteWhileLoopStartCheck();
3352 void WriteWhileLoopEnd(int loopIndex) {
3353 WriteWhileLoopEndCheck(loopIndex);
3354 ilg.WhileBeginCondition();
3356 int XmlNodeType_None = 0;
3357 //int XmlNodeType_Element = 1;
3358 int XmlNodeType_EndElement = 15;
3360 MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
3362 CodeGenerator.InstanceBindingFlags,
3364 CodeGenerator.EmptyTypeArray,
3367 MethodInfo XmlReader_get_NodeType = typeof(XmlReader).GetMethod(
3369 CodeGenerator.InstanceBindingFlags,
3371 CodeGenerator.EmptyTypeArray,
3374 Label labelFalse = ilg.DefineLabel();
3375 Label labelEnd = ilg.DefineLabel();
3377 ilg.Call(XmlSerializationReader_get_Reader);
3378 ilg.Call(XmlReader_get_NodeType);
3379 ilg.Ldc(XmlNodeType_EndElement);
3380 ilg.Beq(labelFalse);
3382 ilg.Call(XmlSerializationReader_get_Reader);
3383 ilg.Call(XmlReader_get_NodeType);
3384 ilg.Ldc(XmlNodeType_None);
3387 ilg.MarkLabel(labelFalse);
3389 ilg.MarkLabel(labelEnd);
3391 ilg.WhileEndCondition();
3395 int WriteWhileLoopStartCheck() {
3396 MethodInfo XmlSerializationReader_get_ReaderCount = typeof(XmlSerializationReader).GetMethod(
3398 CodeGenerator.InstanceBindingFlags,
3400 CodeGenerator.EmptyTypeArray,
3404 ilg.Stloc(typeof(Int32), String.Format(CultureInfo.InvariantCulture, "whileIterations{0}", nextWhileLoopIndex));
3406 ilg.Call(XmlSerializationReader_get_ReaderCount);
3407 ilg.Stloc(typeof(Int32), String.Format(CultureInfo.InvariantCulture, "readerCount{0}", nextWhileLoopIndex));
3408 return nextWhileLoopIndex++;
3411 void WriteWhileLoopEndCheck(int loopIndex) {
3412 Type refIntType = Type.GetType("System.Int32&");
3413 MethodInfo XmlSerializationReader_CheckReaderCount = typeof(XmlSerializationReader).GetMethod(
3415 CodeGenerator.InstanceBindingFlags,
3417 new Type[] { refIntType, refIntType },
3421 ilg.Ldloca(ilg.GetLocal(String.Format(CultureInfo.InvariantCulture, "whileIterations{0}", loopIndex)));
3422 ilg.Ldloca(ilg.GetLocal(String.Format(CultureInfo.InvariantCulture, "readerCount{0}", loopIndex)));
3423 ilg.Call(XmlSerializationReader_CheckReaderCount);
3426 void WriteParamsRead(int length) {
3427 LocalBuilder paramsRead = ilg.DeclareLocal(typeof(Boolean[]), "paramsRead");
3428 ilg.NewArray(typeof(Boolean), length);
3429 ilg.Stloc(paramsRead);
3432 void WriteCreateMapping(TypeMapping mapping, string local) {
3433 string fullTypeName = mapping.TypeDesc.CSharpName;
3434 bool ctorInaccessible = mapping.TypeDesc.CannotNew;
3436 LocalBuilder loc = ilg.DeclareLocal(
3437 mapping.TypeDesc.Type,
3440 if (ctorInaccessible) {
3441 ilg.BeginExceptionBlock();
3443 RaCodeGen.ILGenForCreateInstance(ilg, mapping.TypeDesc.Type, mapping.TypeDesc.CannotNew, true);
3445 if (ctorInaccessible) {
3447 WriteCatchException(typeof(MissingMethodException));
3448 MethodInfo XmlSerializationReader_CreateInaccessibleConstructorException = typeof(XmlSerializationReader).GetMethod(
3449 "CreateInaccessibleConstructorException",
3450 CodeGenerator.InstanceBindingFlags,
3452 new Type[] { typeof(String) },
3456 ilg.Ldstr(fullTypeName);
3457 ilg.Call(XmlSerializationReader_CreateInaccessibleConstructorException);
3460 WriteCatchException(typeof(SecurityException));
3461 MethodInfo XmlSerializationReader_CreateCtorHasSecurityException = typeof(XmlSerializationReader).GetMethod(
3462 "CreateCtorHasSecurityException",
3463 CodeGenerator.InstanceBindingFlags,
3465 new Type[] { typeof(String) },
3469 ilg.Ldstr(fullTypeName);
3470 ilg.Call(XmlSerializationReader_CreateCtorHasSecurityException);
3473 ilg.EndExceptionBlock();
3477 void WriteCatchException(Type exceptionType) {
3478 ilg.BeginCatchBlock(exceptionType);
3482 void WriteCatchCastException(TypeDesc typeDesc, string source, string id) {
3483 WriteCatchException(typeof(InvalidCastException));
3484 MethodInfo XmlSerializationReader_CreateInvalidCastException = typeof(XmlSerializationReader).GetMethod(
3485 "CreateInvalidCastException",
3486 CodeGenerator.InstanceBindingFlags,
3488 new Type[] { typeof(Type), typeof(Object), typeof(String) },
3492 ilg.Ldc(typeDesc.Type);
3494 // GetTarget(ids[0])
3495 if (source.StartsWith("GetTarget(ids[", StringComparison.Ordinal)) {
3496 MethodInfo XmlSerializationReader_GetTarget = typeof(XmlSerializationReader).GetMethod(
3498 CodeGenerator.InstanceBindingFlags,
3500 new Type[] { typeof(String) },
3503 object idsLoc = ilg.GetVariable("ids");
3506 ilg.LoadArrayElement(idsLoc, Int32.Parse(source.Substring(14, source.Length - 16), CultureInfo.InvariantCulture));
3507 ilg.Call(XmlSerializationReader_GetTarget);
3510 ilg.Load(ilg.GetVariable(source));
3517 if (id.StartsWith("ids[", StringComparison.Ordinal)) {
3518 object idsLoc = ilg.GetVariable("ids");
3520 ilg.LoadArrayElement(idsLoc, Int32.Parse(id.Substring(4, id.Length - 5), CultureInfo.InvariantCulture));
3523 object idVar = ilg.GetVariable(id);
3525 ilg.ConvertValue(ilg.GetVariableType(idVar), typeof(string));
3528 ilg.Call(XmlSerializationReader_CreateInvalidCastException);
3531 void WriteArrayLocalDecl(string typeName, string variableName, string initValue, TypeDesc arrayTypeDesc) {
3532 RaCodeGen.WriteArrayLocalDecl(typeName, variableName, new SourceInfo(initValue, initValue, null, arrayTypeDesc.Type, ilg), arrayTypeDesc);
3534 void WriteCreateInstance(string source, bool ctorInaccessible, Type type) {
3535 RaCodeGen.WriteCreateInstance(source, ctorInaccessible, type, ilg);
3537 void WriteLocalDecl(string variableName, SourceInfo initValue) {
3538 RaCodeGen.WriteLocalDecl(variableName, initValue);
3540 void ILGenElseString(string elseString) {
3541 MethodInfo XmlSerializationReader_UnknownNode1 = typeof(XmlSerializationReader).GetMethod(
3543 CodeGenerator.InstanceBindingFlags,
3545 new Type[] { typeof(object) },
3548 MethodInfo XmlSerializationReader_UnknownNode2 = typeof(XmlSerializationReader).GetMethod(
3550 CodeGenerator.InstanceBindingFlags,
3552 new Type[] { typeof(object), typeof(string) },
3555 // UnknownNode(null, @":anyType");
3556 Regex regex = NewRegex("UnknownNode[(]null, @[\"](?<qnames>[^\"]*)[\"][)];");
3557 Match match = regex.Match(elseString);
3558 if (match.Success) {
3561 ilg.Ldstr(match.Groups["qnames"].Value);
3562 ilg.Call(XmlSerializationReader_UnknownNode2);
3565 // UnknownNode((object)o, @"");
3566 regex = NewRegex("UnknownNode[(][(]object[)](?<o>[^,]+), @[\"](?<qnames>[^\"]*)[\"][)];");
3567 match = regex.Match(elseString);
3568 if (match.Success) {
3570 LocalBuilder localO = ilg.GetLocal(match.Groups["o"].Value);
3572 ilg.ConvertValue(localO.LocalType, typeof(object));
3573 ilg.Ldstr(match.Groups["qnames"].Value);
3574 ilg.Call(XmlSerializationReader_UnknownNode2);
3577 // UnknownNode((object)o, null);
3578 regex = NewRegex("UnknownNode[(][(]object[)](?<o>[^,]+), null[)];");
3579 match = regex.Match(elseString);
3580 if (match.Success) {
3582 LocalBuilder localO = ilg.GetLocal(match.Groups["o"].Value);
3584 ilg.ConvertValue(localO.LocalType, typeof(object));
3586 ilg.Call(XmlSerializationReader_UnknownNode2);
3589 // "UnknownNode((object)o);"
3590 regex = NewRegex("UnknownNode[(][(]object[)](?<o>[^)]+)[)];");
3591 match = regex.Match(elseString);
3592 if (match.Success) {
3594 LocalBuilder localO = ilg.GetLocal(match.Groups["o"].Value);
3596 ilg.ConvertValue(localO.LocalType, typeof(object));
3597 ilg.Call(XmlSerializationReader_UnknownNode1);
3600 throw CodeGenerator.NotSupported("Unexpected: " + elseString);
3602 void ILGenParamsReadSource(string paramsReadSource) {
3603 Regex regex = NewRegex("paramsRead\\[(?<index>[0-9]+)\\]");
3604 Match match = regex.Match(paramsReadSource);
3605 if (match.Success) {
3606 ilg.LoadArrayElement(ilg.GetLocal("paramsRead"), Int32.Parse(match.Groups["index"].Value, CultureInfo.InvariantCulture));
3609 throw CodeGenerator.NotSupported("Unexpected: " + paramsReadSource);
3611 void ILGenParamsReadSource(string paramsReadSource, bool value) {
3612 Regex regex = NewRegex("paramsRead\\[(?<index>[0-9]+)\\]");
3613 Match match = regex.Match(paramsReadSource);
3614 if (match.Success) {
3615 ilg.StoreArrayElement(ilg.GetLocal("paramsRead"), Int32.Parse(match.Groups["index"].Value, CultureInfo.InvariantCulture), value);
3618 throw CodeGenerator.NotSupported("Unexpected: " + paramsReadSource);
3620 void ILGenElementElseString(string elementElseString) {
3621 if (elementElseString == "throw CreateUnknownNodeException();") {
3622 MethodInfo XmlSerializationReader_CreateUnknownNodeException = typeof(XmlSerializationReader).GetMethod(
3623 "CreateUnknownNodeException",
3624 CodeGenerator.InstanceBindingFlags,
3626 CodeGenerator.EmptyTypeArray,
3630 ilg.Call(XmlSerializationReader_CreateUnknownNodeException);
3634 if (elementElseString.StartsWith("UnknownNode(", StringComparison.Ordinal)) {
3635 ILGenElseString(elementElseString);
3638 throw CodeGenerator.NotSupported("Unexpected: " + elementElseString);
3640 void ILGenSet(string source, object value) {
3641 WriteSourceBegin(source);
3643 WriteSourceEnd(source, value == null ? typeof(object) : value.GetType());