XmlSerializationReader.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. //
  2. // System.Xml.Serialization.XmlSerializationReader.cs
  3. //
  4. // Authors:
  5. // Tim Coleman ([email protected])
  6. // Gonzalo Paniagua Javier ([email protected])
  7. //
  8. // Copyright (C) Tim Coleman, 2002
  9. // (c) 2002 Ximian, Inc. (http://www.ximian.com)
  10. //
  11. using System;
  12. using System.Collections;
  13. using System.Xml;
  14. namespace System.Xml.Serialization {
  15. public abstract class XmlSerializationReader {
  16. #region Fields
  17. XmlDocument document;
  18. XmlReader reader;
  19. ArrayList fixups;
  20. ArrayList collFixups;
  21. Hashtable readCallbacks;
  22. Hashtable typesCallbacks;
  23. ArrayList noIDTargets;
  24. Hashtable targets;
  25. string w3SchemaNS;
  26. string w3SchemaNS2000;
  27. string w3SchemaNS1999;
  28. string w3InstanceNS;
  29. string w3InstanceNS2000;
  30. string w3InstanceNS1999;
  31. string soapNS;
  32. string schema;
  33. string wsdlNS;
  34. string wsdlArrayType;
  35. string nullX;
  36. string nil;
  37. string typeX;
  38. string arrayType;
  39. string anyType;
  40. #endregion
  41. private void Initialize ()
  42. {
  43. w3SchemaNS = reader.NameTable.Add ("http://www.w3.org/2001/XMLSchema");
  44. w3SchemaNS2000 = reader.NameTable.Add ("http://www.w3.org/2000/10/XMLSchema");
  45. w3SchemaNS1999 = reader.NameTable.Add ("http://www.w3.org/1999/XMLSchema");
  46. w3InstanceNS = reader.NameTable.Add ("http://www.w3.org/2001/XMLSchema-instance");
  47. w3InstanceNS2000 = reader.NameTable.Add ("http://www.w3.org/2000/10/XMLSchema-instance");
  48. w3InstanceNS1999 = reader.NameTable.Add ("http://www.w3.org/1999/XMLSchema-instance");
  49. soapNS = reader.NameTable.Add ("http://schemas.xmlsoap.org/soap/encoding/");
  50. schema = reader.NameTable.Add ("schema");
  51. wsdlNS = reader.NameTable.Add ("http://schemas.xmlsoap.org/wsdl/");
  52. wsdlArrayType = reader.NameTable.Add ("arrayType");
  53. nullX = reader.NameTable.Add ("null");
  54. nil = reader.NameTable.Add ("nil");
  55. typeX = reader.NameTable.Add ("type");
  56. arrayType = reader.NameTable.Add ("arrayType");
  57. anyType = reader.NameTable.Add ("anyType");
  58. InitIDs ();
  59. }
  60. private ArrayList EnsureArrayList (ArrayList list)
  61. {
  62. if (list == null)
  63. list = new ArrayList ();
  64. return list;
  65. }
  66. private Hashtable EnsureHashtable (Hashtable hash)
  67. {
  68. if (hash == null)
  69. hash = new Hashtable ();
  70. return hash;
  71. }
  72. protected XmlSerializationReader ()
  73. {
  74. }
  75. protected XmlDocument Document
  76. {
  77. get {
  78. if (document == null)
  79. document = new XmlDocument (reader.NameTable);
  80. return document;
  81. }
  82. }
  83. protected XmlReader Reader {
  84. get { return reader; }
  85. }
  86. #region Methods
  87. protected void AddFixup (CollectionFixup fixup)
  88. {
  89. collFixups = EnsureArrayList (collFixups);
  90. collFixups.Add(fixup);
  91. }
  92. protected void AddFixup (Fixup fixup)
  93. {
  94. fixups = EnsureArrayList (fixups);
  95. fixups.Add(fixup);
  96. }
  97. protected void AddReadCallback (string name, string ns, Type type, XmlSerializationReadCallback read)
  98. {
  99. XmlNameTable nt = reader.NameTable;
  100. XmlQualifiedName xqn = new XmlQualifiedName (nt.Add (name), nt.Add (ns));
  101. readCallbacks = EnsureHashtable (readCallbacks);
  102. readCallbacks.Add (xqn, read);
  103. typesCallbacks = EnsureHashtable (typesCallbacks);
  104. typesCallbacks.Add (xqn, type);
  105. }
  106. protected void AddTarget (string id, object o)
  107. {
  108. if (id != null) {
  109. targets = EnsureHashtable (targets);
  110. if (targets [id] == null)
  111. targets.Add (id, o);
  112. } else {
  113. if (o != null)
  114. return;
  115. noIDTargets = EnsureArrayList (noIDTargets);
  116. noIDTargets.Add (o);
  117. }
  118. }
  119. private string CurrentTag ()
  120. {
  121. switch (reader.NodeType) {
  122. case XmlNodeType.None:
  123. return String.Format ("<{0} xmlns='{1}'>", reader.LocalName,
  124. reader.NamespaceURI);
  125. case XmlNodeType.Attribute:
  126. return reader.Value;
  127. case XmlNodeType.Text:
  128. return "CDATA";
  129. case XmlNodeType.ProcessingInstruction:
  130. return "<--";
  131. case XmlNodeType.Entity:
  132. return "<?";
  133. case XmlNodeType.EndElement:
  134. return ">";
  135. default:
  136. return "(unknown)";
  137. }
  138. }
  139. protected Exception CreateAbstractTypeException (string name, string ns)
  140. {
  141. string message = "Error at " + name + " " + ns + ":" + CurrentTag ();
  142. return new InvalidOperationException (message);
  143. }
  144. protected Exception CreateInvalidCastException (Type type, object value)
  145. {
  146. string message = String.Format ("Cannot assign object of type {0} to an object of " +
  147. "type {1}.", value.GetType (), type);
  148. return new InvalidCastException (message);
  149. }
  150. protected Exception CreateReadOnlyCollectionException (string name)
  151. {
  152. string message = String.Format ("Could not serialize {0}. Default constructors are " +
  153. "required for collections and enumerators.", name);
  154. return new InvalidOperationException (message);
  155. }
  156. protected Exception CreateUnknownConstantException (string value, Type enumType)
  157. {
  158. string message = String.Format ("'{0}' is not a valid value for {1}.", value, enumType);
  159. return new InvalidOperationException (message);
  160. }
  161. protected Exception CreateUnknownNodeException ()
  162. {
  163. string message = "Unknown xml node -> " + CurrentTag ();
  164. return new InvalidOperationException (message);
  165. }
  166. protected Exception CreateUnknownTypeException (XmlQualifiedName type)
  167. {
  168. string message = "Unknown type " + type.Namespace + ":" + type.Name + " " + CurrentTag ();
  169. return new InvalidOperationException (message);
  170. }
  171. protected Array EnsureArrayIndex (Array a, int index, Type elementType)
  172. {
  173. if (a != null && index < a.Length)
  174. return a;
  175. int size;
  176. if (a == null) {
  177. size = 32;
  178. } else {
  179. size = a.Length * 2;
  180. }
  181. Array result = Array.CreateInstance (elementType, size);
  182. if (a != null)
  183. Array.Copy (a, result, index);
  184. return result;
  185. }
  186. [MonoTODO ("Implement")]
  187. protected void FixupArrayRefs (object fixup)
  188. {
  189. throw new NotImplementedException ();
  190. }
  191. [MonoTODO ("Implement")]
  192. protected int GetArrayLength (string name, string ns)
  193. {
  194. throw new NotImplementedException ();
  195. }
  196. protected bool GetNullAttr ()
  197. {
  198. string na = reader.GetAttribute (nullX, w3InstanceNS);
  199. if (na == null) {
  200. na = reader.GetAttribute (nil, w3InstanceNS);
  201. if (na == null) {
  202. na = reader.GetAttribute (nullX, w3InstanceNS2000);
  203. if (na == null)
  204. na = reader.GetAttribute (nullX, w3InstanceNS1999);
  205. }
  206. }
  207. return (na != null);
  208. }
  209. [MonoTODO ("Implement")]
  210. protected object GetTarget (string id)
  211. {
  212. throw new NotImplementedException ();
  213. }
  214. [MonoTODO ("Implement")]
  215. protected XmlQualifiedName GetXsiType ()
  216. {
  217. throw new NotImplementedException ();
  218. }
  219. protected abstract void InitCallbacks ();
  220. protected abstract void InitIDs ();
  221. protected bool IsXmlnsAttribute (string name)
  222. {
  223. int length = name.Length;
  224. if (length < 5)
  225. return false;
  226. if (length == 5)
  227. return (name == "xmlns");
  228. return name.StartsWith ("xmlns:");
  229. }
  230. [MonoTODO ("Implement")]
  231. protected void ParseWsdlArrayType (XmlAttribute attr)
  232. {
  233. throw new NotImplementedException ();
  234. }
  235. protected XmlQualifiedName ReadElementQualifiedName ()
  236. {
  237. if (reader.IsEmptyElement) {
  238. reader.Skip();
  239. return ToXmlQualifiedName (String.Empty);
  240. }
  241. XmlQualifiedName xqn = ToXmlQualifiedName(reader.ReadString ());
  242. reader.ReadEndElement ();
  243. return xqn;
  244. }
  245. protected void ReadEndElement ()
  246. {
  247. while (reader.NodeType == XmlNodeType.Whitespace)
  248. reader.Skip ();
  249. if (reader.NodeType != XmlNodeType.None) {
  250. reader.ReadEndElement ();
  251. } else {
  252. reader.Skip ();
  253. }
  254. }
  255. protected bool ReadNull ()
  256. {
  257. if (!GetNullAttr ())
  258. return false;
  259. if (reader.IsEmptyElement) {
  260. reader.Skip();
  261. return true;
  262. }
  263. reader.ReadStartElement();
  264. while (reader.NodeType != XmlNodeType.EndElement)
  265. UnknownNode (null);
  266. ReadEndElement ();
  267. return true;
  268. }
  269. protected XmlQualifiedName ReadNullableQualifiedName ()
  270. {
  271. if (ReadNull ())
  272. return null;
  273. return ReadElementQualifiedName ();
  274. }
  275. protected string ReadNullableString ()
  276. {
  277. if (ReadNull ())
  278. return null;
  279. return reader.ReadElementString ();
  280. }
  281. protected bool ReadReference (out string fixupReference)
  282. {
  283. string href = reader.GetAttribute ("href");
  284. if (href == null) {
  285. fixupReference = null;
  286. return false;
  287. }
  288. if (href [0] != '#')
  289. throw new InvalidOperationException("href not found: " + href);
  290. fixupReference = href.Substring (1);
  291. if (!reader.IsEmptyElement) {
  292. reader.ReadStartElement ();
  293. ReadEndElement ();
  294. } else {
  295. reader.Skip ();
  296. }
  297. return true;
  298. }
  299. protected object ReadReferencedElement ()
  300. {
  301. return ReadReferencedElement (null, null);
  302. }
  303. protected object ReadReferencedElement (string name, string ns)
  304. {
  305. string unused;
  306. return ReadReferencingElement (name, ns, false, out unused);
  307. }
  308. protected void ReadReferencedElements ()
  309. {
  310. string unused;
  311. reader.MoveToContent();
  312. XmlNodeType nt = reader.NodeType;
  313. while (nt != XmlNodeType.EndElement && nt != XmlNodeType.None) {
  314. ReadReferencingElement (null, null, true, out unused);
  315. reader.MoveToContent ();
  316. nt = reader.NodeType;
  317. }
  318. }
  319. [MonoTODO ("Implement")]
  320. protected object ReadReferencingElement (out string fixupReference)
  321. {
  322. return ReadReferencingElement (null, null, false, out fixupReference);
  323. }
  324. protected object ReadReferencingElement (string name, string ns, out string fixupReference)
  325. {
  326. return ReadReferencingElement (name, ns, false, out fixupReference);
  327. }
  328. [MonoTODO]
  329. protected object ReadReferencingElement (string name,
  330. string ns,
  331. bool elementCanBeType,
  332. out string fixupReference)
  333. {
  334. throw new NotImplementedException ();
  335. }
  336. [MonoTODO ("Implement")]
  337. protected IXmlSerializable ReadSerializable (IXmlSerializable serializable)
  338. {
  339. throw new NotImplementedException ();
  340. }
  341. protected string ReadString (string value)
  342. {
  343. if (value == null || value == String.Empty)
  344. return reader.ReadString ();
  345. return (value + reader.ReadString ());
  346. }
  347. [MonoTODO ("Implement")]
  348. protected object ReadTypedPrimitive (XmlQualifiedName type)
  349. {
  350. throw new NotImplementedException ();
  351. }
  352. protected XmlNode ReadXmlNode (bool wrapped)
  353. {
  354. return document.ReadNode (reader);
  355. }
  356. [MonoTODO ("Implement")]
  357. protected void Referenced (object o)
  358. {
  359. throw new NotImplementedException ();
  360. }
  361. [MonoTODO ("Implement")]
  362. protected Array ShrinkArray (Array a, int length, Type elementType, bool isNullable)
  363. {
  364. throw new NotImplementedException ();
  365. }
  366. [MonoTODO ("Implement")]
  367. protected byte[] ToByteArrayBase64 (bool isNull)
  368. {
  369. throw new NotImplementedException ();
  370. }
  371. [MonoTODO ("Implement")]
  372. protected static byte[] ToByteArrayBase64 (string value)
  373. {
  374. throw new NotImplementedException ();
  375. }
  376. [MonoTODO ("Implement")]
  377. protected byte[] ToByteArrayHex (bool isNull)
  378. {
  379. throw new NotImplementedException ();
  380. }
  381. [MonoTODO ("Implement")]
  382. protected static byte[] ToByteArrayHex (string value)
  383. {
  384. throw new NotImplementedException ();
  385. }
  386. protected static char ToChar (string value)
  387. {
  388. return XmlCustomFormatter.ToChar (value);
  389. }
  390. protected static DateTime ToDate (string value)
  391. {
  392. return XmlCustomFormatter.ToDate (value);
  393. }
  394. protected static DateTime ToDateTime (string value)
  395. {
  396. return XmlCustomFormatter.ToDateTime (value);
  397. }
  398. [MonoTODO ("Implement")]
  399. protected static long ToEnum (string value, Hashtable h, string typeName)
  400. {
  401. throw new NotImplementedException ();
  402. }
  403. protected static DateTime ToTime (string value)
  404. {
  405. return XmlCustomFormatter.ToTime (value);
  406. }
  407. protected static string ToXmlName (string value)
  408. {
  409. return XmlCustomFormatter.ToXmlName (value);
  410. }
  411. protected static string ToXmlNCName (string value)
  412. {
  413. return XmlCustomFormatter.ToXmlNCName (value);
  414. }
  415. protected static string ToXmlNmToken (string value)
  416. {
  417. return XmlCustomFormatter.ToXmlNmToken (value);
  418. }
  419. protected static string ToXmlNmTokens (string value)
  420. {
  421. return XmlCustomFormatter.ToXmlNmTokens (value);
  422. }
  423. protected XmlQualifiedName ToXmlQualifiedName (string value)
  424. {
  425. string name;
  426. string ns;
  427. int lastColon = value.LastIndexOf (':');
  428. string decodedValue = XmlConvert.DecodeName (value);
  429. if (lastColon < 0) {
  430. name = reader.NameTable.Add (decodedValue);
  431. ns = reader.LookupNamespace (String.Empty);
  432. } else {
  433. string prefix = value.Substring (0, lastColon);
  434. ns = reader.LookupNamespace (prefix);
  435. if (ns == null)
  436. throw new InvalidOperationException ("namespace " + prefix + "not defined");
  437. name = reader.NameTable.Add (value.Substring (lastColon + 1));
  438. }
  439. return new XmlQualifiedName (name, ns);
  440. }
  441. [MonoTODO ("Implement")]
  442. protected void UnknownAttribute (object o, XmlAttribute attr)
  443. {
  444. throw new NotImplementedException ();
  445. }
  446. [MonoTODO ("Implement")]
  447. protected void UnknownElement (object o, XmlElement elem)
  448. {
  449. throw new NotImplementedException ();
  450. }
  451. [MonoTODO ("Implement")]
  452. protected void UnknownNode (object o)
  453. {
  454. throw new NotImplementedException ();
  455. }
  456. [MonoTODO ("Implement")]
  457. protected void UnreferencedObject (string id, object o)
  458. {
  459. throw new NotImplementedException ();
  460. }
  461. #endregion // Methods
  462. protected class CollectionFixup {
  463. #region Fields
  464. XmlSerializationCollectionFixupCallback callback;
  465. object collection;
  466. object collectionItems;
  467. #endregion // Fields
  468. #region Constructors
  469. [MonoTODO]
  470. public CollectionFixup (object collection, XmlSerializationCollectionFixupCallback callback, object collectionItems)
  471. {
  472. this.callback = callback;
  473. this.collection = collection;
  474. this.collectionItems = collectionItems;
  475. }
  476. #endregion // Constructors
  477. #region Properties
  478. public XmlSerializationCollectionFixupCallback Callback {
  479. get { return callback; }
  480. }
  481. public object Collection {
  482. get { return collection; }
  483. }
  484. public object CollectionItems {
  485. get { return collectionItems; }
  486. }
  487. #endregion // Properties
  488. }
  489. protected class Fixup {
  490. #region Fields
  491. object source;
  492. string[] ids;
  493. XmlSerializationFixupCallback callback;
  494. #endregion // Fields
  495. #region Constructors
  496. [MonoTODO]
  497. public Fixup (object o, XmlSerializationFixupCallback callback, int count)
  498. {
  499. this.callback = callback;
  500. }
  501. [MonoTODO]
  502. public Fixup (object o, XmlSerializationFixupCallback callback, string[] ids)
  503. {
  504. this.callback = callback;
  505. }
  506. #endregion // Constructors
  507. #region Properties
  508. public XmlSerializationFixupCallback Callback {
  509. get { return callback; }
  510. }
  511. public string[] Ids {
  512. get { return ids; }
  513. }
  514. public object Source {
  515. get { return source; }
  516. set { source = value; }
  517. }
  518. #endregion // Properties
  519. }
  520. }
  521. }