123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- namespace OSHttpServer
- {
- /// <summary>
- /// represents a HTTP input item. Each item can have multiple sub items, a sub item
- /// is made in a HTML form by using square brackets
- /// </summary>
- /// <example>
- /// // <input type="text" name="user[FirstName]" value="jonas" /> becomes:
- /// Console.WriteLine("Value: {0}", form["user"]["FirstName"].Value);
- /// </example>
- /// <remarks>
- /// All names in a form SHOULD be in lowercase.
- /// </remarks>
- public class HttpInputItem : IHttpInput
- {
- /// <summary> Representation of a non-initialized <see cref="HttpInputItem"/>.</summary>
- public static readonly HttpInputItem Empty = new HttpInputItem(string.Empty, true);
- private readonly IDictionary<string, HttpInputItem> _items = new Dictionary<string, HttpInputItem>();
- private readonly List<string> _values = new List<string>();
- private string _name;
- private readonly bool _ignoreChanges;
-
- /// <summary>
- /// Initializes an input item setting its name/identifier and value
- /// </summary>
- /// <param name="name">Parameter name/id</param>
- /// <param name="value">Parameter value</param>
- public HttpInputItem(string name, string value)
- {
- Name = name;
- Add(value);
- }
- private HttpInputItem(string name, bool ignore)
- {
- Name = name;
- _ignoreChanges = ignore;
- }
- /// <summary>Creates a deep copy of the item specified</summary>
- /// <param name="item">The item to copy</param>
- /// <remarks>The function makes a deep copy of quite a lot which can be slow</remarks>
- public HttpInputItem(HttpInputItem item)
- {
- foreach (KeyValuePair<string, HttpInputItem> pair in item._items)
- _items.Add(pair.Key, pair.Value);
-
- foreach (string value in item._values)
- _values.Add(value);
-
- _ignoreChanges = item._ignoreChanges;
- _name = item.Name;
- }
- /// <summary>
- /// Number of values
- /// </summary>
- public int Count
- {
- get { return _values.Count; }
- }
- /// <summary>
- /// Get a sub item
- /// </summary>
- /// <param name="name">name in lower case.</param>
- /// <returns><see cref="HttpInputItem.Empty"/> if no item was found.</returns>
- public HttpInputItem this[string name]
- {
- get {
- return _items.ContainsKey(name) ? _items[name] : Empty;
- }
- }
- /// <summary>
- /// Name of item (in lower case).
- /// </summary>
- public string Name
- {
- get { return _name; }
- set { _name = value; }
- }
- /// <summary>
- /// Returns the first value, or null if no value exist.
- /// </summary>
- public string Value
- {
- get {
- return _values.Count == 0 ? null : _values[0];
- }
- set
- {
- if (_values.Count == 0)
- _values.Add(value);
- else
- _values[0] = value;
- }
- }
- /// <summary>
- /// Returns the last value, or null if no value exist.
- /// </summary>
- public string LastValue
- {
- get
- {
- return _values.Count == 0 ? null : _values[_values.Count - 1];
- }
- }
- /// <summary>
- /// Returns the list with values.
- /// </summary>
- public IList<string> Values
- {
- get { return _values.AsReadOnly(); }
- }
- /// <summary>
- /// Add another value to this item
- /// </summary>
- /// <param name="value">Value to add.</param>
- /// <exception cref="InvalidOperationException">Cannot add stuff to <see cref="HttpInput.Empty"/>.</exception>
- public void Add(string value)
- {
- if (value == null)
- return;
- if (_ignoreChanges)
- throw new InvalidOperationException("Cannot add stuff to HttpInput.Empty.");
- _values.Add(value);
- }
- /// <summary>
- /// checks if a sub-item exists (and has a value).
- /// </summary>
- /// <param name="name">name in lower case</param>
- /// <returns>true if the sub-item exists and has a value; otherwise false.</returns>
- public bool Contains(string name)
- {
- return _items.ContainsKey(name) && _items[name].Value != null;
- }
- /// <summary> Returns a formatted representation of the instance with the values of all contained parameters </summary>
- public override string ToString()
- {
- return ToString(string.Empty);
- }
- /// <summary>
- /// Outputs the string in a formatted manner
- /// </summary>
- /// <param name="prefix">A prefix to append, used internally</param>
- /// <param name="asQuerySting">produce a query string</param>
- public string ToString(string prefix, bool asQuerySting)
- {
- string name;
- if (string.IsNullOrEmpty(prefix))
- name = Name;
- else
- name = prefix + "[" + Name + "]";
- if (asQuerySting)
- {
- string temp;
- if (_values.Count == 0 && _items.Count > 0)
- temp = string.Empty;
- else
- temp = name;
- if (_values.Count > 0)
- {
- temp += '=';
- foreach (string value in _values)
- temp += value + ',';
- temp = temp.Remove(temp.Length - 1, 1);
- }
- foreach (KeyValuePair<string, HttpInputItem> item in _items)
- temp += item.Value.ToString(name, true) + '&';
- return _items.Count > 0 ? temp.Substring(0, temp.Length - 1) : temp;
- }
- else
- {
- string temp = name;
- if (_values.Count > 0)
- {
- temp += " = ";
- foreach (string value in _values)
- temp += value + ", ";
- temp = temp.Remove(temp.Length - 2, 2);
- }
- temp += Environment.NewLine;
- foreach (KeyValuePair<string, HttpInputItem> item in _items)
- temp += item.Value.ToString(name, false);
- return temp;
- }
- }
- #region IHttpInput Members
- /// <summary>
- ///
- /// </summary>
- /// <param name="name">name in lower case</param>
- /// <returns></returns>
- HttpInputItem IHttpInput.this[string name]
- {
- get
- {
- return _items.ContainsKey(name) ? _items[name] : Empty;
- }
- }
- /// <summary>
- /// Add a sub item.
- /// </summary>
- /// <param name="name">Can contain array formatting, the item is then parsed and added in multiple levels</param>
- /// <param name="value">Value to add.</param>
- /// <exception cref="ArgumentNullException">Argument is null.</exception>
- /// <exception cref="InvalidOperationException">Cannot add stuff to <see cref="HttpInput.Empty"/>.</exception>
- public void Add(string name, string value)
- {
- if (name == null && value != null)
- throw new ArgumentNullException("name");
- if (name == null)
- return;
- if (_ignoreChanges)
- throw new InvalidOperationException("Cannot add stuff to HttpInput.Empty.");
- int pos = name.IndexOf('[');
- if (pos != -1)
- {
- string name1 = name.Substring(0, pos);
- string name2 = HttpInput.ExtractOne(name);
- if (!_items.ContainsKey(name1))
- _items.Add(name1, new HttpInputItem(name1, null));
- _items[name1].Add(name2, value);
- /*
- HttpInputItem item = HttpInput.ParseItem(name, value);
- // Add the value to an existing sub item
- if (_items.ContainsKey(item.Name))
- _items[item.Name].Add(item.Value);
- else
- _items.Add(item.Name, item);
- */
- }
- else
- {
- if (_items.ContainsKey(name))
- _items[name].Add(value);
- else
- _items.Add(name, new HttpInputItem(name, value));
- }
- }
- #endregion
- ///<summary>
- ///Returns an enumerator that iterates through the collection.
- ///</summary>
- ///
- ///<returns>
- ///A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> that can be used to iterate through the collection.
- ///</returns>
- ///<filterpriority>1</filterpriority>
- IEnumerator<HttpInputItem> IEnumerable<HttpInputItem>.GetEnumerator()
- {
- return _items.Values.GetEnumerator();
- }
- #region IEnumerable Members
- ///<summary>
- ///Returns an enumerator that iterates through a collection.
- ///</summary>
- ///
- ///<returns>
- ///An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
- ///</returns>
- ///<filterpriority>2</filterpriority>
- public IEnumerator GetEnumerator()
- {
- return _items.Values.GetEnumerator();
- }
- #endregion
- /// <summary>
- /// Outputs the string in a formatted manner
- /// </summary>
- /// <param name="prefix">A prefix to append, used internally</param>
- /// <returns></returns>
- public string ToString(string prefix)
- {
- return ToString(prefix, false);
- }
- }
- }
|