Refactored CookieCollection.cs

This commit is contained in:
sta 2014-03-24 21:02:06 +09:00
parent 6eead5d317
commit fefae5b72f
3 changed files with 639 additions and 581 deletions

View File

@ -1,35 +1,43 @@
// #region License
// CookieCollection.cs /*
// Copied from System.Net.CookieCollection.cs * CookieCollection.cs
// *
// Authors: * This code is derived from System.Net.CookieCollection.cs of Mono
// Lawrence Pit (loz@cable.a2000.nl) * (http://www.mono-project.com).
// Gonzalo Paniagua Javier (gonzalo@ximian.com) *
// Sebastien Pouliot (sebastien@ximian.com) * The MIT License
// sta (sta.blockhead@gmail.com) *
// * Copyright (c) 2004,2009 Novell, Inc. (http://www.novell.com)
// Copyright (c) 2004,2009 Novell, Inc (http://www.novell.com) * Copyright (c) 2012-2014 sta.blockhead
// Copyright (c) 2012-2013 sta.blockhead (sta.blockhead@gmail.com) *
// * Permission is hereby granted, free of charge, to any person obtaining a copy
// Permission is hereby granted, free of charge, to any person obtaining * of this software and associated documentation files (the "Software"), to deal
// a copy of this software and associated documentation files (the * in the Software without restriction, including without limitation the rights
// "Software"), to deal in the Software without restriction, including * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// without limitation the rights to use, copy, modify, merge, publish, * copies of the Software, and to permit persons to whom the Software is
// distribute, sublicense, and/or sell copies of the Software, and to * furnished to do so, subject to the following conditions:
// 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 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,
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * THE SOFTWARE.
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION */
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endregion
//
#region Authors
/*
* Authors:
* - Lawrence Pit <loz@cable.a2000.nl>
* - Gonzalo Paniagua Javier <gonzalo@ximian.com>
* - Sebastien Pouliot <sebastien@ximian.com>
*/
#endregion
using System; using System;
using System.Collections; using System.Collections;
@ -39,39 +47,24 @@ using System.Linq;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Text; using System.Text;
namespace WebSocketSharp.Net { namespace WebSocketSharp.Net
{
/// <summary> /// <summary>
/// Provides a collection container for instances of the <see cref="Cookie"/> class. /// Provides a collection container for instances of the <see cref="Cookie"/> class.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class CookieCollection : ICollection, IEnumerable public class CookieCollection : ICollection, IEnumerable
{ {
// not 100% identical to MS implementation
sealed class CookieCollectionComparer : IComparer<Cookie>
{
public int Compare (Cookie x, Cookie y)
{
if (x == null || y == null)
return 0;
int c1 = x.Name.Length + x.Value.Length;
int c2 = y.Name.Length + y.Value.Length;
return (c1 - c2);
}
}
#region Private Static Fields #region Private Static Fields
static CookieCollectionComparer Comparer = new CookieCollectionComparer (); private static CookieCollectionComparer _comparer = new CookieCollectionComparer ();
#endregion #endregion
#region Private Fields #region Private Fields
List<Cookie> list; private List<Cookie> _list;
object sync; private object _sync;
#endregion #endregion
@ -82,7 +75,7 @@ namespace WebSocketSharp.Net {
/// </summary> /// </summary>
public CookieCollection () public CookieCollection ()
{ {
list = new List<Cookie> (); _list = new List<Cookie> ();
} }
#endregion #endregion
@ -90,12 +83,14 @@ namespace WebSocketSharp.Net {
#region Internal Properties #region Internal Properties
internal IList<Cookie> List { internal IList<Cookie> List {
get { return list; } get {
return _list;
}
} }
internal IEnumerable<Cookie> Sorted { internal IEnumerable<Cookie> Sorted {
get { get {
return from cookie in list return from cookie in _list
orderby cookie.Version, orderby cookie.Version,
cookie.Name, cookie.Name,
cookie.Path.Length descending cookie.Path.Length descending
@ -111,68 +106,78 @@ namespace WebSocketSharp.Net {
/// Gets the number of cookies contained in the <see cref="CookieCollection"/>. /// Gets the number of cookies contained in the <see cref="CookieCollection"/>.
/// </summary> /// </summary>
/// <value> /// <value>
/// An <see cref="int"/> that indicates the number of cookies contained in the <see cref="CookieCollection"/>. /// An <see cref="int"/> that represents the number of cookies contained in
/// the <see cref="CookieCollection"/>.
/// </value> /// </value>
public int Count { public int Count {
get { return list.Count; } get {
return _list.Count;
}
} }
// LAMESPEC: So how is one supposed to create a writable CookieCollection
// instance?? We simply ignore this property, as this collection is always
// writable.
//
/// <summary> /// <summary>
/// Gets a value indicating whether the <see cref="CookieCollection"/> is read-only. /// Gets a value indicating whether the <see cref="CookieCollection"/> is read-only.
/// </summary> /// </summary>
/// <value> /// <value>
/// <c>true</c> if the <see cref="CookieCollection"/> is read-only; otherwise, <c>false</c>. /// <c>true</c> if the <see cref="CookieCollection"/> is read-only; otherwise, <c>false</c>.
/// The default is <c>true</c>. /// The default value is <c>true</c>.
/// </value> /// </value>
public bool IsReadOnly { public bool IsReadOnly {
get { return true; } // LAMESPEC: So how is one supposed to create a writable CookieCollection instance?
// We simply ignore this property, as this collection is always writable.
get {
return true;
}
} }
/// <summary> /// <summary>
/// Gets a value indicating whether access to the <see cref="CookieCollection"/> is thread safe. /// Gets a value indicating whether the access to the <see cref="CookieCollection"/> is
/// thread safe.
/// </summary> /// </summary>
/// <value> /// <value>
/// <c>true</c> if access to the <see cref="CookieCollection"/> is thread safe; otherwise, <c>false</c>. /// <c>true</c> if the access to the <see cref="CookieCollection"/> is thread safe;
/// The default is <c>false</c>. /// otherwise, <c>false</c>. The default value is <c>false</c>.
/// </value> /// </value>
public bool IsSynchronized { public bool IsSynchronized {
get { return false; } get {
return false;
}
} }
/// <summary> /// <summary>
/// Gets the <see cref="Cookie"/> with the specified <paramref name="index"/> from the <see cref="CookieCollection"/>. /// Gets the <see cref="Cookie"/> with the specified <paramref name="index"/> from
/// the <see cref="CookieCollection"/>.
/// </summary> /// </summary>
/// <value> /// <value>
/// A <see cref="Cookie"/> with the specified <paramref name="index"/> in the <see cref="CookieCollection"/>. /// A <see cref="Cookie"/> with the specified <paramref name="index"/> in
/// the <see cref="CookieCollection"/>.
/// </value> /// </value>
/// <param name="index"> /// <param name="index">
/// An <see cref="int"/> is the zero-based index of the <see cref="Cookie"/> to find. /// An <see cref="int"/> that represents the zero-based index of the <see cref="Cookie"/>
/// to find.
/// </param> /// </param>
/// <exception cref="ArgumentOutOfRangeException"> /// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="index"/> is less than zero or <paramref name="index"/> is greater than or /// <paramref name="index"/> isn't between zero and <see cref="Count"/>.
/// equal to <see cref="Count"/>.
/// </exception> /// </exception>
public Cookie this [int index] { public Cookie this [int index] {
get { get {
if (index < 0 || index >= list.Count) if (index < 0 || index >= _list.Count)
throw new ArgumentOutOfRangeException ("index"); throw new ArgumentOutOfRangeException ("index");
return list [index]; return _list [index];
} }
} }
/// <summary> /// <summary>
/// Gets the <see cref="Cookie"/> with the specified <paramref name="name"/> from the <see cref="CookieCollection"/>. /// Gets the <see cref="Cookie"/> with the specified <paramref name="name"/> from
/// the <see cref="CookieCollection"/>.
/// </summary> /// </summary>
/// <value> /// <value>
/// A <see cref="Cookie"/> with the specified <paramref name="name"/> in the <see cref="CookieCollection"/>. /// A <see cref="Cookie"/> with the specified <paramref name="name"/> in
/// the <see cref="CookieCollection"/>.
/// </value> /// </value>
/// <param name="name"> /// <param name="name">
/// A <see cref="string"/> is the name of the <see cref="Cookie"/> to find. /// A <see cref="string"/> that represents the name of the <see cref="Cookie"/> to find.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> /// <exception cref="ArgumentNullException">
/// <paramref name="name"/> is <see langword="null"/>. /// <paramref name="name"/> is <see langword="null"/>.
@ -182,10 +187,9 @@ namespace WebSocketSharp.Net {
if (name == null) if (name == null)
throw new ArgumentNullException ("name"); throw new ArgumentNullException ("name");
foreach (var cookie in Sorted) { foreach (var cookie in Sorted)
if (cookie.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase)) if (cookie.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase))
return cookie; return cookie;
}
return null; return null;
} }
@ -199,10 +203,7 @@ namespace WebSocketSharp.Net {
/// </value> /// </value>
public Object SyncRoot { public Object SyncRoot {
get { get {
if (sync == null) return _sync ?? (_sync = new object ());
sync = new object ();
return sync;
} }
} }
@ -210,15 +211,15 @@ namespace WebSocketSharp.Net {
#region Private Methods #region Private Methods
static CookieCollection ParseRequest (string value) private static CookieCollection parseRequest (string value)
{ {
var cookies = new CookieCollection (); var cookies = new CookieCollection ();
Cookie cookie = null; Cookie cookie = null;
int version = 0; var version = 0;
string [] pairs = Split(value).ToArray(); var pairs = split (value).ToArray ();
for (int i = 0; i < pairs.Length; i++) { for (int i = 0; i < pairs.Length; i++) {
string pair = pairs [i].Trim (); var pair = pairs [i].Trim ();
if (pair.Length == 0) if (pair.Length == 0)
continue; continue;
@ -247,7 +248,8 @@ namespace WebSocketSharp.Net {
string name; string name;
string val = String.Empty; string val = String.Empty;
int pos = pair.IndexOf ('=');
var pos = pair.IndexOf ('=');
if (pos == -1) { if (pos == -1) {
name = pair; name = pair;
} }
@ -271,14 +273,14 @@ namespace WebSocketSharp.Net {
return cookies; return cookies;
} }
static CookieCollection ParseResponse (string value) private static CookieCollection parseResponse (string value)
{ {
var cookies = new CookieCollection (); var cookies = new CookieCollection ();
Cookie cookie = null; Cookie cookie = null;
string [] pairs = Split(value).ToArray(); var pairs = split (value).ToArray ();
for (int i = 0; i < pairs.Length; i++) { for (int i = 0; i < pairs.Length; i++) {
string pair = pairs [i].Trim (); var pair = pairs [i].Trim ();
if (pair.Length == 0) if (pair.Length == 0)
continue; continue;
@ -292,9 +294,10 @@ namespace WebSocketSharp.Net {
buffer.AppendFormat (", {0}", pairs [++i].Trim ()); buffer.AppendFormat (", {0}", pairs [++i].Trim ());
DateTime expires; DateTime expires;
if (!DateTime.TryParseExact (buffer.ToString (), if (!DateTime.TryParseExact (
new string [] { "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", "r" }, buffer.ToString (),
CultureInfo.CreateSpecificCulture("en-US"), new [] { "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", "r" },
CultureInfo.CreateSpecificCulture ("en-US"),
DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal,
out expires)) out expires))
expires = DateTime.Now; expires = DateTime.Now;
@ -303,7 +306,7 @@ namespace WebSocketSharp.Net {
cookie.Expires = expires.ToLocalTime (); cookie.Expires = expires.ToLocalTime ();
} }
else if (pair.StartsWith ("max-age", StringComparison.InvariantCultureIgnoreCase)) { else if (pair.StartsWith ("max-age", StringComparison.InvariantCultureIgnoreCase)) {
int max = Int32.Parse (pair.GetValueInternal ("=").Trim ('"')); var max = Int32.Parse (pair.GetValueInternal ("=").Trim ('"'));
var expires = DateTime.Now.AddSeconds ((double) max); var expires = DateTime.Now.AddSeconds ((double) max);
if (cookie != null) if (cookie != null)
cookie.Expires = expires; cookie.Expires = expires;
@ -350,7 +353,8 @@ namespace WebSocketSharp.Net {
string name; string name;
string val = String.Empty; string val = String.Empty;
int pos = pair.IndexOf ('=');
var pos = pair.IndexOf ('=');
if (pos == -1) { if (pos == -1) {
name = pair; name = pair;
} }
@ -372,34 +376,25 @@ namespace WebSocketSharp.Net {
return cookies; return cookies;
} }
int SearchCookie (Cookie cookie) private int searchCookie (Cookie cookie)
{ {
string name = cookie.Name; var name = cookie.Name;
string path = cookie.Path; var path = cookie.Path;
string domain = cookie.Domain; var domain = cookie.Domain;
int version = cookie.Version; var version = cookie.Version;
for (int i = _list.Count - 1; i >= 0; i--) {
for (int i = list.Count - 1; i >= 0; i--) { var c = _list [i];
Cookie c = list [i]; if (c.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase) &&
if (!c.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase)) c.Path.Equals (path, StringComparison.InvariantCulture) &&
continue; c.Domain.Equals (domain, StringComparison.InvariantCultureIgnoreCase) &&
c.Version == version)
if (!c.Path.Equals (path, StringComparison.InvariantCulture))
continue;
if (!c.Domain.Equals (domain, StringComparison.InvariantCultureIgnoreCase))
continue;
if (c.Version != version)
continue;
return i; return i;
} }
return -1; return -1;
} }
static IEnumerable<string> Split (string value) private static IEnumerable<string> split (string value)
{ {
return value.SplitHeaderValue (',', ';'); return value.SplitHeaderValue (',', ';');
} }
@ -411,23 +406,26 @@ namespace WebSocketSharp.Net {
internal static CookieCollection Parse (string value, bool response) internal static CookieCollection Parse (string value, bool response)
{ {
return response return response
? ParseResponse (value) ? parseResponse (value)
: ParseRequest (value); : parseRequest (value);
} }
internal void SetOrRemove (Cookie cookie) internal void SetOrRemove (Cookie cookie)
{ {
int pos = SearchCookie (cookie); var pos = searchCookie (cookie);
if (pos == -1) { if (pos == -1) {
if (!cookie.Expired) if (!cookie.Expired)
list.Add (cookie); _list.Add (cookie);
return;
} }
else {
if (!cookie.Expired) if (!cookie.Expired) {
list [pos] = cookie; _list [pos] = cookie;
else return;
list.RemoveAt (pos);
} }
_list.RemoveAt (pos);
} }
internal void SetOrRemove (CookieCollection cookies) internal void SetOrRemove (CookieCollection cookies)
@ -438,8 +436,8 @@ namespace WebSocketSharp.Net {
internal void Sort () internal void Sort ()
{ {
if (list.Count > 0) if (_list.Count > 0)
list.Sort (Comparer); _list.Sort (_comparer);
} }
#endregion #endregion
@ -460,15 +458,18 @@ namespace WebSocketSharp.Net {
if (cookie == null) if (cookie == null)
throw new ArgumentNullException ("cookie"); throw new ArgumentNullException ("cookie");
int pos = SearchCookie (cookie); var pos = searchCookie (cookie);
if (pos == -1) if (pos == -1) {
list.Add (cookie); _list.Add (cookie);
else return;
list [pos] = cookie; }
_list [pos] = cookie;
} }
/// <summary> /// <summary>
/// Add the elements of the specified <see cref="CookieCollection"/> to the current <see cref="CookieCollection"/>. /// Add the elements of the specified <see cref="CookieCollection"/> to the current
/// <see cref="CookieCollection"/>.
/// </summary> /// </summary>
/// <param name="cookies"> /// <param name="cookies">
/// A <see cref="CookieCollection"/> to add to the current <see cref="CookieCollection"/>. /// A <see cref="CookieCollection"/> to add to the current <see cref="CookieCollection"/>.
@ -486,14 +487,17 @@ namespace WebSocketSharp.Net {
} }
/// <summary> /// <summary>
/// Copies the elements of the <see cref="CookieCollection"/> to the specified <see cref="Array"/>, /// Copies the elements of the <see cref="CookieCollection"/> to the specified
/// starting at the specified <paramref name="index"/> in the <paramref name="array"/>. /// <see cref="Array"/>, starting at the specified <paramref name="index"/> in
/// the <paramref name="array"/>.
/// </summary> /// </summary>
/// <param name="array"> /// <param name="array">
/// An <see cref="Array"/> is the destination of the elements copied from the <see cref="CookieCollection"/>. /// An <see cref="Array"/> is the destination of the elements copied from
/// the <see cref="CookieCollection"/>.
/// </param> /// </param>
/// <param name="index"> /// <param name="index">
/// An <see cref="int"/> that indicates the zero-based index in <paramref name="array"/> at which copying begins. /// An <see cref="int"/> that represents the zero-based index in <paramref name="array"/>
/// at which copying begins.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> /// <exception cref="ArgumentNullException">
/// <paramref name="array"/> is <see langword="null"/>. /// <paramref name="array"/> is <see langword="null"/>.
@ -509,13 +513,13 @@ namespace WebSocketSharp.Net {
/// -or- /// -or-
/// </para> /// </para>
/// <para> /// <para>
/// The number of elements in the <see cref="CookieCollection"/> is greater than the available space /// The number of elements in the <see cref="CookieCollection"/> is greater than the available
/// from index to the end of the destination <paramref name="array"/>. /// space from index to the end of the destination <paramref name="array"/>.
/// </para> /// </para>
/// </exception> /// </exception>
/// <exception cref="InvalidCastException"> /// <exception cref="InvalidCastException">
/// The elements in the <see cref="CookieCollection"/> cannot be cast automatically /// The elements in the <see cref="CookieCollection"/> cannot be cast automatically to the type
/// to the type of the destination <paramref name="array"/>. /// of the destination <paramref name="array"/>.
/// </exception> /// </exception>
public void CopyTo (Array array, int index) public void CopyTo (Array array, int index)
{ {
@ -528,7 +532,7 @@ namespace WebSocketSharp.Net {
if (array.Rank > 1) if (array.Rank > 1)
throw new ArgumentException ("Must not be multidimensional.", "array"); throw new ArgumentException ("Must not be multidimensional.", "array");
if (array.Length - index < list.Count) if (array.Length - index < _list.Count)
throw new ArgumentException ( throw new ArgumentException (
"The number of elements in this collection is greater than the available space of the destination array."); "The number of elements in this collection is greater than the available space of the destination array.");
@ -536,18 +540,21 @@ namespace WebSocketSharp.Net {
throw new InvalidCastException ( throw new InvalidCastException (
"The elements in this collection cannot be cast automatically to the type of the destination array."); "The elements in this collection cannot be cast automatically to the type of the destination array.");
(list as IList).CopyTo (array, index); (_list as IList).CopyTo (array, index);
} }
/// <summary> /// <summary>
/// Copies the elements of the <see cref="CookieCollection"/> to the specified array of <see cref="Cookie"/>, /// Copies the elements of the <see cref="CookieCollection"/> to the specified array of
/// starting at the specified <paramref name="index"/> in the <paramref name="array"/>. /// <see cref="Cookie"/>, starting at the specified <paramref name="index"/> in the
/// <paramref name="array"/>.
/// </summary> /// </summary>
/// <param name="array"> /// <param name="array">
/// An array of <see cref="Cookie"/> is the destination of the elements copied from the <see cref="CookieCollection"/>. /// An array of <see cref="Cookie"/> is the destination of the elements copied from the
/// <see cref="CookieCollection"/>.
/// </param> /// </param>
/// <param name="index"> /// <param name="index">
/// An <see cref="int"/> that indicates the zero-based index in <paramref name="array"/> at which copying begins. /// An <see cref="int"/> that represents the zero-based index in <paramref name="array"/>
/// at which copying begins.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> /// <exception cref="ArgumentNullException">
/// <paramref name="array"/> is <see langword="null"/>. /// <paramref name="array"/> is <see langword="null"/>.
@ -556,8 +563,8 @@ namespace WebSocketSharp.Net {
/// <paramref name="index"/> is less than zero. /// <paramref name="index"/> is less than zero.
/// </exception> /// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// The number of elements in the <see cref="CookieCollection"/> is greater than the available space /// The number of elements in the <see cref="CookieCollection"/> is greater than the available
/// from index to the end of the destination <paramref name="array"/>. /// space from index to the end of the destination <paramref name="array"/>.
/// </exception> /// </exception>
public void CopyTo (Cookie [] array, int index) public void CopyTo (Cookie [] array, int index)
{ {
@ -567,23 +574,23 @@ namespace WebSocketSharp.Net {
if (index < 0) if (index < 0)
throw new ArgumentOutOfRangeException ("index", "Must not be less than zero."); throw new ArgumentOutOfRangeException ("index", "Must not be less than zero.");
if (array.Length - index < list.Count) if (array.Length - index < _list.Count)
throw new ArgumentException ( throw new ArgumentException (
"The number of elements in this collection is greater than the available space of the destination array."); "The number of elements in this collection is greater than the available space of the destination array.");
list.CopyTo (array, index); _list.CopyTo (array, index);
} }
/// <summary> /// <summary>
/// Gets the enumerator to use to iterate through the <see cref="CookieCollection"/>. /// Gets the enumerator to use to iterate through the <see cref="CookieCollection"/>.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// An instance of an implementation of the <see cref="IEnumerator"/> interface /// A <see cref="IEnumerator"/> instance to use to iterate through
/// to use to iterate through the <see cref="CookieCollection"/>. /// the <see cref="CookieCollection"/>.
/// </returns> /// </returns>
public IEnumerator GetEnumerator () public IEnumerator GetEnumerator ()
{ {
return list.GetEnumerator (); return _list.GetEnumerator ();
} }
#endregion #endregion

View File

@ -0,0 +1,50 @@
#region License
/*
* CookieCollectionComparer.cs
*
* This code is a separation from CookieCollection.cs.
*
* The MIT License
*
* Copyright (c) 2004,2009 Novell, Inc. (http://www.novell.com)
* Copyright (c) 2014 sta.blockhead
*
* 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.
*/
#endregion
using System;
using System.Collections.Generic;
namespace WebSocketSharp.Net
{
internal sealed class CookieCollectionComparer : IComparer<Cookie>
{
public int Compare (Cookie x, Cookie y)
{
if (x == null || y == null)
return 0;
var c1 = x.Name.Length + x.Value.Length;
var c2 = y.Name.Length + y.Value.Length;
return c1 - c2;
}
}
}

View File

@ -130,6 +130,7 @@
<Compile Include="Net\HttpDigestIdentity.cs" /> <Compile Include="Net\HttpDigestIdentity.cs" />
<Compile Include="Net\NetworkCredential.cs" /> <Compile Include="Net\NetworkCredential.cs" />
<Compile Include="Server\WebSocketServiceManager.cs" /> <Compile Include="Server\WebSocketServiceManager.cs" />
<Compile Include="Net\CookieCollectionComparer.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>