XmlLogObject.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. using System.Xml;
  6. namespace Wayne.Lib.Log
  7. {
  8. /// <summary>
  9. /// Class that is used when logging XML data and wants to utilize the Debuglog mask facilitities.
  10. /// </summary>
  11. public class XmlLogObject : ILogObject
  12. {
  13. #region Private Classes and Enums
  14. private enum ProcessingInstructionAttributeElementKind
  15. {
  16. AttributeName,
  17. EqualSign,
  18. Value
  19. }
  20. #endregion
  21. #region Static Fields
  22. internal static string XmlMaskNode { get { return "MaskNode"; } }
  23. internal static string XmlMaskAttribute { get { return "MaskAttr"; } }
  24. internal static string XmlNodeName { get { return "node"; } }
  25. internal static string XmlAttributeName { get { return "attr"; } }
  26. internal static string XmlMaskKind { get { return "kind"; } }
  27. internal static string XmlMaskNextNodeName { get { return "."; } }
  28. #endregion
  29. #region Fields
  30. private string xml;
  31. private readonly IXmlElementMask[] elementMasks;
  32. #endregion
  33. #region Construction
  34. /// <summary>
  35. /// Constructor.
  36. /// </summary>
  37. /// <param name="xml">The XML document.</param>
  38. public XmlLogObject(string xml)
  39. {
  40. this.xml = xml;
  41. }
  42. /// <summary>
  43. /// Constructor.
  44. /// </summary>
  45. /// <param name="xml">The XML document.</param>
  46. /// <param name="elementMasks">Element masking.</param>
  47. public XmlLogObject(string xml, params IXmlElementMask[] elementMasks)
  48. {
  49. this.xml = xml;
  50. this.elementMasks = new IXmlElementMask[elementMasks.Length];
  51. Array.Copy(elementMasks, this.elementMasks, elementMasks.Length);
  52. }
  53. #endregion
  54. #region Properties
  55. /// <summary>
  56. /// The XML document.
  57. /// </summary>
  58. public string Xml
  59. {
  60. get { return xml; }
  61. }
  62. bool ILogObject.UsesFormat
  63. {
  64. get { return false; }
  65. }
  66. string ILogObject.Format
  67. {
  68. get { return string.Empty; }
  69. set { }
  70. }
  71. IFormatProvider ILogObject.Provider
  72. {
  73. get { return null; }
  74. set { }
  75. }
  76. #endregion
  77. #region Methods
  78. /// <summary>
  79. /// Appends this object's logObjects to a StringBuilder-output.
  80. /// </summary>
  81. /// <param name="output">The StringBuilder.</param>
  82. /// <param name="logWriter">The LogWriter to write the logObject.</param>
  83. /// <param name="indentLength">The indent to be used if many lines.</param>
  84. /// <param name="isFirstLine">Is this the first line to log?</param>
  85. /// <param name="indent">A string holding a generated indent-text (=a number of spaces). Use AppendIndent() to append the indent.</param>
  86. void ILogObject.AppendToStringBuilder(LogWriter logWriter, StringBuilder output,
  87. int indentLength, ref bool isFirstLine, ref string indent)
  88. {
  89. if (DebugLoggerMask.MaskSensitiveData)
  90. {
  91. StringBuilder newXml = new StringBuilder(xml);
  92. // mask Track 2
  93. const string trackTag = "<TagDataElement>57";
  94. int trackStart = xml.IndexOf(trackTag);
  95. if (trackStart > 0)
  96. {
  97. trackStart += trackTag.Length + 2;
  98. int trackEnd = xml.IndexOf("</TagDataElement>", trackStart);
  99. string orgTrack = xml.Substring(trackStart, trackEnd - trackStart);
  100. string maskedTrack = DebugLoggerMask.MaskData(orgTrack, DebugLogMaskKind.MaskTrack64);
  101. newXml.Replace(orgTrack, maskedTrack);
  102. }
  103. // mask PAN
  104. const string panTag = "<TagDataElement>5A";
  105. int panStart = xml.IndexOf(panTag);
  106. if (panStart > 0)
  107. {
  108. panStart += panTag.Length + 2;
  109. int panEnd = xml.IndexOf("</TagDataElement>", panStart);
  110. string orgPan = xml.Substring(panStart, panEnd - panStart);
  111. string maskedPan = DebugLoggerMask.MaskData(orgPan, DebugLogMaskKind.MaskPan64);
  112. newXml.Replace(orgPan, maskedPan);
  113. }
  114. StringReader xmlStringReader = new StringReader(newXml.ToString());
  115. XmlReader xmlReader = XmlReader.Create(xmlStringReader);
  116. XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
  117. xmlWriterSettings.OmitXmlDeclaration = true;
  118. xmlWriterSettings.Indent = true;
  119. StringBuilder cleanXml = new StringBuilder();
  120. #if DEBUG
  121. cleanXml.Append("## MASKED ## ");
  122. #endif
  123. XmlWriter xmlWriter = XmlWriter.Create(cleanXml, xmlWriterSettings);
  124. Dictionary<string, XmlNodeMask> maskedNodes = new Dictionary<string, XmlNodeMask>(StringComparer.CurrentCultureIgnoreCase);
  125. Dictionary<string, Dictionary<string, XmlAttributeMask>> maskedAttributes = new Dictionary<string, Dictionary<string, XmlAttributeMask>>(StringComparer.CurrentCultureIgnoreCase);
  126. int emptyNodeDepth = int.MaxValue;
  127. int maskNodeDepth = int.MaxValue;
  128. int maskDigitsNodeDepth = int.MaxValue;
  129. int maskDigitsAppendHashNodeDepth = int.MaxValue;
  130. int maskHexNodeDepth = int.MaxValue;
  131. int maskHexAppendHashNodeDepth = int.MaxValue;
  132. int maskPanNodeDepth = int.MaxValue;
  133. int maskPanAppendHashNodeDepth = int.MaxValue;
  134. int maskEmbeddedPanNodeDepth = int.MaxValue;
  135. int maskEmbeddedPanAppendHashNodeDepth = int.MaxValue;
  136. DebugLogMaskKind maskNextNode = DebugLogMaskKind.None;
  137. bool skipWhitespace = true;
  138. if (elementMasks != null)
  139. {
  140. foreach (IXmlElementMask elementMask in elementMasks)
  141. {
  142. XmlAttributeMask xmlAttributeMask = elementMask as XmlAttributeMask;
  143. if (xmlAttributeMask != null)
  144. AddXmlAttributeMask(maskedAttributes, xmlAttributeMask.NodeName, xmlAttributeMask.AttributeName, xmlAttributeMask.MaskKind);
  145. else
  146. {
  147. XmlNodeMask xmlNodeMask = elementMask as XmlNodeMask;
  148. if (xmlNodeMask != null)
  149. AddXmlNodeMask(maskedNodes, xmlNodeMask.NodeName, xmlNodeMask.MaskKind);
  150. }
  151. }
  152. }
  153. while (xmlReader.Read())
  154. {
  155. if (xmlReader.NodeType == XmlNodeType.ProcessingInstruction)
  156. {
  157. if (xmlReader.Name.Equals(XmlMaskNode))
  158. {
  159. Dictionary<string, string> attributes = GetProcessingInstructionAttributes(xmlReader);
  160. string nodeName;
  161. if (attributes.TryGetValue(XmlNodeName, out nodeName))
  162. {
  163. DebugLogMaskKind maskKind = InterpretMaskKind(attributes);
  164. if (nodeName.Equals(XmlMaskNextNodeName))
  165. maskNextNode = maskKind;
  166. else
  167. AddXmlNodeMask(maskedNodes, nodeName, maskKind);
  168. }
  169. }
  170. else if (xmlReader.Name.Equals(XmlMaskAttribute))
  171. {
  172. Dictionary<string, string> attributes = GetProcessingInstructionAttributes(xmlReader);
  173. string nodeName;
  174. if (attributes.TryGetValue(XmlNodeName, out nodeName))
  175. {
  176. string attributeName;
  177. if (attributes.TryGetValue(XmlAttributeName, out attributeName))
  178. {
  179. DebugLogMaskKind maskKind = InterpretMaskKind(attributes);
  180. AddXmlAttributeMask(maskedAttributes, nodeName, attributeName, maskKind);
  181. }
  182. }
  183. }
  184. }
  185. CopyNodeContent(xmlReader, xmlWriter, maskedNodes, maskedAttributes,
  186. ref emptyNodeDepth, ref maskNodeDepth, ref maskDigitsNodeDepth, ref maskDigitsAppendHashNodeDepth,
  187. ref maskHexNodeDepth, ref maskHexAppendHashNodeDepth,
  188. ref maskPanNodeDepth, ref maskPanAppendHashNodeDepth,
  189. ref maskEmbeddedPanNodeDepth, ref maskEmbeddedPanAppendHashNodeDepth,
  190. ref maskNextNode, ref skipWhitespace);
  191. }
  192. xmlWriter.Close();
  193. xmlReader.Close();
  194. StringLogObject.AppendObjectToStringBuilder(cleanXml, output, logWriter, indentLength, ref isFirstLine, ref indent);
  195. }
  196. else
  197. {
  198. try
  199. {
  200. StringBuilder sb = new StringBuilder();
  201. int endOfString = xml.IndexOf('\0');
  202. if (endOfString > -1)
  203. xml = xml.Substring(0, endOfString); // Sometimes there come strings with null-characters which the XML reader doesn't like...
  204. XmlReader xmlReader = XmlReader.Create(new StringReader(xml));
  205. XmlWriterSettings settings = new XmlWriterSettings();
  206. settings.Indent = true;
  207. XmlWriter xmlWriter = XmlWriter.Create(sb, settings);
  208. xmlWriter.WriteNode(xmlReader, false);
  209. xmlWriter.Flush();
  210. StringLogObject.AppendObjectToStringBuilder(sb.ToString(), output, logWriter, indentLength, ref isFirstLine, ref indent);
  211. }
  212. catch (ArgumentException)
  213. {
  214. // Just log the xml as a string.
  215. StringLogObject.AppendObjectToStringBuilder(xml, output, logWriter, indentLength, ref isFirstLine, ref indent);
  216. }
  217. }
  218. }
  219. private static void AddXmlNodeMask(IDictionary<string, XmlNodeMask> maskedNodes, string nodeName, DebugLogMaskKind maskKind)
  220. {
  221. XmlNodeMask existingXmlNodeMask;
  222. if (maskedNodes.TryGetValue(nodeName, out existingXmlNodeMask))
  223. {
  224. if (maskKind == DebugLogMaskKind.None)
  225. maskedNodes.Remove(nodeName);
  226. else
  227. existingXmlNodeMask.MaskKind = maskKind;
  228. }
  229. else if (maskKind != DebugLogMaskKind.None)
  230. maskedNodes.Add(nodeName, new XmlNodeMask(nodeName, maskKind));
  231. }
  232. private static void AddXmlAttributeMask(IDictionary<string, Dictionary<string, XmlAttributeMask>> maskedAttributes, string nodeName, string attributeName, DebugLogMaskKind maskKind)
  233. {
  234. bool newDict = false;
  235. Dictionary<string, XmlAttributeMask> attributeMaskDict;
  236. if (!maskedAttributes.TryGetValue(nodeName, out attributeMaskDict))
  237. {
  238. attributeMaskDict = new Dictionary<string, XmlAttributeMask>(StringComparer.CurrentCultureIgnoreCase);
  239. newDict = true;
  240. }
  241. XmlAttributeMask existingXmlAttributeMask;
  242. if (attributeMaskDict.TryGetValue(attributeName, out existingXmlAttributeMask))
  243. {
  244. if (maskKind == DebugLogMaskKind.None)
  245. attributeMaskDict.Remove(attributeName);
  246. else
  247. existingXmlAttributeMask.MaskKind = maskKind;
  248. }
  249. else if (maskKind != DebugLogMaskKind.None)
  250. attributeMaskDict.Add(attributeName, new XmlAttributeMask(nodeName, attributeName, maskKind));
  251. if (newDict)
  252. maskedAttributes.Add(nodeName, attributeMaskDict);
  253. }
  254. #endregion
  255. #region GetProcessingInstructionAttributes
  256. private static Dictionary<string, string> GetProcessingInstructionAttributes(XmlReader xmlReader)
  257. {
  258. Dictionary<string, string> attributes = new Dictionary<string, string>();
  259. string[] elements = xmlReader.Value.Split(' ');
  260. ProcessingInstructionAttributeElementKind elementKind = ProcessingInstructionAttributeElementKind.AttributeName;
  261. string currentAttributeName = string.Empty;
  262. int equalSignPos;
  263. foreach (string element in elements)
  264. {
  265. if (!string.IsNullOrEmpty(element))
  266. {
  267. switch (elementKind)
  268. {
  269. case ProcessingInstructionAttributeElementKind.AttributeName:
  270. equalSignPos = element.IndexOf('=');
  271. if (equalSignPos > -1)
  272. {
  273. if (equalSignPos > 0)
  274. {
  275. currentAttributeName = element.Substring(0, equalSignPos);
  276. if (equalSignPos == element.Length - 1)
  277. elementKind = ProcessingInstructionAttributeElementKind.Value;
  278. else
  279. {
  280. string value = element.Substring(equalSignPos + 1);
  281. if (value.StartsWith("\"") && value.EndsWith("\""))
  282. attributes[currentAttributeName] = value.Substring(1, value.Length - 2);
  283. elementKind = ProcessingInstructionAttributeElementKind.AttributeName;
  284. }
  285. }
  286. }
  287. else
  288. {
  289. currentAttributeName = element;
  290. elementKind = ProcessingInstructionAttributeElementKind.EqualSign;
  291. }
  292. break;
  293. case ProcessingInstructionAttributeElementKind.EqualSign:
  294. if (element.Equals("="))
  295. elementKind = ProcessingInstructionAttributeElementKind.Value;
  296. else if (element.StartsWith("="))
  297. {
  298. string value = element.Substring(1);
  299. if (value.StartsWith("\"") && value.EndsWith("\""))
  300. attributes[currentAttributeName] = value.Substring(1, value.Length - 2);
  301. elementKind = ProcessingInstructionAttributeElementKind.AttributeName;
  302. }
  303. break;
  304. case ProcessingInstructionAttributeElementKind.Value:
  305. if (element.StartsWith("\"") && element.EndsWith("\""))
  306. attributes[currentAttributeName] = element.Substring(1, element.Length - 2);
  307. elementKind = ProcessingInstructionAttributeElementKind.AttributeName;
  308. break;
  309. }
  310. }
  311. }
  312. return attributes;
  313. }
  314. #endregion
  315. #region InterpretMaskKind
  316. private static DebugLogMaskKind InterpretMaskKind(Dictionary<string, string> attributes)
  317. {
  318. string maskKindValue;
  319. if (attributes.TryGetValue(XmlMaskKind, out maskKindValue))
  320. {
  321. try
  322. {
  323. return (DebugLogMaskKind)Enum.Parse(typeof(DebugLogMaskKind), maskKindValue, true);
  324. }
  325. catch (ArgumentException) { }
  326. }
  327. return DebugLogMaskKind.Remove;
  328. }
  329. #endregion
  330. #region CopyNodeContent
  331. private static void CopyNodeContent(XmlReader xmlReader, XmlWriter xmlWriter,
  332. Dictionary<string, XmlNodeMask> maskedNodes, Dictionary<string, Dictionary<string, XmlAttributeMask>> maskedAttributes,
  333. ref int emptyNodeDepth, ref int maskNodeDepth, ref int maskDigitsNodeDepth, ref int maskDigitsAppendHashNodeDepth,
  334. ref int maskHexNodeDepth, ref int maskHexAppendHashNodeDepth, ref int maskPanNodeDepth, ref int maskPanAppendHashNodeDepth,
  335. ref int maskEmbeddedPanNodeDepth, ref int maskEmbeddedPanAppendHashNodeDepth, ref DebugLogMaskKind maskNextNode, ref bool skipWhitespace)
  336. {
  337. switch (xmlReader.NodeType)
  338. {
  339. case XmlNodeType.Element:
  340. if (xmlReader.Depth < emptyNodeDepth)
  341. {
  342. bool skip = false;
  343. XmlNodeMask xmlNodeMask;
  344. DebugLogMaskKind maskKind;
  345. if (maskNextNode != DebugLogMaskKind.None)
  346. {
  347. maskKind = maskNextNode;
  348. maskNextNode = DebugLogMaskKind.None;
  349. }
  350. else if (maskedNodes.TryGetValue(xmlReader.LocalName, out xmlNodeMask))
  351. maskKind = xmlNodeMask.MaskKind;
  352. else
  353. maskKind = DebugLogMaskKind.None;
  354. switch (maskKind)
  355. {
  356. case DebugLogMaskKind.Remove:
  357. xmlReader.Skip();
  358. skip = true;
  359. break;
  360. case DebugLogMaskKind.Empty:
  361. emptyNodeDepth = xmlReader.Depth;
  362. break;
  363. case DebugLogMaskKind.Mask:
  364. maskNodeDepth = xmlReader.Depth;
  365. break;
  366. case DebugLogMaskKind.MaskDigits:
  367. maskDigitsNodeDepth = xmlReader.Depth;
  368. break;
  369. case DebugLogMaskKind.MaskDigitsAppendHash:
  370. maskDigitsAppendHashNodeDepth = xmlReader.Depth;
  371. break;
  372. case DebugLogMaskKind.MaskHex:
  373. maskHexNodeDepth = xmlReader.Depth;
  374. break;
  375. case DebugLogMaskKind.MaskHexAppendHash:
  376. maskHexAppendHashNodeDepth = xmlReader.Depth;
  377. break;
  378. case DebugLogMaskKind.MaskPan:
  379. maskPanNodeDepth = xmlReader.Depth;
  380. break;
  381. case DebugLogMaskKind.MaskPanAppendHash:
  382. maskPanAppendHashNodeDepth = xmlReader.Depth;
  383. break;
  384. case DebugLogMaskKind.MaskEmbeddedPan:
  385. maskEmbeddedPanNodeDepth = xmlReader.Depth;
  386. break;
  387. case DebugLogMaskKind.MaskEmbeddedPanAppendHash:
  388. maskEmbeddedPanAppendHashNodeDepth = xmlReader.Depth;
  389. break;
  390. }
  391. if (!skip)
  392. {
  393. skipWhitespace = false;
  394. xmlWriter.WriteStartElement(xmlReader.Prefix, xmlReader.LocalName, xmlReader.NamespaceURI);
  395. if ((xmlReader.Depth < emptyNodeDepth) && xmlReader.HasAttributes)
  396. {
  397. bool manualAttributes = false;
  398. Dictionary<string, XmlAttributeMask> attributeMaskDict;
  399. if (maskedAttributes.TryGetValue(xmlReader.LocalName, out attributeMaskDict) && (attributeMaskDict.Count > 0))
  400. {
  401. manualAttributes = true;
  402. while (xmlReader.MoveToNextAttribute())
  403. {
  404. if (!xmlReader.Prefix.Equals("xmlns")) // This attribute is already written.
  405. {
  406. bool writeAttribute = true;
  407. string value = xmlReader.Value;
  408. XmlAttributeMask xmlAttributeMask;
  409. if (attributeMaskDict.TryGetValue(xmlReader.Name, out xmlAttributeMask))
  410. {
  411. switch (xmlAttributeMask.MaskKind)
  412. {
  413. case DebugLogMaskKind.Remove: writeAttribute = false; break;
  414. case DebugLogMaskKind.Empty: value = string.Empty; break;
  415. default: value = DebugLoggerMask.MaskData(value, xmlAttributeMask.MaskKind); break;
  416. }
  417. }
  418. if (writeAttribute)
  419. {
  420. xmlWriter.WriteStartAttribute(xmlReader.Prefix, xmlReader.LocalName, xmlReader.NamespaceURI);
  421. xmlWriter.WriteValue(value);
  422. xmlWriter.WriteEndAttribute();
  423. }
  424. }
  425. }
  426. xmlReader.MoveToElement(); // Move the reader back to the element node.
  427. }
  428. if (!manualAttributes)
  429. xmlWriter.WriteAttributes(xmlReader, true);
  430. }
  431. if (xmlReader.IsEmptyElement)
  432. {
  433. if ((emptyNodeDepth < int.MaxValue) && (xmlReader.Depth <= emptyNodeDepth))
  434. emptyNodeDepth = int.MaxValue;
  435. if ((maskNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskNodeDepth))
  436. maskNodeDepth = int.MaxValue;
  437. if ((maskDigitsNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskDigitsNodeDepth))
  438. maskDigitsNodeDepth = int.MaxValue;
  439. if ((maskDigitsAppendHashNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskDigitsAppendHashNodeDepth))
  440. maskDigitsAppendHashNodeDepth = int.MaxValue;
  441. if ((maskHexNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskHexNodeDepth))
  442. maskHexNodeDepth = int.MaxValue;
  443. if ((maskHexAppendHashNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskHexAppendHashNodeDepth))
  444. maskHexAppendHashNodeDepth = int.MaxValue;
  445. if ((maskPanNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskPanNodeDepth))
  446. maskPanNodeDepth = int.MaxValue;
  447. if ((maskPanAppendHashNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskPanAppendHashNodeDepth))
  448. maskPanAppendHashNodeDepth = int.MaxValue;
  449. if ((maskEmbeddedPanNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskEmbeddedPanNodeDepth))
  450. maskEmbeddedPanNodeDepth = int.MaxValue;
  451. if ((maskEmbeddedPanAppendHashNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskEmbeddedPanAppendHashNodeDepth))
  452. maskEmbeddedPanAppendHashNodeDepth = int.MaxValue;
  453. xmlWriter.WriteEndElement();
  454. }
  455. }
  456. }
  457. break;
  458. case XmlNodeType.Text:
  459. if (xmlReader.Depth < emptyNodeDepth)
  460. {
  461. if (xmlReader.Depth >= maskNodeDepth)
  462. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.Mask));
  463. else if (xmlReader.Depth >= maskDigitsNodeDepth)
  464. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.MaskDigits));
  465. else if (xmlReader.Depth >= maskDigitsAppendHashNodeDepth)
  466. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.MaskDigitsAppendHash));
  467. else if (xmlReader.Depth >= maskHexNodeDepth)
  468. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.MaskHex));
  469. else if (xmlReader.Depth >= maskHexAppendHashNodeDepth)
  470. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.MaskHexAppendHash));
  471. else if (xmlReader.Depth >= maskPanNodeDepth)
  472. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.MaskPan));
  473. else if (xmlReader.Depth >= maskPanAppendHashNodeDepth)
  474. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.MaskPanAppendHash));
  475. else if (xmlReader.Depth >= maskEmbeddedPanNodeDepth)
  476. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.MaskEmbeddedPan));
  477. else if (xmlReader.Depth >= maskEmbeddedPanAppendHashNodeDepth)
  478. xmlWriter.WriteString(DebugLoggerMask.MaskData(xmlReader.Value, DebugLogMaskKind.MaskEmbeddedPanAppendHash));
  479. else
  480. xmlWriter.WriteString(xmlReader.Value);
  481. skipWhitespace = false;
  482. }
  483. break;
  484. case XmlNodeType.Whitespace:
  485. case XmlNodeType.SignificantWhitespace:
  486. if (!skipWhitespace && (xmlReader.Depth < emptyNodeDepth))
  487. xmlWriter.WriteWhitespace(xmlReader.Value);
  488. break;
  489. case XmlNodeType.CDATA:
  490. if (xmlReader.Depth < emptyNodeDepth)
  491. {
  492. xmlWriter.WriteCData(xmlReader.Value);
  493. skipWhitespace = false;
  494. }
  495. break;
  496. case XmlNodeType.EntityReference:
  497. if (xmlReader.Depth < emptyNodeDepth)
  498. {
  499. xmlWriter.WriteEntityRef(xmlReader.Name);
  500. skipWhitespace = false;
  501. }
  502. break;
  503. case XmlNodeType.XmlDeclaration:
  504. //if (xmlReader.Depth < emptyNodeDepth)
  505. // xmlWriter.WriteProcessingInstruction(xmlReader.Name, xmlReader.Value);
  506. skipWhitespace = true;
  507. break;
  508. case XmlNodeType.ProcessingInstruction:
  509. //if (xmlReader.Depth < emptyNodeDepth)
  510. // xmlWriter.WriteProcessingInstruction(xmlReader.Name, xmlReader.Value);
  511. skipWhitespace = true;
  512. break;
  513. case XmlNodeType.DocumentType:
  514. if (xmlReader.Depth < emptyNodeDepth)
  515. {
  516. xmlWriter.WriteDocType(xmlReader.Name, xmlReader.GetAttribute("PUBLIC"), xmlReader.GetAttribute("SYSTEM"), xmlReader.Value);
  517. skipWhitespace = false;
  518. }
  519. break;
  520. case XmlNodeType.Comment:
  521. skipWhitespace = false;
  522. if (xmlReader.Depth < emptyNodeDepth)
  523. {
  524. xmlWriter.WriteComment(xmlReader.Value);
  525. skipWhitespace = false;
  526. }
  527. break;
  528. case XmlNodeType.EndElement:
  529. if ((emptyNodeDepth < int.MaxValue) && (xmlReader.Depth <= emptyNodeDepth))
  530. emptyNodeDepth = int.MaxValue;
  531. if ((maskNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskNodeDepth))
  532. maskNodeDepth = int.MaxValue;
  533. if ((maskDigitsNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskDigitsNodeDepth))
  534. maskDigitsNodeDepth = int.MaxValue;
  535. if ((maskDigitsAppendHashNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskDigitsAppendHashNodeDepth))
  536. maskDigitsAppendHashNodeDepth = int.MaxValue;
  537. if ((maskHexNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskHexNodeDepth))
  538. maskHexNodeDepth = int.MaxValue;
  539. if ((maskHexAppendHashNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskHexAppendHashNodeDepth))
  540. maskHexAppendHashNodeDepth = int.MaxValue;
  541. if ((maskPanNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskPanNodeDepth))
  542. maskPanNodeDepth = int.MaxValue;
  543. if ((maskPanAppendHashNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskPanAppendHashNodeDepth))
  544. maskPanAppendHashNodeDepth = int.MaxValue;
  545. if ((maskEmbeddedPanNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskEmbeddedPanNodeDepth))
  546. maskEmbeddedPanNodeDepth = int.MaxValue;
  547. if ((maskEmbeddedPanAppendHashNodeDepth < int.MaxValue) && (xmlReader.Depth <= maskEmbeddedPanAppendHashNodeDepth))
  548. maskEmbeddedPanAppendHashNodeDepth = int.MaxValue;
  549. if (xmlReader.Depth < emptyNodeDepth)
  550. {
  551. xmlWriter.WriteFullEndElement();
  552. skipWhitespace = false;
  553. }
  554. break;
  555. }
  556. }
  557. #endregion
  558. }
  559. }