PageRenderTime 25ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/System.Xml.XDocument/tests/XDocument.Common/ManagedNodeWriter.cs

https://gitlab.com/0072016/0072016-corefx-
C# | 325 lines | 215 code | 42 blank | 68 comment | 5 complexity | 9705d78f2ff62cc931c69e85f430d9a0 MD5 | raw file
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Text;
  8. namespace CoreXml.Test.XLinq
  9. {
  10. public class ManagedNodeWriter
  11. {
  12. public static bool DEBUG = false;
  13. private const string XML_DECL = "<?xml version='1.0' ?>\n";
  14. private const string S_ROOT = "<root>";
  15. private const string E_ROOT = "</root>";
  16. private const string E_NAME = "ELEMENT_";
  17. private const string A_NAME = "ATTRIB_";
  18. private const string A_VALUE = "VALUE_";
  19. private const string CDATA = "CDATA_";
  20. private const string TEXT = "TEXT_";
  21. private const string PI = "PI_";
  22. private const string COMMENT = "COMMENT_";
  23. private long _eCount = 0; //element indexer
  24. private long _aCount = 0; //attribute indexer
  25. private long _cCount = 0; //Cdata indexer
  26. private long _tCount = 0; //Text indexer
  27. private long _pCount = 0; //PI Indexer
  28. private long _mCount = 0; //Comment Indexer
  29. private StreamWriter _textWriter = null;
  30. private Stack<string> _elementStack = new Stack<string>();
  31. private StringBuilder _nodeQueue = new StringBuilder();
  32. private const string LT = "<";
  33. private const string GT = ">";
  34. private const string MT = "/>";
  35. private const string ET = "</";
  36. private const string SPACE = " ";
  37. private const string S_QUOTE = "'";
  38. private const string D_QUOTE = "\"";
  39. private const string EQ = "=";
  40. private const string LF = "\n";
  41. public ManagedNodeWriter()
  42. { }
  43. public ManagedNodeWriter(Stream myStream, Encoding enc)
  44. {
  45. _textWriter = new StreamWriter(myStream, enc);
  46. }
  47. /// <summary>
  48. /// GetNodes returns the existing XML string thats been written so far.
  49. /// </summary>
  50. /// <returns>String of XML</returns>
  51. public string GetNodes()
  52. {
  53. return _nodeQueue.ToString();
  54. }
  55. /// Closing the NodeWriter
  56. public void Close()
  57. {
  58. if (_textWriter != null)
  59. {
  60. _textWriter.Write(_nodeQueue.ToString());
  61. _textWriter.Dispose();
  62. _textWriter = null;
  63. }
  64. }
  65. /// Writing XML Decl
  66. public void PutDecl()
  67. {
  68. _nodeQueue.Append(XML_DECL);
  69. }
  70. /// Writing a Root Element.
  71. public void PutRoot()
  72. {
  73. _nodeQueue.Append(S_ROOT);
  74. }
  75. /// Writing End Root Element.
  76. public void PutEndRoot()
  77. {
  78. _nodeQueue.Append(E_ROOT);
  79. }
  80. /// Writing a start of open element.
  81. public void OpenElement()
  82. {
  83. string elem = LT + E_NAME + _eCount + SPACE;
  84. _nodeQueue.Append(elem);
  85. _elementStack.Push(E_NAME + _eCount);
  86. ++_eCount;
  87. }
  88. /// Writing a start of open element with user supplied name.
  89. public void OpenElement(string myName)
  90. {
  91. string elem = LT + myName + SPACE;
  92. _elementStack.Push(myName);
  93. _nodeQueue.Append(elem);
  94. }
  95. /// Closing the open element.
  96. public void CloseElement()
  97. {
  98. _nodeQueue.Append(GT);
  99. }
  100. // Closing the open element as empty element
  101. public void CloseEmptyElement()
  102. {
  103. _nodeQueue.Append(MT);
  104. }
  105. /// Writing an attribute.
  106. public void PutAttribute()
  107. {
  108. string attr = A_NAME + _aCount + EQ + S_QUOTE + A_VALUE + _aCount + S_QUOTE + SPACE;
  109. _nodeQueue.Append(attr);
  110. ++_aCount;
  111. }
  112. /// Overloaded PutAttribute which takes user values.
  113. public void PutAttribute(string myAttrName, string myAttrValue)
  114. {
  115. string attr = SPACE + myAttrName + EQ + S_QUOTE + myAttrValue + S_QUOTE;
  116. _nodeQueue.Append(attr);
  117. }
  118. /// Writing empty element.
  119. public void PutEmptyElement()
  120. {
  121. string elem = LT + E_NAME + _eCount + MT;
  122. _nodeQueue.Append(elem);
  123. ++_eCount;
  124. }
  125. /// Writing an end element from the stack.
  126. public void PutEndElement()
  127. {
  128. string elem = _elementStack.Pop();
  129. _nodeQueue.Append(ET + elem + GT);
  130. }
  131. /// Writing an end element for a given name.
  132. public void PutEndElement(string myName)
  133. {
  134. if (DEBUG)
  135. {
  136. string elem = _elementStack.Pop();
  137. }
  138. _nodeQueue.Append(ET + myName + GT);
  139. }
  140. /// <summary>
  141. /// Finish allows user to complete xml file with the end element tags that were so far open.
  142. /// </summary>
  143. public void Finish()
  144. {
  145. while (_elementStack.Count > 0)
  146. {
  147. string elem = _elementStack.Pop();
  148. _nodeQueue.Append(ET + elem + GT);
  149. }
  150. }
  151. /// Writing text.
  152. /// Note : This is basically equivalent to WriteRaw and the string may contain any number of embedded tags.
  153. /// No checking is performed on them either.
  154. public void PutText(string myStr)
  155. {
  156. _nodeQueue.Append(myStr);
  157. }
  158. /// <summary>
  159. /// AutoGenerated Text
  160. /// </summary>
  161. public void PutText()
  162. {
  163. _nodeQueue.Append(TEXT + _tCount++);
  164. }
  165. /// <summary>
  166. /// Writing a Byte Array.
  167. /// </summary>
  168. /// <param name="bArr"></param>
  169. public void PutBytes(byte[] bArr)
  170. {
  171. foreach (byte b in bArr)
  172. {
  173. _nodeQueue.Append(b);
  174. }
  175. }
  176. public void PutByte()
  177. {
  178. _nodeQueue.Append(Convert.ToByte("a"));
  179. }
  180. /// <summary>
  181. /// Writes out CDATA Node.
  182. /// </summary>
  183. public void PutCData()
  184. {
  185. _nodeQueue.Append("<![CDATA[" + CDATA + _cCount++ + "]]>");
  186. }
  187. /// <summary>
  188. /// Writes out a PI Node.
  189. /// </summary>
  190. public void PutPI()
  191. {
  192. _nodeQueue.Append("<?" + PI + _pCount++ + "?>");
  193. }
  194. /// <summary>
  195. /// Writes out a Comment Node.
  196. /// </summary>
  197. public void PutComment()
  198. {
  199. _nodeQueue.Append("<!--" + COMMENT + _mCount++ + " -->");
  200. }
  201. /// <summary>
  202. /// Writes out a single whitespace
  203. /// </summary>
  204. public void PutWhiteSpace()
  205. {
  206. _nodeQueue.Append(" ");
  207. }
  208. /// <summary>
  209. /// This method is a conveinience method and a shortcut to create an XML string. Each character in the pattern
  210. /// maps to a particular Put/Open function and calls it for you. For e.g. XEAA/ will call PutDecl, OpenElement,
  211. /// PutAttribute, PutAttribute and CloseElement for you.
  212. /// The following is the list of all allowed characters and their function mappings :
  213. ///
  214. ///'X' : PutDecl()
  215. ///'E' : OpenElement()
  216. ///'M' : CloseEmptyElement()
  217. ///'/' : CloseElement()
  218. ///'e' : PutEndElement()
  219. ///'A' : PutAttribute()
  220. ///'P' : PutPI()
  221. ///'T' : PutText()
  222. ///'C' : PutComment()
  223. ///'R' : PutRoot()
  224. ///'r' : PutEndRoot()
  225. ///'B' : PutEndRoot()
  226. ///'W' : PutWhiteSpace()
  227. ///
  228. /// </summary>
  229. /// <param name="pattern">String containing the pattern which you want to use to create
  230. /// the XML string. Refer to table above for supported chars.</param>
  231. public void PutPattern(string pattern)
  232. {
  233. char[] patternArr = pattern.ToCharArray();
  234. foreach (char ch in patternArr)
  235. {
  236. switch (ch)
  237. {
  238. case 'X':
  239. PutDecl();
  240. break;
  241. case 'E':
  242. OpenElement();
  243. break;
  244. case 'M':
  245. CloseEmptyElement();
  246. break;
  247. case '/':
  248. CloseElement();
  249. break;
  250. case 'e':
  251. PutEndElement();
  252. break;
  253. case 'A':
  254. PutAttribute();
  255. break;
  256. case 'P':
  257. PutPI();
  258. break;
  259. case 'T':
  260. PutText();
  261. break;
  262. case 'C':
  263. PutComment();
  264. break;
  265. case 'R':
  266. PutRoot();
  267. break;
  268. case 'r':
  269. PutEndRoot();
  270. break;
  271. case 'B':
  272. PutEndRoot();
  273. break;
  274. case 'W':
  275. PutWhiteSpace();
  276. break;
  277. default:
  278. break;
  279. }
  280. }
  281. }
  282. }
  283. }