* TagAttribute.cs: attributes can be stored as encoded html so we
[mono.git] / mcs / class / System.Web / System.Web / HttpValueCollection.cs
1 // 
2 // System.Web.HttpValueCollection
3 //
4 // Author:
5 //      Patrik Torstensson (Patrik.Torstensson@labs2.com)
6 //      Gonzalo Paniagua (gonzalo@ximian.com)
7 //
8 using System;
9 using System.Collections.Specialized;
10 using System.Runtime.Serialization;
11 using System.Text;
12 using System.Web.Util;
13
14 namespace System.Web
15 {
16         [Serializable]
17         class HttpValueCollection : NameValueCollection
18         {
19                 bool _bHeaders;
20
21                 internal HttpValueCollection ()
22                 {
23                         _bHeaders = false;
24                 }
25
26                 internal HttpValueCollection (string sData)
27                 {
28                         FillFromQueryString (sData, Encoding.UTF8);
29                         IsReadOnly = true;
30                 }
31
32                 internal HttpValueCollection(string sData, bool ReadOnly, Encoding encoding)
33                 {
34                         FillFromQueryString (sData, encoding);
35                         IsReadOnly = ReadOnly;
36                 }
37
38                 protected HttpValueCollection (SerializationInfo info, StreamingContext context)
39                         : base (info, context)
40                 {
41                 }
42
43                 // string = header1: value1\r\nheader2: value2
44                 internal void FillFromHeaders (string sHeaders, Encoding encoding)
45                 {
46                         _bHeaders = true;
47                         char [] arrSplitValue = new char [] {':'};
48                         string sKey, sValue;
49
50                         sKey = "";
51                         sValue = "";
52
53                         string [] arrValues = sHeaders.Split (new char [] {'\r', '\n'});
54                         foreach (string sLine in arrValues) {
55                                 string [] arrKeyValue = sLine.Split (arrSplitValue);
56                                 if (arrKeyValue.Length == 1 && arrKeyValue [0].Length == 0) {
57                                         // Empty \r or \n is ignored
58                                         continue;
59                                 }
60
61                                 if (arrKeyValue[0] != sKey && sKey.Length > 0) {
62                                         Add (HttpUtility.UrlDecode (sKey, encoding),
63                                              HttpUtility.UrlDecode (sValue, encoding));
64                                 }
65
66                                 if (arrKeyValue.Length == 1) {
67                                         sValue += "\r\n" + arrKeyValue [0].Trim();
68                                         continue;
69                                 } else if (arrKeyValue.Length == 2) {
70                                         if (arrKeyValue[0].Length == 0) {
71                                                 sValue += arrKeyValue [1].Trim();
72                                                 continue;
73                                         }
74
75                                         sKey = arrKeyValue [0].Trim();
76                                         sValue = arrKeyValue [1].Trim();
77                                 } 
78                         }
79
80                         if (sKey.Length > 0) {
81                                 Add (HttpUtility.UrlDecode (sKey, encoding),
82                                      HttpUtility.UrlDecode (sValue, encoding));
83                         }
84                 }
85
86                 internal void FillFromHeaders (string sData)
87                 {
88                         FillFromHeaders (sData, Encoding.UTF8);
89                 }
90
91                 // String = test=aaa&kalle=nisse
92                 internal void FillFromQueryString (string sData, Encoding encoding)
93                 {
94                         _bHeaders = false;
95                         if (sData == null || sData == "")
96                                 return;
97
98                         string k, v;
99                         int eq;
100                         string [] arrValues = sData.Split (new char [] {'&'});
101                         foreach (string sValue in arrValues) {
102                                 eq = sValue.IndexOf ('=');
103
104                                 if (eq == -1) {
105                                         k = HttpUtility.UrlDecode (sValue.Trim (), encoding);
106                                         Add (k, String.Empty);
107                                         continue;
108                                 }
109
110                                 k = sValue.Substring (0, eq).Trim ();
111                                 v = String.Empty;
112                                 if (eq + 1 < sValue.Length) {
113                                         v = sValue.Substring (eq + 1).Trim ();
114                                         if (v.Length == 0)
115                                                 v = String.Empty;
116                                 }
117
118                                 k = HttpUtility.UrlDecode (k, encoding);
119                                 if (v.Length > 0)
120                                         v = HttpUtility.UrlDecode (v, encoding);
121
122                                 Add (k, v); 
123                         }               
124                 }
125
126                 internal void FillFromQueryString (string sData)
127                 {
128                         FillFromQueryString (sData, Encoding.UTF8);
129                 }
130
131                 internal void FillFromCookieString (string sData)
132                 {
133                         FillFromQueryString (sData, Encoding.UTF8);
134                 }
135
136                 internal void MakeReadOnly ()
137                 {
138                         IsReadOnly = true;
139                 }
140
141                 internal void MakeReadWrite ()
142                 {
143                         IsReadOnly = false;
144                 }
145
146                 internal void Merge (NameValueCollection oData)
147                 {
148                         foreach (string sKey in oData)
149                                 Add (sKey, oData [sKey]);
150                 }
151
152                 internal void Reset ()
153                 {
154                         Clear ();
155                 }
156
157                 internal string ToString (bool UrlEncode)
158                 {
159                         StringBuilder result = new StringBuilder ();
160                         string eq = (_bHeaders ? ":" : "=");
161                         string separator = (_bHeaders ? "\r\n" : "&");
162
163                         foreach (string strKey in AllKeys) {
164
165                                 if (result.Length > 0)
166                                         result.Append (separator);
167
168                                 if (UrlEncode) {
169                                         // use encoding
170                                         result.Append (HttpUtility.UrlEncode (strKey, Encoding.UTF8));
171                                         result.Append (eq);
172                                         result.Append (HttpUtility.UrlEncode (Get (strKey), Encoding.UTF8));
173                                 } else {
174                                         result.Append (strKey);
175                                         result.Append (eq);
176                                         result.Append (Get (strKey));
177                                 }                               
178                         }
179
180                         return result.ToString ();
181                 }
182
183                 virtual new public string ToString ()
184                 {
185                         return ToString (false);
186                 }
187         }
188 }
189