using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BestHTTP.Extensions { /// /// Used in string parsers. Its Value is optional. /// public sealed class HeaderValue { #region Public Properties public string Key { get; set; } public string Value { get; set; } public List Options { get; set; } public bool HasValue { get { return !string.IsNullOrEmpty(this.Value); } } #endregion #region Constructors public HeaderValue() { } public HeaderValue(string key) { this.Key = key; } #endregion #region Public Helper Functions public void Parse(string headerStr, ref int pos) { ParseImplementation(headerStr, ref pos, true); } public bool TryGetOption(string key, out HeaderValue option) { option = null; if (Options == null || Options.Count == 0) return false; for (int i = 0; i < Options.Count; ++i) if (String.Equals(Options[i].Key, key, StringComparison.OrdinalIgnoreCase)) { option = Options[i]; return true; } return false; } #endregion #region Private Helper Functions private void ParseImplementation(string headerStr, ref int pos, bool isOptionIsAnOption) { string key = headerStr.Read(ref pos, (ch) => ch != ';' && ch != '=' && ch != ',', true); this.Key = key; char? skippedChar = headerStr.Peek(pos - 1); bool isValue = skippedChar == '='; bool isOption = isOptionIsAnOption && skippedChar == ';'; while (skippedChar != null && isValue || isOption) { if (isValue) { string value = headerStr.ReadPossibleQuotedText(ref pos); this.Value = value; } else if (isOption) { HeaderValue option = new HeaderValue(); option.ParseImplementation(headerStr, ref pos, false); if (this.Options == null) this.Options = new List(); this.Options.Add(option); } if (!isOptionIsAnOption) return; skippedChar = headerStr.Peek(pos - 1); isValue = skippedChar == '='; isOption = isOptionIsAnOption && skippedChar == ';'; } } #endregion #region Overrides public override string ToString() { if (!string.IsNullOrEmpty(Value)) return String.Concat(Key, '=', Value); else return Key; } #endregion } }