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.
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Globalization;
38 namespace System.Net.Mime {
39 public class ContentDisposition
41 // FIXME: "r" was not enough, neither was zzz
42 // so this will fail if the offset is not an even hour
43 const string rfc822 = "dd MMM yyyy HH':'mm':'ss zz00";
47 string dispositionType;
48 StringDictionary parameters = new StringDictionary ();
54 public ContentDisposition () : this (DispositionTypeNames.Attachment)
58 public ContentDisposition (string disposition)
60 if (disposition == null)
61 throw new ArgumentNullException ();
62 if (disposition.Length < 1)
63 throw new FormatException ();
67 int index = disposition.IndexOf (';');
69 dispositionType = disposition.Trim ();
72 string[] split = disposition.Split (';');
73 dispositionType = split[0].Trim ();
74 for (int i = 1; i < split.Length; i++)
78 throw new FormatException ();
82 // the individual pieces
83 void Parse (string pair)
85 if (pair == null || pair.Length < 0)
88 string[] split = pair.Split ('=');
89 if (split.Length == 2)
90 parameters.Add (split[0].Trim (), split[1].Trim ());
92 throw new FormatException ();
95 #endregion // Constructors
99 public DateTime CreationDate {
101 if (parameters.ContainsKey ("creation-date"))
102 return DateTime.ParseExact (parameters["creation-date"], rfc822, null);
104 return DateTime.MinValue;
107 if (value > DateTime.MinValue)
108 parameters["creation-date"] = value.ToString (rfc822);
110 parameters.Remove ("modification-date");
114 public string DispositionType {
115 get { return dispositionType; }
118 throw new ArgumentNullException ();
119 if (value.Length < 1)
120 throw new ArgumentException ();
121 dispositionType = value;
125 public string FileName {
126 get { return parameters["filename"]; }
127 set { parameters["filename"] = value; }
131 get { return String.Compare (dispositionType, DispositionTypeNames.Inline, true, CultureInfo.InvariantCulture) == 0; }
134 dispositionType = DispositionTypeNames.Inline;
136 dispositionType = DispositionTypeNames.Attachment;
140 public DateTime ModificationDate {
142 if (parameters.ContainsKey ("modification-date"))
143 return DateTime.ParseExact (parameters["modification-date"], rfc822, null);
145 return DateTime.MinValue;
148 if (value > DateTime.MinValue)
149 parameters["modification-date"] = value.ToString (rfc822);
151 parameters.Remove ("modification-date");
155 public StringDictionary Parameters {
156 get { return parameters; }
159 public DateTime ReadDate {
161 if (parameters.ContainsKey ("read-date"))
162 return DateTime.ParseExact (parameters["read-date"], rfc822, null);
164 return DateTime.MinValue;
167 if (value > DateTime.MinValue)
168 parameters["read-date"] = value.ToString (rfc822);
170 parameters.Remove ("read-date");
176 if (parameters.ContainsKey ("size"))
177 return long.Parse (parameters["size"]);
183 parameters["size"] = value.ToString ();
185 parameters.Remove ("size");
189 #endregion // Properties
193 public override bool Equals (object obj)
195 return Equals (obj as ContentDisposition);
198 bool Equals (ContentDisposition other)
200 return other != null && ToString () == other.ToString ();
203 public override int GetHashCode ()
205 return ToString ().GetHashCode ();
208 public override string ToString ()
210 // the content-disposition header as in RFC 2183
211 // ex. attachment; filename=genome.jpeg; modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
212 // the dates must be quoted and in RFC 822 format
214 // According to RFC 2183, the filename field value follows the definition
215 // given in RFC 1521, which is
217 // value := token / quoted-string
219 StringBuilder sb = new StringBuilder ();
220 sb.Append (DispositionType.ToLower ());
221 if (Parameters != null && Parameters.Count > 0) {
225 foreach (DictionaryEntry pair in Parameters)
227 if (pair.Value != null && pair.Value.ToString ().Length > 0) {
229 sb.Append (pair.Key);
232 key = pair.Key.ToString ();
233 value = pair.Value.ToString ();
234 if ((key == "filename" && value.IndexOf (' ') != -1) || key.EndsWith ("date"))
247 return sb.ToString ();
250 #endregion // Methods