Merge pull request #820 from brendanzagaeski/master
[mono.git] / mcs / class / System.Net.Http / System.Net.Http.Headers / MediaTypeHeaderValue.cs
index 6c3394e18384759f03bed270baefa709eb6e11c7..296010aa2ad5687ccc1487e963398122c412ec58 100644 (file)
 //
 
 using System.Collections.Generic;
-using System.Linq;
 
 namespace System.Net.Http.Headers
 {
        public class MediaTypeHeaderValue : ICloneable
        {
-               List<NameValueHeaderValue> parameters;
-               string media_type;
+               internal List<NameValueHeaderValue> parameters;
+               internal string media_type;
 
                public MediaTypeHeaderValue (string mediaType)
                {
@@ -53,14 +52,44 @@ namespace System.Net.Http.Headers
                        }
                }
 
-               public string CharSet { get; set; }
+               internal MediaTypeHeaderValue ()
+               {
+               }
+
+               public string CharSet {
+                       get {
+                               if (parameters == null)
+                                       return null;
+
+                               var found = parameters.Find (l => string.Equals (l.Name, "charset", StringComparison.OrdinalIgnoreCase));
+                               if (found == null)
+                                       return null;
+
+                               return found.Value;
+                       }
+
+                       set {
+                               if (parameters == null)
+                                       parameters = new List<NameValueHeaderValue> ();
+
+                               parameters.SetValue ("charset", value);
+                       }
+               }
 
                public string MediaType {
                        get {
                                return media_type;
                        }
                        set {
-                               media_type = value;
+                               if (value == null)
+                                       throw new ArgumentNullException ("MediaType");
+
+                               string temp;
+                               var token = TryParseMediaType (new Lexer (value), out temp);
+                               if (token == null || token.Value.Kind != Token.Type.End)
+                                       throw new FormatException ();
+
+                               media_type = temp;
                        }
                }
 
@@ -82,7 +111,7 @@ namespace System.Net.Http.Headers
                                return false;
 
                        return string.Equals (source.media_type, media_type, StringComparison.OrdinalIgnoreCase) &&
-                               Enumerable.SequenceEqual (source.parameters, parameters);
+                               source.parameters.SequenceEqual (parameters);
                }
 
                public override int GetHashCode ()
@@ -98,10 +127,65 @@ namespace System.Net.Http.Headers
 
                        throw new FormatException (input);
                }
+
+               public override string ToString ()
+               {
+                       if (parameters == null)
+                               return media_type;
+
+                       return media_type + CollectionExtensions.ToString (parameters);
+               }
                
                public static bool TryParse (string input, out MediaTypeHeaderValue parsedValue)
                {
-                       throw new NotImplementedException ();
+                       parsedValue = null;
+
+                       var lexer = new Lexer (input);
+
+                       string media;
+                       List<NameValueHeaderValue> parameters = null;
+                       var token = TryParseMediaType (lexer, out media);
+                       if (token == null)
+                               return false;
+
+                       switch (token.Value.Kind) {
+                       case Token.Type.SeparatorSemicolon:
+                               Token t;
+                               if (!NameValueHeaderValue.TryParseParameters (lexer, out parameters, out t) || t != Token.Type.End)
+                                       return false;
+                               break;
+                       case Token.Type.End:
+                               break;
+                       default:
+                               return false;
+                       }
+
+                       parsedValue = new MediaTypeHeaderValue () {
+                               media_type = media,
+                               parameters = parameters
+                       };
+
+                       return true;
+               }
+
+               internal static Token? TryParseMediaType (Lexer lexer, out string media)
+               {
+                       media = null;
+
+                       var token = lexer.Scan ();
+                       if (token != Token.Type.Token)
+                               return null;
+
+                       if (lexer.Scan () != Token.Type.SeparatorSlash)
+                               return null;
+
+                       var token2 = lexer.Scan ();
+                       if (token2 != Token.Type.Token)
+                               return null;
+
+                       media = lexer.GetStringValue (token) + "/" + lexer.GetStringValue (token2);
+
+                       return lexer.Scan ();
                }
        }
 }