// // HeaderInfo.cs // // Authors: // Marek Safar // // Copyright (C) 2011, 2014 Xamarin Inc (http://www.xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System.Diagnostics; using System.Collections.Generic; namespace System.Net.Http.Headers { delegate bool TryParseDelegate (string value, out T result); delegate bool TryParseListDelegate (string value, int minimalCount, out List result); abstract class HeaderInfo { class HeaderTypeInfo : HeaderInfo where U : class { readonly TryParseDelegate parser; public HeaderTypeInfo (string name, TryParseDelegate parser, HttpHeaderKind headerKind) : base (name, headerKind) { this.parser = parser; } public override void AddToCollection (object collection, object value) { Debug.Assert (AllowsMany); var c = (HttpHeaderValueCollection) collection; var list = value as List; if (list != null) c.AddRange (list); else c.Add ((U) value); } protected override object CreateCollection (HttpHeaders headers, HeaderInfo headerInfo) { return new HttpHeaderValueCollection (headers, headerInfo); } public override List ToStringCollection (object collection) { if (collection == null) return null; var c = (HttpHeaderValueCollection) collection; if (c.Count == 0) return null; var list = new List (); foreach (var item in c) { list.Add (item.ToString ()); } return list; } public override bool TryParse (string value, out object result) { T tresult; bool b = parser (value, out tresult); result = tresult; return b; } } class CollectionHeaderTypeInfo : HeaderTypeInfo where U : class { readonly int minimalCount; TryParseListDelegate parser; public CollectionHeaderTypeInfo (string name, TryParseListDelegate parser, HttpHeaderKind headerKind, int minimalCount) : base (name, null, headerKind) { this.parser = parser; this.minimalCount = minimalCount; AllowsMany = true; } public override bool TryParse (string value, out object result) { List tresult; if (!parser (value, minimalCount, out tresult)) { result = null; return false; } result = tresult; return true; } } public bool AllowsMany; public readonly HttpHeaderKind HeaderKind; public readonly string Name; protected HeaderInfo (string name, HttpHeaderKind headerKind) { this.Name = name; this.HeaderKind = headerKind; } public static HeaderInfo CreateSingle (string name, TryParseDelegate parser, HttpHeaderKind headerKind) { return new HeaderTypeInfo (name, parser, headerKind); } // // Headers with #rule for defining lists of elements or *rule for defining occurences of elements // public static HeaderInfo CreateMulti (string name, TryParseListDelegate elementParser, HttpHeaderKind headerKind, int minimalCount = 1) where T : class { return new CollectionHeaderTypeInfo (name, elementParser, headerKind, minimalCount); } public object CreateCollection (HttpHeaders headers) { return CreateCollection (headers, this); } public abstract void AddToCollection (object collection, object value); protected abstract object CreateCollection (HttpHeaders headers, HeaderInfo headerInfo); public abstract List ToStringCollection (object collection); public abstract bool TryParse (string value, out object result); } }