/oSpy1/Parser/TransactionNode.cs

http://ospy.googlecode.com/ · C# · 302 lines · 236 code · 41 blank · 25 comment · 21 complexity · 829c5ea31f02cfde8a27a1ce3dd81d32 MD5 · raw file

  1. /**
  2. * Copyright (C) 2006 Ole André Vadla Ravn?s <oleavr@gmail.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Text;
  21. using Flobbster.Windows.Forms;
  22. using System.ComponentModel;
  23. using oSpy.Net;
  24. namespace oSpy.Parser
  25. {
  26. [Serializable()]
  27. [TypeConverterAttribute(typeof(TransactionNodeConverter))]
  28. public class TransactionNode : PropertyTable, IComparable
  29. {
  30. protected TransactionNode parent;
  31. public TransactionNode Parent
  32. {
  33. get { return parent; }
  34. }
  35. protected List<TransactionNode> children;
  36. public List<TransactionNode> Children
  37. {
  38. get { return children; }
  39. }
  40. protected Dictionary<string, TransactionNode> childrenDict;
  41. public Dictionary<string, TransactionNode> ChildrenDict
  42. {
  43. get { return childrenDict; }
  44. }
  45. protected string name;
  46. public string Name
  47. {
  48. get { return name; }
  49. }
  50. protected string description;
  51. public string Description
  52. {
  53. get { return description; }
  54. set { description = value; }
  55. }
  56. protected string summary;
  57. public string Summary
  58. {
  59. get { return summary; }
  60. set { summary = value; }
  61. }
  62. protected List<string> fieldNames;
  63. public List<string> FieldNames
  64. {
  65. get { return fieldNames; }
  66. }
  67. protected Dictionary<string, object> fields;
  68. public Dictionary<string, object> Fields
  69. {
  70. get { return fields; }
  71. }
  72. protected List<PacketSlice> slices;
  73. public List<PacketSlice> Slices
  74. {
  75. get { return slices; }
  76. }
  77. protected Dictionary<string, List<PacketSlice>> fieldSlices;
  78. public PacketSlice FirstSlice
  79. {
  80. get
  81. {
  82. if (slices.Count > 0)
  83. return slices[0];
  84. else if (children.Count > 0)
  85. return children[0].FirstSlice;
  86. else
  87. return null;
  88. }
  89. }
  90. public PacketSlice LastSlice
  91. {
  92. get
  93. {
  94. if (children.Count > 0)
  95. return children[children.Count - 1].LastSlice;
  96. else if (slices.Count > 0)
  97. return slices[slices.Count - 1];
  98. else
  99. return null;
  100. }
  101. }
  102. public DateTime StartTime
  103. {
  104. get { return FirstSlice.Packet.Timestamp; }
  105. }
  106. public DateTime EndTime
  107. {
  108. get { return LastSlice.Packet.Timestamp; }
  109. }
  110. public int Index
  111. {
  112. get
  113. {
  114. PacketSlice slice = FirstSlice;
  115. return (slice.Packet.Index << 11) | slice.Offset;
  116. }
  117. }
  118. public TransactionNode(string name)
  119. {
  120. Initialize(null, name);
  121. }
  122. public TransactionNode(TransactionNode parent, string name)
  123. {
  124. Initialize(parent, name);
  125. parent.AddChild(this);
  126. }
  127. private void Initialize(TransactionNode parent, string name)
  128. {
  129. this.name = name;
  130. this.description = "";
  131. this.summary = "";
  132. this.parent = parent;
  133. this.children = new List<TransactionNode>();
  134. this.childrenDict = new Dictionary<string, TransactionNode>();
  135. this.slices = new List<PacketSlice>();
  136. this.fieldNames = new List<string>();
  137. this.fields = new Dictionary<string, object>();
  138. this.fieldSlices = new Dictionary<string, List<PacketSlice>>();
  139. }
  140. public void AddChild(TransactionNode node)
  141. {
  142. children.Add(node);
  143. childrenDict[node.Name] = node;
  144. PropertySpec propSpec = new PropertySpec(node.Name, typeof(TransactionNode), "Packet");
  145. propSpec.Description = node.Name;
  146. propSpec.Attributes = new Attribute[1] { new ReadOnlyAttribute(true) };
  147. Properties.Add(propSpec);
  148. this[node.Name] = node;
  149. }
  150. public TransactionNode FindChild(string name)
  151. {
  152. return FindChild(name, true);
  153. }
  154. public TransactionNode FindChild(string name, bool recursive)
  155. {
  156. if (childrenDict.ContainsKey(name))
  157. return childrenDict[name];
  158. if (recursive)
  159. {
  160. foreach (TransactionNode child in childrenDict.Values)
  161. {
  162. TransactionNode node = child.FindChild(name);
  163. if (node != null)
  164. return node;
  165. }
  166. }
  167. return null;
  168. }
  169. public void AddField(string name, object value, string description, List<PacketSlice> slices)
  170. {
  171. AddField(name, value, value, description, slices);
  172. }
  173. public void AddField(string name, object value, object formattedValue, string description, List<PacketSlice> slices)
  174. {
  175. this.fieldNames.Add(name);
  176. this.fields[name] = value;
  177. Properties.Add(new PropertySpec(name, typeof(ValueType), "Packet", description));
  178. this[name] = formattedValue;
  179. AddFieldSlices(name, slices);
  180. }
  181. public void AddTextField(string name, object value, string description, List<PacketSlice> slices)
  182. {
  183. AddTextField(name, value, value, description, slices);
  184. }
  185. public void AddTextField(string name, object value, object formattedValue, string description, List<PacketSlice> slices)
  186. {
  187. AddSpecialField(name, value, formattedValue, description, slices, typeof(TextUITypeEditor));
  188. }
  189. public void AddXMLField(string name, object value, string description, List<PacketSlice> slices)
  190. {
  191. AddXMLField(name, value, value, description, slices);
  192. }
  193. public void AddXMLField(string name, object value, object formattedValue, string description, List<PacketSlice> slices)
  194. {
  195. AddSpecialField(name, value, formattedValue, description, slices, typeof(XMLUITypeEditor));
  196. }
  197. protected void AddSpecialField(string name, object value, object formattedValue, string description, List<PacketSlice> slices, Type editorType)
  198. {
  199. this.fieldNames.Add(name);
  200. this.fields[name] = value;
  201. PropertySpec propSpec = new PropertySpec(name, typeof(string), "Packet");
  202. propSpec.Description = description;
  203. propSpec.Attributes = new Attribute[2] {
  204. new System.ComponentModel.EditorAttribute(editorType, typeof(System.Drawing.Design.UITypeEditor)),
  205. new ReadOnlyAttribute(true)
  206. };
  207. Properties.Add(propSpec);
  208. this[name] = formattedValue;
  209. AddFieldSlices(name, slices);
  210. }
  211. protected void AddFieldSlices(string name, List<PacketSlice> slices)
  212. {
  213. this.slices.AddRange(slices);
  214. fieldSlices[name] = new List<PacketSlice>(slices);
  215. slices.Clear();
  216. }
  217. public List<PacketSlice> GetAllSlices()
  218. {
  219. List<PacketSlice> all = new List<PacketSlice>(slices.Count);
  220. all.AddRange(slices);
  221. foreach (TransactionNode node in childrenDict.Values)
  222. {
  223. List<PacketSlice> childAll = node.GetAllSlices();
  224. all.AddRange(childAll);
  225. }
  226. return all;
  227. }
  228. //
  229. // Gets the slices for the given path, which may contain the
  230. // full pipe-separated path to a subnode's field, or just the
  231. // name of a field on this node.
  232. //
  233. // For example:
  234. // "1|Request|hKey"
  235. //
  236. public List<PacketSlice> GetSlicesForFieldPath(string path)
  237. {
  238. if (path == null || path == "")
  239. return GetAllSlices();
  240. if (path.IndexOf("|") == -1)
  241. {
  242. if (childrenDict.ContainsKey(path))
  243. return childrenDict[path].GetAllSlices();
  244. else
  245. return fieldSlices[path];
  246. }
  247. string[] tokens = path.Split(new char[] { '|' }, 2);
  248. return childrenDict[tokens[0]].GetSlicesForFieldPath(tokens[1]);
  249. }
  250. public int CompareTo(Object obj)
  251. {
  252. TransactionNode otherNode = obj as TransactionNode;
  253. PacketSlice slice = FirstSlice;
  254. PacketSlice otherSlice = otherNode.FirstSlice;
  255. if (slice != null && otherSlice != null)
  256. return FirstSlice.CompareTo(otherNode.FirstSlice);
  257. else
  258. return 0; // FIXME
  259. }
  260. }
  261. }