XmlSerializationReaderILGen.cs 163 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697
  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlSerializationReaderILGen.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">Microsoft</owner>
  6. //------------------------------------------------------------------------------
  7. namespace System.Xml.Serialization {
  8. using System;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using System.Diagnostics;
  12. using System.Globalization;
  13. using System.Reflection;
  14. using System.Reflection.Emit;
  15. using System.Security;
  16. using System.Text.RegularExpressions;
  17. using System.Xml;
  18. using System.Xml.Schema;
  19. internal class XmlSerializationReaderILGen : XmlSerializationILGen {
  20. Hashtable idNames = new Hashtable();
  21. // Mapping name->id_XXXNN field
  22. Dictionary<string, FieldBuilder> idNameFields = new Dictionary<string, FieldBuilder>();
  23. Hashtable enums;
  24. int nextIdNumber = 0;
  25. int nextWhileLoopIndex = 0;
  26. internal Hashtable Enums {
  27. get {
  28. if (enums == null) {
  29. enums = new Hashtable();
  30. }
  31. return enums;
  32. }
  33. }
  34. class CreateCollectionInfo {
  35. string name;
  36. TypeDesc td;
  37. internal CreateCollectionInfo(string name, TypeDesc td) {
  38. this.name = name;
  39. this.td = td;
  40. }
  41. internal string Name {
  42. get { return name; }
  43. }
  44. internal TypeDesc TypeDesc {
  45. get { return td; }
  46. }
  47. }
  48. class Member {
  49. string source;
  50. string arrayName;
  51. string arraySource;
  52. string choiceArrayName;
  53. string choiceSource;
  54. string choiceArraySource;
  55. MemberMapping mapping;
  56. bool isArray;
  57. bool isList;
  58. bool isNullable;
  59. bool multiRef;
  60. int fixupIndex = -1;
  61. string paramsReadSource;
  62. string checkSpecifiedSource;
  63. internal Member(XmlSerializationReaderILGen outerClass, string source, string arrayName, int i, MemberMapping mapping)
  64. : this(outerClass, source, null, arrayName, i, mapping, false, null) {
  65. }
  66. internal Member(XmlSerializationReaderILGen outerClass, string source, string arrayName, int i, MemberMapping mapping, string choiceSource)
  67. : this(outerClass, source, null, arrayName, i, mapping, false, choiceSource) {
  68. }
  69. internal Member(XmlSerializationReaderILGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping)
  70. : this(outerClass, source, arraySource, arrayName, i, mapping, false, null) {
  71. }
  72. internal Member(XmlSerializationReaderILGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping, string choiceSource)
  73. : this(outerClass, source, arraySource, arrayName, i, mapping, false, choiceSource) {
  74. }
  75. internal Member(XmlSerializationReaderILGen outerClass, string source, string arrayName, int i, MemberMapping mapping, bool multiRef)
  76. : this(outerClass, source, null, arrayName, i, mapping, multiRef, null) {
  77. }
  78. internal Member(XmlSerializationReaderILGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping, bool multiRef, string choiceSource) {
  79. this.source = source;
  80. this.arrayName = arrayName + "_" + i.ToString(CultureInfo.InvariantCulture);
  81. this.choiceArrayName = "choice_" + this.arrayName;
  82. this.choiceSource = choiceSource;
  83. if (mapping.TypeDesc.IsArrayLike) {
  84. if (arraySource != null)
  85. this.arraySource = arraySource;
  86. else
  87. this.arraySource = outerClass.GetArraySource(mapping.TypeDesc, this.arrayName, multiRef);
  88. isArray = mapping.TypeDesc.IsArray;
  89. isList = !isArray;
  90. if (mapping.ChoiceIdentifier != null) {
  91. this.choiceArraySource = outerClass.GetArraySource(mapping.TypeDesc, this.choiceArrayName, multiRef);
  92. string a = choiceArrayName;
  93. string c = "c" + a;
  94. string choiceTypeFullName = mapping.ChoiceIdentifier.Mapping.TypeDesc.CSharpName;
  95. string castString = "(" + choiceTypeFullName + "[])";
  96. string init = a + " = " + castString +
  97. "EnsureArrayIndex(" + a + ", " + c + ", " + outerClass.RaCodeGen.GetStringForTypeof(choiceTypeFullName) + ");";
  98. this.choiceArraySource = init + outerClass.RaCodeGen.GetStringForArrayMember(a, c + "++", mapping.ChoiceIdentifier.Mapping.TypeDesc);
  99. }
  100. else {
  101. this.choiceArraySource = this.choiceSource;
  102. }
  103. }
  104. else {
  105. this.arraySource = arraySource == null ? source : arraySource;
  106. this.choiceArraySource = this.choiceSource;
  107. }
  108. this.mapping = mapping;
  109. }
  110. internal MemberMapping Mapping {
  111. get { return mapping; }
  112. }
  113. internal string Source {
  114. get { return source; }
  115. }
  116. internal string ArrayName {
  117. get { return arrayName; }
  118. }
  119. internal string ArraySource {
  120. get { return arraySource; }
  121. }
  122. internal bool IsList {
  123. get { return isList; }
  124. }
  125. internal bool IsArrayLike {
  126. get { return (isArray || isList); }
  127. }
  128. internal bool IsNullable {
  129. get { return isNullable; }
  130. set { isNullable = value; }
  131. }
  132. internal bool MultiRef {
  133. get { return multiRef; }
  134. set { multiRef = value; }
  135. }
  136. internal int FixupIndex {
  137. get { return fixupIndex; }
  138. set { fixupIndex = value; }
  139. }
  140. internal string ParamsReadSource {
  141. get { return paramsReadSource; }
  142. set { paramsReadSource = value; }
  143. }
  144. internal string CheckSpecifiedSource {
  145. get { return checkSpecifiedSource; }
  146. set { checkSpecifiedSource = value; }
  147. }
  148. internal string ChoiceSource {
  149. get { return choiceSource; }
  150. }
  151. internal string ChoiceArrayName {
  152. get { return choiceArrayName; }
  153. }
  154. internal string ChoiceArraySource {
  155. get { return choiceArraySource; }
  156. }
  157. }
  158. internal XmlSerializationReaderILGen(TypeScope[] scopes, string access, string className)
  159. : base(scopes, access, className) {
  160. }
  161. internal void GenerateBegin() {
  162. this.typeBuilder = CodeGenerator.CreateTypeBuilder(
  163. ModuleBuilder,
  164. ClassName,
  165. TypeAttributes | TypeAttributes.BeforeFieldInit,
  166. typeof(XmlSerializationReader),
  167. CodeGenerator.EmptyTypeArray);
  168. foreach (TypeScope scope in Scopes) {
  169. foreach (TypeMapping mapping in scope.TypeMappings) {
  170. if (mapping is StructMapping || mapping is EnumMapping || mapping is NullableMapping)
  171. MethodNames.Add(mapping, NextMethodName(mapping.TypeDesc.Name));
  172. }
  173. RaCodeGen.WriteReflectionInit(scope);
  174. }
  175. }
  176. internal override void GenerateMethod(TypeMapping mapping) {
  177. if (GeneratedMethods.Contains(mapping))
  178. return;
  179. GeneratedMethods[mapping] = mapping;
  180. if (mapping is StructMapping) {
  181. WriteStructMethod((StructMapping)mapping);
  182. }
  183. else if (mapping is EnumMapping) {
  184. WriteEnumMethod((EnumMapping)mapping);
  185. }
  186. else if (mapping is NullableMapping) {
  187. WriteNullableMethod((NullableMapping)mapping);
  188. }
  189. }
  190. internal void GenerateEnd(string[] methods, XmlMapping[] xmlMappings, Type[] types) {
  191. GenerateReferencedMethods();
  192. GenerateInitCallbacksMethod();
  193. ilg = new CodeGenerator(this.typeBuilder);
  194. ilg.BeginMethod(typeof(void), "InitIDs", CodeGenerator.EmptyTypeArray, CodeGenerator.EmptyStringArray,
  195. CodeGenerator.ProtectedOverrideMethodAttributes);
  196. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  197. "get_Reader",
  198. CodeGenerator.InstanceBindingFlags,
  199. null,
  200. CodeGenerator.EmptyTypeArray,
  201. null
  202. );
  203. MethodInfo XmlReader_get_NameTable = typeof(XmlReader).GetMethod(
  204. "get_NameTable",
  205. CodeGenerator.InstanceBindingFlags,
  206. null,
  207. CodeGenerator.EmptyTypeArray,
  208. null
  209. );
  210. MethodInfo XmlNameTable_Add = typeof(XmlNameTable).GetMethod(
  211. "Add",
  212. CodeGenerator.InstanceBindingFlags,
  213. null,
  214. new Type[] { typeof(String) },
  215. null
  216. );
  217. foreach (string id in idNames.Keys) {
  218. //
  219. ilg.Ldarg(0);
  220. ilg.Ldarg(0);
  221. ilg.Call(XmlSerializationReader_get_Reader);
  222. ilg.Call(XmlReader_get_NameTable);
  223. ilg.Ldstr(id);
  224. ilg.Call(XmlNameTable_Add);
  225. Debug.Assert(idNameFields.ContainsKey(id));
  226. ilg.StoreMember(idNameFields[id]);
  227. }
  228. ilg.EndMethod();
  229. this.typeBuilder.DefineDefaultConstructor(
  230. CodeGenerator.PublicMethodAttributes);
  231. Type readerType = this.typeBuilder.CreateType();
  232. CreatedTypes.Add(readerType.Name, readerType);
  233. }
  234. internal string GenerateElement(XmlMapping xmlMapping) {
  235. if (!xmlMapping.IsReadable)
  236. return null;
  237. if (!xmlMapping.GenerateSerializer)
  238. throw new ArgumentException(Res.GetString(Res.XmlInternalError), "xmlMapping");
  239. if (xmlMapping is XmlTypeMapping)
  240. return GenerateTypeElement((XmlTypeMapping)xmlMapping);
  241. else if (xmlMapping is XmlMembersMapping)
  242. return GenerateMembersElement((XmlMembersMapping)xmlMapping);
  243. else
  244. throw new ArgumentException(Res.GetString(Res.XmlInternalError), "xmlMapping");
  245. }
  246. void WriteIsStartTag(string name, string ns) {
  247. WriteID(name);
  248. WriteID(ns);
  249. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  250. "get_Reader",
  251. CodeGenerator.InstanceBindingFlags,
  252. null,
  253. CodeGenerator.EmptyTypeArray,
  254. null
  255. );
  256. MethodInfo XmlReader_IsStartElement = typeof(XmlReader).GetMethod(
  257. "IsStartElement",
  258. CodeGenerator.InstanceBindingFlags,
  259. null,
  260. new Type[] { typeof(String), typeof(String) },
  261. null
  262. );
  263. ilg.Ldarg(0);
  264. ilg.Call(XmlSerializationReader_get_Reader);
  265. ilg.Ldarg(0);
  266. ilg.LoadMember(idNameFields[name ?? String.Empty]);
  267. ilg.Ldarg(0);
  268. ilg.LoadMember(idNameFields[ns ?? String.Empty]);
  269. ilg.Call(XmlReader_IsStartElement);
  270. ilg.If();
  271. }
  272. void WriteUnknownNode(string func, string node, ElementAccessor e, bool anyIfs) {
  273. if (anyIfs) {
  274. ilg.Else();
  275. }
  276. List<Type> argTypes = new List<Type>();
  277. ilg.Ldarg(0);
  278. Debug.Assert(node == "null" || node == "(object)p");
  279. if (node == "null")
  280. ilg.Load(null);
  281. else {
  282. object pVar = ilg.GetVariable("p");
  283. ilg.Load(pVar);
  284. ilg.ConvertValue(ilg.GetVariableType(pVar), typeof(object));
  285. }
  286. argTypes.Add(typeof(object));
  287. if (e != null) {
  288. string expectedElement = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
  289. expectedElement += ":";
  290. expectedElement += e.Name;
  291. ilg.Ldstr(ReflectionAwareILGen.GetCSharpString(expectedElement));
  292. argTypes.Add(typeof(string));
  293. }
  294. MethodInfo method = typeof(XmlSerializationReader).GetMethod(
  295. func,
  296. CodeGenerator.InstanceBindingFlags,
  297. null,
  298. argTypes.ToArray(),
  299. null
  300. );
  301. ilg.Call(method);
  302. if (anyIfs) {
  303. ilg.EndIf();
  304. }
  305. }
  306. void GenerateInitCallbacksMethod() {
  307. ilg = new CodeGenerator(this.typeBuilder);
  308. ilg.BeginMethod(typeof(void), "InitCallbacks", CodeGenerator.EmptyTypeArray, CodeGenerator.EmptyStringArray,
  309. CodeGenerator.ProtectedOverrideMethodAttributes);
  310. string dummyArrayMethodName = NextMethodName("Array");
  311. bool needDummyArrayMethod = false;
  312. ilg.EndMethod();
  313. if (needDummyArrayMethod) {
  314. ilg.BeginMethod(
  315. typeof(object),
  316. GetMethodBuilder(dummyArrayMethodName),
  317. CodeGenerator.EmptyTypeArray,
  318. CodeGenerator.EmptyStringArray,
  319. CodeGenerator.PrivateMethodAttributes);
  320. MethodInfo XmlSerializationReader_UnknownNode1 = typeof(XmlSerializationReader).GetMethod(
  321. "UnknownNode",
  322. CodeGenerator.InstanceBindingFlags,
  323. null,
  324. new Type[] { typeof(object) },
  325. null
  326. );
  327. ilg.Ldarg(0);
  328. ilg.Load(null);
  329. ilg.Call(XmlSerializationReader_UnknownNode1);
  330. ilg.Load(null);
  331. ilg.EndMethod();
  332. }
  333. }
  334. string GenerateMembersElement(XmlMembersMapping xmlMembersMapping) {
  335. return GenerateLiteralMembersElement(xmlMembersMapping);
  336. }
  337. string GetChoiceIdentifierSource(MemberMapping[] mappings, MemberMapping member) {
  338. string choiceSource = null;
  339. if (member.ChoiceIdentifier != null) {
  340. for (int j = 0; j < mappings.Length; j++) {
  341. if (mappings[j].Name == member.ChoiceIdentifier.MemberName) {
  342. choiceSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
  343. break;
  344. }
  345. }
  346. #if DEBUG
  347. // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  348. if (choiceSource == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Can not find " + member.ChoiceIdentifier.MemberName + " in the members mapping."));
  349. #endif
  350. }
  351. return choiceSource;
  352. }
  353. string GetChoiceIdentifierSource(MemberMapping mapping, string parent, TypeDesc parentTypeDesc) {
  354. if (mapping.ChoiceIdentifier == null) return "";
  355. CodeIdentifier.CheckValidIdentifier(mapping.ChoiceIdentifier.MemberName);
  356. return RaCodeGen.GetStringForMember(parent, mapping.ChoiceIdentifier.MemberName, parentTypeDesc);
  357. }
  358. string GenerateLiteralMembersElement(XmlMembersMapping xmlMembersMapping) {
  359. ElementAccessor element = xmlMembersMapping.Accessor;
  360. MemberMapping[] mappings = ((MembersMapping)element.Mapping).Members;
  361. bool hasWrapperElement = ((MembersMapping)element.Mapping).HasWrapperElement;
  362. string methodName = NextMethodName(element.Name);
  363. ilg = new CodeGenerator(this.typeBuilder);
  364. ilg.BeginMethod(
  365. typeof(object[]),
  366. methodName,
  367. CodeGenerator.EmptyTypeArray,
  368. CodeGenerator.EmptyStringArray,
  369. CodeGenerator.PublicMethodAttributes
  370. );
  371. ilg.Load(null);
  372. ilg.Stloc(ilg.ReturnLocal);
  373. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  374. "get_Reader",
  375. CodeGenerator.InstanceBindingFlags,
  376. null,
  377. CodeGenerator.EmptyTypeArray,
  378. null
  379. );
  380. MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
  381. "MoveToContent",
  382. CodeGenerator.InstanceBindingFlags,
  383. null,
  384. CodeGenerator.EmptyTypeArray,
  385. null
  386. );
  387. ilg.Ldarg(0);
  388. ilg.Call(XmlSerializationReader_get_Reader);
  389. ilg.Call(XmlReader_MoveToContent);
  390. ilg.Pop();
  391. LocalBuilder localP = ilg.DeclareLocal(typeof(object[]), "p");
  392. ilg.NewArray(typeof(object), mappings.Length);
  393. ilg.Stloc(localP);
  394. InitializeValueTypes("p", mappings);
  395. int wrapperLoopIndex = 0;
  396. if (hasWrapperElement) {
  397. wrapperLoopIndex = WriteWhileNotLoopStart();
  398. WriteIsStartTag(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
  399. }
  400. Member anyText = null;
  401. Member anyElement = null;
  402. Member anyAttribute = null;
  403. ArrayList membersList = new ArrayList();
  404. ArrayList textOrArrayMembersList = new ArrayList();
  405. ArrayList attributeMembersList = new ArrayList();
  406. for (int i = 0; i < mappings.Length; i++) {
  407. MemberMapping mapping = mappings[i];
  408. string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  409. string arraySource = source;
  410. if (mapping.Xmlns != null) {
  411. arraySource = "((" + mapping.TypeDesc.CSharpName + ")" + source + ")";
  412. }
  413. string choiceSource = GetChoiceIdentifierSource(mappings, mapping);
  414. Member member = new Member(this, source, arraySource, "a", i, mapping, choiceSource);
  415. Member anyMember = new Member(this, source, null, "a", i, mapping, choiceSource);
  416. if (!mapping.IsSequence)
  417. member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  418. if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite) {
  419. string nameSpecified = mapping.Name + "Specified";
  420. for (int j = 0; j < mappings.Length; j++) {
  421. if (mappings[j].Name == nameSpecified) {
  422. member.CheckSpecifiedSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
  423. break;
  424. }
  425. }
  426. }
  427. bool foundAnyElement = false;
  428. if (mapping.Text != null) anyText = anyMember;
  429. if (mapping.Attribute != null && mapping.Attribute.Any)
  430. anyAttribute = anyMember;
  431. if (mapping.Attribute != null || mapping.Xmlns != null)
  432. attributeMembersList.Add(member);
  433. else if (mapping.Text != null)
  434. textOrArrayMembersList.Add(member);
  435. if (!mapping.IsSequence) {
  436. for (int j = 0; j < mapping.Elements.Length; j++) {
  437. if (mapping.Elements[j].Any && mapping.Elements[j].Name.Length == 0) {
  438. anyElement = anyMember;
  439. if (mapping.Attribute == null && mapping.Text == null)
  440. textOrArrayMembersList.Add(anyMember);
  441. foundAnyElement = true;
  442. break;
  443. }
  444. }
  445. }
  446. if (mapping.Attribute != null || mapping.Text != null || foundAnyElement)
  447. membersList.Add(anyMember);
  448. else if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) {
  449. membersList.Add(anyMember);
  450. textOrArrayMembersList.Add(anyMember);
  451. }
  452. else {
  453. if (mapping.TypeDesc.IsArrayLike && !mapping.TypeDesc.IsArray)
  454. member.ParamsReadSource = null; // collection
  455. membersList.Add(member);
  456. }
  457. }
  458. Member[] members = (Member[])membersList.ToArray(typeof(Member));
  459. Member[] textOrArrayMembers = (Member[])textOrArrayMembersList.ToArray(typeof(Member));
  460. if (members.Length > 0 && members[0].Mapping.IsReturnValue) {
  461. MethodInfo XmlSerializationReader_set_IsReturnValue = typeof(XmlSerializationReader).GetMethod(
  462. "set_IsReturnValue",
  463. CodeGenerator.InstanceBindingFlags,
  464. null,
  465. new Type[] { typeof(Boolean) },
  466. null
  467. );
  468. ilg.Ldarg(0);
  469. ilg.Ldc(true);
  470. ilg.Call(XmlSerializationReader_set_IsReturnValue);
  471. }
  472. WriteParamsRead(mappings.Length);
  473. if (attributeMembersList.Count > 0) {
  474. Member[] attributeMembers = (Member[])attributeMembersList.ToArray(typeof(Member));
  475. WriteMemberBegin(attributeMembers);
  476. WriteAttributes(attributeMembers, anyAttribute, "UnknownNode", localP);
  477. WriteMemberEnd(attributeMembers);
  478. MethodInfo XmlReader_MoveToElement = typeof(XmlReader).GetMethod(
  479. "MoveToElement",
  480. CodeGenerator.InstanceBindingFlags,
  481. null,
  482. CodeGenerator.EmptyTypeArray,
  483. null
  484. );
  485. ilg.Ldarg(0);
  486. ilg.Call(XmlSerializationReader_get_Reader);
  487. ilg.Call(XmlReader_MoveToElement);
  488. ilg.Pop();
  489. }
  490. WriteMemberBegin(textOrArrayMembers);
  491. if (hasWrapperElement) {
  492. MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
  493. "get_IsEmptyElement",
  494. CodeGenerator.InstanceBindingFlags,
  495. null,
  496. CodeGenerator.EmptyTypeArray,
  497. null
  498. );
  499. ilg.Ldarg(0);
  500. ilg.Call(XmlSerializationReader_get_Reader);
  501. ilg.Call(XmlReader_get_IsEmptyElement);
  502. ilg.If();
  503. {
  504. MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
  505. "Skip",
  506. CodeGenerator.InstanceBindingFlags,
  507. null,
  508. CodeGenerator.EmptyTypeArray,
  509. null
  510. );
  511. ilg.Ldarg(0);
  512. ilg.Call(XmlSerializationReader_get_Reader);
  513. ilg.Call(XmlReader_Skip);
  514. ilg.Ldarg(0);
  515. ilg.Call(XmlSerializationReader_get_Reader);
  516. ilg.Call(XmlReader_MoveToContent);
  517. ilg.Pop();
  518. ilg.WhileContinue();
  519. }
  520. ilg.EndIf();
  521. MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
  522. "ReadStartElement",
  523. CodeGenerator.InstanceBindingFlags,
  524. null,
  525. CodeGenerator.EmptyTypeArray,
  526. null
  527. );
  528. ilg.Ldarg(0);
  529. ilg.Call(XmlSerializationReader_get_Reader);
  530. ilg.Call(XmlReader_ReadStartElement);
  531. }
  532. if (IsSequence(members)) {
  533. ilg.Ldc(0);
  534. ilg.Stloc(typeof(Int32), "state");
  535. }
  536. int loopIndex = WriteWhileNotLoopStart();
  537. string unknownNode = "UnknownNode((object)p, " + ExpectedElements(members) + ");";
  538. WriteMemberElements(members, unknownNode, unknownNode, anyElement, anyText);
  539. ilg.Ldarg(0);
  540. ilg.Call(XmlSerializationReader_get_Reader);
  541. ilg.Call(XmlReader_MoveToContent);
  542. ilg.Pop();
  543. WriteWhileLoopEnd(loopIndex);
  544. WriteMemberEnd(textOrArrayMembers);
  545. if (hasWrapperElement) {
  546. MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
  547. "ReadEndElement",
  548. CodeGenerator.InstanceBindingFlags,
  549. null,
  550. CodeGenerator.EmptyTypeArray,
  551. null
  552. );
  553. ilg.Ldarg(0);
  554. ilg.Call(XmlSerializationReader_ReadEndElement);
  555. WriteUnknownNode("UnknownNode", "null", element, true);
  556. ilg.Ldarg(0);
  557. ilg.Call(XmlSerializationReader_get_Reader);
  558. ilg.Call(XmlReader_MoveToContent);
  559. ilg.Pop();
  560. WriteWhileLoopEnd(wrapperLoopIndex);
  561. }
  562. ilg.Ldloc(ilg.GetLocal("p"));
  563. ilg.EndMethod();
  564. return methodName;
  565. }
  566. void InitializeValueTypes(string arrayName, MemberMapping[] mappings) {
  567. for (int i = 0; i < mappings.Length; i++) {
  568. if (!mappings[i].TypeDesc.IsValueType)
  569. continue;
  570. LocalBuilder arrayLoc = ilg.GetLocal(arrayName);
  571. ilg.Ldloc(arrayLoc);
  572. ilg.Ldc(i);
  573. RaCodeGen.ILGenForCreateInstance(ilg, mappings[i].TypeDesc.Type, false, false);
  574. ilg.ConvertValue(mappings[i].TypeDesc.Type, typeof(object));
  575. ilg.Stelem(arrayLoc.LocalType.GetElementType());
  576. }
  577. }
  578. string GenerateTypeElement(XmlTypeMapping xmlTypeMapping) {
  579. ElementAccessor element = xmlTypeMapping.Accessor;
  580. TypeMapping mapping = element.Mapping;
  581. string methodName = NextMethodName(element.Name);
  582. ilg = new CodeGenerator(this.typeBuilder);
  583. ilg.BeginMethod(
  584. typeof(object),
  585. methodName,
  586. CodeGenerator.EmptyTypeArray,
  587. CodeGenerator.EmptyStringArray,
  588. CodeGenerator.PublicMethodAttributes
  589. );
  590. LocalBuilder oLoc = ilg.DeclareLocal(typeof(object), "o");
  591. ilg.Load(null);
  592. ilg.Stloc(oLoc);
  593. MemberMapping member = new MemberMapping();
  594. member.TypeDesc = mapping.TypeDesc;
  595. //member.ReadOnly = !mapping.TypeDesc.HasDefaultConstructor;
  596. member.Elements = new ElementAccessor[] { element };
  597. Member[] members = new Member[] { new Member(this, "o", "o", "a", 0, member) };
  598. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  599. "get_Reader",
  600. CodeGenerator.InstanceBindingFlags,
  601. null,
  602. CodeGenerator.EmptyTypeArray,
  603. null
  604. );
  605. MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
  606. "MoveToContent",
  607. CodeGenerator.InstanceBindingFlags,
  608. null,
  609. CodeGenerator.EmptyTypeArray,
  610. null
  611. );
  612. ilg.Ldarg(0);
  613. ilg.Call(XmlSerializationReader_get_Reader);
  614. ilg.Call(XmlReader_MoveToContent);
  615. ilg.Pop();
  616. string unknownNode = "UnknownNode(null, " + ExpectedElements(members) + ");";
  617. WriteMemberElements(members, "throw CreateUnknownNodeException();", unknownNode, element.Any ? members[0] : null, null);
  618. ilg.Ldloc(oLoc);
  619. // for code compat as compiler does
  620. ilg.Stloc(ilg.ReturnLocal);
  621. ilg.Ldloc(ilg.ReturnLocal);
  622. ilg.EndMethod();
  623. return methodName;
  624. }
  625. string NextMethodName(string name) {
  626. return "Read" + (++NextMethodNumber).ToString(CultureInfo.InvariantCulture) + "_" + CodeIdentifier.MakeValidInternal(name);
  627. }
  628. string NextIdName(string name) {
  629. return "id" + (++nextIdNumber).ToString(CultureInfo.InvariantCulture) + "_" + CodeIdentifier.MakeValidInternal(name);
  630. }
  631. void WritePrimitive(TypeMapping mapping, string source) {
  632. System.Diagnostics.Debug.Assert(source == "Reader.ReadElementString()" || source == "Reader.ReadString()"
  633. || source == "false" || source == "Reader.Value" || source == "vals[i]");
  634. if (mapping is EnumMapping) {
  635. string enumMethodName = ReferenceMapping(mapping);
  636. if (enumMethodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlMissingMethodEnum, mapping.TypeDesc.Name));
  637. // For enum, its read method (eg. Read1_Gender) could be called multiple times
  638. // prior to its declaration.
  639. MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
  640. enumMethodName,
  641. CodeGenerator.PrivateMethodAttributes,
  642. mapping.TypeDesc.Type,
  643. new Type[] { typeof(string) }
  644. );
  645. ilg.Ldarg(0);
  646. if (source == "Reader.ReadElementString()" || source == "Reader.ReadString()") {
  647. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  648. "get_Reader",
  649. CodeGenerator.InstanceBindingFlags,
  650. null,
  651. CodeGenerator.EmptyTypeArray,
  652. null
  653. );
  654. MethodInfo XmlReader_ReadXXXString = typeof(XmlReader).GetMethod(
  655. source == "Reader.ReadElementString()" ? "ReadElementString" : "ReadString",
  656. CodeGenerator.InstanceBindingFlags,
  657. null,
  658. CodeGenerator.EmptyTypeArray,
  659. null
  660. );
  661. ilg.Ldarg(0);
  662. ilg.Call(XmlSerializationReader_get_Reader);
  663. ilg.Call(XmlReader_ReadXXXString);
  664. }
  665. else if (source == "Reader.Value") {
  666. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  667. "get_Reader",
  668. CodeGenerator.InstanceBindingFlags,
  669. null,
  670. CodeGenerator.EmptyTypeArray,
  671. null
  672. );
  673. MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
  674. "get_Value",
  675. CodeGenerator.InstanceBindingFlags,
  676. null,
  677. CodeGenerator.EmptyTypeArray,
  678. null
  679. );
  680. ilg.Ldarg(0);
  681. ilg.Call(XmlSerializationReader_get_Reader);
  682. ilg.Call(XmlReader_get_Value);
  683. }
  684. else if (source == "vals[i]") {
  685. LocalBuilder locVals = ilg.GetLocal("vals");
  686. LocalBuilder locI = ilg.GetLocal("i");
  687. ilg.LoadArrayElement(locVals, locI);
  688. }
  689. else if (source == "false") {
  690. ilg.Ldc(false);
  691. }
  692. else {
  693. throw CodeGenerator.NotSupported("Unexpected: " + source);
  694. }
  695. ilg.Call(methodBuilder);
  696. }
  697. else if (mapping.TypeDesc == StringTypeDesc) {
  698. if (source == "Reader.ReadElementString()" || source == "Reader.ReadString()") {
  699. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  700. "get_Reader",
  701. CodeGenerator.InstanceBindingFlags,
  702. null,
  703. CodeGenerator.EmptyTypeArray,
  704. null
  705. );
  706. MethodInfo XmlReader_ReadXXXString = typeof(XmlReader).GetMethod(
  707. source == "Reader.ReadElementString()" ? "ReadElementString" : "ReadString",
  708. CodeGenerator.InstanceBindingFlags,
  709. null,
  710. CodeGenerator.EmptyTypeArray,
  711. null
  712. );
  713. ilg.Ldarg(0);
  714. ilg.Call(XmlSerializationReader_get_Reader);
  715. ilg.Call(XmlReader_ReadXXXString);
  716. }
  717. else if (source == "Reader.Value") {
  718. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  719. "get_Reader",
  720. CodeGenerator.InstanceBindingFlags,
  721. null,
  722. CodeGenerator.EmptyTypeArray,
  723. null
  724. );
  725. MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
  726. "get_Value",
  727. CodeGenerator.InstanceBindingFlags,
  728. null,
  729. CodeGenerator.EmptyTypeArray,
  730. null
  731. );
  732. ilg.Ldarg(0);
  733. ilg.Call(XmlSerializationReader_get_Reader);
  734. ilg.Call(XmlReader_get_Value);
  735. }
  736. else if (source == "vals[i]") {
  737. LocalBuilder locVals = ilg.GetLocal("vals");
  738. LocalBuilder locI = ilg.GetLocal("i");
  739. ilg.LoadArrayElement(locVals, locI);
  740. }
  741. else {
  742. throw CodeGenerator.NotSupported("Unexpected: " + source);
  743. }
  744. }
  745. else if (mapping.TypeDesc.FormatterName == "String") {
  746. if (source == "vals[i]") {
  747. if (mapping.TypeDesc.CollapseWhitespace)
  748. ilg.Ldarg(0);
  749. LocalBuilder locVals = ilg.GetLocal("vals");
  750. LocalBuilder locI = ilg.GetLocal("i");
  751. ilg.LoadArrayElement(locVals, locI);
  752. if (mapping.TypeDesc.CollapseWhitespace) {
  753. MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod(
  754. "CollapseWhitespace",
  755. CodeGenerator.InstanceBindingFlags,
  756. null,
  757. new Type[] { typeof(String) },
  758. null
  759. );
  760. ilg.Call(XmlSerializationReader_CollapseWhitespace);
  761. }
  762. }
  763. else {
  764. System.Diagnostics.Debug.Assert(source == "Reader.Value" || source == "Reader.ReadElementString()");
  765. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  766. "get_Reader",
  767. CodeGenerator.InstanceBindingFlags,
  768. null,
  769. CodeGenerator.EmptyTypeArray,
  770. null
  771. );
  772. MethodInfo XmlReader_method = typeof(XmlReader).GetMethod(
  773. source == "Reader.Value" ? "get_Value" : "ReadElementString",
  774. CodeGenerator.InstanceBindingFlags,
  775. null,
  776. CodeGenerator.EmptyTypeArray,
  777. null
  778. );
  779. if (mapping.TypeDesc.CollapseWhitespace)
  780. ilg.Ldarg(0);
  781. ilg.Ldarg(0);
  782. ilg.Call(XmlSerializationReader_get_Reader);
  783. ilg.Call(XmlReader_method);
  784. if (mapping.TypeDesc.CollapseWhitespace) {
  785. MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod(
  786. "CollapseWhitespace",
  787. CodeGenerator.InstanceBindingFlags,
  788. null,
  789. new Type[] { typeof(String) },
  790. null
  791. );
  792. ilg.Call(XmlSerializationReader_CollapseWhitespace);
  793. }
  794. }
  795. }
  796. else {
  797. Type argType = source == "false" ? typeof(Boolean) : typeof(String);
  798. MethodInfo ToXXX;
  799. if (mapping.TypeDesc.HasCustomFormatter) {
  800. // Only these methods below that is non Static and need to ldarg("this") for Call.
  801. BindingFlags bindingFlags = CodeGenerator.StaticBindingFlags;
  802. if ((mapping.TypeDesc.FormatterName == "ByteArrayBase64" && source == "false")
  803. || (mapping.TypeDesc.FormatterName == "ByteArrayHex" && source == "false")
  804. || (mapping.TypeDesc.FormatterName == "XmlQualifiedName")) {
  805. bindingFlags = CodeGenerator.InstanceBindingFlags;
  806. ilg.Ldarg(0);
  807. }
  808. ToXXX = typeof(XmlSerializationReader).GetMethod(
  809. "To" + mapping.TypeDesc.FormatterName,
  810. bindingFlags,
  811. null,
  812. new Type[] { argType },
  813. null
  814. );
  815. }
  816. else {
  817. ToXXX = typeof(XmlConvert).GetMethod(
  818. "To" + mapping.TypeDesc.FormatterName,
  819. CodeGenerator.StaticBindingFlags,
  820. null,
  821. new Type[] { argType },
  822. null
  823. );
  824. }
  825. if (source == "Reader.ReadElementString()" || source == "Reader.ReadString()") {
  826. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  827. "get_Reader",
  828. CodeGenerator.InstanceBindingFlags,
  829. null,
  830. CodeGenerator.EmptyTypeArray,
  831. null
  832. );
  833. MethodInfo XmlReader_ReadXXXString = typeof(XmlReader).GetMethod(
  834. source == "Reader.ReadElementString()" ? "ReadElementString" : "ReadString",
  835. CodeGenerator.InstanceBindingFlags,
  836. null,
  837. CodeGenerator.EmptyTypeArray,
  838. null
  839. );
  840. ilg.Ldarg(0);
  841. ilg.Call(XmlSerializationReader_get_Reader);
  842. ilg.Call(XmlReader_ReadXXXString);
  843. }
  844. else if (source == "Reader.Value") {
  845. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  846. "get_Reader",
  847. CodeGenerator.InstanceBindingFlags,
  848. null,
  849. CodeGenerator.EmptyTypeArray,
  850. null
  851. );
  852. MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
  853. "get_Value",
  854. CodeGenerator.InstanceBindingFlags,
  855. null,
  856. CodeGenerator.EmptyTypeArray,
  857. null
  858. );
  859. ilg.Ldarg(0);
  860. ilg.Call(XmlSerializationReader_get_Reader);
  861. ilg.Call(XmlReader_get_Value);
  862. }
  863. else if (source == "vals[i]") {
  864. LocalBuilder locVals = ilg.GetLocal("vals");
  865. LocalBuilder locI = ilg.GetLocal("i");
  866. ilg.LoadArrayElement(locVals, locI);
  867. }
  868. else {
  869. System.Diagnostics.Debug.Assert(source == "false");
  870. ilg.Ldc(false);
  871. }
  872. ilg.Call(ToXXX);
  873. }
  874. }
  875. string MakeUnique(EnumMapping mapping, string name) {
  876. string uniqueName = name;
  877. object m = Enums[uniqueName];
  878. if (m != null) {
  879. if (m == mapping) {
  880. // we already have created the hashtable
  881. return null;
  882. }
  883. int i = 0;
  884. while (m != null) {
  885. i++;
  886. uniqueName = name + i.ToString(CultureInfo.InvariantCulture);
  887. m = Enums[uniqueName];
  888. }
  889. }
  890. Enums.Add(uniqueName, mapping);
  891. return uniqueName;
  892. }
  893. string WriteHashtable(EnumMapping mapping, string typeName, out MethodBuilder get_TableName) {
  894. get_TableName = null;
  895. CodeIdentifier.CheckValidIdentifier(typeName);
  896. string propName = MakeUnique(mapping, typeName + "Values");
  897. if (propName == null) return CodeIdentifier.GetCSharpName(typeName);
  898. string memberName = MakeUnique(mapping, "_" + propName);
  899. propName = CodeIdentifier.GetCSharpName(propName);
  900. FieldBuilder fieldBuilder = this.typeBuilder.DefineField(
  901. memberName,
  902. typeof(Hashtable),
  903. FieldAttributes.Private
  904. );
  905. PropertyBuilder propertyBuilder = this.typeBuilder.DefineProperty(
  906. propName,
  907. PropertyAttributes.None,
  908. CallingConventions.HasThis,
  909. typeof(Hashtable),
  910. null, null, null, null, null);
  911. ilg = new CodeGenerator(this.typeBuilder);
  912. ilg.BeginMethod(
  913. typeof(Hashtable),
  914. "get_" + propName,
  915. CodeGenerator.EmptyTypeArray,
  916. CodeGenerator.EmptyStringArray,
  917. MethodAttributes.Assembly | MethodAttributes.HideBySig | MethodAttributes.SpecialName);
  918. ilg.Ldarg(0);
  919. ilg.LoadMember(fieldBuilder);
  920. ilg.Load(null);
  921. ilg.If(Cmp.EqualTo);
  922. ConstructorInfo Hashtable_ctor = typeof(Hashtable).GetConstructor(
  923. CodeGenerator.InstanceBindingFlags,
  924. null,
  925. CodeGenerator.EmptyTypeArray,
  926. null
  927. );
  928. LocalBuilder hLoc = ilg.DeclareLocal(typeof(Hashtable), "h");
  929. ilg.New(Hashtable_ctor);
  930. ilg.Stloc(hLoc);
  931. ConstantMapping[] constants = mapping.Constants;
  932. MethodInfo Hashtable_Add = typeof(Hashtable).GetMethod(
  933. "Add",
  934. CodeGenerator.InstanceBindingFlags,
  935. null,
  936. new Type[] { typeof(Object), typeof(Object) },
  937. null
  938. );
  939. for (int i = 0; i < constants.Length; i++) {
  940. ilg.Ldloc(hLoc);
  941. ilg.Ldstr(constants[i].XmlName);
  942. ilg.Ldc(Enum.ToObject(mapping.TypeDesc.Type, constants[i].Value));
  943. ilg.ConvertValue(mapping.TypeDesc.Type, typeof(long));
  944. ilg.ConvertValue(typeof(long), typeof(Object));
  945. ilg.Call(Hashtable_Add);
  946. }
  947. ilg.Ldarg(0);
  948. ilg.Ldloc(hLoc);
  949. ilg.StoreMember(fieldBuilder);
  950. ilg.EndIf();
  951. ilg.Ldarg(0);
  952. ilg.LoadMember(fieldBuilder);
  953. get_TableName = ilg.EndMethod();
  954. propertyBuilder.SetGetMethod(get_TableName);
  955. return propName;
  956. }
  957. void WriteEnumMethod(EnumMapping mapping) {
  958. MethodBuilder get_TableName = null;
  959. if (mapping.IsFlags)
  960. WriteHashtable(mapping, mapping.TypeDesc.Name, out get_TableName);
  961. string methodName = (string)MethodNames[mapping];
  962. string fullTypeName = mapping.TypeDesc.CSharpName;
  963. List<Type> argTypes = new List<Type>();
  964. List<string> argNames = new List<string>();
  965. Type returnType;
  966. Type underlyingType;
  967. returnType = mapping.TypeDesc.Type;
  968. underlyingType = Enum.GetUnderlyingType(returnType);
  969. argTypes.Add(typeof(string));
  970. argNames.Add("s");
  971. ilg = new CodeGenerator(this.typeBuilder);
  972. ilg.BeginMethod(
  973. returnType,
  974. GetMethodBuilder(methodName),
  975. argTypes.ToArray(),
  976. argNames.ToArray(),
  977. CodeGenerator.PrivateMethodAttributes);
  978. ConstantMapping[] constants = mapping.Constants;
  979. if (mapping.IsFlags) {
  980. {
  981. MethodInfo XmlSerializationReader_ToEnum = typeof(XmlSerializationReader).GetMethod(
  982. "ToEnum",
  983. CodeGenerator.StaticBindingFlags,
  984. null,
  985. new Type[] { typeof(String), typeof(Hashtable), typeof(String) },
  986. null
  987. );
  988. ilg.Ldarg("s");
  989. ilg.Ldarg(0);
  990. Debug.Assert(get_TableName != null);
  991. ilg.Call(get_TableName);
  992. ilg.Ldstr(fullTypeName);
  993. ilg.Call(XmlSerializationReader_ToEnum);
  994. // XmlSerializationReader_ToEnum return long!
  995. if (underlyingType != typeof(long)) {
  996. ilg.ConvertValue(typeof(long), underlyingType);
  997. }
  998. ilg.Stloc(ilg.ReturnLocal);
  999. ilg.Br(ilg.ReturnLabel);
  1000. }
  1001. }
  1002. else {
  1003. List<Label> caseLabels = new List<Label>();
  1004. List<object> retValues = new List<object>();
  1005. Label defaultLabel = ilg.DefineLabel();
  1006. Label endSwitchLabel = ilg.DefineLabel();
  1007. // This local is necessary; otherwise, it becomes if/else
  1008. LocalBuilder localTmp = ilg.GetTempLocal(typeof(string));
  1009. ilg.Ldarg("s");
  1010. ilg.Stloc(localTmp);
  1011. ilg.Ldloc(localTmp);
  1012. ilg.Brfalse(defaultLabel);
  1013. Hashtable cases = new Hashtable();
  1014. for (int i = 0; i < constants.Length; i++) {
  1015. ConstantMapping c = constants[i];
  1016. CodeIdentifier.CheckValidIdentifier(c.Name);
  1017. if (cases[c.XmlName] == null) {
  1018. cases[c.XmlName] = c.XmlName;
  1019. Label caseLabel = ilg.DefineLabel();
  1020. ilg.Ldloc(localTmp);
  1021. ilg.Ldstr(c.XmlName);
  1022. MethodInfo String_op_Equality = typeof(string).GetMethod(
  1023. "op_Equality",
  1024. CodeGenerator.StaticBindingFlags,
  1025. null,
  1026. new Type[] { typeof(string), typeof(string) },
  1027. null
  1028. );
  1029. ilg.Call(String_op_Equality);
  1030. ilg.Brtrue(caseLabel);
  1031. caseLabels.Add(caseLabel);
  1032. retValues.Add(Enum.ToObject(mapping.TypeDesc.Type, c.Value));
  1033. }
  1034. }
  1035. ilg.Br(defaultLabel);
  1036. // Case bodies
  1037. for (int i = 0; i < caseLabels.Count; i++) {
  1038. ilg.MarkLabel(caseLabels[i]);
  1039. ilg.Ldc(retValues[i]);
  1040. ilg.Stloc(ilg.ReturnLocal);
  1041. ilg.Br(ilg.ReturnLabel);
  1042. }
  1043. MethodInfo XmlSerializationReader_CreateUnknownConstantException = typeof(XmlSerializationReader).GetMethod(
  1044. "CreateUnknownConstantException",
  1045. CodeGenerator.InstanceBindingFlags,
  1046. null,
  1047. new Type[] { typeof(string), typeof(Type) },
  1048. null
  1049. );
  1050. // Default body
  1051. ilg.MarkLabel(defaultLabel);
  1052. ilg.Ldarg(0);
  1053. ilg.Ldarg("s");
  1054. // typeof(..)
  1055. ilg.Ldc(mapping.TypeDesc.Type);
  1056. ilg.Call(XmlSerializationReader_CreateUnknownConstantException);
  1057. ilg.Throw();
  1058. // End switch
  1059. ilg.MarkLabel(endSwitchLabel);
  1060. }
  1061. ilg.MarkLabel(ilg.ReturnLabel);
  1062. ilg.Ldloc(ilg.ReturnLocal);
  1063. ilg.EndMethod();
  1064. }
  1065. void WriteDerivedTypes(StructMapping mapping, bool isTypedReturn, string returnTypeName) {
  1066. for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) {
  1067. ilg.InitElseIf();
  1068. WriteQNameEqual("xsiType", derived.TypeName, derived.Namespace);
  1069. ilg.AndIf();
  1070. string methodName = ReferenceMapping(derived);
  1071. #if DEBUG
  1072. // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  1073. if (methodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, derived.TypeDesc.Name));
  1074. #endif
  1075. List<Type> argTypes = new List<Type>();
  1076. ilg.Ldarg(0);
  1077. if (derived.TypeDesc.IsNullable) {
  1078. ilg.Ldarg("isNullable");
  1079. argTypes.Add(typeof(Boolean));
  1080. }
  1081. ilg.Ldc(false);
  1082. argTypes.Add(typeof(Boolean));
  1083. MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
  1084. methodName,
  1085. CodeGenerator.PrivateMethodAttributes,
  1086. derived.TypeDesc.Type,
  1087. argTypes.ToArray()
  1088. );
  1089. ilg.Call(methodBuilder);
  1090. ilg.ConvertValue(methodBuilder.ReturnType, ilg.ReturnLocal.LocalType);
  1091. ilg.Stloc(ilg.ReturnLocal);
  1092. ilg.Br(ilg.ReturnLabel);
  1093. WriteDerivedTypes(derived, isTypedReturn, returnTypeName);
  1094. }
  1095. }
  1096. void WriteEnumAndArrayTypes() {
  1097. foreach (TypeScope scope in Scopes) {
  1098. foreach (Mapping m in scope.TypeMappings) {
  1099. if (m is EnumMapping) {
  1100. EnumMapping mapping = (EnumMapping)m;
  1101. ilg.InitElseIf();
  1102. WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace);
  1103. ilg.AndIf();
  1104. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  1105. "get_Reader",
  1106. CodeGenerator.InstanceBindingFlags,
  1107. null,
  1108. CodeGenerator.EmptyTypeArray,
  1109. null
  1110. );
  1111. MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
  1112. "ReadStartElement",
  1113. CodeGenerator.InstanceBindingFlags,
  1114. null,
  1115. CodeGenerator.EmptyTypeArray,
  1116. null
  1117. );
  1118. ilg.Ldarg(0);
  1119. ilg.Call(XmlSerializationReader_get_Reader);
  1120. ilg.Call(XmlReader_ReadStartElement);
  1121. string methodName = ReferenceMapping(mapping);
  1122. #if DEBUG
  1123. // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  1124. if (methodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name));
  1125. #endif
  1126. LocalBuilder eLoc = ilg.DeclareOrGetLocal(typeof(object), "e");
  1127. MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
  1128. methodName,
  1129. CodeGenerator.PrivateMethodAttributes,
  1130. mapping.TypeDesc.Type,
  1131. new Type[] { typeof(string) }
  1132. );
  1133. MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod(
  1134. "CollapseWhitespace",
  1135. CodeGenerator.InstanceBindingFlags,
  1136. null,
  1137. new Type[] { typeof(String) },
  1138. null
  1139. );
  1140. MethodInfo XmlReader_ReadString = typeof(XmlReader).GetMethod(
  1141. "ReadString",
  1142. CodeGenerator.InstanceBindingFlags,
  1143. null,
  1144. CodeGenerator.EmptyTypeArray,
  1145. null
  1146. );
  1147. ilg.Ldarg(0);
  1148. ilg.Ldarg(0);
  1149. ilg.Ldarg(0);
  1150. ilg.Call(XmlSerializationReader_get_Reader);
  1151. ilg.Call(XmlReader_ReadString);
  1152. ilg.Call(XmlSerializationReader_CollapseWhitespace);
  1153. ilg.Call(methodBuilder);
  1154. ilg.ConvertValue(methodBuilder.ReturnType, eLoc.LocalType);
  1155. ilg.Stloc(eLoc);
  1156. MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
  1157. "ReadEndElement",
  1158. CodeGenerator.InstanceBindingFlags,
  1159. null,
  1160. CodeGenerator.EmptyTypeArray,
  1161. null
  1162. );
  1163. ilg.Ldarg(0);
  1164. ilg.Call(XmlSerializationReader_ReadEndElement);
  1165. ilg.Ldloc(eLoc);
  1166. ilg.Stloc(ilg.ReturnLocal);
  1167. ilg.Br(ilg.ReturnLabel);
  1168. // Caller own calling ilg.EndIf();
  1169. }
  1170. else if (m is ArrayMapping) {
  1171. ArrayMapping mapping = (ArrayMapping)m;
  1172. if (mapping.TypeDesc.HasDefaultConstructor) {
  1173. ilg.InitElseIf();
  1174. WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace);
  1175. ilg.AndIf();
  1176. ilg.EnterScope();
  1177. MemberMapping memberMapping = new MemberMapping();
  1178. memberMapping.TypeDesc = mapping.TypeDesc;
  1179. memberMapping.Elements = mapping.Elements;
  1180. string aVar = "a";
  1181. string zVar = "z";
  1182. Member member = new Member(this, aVar, zVar, 0, memberMapping);
  1183. TypeDesc td = mapping.TypeDesc;
  1184. LocalBuilder aLoc = ilg.DeclareLocal(mapping.TypeDesc.Type, aVar);
  1185. if (mapping.TypeDesc.IsValueType) {
  1186. RaCodeGen.ILGenForCreateInstance(ilg, td.Type, false, false);
  1187. }
  1188. else
  1189. ilg.Load(null);
  1190. ilg.Stloc(aLoc);
  1191. WriteArray(member.Source, member.ArrayName, mapping, false, false, -1, 0);
  1192. ilg.Ldloc(aLoc);
  1193. ilg.Stloc(ilg.ReturnLocal);
  1194. ilg.Br(ilg.ReturnLabel);
  1195. ilg.ExitScope();
  1196. // Caller own calling ilg.EndIf();
  1197. }
  1198. }
  1199. }
  1200. }
  1201. }
  1202. void WriteNullableMethod(NullableMapping nullableMapping) {
  1203. string methodName = (string)MethodNames[nullableMapping];
  1204. ilg = new CodeGenerator(this.typeBuilder);
  1205. ilg.BeginMethod(
  1206. nullableMapping.TypeDesc.Type,
  1207. GetMethodBuilder(methodName),
  1208. new Type[] { typeof(Boolean) },
  1209. new string[] { "checkType" },
  1210. CodeGenerator.PrivateMethodAttributes);
  1211. LocalBuilder oLoc = ilg.DeclareLocal(nullableMapping.TypeDesc.Type, "o");
  1212. ilg.LoadAddress(oLoc);
  1213. ilg.InitObj(nullableMapping.TypeDesc.Type);
  1214. MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
  1215. "ReadNull",
  1216. CodeGenerator.InstanceBindingFlags,
  1217. null,
  1218. CodeGenerator.EmptyTypeArray,
  1219. null);
  1220. ilg.Ldarg(0);
  1221. ilg.Call(XmlSerializationReader_ReadNull);
  1222. ilg.If();
  1223. {
  1224. ilg.Ldloc(oLoc);
  1225. ilg.Stloc(ilg.ReturnLocal);
  1226. ilg.Br(ilg.ReturnLabel);
  1227. }
  1228. ilg.EndIf();
  1229. ElementAccessor element = new ElementAccessor();
  1230. element.Mapping = nullableMapping.BaseMapping;
  1231. element.Any = false;
  1232. element.IsNullable = nullableMapping.BaseMapping.TypeDesc.IsNullable;
  1233. WriteElement("o", null, null, element, null, null, false, false, -1, -1);
  1234. ilg.Ldloc(oLoc);
  1235. ilg.Stloc(ilg.ReturnLocal);
  1236. ilg.Br(ilg.ReturnLabel);
  1237. ilg.MarkLabel(ilg.ReturnLabel);
  1238. ilg.Ldloc(ilg.ReturnLocal);
  1239. ilg.EndMethod();
  1240. }
  1241. void WriteStructMethod(StructMapping structMapping) {
  1242. WriteLiteralStructMethod(structMapping);
  1243. }
  1244. void WriteLiteralStructMethod(StructMapping structMapping) {
  1245. string methodName = (string)MethodNames[structMapping];
  1246. string typeName = structMapping.TypeDesc.CSharpName;
  1247. ilg = new CodeGenerator(this.typeBuilder);
  1248. List<Type> argTypes = new List<Type>();
  1249. List<string> argNames = new List<string>();
  1250. if (structMapping.TypeDesc.IsNullable) {
  1251. argTypes.Add(typeof(Boolean));
  1252. argNames.Add("isNullable");
  1253. }
  1254. argTypes.Add(typeof(Boolean));
  1255. argNames.Add("checkType");
  1256. ilg.BeginMethod(
  1257. structMapping.TypeDesc.Type,
  1258. GetMethodBuilder(methodName),
  1259. argTypes.ToArray(),
  1260. argNames.ToArray(),
  1261. CodeGenerator.PrivateMethodAttributes);
  1262. LocalBuilder locXsiType = ilg.DeclareLocal(typeof(XmlQualifiedName), "xsiType");
  1263. LocalBuilder locIsNull = ilg.DeclareLocal(typeof(Boolean), "isNull");
  1264. MethodInfo XmlSerializationReader_GetXsiType = typeof(XmlSerializationReader).GetMethod(
  1265. "GetXsiType",
  1266. CodeGenerator.InstanceBindingFlags,
  1267. null,
  1268. CodeGenerator.EmptyTypeArray,
  1269. null
  1270. );
  1271. MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
  1272. "ReadNull",
  1273. CodeGenerator.InstanceBindingFlags,
  1274. null,
  1275. CodeGenerator.EmptyTypeArray,
  1276. null
  1277. );
  1278. Label labelTrue = ilg.DefineLabel();
  1279. Label labelEnd = ilg.DefineLabel();
  1280. ilg.Ldarg("checkType");
  1281. ilg.Brtrue(labelTrue);
  1282. ilg.Load(null);
  1283. ilg.Br_S(labelEnd);
  1284. ilg.MarkLabel(labelTrue);
  1285. ilg.Ldarg(0);
  1286. ilg.Call(XmlSerializationReader_GetXsiType);
  1287. ilg.MarkLabel(labelEnd);
  1288. ilg.Stloc(locXsiType);
  1289. ilg.Ldc(false);
  1290. ilg.Stloc(locIsNull);
  1291. if (structMapping.TypeDesc.IsNullable) {
  1292. ilg.Ldarg("isNullable");
  1293. ilg.If();
  1294. {
  1295. ilg.Ldarg(0);
  1296. ilg.Call(XmlSerializationReader_ReadNull);
  1297. ilg.Stloc(locIsNull);
  1298. }
  1299. ilg.EndIf();
  1300. }
  1301. ilg.Ldarg("checkType");
  1302. ilg.If(); // if (checkType)
  1303. if (structMapping.TypeDesc.IsRoot) {
  1304. ilg.Ldloc(locIsNull);
  1305. ilg.If();
  1306. ilg.Ldloc(locXsiType);
  1307. ilg.Load(null);
  1308. ilg.If(Cmp.NotEqualTo);
  1309. MethodInfo XmlSerializationReader_ReadTypedNull = typeof(XmlSerializationReader).GetMethod(
  1310. "ReadTypedNull",
  1311. CodeGenerator.InstanceBindingFlags,
  1312. null,
  1313. new Type[] { locXsiType.LocalType },
  1314. null
  1315. );
  1316. ilg.Ldarg(0);
  1317. ilg.Ldloc(locXsiType);
  1318. ilg.Call(XmlSerializationReader_ReadTypedNull);
  1319. ilg.Stloc(ilg.ReturnLocal);
  1320. ilg.Br(ilg.ReturnLabel);
  1321. ilg.Else();
  1322. if (structMapping.TypeDesc.IsValueType) {
  1323. throw CodeGenerator.NotSupported("Arg_NeverValueType");
  1324. }
  1325. else {
  1326. ilg.Load(null);
  1327. ilg.Stloc(ilg.ReturnLocal);
  1328. ilg.Br(ilg.ReturnLabel);
  1329. }
  1330. ilg.EndIf(); // if (xsiType != null)
  1331. ilg.EndIf(); // if (isNull)
  1332. }
  1333. ilg.Ldloc(typeof(XmlQualifiedName), "xsiType");
  1334. ilg.Load(null);
  1335. ilg.Ceq();
  1336. if (!structMapping.TypeDesc.IsRoot) {
  1337. labelTrue = ilg.DefineLabel();
  1338. labelEnd = ilg.DefineLabel();
  1339. // xsiType == null
  1340. ilg.Brtrue(labelTrue);
  1341. WriteQNameEqual("xsiType", structMapping.TypeName, structMapping.Namespace);
  1342. // Bool result for WriteQNameEqual is on the stack
  1343. ilg.Br_S(labelEnd);
  1344. ilg.MarkLabel(labelTrue);
  1345. ilg.Ldc(true);
  1346. ilg.MarkLabel(labelEnd);
  1347. }
  1348. ilg.If(); // if (xsiType == null
  1349. if (structMapping.TypeDesc.IsRoot) {
  1350. ConstructorInfo XmlQualifiedName_ctor = typeof(XmlQualifiedName).GetConstructor(
  1351. CodeGenerator.InstanceBindingFlags,
  1352. null,
  1353. new Type[] { typeof(String), typeof(String) },
  1354. null
  1355. );
  1356. MethodInfo XmlSerializationReader_ReadTypedPrimitive = typeof(XmlSerializationReader).GetMethod(
  1357. "ReadTypedPrimitive",
  1358. CodeGenerator.InstanceBindingFlags,
  1359. null,
  1360. new Type[] { typeof(XmlQualifiedName) },
  1361. null
  1362. );
  1363. ilg.Ldarg(0);
  1364. ilg.Ldstr(Soap.UrType);
  1365. ilg.Ldstr(XmlSchema.Namespace);
  1366. ilg.New(XmlQualifiedName_ctor);
  1367. ilg.Call(XmlSerializationReader_ReadTypedPrimitive);
  1368. ilg.Stloc(ilg.ReturnLocal);
  1369. ilg.Br(ilg.ReturnLabel);
  1370. }
  1371. WriteDerivedTypes(structMapping, !structMapping.TypeDesc.IsRoot, typeName);
  1372. if (structMapping.TypeDesc.IsRoot) WriteEnumAndArrayTypes();
  1373. ilg.Else(); // if (xsiType == null
  1374. if (structMapping.TypeDesc.IsRoot) {
  1375. MethodInfo XmlSerializationReader_ReadTypedPrimitive = typeof(XmlSerializationReader).GetMethod(
  1376. "ReadTypedPrimitive",
  1377. CodeGenerator.InstanceBindingFlags,
  1378. null,
  1379. new Type[] { locXsiType.LocalType },
  1380. null
  1381. );
  1382. ilg.Ldarg(0);
  1383. ilg.Ldloc(locXsiType);
  1384. ilg.Call(XmlSerializationReader_ReadTypedPrimitive);
  1385. ilg.Stloc(ilg.ReturnLocal);
  1386. ilg.Br(ilg.ReturnLabel);
  1387. }
  1388. else {
  1389. MethodInfo XmlSerializationReader_CreateUnknownTypeException = typeof(XmlSerializationReader).GetMethod(
  1390. "CreateUnknownTypeException",
  1391. CodeGenerator.InstanceBindingFlags,
  1392. null,
  1393. new Type[] { typeof(XmlQualifiedName) },
  1394. null
  1395. );
  1396. ilg.Ldarg(0);
  1397. ilg.Ldloc(locXsiType);
  1398. ilg.Call(XmlSerializationReader_CreateUnknownTypeException);
  1399. ilg.Throw();
  1400. }
  1401. ilg.EndIf(); // if (xsiType == null
  1402. ilg.EndIf(); // checkType
  1403. if (structMapping.TypeDesc.IsNullable) {
  1404. ilg.Ldloc(typeof(bool), "isNull");
  1405. ilg.If();
  1406. {
  1407. ilg.Load(null);
  1408. ilg.Stloc(ilg.ReturnLocal);
  1409. ilg.Br(ilg.ReturnLabel);
  1410. }
  1411. ilg.EndIf();
  1412. }
  1413. if (structMapping.TypeDesc.IsAbstract) {
  1414. MethodInfo XmlSerializationReader_CreateAbstractTypeException = typeof(XmlSerializationReader).GetMethod(
  1415. "CreateAbstractTypeException",
  1416. CodeGenerator.InstanceBindingFlags,
  1417. null,
  1418. new Type[] { typeof(String), typeof(String) },
  1419. null
  1420. );
  1421. ilg.Ldarg(0);
  1422. ilg.Ldstr(structMapping.TypeName);
  1423. ilg.Ldstr(structMapping.Namespace);
  1424. ilg.Call(XmlSerializationReader_CreateAbstractTypeException);
  1425. ilg.Throw();
  1426. }
  1427. else {
  1428. if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type)) {
  1429. MethodInfo XmlSerializationReader_set_DecodeName = typeof(XmlSerializationReader).GetMethod(
  1430. "set_DecodeName",
  1431. CodeGenerator.InstanceBindingFlags,
  1432. null,
  1433. new Type[] { typeof(Boolean) },
  1434. null
  1435. );
  1436. ilg.Ldarg(0);
  1437. ilg.Ldc(false);
  1438. ilg.Call(XmlSerializationReader_set_DecodeName);
  1439. }
  1440. WriteCreateMapping(structMapping, "o");
  1441. LocalBuilder oLoc = ilg.GetLocal("o");
  1442. // this method populates the memberInfos dictionary based on the structMapping
  1443. MemberMapping[] mappings = TypeScope.GetSettableMembers(structMapping, memberInfos);
  1444. Member anyText = null;
  1445. Member anyElement = null;
  1446. Member anyAttribute = null;
  1447. bool isSequence = structMapping.HasExplicitSequence();
  1448. ArrayList arraysToDeclareList = new ArrayList(mappings.Length);
  1449. ArrayList arraysToSetList = new ArrayList(mappings.Length);
  1450. ArrayList allMembersList = new ArrayList(mappings.Length);
  1451. for (int i = 0; i < mappings.Length; i++) {
  1452. MemberMapping mapping = mappings[i];
  1453. CodeIdentifier.CheckValidIdentifier(mapping.Name);
  1454. string source = RaCodeGen.GetStringForMember("o", mapping.Name, structMapping.TypeDesc);
  1455. Member member = new Member(this, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
  1456. if (!mapping.IsSequence)
  1457. member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  1458. member.IsNullable = mapping.TypeDesc.IsNullable;
  1459. if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite)
  1460. member.CheckSpecifiedSource = RaCodeGen.GetStringForMember("o", mapping.Name + "Specified", structMapping.TypeDesc);
  1461. if (mapping.Text != null)
  1462. anyText = member;
  1463. if (mapping.Attribute != null && mapping.Attribute.Any)
  1464. anyAttribute = member;
  1465. if (!isSequence) {
  1466. // find anyElement if present.
  1467. for (int j = 0; j < mapping.Elements.Length; j++) {
  1468. if (mapping.Elements[j].Any && (mapping.Elements[j].Name == null || mapping.Elements[j].Name.Length == 0)) {
  1469. anyElement = member;
  1470. break;
  1471. }
  1472. }
  1473. }
  1474. else if (mapping.IsParticle && !mapping.IsSequence) {
  1475. StructMapping declaringMapping;
  1476. structMapping.FindDeclaringMapping(mapping, out declaringMapping, structMapping.TypeName);
  1477. throw new InvalidOperationException(Res.GetString(Res.XmlSequenceHierarchy, structMapping.TypeDesc.FullName, mapping.Name, declaringMapping.TypeDesc.FullName, "Order"));
  1478. }
  1479. if (mapping.Attribute == null && mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping) {
  1480. Member arrayMember = new Member(this, source, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
  1481. arrayMember.CheckSpecifiedSource = member.CheckSpecifiedSource;
  1482. allMembersList.Add(arrayMember);
  1483. }
  1484. else {
  1485. allMembersList.Add(member);
  1486. }
  1487. if (mapping.TypeDesc.IsArrayLike) {
  1488. arraysToDeclareList.Add(member);
  1489. if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) {
  1490. member.ParamsReadSource = null; // flat arrays -- don't want to count params read.
  1491. if (member != anyText && member != anyElement) {
  1492. arraysToSetList.Add(member);
  1493. }
  1494. }
  1495. else if (!mapping.TypeDesc.IsArray) {
  1496. member.ParamsReadSource = null; // collection
  1497. }
  1498. }
  1499. }
  1500. if (anyElement != null) arraysToSetList.Add(anyElement);
  1501. if (anyText != null && anyText != anyElement) arraysToSetList.Add(anyText);
  1502. Member[] arraysToDeclare = (Member[])arraysToDeclareList.ToArray(typeof(Member));
  1503. Member[] arraysToSet = (Member[])arraysToSetList.ToArray(typeof(Member));
  1504. Member[] allMembers = (Member[])allMembersList.ToArray(typeof(Member));
  1505. WriteMemberBegin(arraysToDeclare);
  1506. WriteParamsRead(mappings.Length);
  1507. WriteAttributes(allMembers, anyAttribute, "UnknownNode", oLoc);
  1508. if (anyAttribute != null)
  1509. WriteMemberEnd(arraysToDeclare);
  1510. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  1511. "get_Reader",
  1512. CodeGenerator.InstanceBindingFlags,
  1513. null,
  1514. CodeGenerator.EmptyTypeArray,
  1515. null
  1516. );
  1517. MethodInfo XmlReader_MoveToElement = typeof(XmlReader).GetMethod(
  1518. "MoveToElement",
  1519. CodeGenerator.InstanceBindingFlags,
  1520. null,
  1521. CodeGenerator.EmptyTypeArray,
  1522. null
  1523. );
  1524. ilg.Ldarg(0);
  1525. ilg.Call(XmlSerializationReader_get_Reader);
  1526. ilg.Call(XmlReader_MoveToElement);
  1527. ilg.Pop();
  1528. MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
  1529. "get_IsEmptyElement",
  1530. CodeGenerator.InstanceBindingFlags,
  1531. null,
  1532. CodeGenerator.EmptyTypeArray,
  1533. null
  1534. );
  1535. ilg.Ldarg(0);
  1536. ilg.Call(XmlSerializationReader_get_Reader);
  1537. ilg.Call(XmlReader_get_IsEmptyElement);
  1538. ilg.If();
  1539. MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
  1540. "Skip",
  1541. CodeGenerator.InstanceBindingFlags,
  1542. null,
  1543. CodeGenerator.EmptyTypeArray,
  1544. null
  1545. );
  1546. ilg.Ldarg(0);
  1547. ilg.Call(XmlSerializationReader_get_Reader);
  1548. ilg.Call(XmlReader_Skip);
  1549. WriteMemberEnd(arraysToSet);
  1550. ilg.Ldloc(oLoc);
  1551. ilg.Stloc(ilg.ReturnLocal);
  1552. ilg.Br(ilg.ReturnLabel);
  1553. ilg.EndIf();
  1554. MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
  1555. "ReadStartElement",
  1556. CodeGenerator.InstanceBindingFlags,
  1557. null,
  1558. CodeGenerator.EmptyTypeArray,
  1559. null
  1560. );
  1561. ilg.Ldarg(0);
  1562. ilg.Call(XmlSerializationReader_get_Reader);
  1563. ilg.Call(XmlReader_ReadStartElement);
  1564. if (IsSequence(allMembers)) {
  1565. ilg.Ldc(0);
  1566. ilg.Stloc(typeof(Int32), "state");
  1567. }
  1568. int loopIndex = WriteWhileNotLoopStart();
  1569. string unknownNode = "UnknownNode((object)o, " + ExpectedElements(allMembers) + ");";
  1570. WriteMemberElements(allMembers, unknownNode, unknownNode, anyElement, anyText);
  1571. MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
  1572. "MoveToContent",
  1573. CodeGenerator.InstanceBindingFlags,
  1574. null,
  1575. CodeGenerator.EmptyTypeArray,
  1576. null
  1577. );
  1578. ilg.Ldarg(0);
  1579. ilg.Call(XmlSerializationReader_get_Reader);
  1580. ilg.Call(XmlReader_MoveToContent);
  1581. ilg.Pop();
  1582. WriteWhileLoopEnd(loopIndex);
  1583. WriteMemberEnd(arraysToSet);
  1584. MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
  1585. "ReadEndElement",
  1586. CodeGenerator.InstanceBindingFlags,
  1587. null,
  1588. CodeGenerator.EmptyTypeArray,
  1589. null
  1590. );
  1591. ilg.Ldarg(0);
  1592. ilg.Call(XmlSerializationReader_ReadEndElement);
  1593. ilg.Ldloc(structMapping.TypeDesc.Type, "o");
  1594. ilg.Stloc(ilg.ReturnLocal);
  1595. }
  1596. ilg.MarkLabel(ilg.ReturnLabel);
  1597. ilg.Ldloc(ilg.ReturnLocal);
  1598. ilg.EndMethod();
  1599. }
  1600. void WriteQNameEqual(string source, string name, string ns) {
  1601. WriteID(name);
  1602. WriteID(ns);
  1603. // This api assume the source is local member of XmlQualifiedName type
  1604. // It leaves bool result on the stack
  1605. MethodInfo XmlQualifiedName_get_Name = typeof(XmlQualifiedName).GetMethod(
  1606. "get_Name",
  1607. CodeGenerator.InstanceBindingFlags,
  1608. null,
  1609. CodeGenerator.EmptyTypeArray,
  1610. null
  1611. );
  1612. MethodInfo XmlQualifiedName_get_Namespace = typeof(XmlQualifiedName).GetMethod(
  1613. "get_Namespace",
  1614. CodeGenerator.InstanceBindingFlags,
  1615. null,
  1616. CodeGenerator.EmptyTypeArray,
  1617. null
  1618. );
  1619. Label labelEnd = ilg.DefineLabel();
  1620. Label labelFalse = ilg.DefineLabel();
  1621. LocalBuilder sLoc = ilg.GetLocal(source);
  1622. ilg.Ldloc(sLoc);
  1623. ilg.Call(XmlQualifiedName_get_Name);
  1624. ilg.Ldarg(0);
  1625. ilg.LoadMember(idNameFields[name ?? String.Empty]);
  1626. ilg.Bne(labelFalse);
  1627. ilg.Ldloc(sLoc);
  1628. ilg.Call(XmlQualifiedName_get_Namespace);
  1629. ilg.Ldarg(0);
  1630. ilg.LoadMember(idNameFields[ns ?? String.Empty]);
  1631. ilg.Ceq();
  1632. ilg.Br_S(labelEnd);
  1633. ilg.MarkLabel(labelFalse);
  1634. ilg.Ldc(false);
  1635. ilg.MarkLabel(labelEnd);
  1636. }
  1637. void WriteXmlNodeEqual(string source, string name, string ns) {
  1638. WriteXmlNodeEqual(source, name, ns, true);
  1639. }
  1640. void WriteXmlNodeEqual(string source, string name, string ns, bool doAndIf) {
  1641. bool isNameNullOrEmpty = string.IsNullOrEmpty(name);
  1642. if (!isNameNullOrEmpty) {
  1643. WriteID(name);
  1644. }
  1645. WriteID(ns);
  1646. // Only support Reader and XmlSerializationReaderReader only
  1647. System.Diagnostics.Debug.Assert(source == "Reader");
  1648. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  1649. "get_" + source,
  1650. CodeGenerator.InstanceBindingFlags,
  1651. null,
  1652. CodeGenerator.EmptyTypeArray,
  1653. null
  1654. );
  1655. MethodInfo XmlReader_get_LocalName = typeof(XmlReader).GetMethod(
  1656. "get_LocalName",
  1657. CodeGenerator.InstanceBindingFlags,
  1658. null,
  1659. CodeGenerator.EmptyTypeArray,
  1660. null
  1661. );
  1662. MethodInfo XmlReader_get_NamespaceURI = typeof(XmlReader).GetMethod(
  1663. "get_NamespaceURI",
  1664. CodeGenerator.InstanceBindingFlags,
  1665. null,
  1666. CodeGenerator.EmptyTypeArray,
  1667. null
  1668. );
  1669. Label labelFalse = ilg.DefineLabel();
  1670. Label labelEnd = ilg.DefineLabel();
  1671. if (!isNameNullOrEmpty) {
  1672. ilg.Ldarg(0);
  1673. ilg.Call(XmlSerializationReader_get_Reader);
  1674. ilg.Call(XmlReader_get_LocalName);
  1675. ilg.Ldarg(0);
  1676. ilg.LoadMember(idNameFields[name ?? String.Empty]);
  1677. ilg.Bne(labelFalse);
  1678. }
  1679. ilg.Ldarg(0);
  1680. ilg.Call(XmlSerializationReader_get_Reader);
  1681. ilg.Call(XmlReader_get_NamespaceURI);
  1682. ilg.Ldarg(0);
  1683. ilg.LoadMember(idNameFields[ns ?? String.Empty]);
  1684. ilg.Ceq();
  1685. if (!isNameNullOrEmpty) {
  1686. ilg.Br_S(labelEnd);
  1687. ilg.MarkLabel(labelFalse);
  1688. ilg.Ldc(false);
  1689. ilg.MarkLabel(labelEnd);
  1690. }
  1691. if (doAndIf)
  1692. ilg.AndIf();
  1693. }
  1694. void WriteID(string name) {
  1695. if (name == null) {
  1696. //Writer.Write("null");
  1697. //return;
  1698. name = "";
  1699. }
  1700. string idName = (string)idNames[name];
  1701. if (idName == null) {
  1702. idName = NextIdName(name);
  1703. idNames.Add(name, idName);
  1704. idNameFields.Add(name, this.typeBuilder.DefineField(idName, typeof(string), FieldAttributes.Private));
  1705. }
  1706. }
  1707. void WriteAttributes(Member[] members, Member anyAttribute, string elseCall, LocalBuilder firstParam) {
  1708. int count = 0;
  1709. Member xmlnsMember = null;
  1710. ArrayList attributes = new ArrayList();
  1711. // Condition do at the end, so C# looks the same
  1712. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  1713. "get_Reader",
  1714. CodeGenerator.InstanceBindingFlags,
  1715. null,
  1716. CodeGenerator.EmptyTypeArray,
  1717. null
  1718. );
  1719. MethodInfo XmlReader_MoveToNextAttribute = typeof(XmlReader).GetMethod(
  1720. "MoveToNextAttribute",
  1721. CodeGenerator.InstanceBindingFlags,
  1722. null,
  1723. CodeGenerator.EmptyTypeArray,
  1724. null
  1725. );
  1726. ilg.WhileBegin();
  1727. for (int i = 0; i < members.Length; i++) {
  1728. Member member = (Member)members[i];
  1729. if (member.Mapping.Xmlns != null) {
  1730. xmlnsMember = member;
  1731. continue;
  1732. }
  1733. if (member.Mapping.Ignore)
  1734. continue;
  1735. AttributeAccessor attribute = member.Mapping.Attribute;
  1736. if (attribute == null) continue;
  1737. if (attribute.Any) continue;
  1738. attributes.Add(attribute);
  1739. if (count++ > 0)
  1740. ilg.InitElseIf();
  1741. else
  1742. ilg.InitIf();
  1743. if (member.ParamsReadSource != null) {
  1744. ILGenParamsReadSource(member.ParamsReadSource);
  1745. ilg.Ldc(false);
  1746. ilg.AndIf(Cmp.EqualTo);
  1747. }
  1748. if (attribute.IsSpecialXmlNamespace) {
  1749. WriteXmlNodeEqual("Reader", attribute.Name, XmlReservedNs.NsXml);
  1750. }
  1751. else
  1752. WriteXmlNodeEqual("Reader", attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "");
  1753. WriteAttribute(member);
  1754. }
  1755. if (count > 0)
  1756. ilg.InitElseIf();
  1757. else
  1758. ilg.InitIf();
  1759. if (xmlnsMember != null) {
  1760. MethodInfo XmlSerializationReader_IsXmlnsAttribute = typeof(XmlSerializationReader).GetMethod(
  1761. "IsXmlnsAttribute",
  1762. CodeGenerator.InstanceBindingFlags,
  1763. null,
  1764. new Type[] { typeof(string) },
  1765. null
  1766. );
  1767. MethodInfo XmlReader_get_Name = typeof(XmlReader).GetMethod(
  1768. "get_Name",
  1769. CodeGenerator.InstanceBindingFlags,
  1770. null,
  1771. CodeGenerator.EmptyTypeArray,
  1772. null
  1773. );
  1774. MethodInfo XmlReader_get_LocalName = typeof(XmlReader).GetMethod(
  1775. "get_LocalName",
  1776. CodeGenerator.InstanceBindingFlags,
  1777. null,
  1778. CodeGenerator.EmptyTypeArray,
  1779. null
  1780. );
  1781. MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
  1782. "get_Value",
  1783. CodeGenerator.InstanceBindingFlags,
  1784. null,
  1785. CodeGenerator.EmptyTypeArray,
  1786. null
  1787. );
  1788. ilg.Ldarg(0);
  1789. ilg.Ldarg(0);
  1790. ilg.Call(XmlSerializationReader_get_Reader);
  1791. ilg.Call(XmlReader_get_Name);
  1792. ilg.Call(XmlSerializationReader_IsXmlnsAttribute);
  1793. ilg.Ldc(true);
  1794. ilg.AndIf(Cmp.EqualTo);
  1795. ILGenLoad(xmlnsMember.Source);
  1796. ilg.Load(null);
  1797. ilg.If(Cmp.EqualTo);
  1798. WriteSourceBegin(xmlnsMember.Source);
  1799. ConstructorInfo ctor = xmlnsMember.Mapping.TypeDesc.Type.GetConstructor(
  1800. CodeGenerator.InstanceBindingFlags,
  1801. null,
  1802. CodeGenerator.EmptyTypeArray,
  1803. null
  1804. );
  1805. ilg.New(ctor);
  1806. WriteSourceEnd(xmlnsMember.Source, xmlnsMember.Mapping.TypeDesc.Type);
  1807. ilg.EndIf(); // if (xmlnsMember.Source == null
  1808. Label labelEqual5 = ilg.DefineLabel();
  1809. Label labelEndLength = ilg.DefineLabel();
  1810. MethodInfo Add = xmlnsMember.Mapping.TypeDesc.Type.GetMethod(
  1811. "Add",
  1812. CodeGenerator.InstanceBindingFlags,
  1813. null,
  1814. new Type[] { typeof(String), typeof(String) },
  1815. null
  1816. );
  1817. MethodInfo String_get_Length = typeof(String).GetMethod(
  1818. "get_Length",
  1819. CodeGenerator.InstanceBindingFlags,
  1820. null,
  1821. CodeGenerator.EmptyTypeArray,
  1822. null
  1823. );
  1824. ILGenLoad(xmlnsMember.ArraySource, xmlnsMember.Mapping.TypeDesc.Type);
  1825. ilg.Ldarg(0);
  1826. ilg.Call(XmlSerializationReader_get_Reader);
  1827. ilg.Call(XmlReader_get_Name);
  1828. ilg.Call(String_get_Length);
  1829. ilg.Ldc(5);
  1830. ilg.Beq(labelEqual5);
  1831. ilg.Ldarg(0);
  1832. ilg.Call(XmlSerializationReader_get_Reader);
  1833. ilg.Call(XmlReader_get_LocalName);
  1834. ilg.Br(labelEndLength);
  1835. ilg.MarkLabel(labelEqual5);
  1836. ilg.Ldstr(String.Empty);
  1837. ilg.MarkLabel(labelEndLength);
  1838. ilg.Ldarg(0);
  1839. ilg.Call(XmlSerializationReader_get_Reader);
  1840. ilg.Call(XmlReader_get_Value);
  1841. ilg.Call(Add);
  1842. ilg.Else();
  1843. }
  1844. else {
  1845. MethodInfo XmlSerializationReader_IsXmlnsAttribute = typeof(XmlSerializationReader).GetMethod(
  1846. "IsXmlnsAttribute",
  1847. CodeGenerator.InstanceBindingFlags,
  1848. null,
  1849. new Type[] { typeof(string) },
  1850. null
  1851. );
  1852. MethodInfo XmlReader_get_Name = typeof(XmlReader).GetMethod(
  1853. "get_Name",
  1854. CodeGenerator.InstanceBindingFlags,
  1855. null,
  1856. CodeGenerator.EmptyTypeArray,
  1857. null
  1858. );
  1859. ilg.Ldarg(0);
  1860. ilg.Ldarg(0);
  1861. ilg.Call(XmlSerializationReader_get_Reader);
  1862. ilg.Call(XmlReader_get_Name);
  1863. ilg.Call(XmlSerializationReader_IsXmlnsAttribute);
  1864. ilg.Ldc(false);
  1865. ilg.AndIf(Cmp.EqualTo);
  1866. }
  1867. if (anyAttribute != null) {
  1868. LocalBuilder localAttr = ilg.DeclareOrGetLocal(typeof(XmlAttribute), "attr");
  1869. MethodInfo XmlSerializationReader_get_Document = typeof(XmlSerializationReader).GetMethod(
  1870. "get_Document",
  1871. CodeGenerator.InstanceBindingFlags,
  1872. null,
  1873. CodeGenerator.EmptyTypeArray,
  1874. null
  1875. );
  1876. MethodInfo XmlDocument_ReadNode = typeof(XmlDocument).GetMethod(
  1877. "ReadNode",
  1878. CodeGenerator.InstanceBindingFlags,
  1879. null,
  1880. new Type[] { typeof(XmlReader) },
  1881. null
  1882. );
  1883. ilg.Ldarg(0);
  1884. ilg.Call(XmlSerializationReader_get_Document);
  1885. ilg.Ldarg(0);
  1886. ilg.Call(XmlSerializationReader_get_Reader);
  1887. ilg.Call(XmlDocument_ReadNode);
  1888. ilg.ConvertValue(XmlDocument_ReadNode.ReturnType, localAttr.LocalType);
  1889. ilg.Stloc(localAttr);
  1890. MethodInfo XmlSerializationReader_ParseWsdlArrayType = typeof(XmlSerializationReader).GetMethod(
  1891. "ParseWsdlArrayType",
  1892. CodeGenerator.InstanceBindingFlags,
  1893. null,
  1894. new Type[] { localAttr.LocalType },
  1895. null
  1896. );
  1897. ilg.Ldarg(0);
  1898. ilg.Ldloc(localAttr);
  1899. ilg.Call(XmlSerializationReader_ParseWsdlArrayType);
  1900. WriteAttribute(anyAttribute);
  1901. }
  1902. else {
  1903. List<Type> argTypes = new List<Type>();
  1904. ilg.Ldarg(0);
  1905. argTypes.Add(typeof(object));
  1906. ilg.Ldloc(firstParam);
  1907. ilg.ConvertValue(firstParam.LocalType, typeof(object));
  1908. if (attributes.Count > 0) {
  1909. string qnames = "";
  1910. for (int i = 0; i < attributes.Count; i++) {
  1911. AttributeAccessor attribute = (AttributeAccessor)attributes[i];
  1912. if (i > 0)
  1913. qnames += ", ";
  1914. qnames += attribute.IsSpecialXmlNamespace ? XmlReservedNs.NsXml : (attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "") + ":" + attribute.Name;
  1915. }
  1916. argTypes.Add(typeof(string));
  1917. ilg.Ldstr(qnames);
  1918. }
  1919. System.Diagnostics.Debug.Assert(elseCall == "UnknownNode");
  1920. MethodInfo elseCallMethod = typeof(XmlSerializationReader).GetMethod(
  1921. elseCall,
  1922. CodeGenerator.InstanceBindingFlags,
  1923. null,
  1924. argTypes.ToArray(),
  1925. null
  1926. );
  1927. ilg.Call(elseCallMethod);
  1928. }
  1929. ilg.EndIf();
  1930. ilg.WhileBeginCondition();
  1931. {
  1932. ilg.Ldarg(0);
  1933. ilg.Call(XmlSerializationReader_get_Reader);
  1934. ilg.Call(XmlReader_MoveToNextAttribute);
  1935. }
  1936. ilg.WhileEndCondition();
  1937. ilg.WhileEnd();
  1938. }
  1939. void WriteAttribute(Member member) {
  1940. AttributeAccessor attribute = member.Mapping.Attribute;
  1941. if (attribute.Mapping is SpecialMapping) {
  1942. SpecialMapping special = (SpecialMapping)attribute.Mapping;
  1943. if (special.TypeDesc.Kind == TypeKind.Attribute) {
  1944. WriteSourceBegin(member.ArraySource);
  1945. ilg.Ldloc("attr");
  1946. WriteSourceEnd(member.ArraySource, member.Mapping.TypeDesc.IsArrayLike ? member.Mapping.TypeDesc.ArrayElementTypeDesc.Type : member.Mapping.TypeDesc.Type);
  1947. }
  1948. else if (special.TypeDesc.CanBeAttributeValue) {
  1949. LocalBuilder attrLoc = ilg.GetLocal("attr");
  1950. ilg.Ldloc(attrLoc);
  1951. // to get code compat
  1952. if (attrLoc.LocalType == typeof(XmlAttribute)) {
  1953. ilg.Load(null);
  1954. ilg.Cne();
  1955. }
  1956. else
  1957. ilg.IsInst(typeof(XmlAttribute));
  1958. ilg.If();
  1959. WriteSourceBegin(member.ArraySource);
  1960. ilg.Ldloc(attrLoc);
  1961. ilg.ConvertValue(attrLoc.LocalType, typeof(XmlAttribute));
  1962. WriteSourceEnd(member.ArraySource, member.Mapping.TypeDesc.IsArrayLike ? member.Mapping.TypeDesc.ArrayElementTypeDesc.Type : member.Mapping.TypeDesc.Type);
  1963. ilg.EndIf();
  1964. }
  1965. else
  1966. throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  1967. }
  1968. else {
  1969. if (attribute.IsList) {
  1970. LocalBuilder locListValues = ilg.DeclareOrGetLocal(typeof(string), "listValues");
  1971. LocalBuilder locVals = ilg.DeclareOrGetLocal(typeof(string[]), "vals");
  1972. MethodInfo String_Split = typeof(String).GetMethod(
  1973. "Split",
  1974. CodeGenerator.InstanceBindingFlags,
  1975. null,
  1976. new Type[] { typeof(Char[]) },
  1977. null
  1978. );
  1979. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  1980. "get_Reader",
  1981. CodeGenerator.InstanceBindingFlags,
  1982. null,
  1983. CodeGenerator.EmptyTypeArray,
  1984. null
  1985. );
  1986. MethodInfo XmlReader_get_Value = typeof(XmlReader).GetMethod(
  1987. "get_Value",
  1988. CodeGenerator.InstanceBindingFlags,
  1989. null,
  1990. CodeGenerator.EmptyTypeArray,
  1991. null
  1992. );
  1993. ilg.Ldarg(0);
  1994. ilg.Call(XmlSerializationReader_get_Reader);
  1995. ilg.Call(XmlReader_get_Value);
  1996. ilg.Stloc(locListValues);
  1997. ilg.Ldloc(locListValues);
  1998. ilg.Load(null);
  1999. ilg.Call(String_Split);
  2000. ilg.Stloc(locVals);
  2001. LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), "i");
  2002. ilg.For(localI, 0, locVals);
  2003. string attributeSource = GetArraySource(member.Mapping.TypeDesc, member.ArrayName);
  2004. WriteSourceBegin(attributeSource);
  2005. WritePrimitive(attribute.Mapping, "vals[i]");
  2006. WriteSourceEnd(attributeSource, member.Mapping.TypeDesc.ArrayElementTypeDesc.Type);
  2007. ilg.EndFor();
  2008. }
  2009. else {
  2010. WriteSourceBegin(member.ArraySource);
  2011. WritePrimitive(attribute.Mapping, attribute.IsList ? "vals[i]" : "Reader.Value");
  2012. WriteSourceEnd(member.ArraySource, member.Mapping.TypeDesc.IsArrayLike ? member.Mapping.TypeDesc.ArrayElementTypeDesc.Type : member.Mapping.TypeDesc.Type);
  2013. }
  2014. }
  2015. if (member.Mapping.CheckSpecified == SpecifiedAccessor.ReadWrite && member.CheckSpecifiedSource != null && member.CheckSpecifiedSource.Length > 0) {
  2016. ILGenSet(member.CheckSpecifiedSource, true);
  2017. }
  2018. if (member.ParamsReadSource != null) {
  2019. ILGenParamsReadSource(member.ParamsReadSource, true);
  2020. }
  2021. }
  2022. void WriteMemberBegin(Member[] members) {
  2023. for (int i = 0; i < members.Length; i++) {
  2024. Member member = (Member)members[i];
  2025. if (member.IsArrayLike) {
  2026. string a = member.ArrayName;
  2027. string c = "c" + a;
  2028. TypeDesc typeDesc = member.Mapping.TypeDesc;
  2029. if (member.Mapping.TypeDesc.IsArray) {
  2030. WriteArrayLocalDecl(typeDesc.CSharpName,
  2031. a, "null", typeDesc);
  2032. ilg.Ldc(0);
  2033. ilg.Stloc(typeof(int), c);
  2034. if (member.Mapping.ChoiceIdentifier != null) {
  2035. WriteArrayLocalDecl(member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.CSharpName + "[]",
  2036. member.ChoiceArrayName, "null",
  2037. member.Mapping.ChoiceIdentifier.Mapping.TypeDesc);
  2038. ilg.Ldc(0);
  2039. ilg.Stloc(typeof(int), "c" + member.ChoiceArrayName);
  2040. }
  2041. }
  2042. else {
  2043. if (member.Source[member.Source.Length - 1] == '(' || member.Source[member.Source.Length - 1] == '{') {
  2044. WriteCreateInstance(a, typeDesc.CannotNew, typeDesc.Type);
  2045. WriteSourceBegin(member.Source);
  2046. ilg.Ldloc(ilg.GetLocal(a));
  2047. WriteSourceEnd(member.Source, typeDesc.Type);
  2048. }
  2049. else {
  2050. if (member.IsList && !member.Mapping.ReadOnly && member.Mapping.TypeDesc.IsNullable) {
  2051. // we need to new the Collections and ArrayLists
  2052. ILGenLoad(member.Source, typeof(object));
  2053. ilg.Load(null);
  2054. ilg.If(Cmp.EqualTo);
  2055. if (!member.Mapping.TypeDesc.HasDefaultConstructor) {
  2056. MethodInfo XmlSerializationReader_CreateReadOnlyCollectionException = typeof(XmlSerializationReader).GetMethod(
  2057. "CreateReadOnlyCollectionException",
  2058. CodeGenerator.InstanceBindingFlags,
  2059. null,
  2060. new Type[] { typeof(String) },
  2061. null
  2062. );
  2063. ilg.Ldarg(0);
  2064. ilg.Ldstr(member.Mapping.TypeDesc.CSharpName);
  2065. ilg.Call(XmlSerializationReader_CreateReadOnlyCollectionException);
  2066. ilg.Throw();
  2067. }
  2068. else {
  2069. WriteSourceBegin(member.Source);
  2070. RaCodeGen.ILGenForCreateInstance(ilg, member.Mapping.TypeDesc.Type, typeDesc.CannotNew, true);
  2071. WriteSourceEnd(member.Source, member.Mapping.TypeDesc.Type);
  2072. }
  2073. ilg.EndIf(); // if ((object)(member.Source) == null
  2074. }
  2075. WriteLocalDecl(a, new SourceInfo(member.Source, member.Source, member.Mapping.MemberInfo, member.Mapping.TypeDesc.Type, ilg));
  2076. }
  2077. }
  2078. }
  2079. }
  2080. }
  2081. string ExpectedElements(Member[] members) {
  2082. if (IsSequence(members))
  2083. return "null";
  2084. string qnames = string.Empty;
  2085. bool firstElement = true;
  2086. for (int i = 0; i < members.Length; i++) {
  2087. Member member = (Member)members[i];
  2088. if (member.Mapping.Xmlns != null)
  2089. continue;
  2090. if (member.Mapping.Ignore)
  2091. continue;
  2092. if (member.Mapping.IsText || member.Mapping.IsAttribute)
  2093. continue;
  2094. ElementAccessor[] elements = member.Mapping.Elements;
  2095. for (int j = 0; j < elements.Length; j++) {
  2096. ElementAccessor e = elements[j];
  2097. string ns = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
  2098. if (e.Any && (e.Name == null || e.Name.Length == 0)) continue;
  2099. if (!firstElement)
  2100. qnames += ", ";
  2101. qnames += ns + ":" + e.Name;
  2102. firstElement = false;
  2103. }
  2104. }
  2105. return ReflectionAwareILGen.GetQuotedCSharpString(null, qnames);
  2106. }
  2107. void WriteMemberElements(Member[] members, string elementElseString, string elseString, Member anyElement, Member anyText) {
  2108. if (anyText != null) {
  2109. ilg.Load(null);
  2110. ilg.Stloc(typeof(string), "tmp");
  2111. }
  2112. MethodInfo XmlReader_get_NodeType = typeof(XmlReader).GetMethod(
  2113. "get_NodeType",
  2114. CodeGenerator.InstanceBindingFlags,
  2115. null,
  2116. CodeGenerator.EmptyTypeArray,
  2117. null
  2118. );
  2119. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  2120. "get_Reader",
  2121. CodeGenerator.InstanceBindingFlags,
  2122. null,
  2123. CodeGenerator.EmptyTypeArray,
  2124. null
  2125. );
  2126. int XmlNodeType_Element = 1;
  2127. ilg.Ldarg(0);
  2128. ilg.Call(XmlSerializationReader_get_Reader);
  2129. ilg.Call(XmlReader_get_NodeType);
  2130. ilg.Ldc(XmlNodeType_Element);
  2131. ilg.If(Cmp.EqualTo);
  2132. WriteMemberElementsIf(members, anyElement, elementElseString);
  2133. if (anyText != null)
  2134. WriteMemberText(anyText, elseString);
  2135. ilg.Else();
  2136. ILGenElseString(elseString);
  2137. ilg.EndIf();
  2138. }
  2139. void WriteMemberText(Member anyText, string elseString) {
  2140. ilg.InitElseIf();
  2141. Label labelTrue = ilg.DefineLabel();
  2142. Label labelEnd = ilg.DefineLabel();
  2143. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  2144. "get_Reader",
  2145. CodeGenerator.InstanceBindingFlags,
  2146. null,
  2147. CodeGenerator.EmptyTypeArray,
  2148. null
  2149. );
  2150. MethodInfo XmlReader_get_NodeType = typeof(XmlReader).GetMethod(
  2151. "get_NodeType",
  2152. CodeGenerator.InstanceBindingFlags,
  2153. null,
  2154. CodeGenerator.EmptyTypeArray,
  2155. null
  2156. );
  2157. ilg.Ldarg(0);
  2158. ilg.Call(XmlSerializationReader_get_Reader);
  2159. ilg.Call(XmlReader_get_NodeType);
  2160. ilg.Ldc(XmlNodeType.Text);
  2161. ilg.Ceq();
  2162. ilg.Brtrue(labelTrue);
  2163. ilg.Ldarg(0);
  2164. ilg.Call(XmlSerializationReader_get_Reader);
  2165. ilg.Call(XmlReader_get_NodeType);
  2166. ilg.Ldc(XmlNodeType.CDATA);
  2167. ilg.Ceq();
  2168. ilg.Brtrue(labelTrue);
  2169. ilg.Ldarg(0);
  2170. ilg.Call(XmlSerializationReader_get_Reader);
  2171. ilg.Call(XmlReader_get_NodeType);
  2172. ilg.Ldc(XmlNodeType.Whitespace);
  2173. ilg.Ceq();
  2174. ilg.Brtrue(labelTrue);
  2175. ilg.Ldarg(0);
  2176. ilg.Call(XmlSerializationReader_get_Reader);
  2177. ilg.Call(XmlReader_get_NodeType);
  2178. ilg.Ldc(XmlNodeType.SignificantWhitespace);
  2179. ilg.Ceq();
  2180. ilg.Br(labelEnd);
  2181. ilg.MarkLabel(labelTrue);
  2182. ilg.Ldc(true);
  2183. ilg.MarkLabel(labelEnd);
  2184. ilg.AndIf();
  2185. if (anyText != null) {
  2186. WriteText(anyText);
  2187. }
  2188. Debug.Assert(anyText != null);
  2189. }
  2190. void WriteText(Member member) {
  2191. TextAccessor text = member.Mapping.Text;
  2192. if (text.Mapping is SpecialMapping) {
  2193. SpecialMapping special = (SpecialMapping)text.Mapping;
  2194. WriteSourceBeginTyped(member.ArraySource, special.TypeDesc);
  2195. switch (special.TypeDesc.Kind) {
  2196. case TypeKind.Node:
  2197. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  2198. "get_Reader",
  2199. CodeGenerator.InstanceBindingFlags,
  2200. null,
  2201. CodeGenerator.EmptyTypeArray,
  2202. null
  2203. );
  2204. MethodInfo XmlReader_ReadString = typeof(XmlReader).GetMethod(
  2205. "ReadString",
  2206. CodeGenerator.InstanceBindingFlags,
  2207. null,
  2208. CodeGenerator.EmptyTypeArray,
  2209. null
  2210. );
  2211. MethodInfo XmlSerializationReader_get_Document = typeof(XmlSerializationReader).GetMethod(
  2212. "get_Document",
  2213. CodeGenerator.InstanceBindingFlags,
  2214. null,
  2215. CodeGenerator.EmptyTypeArray,
  2216. null
  2217. );
  2218. MethodInfo XmlDocument_CreateTextNode = typeof(XmlDocument).GetMethod(
  2219. "CreateTextNode",
  2220. CodeGenerator.InstanceBindingFlags,
  2221. null,
  2222. new Type[] { typeof(String) },
  2223. null
  2224. );
  2225. ilg.Ldarg(0);
  2226. ilg.Call(XmlSerializationReader_get_Document);
  2227. ilg.Ldarg(0);
  2228. ilg.Call(XmlSerializationReader_get_Reader);
  2229. ilg.Call(XmlReader_ReadString);
  2230. ilg.Call(XmlDocument_CreateTextNode);
  2231. break;
  2232. default:
  2233. throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  2234. }
  2235. WriteSourceEnd(member.ArraySource, special.TypeDesc.Type);
  2236. }
  2237. else {
  2238. if (member.IsArrayLike) {
  2239. WriteSourceBegin(member.ArraySource);
  2240. if (text.Mapping.TypeDesc.CollapseWhitespace) {
  2241. ilg.Ldarg(0); // for calling CollapseWhitespace
  2242. }
  2243. else {
  2244. }
  2245. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  2246. "get_Reader",
  2247. CodeGenerator.InstanceBindingFlags,
  2248. null,
  2249. CodeGenerator.EmptyTypeArray,
  2250. null
  2251. );
  2252. MethodInfo XmlReader_ReadString = typeof(XmlReader).GetMethod(
  2253. "ReadString",
  2254. CodeGenerator.InstanceBindingFlags,
  2255. null,
  2256. CodeGenerator.EmptyTypeArray,
  2257. null
  2258. );
  2259. ilg.Ldarg(0);
  2260. ilg.Call(XmlSerializationReader_get_Reader);
  2261. ilg.Call(XmlReader_ReadString);
  2262. if (text.Mapping.TypeDesc.CollapseWhitespace) {
  2263. MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod(
  2264. "CollapseWhitespace",
  2265. CodeGenerator.InstanceBindingFlags,
  2266. null,
  2267. new Type[] { typeof(String) },
  2268. null
  2269. );
  2270. ilg.Call(XmlSerializationReader_CollapseWhitespace);
  2271. }
  2272. }
  2273. else {
  2274. if (text.Mapping.TypeDesc == StringTypeDesc || text.Mapping.TypeDesc.FormatterName == "String") {
  2275. LocalBuilder tmpLoc = ilg.GetLocal("tmp");
  2276. MethodInfo XmlSerializationReader_ReadString = typeof(XmlSerializationReader).GetMethod(
  2277. "ReadString",
  2278. CodeGenerator.InstanceBindingFlags,
  2279. null,
  2280. new Type[] { typeof(String), typeof(Boolean) },
  2281. null
  2282. );
  2283. ilg.Ldarg(0);
  2284. ilg.Ldloc(tmpLoc);
  2285. ilg.Ldc(text.Mapping.TypeDesc.CollapseWhitespace);
  2286. ilg.Call(XmlSerializationReader_ReadString);
  2287. ilg.Stloc(tmpLoc);
  2288. WriteSourceBegin(member.ArraySource);
  2289. ilg.Ldloc(tmpLoc);
  2290. }
  2291. else {
  2292. WriteSourceBegin(member.ArraySource);
  2293. WritePrimitive(text.Mapping, "Reader.ReadString()");
  2294. }
  2295. }
  2296. WriteSourceEnd(member.ArraySource, text.Mapping.TypeDesc.Type);
  2297. }
  2298. }
  2299. void WriteMemberElementsElse(Member anyElement, string elementElseString) {
  2300. if (anyElement != null) {
  2301. ElementAccessor[] elements = anyElement.Mapping.Elements;
  2302. for (int i = 0; i < elements.Length; i++) {
  2303. ElementAccessor element = elements[i];
  2304. if (element.Any && element.Name.Length == 0) {
  2305. WriteElement(anyElement.ArraySource, anyElement.ArrayName, anyElement.ChoiceArraySource, element, anyElement.Mapping.ChoiceIdentifier, anyElement.Mapping.CheckSpecified == SpecifiedAccessor.ReadWrite ? anyElement.CheckSpecifiedSource : null, false, false, -1, i);
  2306. break;
  2307. }
  2308. }
  2309. }
  2310. else {
  2311. ILGenElementElseString(elementElseString);
  2312. }
  2313. }
  2314. bool IsSequence(Member[] members) {
  2315. for (int i = 0; i < members.Length; i++) {
  2316. if (members[i].Mapping.IsParticle && members[i].Mapping.IsSequence)
  2317. return true;
  2318. }
  2319. return false;
  2320. }
  2321. void WriteMemberElementsIf(Member[] members, Member anyElement, string elementElseString) {
  2322. int count = 0;
  2323. bool isSequence = IsSequence(members);
  2324. int cases = 0;
  2325. for (int i = 0; i < members.Length; i++) {
  2326. Member member = (Member)members[i];
  2327. if (member.Mapping.Xmlns != null)
  2328. continue;
  2329. if (member.Mapping.Ignore)
  2330. continue;
  2331. if (isSequence && (member.Mapping.IsText || member.Mapping.IsAttribute))
  2332. continue;
  2333. bool firstElement = true;
  2334. ChoiceIdentifierAccessor choice = member.Mapping.ChoiceIdentifier;
  2335. ElementAccessor[] elements = member.Mapping.Elements;
  2336. for (int j = 0; j < elements.Length; j++) {
  2337. ElementAccessor e = elements[j];
  2338. string ns = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
  2339. if (!isSequence && e.Any && (e.Name == null || e.Name.Length == 0)) continue;
  2340. if (!firstElement || (!isSequence && count > 0)) {
  2341. ilg.InitElseIf();
  2342. }
  2343. else if (isSequence) {
  2344. if (cases > 0)
  2345. ilg.InitElseIf();
  2346. else
  2347. ilg.InitIf();
  2348. ilg.Ldloc("state");
  2349. ilg.Ldc(cases);
  2350. ilg.AndIf(Cmp.EqualTo);
  2351. ilg.InitIf();
  2352. }
  2353. else {
  2354. ilg.InitIf();
  2355. }
  2356. count++;
  2357. firstElement = false;
  2358. if (member.ParamsReadSource != null) {
  2359. ILGenParamsReadSource(member.ParamsReadSource);
  2360. ilg.Ldc(false);
  2361. ilg.AndIf(Cmp.EqualTo);
  2362. }
  2363. Label labelTrue = ilg.DefineLabel();
  2364. Label labelEnd = ilg.DefineLabel();
  2365. if (member.Mapping.IsReturnValue) {
  2366. MethodInfo XmlSerializationReader_get_IsReturnValue = typeof(XmlSerializationReader).GetMethod(
  2367. "get_IsReturnValue",
  2368. CodeGenerator.InstanceBindingFlags,
  2369. null,
  2370. CodeGenerator.EmptyTypeArray,
  2371. null
  2372. );
  2373. ilg.Ldarg(0);
  2374. ilg.Call(XmlSerializationReader_get_IsReturnValue);
  2375. ilg.Brtrue(labelTrue);
  2376. }
  2377. if (isSequence && e.Any && e.AnyNamespaces == null) {
  2378. ilg.Ldc(true);
  2379. }
  2380. else {
  2381. WriteXmlNodeEqual("Reader", e.Name, ns, false);
  2382. }
  2383. if (member.Mapping.IsReturnValue) {
  2384. ilg.Br_S(labelEnd);
  2385. ilg.MarkLabel(labelTrue);
  2386. ilg.Ldc(true);
  2387. ilg.MarkLabel(labelEnd);
  2388. }
  2389. ilg.AndIf();
  2390. 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);
  2391. if (member.Mapping.IsReturnValue) {
  2392. MethodInfo XmlSerializationReader_set_IsReturnValue = typeof(XmlSerializationReader).GetMethod(
  2393. "set_IsReturnValue",
  2394. CodeGenerator.InstanceBindingFlags,
  2395. null,
  2396. new Type[] { typeof(Boolean) },
  2397. null
  2398. );
  2399. ilg.Ldarg(0);
  2400. ilg.Ldc(false);
  2401. ilg.Call(XmlSerializationReader_set_IsReturnValue);
  2402. }
  2403. if (member.ParamsReadSource != null) {
  2404. ILGenParamsReadSource(member.ParamsReadSource, true);
  2405. }
  2406. }
  2407. if (isSequence) {
  2408. if (member.IsArrayLike) {
  2409. ilg.Else();
  2410. }
  2411. else {
  2412. ilg.EndIf();
  2413. }
  2414. cases++;
  2415. ilg.Ldc(cases);
  2416. ilg.Stloc(ilg.GetLocal("state"));
  2417. if (member.IsArrayLike) {
  2418. ilg.EndIf();
  2419. }
  2420. }
  2421. }
  2422. if (count > 0) {
  2423. ilg.Else();
  2424. }
  2425. WriteMemberElementsElse(anyElement, elementElseString);
  2426. if (count > 0) {
  2427. ilg.EndIf();
  2428. }
  2429. }
  2430. string GetArraySource(TypeDesc typeDesc, string arrayName) {
  2431. return GetArraySource(typeDesc, arrayName, false);
  2432. }
  2433. string GetArraySource(TypeDesc typeDesc, string arrayName, bool multiRef) {
  2434. string a = arrayName;
  2435. string c = "c" + a;
  2436. string init = "";
  2437. if (multiRef) {
  2438. init = "soap = (System.Object[])EnsureArrayIndex(soap, " + c + "+2, typeof(System.Object)); ";
  2439. }
  2440. if (typeDesc.IsArray) {
  2441. string arrayTypeFullName = typeDesc.ArrayElementTypeDesc.CSharpName;
  2442. string castString = "(" + arrayTypeFullName + "[])";
  2443. init = init + a + " = " + castString +
  2444. "EnsureArrayIndex(" + a + ", " + c + ", " + RaCodeGen.GetStringForTypeof(arrayTypeFullName) + ");";
  2445. string arraySource = RaCodeGen.GetStringForArrayMember(a, c + "++", typeDesc);
  2446. if (multiRef) {
  2447. init = init + " soap[1] = " + a + ";";
  2448. init = init + " if (ReadReference(out soap[" + c + "+2])) " + arraySource + " = null; else ";
  2449. }
  2450. return init + arraySource;
  2451. }
  2452. else {
  2453. return RaCodeGen.GetStringForMethod(arrayName, typeDesc.CSharpName, "Add");
  2454. }
  2455. }
  2456. void WriteMemberEnd(Member[] members) {
  2457. WriteMemberEnd(members, false);
  2458. }
  2459. void WriteMemberEnd(Member[] members, bool soapRefs) {
  2460. for (int i = 0; i < members.Length; i++) {
  2461. Member member = (Member)members[i];
  2462. if (member.IsArrayLike) {
  2463. TypeDesc typeDesc = member.Mapping.TypeDesc;
  2464. if (typeDesc.IsArray) {
  2465. WriteSourceBegin(member.Source);
  2466. Debug.Assert(!soapRefs);
  2467. string a = member.ArrayName;
  2468. string c = "c" + a;
  2469. MethodInfo XmlSerializationReader_ShrinkArray = typeof(XmlSerializationReader).GetMethod(
  2470. "ShrinkArray",
  2471. CodeGenerator.InstanceBindingFlags,
  2472. null,
  2473. new Type[] { typeof(Array), typeof(Int32), typeof(Type), typeof(Boolean) },
  2474. null
  2475. );
  2476. ilg.Ldarg(0);
  2477. ilg.Ldloc(ilg.GetLocal(a));
  2478. ilg.Ldloc(ilg.GetLocal(c));
  2479. ilg.Ldc(typeDesc.ArrayElementTypeDesc.Type);
  2480. ilg.Ldc(member.IsNullable);
  2481. ilg.Call(XmlSerializationReader_ShrinkArray);
  2482. ilg.ConvertValue(XmlSerializationReader_ShrinkArray.ReturnType, typeDesc.Type);
  2483. WriteSourceEnd(member.Source, typeDesc.Type);
  2484. if (member.Mapping.ChoiceIdentifier != null) {
  2485. WriteSourceBegin(member.ChoiceSource);
  2486. a = member.ChoiceArrayName;
  2487. c = "c" + a;
  2488. ilg.Ldarg(0);
  2489. ilg.Ldloc(ilg.GetLocal(a));
  2490. ilg.Ldloc(ilg.GetLocal(c));
  2491. ilg.Ldc(member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.Type);
  2492. ilg.Ldc(member.IsNullable);
  2493. ilg.Call(XmlSerializationReader_ShrinkArray);
  2494. ilg.ConvertValue(XmlSerializationReader_ShrinkArray.ReturnType, member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.Type.MakeArrayType());
  2495. WriteSourceEnd(member.ChoiceSource, member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.Type.MakeArrayType());
  2496. }
  2497. }
  2498. else if (typeDesc.IsValueType) {
  2499. LocalBuilder arrayLoc = ilg.GetLocal(member.ArrayName);
  2500. WriteSourceBegin(member.Source);
  2501. ilg.Ldloc(arrayLoc);
  2502. WriteSourceEnd(member.Source, arrayLoc.LocalType);
  2503. }
  2504. }
  2505. }
  2506. }
  2507. void WriteSourceBeginTyped(string source, TypeDesc typeDesc) {
  2508. WriteSourceBegin(source);
  2509. }
  2510. void WriteSourceBegin(string source) {
  2511. object variable;
  2512. if (ilg.TryGetVariable(source, out variable)) {
  2513. Type varType = ilg.GetVariableType(variable);
  2514. if (CodeGenerator.IsNullableGenericType(varType)) {
  2515. // local address to invoke ctor on WriteSourceEnd
  2516. ilg.LoadAddress(variable);
  2517. }
  2518. return;
  2519. }
  2520. // o.@Field
  2521. if (source.StartsWith("o.@", StringComparison.Ordinal)) {
  2522. ilg.LdlocAddress(ilg.GetLocal("o"));
  2523. return;
  2524. }
  2525. // a_0_0 = (global::System.Object[])EnsureArrayIndex(a_0_0, ca_0_0, typeof(global::System.Object));a_0_0[ca_0_0++]
  2526. Regex regex = NewRegex("(?<locA1>[^ ]+) = .+EnsureArrayIndex[(](?<locA2>[^,]+), (?<locI1>[^,]+),[^;]+;(?<locA3>[^[]+)[[](?<locI2>[^+]+)[+][+][]]");
  2527. Match match = regex.Match(source);
  2528. if (match.Success) {
  2529. Debug.Assert(match.Groups["locA1"].Value == match.Groups["locA2"].Value);
  2530. Debug.Assert(match.Groups["locA1"].Value == match.Groups["locA3"].Value);
  2531. Debug.Assert(match.Groups["locI1"].Value == match.Groups["locI2"].Value);
  2532. LocalBuilder localA = ilg.GetLocal(match.Groups["locA1"].Value);
  2533. LocalBuilder localI = ilg.GetLocal(match.Groups["locI1"].Value);
  2534. Type arrayElementType = localA.LocalType.GetElementType();
  2535. MethodInfo XmlSerializationReader_EnsureArrayIndex = typeof(XmlSerializationReader).GetMethod(
  2536. "EnsureArrayIndex",
  2537. CodeGenerator.InstanceBindingFlags,
  2538. null,
  2539. new Type[] { typeof(Array), typeof(Int32), typeof(Type) },
  2540. null
  2541. );
  2542. ilg.Ldarg(0);
  2543. ilg.Ldloc(localA);
  2544. ilg.Ldloc(localI);
  2545. ilg.Ldc(arrayElementType);
  2546. ilg.Call(XmlSerializationReader_EnsureArrayIndex);
  2547. ilg.Castclass(localA.LocalType);
  2548. ilg.Stloc(localA);
  2549. // a_0[ca_0++]
  2550. ilg.Ldloc(localA);
  2551. ilg.Ldloc(localI);
  2552. ilg.Dup();
  2553. ilg.Ldc(1);
  2554. ilg.Add();
  2555. ilg.Stloc(localI);
  2556. if (CodeGenerator.IsNullableGenericType(arrayElementType) || arrayElementType.IsValueType) {
  2557. ilg.Ldelema(arrayElementType);
  2558. }
  2559. return;
  2560. }
  2561. //"a_0_0.Add("
  2562. if (source.EndsWith(".Add(", StringComparison.Ordinal)) {
  2563. int index = source.LastIndexOf(".Add(", StringComparison.Ordinal);
  2564. LocalBuilder localA = ilg.GetLocal(source.Substring(0, index));
  2565. ilg.LdlocAddress(localA);
  2566. return;
  2567. }
  2568. // p[0]
  2569. regex = NewRegex("(?<a>[^[]+)[[](?<ia>.+)[]]");
  2570. match = regex.Match(source);
  2571. if (match.Success) {
  2572. System.Diagnostics.Debug.Assert(ilg.GetVariableType(ilg.GetVariable(match.Groups["a"].Value)).IsArray);
  2573. ilg.Load(ilg.GetVariable(match.Groups["a"].Value));
  2574. ilg.Load(ilg.GetVariable(match.Groups["ia"].Value));
  2575. return;
  2576. }
  2577. throw CodeGenerator.NotSupported("Unexpected: " + source);
  2578. }
  2579. void WriteSourceEnd(string source, Type elementType) {
  2580. WriteSourceEnd(source, elementType, elementType);
  2581. }
  2582. void WriteSourceEnd(string source, Type elementType, Type stackType) {
  2583. object variable;
  2584. if (ilg.TryGetVariable(source, out variable)) {
  2585. Type varType = ilg.GetVariableType(variable);
  2586. if (CodeGenerator.IsNullableGenericType(varType)) {
  2587. ilg.Call(varType.GetConstructor(varType.GetGenericArguments()));
  2588. }
  2589. else {
  2590. Debug.Assert(elementType != null && variable is LocalBuilder);
  2591. ilg.ConvertValue(stackType, elementType);
  2592. ilg.ConvertValue(elementType, varType);
  2593. ilg.Stloc((LocalBuilder)variable);
  2594. }
  2595. return;
  2596. }
  2597. // o.@Field
  2598. if (source.StartsWith("o.@", StringComparison.Ordinal)) {
  2599. Debug.Assert(memberInfos.ContainsKey(source.Substring(3)));
  2600. MemberInfo memInfo = memberInfos[source.Substring(3)];
  2601. ilg.ConvertValue(stackType, memInfo.MemberType == MemberTypes.Field ? ((FieldInfo)memInfo).FieldType : ((PropertyInfo)memInfo).PropertyType);
  2602. ilg.StoreMember(memInfo);
  2603. return;
  2604. }
  2605. // a_0_0 = (global::System.Object[])EnsureArrayIndex(a_0_0, ca_0_0, typeof(global::System.Object));a_0_0[ca_0_0++]
  2606. Regex regex = NewRegex("(?<locA1>[^ ]+) = .+EnsureArrayIndex[(](?<locA2>[^,]+), (?<locI1>[^,]+),[^;]+;(?<locA3>[^[]+)[[](?<locI2>[^+]+)[+][+][]]");
  2607. Match match = regex.Match(source);
  2608. if (match.Success) {
  2609. object oVar = ilg.GetVariable(match.Groups["locA1"].Value);
  2610. Type arrayElementType = ilg.GetVariableType(oVar).GetElementType();
  2611. ilg.ConvertValue(elementType, arrayElementType);
  2612. if (CodeGenerator.IsNullableGenericType(arrayElementType) || arrayElementType.IsValueType) {
  2613. ilg.Stobj(arrayElementType);
  2614. }
  2615. else {
  2616. ilg.Stelem(arrayElementType);
  2617. }
  2618. return;
  2619. }
  2620. //"a_0_0.Add("
  2621. if (source.EndsWith(".Add(", StringComparison.Ordinal)) {
  2622. int index = source.LastIndexOf(".Add(", StringComparison.Ordinal);
  2623. LocalBuilder localA = ilg.GetLocal(source.Substring(0, index));
  2624. Debug.Assert(!localA.LocalType.IsGenericType || (localA.LocalType.GetGenericArguments().Length == 1 && localA.LocalType.GetGenericArguments()[0].IsAssignableFrom(elementType)));
  2625. MethodInfo Add = localA.LocalType.GetMethod(
  2626. "Add",
  2627. CodeGenerator.InstanceBindingFlags,
  2628. null,
  2629. new Type[] { elementType },
  2630. null
  2631. );
  2632. Debug.Assert(Add != null);
  2633. Type addParameterType = Add.GetParameters()[0].ParameterType;
  2634. ilg.ConvertValue(stackType, addParameterType);
  2635. ilg.Call(Add);
  2636. if (Add.ReturnType != typeof(void))
  2637. ilg.Pop();
  2638. return;
  2639. }
  2640. // p[0]
  2641. regex = NewRegex("(?<a>[^[]+)[[](?<ia>.+)[]]");
  2642. match = regex.Match(source);
  2643. if (match.Success) {
  2644. Type varType = ilg.GetVariableType(ilg.GetVariable(match.Groups["a"].Value));
  2645. System.Diagnostics.Debug.Assert(varType.IsArray);
  2646. Type varElementType = varType.GetElementType();
  2647. ilg.ConvertValue(stackType, varElementType);
  2648. ilg.Stelem(varElementType);
  2649. return;
  2650. }
  2651. throw CodeGenerator.NotSupported("Unexpected: " + source);
  2652. }
  2653. void WriteArray(string source, string arrayName, ArrayMapping arrayMapping, bool readOnly, bool isNullable, int fixupIndex, int elementIndex) {
  2654. MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
  2655. "ReadNull",
  2656. CodeGenerator.InstanceBindingFlags,
  2657. null,
  2658. CodeGenerator.EmptyTypeArray,
  2659. null
  2660. );
  2661. ilg.Ldarg(0);
  2662. ilg.Call(XmlSerializationReader_ReadNull);
  2663. ilg.IfNot();
  2664. MemberMapping memberMapping = new MemberMapping();
  2665. memberMapping.Elements = arrayMapping.Elements;
  2666. memberMapping.TypeDesc = arrayMapping.TypeDesc;
  2667. memberMapping.ReadOnly = readOnly;
  2668. if (source.StartsWith("o.@", StringComparison.Ordinal)) {
  2669. Debug.Assert(memberInfos.ContainsKey(source.Substring(3)));
  2670. memberMapping.MemberInfo = memberInfos[source.Substring(3)];
  2671. }
  2672. Member member = new Member(this, source, arrayName, elementIndex, memberMapping, false);
  2673. member.IsNullable = false;//Note, Microsoft: IsNullable is set to false since null condition (xsi:nil) is already handled by 'ReadNull()'
  2674. Member[] members = new Member[] { member };
  2675. WriteMemberBegin(members);
  2676. Label labelTrue = ilg.DefineLabel();
  2677. Label labelEnd = ilg.DefineLabel();
  2678. if (readOnly) {
  2679. ilg.Load(ilg.GetVariable(member.ArrayName));
  2680. ilg.Load(null);
  2681. ilg.Beq(labelTrue);
  2682. }
  2683. else {
  2684. }
  2685. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  2686. "get_Reader",
  2687. CodeGenerator.InstanceBindingFlags,
  2688. null,
  2689. CodeGenerator.EmptyTypeArray,
  2690. null
  2691. );
  2692. MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
  2693. "get_IsEmptyElement",
  2694. CodeGenerator.InstanceBindingFlags,
  2695. null,
  2696. CodeGenerator.EmptyTypeArray,
  2697. null
  2698. );
  2699. ilg.Ldarg(0);
  2700. ilg.Call(XmlSerializationReader_get_Reader);
  2701. ilg.Call(XmlReader_get_IsEmptyElement);
  2702. if (readOnly) {
  2703. ilg.Br_S(labelEnd);
  2704. ilg.MarkLabel(labelTrue);
  2705. ilg.Ldc(true);
  2706. ilg.MarkLabel(labelEnd);
  2707. }
  2708. ilg.If();
  2709. MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
  2710. "Skip",
  2711. CodeGenerator.InstanceBindingFlags,
  2712. null,
  2713. CodeGenerator.EmptyTypeArray,
  2714. null
  2715. );
  2716. ilg.Ldarg(0);
  2717. ilg.Call(XmlSerializationReader_get_Reader);
  2718. ilg.Call(XmlReader_Skip);
  2719. ilg.Else();
  2720. MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
  2721. "ReadStartElement",
  2722. CodeGenerator.InstanceBindingFlags,
  2723. null,
  2724. CodeGenerator.EmptyTypeArray,
  2725. null
  2726. );
  2727. ilg.Ldarg(0);
  2728. ilg.Call(XmlSerializationReader_get_Reader);
  2729. ilg.Call(XmlReader_ReadStartElement);
  2730. int loopIndex = WriteWhileNotLoopStart();
  2731. string unknownNode = "UnknownNode(null, " + ExpectedElements(members) + ");";
  2732. WriteMemberElements(members, unknownNode, unknownNode, null, null);
  2733. MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
  2734. "MoveToContent",
  2735. CodeGenerator.InstanceBindingFlags,
  2736. null,
  2737. CodeGenerator.EmptyTypeArray,
  2738. null
  2739. );
  2740. ilg.Ldarg(0);
  2741. ilg.Call(XmlSerializationReader_get_Reader);
  2742. ilg.Call(XmlReader_MoveToContent);
  2743. ilg.Pop();
  2744. WriteWhileLoopEnd(loopIndex);
  2745. MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
  2746. "ReadEndElement",
  2747. CodeGenerator.InstanceBindingFlags,
  2748. null,
  2749. CodeGenerator.EmptyTypeArray,
  2750. null
  2751. );
  2752. ilg.Ldarg(0);
  2753. ilg.Call(XmlSerializationReader_ReadEndElement);
  2754. ilg.EndIf();
  2755. WriteMemberEnd(members, false);
  2756. if (isNullable) {
  2757. ilg.Else();
  2758. member.IsNullable = true;
  2759. WriteMemberBegin(members);
  2760. WriteMemberEnd(members);
  2761. }
  2762. ilg.EndIf();
  2763. }
  2764. void WriteElement(string source, string arrayName, string choiceSource, ElementAccessor element, ChoiceIdentifierAccessor choice, string checkSpecified, bool checkForNull, bool readOnly, int fixupIndex, int elementIndex) {
  2765. if (checkSpecified != null && checkSpecified.Length > 0) {
  2766. ILGenSet(checkSpecified, true);
  2767. }
  2768. if (element.Mapping is ArrayMapping) {
  2769. WriteArray(source, arrayName, (ArrayMapping)element.Mapping, readOnly, element.IsNullable, fixupIndex, elementIndex);
  2770. }
  2771. else if (element.Mapping is NullableMapping) {
  2772. string methodName = ReferenceMapping(element.Mapping);
  2773. #if DEBUG
  2774. // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  2775. if (methodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, element.Mapping.TypeDesc.Name));
  2776. #endif
  2777. WriteSourceBegin(source);
  2778. ilg.Ldarg(0);
  2779. ilg.Ldc(true);
  2780. MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
  2781. methodName,
  2782. CodeGenerator.PrivateMethodAttributes,
  2783. // See WriteNullableMethod for different return type logic
  2784. element.Mapping.TypeDesc.Type,
  2785. new Type[] { typeof(Boolean) }
  2786. );
  2787. ilg.Call(methodBuilder);
  2788. WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
  2789. }
  2790. else if (element.Mapping is PrimitiveMapping) {
  2791. bool doEndIf = false;
  2792. if (element.IsNullable) {
  2793. MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
  2794. "ReadNull",
  2795. CodeGenerator.InstanceBindingFlags,
  2796. null,
  2797. CodeGenerator.EmptyTypeArray,
  2798. null
  2799. );
  2800. ilg.Ldarg(0);
  2801. ilg.Call(XmlSerializationReader_ReadNull);
  2802. ilg.If();
  2803. WriteSourceBegin(source);
  2804. if (element.Mapping.TypeDesc.IsValueType) {
  2805. throw CodeGenerator.NotSupported("No such condition. PrimitiveMapping && IsNullable = String, XmlQualifiedName and never IsValueType");
  2806. }
  2807. else {
  2808. ilg.Load(null);
  2809. }
  2810. WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
  2811. ilg.Else();
  2812. doEndIf = true;
  2813. }
  2814. if (element.Default != null && element.Default != DBNull.Value && element.Mapping.TypeDesc.IsValueType) {
  2815. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  2816. "get_Reader",
  2817. CodeGenerator.InstanceBindingFlags,
  2818. null,
  2819. CodeGenerator.EmptyTypeArray,
  2820. null
  2821. );
  2822. MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
  2823. "get_IsEmptyElement",
  2824. CodeGenerator.InstanceBindingFlags,
  2825. null,
  2826. CodeGenerator.EmptyTypeArray,
  2827. null
  2828. );
  2829. ilg.Ldarg(0);
  2830. ilg.Call(XmlSerializationReader_get_Reader);
  2831. ilg.Call(XmlReader_get_IsEmptyElement);
  2832. ilg.If();
  2833. MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
  2834. "Skip",
  2835. CodeGenerator.InstanceBindingFlags,
  2836. null,
  2837. CodeGenerator.EmptyTypeArray,
  2838. null
  2839. );
  2840. ilg.Ldarg(0);
  2841. ilg.Call(XmlSerializationReader_get_Reader);
  2842. ilg.Call(XmlReader_Skip);
  2843. ilg.Else();
  2844. doEndIf = true;
  2845. }
  2846. else {
  2847. }
  2848. //For backward compatibiity
  2849. //When using old serializer, the serialized TimeSpan value is empty string
  2850. if (LocalAppContextSwitches.EnableTimeSpanSerialization && element.Mapping.TypeDesc.Type == typeof(TimeSpan))
  2851. {
  2852. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  2853. "get_Reader",
  2854. CodeGenerator.InstanceBindingFlags,
  2855. null,
  2856. CodeGenerator.EmptyTypeArray,
  2857. null
  2858. );
  2859. MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
  2860. "get_IsEmptyElement",
  2861. CodeGenerator.InstanceBindingFlags,
  2862. null,
  2863. CodeGenerator.EmptyTypeArray,
  2864. null
  2865. );
  2866. ilg.Ldarg(0);
  2867. ilg.Call(XmlSerializationReader_get_Reader);
  2868. ilg.Call(XmlReader_get_IsEmptyElement);
  2869. ilg.If();
  2870. WriteSourceBegin(source);
  2871. MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
  2872. "Skip",
  2873. CodeGenerator.InstanceBindingFlags,
  2874. null,
  2875. CodeGenerator.EmptyTypeArray,
  2876. null
  2877. );
  2878. ilg.Ldarg(0);
  2879. ilg.Call(XmlSerializationReader_get_Reader);
  2880. ilg.Call(XmlReader_Skip);
  2881. ConstructorInfo TimeSpan_ctor = typeof(TimeSpan).GetConstructor(
  2882. CodeGenerator.InstanceBindingFlags,
  2883. null,
  2884. new Type[] { typeof(Int64) },
  2885. null
  2886. );
  2887. ilg.Ldc(default(TimeSpan).Ticks);
  2888. ilg.New(TimeSpan_ctor);
  2889. WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
  2890. ilg.Else();
  2891. WriteSourceBegin(source);
  2892. WritePrimitive(element.Mapping, "Reader.ReadElementString()");
  2893. WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
  2894. ilg.EndIf();
  2895. }
  2896. else
  2897. {
  2898. WriteSourceBegin(source);
  2899. if (element.Mapping.TypeDesc == QnameTypeDesc) {
  2900. MethodInfo XmlSerializationReader_ReadElementQualifiedName = typeof(XmlSerializationReader).GetMethod(
  2901. "ReadElementQualifiedName",
  2902. CodeGenerator.InstanceBindingFlags,
  2903. null,
  2904. CodeGenerator.EmptyTypeArray,
  2905. null
  2906. );
  2907. ilg.Ldarg(0);
  2908. ilg.Call(XmlSerializationReader_ReadElementQualifiedName);
  2909. }
  2910. else {
  2911. string readFunc;
  2912. switch (element.Mapping.TypeDesc.FormatterName) {
  2913. case "ByteArrayBase64":
  2914. case "ByteArrayHex":
  2915. readFunc = "false";
  2916. break;
  2917. default:
  2918. readFunc = "Reader.ReadElementString()";
  2919. break;
  2920. }
  2921. WritePrimitive(element.Mapping, readFunc);
  2922. }
  2923. WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
  2924. }
  2925. if (doEndIf)
  2926. ilg.EndIf();
  2927. }
  2928. else if (element.Mapping is StructMapping) {
  2929. TypeMapping mapping = element.Mapping;
  2930. string methodName = ReferenceMapping(mapping);
  2931. #if DEBUG
  2932. // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  2933. if (methodName == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name));
  2934. #endif
  2935. if (checkForNull) {
  2936. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  2937. "get_Reader",
  2938. CodeGenerator.InstanceBindingFlags,
  2939. null,
  2940. CodeGenerator.EmptyTypeArray,
  2941. null
  2942. );
  2943. MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
  2944. "Skip",
  2945. CodeGenerator.InstanceBindingFlags,
  2946. null,
  2947. CodeGenerator.EmptyTypeArray,
  2948. null
  2949. );
  2950. ilg.Ldloc(arrayName);
  2951. ilg.Load(null);
  2952. ilg.If(Cmp.EqualTo);
  2953. ilg.Ldarg(0);
  2954. ilg.Call(XmlSerializationReader_get_Reader);
  2955. ilg.Call(XmlReader_Skip);
  2956. ilg.Else();
  2957. }
  2958. WriteSourceBegin(source);
  2959. List<Type> argTypes = new List<Type>();
  2960. ilg.Ldarg(0);
  2961. if (mapping.TypeDesc.IsNullable) {
  2962. ilg.Load(element.IsNullable);
  2963. argTypes.Add(typeof(Boolean));
  2964. }
  2965. ilg.Ldc(true);
  2966. argTypes.Add(typeof(Boolean));
  2967. MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
  2968. methodName,
  2969. CodeGenerator.PrivateMethodAttributes,
  2970. mapping.TypeDesc.Type,
  2971. argTypes.ToArray()
  2972. );
  2973. ilg.Call(methodBuilder);
  2974. WriteSourceEnd(source, mapping.TypeDesc.Type);
  2975. if (checkForNull)
  2976. // 'If' begins in checkForNull above
  2977. ilg.EndIf();
  2978. }
  2979. else if (element.Mapping is SpecialMapping) {
  2980. SpecialMapping special = (SpecialMapping)element.Mapping;
  2981. switch (special.TypeDesc.Kind) {
  2982. case TypeKind.Node:
  2983. bool isDoc = special.TypeDesc.FullName == typeof(XmlDocument).FullName;
  2984. WriteSourceBeginTyped(source, special.TypeDesc);
  2985. MethodInfo XmlSerializationReader_ReadXmlXXX = typeof(XmlSerializationReader).GetMethod(
  2986. isDoc ? "ReadXmlDocument" : "ReadXmlNode",
  2987. CodeGenerator.InstanceBindingFlags,
  2988. null,
  2989. new Type[] { typeof(Boolean) },
  2990. null
  2991. );
  2992. ilg.Ldarg(0);
  2993. ilg.Ldc(element.Any ? false : true);
  2994. ilg.Call(XmlSerializationReader_ReadXmlXXX);
  2995. // See logic in WriteSourceBeginTyped whether or not to castclass.
  2996. if (special.TypeDesc != null)
  2997. ilg.Castclass(special.TypeDesc.Type);
  2998. WriteSourceEnd(source, special.TypeDesc.Type);
  2999. break;
  3000. case TypeKind.Serializable:
  3001. SerializableMapping sm = (SerializableMapping)element.Mapping;
  3002. // check to see if we need to do the derivation
  3003. if (sm.DerivedMappings != null) {
  3004. MethodInfo XmlSerializationReader_GetXsiType = typeof(XmlSerializationReader).GetMethod(
  3005. "GetXsiType",
  3006. CodeGenerator.InstanceBindingFlags,
  3007. null,
  3008. CodeGenerator.EmptyTypeArray,
  3009. null
  3010. );
  3011. Label labelTrue = ilg.DefineLabel();
  3012. Label labelEnd = ilg.DefineLabel();
  3013. LocalBuilder tserLoc = ilg.DeclareOrGetLocal(typeof(XmlQualifiedName), "tser");
  3014. ilg.Ldarg(0);
  3015. ilg.Call(XmlSerializationReader_GetXsiType);
  3016. ilg.Stloc(tserLoc);
  3017. ilg.Ldloc(tserLoc);
  3018. ilg.Load(null);
  3019. ilg.Ceq();
  3020. ilg.Brtrue(labelTrue);
  3021. WriteQNameEqual("tser", sm.XsiType.Name, sm.XsiType.Namespace);
  3022. ilg.Br_S(labelEnd);
  3023. ilg.MarkLabel(labelTrue);
  3024. ilg.Ldc(true);
  3025. ilg.MarkLabel(labelEnd);
  3026. ilg.If();
  3027. }
  3028. WriteSourceBeginTyped(source, sm.TypeDesc);
  3029. bool isWrappedAny = !element.Any && IsWildcard(sm);
  3030. MethodInfo XmlSerializationReader_ReadSerializable = typeof(XmlSerializationReader).GetMethod(
  3031. "ReadSerializable",
  3032. CodeGenerator.InstanceBindingFlags,
  3033. null,
  3034. isWrappedAny ? new Type[] { typeof(IXmlSerializable), typeof(Boolean) } : new Type[] { typeof(IXmlSerializable) },
  3035. null
  3036. );
  3037. ilg.Ldarg(0);
  3038. RaCodeGen.ILGenForCreateInstance(ilg, sm.TypeDesc.Type, sm.TypeDesc.CannotNew, false);
  3039. if (sm.TypeDesc.CannotNew)
  3040. ilg.ConvertValue(typeof(object), typeof(IXmlSerializable));
  3041. if (isWrappedAny)
  3042. ilg.Ldc(true);
  3043. ilg.Call(XmlSerializationReader_ReadSerializable);
  3044. // See logic in WriteSourceBeginTyped whether or not to castclass.
  3045. if (sm.TypeDesc != null)
  3046. ilg.ConvertValue(typeof(IXmlSerializable), sm.TypeDesc.Type);
  3047. WriteSourceEnd(source, sm.TypeDesc.Type);
  3048. if (sm.DerivedMappings != null) {
  3049. WriteDerivedSerializable(sm, sm, source, isWrappedAny);
  3050. WriteUnknownNode("UnknownNode", "null", null, true);
  3051. }
  3052. break;
  3053. default:
  3054. throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  3055. }
  3056. }
  3057. else {
  3058. throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  3059. }
  3060. if (choice != null) {
  3061. #if DEBUG
  3062. // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  3063. if (choiceSource == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "need parent for the " + source));
  3064. #endif
  3065. WriteSourceBegin(choiceSource);
  3066. CodeIdentifier.CheckValidIdentifier(choice.MemberIds[elementIndex]);
  3067. RaCodeGen.ILGenForEnumMember(ilg, choice.Mapping.TypeDesc.Type, choice.MemberIds[elementIndex]);
  3068. WriteSourceEnd(choiceSource, choice.Mapping.TypeDesc.Type);
  3069. }
  3070. }
  3071. void WriteDerivedSerializable(SerializableMapping head, SerializableMapping mapping, string source, bool isWrappedAny) {
  3072. if (mapping == null)
  3073. return;
  3074. for (SerializableMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) {
  3075. Label labelTrue = ilg.DefineLabel();
  3076. Label labelEnd = ilg.DefineLabel();
  3077. LocalBuilder tserLoc = ilg.GetLocal("tser");
  3078. ilg.InitElseIf();
  3079. ilg.Ldloc(tserLoc);
  3080. ilg.Load(null);
  3081. ilg.Ceq();
  3082. ilg.Brtrue(labelTrue);
  3083. WriteQNameEqual("tser", derived.XsiType.Name, derived.XsiType.Namespace);
  3084. ilg.Br_S(labelEnd);
  3085. ilg.MarkLabel(labelTrue);
  3086. ilg.Ldc(true);
  3087. ilg.MarkLabel(labelEnd);
  3088. ilg.AndIf();
  3089. if (derived.Type != null) {
  3090. if (head.Type.IsAssignableFrom(derived.Type)) {
  3091. WriteSourceBeginTyped(source, head.TypeDesc);
  3092. MethodInfo XmlSerializationReader_ReadSerializable = typeof(XmlSerializationReader).GetMethod(
  3093. "ReadSerializable",
  3094. CodeGenerator.InstanceBindingFlags,
  3095. null,
  3096. isWrappedAny ? new Type[] { typeof(IXmlSerializable), typeof(Boolean) } : new Type[] { typeof(IXmlSerializable) },
  3097. null
  3098. );
  3099. ilg.Ldarg(0);
  3100. RaCodeGen.ILGenForCreateInstance(ilg, derived.TypeDesc.Type, derived.TypeDesc.CannotNew, false);
  3101. if (derived.TypeDesc.CannotNew)
  3102. ilg.ConvertValue(typeof(object), typeof(IXmlSerializable));
  3103. if (isWrappedAny)
  3104. ilg.Ldc(true);
  3105. ilg.Call(XmlSerializationReader_ReadSerializable);
  3106. // See logic in WriteSourceBeginTyped whether or not to castclass.
  3107. if (head.TypeDesc != null)
  3108. ilg.ConvertValue(typeof(IXmlSerializable), head.TypeDesc.Type);
  3109. WriteSourceEnd(source, head.TypeDesc.Type);
  3110. }
  3111. else {
  3112. MethodInfo XmlSerializationReader_CreateBadDerivationException = typeof(XmlSerializationReader).GetMethod(
  3113. "CreateBadDerivationException",
  3114. CodeGenerator.InstanceBindingFlags,
  3115. null,
  3116. new Type[] { typeof(String), typeof(String), typeof(String), typeof(String), typeof(String), typeof(String) },
  3117. null
  3118. );
  3119. ilg.Ldarg(0);
  3120. ilg.Ldstr(derived.XsiType.Name);
  3121. ilg.Ldstr(derived.XsiType.Namespace);
  3122. ilg.Ldstr(head.XsiType.Name);
  3123. ilg.Ldstr(head.XsiType.Namespace);
  3124. ilg.Ldstr(derived.Type.FullName);
  3125. ilg.Ldstr(head.Type.FullName);
  3126. ilg.Call(XmlSerializationReader_CreateBadDerivationException);
  3127. ilg.Throw();
  3128. }
  3129. }
  3130. else {
  3131. MethodInfo XmlSerializationReader_CreateMissingIXmlSerializableType = typeof(XmlSerializationReader).GetMethod(
  3132. "CreateMissingIXmlSerializableType",
  3133. CodeGenerator.InstanceBindingFlags,
  3134. null,
  3135. new Type[] { typeof(String), typeof(String), typeof(String) },
  3136. null
  3137. );
  3138. ilg.Ldarg(0);
  3139. ilg.Ldstr(derived.XsiType.Name);
  3140. ilg.Ldstr(derived.XsiType.Namespace);
  3141. ilg.Ldstr(head.Type.FullName);
  3142. ilg.Call(XmlSerializationReader_CreateMissingIXmlSerializableType);
  3143. ilg.Throw();
  3144. }
  3145. WriteDerivedSerializable(head, derived, source, isWrappedAny);
  3146. }
  3147. }
  3148. int WriteWhileNotLoopStart() {
  3149. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  3150. "get_Reader",
  3151. CodeGenerator.InstanceBindingFlags,
  3152. null,
  3153. CodeGenerator.EmptyTypeArray,
  3154. null
  3155. );
  3156. MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
  3157. "MoveToContent",
  3158. CodeGenerator.InstanceBindingFlags,
  3159. null,
  3160. CodeGenerator.EmptyTypeArray,
  3161. null
  3162. );
  3163. ilg.Ldarg(0);
  3164. ilg.Call(XmlSerializationReader_get_Reader);
  3165. ilg.Call(XmlReader_MoveToContent);
  3166. ilg.Pop();
  3167. int loopIndex = WriteWhileLoopStartCheck();
  3168. ilg.WhileBegin();
  3169. return loopIndex;
  3170. }
  3171. void WriteWhileLoopEnd(int loopIndex) {
  3172. WriteWhileLoopEndCheck(loopIndex);
  3173. ilg.WhileBeginCondition();
  3174. {
  3175. int XmlNodeType_None = 0;
  3176. //int XmlNodeType_Element = 1;
  3177. int XmlNodeType_EndElement = 15;
  3178. MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
  3179. "get_Reader",
  3180. CodeGenerator.InstanceBindingFlags,
  3181. null,
  3182. CodeGenerator.EmptyTypeArray,
  3183. null
  3184. );
  3185. MethodInfo XmlReader_get_NodeType = typeof(XmlReader).GetMethod(
  3186. "get_NodeType",
  3187. CodeGenerator.InstanceBindingFlags,
  3188. null,
  3189. CodeGenerator.EmptyTypeArray,
  3190. null
  3191. );
  3192. Label labelFalse = ilg.DefineLabel();
  3193. Label labelEnd = ilg.DefineLabel();
  3194. ilg.Ldarg(0);
  3195. ilg.Call(XmlSerializationReader_get_Reader);
  3196. ilg.Call(XmlReader_get_NodeType);
  3197. ilg.Ldc(XmlNodeType_EndElement);
  3198. ilg.Beq(labelFalse);
  3199. ilg.Ldarg(0);
  3200. ilg.Call(XmlSerializationReader_get_Reader);
  3201. ilg.Call(XmlReader_get_NodeType);
  3202. ilg.Ldc(XmlNodeType_None);
  3203. ilg.Cne();
  3204. ilg.Br_S(labelEnd);
  3205. ilg.MarkLabel(labelFalse);
  3206. ilg.Ldc(false);
  3207. ilg.MarkLabel(labelEnd);
  3208. }
  3209. ilg.WhileEndCondition();
  3210. ilg.WhileEnd();
  3211. }
  3212. int WriteWhileLoopStartCheck() {
  3213. MethodInfo XmlSerializationReader_get_ReaderCount = typeof(XmlSerializationReader).GetMethod(
  3214. "get_ReaderCount",
  3215. CodeGenerator.InstanceBindingFlags,
  3216. null,
  3217. CodeGenerator.EmptyTypeArray,
  3218. null
  3219. );
  3220. ilg.Ldc(0);
  3221. ilg.Stloc(typeof(Int32), String.Format(CultureInfo.InvariantCulture, "whileIterations{0}", nextWhileLoopIndex));
  3222. ilg.Ldarg(0);
  3223. ilg.Call(XmlSerializationReader_get_ReaderCount);
  3224. ilg.Stloc(typeof(Int32), String.Format(CultureInfo.InvariantCulture, "readerCount{0}", nextWhileLoopIndex));
  3225. return nextWhileLoopIndex++;
  3226. }
  3227. void WriteWhileLoopEndCheck(int loopIndex) {
  3228. Type refIntType = Type.GetType("System.Int32&");
  3229. MethodInfo XmlSerializationReader_CheckReaderCount = typeof(XmlSerializationReader).GetMethod(
  3230. "CheckReaderCount",
  3231. CodeGenerator.InstanceBindingFlags,
  3232. null,
  3233. new Type[] { refIntType, refIntType },
  3234. null
  3235. );
  3236. ilg.Ldarg(0);
  3237. ilg.Ldloca(ilg.GetLocal(String.Format(CultureInfo.InvariantCulture, "whileIterations{0}", loopIndex)));
  3238. ilg.Ldloca(ilg.GetLocal(String.Format(CultureInfo.InvariantCulture, "readerCount{0}", loopIndex)));
  3239. ilg.Call(XmlSerializationReader_CheckReaderCount);
  3240. }
  3241. void WriteParamsRead(int length) {
  3242. LocalBuilder paramsRead = ilg.DeclareLocal(typeof(Boolean[]), "paramsRead");
  3243. ilg.NewArray(typeof(Boolean), length);
  3244. ilg.Stloc(paramsRead);
  3245. }
  3246. void WriteCreateMapping(TypeMapping mapping, string local) {
  3247. string fullTypeName = mapping.TypeDesc.CSharpName;
  3248. bool ctorInaccessible = mapping.TypeDesc.CannotNew;
  3249. LocalBuilder loc = ilg.DeclareLocal(
  3250. mapping.TypeDesc.Type,
  3251. local);
  3252. if (ctorInaccessible) {
  3253. ilg.BeginExceptionBlock();
  3254. }
  3255. RaCodeGen.ILGenForCreateInstance(ilg, mapping.TypeDesc.Type, mapping.TypeDesc.CannotNew, true);
  3256. ilg.Stloc(loc);
  3257. if (ctorInaccessible) {
  3258. ilg.Leave();
  3259. WriteCatchException(typeof(MissingMethodException));
  3260. MethodInfo XmlSerializationReader_CreateInaccessibleConstructorException = typeof(XmlSerializationReader).GetMethod(
  3261. "CreateInaccessibleConstructorException",
  3262. CodeGenerator.InstanceBindingFlags,
  3263. null,
  3264. new Type[] { typeof(String) },
  3265. null
  3266. );
  3267. ilg.Ldarg(0);
  3268. ilg.Ldstr(fullTypeName);
  3269. ilg.Call(XmlSerializationReader_CreateInaccessibleConstructorException);
  3270. ilg.Throw();
  3271. WriteCatchException(typeof(SecurityException));
  3272. MethodInfo XmlSerializationReader_CreateCtorHasSecurityException = typeof(XmlSerializationReader).GetMethod(
  3273. "CreateCtorHasSecurityException",
  3274. CodeGenerator.InstanceBindingFlags,
  3275. null,
  3276. new Type[] { typeof(String) },
  3277. null
  3278. );
  3279. ilg.Ldarg(0);
  3280. ilg.Ldstr(fullTypeName);
  3281. ilg.Call(XmlSerializationReader_CreateCtorHasSecurityException);
  3282. ilg.Throw();
  3283. ilg.EndExceptionBlock();
  3284. }
  3285. }
  3286. void WriteCatchException(Type exceptionType) {
  3287. ilg.BeginCatchBlock(exceptionType);
  3288. ilg.Pop();
  3289. }
  3290. void WriteCatchCastException(TypeDesc typeDesc, string source, string id) {
  3291. WriteCatchException(typeof(InvalidCastException));
  3292. MethodInfo XmlSerializationReader_CreateInvalidCastException = typeof(XmlSerializationReader).GetMethod(
  3293. "CreateInvalidCastException",
  3294. CodeGenerator.InstanceBindingFlags,
  3295. null,
  3296. new Type[] { typeof(Type), typeof(Object), typeof(String) },
  3297. null
  3298. );
  3299. ilg.Ldarg(0);
  3300. ilg.Ldc(typeDesc.Type);
  3301. // GetTarget(ids[0])
  3302. if (source.StartsWith("GetTarget(ids[", StringComparison.Ordinal)) {
  3303. MethodInfo XmlSerializationReader_GetTarget = typeof(XmlSerializationReader).GetMethod(
  3304. "GetTarget",
  3305. CodeGenerator.InstanceBindingFlags,
  3306. null,
  3307. new Type[] { typeof(String) },
  3308. null
  3309. );
  3310. object idsLoc = ilg.GetVariable("ids");
  3311. ilg.Ldarg(0);
  3312. // Parse index
  3313. ilg.LoadArrayElement(idsLoc, Int32.Parse(source.Substring(14, source.Length - 16), CultureInfo.InvariantCulture));
  3314. ilg.Call(XmlSerializationReader_GetTarget);
  3315. }
  3316. else {
  3317. ilg.Load(ilg.GetVariable(source));
  3318. }
  3319. if (id == null)
  3320. ilg.Load(null);
  3321. else {
  3322. // ids[0]
  3323. if (id.StartsWith("ids[", StringComparison.Ordinal)) {
  3324. object idsLoc = ilg.GetVariable("ids");
  3325. // Parse index
  3326. ilg.LoadArrayElement(idsLoc, Int32.Parse(id.Substring(4, id.Length - 5), CultureInfo.InvariantCulture));
  3327. }
  3328. else {
  3329. object idVar = ilg.GetVariable(id);
  3330. ilg.Load(idVar);
  3331. ilg.ConvertValue(ilg.GetVariableType(idVar), typeof(string));
  3332. }
  3333. }
  3334. ilg.Call(XmlSerializationReader_CreateInvalidCastException);
  3335. ilg.Throw();
  3336. }
  3337. void WriteArrayLocalDecl(string typeName, string variableName, string initValue, TypeDesc arrayTypeDesc) {
  3338. RaCodeGen.WriteArrayLocalDecl(typeName, variableName, new SourceInfo(initValue, initValue, null, arrayTypeDesc.Type, ilg), arrayTypeDesc);
  3339. }
  3340. void WriteCreateInstance(string source, bool ctorInaccessible, Type type) {
  3341. RaCodeGen.WriteCreateInstance(source, ctorInaccessible, type, ilg);
  3342. }
  3343. void WriteLocalDecl(string variableName, SourceInfo initValue) {
  3344. RaCodeGen.WriteLocalDecl(variableName, initValue);
  3345. }
  3346. void ILGenElseString(string elseString) {
  3347. MethodInfo XmlSerializationReader_UnknownNode1 = typeof(XmlSerializationReader).GetMethod(
  3348. "UnknownNode",
  3349. CodeGenerator.InstanceBindingFlags,
  3350. null,
  3351. new Type[] { typeof(object) },
  3352. null
  3353. );
  3354. MethodInfo XmlSerializationReader_UnknownNode2 = typeof(XmlSerializationReader).GetMethod(
  3355. "UnknownNode",
  3356. CodeGenerator.InstanceBindingFlags,
  3357. null,
  3358. new Type[] { typeof(object), typeof(string) },
  3359. null
  3360. );
  3361. // UnknownNode(null, @":anyType");
  3362. Regex regex = NewRegex("UnknownNode[(]null, @[\"](?<qnames>[^\"]*)[\"][)];");
  3363. Match match = regex.Match(elseString);
  3364. if (match.Success) {
  3365. ilg.Ldarg(0);
  3366. ilg.Load(null);
  3367. ilg.Ldstr(match.Groups["qnames"].Value);
  3368. ilg.Call(XmlSerializationReader_UnknownNode2);
  3369. return;
  3370. }
  3371. // UnknownNode((object)o, @"");
  3372. regex = NewRegex("UnknownNode[(][(]object[)](?<o>[^,]+), @[\"](?<qnames>[^\"]*)[\"][)];");
  3373. match = regex.Match(elseString);
  3374. if (match.Success) {
  3375. ilg.Ldarg(0);
  3376. LocalBuilder localO = ilg.GetLocal(match.Groups["o"].Value);
  3377. ilg.Ldloc(localO);
  3378. ilg.ConvertValue(localO.LocalType, typeof(object));
  3379. ilg.Ldstr(match.Groups["qnames"].Value);
  3380. ilg.Call(XmlSerializationReader_UnknownNode2);
  3381. return;
  3382. }
  3383. // UnknownNode((object)o, null);
  3384. regex = NewRegex("UnknownNode[(][(]object[)](?<o>[^,]+), null[)];");
  3385. match = regex.Match(elseString);
  3386. if (match.Success) {
  3387. ilg.Ldarg(0);
  3388. LocalBuilder localO = ilg.GetLocal(match.Groups["o"].Value);
  3389. ilg.Ldloc(localO);
  3390. ilg.ConvertValue(localO.LocalType, typeof(object));
  3391. ilg.Load(null);
  3392. ilg.Call(XmlSerializationReader_UnknownNode2);
  3393. return;
  3394. }
  3395. // "UnknownNode((object)o);"
  3396. regex = NewRegex("UnknownNode[(][(]object[)](?<o>[^)]+)[)];");
  3397. match = regex.Match(elseString);
  3398. if (match.Success) {
  3399. ilg.Ldarg(0);
  3400. LocalBuilder localO = ilg.GetLocal(match.Groups["o"].Value);
  3401. ilg.Ldloc(localO);
  3402. ilg.ConvertValue(localO.LocalType, typeof(object));
  3403. ilg.Call(XmlSerializationReader_UnknownNode1);
  3404. return;
  3405. }
  3406. throw CodeGenerator.NotSupported("Unexpected: " + elseString);
  3407. }
  3408. void ILGenParamsReadSource(string paramsReadSource) {
  3409. Regex regex = NewRegex("paramsRead\\[(?<index>[0-9]+)\\]");
  3410. Match match = regex.Match(paramsReadSource);
  3411. if (match.Success) {
  3412. ilg.LoadArrayElement(ilg.GetLocal("paramsRead"), Int32.Parse(match.Groups["index"].Value, CultureInfo.InvariantCulture));
  3413. return;
  3414. }
  3415. throw CodeGenerator.NotSupported("Unexpected: " + paramsReadSource);
  3416. }
  3417. void ILGenParamsReadSource(string paramsReadSource, bool value) {
  3418. Regex regex = NewRegex("paramsRead\\[(?<index>[0-9]+)\\]");
  3419. Match match = regex.Match(paramsReadSource);
  3420. if (match.Success) {
  3421. ilg.StoreArrayElement(ilg.GetLocal("paramsRead"), Int32.Parse(match.Groups["index"].Value, CultureInfo.InvariantCulture), value);
  3422. return;
  3423. }
  3424. throw CodeGenerator.NotSupported("Unexpected: " + paramsReadSource);
  3425. }
  3426. void ILGenElementElseString(string elementElseString) {
  3427. if (elementElseString == "throw CreateUnknownNodeException();") {
  3428. MethodInfo XmlSerializationReader_CreateUnknownNodeException = typeof(XmlSerializationReader).GetMethod(
  3429. "CreateUnknownNodeException",
  3430. CodeGenerator.InstanceBindingFlags,
  3431. null,
  3432. CodeGenerator.EmptyTypeArray,
  3433. null
  3434. );
  3435. ilg.Ldarg(0);
  3436. ilg.Call(XmlSerializationReader_CreateUnknownNodeException);
  3437. ilg.Throw();
  3438. return;
  3439. }
  3440. if (elementElseString.StartsWith("UnknownNode(", StringComparison.Ordinal)) {
  3441. ILGenElseString(elementElseString);
  3442. return;
  3443. }
  3444. throw CodeGenerator.NotSupported("Unexpected: " + elementElseString);
  3445. }
  3446. void ILGenSet(string source, object value) {
  3447. WriteSourceBegin(source);
  3448. ilg.Load(value);
  3449. WriteSourceEnd(source, value == null ? typeof(object) : value.GetType());
  3450. }
  3451. }
  3452. }