2 // MediaTypeHeaderValue.cs
5 // Marek Safar <marek.safar@gmail.com>
7 // Copyright (C) 2011 Xamarin Inc (http://www.xamarin.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System
.Collections
.Generic
;
31 namespace System
.Net
.Http
.Headers
33 public class MediaTypeHeaderValue
: ICloneable
35 internal List
<NameValueHeaderValue
> parameters
;
36 internal string media_type
;
38 public MediaTypeHeaderValue (string mediaType
)
40 MediaType
= mediaType
;
43 protected MediaTypeHeaderValue (MediaTypeHeaderValue source
)
46 throw new ArgumentNullException ("source");
48 media_type
= source
.media_type
;
49 if (source
.parameters
!= null) {
50 foreach (var item
in source
.parameters
)
51 Parameters
.Add (new NameValueHeaderValue (item
));
55 internal MediaTypeHeaderValue ()
59 public string CharSet
{
61 if (parameters
== null)
64 var found
= parameters
.Find (l
=> string.Equals (l
.Name
, "charset", StringComparison
.OrdinalIgnoreCase
));
72 if (parameters
== null)
73 parameters
= new List
<NameValueHeaderValue
> ();
75 parameters
.SetValue ("charset", value);
79 public string MediaType
{
85 throw new ArgumentNullException ("MediaType");
88 var token
= TryParseMediaType (new Lexer (value), out temp
);
89 if (token
== null || token
.Value
.Kind
!= Token
.Type
.End
)
90 throw new FormatException ();
96 public ICollection
<NameValueHeaderValue
> Parameters
{
98 return parameters
?? (parameters
= new List
<NameValueHeaderValue
> ());
102 object ICloneable
.Clone ()
104 return new MediaTypeHeaderValue (this);
107 public override bool Equals (object obj
)
109 var source
= obj
as MediaTypeHeaderValue
;
113 return string.Equals (source
.media_type
, media_type
, StringComparison
.OrdinalIgnoreCase
) &&
114 source
.parameters
.SequenceEqual (parameters
);
117 public override int GetHashCode ()
119 return media_type
.ToLowerInvariant ().GetHashCode () ^ HashCodeCalculator
.Calculate (parameters
);
122 public static MediaTypeHeaderValue
Parse (string input
)
124 MediaTypeHeaderValue
value;
125 if (TryParse (input
, out value))
128 throw new FormatException (input
);
131 public override string ToString ()
133 if (parameters
== null)
136 return media_type
+ CollectionExtensions
.ToString (parameters
);
139 public static bool TryParse (string input
, out MediaTypeHeaderValue parsedValue
)
143 var lexer
= new Lexer (input
);
146 List
<NameValueHeaderValue
> parameters
= null;
147 var token
= TryParseMediaType (lexer
, out media
);
151 switch (token
.Value
.Kind
) {
152 case Token
.Type
.SeparatorSemicolon
:
154 if (!NameValueHeaderValue
.TryParseParameters (lexer
, out parameters
, out t
) || t
!= Token
.Type
.End
)
163 parsedValue
= new MediaTypeHeaderValue () {
165 parameters
= parameters
171 internal static Token
? TryParseMediaType (Lexer lexer
, out string media
)
175 var token
= lexer
.Scan ();
176 if (token
!= Token
.Type
.Token
)
179 if (lexer
.Scan () != Token
.Type
.SeparatorSlash
)
182 var token2
= lexer
.Scan ();
183 if (token2
!= Token
.Type
.Token
)
186 media
= lexer
.GetStringValue (token
) + "/" + lexer
.GetStringValue (token2
);
188 return lexer
.Scan ();