XmlSerializer.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. //
  2. // XmlSerializer.cs:
  3. //
  4. // Author:
  5. // Lluis Sanchez Gual ([email protected])
  6. //
  7. // (C) 2002, 2003 Ximian, Inc. http://www.ximian.com
  8. //
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. using System;
  30. using System.Threading;
  31. using System.Collections;
  32. using System.Globalization;
  33. using System.IO;
  34. using System.Reflection;
  35. using System.Xml;
  36. using System.Xml.Schema;
  37. using System.Text;
  38. #if !TARGET_JVM
  39. using System.CodeDom;
  40. using System.CodeDom.Compiler;
  41. using Microsoft.CSharp;
  42. #endif
  43. using System.Configuration;
  44. using System.Security.Policy;
  45. namespace System.Xml.Serialization
  46. {
  47. public class XmlSerializer
  48. {
  49. internal const string WsdlNamespace = "http://schemas.xmlsoap.org/wsdl/";
  50. internal const string EncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";
  51. static int generationThreshold;
  52. static bool backgroundGeneration = true;
  53. static bool deleteTempFiles = true;
  54. static bool generatorFallback = true;
  55. bool customSerializer;
  56. XmlMapping typeMapping;
  57. SerializerData serializerData;
  58. static Hashtable serializerTypes = new Hashtable ();
  59. internal class SerializerData
  60. {
  61. public int UsageCount;
  62. public Type ReaderType;
  63. public MethodInfo ReaderMethod;
  64. public Type WriterType;
  65. public MethodInfo WriterMethod;
  66. public GenerationBatch Batch;
  67. public IXmlSerializerImplementation Implementation = null;
  68. public XmlSerializationReader CreateReader () {
  69. if (ReaderType != null)
  70. return (XmlSerializationReader) Activator.CreateInstance (ReaderType);
  71. else if (Implementation != null)
  72. return Implementation.Reader;
  73. else
  74. return null;
  75. }
  76. public XmlSerializationWriter CreateWriter () {
  77. if (WriterType != null)
  78. return (XmlSerializationWriter) Activator.CreateInstance (WriterType);
  79. else if (Implementation != null)
  80. return Implementation.Writer;
  81. else
  82. return null;
  83. }
  84. }
  85. internal class GenerationBatch
  86. {
  87. public bool Done;
  88. public XmlMapping[] Maps;
  89. public SerializerData[] Datas;
  90. }
  91. static XmlSerializer ()
  92. {
  93. // The following options are available:
  94. // MONO_XMLSERIALIZER_DEBUG: when set to something != "no", it will
  95. // it will print the name of the generated file, and it won't
  96. // be deleted.
  97. // MONO_XMLSERIALIZER_THS: The code generator threshold. It can be:
  98. // no: does not use the generator, always the interpreter.
  99. // 0: always use the generator, wait until the generation is done.
  100. // any number: use the interpreted serializer until the specified
  101. // number of serializations is reached. At this point the generation
  102. // of the serializer will start in the background. The interpreter
  103. // will be used while the serializer is being generated.
  104. //
  105. // XmlSerializer will fall back to the interpreted serializer if
  106. // the code generation somehow fails. This can be avoided for
  107. // debugging pourposes by adding the "nofallback" option.
  108. // For example: MONO_XMLSERIALIZER_THS=0,nofallback
  109. #if TARGET_JVM
  110. string db = null;
  111. string th = null;
  112. generationThreshold = -1;
  113. backgroundGeneration = false;
  114. #else
  115. string db = Environment.GetEnvironmentVariable ("MONO_XMLSERIALIZER_DEBUG");
  116. string th = Environment.GetEnvironmentVariable ("MONO_XMLSERIALIZER_THS");
  117. if (th == null) {
  118. generationThreshold = 50;
  119. backgroundGeneration = true;
  120. } else {
  121. int i = th.IndexOf (',');
  122. if (i != -1) {
  123. if (th.Substring (i+1) == "nofallback")
  124. generatorFallback = false;
  125. th = th.Substring (0, i);
  126. }
  127. if (th.ToLower(CultureInfo.InvariantCulture) == "no")
  128. generationThreshold = -1;
  129. else {
  130. generationThreshold = int.Parse (th, CultureInfo.InvariantCulture);
  131. backgroundGeneration = (generationThreshold != 0);
  132. if (generationThreshold < 1) generationThreshold = 1;
  133. }
  134. }
  135. #endif
  136. deleteTempFiles = (db == null || db == "no");
  137. IDictionary table = (IDictionary) ConfigurationSettings.GetConfig("system.diagnostics");
  138. if (table != null)
  139. {
  140. table = (IDictionary) table["switches"];
  141. if (table != null)
  142. {
  143. string val = (string) table ["XmlSerialization.Compilation"];
  144. if (val == "1") deleteTempFiles = false;
  145. }
  146. }
  147. }
  148. #region Constructors
  149. protected XmlSerializer ()
  150. {
  151. customSerializer = true;
  152. }
  153. public XmlSerializer (Type type)
  154. : this (type, null, null, null, null)
  155. {
  156. }
  157. public XmlSerializer (XmlTypeMapping xmlTypeMapping)
  158. {
  159. typeMapping = xmlTypeMapping;
  160. }
  161. internal XmlSerializer (XmlMapping mapping, SerializerData data)
  162. {
  163. typeMapping = mapping;
  164. serializerData = data;
  165. }
  166. public XmlSerializer (Type type, string defaultNamespace)
  167. : this (type, null, null, null, defaultNamespace)
  168. {
  169. }
  170. public XmlSerializer (Type type, Type[] extraTypes)
  171. : this (type, null, extraTypes, null, null)
  172. {
  173. }
  174. public XmlSerializer (Type type, XmlAttributeOverrides overrides)
  175. : this (type, overrides, null, null, null)
  176. {
  177. }
  178. public XmlSerializer (Type type, XmlRootAttribute root)
  179. : this (type, null, null, root, null)
  180. {
  181. }
  182. public XmlSerializer (Type type,
  183. XmlAttributeOverrides overrides,
  184. Type [] extraTypes,
  185. XmlRootAttribute root,
  186. string defaultNamespace)
  187. {
  188. if (type == null)
  189. throw new ArgumentNullException ("type");
  190. XmlReflectionImporter importer = new XmlReflectionImporter (overrides, defaultNamespace);
  191. if (extraTypes != null)
  192. {
  193. foreach (Type intype in extraTypes)
  194. importer.IncludeType (intype);
  195. }
  196. typeMapping = importer.ImportTypeMapping (type, root, defaultNamespace);
  197. }
  198. internal XmlMapping Mapping
  199. {
  200. get { return typeMapping; }
  201. }
  202. #if NET_2_0
  203. [MonoTODO]
  204. public XmlSerializer (Type type,
  205. XmlAttributeOverrides overrides,
  206. Type [] extraTypes,
  207. XmlRootAttribute root,
  208. string defaultNamespace,
  209. string location,
  210. Evidence evidence)
  211. {
  212. }
  213. #endif
  214. #endregion // Constructors
  215. #region Events
  216. private XmlAttributeEventHandler onUnknownAttribute;
  217. private XmlElementEventHandler onUnknownElement;
  218. private XmlNodeEventHandler onUnknownNode;
  219. private UnreferencedObjectEventHandler onUnreferencedObject;
  220. public event XmlAttributeEventHandler UnknownAttribute
  221. {
  222. add { onUnknownAttribute += value; } remove { onUnknownAttribute -= value; }
  223. }
  224. public event XmlElementEventHandler UnknownElement
  225. {
  226. add { onUnknownElement += value; } remove { onUnknownElement -= value; }
  227. }
  228. public event XmlNodeEventHandler UnknownNode
  229. {
  230. add { onUnknownNode += value; } remove { onUnknownNode -= value; }
  231. }
  232. public event UnreferencedObjectEventHandler UnreferencedObject
  233. {
  234. add { onUnreferencedObject += value; } remove { onUnreferencedObject -= value; }
  235. }
  236. internal virtual void OnUnknownAttribute (XmlAttributeEventArgs e)
  237. {
  238. if (onUnknownAttribute != null) onUnknownAttribute(this, e);
  239. }
  240. internal virtual void OnUnknownElement (XmlElementEventArgs e)
  241. {
  242. if (onUnknownElement != null) onUnknownElement(this, e);
  243. }
  244. internal virtual void OnUnknownNode (XmlNodeEventArgs e)
  245. {
  246. if (onUnknownNode != null) onUnknownNode(this, e);
  247. }
  248. internal virtual void OnUnreferencedObject (UnreferencedObjectEventArgs e)
  249. {
  250. if (onUnreferencedObject != null) onUnreferencedObject(this, e);
  251. }
  252. #endregion // Events
  253. #region Methods
  254. public virtual bool CanDeserialize (XmlReader xmlReader)
  255. {
  256. xmlReader.MoveToContent ();
  257. if (typeMapping is XmlMembersMapping)
  258. return true;
  259. else
  260. return ((XmlTypeMapping)typeMapping).ElementName == xmlReader.LocalName;
  261. }
  262. protected virtual XmlSerializationReader CreateReader ()
  263. {
  264. // Must be implemented in derived class
  265. throw new NotImplementedException ();
  266. }
  267. protected virtual XmlSerializationWriter CreateWriter ()
  268. {
  269. // Must be implemented in derived class
  270. throw new NotImplementedException ();
  271. }
  272. public object Deserialize (Stream stream)
  273. {
  274. XmlTextReader xmlReader = new XmlTextReader(stream);
  275. xmlReader.Normalization = true;
  276. return Deserialize(xmlReader);
  277. }
  278. public object Deserialize (TextReader textReader)
  279. {
  280. XmlTextReader xmlReader = new XmlTextReader(textReader);
  281. xmlReader.Normalization = true;
  282. return Deserialize(xmlReader);
  283. }
  284. public object Deserialize (XmlReader xmlReader)
  285. {
  286. XmlSerializationReader xsReader;
  287. if (customSerializer)
  288. xsReader = CreateReader ();
  289. else
  290. xsReader = CreateReader (typeMapping);
  291. xsReader.Initialize (xmlReader, this);
  292. return Deserialize (xsReader);
  293. }
  294. protected virtual object Deserialize (XmlSerializationReader reader)
  295. {
  296. if (customSerializer)
  297. // Must be implemented in derived class
  298. throw new NotImplementedException ();
  299. if (reader is XmlSerializationReaderInterpreter)
  300. return ((XmlSerializationReaderInterpreter)reader).ReadRoot ();
  301. else
  302. return serializerData.ReaderMethod.Invoke (reader, null);
  303. }
  304. public static XmlSerializer [] FromMappings (XmlMapping [] mappings)
  305. {
  306. XmlSerializer[] sers = new XmlSerializer [mappings.Length];
  307. SerializerData[] datas = new SerializerData [mappings.Length];
  308. GenerationBatch batch = new GenerationBatch ();
  309. batch.Maps = mappings;
  310. batch.Datas = datas;
  311. for (int n=0; n<mappings.Length; n++)
  312. {
  313. if (mappings[n] != null)
  314. {
  315. SerializerData data = new SerializerData ();
  316. data.Batch = batch;
  317. sers[n] = new XmlSerializer (mappings[n], data);
  318. datas[n] = data;
  319. }
  320. }
  321. return sers;
  322. }
  323. public static XmlSerializer [] FromTypes (Type [] mappings)
  324. {
  325. XmlSerializer [] sers = new XmlSerializer [mappings.Length];
  326. for (int n=0; n<mappings.Length; n++)
  327. sers[n] = new XmlSerializer (mappings[n]);
  328. return sers;
  329. }
  330. protected virtual void Serialize (object o, XmlSerializationWriter writer)
  331. {
  332. if (customSerializer)
  333. // Must be implemented in derived class
  334. throw new NotImplementedException ();
  335. if (writer is XmlSerializationWriterInterpreter)
  336. ((XmlSerializationWriterInterpreter)writer).WriteRoot (o);
  337. else
  338. serializerData.WriterMethod.Invoke (writer, new object[] {o});
  339. }
  340. public void Serialize (Stream stream, object o)
  341. {
  342. XmlTextWriter xmlWriter = new XmlTextWriter (stream, System.Text.Encoding.Default);
  343. xmlWriter.Formatting = Formatting.Indented;
  344. Serialize (xmlWriter, o, null);
  345. }
  346. public void Serialize (TextWriter textWriter, object o)
  347. {
  348. XmlTextWriter xmlWriter = new XmlTextWriter (textWriter);
  349. xmlWriter.Formatting = Formatting.Indented;
  350. Serialize (xmlWriter, o, null);
  351. }
  352. public void Serialize (XmlWriter xmlWriter, object o)
  353. {
  354. Serialize (xmlWriter, o, null);
  355. }
  356. public void Serialize (Stream stream, object o, XmlSerializerNamespaces namespaces)
  357. {
  358. XmlTextWriter xmlWriter = new XmlTextWriter (stream, System.Text.Encoding.Default);
  359. xmlWriter.Formatting = Formatting.Indented;
  360. Serialize (xmlWriter, o, namespaces);
  361. }
  362. public void Serialize (TextWriter textWriter, object o, XmlSerializerNamespaces namespaces)
  363. {
  364. XmlTextWriter xmlWriter = new XmlTextWriter (textWriter);
  365. xmlWriter.Formatting = Formatting.Indented;
  366. Serialize (xmlWriter, o, namespaces);
  367. xmlWriter.Flush();
  368. }
  369. public void Serialize (XmlWriter writer, object o, XmlSerializerNamespaces namespaces)
  370. {
  371. XmlSerializationWriter xsWriter;
  372. if (customSerializer)
  373. xsWriter = CreateWriter ();
  374. else
  375. xsWriter = CreateWriter (typeMapping);
  376. if (namespaces == null || namespaces.Count == 0)
  377. {
  378. namespaces = new XmlSerializerNamespaces ();
  379. namespaces.Add ("xsd", XmlSchema.Namespace);
  380. namespaces.Add ("xsi", XmlSchema.InstanceNamespace);
  381. }
  382. xsWriter.Initialize (writer, namespaces);
  383. Serialize (o, xsWriter);
  384. writer.Flush ();
  385. }
  386. #if NET_2_0
  387. [MonoTODO]
  388. public object Deserialize (XmlReader xmlReader, string encodingStyle, XmlDeserializationEvents events)
  389. {
  390. throw new NotImplementedException ();
  391. }
  392. [MonoTODO]
  393. public object Deserialize (XmlReader xmlReader, string encodingStyle)
  394. {
  395. throw new NotImplementedException ();
  396. }
  397. [MonoTODO]
  398. public object Deserialize (XmlReader xmlReader, XmlDeserializationEvents events)
  399. {
  400. throw new NotImplementedException ();
  401. }
  402. [MonoTODO]
  403. public static XmlSerializer[] FromMappings (XmlMapping[] mappings, Evidence evidence)
  404. {
  405. throw new NotImplementedException ();
  406. }
  407. [MonoTODO]
  408. public static XmlSerializer[] FromMappings (XmlMapping[] mappings, Type type)
  409. {
  410. throw new NotImplementedException ();
  411. }
  412. public static Assembly GenerateSerializer (Type[] types, XmlMapping[] mappings)
  413. {
  414. return GenerateSerializer (types, mappings, null);
  415. }
  416. [MonoTODO]
  417. public static Assembly GenerateSerializer (Type[] types, XmlMapping[] mappings, CompilerParameters parameters)
  418. {
  419. GenerationBatch batch = new GenerationBatch ();
  420. batch.Maps = mappings;
  421. batch.Datas = new SerializerData [mappings.Length];
  422. for (int n=0; n<mappings.Length; n++) {
  423. SerializerData data = new SerializerData ();
  424. data.Batch = batch;
  425. batch.Datas [n] = data;
  426. }
  427. return GenerateSerializers (batch, parameters);
  428. }
  429. [MonoTODO]
  430. [Obsolete]
  431. public static Assembly GenerateSerializer (Type[] types,
  432. XmlMapping[] mappings,
  433. string codePath,
  434. bool debug,
  435. bool keepFiles)
  436. {
  437. throw new NotImplementedException ();
  438. }
  439. [MonoTODO]
  440. [Obsolete]
  441. public static Assembly GenerateSerializer (Type[] types,
  442. XmlMapping[] mappings,
  443. string codePath,
  444. bool debug,
  445. bool keepFiles,
  446. string compilerOptions)
  447. {
  448. throw new NotImplementedException ();
  449. }
  450. public static string GetXmlSerializerAssemblyName (Type type)
  451. {
  452. return type.Assembly.GetName().Name + ".XmlSerializers";
  453. }
  454. public static string GetXmlSerializerAssemblyName (Type type, string defaultNamespace)
  455. {
  456. return GetXmlSerializerAssemblyName (type) + "." + defaultNamespace.GetHashCode ();
  457. }
  458. [MonoTODO]
  459. public void Serialize (XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces, string encodingStyle)
  460. {
  461. throw new NotImplementedException ();
  462. }
  463. #endif
  464. XmlSerializationWriter CreateWriter (XmlMapping typeMapping)
  465. {
  466. XmlSerializationWriter writer;
  467. lock (this) {
  468. if (serializerData != null) {
  469. lock (serializerData) {
  470. writer = serializerData.CreateWriter ();
  471. }
  472. if (writer != null) return writer;
  473. }
  474. }
  475. if (!typeMapping.Source.CanBeGenerated || generationThreshold == -1)
  476. return new XmlSerializationWriterInterpreter (typeMapping);
  477. CheckGeneratedTypes (typeMapping);
  478. lock (this) {
  479. lock (serializerData) {
  480. writer = serializerData.CreateWriter ();
  481. }
  482. if (writer != null) return writer;
  483. if (!generatorFallback)
  484. throw new InvalidOperationException ("Error while generating serializer");
  485. }
  486. return new XmlSerializationWriterInterpreter (typeMapping);
  487. }
  488. XmlSerializationReader CreateReader (XmlMapping typeMapping)
  489. {
  490. XmlSerializationReader reader;
  491. lock (this) {
  492. if (serializerData != null) {
  493. lock (serializerData) {
  494. reader = serializerData.CreateReader ();
  495. }
  496. if (reader != null) return reader;
  497. }
  498. }
  499. if (!typeMapping.Source.CanBeGenerated || generationThreshold == -1)
  500. return new XmlSerializationReaderInterpreter (typeMapping);
  501. CheckGeneratedTypes (typeMapping);
  502. lock (this) {
  503. lock (serializerData) {
  504. reader = serializerData.CreateReader ();
  505. }
  506. if (reader != null) return reader;
  507. if (!generatorFallback)
  508. throw new InvalidOperationException ("Error while generating serializer");
  509. }
  510. return new XmlSerializationReaderInterpreter (typeMapping);
  511. }
  512. #if TARGET_JVM
  513. void CheckGeneratedTypes (XmlMapping typeMapping)
  514. {
  515. throw new NotImplementedException();
  516. }
  517. void GenerateSerializersAsync (GenerationBatch batch)
  518. {
  519. throw new NotImplementedException();
  520. }
  521. void RunSerializerGeneration (object obj)
  522. {
  523. throw new NotImplementedException();
  524. }
  525. #else
  526. void CheckGeneratedTypes (XmlMapping typeMapping)
  527. {
  528. lock (this)
  529. {
  530. if (serializerData == null)
  531. {
  532. lock (serializerTypes)
  533. {
  534. serializerData = (SerializerData) serializerTypes [typeMapping.Source];
  535. if (serializerData == null) {
  536. serializerData = new SerializerData();
  537. serializerTypes [typeMapping.Source] = serializerData;
  538. }
  539. }
  540. }
  541. }
  542. bool generate = false;
  543. lock (serializerData)
  544. {
  545. generate = (++serializerData.UsageCount == generationThreshold);
  546. }
  547. if (generate)
  548. {
  549. if (serializerData.Batch != null)
  550. GenerateSerializersAsync (serializerData.Batch);
  551. else
  552. {
  553. GenerationBatch batch = new GenerationBatch ();
  554. batch.Maps = new XmlMapping[] {typeMapping};
  555. batch.Datas = new SerializerData[] {serializerData};
  556. GenerateSerializersAsync (batch);
  557. }
  558. }
  559. }
  560. void GenerateSerializersAsync (GenerationBatch batch)
  561. {
  562. if (batch.Maps.Length != batch.Datas.Length)
  563. throw new ArgumentException ("batch");
  564. lock (batch)
  565. {
  566. if (batch.Done) return;
  567. batch.Done = true;
  568. }
  569. if (backgroundGeneration)
  570. ThreadPool.QueueUserWorkItem (new WaitCallback (RunSerializerGeneration), batch);
  571. else
  572. RunSerializerGeneration (batch);
  573. }
  574. void RunSerializerGeneration (object obj)
  575. {
  576. try
  577. {
  578. GenerationBatch batch = (GenerationBatch) obj;
  579. batch = LoadFromSatelliteAssembly (batch);
  580. if (batch != null)
  581. GenerateSerializers (batch, null);
  582. }
  583. catch (Exception ex)
  584. {
  585. Console.WriteLine (ex);
  586. }
  587. }
  588. static Assembly GenerateSerializers (GenerationBatch batch, CompilerParameters cp)
  589. {
  590. DateTime tim = DateTime.Now;
  591. XmlMapping[] maps = batch.Maps;
  592. if (cp == null) {
  593. cp = new CompilerParameters();
  594. cp.IncludeDebugInformation = false;
  595. cp.GenerateInMemory = true;
  596. cp.TempFiles.KeepFiles = !deleteTempFiles;
  597. }
  598. string file = cp.TempFiles.AddExtension ("cs");
  599. StreamWriter sw = new StreamWriter (file);
  600. if (!deleteTempFiles)
  601. Console.WriteLine ("Generating " + file);
  602. SerializationCodeGenerator gen = new SerializationCodeGenerator (maps);
  603. try
  604. {
  605. gen.GenerateSerializers (sw);
  606. }
  607. catch (Exception ex)
  608. {
  609. Console.WriteLine ("Serializer could not be generated");
  610. Console.WriteLine (ex);
  611. cp.TempFiles.Delete ();
  612. return null;
  613. }
  614. sw.Close ();
  615. CSharpCodeProvider provider = new CSharpCodeProvider();
  616. ICodeCompiler comp = provider.CreateCompiler ();
  617. cp.GenerateExecutable = false;
  618. foreach (Type rtype in gen.ReferencedTypes)
  619. {
  620. if (!cp.ReferencedAssemblies.Contains (rtype.Assembly.Location))
  621. cp.ReferencedAssemblies.Add (rtype.Assembly.Location);
  622. }
  623. if (!cp.ReferencedAssemblies.Contains ("System.dll"))
  624. cp.ReferencedAssemblies.Add ("System.dll");
  625. if (!cp.ReferencedAssemblies.Contains ("System.Xml"))
  626. cp.ReferencedAssemblies.Add ("System.Xml");
  627. if (!cp.ReferencedAssemblies.Contains ("System.Data"))
  628. cp.ReferencedAssemblies.Add ("System.Data");
  629. CompilerResults res = comp.CompileAssemblyFromFile (cp, file);
  630. if (res.Errors.HasErrors || res.CompiledAssembly == null) {
  631. Console.WriteLine ("Error while compiling generated serializer");
  632. foreach (CompilerError error in res.Errors)
  633. Console.WriteLine (error);
  634. cp.TempFiles.Delete ();
  635. return null;
  636. }
  637. GenerationResult[] results = gen.GenerationResults;
  638. for (int n=0; n<results.Length; n++)
  639. {
  640. GenerationResult gres = results[n];
  641. SerializerData sd = batch.Datas [n];
  642. lock (sd)
  643. {
  644. sd.WriterType = res.CompiledAssembly.GetType (gres.Namespace + "." + gres.WriterClassName);
  645. sd.ReaderType = res.CompiledAssembly.GetType (gres.Namespace + "." + gres.ReaderClassName);
  646. sd.WriterMethod = sd.WriterType.GetMethod (gres.WriteMethodName);
  647. sd.ReaderMethod = sd.ReaderType.GetMethod (gres.ReadMethodName);
  648. sd.Batch = null;
  649. }
  650. }
  651. cp.TempFiles.Delete ();
  652. if (!deleteTempFiles)
  653. Console.WriteLine ("Generation finished - " + (DateTime.Now - tim).TotalMilliseconds + " ms");
  654. return res.CompiledAssembly;
  655. }
  656. #endif
  657. #if NET_2_0
  658. GenerationBatch LoadFromSatelliteAssembly (GenerationBatch batch)
  659. {
  660. return batch;
  661. }
  662. #else
  663. GenerationBatch LoadFromSatelliteAssembly (GenerationBatch batch)
  664. {
  665. return batch;
  666. }
  667. #endif
  668. #endregion // Methods
  669. }
  670. }