2003-07-08 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.SessionState / SessionDictionary.cs
1 //
2 // System.Web.SessionState.SessionDictionary
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
8 //
9
10 using System;
11 using System.IO;
12 using System.Collections;
13 using System.Collections.Specialized;
14 using System.Runtime.Serialization.Formatters.Binary;
15
16 namespace System.Web.SessionState {
17 internal class SessionDictionary : NameObjectCollectionBase
18 {
19         static ArrayList types;
20         bool _dirty;
21
22         static SessionDictionary ()
23         {
24                 types = new ArrayList ();
25                 types.Add ("");
26                 types.Add (typeof (string));
27                 types.Add (typeof (int));
28                 types.Add (typeof (bool));
29                 types.Add (typeof (DateTime));
30                 types.Add (typeof (Decimal));
31                 types.Add (typeof (Byte));
32                 types.Add (typeof (Char));
33                 types.Add (typeof (Single));
34                 types.Add (typeof (Double));
35                 types.Add (typeof (short));
36                 types.Add (typeof (long));
37                 types.Add (typeof (ushort));
38                 types.Add (typeof (uint));
39                 types.Add (typeof (ulong));
40         }
41
42         public SessionDictionary ()
43         {
44         }
45
46         internal void Clear ()
47         {
48                 _dirty = true;
49                 lock (this)
50                         BaseClear ();
51         }
52
53         internal string GetKey (int index)
54         {
55                 string value;
56                 lock (this)
57                         value = BaseGetKey (index);
58                         
59                 return value;
60         }
61
62         internal static bool IsInmutable (object o)
63         {
64                 Type t = o.GetType ();
65                 return (t == typeof (string) || t.IsPrimitive);
66         }
67
68         internal void Remove (string s)
69         {
70                 lock (this)
71                         BaseRemove (s);
72                 _dirty = true;
73         }
74
75         internal void RemoveAt (int index)
76         {
77                 lock (this)
78                         BaseRemoveAt (index);
79                 _dirty = true;
80         }
81
82         internal void Serialize (BinaryWriter w)
83         {
84                 lock (this) {
85                         w.Write (Count);
86                         foreach (string key in Keys) {
87                                 w.Write (key);
88                                 object value = BaseGet (key);
89                                 if (value == null) {
90                                         w.Write (16); // types.Count + 1
91                                         continue;
92                                 }
93
94                                 SerializeByType (w, value);
95                         }
96                 }
97         }
98
99         static void SerializeByType (BinaryWriter w, object value)
100         {
101                 Type type = value.GetType ();
102                 int i = types.IndexOf (type);
103                 if (i == -1) {
104                         w.Write (15); // types.Count
105                         BinaryFormatter bf = new BinaryFormatter ();
106                         bf.Serialize (w.BaseStream, value);
107                         return;
108                 }
109
110                 w.Write (i);
111                 switch (i) {
112                 case 1:
113                         w.Write ((string) value);
114                         break;
115                 case 2:
116                         w.Write ((int) value);
117                         break;
118                 case 3:
119                         w.Write ((bool) value);
120                         break;
121                 case 4:
122                         w.Write (((DateTime) value).Ticks);
123                         break;
124                 case 5:
125                         w.Write ((decimal) value);
126                         break;
127                 case 6:
128                         w.Write ((byte) value);
129                         break;
130                 case 7:
131                         w.Write ((char) value);
132                         break;
133                 case 8:
134                         w.Write ((float) value);
135                         break;
136                 case 9:
137                         w.Write ((double) value);
138                         break;
139                 case 10:
140                         w.Write ((short) value);
141                         break;
142                 case 11:
143                         w.Write ((long) value);
144                         break;
145                 case 12:
146                         w.Write ((ushort) value);
147                         break;
148                 case 13:
149                         w.Write ((uint) value);
150                         break;
151                 case 14:
152                         w.Write ((ulong) value);
153                         break;
154                 }
155         }
156
157         internal static SessionDictionary Deserialize (BinaryReader r)
158         {
159                 SessionDictionary result = new SessionDictionary ();
160                 for (int i = r.ReadInt32 (); i > 0; i--) {
161                         string key = r.ReadString ();
162                         int index = r.ReadInt32 ();
163                         if (index == 16)
164                                 result [key] = null;
165                         else
166                                 result [key] = DeserializeFromIndex (index, r);
167                 }
168
169                 return result;
170         }
171
172         static object DeserializeFromIndex (int index, BinaryReader r)
173         {
174                 if (index == 15){
175                         BinaryFormatter bf = new BinaryFormatter ();
176                         return bf.Deserialize (r.BaseStream);
177                 }
178
179                 object value = null;
180                 switch (index) {
181                 case 1:
182                         value = r.ReadString ();
183                         break;
184                 case 2:
185                         value = r.ReadInt32 ();
186                         break;
187                 case 3:
188                         value = r.ReadBoolean ();
189                         break;
190                 case 4:
191                         value = new DateTime (r.ReadInt64 ());
192                         break;
193                 case 5:
194                         value = r.ReadDecimal ();
195                         break;
196                 case 6:
197                         value = r.ReadByte ();
198                         break;
199                 case 7:
200                         value = r.ReadChar ();
201                         break;
202                 case 8:
203                         value = r.ReadSingle ();
204                         break;
205                 case 9:
206                         value = r.ReadDouble ();
207                         break;
208                 case 10:
209                         value = r.ReadInt16 ();
210                         break;
211                 case 11:
212                         value = r.ReadInt64 ();
213                         break;
214                 case 12:
215                         value = r.ReadUInt16 ();
216                         break;
217                 case 13:
218                         value = r.ReadUInt32 ();
219                         break;
220                 case 14:
221                         value = r.ReadUInt64 ();
222                         break;
223                 }
224
225                 return value;
226         }
227
228
229         internal bool Dirty
230         {
231                 get { return _dirty; }
232                 set { _dirty = value; }
233         }
234
235         internal object this [string s]
236         {
237                 get {
238                         object o;
239                         lock (this)
240                                 o = BaseGet (s);
241
242                         return o;
243                 }
244
245                 set {
246                         lock (this)
247                                 BaseSet (s, value);
248
249                         _dirty = true;
250                 }
251         }
252
253         public object this [int index]
254         {
255                 get {
256                         object o;
257                         lock (this)
258                                 o = BaseGet (index);
259
260                         return o;
261                 }
262                 set {
263                         lock (this)
264                                 BaseSet (index, value);
265
266                         _dirty = true;
267                 }
268         }
269 }
270
271 }
272