ExtensionDataObject.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.Runtime.Serialization
  5. {
  6. using System;
  7. using System.Xml;
  8. using System.Collections.Generic;
  9. using System.Globalization;
  10. public sealed class ExtensionDataObject
  11. {
  12. IList<ExtensionDataMember> members;
  13. #if USE_REFEMIT
  14. public ExtensionDataObject()
  15. #else
  16. internal ExtensionDataObject()
  17. #endif
  18. {
  19. }
  20. #if USE_REFEMIT
  21. public IList<ExtensionDataMember> Members
  22. #else
  23. internal IList<ExtensionDataMember> Members
  24. #endif
  25. {
  26. get { return members; }
  27. set { members = value; }
  28. }
  29. }
  30. #if USE_REFEMIT
  31. public class ExtensionDataMember
  32. #else
  33. internal class ExtensionDataMember
  34. #endif
  35. {
  36. string name;
  37. string ns;
  38. IDataNode value;
  39. int memberIndex;
  40. public string Name
  41. {
  42. get { return name; }
  43. set { name = value; }
  44. }
  45. public string Namespace
  46. {
  47. get { return ns; }
  48. set { ns = value; }
  49. }
  50. public IDataNode Value
  51. {
  52. get { return value; }
  53. set { this.value = value; }
  54. }
  55. public int MemberIndex
  56. {
  57. get { return memberIndex; }
  58. set { memberIndex = value; }
  59. }
  60. }
  61. #if USE_REFEMIT
  62. public interface IDataNode
  63. #else
  64. internal interface IDataNode
  65. #endif
  66. {
  67. Type DataType { get; }
  68. object Value { get; set; } // boxes for primitives
  69. string DataContractName { get; set; }
  70. string DataContractNamespace { get; set; }
  71. string ClrTypeName { get; set; }
  72. string ClrAssemblyName { get; set; }
  73. string Id { get; set; }
  74. bool PreservesReferences { get; }
  75. // NOTE: consider moving below APIs to DataNode<T> if IDataNode API is made public
  76. void GetData(ElementData element);
  77. bool IsFinalValue { get; set; }
  78. void Clear();
  79. }
  80. internal class DataNode<T> : IDataNode
  81. {
  82. protected Type dataType;
  83. T value;
  84. string dataContractName;
  85. string dataContractNamespace;
  86. string clrTypeName;
  87. string clrAssemblyName;
  88. string id = Globals.NewObjectId;
  89. bool isFinalValue;
  90. internal DataNode()
  91. {
  92. this.dataType = typeof(T);
  93. this.isFinalValue = true;
  94. }
  95. internal DataNode(T value)
  96. : this()
  97. {
  98. this.value = value;
  99. }
  100. public Type DataType
  101. {
  102. get { return dataType; }
  103. }
  104. public object Value
  105. {
  106. get { return value; }
  107. set { this.value = (T)value; }
  108. }
  109. bool IDataNode.IsFinalValue
  110. {
  111. get { return isFinalValue; }
  112. set { isFinalValue = value; }
  113. }
  114. public T GetValue()
  115. {
  116. return value;
  117. }
  118. #if NotUsed
  119. public void SetValue(T value)
  120. {
  121. this.value = value;
  122. }
  123. #endif
  124. public string DataContractName
  125. {
  126. get { return dataContractName; }
  127. set { dataContractName = value; }
  128. }
  129. public string DataContractNamespace
  130. {
  131. get { return dataContractNamespace; }
  132. set { dataContractNamespace = value; }
  133. }
  134. public string ClrTypeName
  135. {
  136. get { return clrTypeName; }
  137. set { clrTypeName = value; }
  138. }
  139. public string ClrAssemblyName
  140. {
  141. get { return clrAssemblyName; }
  142. set { clrAssemblyName = value; }
  143. }
  144. public bool PreservesReferences
  145. {
  146. get { return (Id != Globals.NewObjectId); }
  147. }
  148. public string Id
  149. {
  150. get { return id; }
  151. set { id = value; }
  152. }
  153. public virtual void GetData(ElementData element)
  154. {
  155. element.dataNode = this;
  156. element.attributeCount = 0;
  157. element.childElementIndex = 0;
  158. if (DataContractName != null)
  159. AddQualifiedNameAttribute(element, Globals.XsiPrefix, Globals.XsiTypeLocalName, Globals.SchemaInstanceNamespace, DataContractName, DataContractNamespace);
  160. if (ClrTypeName != null)
  161. element.AddAttribute(Globals.SerPrefix, Globals.SerializationNamespace, Globals.ClrTypeLocalName, ClrTypeName);
  162. if (ClrAssemblyName != null)
  163. element.AddAttribute(Globals.SerPrefix, Globals.SerializationNamespace, Globals.ClrAssemblyLocalName, ClrAssemblyName);
  164. }
  165. public virtual void Clear()
  166. {
  167. // dataContractName not cleared because it is used when re-serializing from unknown data
  168. clrTypeName = clrAssemblyName = null;
  169. }
  170. internal void AddQualifiedNameAttribute(ElementData element, string elementPrefix, string elementName, string elementNs, string valueName, string valueNs)
  171. {
  172. string prefix = ExtensionDataReader.GetPrefix(valueNs);
  173. element.AddAttribute(elementPrefix, elementNs, elementName, String.Format(CultureInfo.InvariantCulture, "{0}:{1}", prefix, valueName));
  174. bool prefixDeclaredOnElement = false;
  175. if (element.attributes != null)
  176. {
  177. for (int i = 0; i < element.attributes.Length; i++)
  178. {
  179. AttributeData attribute = element.attributes[i];
  180. if (attribute != null && attribute.prefix == Globals.XmlnsPrefix && attribute.localName == prefix)
  181. {
  182. prefixDeclaredOnElement = true;
  183. break;
  184. }
  185. }
  186. }
  187. if (!prefixDeclaredOnElement)
  188. element.AddAttribute(Globals.XmlnsPrefix, Globals.XmlnsNamespace, prefix, valueNs);
  189. }
  190. }
  191. internal class ClassDataNode : DataNode<object>
  192. {
  193. IList<ExtensionDataMember> members;
  194. internal ClassDataNode()
  195. {
  196. dataType = Globals.TypeOfClassDataNode;
  197. }
  198. internal IList<ExtensionDataMember> Members
  199. {
  200. get { return members; }
  201. set { members = value; }
  202. }
  203. public override void Clear()
  204. {
  205. base.Clear();
  206. members = null;
  207. }
  208. }
  209. internal class CollectionDataNode : DataNode<Array>
  210. {
  211. IList<IDataNode> items;
  212. string itemName;
  213. string itemNamespace;
  214. int size = -1;
  215. internal CollectionDataNode()
  216. {
  217. dataType = Globals.TypeOfCollectionDataNode;
  218. }
  219. internal IList<IDataNode> Items
  220. {
  221. get { return items; }
  222. set { items = value; }
  223. }
  224. internal string ItemName
  225. {
  226. get { return itemName; }
  227. set { itemName = value; }
  228. }
  229. internal string ItemNamespace
  230. {
  231. get { return itemNamespace; }
  232. set { itemNamespace = value; }
  233. }
  234. internal int Size
  235. {
  236. get { return size; }
  237. set { size = value; }
  238. }
  239. public override void GetData(ElementData element)
  240. {
  241. base.GetData(element);
  242. element.AddAttribute(Globals.SerPrefix, Globals.SerializationNamespace, Globals.ArraySizeLocalName, Size.ToString(NumberFormatInfo.InvariantInfo));
  243. }
  244. public override void Clear()
  245. {
  246. base.Clear();
  247. items = null;
  248. size = -1;
  249. }
  250. }
  251. internal class XmlDataNode : DataNode<object>
  252. {
  253. IList<XmlAttribute> xmlAttributes;
  254. IList<XmlNode> xmlChildNodes;
  255. XmlDocument ownerDocument;
  256. internal XmlDataNode()
  257. {
  258. dataType = Globals.TypeOfXmlDataNode;
  259. }
  260. internal IList<XmlAttribute> XmlAttributes
  261. {
  262. get { return xmlAttributes; }
  263. set { xmlAttributes = value; }
  264. }
  265. internal IList<XmlNode> XmlChildNodes
  266. {
  267. get { return xmlChildNodes; }
  268. set { xmlChildNodes = value; }
  269. }
  270. internal XmlDocument OwnerDocument
  271. {
  272. get { return ownerDocument; }
  273. set { ownerDocument = value; }
  274. }
  275. public override void Clear()
  276. {
  277. base.Clear();
  278. xmlAttributes = null;
  279. xmlChildNodes = null;
  280. ownerDocument = null;
  281. }
  282. }
  283. internal class ISerializableDataNode : DataNode<object>
  284. {
  285. string factoryTypeName;
  286. string factoryTypeNamespace;
  287. IList<ISerializableDataMember> members;
  288. internal ISerializableDataNode()
  289. {
  290. dataType = Globals.TypeOfISerializableDataNode;
  291. }
  292. internal string FactoryTypeName
  293. {
  294. get { return factoryTypeName; }
  295. set { factoryTypeName = value; }
  296. }
  297. internal string FactoryTypeNamespace
  298. {
  299. get { return factoryTypeNamespace; }
  300. set { factoryTypeNamespace = value; }
  301. }
  302. internal IList<ISerializableDataMember> Members
  303. {
  304. get { return members; }
  305. set { members = value; }
  306. }
  307. public override void GetData(ElementData element)
  308. {
  309. base.GetData(element);
  310. if (FactoryTypeName != null)
  311. AddQualifiedNameAttribute(element, Globals.SerPrefix, Globals.ISerializableFactoryTypeLocalName, Globals.SerializationNamespace, FactoryTypeName, FactoryTypeNamespace);
  312. }
  313. public override void Clear()
  314. {
  315. base.Clear();
  316. members = null;
  317. factoryTypeName = factoryTypeNamespace = null;
  318. }
  319. }
  320. internal class ISerializableDataMember
  321. {
  322. string name;
  323. IDataNode value;
  324. internal string Name
  325. {
  326. get { return name; }
  327. set { name = value; }
  328. }
  329. internal IDataNode Value
  330. {
  331. get { return value; }
  332. set { this.value = value; }
  333. }
  334. }
  335. }