2 // System.Net.Mime.ContentDisposition.cs
5 // Tim Coleman (tim@timcoleman.com)
6 // John Luke (john.luke@gmail.com)
8 // Copyright (C) Tim Coleman, 2004
9 // Copyright (C) John Luke, 2005
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Collections;
37 using System.Collections.Specialized;
38 using System.Globalization;
40 namespace System.Net.Mime {
41 public class ContentDisposition
43 // FIXME: "r" was not enough, neither was zzz
44 // so this will fail if the offset is not an even hour
45 const string rfc822 = "dd MMM yyyy HH':'mm':'ss zz00";
49 string dispositionType;
50 StringDictionary parameters = new StringDictionary ();
56 public ContentDisposition () : this (DispositionTypeNames.Attachment)
60 public ContentDisposition (string disposition)
62 if (disposition == null)
63 throw new ArgumentNullException ();
64 if (disposition.Length < 1)
65 throw new FormatException ();
69 int index = disposition.IndexOf (';');
71 dispositionType = disposition.Trim ();
74 string[] split = disposition.Split (';');
75 dispositionType = split[0].Trim ();
76 for (int i = 1; i < split.Length; i++)
80 throw new FormatException ();
84 // the individual pieces
85 void Parse (string pair)
87 if (pair == null || pair.Length < 0)
90 string[] split = pair.Split ('=');
91 if (split.Length == 2)
92 parameters.Add (split[0].Trim (), split[1].Trim ());
94 throw new FormatException ();
97 #endregion // Constructors
101 public DateTime CreationDate {
103 if (parameters.ContainsKey ("creation-date"))
104 return DateTime.ParseExact (parameters["creation-date"], rfc822, null);
106 return DateTime.MinValue;
109 if (value > DateTime.MinValue)
110 parameters["creation-date"] = value.ToString (rfc822);
112 parameters.Remove ("modification-date");
116 public string DispositionType {
117 get { return dispositionType; }
120 throw new ArgumentNullException ();
121 if (value.Length < 1)
122 throw new ArgumentException ();
123 dispositionType = value;
127 public string FileName {
128 get { return parameters["filename"]; }
129 set { parameters["filename"] = value; }
133 get { return String.Compare (dispositionType, DispositionTypeNames.Inline, true, CultureInfo.InvariantCulture) == 0; }
136 dispositionType = DispositionTypeNames.Inline;
138 dispositionType = DispositionTypeNames.Attachment;
142 public DateTime ModificationDate {
144 if (parameters.ContainsKey ("modification-date"))
145 return DateTime.ParseExact (parameters["modification-date"], rfc822, null);
147 return DateTime.MinValue;
150 if (value > DateTime.MinValue)
151 parameters["modification-date"] = value.ToString (rfc822);
153 parameters.Remove ("modification-date");
157 public StringDictionary Parameters {
158 get { return parameters; }
161 public DateTime ReadDate {
163 if (parameters.ContainsKey ("read-date"))
164 return DateTime.ParseExact (parameters["read-date"], rfc822, null);
166 return DateTime.MinValue;
169 if (value > DateTime.MinValue)
170 parameters["read-date"] = value.ToString (rfc822);
172 parameters.Remove ("read-date");
178 if (parameters.ContainsKey ("size"))
179 return long.Parse (parameters["size"]);
185 parameters["size"] = value.ToString ();
187 parameters.Remove ("size");
191 #endregion // Properties
195 public override bool Equals (object obj)
197 return Equals (obj as ContentDisposition);
200 bool Equals (ContentDisposition other)
202 return other != null && ToString () == other.ToString ();
205 public override int GetHashCode ()
207 return ToString ().GetHashCode ();
210 public override string ToString ()
212 // the content-disposition header as in RFC 2183
213 // ex. attachment; filename=genome.jpeg; modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
214 // the dates must be quoted and in RFC 822 format
216 // According to RFC 2183, the filename field value follows the definition
217 // given in RFC 1521, which is
219 // value := token / quoted-string
221 StringBuilder sb = new StringBuilder ();
222 sb.Append (DispositionType.ToLower ());
223 if (Parameters != null && Parameters.Count > 0) {
227 foreach (DictionaryEntry pair in Parameters)
229 if (pair.Value != null && pair.Value.ToString ().Length > 0) {
231 sb.Append (pair.Key);
234 key = pair.Key.ToString ();
235 value = pair.Value.ToString ();
236 if ((key == "filename" && value.IndexOf (' ') != -1) || key.EndsWith ("date"))
249 return sb.ToString ();
252 #endregion // Methods