using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace Apewer.Network
{
/// HTTP 头的集合。
[Serializable]
public sealed class HttpHeaders : IEnumerable, ICollection, IToJson
{
#region IEnumerable
List _list = new List();
long _version = 0L;
/// 获取枚举器。
public IEnumerator GetEnumerator() => new Enumerator(this);
/// 获取枚举器。
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(this);
///
public sealed class Enumerator : IEnumerator
{
HttpHeaders _headeres = null;
long _version = 0L;
bool _disposed = false;
HttpHeader _current = null;
int _index = 0;
const string ObjectName = nameof(Enumerator);
const string OriginChanged = "原集合已变更,无法继续遍历。";
///
public HttpHeader Current
{
get
{
if (_disposed) throw new ObjectDisposedException(ObjectName);
if (_version != _headeres._version) throw new InvalidOperationException(OriginChanged);
return _current;
}
}
///
object IEnumerator.Current { get => Current; }
///
public void Dispose() { _disposed = true; }
///
public bool MoveNext()
{
if (_disposed) throw new ObjectDisposedException(ObjectName);
if (_version != _headeres._version) throw new InvalidOperationException(OriginChanged);
if (_index < _headeres._list.Count)
{
_current = _headeres._list[_index];
_index++;
return true;
}
return false;
}
///
public void Reset()
{
_current = null;
_index = 0;
}
///
public Enumerator(HttpHeaders headers)
{
if (headers == null) throw new ArgumentNullException(nameof(headers));
_headeres = headers;
_version = headers._version;
Reset();
}
}
#endregion
#region ICollection
/// 元素数量。
public int Count { get => _list.Count; }
/// 当前集合是只读。
public bool IsReadOnly { get => false; }
/// 添加一项。
///
public HttpHeader Add(string name, string value)
{
if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
var header = new HttpHeader(name, value);
_list.Add(header);
_version++;
return header;
}
/// 添加一项。
///
public void Add(HttpHeader header)
{
if (header == null) throw new ArgumentNullException(nameof(header));
_list.Add(header);
_version++;
}
/// 移除所有元素。
public void Clear() => _list.Clear();
/// 判断是否包含指定的元素。
public bool Contains(HttpHeader item) => _list.Contains(item);
/// 复制所有元素到数组。
/// 目标数组。
/// 数组的位置。
///
///
///
public void CopyTo(HttpHeader[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
/// 移除指定的元素
public bool Remove(HttpHeader item) => _list.Remove(item);
#endregion
#region IList
///
///
public HttpHeader this[int index] { get => _list[index]; set => _list[index] = value; }
///
///
public string this[string name] { get => GetValue(name); set => SetValue(name, value); }
/// 搜索指定对象在当前集合中的位置索引。
public int IndexOf(HttpHeader item) => _list.IndexOf(item);
/// 插入元素到指定位置。
///
public void Insert(int index, HttpHeader item) => _list.Insert(index, item);
/// 移除指定位置的元素。
///
public void RemoveAt(int index) => _list.RemoveAt(index);
#endregion
#region constructor
///
public HttpHeaders() { }
///
///
public HttpHeaders(params HttpHeader[] headers) : this(headers as IEnumerable) { }
///
///
public HttpHeaders(IEnumerable headers)
{
if (headers == null) throw new ArgumentNullException(nameof(headers));
foreach (var header in headers)
{
if (header == null) continue;
if (header.Name.IsEmpty()) continue;
Add(header);
}
}
///
///
public HttpHeaders(IEnumerable> headers)
{
if (headers == null) return;
foreach (var header in headers)
{
if (header.Key.IsEmpty()) continue;
Add(header.Key, header.Value);
}
}
///
///
public HttpHeaders(NameValueCollection headers)
{
if (headers == null) return;
var keys = headers.AllKeys;
foreach (var key in keys)
{
if (key.IsEmpty()) continue;
var value = headers[key];
Add(key, value);
}
}
#endregion
#region operation
/// 获取所有名称。
public string[] GetNames()
{
var names = new List();
var count = _list.Count;
for (var i = 0; i < count; i++)
{
var name = _list[i].Name;
if (string.IsNullOrEmpty(name)) continue;
if (names.Contains(name)) continue;
names.Add(name);
}
names.Sort();
return names.ToArray();
}
/// 获取匹配 Name 的 Value。不存在 Name 时返回 NULL 值。
///
public string GetValue(string name)
{
if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
// 精准匹配。
var count = _list.Count;
for (var i = 0; i < count; i++)
{
var item = _list[i];
if (string.IsNullOrEmpty(item.Name)) continue;
if (item.Name == name)
{
if (string.IsNullOrEmpty(item.Value)) continue;
return item.Value;
}
}
// 忽略大小写。
var lower = TextUtility.Lower(name);
for (var i = 0; i < count; i++)
{
var item = _list[i];
if (string.IsNullOrEmpty(item.Name)) continue;
if (TextUtility.Lower(item.Name) == lower)
{
if (string.IsNullOrEmpty(item.Value)) continue;
return item.Value;
}
}
return null;
}
/// 获取匹配 Name 的 Value。不存在 Name 时返回 NULL 值。
///
public string[] GetValues(string name)
{
if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
// 忽略大小写。
// name = TextUtility.Lower(name);
var count = _list.Count;
var values = new List(_list.Count);
for (var i = 0; i < count; i++)
{
var item = _list[i];
if (string.IsNullOrEmpty(item.Name)) continue;
if (string.Equals(item.Name, name, StringComparison.CurrentCultureIgnoreCase))
{
var value = item.Value.ToTrim();
if (string.IsNullOrEmpty(value)) continue;
values.Add(value);
}
}
return values.ToArray();
}
/// 设置 Name 的 Value。不存在 Name 时添加新元素。
///
public HttpHeader SetValue(string name, string value)
{
if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
// 尝试精准匹配。
var count = _list.Count;
for (var i = 0; i < count; i++)
{
var item = _list[i];
if (string.IsNullOrEmpty(item.Name)) continue;
if (item.Name == name)
{
item.Value = value;
_version++;
return item;
}
}
// 尝试模糊匹配。
var lower = TextUtility.Lower(name);
for (var i = 0; i < count; i++)
{
var item = _list[i];
if (TextUtility.Lower(item.Name) == lower)
{
item.Value = value;
_version++;
return item;
}
}
// 添加新项。
return Add(name, value);
}
/// 每个元素组成为新数组。
public HttpHeader[] ToArray() => _list.ToArray();
#endregion
#region Json
internal HttpHeaders(Json json)
{
if (!json) return;
if (json.IsObject)
{
var properties = json.GetProperties();
foreach (var property in properties)
{
if (property == null) continue;
if (property.Name.IsEmpty()) continue;
Add(property.Name, property.Value?.ToString());
}
}
if (json.IsArray)
{
var array = json.Array();
if (array != null)
{
for (var i = 0; i < array.Length; i++)
{
if (array[i] == null) continue;
if (array[i].Name.IsEmpty()) continue;
_list.Add(array[i]);
}
}
}
}
///
public Json ToJson()
{
var array = Json.NewArray();
var count = 0;
for (var i = 0; i < count; i++)
{
var item = Json.From(_list[i]);
array.AddItem(item);
}
return array;
}
#endregion
}
}