/MediaPortal/Source/System/HttpServer/HttpInputItem.cs

https://github.com/cienesdi/MediaPortal-2 · C# · 299 lines · 167 code · 34 blank · 98 comment · 27 complexity · 545a0f32bbf7e52d5610f300b3b26993 MD5 · raw file

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. namespace HttpServer
  5. {
  6. /// <summary>
  7. /// represents a HTTP input item. Each item can have multiple sub items, a sub item
  8. /// is made in a HTML form by using square brackets
  9. /// </summary>
  10. /// <example>
  11. /// // <input type="text" name="user[FirstName]" value="jonas" /> becomes:
  12. /// Console.WriteLine("Value: {0}", form["user"]["FirstName"].Value);
  13. /// </example>
  14. /// <remarks>
  15. /// All names in a form SHOULD be in lowercase.
  16. /// </remarks>
  17. public class HttpInputItem : IHttpInput
  18. {
  19. /// <summary> Representation of a non-initialized <see cref="HttpInputItem"/>.</summary>
  20. public static readonly HttpInputItem Empty = new HttpInputItem(string.Empty, true);
  21. private readonly IDictionary<string, HttpInputItem> _items = new Dictionary<string, HttpInputItem>();
  22. private readonly List<string> _values = new List<string>();
  23. private string _name;
  24. private readonly bool _ignoreChanges;
  25. /// <summary>
  26. /// Initializes an input item setting its name/identifier and value
  27. /// </summary>
  28. /// <param name="name">Parameter name/id</param>
  29. /// <param name="value">Parameter value</param>
  30. public HttpInputItem(string name, string value)
  31. {
  32. Name = name;
  33. Add(value);
  34. }
  35. private HttpInputItem(string name, bool ignore)
  36. {
  37. Name = name;
  38. _ignoreChanges = ignore;
  39. }
  40. /// <summary>Creates a deep copy of the item specified</summary>
  41. /// <param name="item">The item to copy</param>
  42. /// <remarks>The function makes a deep copy of quite a lot which can be slow</remarks>
  43. public HttpInputItem(HttpInputItem item)
  44. {
  45. foreach (KeyValuePair<string, HttpInputItem> pair in item._items)
  46. _items.Add(pair.Key, pair.Value);
  47. foreach (string value in item._values)
  48. _values.Add(value);
  49. _ignoreChanges = item._ignoreChanges;
  50. _name = item.Name;
  51. }
  52. /// <summary>
  53. /// Number of values
  54. /// </summary>
  55. public int Count
  56. {
  57. get { return _values.Count; }
  58. }
  59. /// <summary>
  60. /// Get a sub item
  61. /// </summary>
  62. /// <param name="name">name in lower case.</param>
  63. /// <returns><see cref="HttpInputItem.Empty"/> if no item was found.</returns>
  64. public HttpInputItem this[string name]
  65. {
  66. get { return _items.ContainsKey(name) ? _items[name] : Empty; }
  67. }
  68. /// <summary>
  69. /// Name of item (in lower case).
  70. /// </summary>
  71. public string Name
  72. {
  73. get { return _name; }
  74. set { _name = value; }
  75. }
  76. /// <summary>
  77. /// Returns the first value, or null if no value exist.
  78. /// </summary>
  79. public string Value
  80. {
  81. get { return _values.Count == 0 ? null : _values[0]; }
  82. set
  83. {
  84. if (_values.Count == 0)
  85. _values.Add(value);
  86. else
  87. _values[0] = value;
  88. }
  89. }
  90. /// <summary>
  91. /// Returns the last value, or null if no value exist.
  92. /// </summary>
  93. public string LastValue
  94. {
  95. get { return _values.Count == 0 ? null : _values[_values.Count - 1]; }
  96. }
  97. /// <summary>
  98. /// Returns the list with values.
  99. /// </summary>
  100. public IList<string> Values
  101. {
  102. get { return _values.AsReadOnly(); }
  103. }
  104. /// <summary>
  105. /// Add another value to this item
  106. /// </summary>
  107. /// <param name="value">Value to add.</param>
  108. /// <exception cref="InvalidOperationException">Cannot add stuff to <see cref="HttpInput.Empty"/>.</exception>
  109. public void Add(string value)
  110. {
  111. if (value == null)
  112. return;
  113. if (_ignoreChanges)
  114. throw new InvalidOperationException("Cannot add stuff to HttpInput.Empty.");
  115. _values.Add(value);
  116. }
  117. /// <summary>
  118. /// checks if a sub-item exists (and has a value).
  119. /// </summary>
  120. /// <param name="name">name in lower case</param>
  121. /// <returns>true if the sub-item exists and has a value; otherwise false.</returns>
  122. public bool Contains(string name)
  123. {
  124. return _items.ContainsKey(name) && _items[name].Value != null;
  125. }
  126. /// <summary> Returns a formatted representation of the instance with the values of all contained parameters </summary>
  127. public override string ToString()
  128. {
  129. return ToString(string.Empty);
  130. }
  131. /// <summary>
  132. /// Outputs the string in a formatted manner
  133. /// </summary>
  134. /// <param name="prefix">A prefix to append, used internally</param>
  135. /// <param name="asQuerySting">produce a query string</param>
  136. public string ToString(string prefix, bool asQuerySting)
  137. {
  138. string name;
  139. if (string.IsNullOrEmpty(prefix))
  140. name = Name;
  141. else
  142. name = prefix + "[" + Name + "]";
  143. if (asQuerySting)
  144. {
  145. string temp;
  146. if (_values.Count == 0 && _items.Count > 0)
  147. temp = string.Empty;
  148. else
  149. temp = name;
  150. if (_values.Count > 0)
  151. {
  152. temp += '=';
  153. foreach (string value in _values)
  154. temp += value + ',';
  155. temp = temp.Remove(temp.Length - 1, 1);
  156. }
  157. foreach (KeyValuePair<string, HttpInputItem> item in _items)
  158. temp += item.Value.ToString(name, true) + '&';
  159. return _items.Count > 0 ? temp.Substring(0, temp.Length - 1) : temp;
  160. }
  161. else
  162. {
  163. string temp = name;
  164. if (_values.Count > 0)
  165. {
  166. temp += " = ";
  167. foreach (string value in _values)
  168. temp += value + ", ";
  169. temp = temp.Remove(temp.Length - 2, 2);
  170. }
  171. temp += Environment.NewLine;
  172. foreach (KeyValuePair<string, HttpInputItem> item in _items)
  173. temp += item.Value.ToString(name, false);
  174. return temp;
  175. }
  176. }
  177. #region IHttpInput Members
  178. /// <summary>
  179. ///
  180. /// </summary>
  181. /// <param name="name">name in lower case</param>
  182. /// <returns></returns>
  183. HttpInputItem IHttpInput.this[string name]
  184. {
  185. get { return _items.ContainsKey(name) ? _items[name] : Empty; }
  186. }
  187. /// <summary>
  188. /// Add a sub item.
  189. /// </summary>
  190. /// <param name="name">Can contain array formatting, the item is then parsed and added in multiple levels</param>
  191. /// <param name="value">Value to add.</param>
  192. /// <exception cref="ArgumentNullException">Argument is null.</exception>
  193. /// <exception cref="InvalidOperationException">Cannot add stuff to <see cref="HttpInput.Empty"/>.</exception>
  194. public void Add(string name, string value)
  195. {
  196. if (name == null && value != null)
  197. throw new ArgumentNullException("name");
  198. if (name == null)
  199. return;
  200. if (_ignoreChanges)
  201. throw new InvalidOperationException("Cannot add stuff to HttpInput.Empty.");
  202. int pos = name.IndexOf('[');
  203. if (pos != -1)
  204. {
  205. string name1 = name.Substring(0, pos);
  206. string name2 = HttpInput.ExtractOne(name);
  207. if (!_items.ContainsKey(name1))
  208. _items.Add(name1, new HttpInputItem(name1, null));
  209. _items[name1].Add(name2, value);
  210. /*
  211. HttpInputItem item = HttpInput.ParseItem(name, value);
  212. // Add the value to an existing sub item
  213. if (_items.ContainsKey(item.Name))
  214. _items[item.Name].Add(item.Value);
  215. else
  216. _items.Add(item.Name, item);
  217. */
  218. }
  219. else
  220. {
  221. if (_items.ContainsKey(name))
  222. _items[name].Add(value);
  223. else
  224. _items.Add(name, new HttpInputItem(name, value));
  225. }
  226. }
  227. #endregion
  228. ///<summary>
  229. ///Returns an enumerator that iterates through the collection.
  230. ///</summary>
  231. ///
  232. ///<returns>
  233. ///A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> that can be used to iterate through the collection.
  234. ///</returns>
  235. ///<filterpriority>1</filterpriority>
  236. IEnumerator<HttpInputItem> IEnumerable<HttpInputItem>.GetEnumerator()
  237. {
  238. return _items.Values.GetEnumerator();
  239. }
  240. #region IEnumerable Members
  241. ///<summary>
  242. ///Returns an enumerator that iterates through a collection.
  243. ///</summary>
  244. ///
  245. ///<returns>
  246. ///An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
  247. ///</returns>
  248. ///<filterpriority>2</filterpriority>
  249. public IEnumerator GetEnumerator()
  250. {
  251. return _items.Values.GetEnumerator();
  252. }
  253. #endregion
  254. /// <summary>
  255. /// Outputs the string in a formatted manner
  256. /// </summary>
  257. /// <param name="prefix">A prefix to append, used internally</param>
  258. /// <returns></returns>
  259. public string ToString(string prefix)
  260. {
  261. return ToString(prefix, false);
  262. }
  263. }
  264. }