PageRenderTime 50ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReader.cs

https://bitbucket.org/danipen/mono
C# | 1208 lines | 980 code | 183 blank | 45 comment | 213 complexity | 7aff13030b759be10e77f2b15c824f90 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //
  2. // System.Xml.Serialization.XmlSerializationReader.cs
  3. //
  4. // Authors:
  5. // Tim Coleman (tim@timcoleman.com)
  6. // Gonzalo Paniagua Javier (gonzalo@ximian.com)
  7. // Lluis Sanchez Gual (lluis@ximian.com)
  8. //
  9. // Copyright (C) Tim Coleman, 2002
  10. // (c) 2002 Ximian, Inc. (http://www.ximian.com)
  11. //
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System;
  33. using System.Collections;
  34. using System.Globalization;
  35. using System.Xml;
  36. using System.Xml.Schema;
  37. using System.Reflection;
  38. namespace System.Xml.Serialization
  39. {
  40. #if NET_2_0
  41. [MonoTODO]
  42. // FIXME: provide expected elements/attributes on unknown elements/attributs
  43. #endif
  44. public abstract class XmlSerializationReader
  45. #if NET_2_0
  46. : XmlSerializationGeneratedCode
  47. #endif
  48. {
  49. #region Fields
  50. XmlDocument document;
  51. XmlReader reader;
  52. ArrayList fixups;
  53. Hashtable collFixups;
  54. ArrayList collItemFixups;
  55. Hashtable typesCallbacks;
  56. ArrayList noIDTargets;
  57. Hashtable targets;
  58. Hashtable delayedListFixups;
  59. XmlSerializer eventSource;
  60. int delayedFixupId = 0;
  61. Hashtable referencedObjects;
  62. int readCount, whileIterationCount;
  63. string w3SchemaNS;
  64. string w3InstanceNS;
  65. string w3InstanceNS2000;
  66. string w3InstanceNS1999;
  67. string soapNS;
  68. string wsdlNS;
  69. string nullX;
  70. string nil;
  71. string typeX;
  72. string arrayType;
  73. XmlQualifiedName arrayQName;
  74. #endregion
  75. internal void Initialize (XmlReader reader, XmlSerializer eventSource)
  76. {
  77. w3SchemaNS = reader.NameTable.Add (XmlSchema.Namespace);
  78. w3InstanceNS = reader.NameTable.Add (XmlSchema.InstanceNamespace);
  79. w3InstanceNS2000 = reader.NameTable.Add ("http://www.w3.org/2000/10/XMLSchema-instance");
  80. w3InstanceNS1999 = reader.NameTable.Add ("http://www.w3.org/1999/XMLSchema-instance");
  81. soapNS = reader.NameTable.Add (XmlSerializer.EncodingNamespace);
  82. wsdlNS = reader.NameTable.Add (XmlSerializer.WsdlNamespace);
  83. nullX = reader.NameTable.Add ("null");
  84. nil = reader.NameTable.Add ("nil");
  85. typeX = reader.NameTable.Add ("type");
  86. arrayType = reader.NameTable.Add ("arrayType");
  87. this.reader = reader;
  88. this.eventSource = eventSource;
  89. arrayQName = new XmlQualifiedName ("Array", soapNS);
  90. InitIDs ();
  91. }
  92. private ArrayList EnsureArrayList (ArrayList list)
  93. {
  94. if (list == null)
  95. list = new ArrayList ();
  96. return list;
  97. }
  98. private Hashtable EnsureHashtable (Hashtable hash)
  99. {
  100. if (hash == null)
  101. hash = new Hashtable ();
  102. return hash;
  103. }
  104. protected XmlSerializationReader ()
  105. {
  106. }
  107. protected XmlDocument Document
  108. {
  109. get {
  110. if (document == null)
  111. document = new XmlDocument (reader.NameTable);
  112. return document;
  113. }
  114. }
  115. protected XmlReader Reader {
  116. get { return reader; }
  117. }
  118. [MonoTODO]
  119. protected bool IsReturnValue
  120. {
  121. get {
  122. throw new NotImplementedException ();
  123. }
  124. set {
  125. throw new NotImplementedException ();
  126. }
  127. }
  128. #if NET_2_0
  129. protected int ReaderCount {
  130. get { return readCount; }
  131. }
  132. #endif
  133. #region Methods
  134. protected void AddFixup (CollectionFixup fixup)
  135. {
  136. collFixups = EnsureHashtable (collFixups);
  137. collFixups [fixup.Id] = fixup;
  138. if (delayedListFixups != null && delayedListFixups.ContainsKey (fixup.Id)) {
  139. fixup.CollectionItems = delayedListFixups [fixup.Id];
  140. delayedListFixups.Remove (fixup.Id);
  141. }
  142. }
  143. protected void AddFixup (Fixup fixup)
  144. {
  145. fixups = EnsureArrayList (fixups);
  146. fixups.Add (fixup);
  147. }
  148. void AddFixup (CollectionItemFixup fixup)
  149. {
  150. collItemFixups = EnsureArrayList (collItemFixups);
  151. collItemFixups.Add(fixup);
  152. }
  153. protected void AddReadCallback (string name, string ns, Type type, XmlSerializationReadCallback read)
  154. {
  155. WriteCallbackInfo info = new WriteCallbackInfo ();
  156. info.Type = type;
  157. info.TypeName = name;
  158. info.TypeNs = ns;
  159. info.Callback = read;
  160. typesCallbacks = EnsureHashtable (typesCallbacks);
  161. typesCallbacks.Add (new XmlQualifiedName (name, ns), info);
  162. }
  163. protected void AddTarget (string id, object o)
  164. {
  165. if (id != null) {
  166. targets = EnsureHashtable (targets);
  167. if (targets [id] == null)
  168. targets.Add (id, o);
  169. } else {
  170. if (o != null)
  171. return;
  172. noIDTargets = EnsureArrayList (noIDTargets);
  173. noIDTargets.Add (o);
  174. }
  175. }
  176. private string CurrentTag ()
  177. {
  178. switch (reader.NodeType) {
  179. case XmlNodeType.Element:
  180. return String.Format ("<{0} xmlns='{1}'>", reader.LocalName,
  181. reader.NamespaceURI);
  182. case XmlNodeType.Attribute:
  183. return reader.Value;
  184. case XmlNodeType.Text:
  185. return "CDATA";
  186. case XmlNodeType.ProcessingInstruction:
  187. return "<--";
  188. case XmlNodeType.Entity:
  189. return "<?";
  190. case XmlNodeType.EndElement:
  191. return ">";
  192. default:
  193. return "(unknown)";
  194. }
  195. }
  196. protected Exception CreateCtorHasSecurityException (string typeName)
  197. {
  198. string message = string.Format ("The type '{0}' cannot"
  199. + " be serialized because its parameterless"
  200. + " constructor is decorated with declarative"
  201. + " security permission attributes."
  202. + " Consider using imperative asserts or demands"
  203. + " in the constructor.", typeName);
  204. return new InvalidOperationException (message);
  205. }
  206. protected Exception CreateInaccessibleConstructorException (string typeName)
  207. {
  208. string message = string.Format ("{0} cannot be serialized"
  209. + " because it does not have a default public"
  210. + " constructor.", typeName);
  211. return new InvalidOperationException (message);
  212. }
  213. protected Exception CreateAbstractTypeException (string name, string ns)
  214. {
  215. string message = "The specified type is abstrace: name='" + name + "' namespace='" + ns + "', at " + CurrentTag ();
  216. return new InvalidOperationException (message);
  217. }
  218. protected Exception CreateInvalidCastException (Type type, object value)
  219. {
  220. string message = String.Format (CultureInfo.InvariantCulture, "Cannot assign object of type {0} to an object of " +
  221. "type {1}.", value.GetType (), type);
  222. return new InvalidCastException (message);
  223. }
  224. protected Exception CreateReadOnlyCollectionException (string name)
  225. {
  226. string message = String.Format ("Could not serialize {0}. Default constructors are " +
  227. "required for collections and enumerators.", name);
  228. return new InvalidOperationException (message);
  229. }
  230. protected Exception CreateUnknownConstantException (string value, Type enumType)
  231. {
  232. string message = String.Format ("'{0}' is not a valid value for {1}.", value, enumType);
  233. return new InvalidOperationException (message);
  234. }
  235. protected Exception CreateUnknownNodeException ()
  236. {
  237. string message = CurrentTag () + " was not expected";
  238. return new InvalidOperationException (message);
  239. }
  240. protected Exception CreateUnknownTypeException (XmlQualifiedName type)
  241. {
  242. string message = "The specified type was not recognized: name='" + type.Name + "' namespace='" + type.Namespace + "', at " + CurrentTag ();
  243. return new InvalidOperationException (message);
  244. }
  245. #if NET_2_0
  246. protected void CheckReaderCount (ref int whileIterations, ref int readerCount)
  247. {
  248. whileIterations = whileIterationCount;
  249. readerCount = readCount;
  250. }
  251. #endif
  252. protected Array EnsureArrayIndex (Array a, int index, Type elementType)
  253. {
  254. if (a != null && index < a.Length)
  255. return a;
  256. int size;
  257. if (a == null) {
  258. size = 32;
  259. } else {
  260. size = a.Length * 2;
  261. }
  262. Array result = Array.CreateInstance (elementType, size);
  263. if (a != null)
  264. Array.Copy (a, result, index);
  265. return result;
  266. }
  267. [MonoTODO]
  268. protected void FixupArrayRefs (object fixup)
  269. {
  270. throw new NotImplementedException ();
  271. }
  272. [MonoTODO]
  273. protected int GetArrayLength (string name, string ns)
  274. {
  275. throw new NotImplementedException ();
  276. }
  277. protected bool GetNullAttr ()
  278. {
  279. string na = reader.GetAttribute (nullX, w3InstanceNS);
  280. if (na == null) {
  281. na = reader.GetAttribute (nil, w3InstanceNS);
  282. if (na == null) {
  283. na = reader.GetAttribute (nullX, w3InstanceNS2000);
  284. if (na == null)
  285. na = reader.GetAttribute (nullX, w3InstanceNS1999);
  286. }
  287. }
  288. return (na != null);
  289. }
  290. protected object GetTarget (string id)
  291. {
  292. if (targets == null) return null;
  293. object ob = targets [id];
  294. if (ob != null) {
  295. if (referencedObjects == null) referencedObjects = new Hashtable ();
  296. referencedObjects [ob] = ob;
  297. }
  298. return ob;
  299. }
  300. bool TargetReady (string id)
  301. {
  302. if (targets == null) return false;
  303. return targets.ContainsKey (id);
  304. }
  305. protected XmlQualifiedName GetXsiType ()
  306. {
  307. string typeName = Reader.GetAttribute (typeX, XmlSchema.InstanceNamespace);
  308. if (typeName == string.Empty || typeName == null) {
  309. typeName = Reader.GetAttribute (typeX, w3InstanceNS1999);
  310. if (typeName == string.Empty || typeName == null) {
  311. typeName = Reader.GetAttribute (typeX, w3InstanceNS2000);
  312. if (typeName == string.Empty || typeName == null)
  313. return null;
  314. }
  315. }
  316. int i = typeName.IndexOf (":");
  317. if (i == -1) return new XmlQualifiedName (typeName, Reader.NamespaceURI);
  318. else
  319. {
  320. string prefix = typeName.Substring(0,i);
  321. string name = typeName.Substring (i+1);
  322. return new XmlQualifiedName (name, Reader.LookupNamespace (prefix));
  323. }
  324. }
  325. protected abstract void InitCallbacks ();
  326. protected abstract void InitIDs ();
  327. protected bool IsXmlnsAttribute (string name)
  328. {
  329. int length = name.Length;
  330. if (length < 5)
  331. return false;
  332. if (length == 5)
  333. return (name == "xmlns");
  334. return name.StartsWith ("xmlns:");
  335. }
  336. protected void ParseWsdlArrayType (XmlAttribute attr)
  337. {
  338. if (attr.NamespaceURI == wsdlNS && attr.LocalName == arrayType)
  339. {
  340. string ns = "", type, dimensions;
  341. TypeTranslator.ParseArrayType (attr.Value, out type, out ns, out dimensions);
  342. if (ns != "") ns = Reader.LookupNamespace (ns) + ":";
  343. attr.Value = ns + type + dimensions;
  344. }
  345. }
  346. protected XmlQualifiedName ReadElementQualifiedName ()
  347. {
  348. readCount++;
  349. if (reader.IsEmptyElement) {
  350. reader.Skip();
  351. return ToXmlQualifiedName (String.Empty);
  352. }
  353. reader.ReadStartElement ();
  354. XmlQualifiedName xqn = ToXmlQualifiedName(reader.ReadString ());
  355. reader.ReadEndElement ();
  356. return xqn;
  357. }
  358. protected void ReadEndElement ()
  359. {
  360. readCount++;
  361. while (reader.NodeType == XmlNodeType.Whitespace)
  362. reader.Skip ();
  363. if (reader.NodeType != XmlNodeType.None) {
  364. reader.ReadEndElement ();
  365. } else {
  366. reader.Skip ();
  367. }
  368. }
  369. protected bool ReadNull ()
  370. {
  371. if (!GetNullAttr ())
  372. return false;
  373. readCount++;
  374. if (reader.IsEmptyElement) {
  375. reader.Skip();
  376. return true;
  377. }
  378. reader.ReadStartElement();
  379. while (reader.NodeType != XmlNodeType.EndElement)
  380. UnknownNode (null);
  381. ReadEndElement ();
  382. return true;
  383. }
  384. protected XmlQualifiedName ReadNullableQualifiedName ()
  385. {
  386. if (ReadNull ())
  387. return null;
  388. return ReadElementQualifiedName ();
  389. }
  390. protected string ReadNullableString ()
  391. {
  392. if (ReadNull ())
  393. return null;
  394. readCount++;
  395. return reader.ReadElementString ();
  396. }
  397. protected bool ReadReference (out string fixupReference)
  398. {
  399. string href = reader.GetAttribute ("href");
  400. if (href == null) {
  401. fixupReference = null;
  402. return false;
  403. }
  404. if (href [0] != '#')
  405. throw new InvalidOperationException("href not found: " + href);
  406. fixupReference = href.Substring (1);
  407. readCount++;
  408. if (!reader.IsEmptyElement) {
  409. reader.ReadStartElement ();
  410. ReadEndElement ();
  411. } else {
  412. reader.Skip ();
  413. }
  414. return true;
  415. }
  416. protected object ReadReferencedElement ()
  417. {
  418. return ReadReferencedElement (Reader.LocalName, Reader.NamespaceURI);
  419. }
  420. WriteCallbackInfo GetCallbackInfo (XmlQualifiedName qname)
  421. {
  422. if (typesCallbacks == null)
  423. {
  424. typesCallbacks = new Hashtable ();
  425. InitCallbacks ();
  426. }
  427. return (WriteCallbackInfo) typesCallbacks[qname];
  428. }
  429. protected object ReadReferencedElement (string name, string ns)
  430. {
  431. XmlQualifiedName qname = GetXsiType ();
  432. if (qname == null) qname = new XmlQualifiedName (name, ns);
  433. string id = Reader.GetAttribute ("id");
  434. object ob;
  435. // it takes precedence over xsi:type.
  436. // Sometimes there are array types in WSDL,
  437. // which are not reflected in client proxies.
  438. // In SOAP messages, they are marked
  439. // soap-env:arrayType, so use it (this could coexist
  440. // with xsi:type, which indicates the type in WSDL).
  441. // See bug #79057.
  442. string arrayTypeVal = Reader.GetAttribute (arrayType, soapNS);
  443. if (qname == arrayQName || arrayTypeVal != null && arrayTypeVal.Length > 0)
  444. {
  445. CollectionFixup fixup = (collFixups != null) ? (CollectionFixup) collFixups[id] : null;
  446. if (ReadList (out ob))
  447. {
  448. // List complete (does not contain references)
  449. if (fixup != null)
  450. {
  451. fixup.Callback (fixup.Collection, ob);
  452. collFixups.Remove (id);
  453. ob = fixup.Collection;
  454. }
  455. }
  456. else if (fixup != null)
  457. {
  458. fixup.CollectionItems = (object[])ob;
  459. ob = fixup.Collection;
  460. }
  461. }
  462. else
  463. {
  464. WriteCallbackInfo info = GetCallbackInfo (qname);
  465. if (info == null)
  466. ob = ReadTypedPrimitive (qname, id != null);
  467. else
  468. ob = info.Callback();
  469. }
  470. AddTarget (id, ob);
  471. return ob;
  472. }
  473. bool ReadList (out object resultList)
  474. {
  475. string arrayTypeAttr = Reader.GetAttribute (arrayType, soapNS);
  476. if (arrayTypeAttr == null) arrayTypeAttr = Reader.GetAttribute (arrayType, wsdlNS);
  477. XmlQualifiedName qn = ToXmlQualifiedName (arrayTypeAttr);
  478. int i = qn.Name.LastIndexOf ('[');
  479. string dim = qn.Name.Substring (i);
  480. string itemType = qn.Name.Substring (0,i);
  481. int count = Int32.Parse (dim.Substring (1, dim.Length - 2), CultureInfo.InvariantCulture);
  482. Array list;
  483. i = itemType.IndexOf ('['); if (i == -1) i = itemType.Length;
  484. string baseType = itemType.Substring (0,i);
  485. string arrayTypeName;
  486. if (qn.Namespace == w3SchemaNS)
  487. arrayTypeName = TypeTranslator.GetPrimitiveTypeData (baseType).Type.FullName + itemType.Substring (i);
  488. else
  489. {
  490. WriteCallbackInfo info = GetCallbackInfo (new XmlQualifiedName (baseType,qn.Namespace));
  491. arrayTypeName = info.Type.FullName + itemType.Substring (i) + ", " + info.Type.Assembly.FullName;
  492. }
  493. list = Array.CreateInstance (Type.GetType (arrayTypeName), count);
  494. bool listComplete = true;
  495. if (Reader.IsEmptyElement) {
  496. readCount++;
  497. Reader.Skip ();
  498. } else {
  499. Reader.ReadStartElement ();
  500. for (int n=0; n<count; n++)
  501. {
  502. whileIterationCount++;
  503. readCount++;
  504. Reader.MoveToContent ();
  505. string id;
  506. object item = ReadReferencingElement (itemType, qn.Namespace, out id);
  507. if (id == null)
  508. list.SetValue (item,n);
  509. else
  510. {
  511. AddFixup (new CollectionItemFixup (list, n, id));
  512. listComplete = false;
  513. }
  514. }
  515. whileIterationCount = 0;
  516. Reader.ReadEndElement ();
  517. }
  518. resultList = list;
  519. return listComplete;
  520. }
  521. protected void ReadReferencedElements ()
  522. {
  523. reader.MoveToContent();
  524. XmlNodeType nt = reader.NodeType;
  525. while (nt != XmlNodeType.EndElement && nt != XmlNodeType.None) {
  526. whileIterationCount++;
  527. readCount++;
  528. ReadReferencedElement ();
  529. reader.MoveToContent ();
  530. nt = reader.NodeType;
  531. }
  532. whileIterationCount = 0;
  533. // Registers delayed list
  534. if (delayedListFixups != null)
  535. {
  536. foreach (DictionaryEntry entry in delayedListFixups)
  537. AddTarget ((string)entry.Key, entry.Value);
  538. }
  539. // Fix arrays
  540. if (collItemFixups != null)
  541. {
  542. foreach (CollectionItemFixup itemFixup in collItemFixups)
  543. itemFixup.Collection.SetValue (GetTarget (itemFixup.Id), itemFixup.Index);
  544. }
  545. // Fills collections
  546. if (collFixups != null)
  547. {
  548. ICollection cfixups = collFixups.Values;
  549. foreach (CollectionFixup fixup in cfixups)
  550. fixup.Callback (fixup.Collection, fixup.CollectionItems);
  551. }
  552. // Fills class instances
  553. if (fixups != null)
  554. {
  555. foreach (Fixup fixup in fixups)
  556. fixup.Callback (fixup);
  557. }
  558. if (targets != null) {
  559. foreach (DictionaryEntry e in targets) {
  560. if (e.Value != null && (referencedObjects == null || !referencedObjects.Contains (e.Value)))
  561. UnreferencedObject ((string)e.Key, e.Value);
  562. }
  563. }
  564. }
  565. protected object ReadReferencingElement (out string fixupReference)
  566. {
  567. return ReadReferencingElement (Reader.LocalName, Reader.NamespaceURI, false, out fixupReference);
  568. }
  569. protected object ReadReferencingElement (string name, string ns, out string fixupReference)
  570. {
  571. return ReadReferencingElement (name, ns, false, out fixupReference);
  572. }
  573. protected object ReadReferencingElement (string name,
  574. string ns,
  575. bool elementCanBeType,
  576. out string fixupReference)
  577. {
  578. if (ReadNull ())
  579. {
  580. fixupReference = null;
  581. return null;
  582. }
  583. string refid = Reader.GetAttribute ("href");
  584. if (refid == string.Empty || refid == null)
  585. {
  586. fixupReference = null;
  587. XmlQualifiedName qname = GetXsiType ();
  588. if (qname == null) qname = new XmlQualifiedName (name, ns);
  589. string arrayTypeAttr = Reader.GetAttribute (arrayType, soapNS);
  590. if (qname == arrayQName || arrayTypeAttr != null)
  591. {
  592. delayedListFixups = EnsureHashtable (delayedListFixups);
  593. fixupReference = "__<" + (delayedFixupId++) + ">";
  594. object items;
  595. ReadList (out items);
  596. delayedListFixups [fixupReference] = items;
  597. return null;
  598. }
  599. else
  600. {
  601. WriteCallbackInfo info = GetCallbackInfo (qname);
  602. if (info == null)
  603. return ReadTypedPrimitive (qname, true);
  604. else
  605. return info.Callback();
  606. }
  607. }
  608. else
  609. {
  610. if (refid.StartsWith ("#")) refid = refid.Substring (1);
  611. readCount++;
  612. Reader.Skip ();
  613. if (TargetReady (refid))
  614. {
  615. fixupReference = null;
  616. return GetTarget (refid);
  617. }
  618. else
  619. {
  620. fixupReference = refid;
  621. return null;
  622. }
  623. }
  624. }
  625. protected IXmlSerializable ReadSerializable (IXmlSerializable serializable)
  626. {
  627. if (ReadNull ()) return null;
  628. int depth = reader.Depth;
  629. readCount++;
  630. serializable.ReadXml (reader);
  631. Reader.MoveToContent ();
  632. while (reader.Depth > depth)
  633. reader.Skip ();
  634. if (reader.Depth == depth && reader.NodeType == XmlNodeType.EndElement)
  635. reader.ReadEndElement ();
  636. return serializable;
  637. }
  638. protected string ReadString (string value)
  639. {
  640. readCount++;
  641. if (value == null || value == String.Empty)
  642. return reader.ReadString ();
  643. return (value + reader.ReadString ());
  644. }
  645. protected object ReadTypedPrimitive (XmlQualifiedName type)
  646. {
  647. return ReadTypedPrimitive (type, false);
  648. }
  649. object ReadTypedPrimitive (XmlQualifiedName qname, bool reportUnknown)
  650. {
  651. if (qname == null) qname = GetXsiType ();
  652. TypeData typeData = TypeTranslator.FindPrimitiveTypeData (qname.Name);
  653. if (typeData == null || typeData.SchemaType != SchemaTypes.Primitive)
  654. {
  655. // Put everything into a node array
  656. readCount++;
  657. XmlNode node = Document.ReadNode (reader);
  658. if (reportUnknown)
  659. OnUnknownNode (node, null, null);
  660. if (node.ChildNodes.Count == 0 && node.Attributes.Count == 0)
  661. return new Object ();
  662. XmlElement elem = node as XmlElement;
  663. if (elem == null)
  664. return new XmlNode[] {node};
  665. else {
  666. XmlNode[] nodes = new XmlNode[elem.Attributes.Count + elem.ChildNodes.Count];
  667. int n = 0;
  668. foreach (XmlNode no in elem.Attributes)
  669. nodes[n++] = no;
  670. foreach (XmlNode no in elem.ChildNodes)
  671. nodes[n++] = no;
  672. return nodes;
  673. }
  674. }
  675. if (typeData.Type == typeof (XmlQualifiedName)) return ReadNullableQualifiedName ();
  676. readCount++;
  677. return XmlCustomFormatter.FromXmlString (typeData, Reader.ReadElementString ());
  678. }
  679. protected XmlNode ReadXmlNode (bool wrapped)
  680. {
  681. readCount++;
  682. XmlNode node = Document.ReadNode (reader);
  683. if (wrapped)
  684. return node.FirstChild;
  685. else
  686. return node;
  687. }
  688. protected XmlDocument ReadXmlDocument (bool wrapped)
  689. {
  690. readCount++;
  691. if (wrapped)
  692. reader.ReadStartElement ();
  693. reader.MoveToContent ();
  694. XmlDocument doc = new XmlDocument ();
  695. XmlNode node = doc.ReadNode (reader);
  696. doc.AppendChild (node);
  697. if (wrapped)
  698. reader.ReadEndElement ();
  699. return doc;
  700. }
  701. protected void Referenced (object o)
  702. {
  703. if (o != null) {
  704. if (referencedObjects == null) referencedObjects = new Hashtable ();
  705. referencedObjects [o] = o;
  706. }
  707. }
  708. protected Array ShrinkArray (Array a, int length, Type elementType, bool isNullable)
  709. {
  710. if (length == 0 && isNullable) return null;
  711. if (a == null) return Array.CreateInstance (elementType, length);
  712. if (a.Length == length) return a;
  713. Array result = Array.CreateInstance (elementType, length);
  714. Array.Copy (a, result, length);
  715. return result;
  716. }
  717. protected byte[] ToByteArrayBase64 (bool isNull)
  718. {
  719. readCount++;
  720. if (isNull) {
  721. Reader.ReadString ();
  722. return null;
  723. }
  724. else
  725. return ToByteArrayBase64 (Reader.ReadString ());
  726. }
  727. protected static byte[] ToByteArrayBase64 (string value)
  728. {
  729. return Convert.FromBase64String (value);
  730. }
  731. protected byte[] ToByteArrayHex (bool isNull)
  732. {
  733. readCount++;
  734. if (isNull) {
  735. Reader.ReadString ();
  736. return null;
  737. }
  738. else
  739. return ToByteArrayHex (Reader.ReadString ());
  740. }
  741. protected static byte[] ToByteArrayHex (string value)
  742. {
  743. return XmlConvert.FromBinHexString (value);
  744. }
  745. protected static char ToChar (string value)
  746. {
  747. return XmlCustomFormatter.ToChar (value);
  748. }
  749. protected static DateTime ToDate (string value)
  750. {
  751. return XmlCustomFormatter.ToDate (value);
  752. }
  753. protected static DateTime ToDateTime (string value)
  754. {
  755. return XmlCustomFormatter.ToDateTime (value);
  756. }
  757. protected static long ToEnum (string value, Hashtable h, string typeName)
  758. {
  759. return XmlCustomFormatter.ToEnum (value, h, typeName, true);
  760. }
  761. protected static DateTime ToTime (string value)
  762. {
  763. return XmlCustomFormatter.ToTime (value);
  764. }
  765. protected static string ToXmlName (string value)
  766. {
  767. return XmlCustomFormatter.ToXmlName (value);
  768. }
  769. protected static string ToXmlNCName (string value)
  770. {
  771. return XmlCustomFormatter.ToXmlNCName (value);
  772. }
  773. protected static string ToXmlNmToken (string value)
  774. {
  775. return XmlCustomFormatter.ToXmlNmToken (value);
  776. }
  777. protected static string ToXmlNmTokens (string value)
  778. {
  779. return XmlCustomFormatter.ToXmlNmTokens (value);
  780. }
  781. protected XmlQualifiedName ToXmlQualifiedName (string value)
  782. {
  783. string name;
  784. string ns;
  785. int lastColon = value.LastIndexOf (':');
  786. string decodedValue = XmlConvert.DecodeName (value);
  787. if (lastColon < 0) {
  788. name = reader.NameTable.Add (decodedValue);
  789. ns = reader.LookupNamespace (String.Empty);
  790. } else {
  791. string prefix = value.Substring (0, lastColon);
  792. ns = reader.LookupNamespace (prefix);
  793. if (ns == null)
  794. throw new InvalidOperationException ("namespace " + prefix + " not defined");
  795. name = reader.NameTable.Add (value.Substring (lastColon + 1));
  796. }
  797. return new XmlQualifiedName (name, ns);
  798. }
  799. protected void UnknownAttribute (object o, XmlAttribute attr)
  800. {
  801. UnknownAttribute (o, attr, null);
  802. }
  803. #if NET_2_0
  804. protected
  805. #endif
  806. void UnknownAttribute (object o, XmlAttribute attr, string qnames)
  807. {
  808. int line_number, line_position;
  809. if (Reader is XmlTextReader){
  810. line_number = ((XmlTextReader)Reader).LineNumber;
  811. line_position = ((XmlTextReader)Reader).LinePosition;
  812. } else {
  813. line_number = 0;
  814. line_position = 0;
  815. }
  816. XmlAttributeEventArgs args = new XmlAttributeEventArgs (attr, line_number, line_position, o);
  817. #if NET_2_0
  818. args.ExpectedAttributes = qnames;
  819. #endif
  820. if (eventSource != null)
  821. eventSource.OnUnknownAttribute (args);
  822. }
  823. protected void UnknownElement (object o, XmlElement elem)
  824. {
  825. UnknownElement (o, elem, null);
  826. }
  827. #if NET_2_0
  828. protected
  829. #endif
  830. void UnknownElement (object o, XmlElement elem, string qnames)
  831. {
  832. int line_number, line_position;
  833. if (Reader is XmlTextReader){
  834. line_number = ((XmlTextReader)Reader).LineNumber;
  835. line_position = ((XmlTextReader)Reader).LinePosition;
  836. } else {
  837. line_number = 0;
  838. line_position = 0;
  839. }
  840. XmlElementEventArgs args = new XmlElementEventArgs (elem, line_number, line_position, o);
  841. #if NET_2_0
  842. args.ExpectedElements = qnames;
  843. #endif
  844. if (eventSource != null)
  845. eventSource.OnUnknownElement (args);
  846. }
  847. protected void UnknownNode (object o)
  848. {
  849. UnknownNode (o, null);
  850. }
  851. #if NET_2_0
  852. protected
  853. #endif
  854. void UnknownNode (object o, string qnames)
  855. {
  856. OnUnknownNode (ReadXmlNode (false), o, qnames);
  857. }
  858. void OnUnknownNode (XmlNode node, object o, string qnames)
  859. {
  860. int line_number, line_position;
  861. if (Reader is XmlTextReader){
  862. line_number = ((XmlTextReader)Reader).LineNumber;
  863. line_position = ((XmlTextReader)Reader).LinePosition;
  864. } else {
  865. line_number = 0;
  866. line_position = 0;
  867. }
  868. if (node is XmlAttribute)
  869. {
  870. UnknownAttribute (o, (XmlAttribute)node, qnames);
  871. return;
  872. }
  873. else if (node is XmlElement)
  874. {
  875. UnknownElement (o, (XmlElement) node, qnames);
  876. return;
  877. }
  878. else
  879. {
  880. if (eventSource != null)
  881. eventSource.OnUnknownNode (new XmlNodeEventArgs(line_number, line_position, node.LocalName, node.Name, node.NamespaceURI, node.NodeType, o, node.Value));
  882. if (Reader.ReadState == ReadState.EndOfFile)
  883. throw new InvalidOperationException ("End of document found");
  884. }
  885. }
  886. protected void UnreferencedObject (string id, object o)
  887. {
  888. if (eventSource != null)
  889. eventSource.OnUnreferencedObject (new UnreferencedObjectEventArgs (o,id));
  890. }
  891. #endregion // Methods
  892. class WriteCallbackInfo
  893. {
  894. public Type Type;
  895. public string TypeName;
  896. public string TypeNs;
  897. public XmlSerializationReadCallback Callback;
  898. }
  899. protected class CollectionFixup {
  900. XmlSerializationCollectionFixupCallback callback;
  901. object collection;
  902. object collectionItems;
  903. string id;
  904. public CollectionFixup (object collection, XmlSerializationCollectionFixupCallback callback, string id)
  905. {
  906. this.callback = callback;
  907. this.collection = collection;
  908. this.id = id;
  909. }
  910. public XmlSerializationCollectionFixupCallback Callback {
  911. get { return callback; }
  912. }
  913. public object Collection {
  914. get { return collection; }
  915. }
  916. public object Id {
  917. get { return id; }
  918. }
  919. internal object CollectionItems
  920. {
  921. get { return collectionItems; }
  922. set { collectionItems = value; }
  923. }
  924. }
  925. protected class Fixup {
  926. object source;
  927. string[] ids;
  928. XmlSerializationFixupCallback callback;
  929. public Fixup (object o, XmlSerializationFixupCallback callback, int count)
  930. {
  931. this.source = o;
  932. this.callback = callback;
  933. this.ids = new string[count];
  934. }
  935. public Fixup (object o, XmlSerializationFixupCallback callback, string[] ids)
  936. {
  937. this.source = o;
  938. this.ids = ids;
  939. this.callback = callback;
  940. }
  941. public XmlSerializationFixupCallback Callback {
  942. get { return callback; }
  943. }
  944. public string[] Ids {
  945. get { return ids; }
  946. }
  947. public object Source {
  948. get { return source; }
  949. set { source = value; }
  950. }
  951. }
  952. protected class CollectionItemFixup
  953. {
  954. Array list;
  955. int index;
  956. string id;
  957. public CollectionItemFixup (Array list, int index, string id)
  958. {
  959. this.list = list;
  960. this.index = index;
  961. this.id = id;
  962. }
  963. public Array Collection
  964. {
  965. get { return list; }
  966. }
  967. public int Index
  968. {
  969. get { return index; }
  970. }
  971. public string Id
  972. {
  973. get { return id; }
  974. }
  975. }
  976. #if NET_2_0
  977. [MonoTODO]
  978. protected bool DecodeName
  979. {
  980. get { throw new NotImplementedException(); }
  981. set { throw new NotImplementedException(); }
  982. }
  983. protected string CollapseWhitespace (string value)
  984. {
  985. return value == null ? null : value.Trim ();
  986. }
  987. [MonoTODO]
  988. protected Exception CreateBadDerivationException (
  989. string xsdDerived,
  990. string nsDerived,
  991. string xsdBase,
  992. string nsBase,
  993. string clrDerived,
  994. string clrBase)
  995. {
  996. throw new NotImplementedException ();
  997. }
  998. [MonoTODO]
  999. protected Exception CreateInvalidCastException (Type type, object value, string id)
  1000. {
  1001. throw new NotImplementedException ();
  1002. }
  1003. [MonoTODO]
  1004. protected Exception CreateMissingIXmlSerializableType (string name, string ns, string clrType)
  1005. {
  1006. throw new NotImplementedException ();
  1007. }
  1008. [MonoTODO]
  1009. protected string ReadString (string value, bool trim)
  1010. {
  1011. throw new NotImplementedException ();
  1012. }
  1013. [MonoTODO]
  1014. protected object ReadTypedNull (XmlQualifiedName type)
  1015. {
  1016. throw new NotImplementedException ();
  1017. }
  1018. [MonoTODO]
  1019. protected static Assembly ResolveDynamicAssembly (string assemblyFullName)
  1020. {
  1021. throw new NotImplementedException ();
  1022. }
  1023. #endif
  1024. }
  1025. }