2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.Web / System.Web.SessionState / SessionDictionary.cs
index 8a916d08fbf7bd3be075af50b9a188936b477f56..d1b193d90d594d4e36e73351fb7c15ac6afa34aa 100644 (file)
@@ -7,51 +7,67 @@
 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
 //
 
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System;
 using System.IO;
 using System.Collections;
 using System.Collections.Specialized;
-using System.Runtime.Serialization.Formatters.Binary;
 
 namespace System.Web.SessionState {
 internal class SessionDictionary : NameObjectCollectionBase
 {
-       static ArrayList types;
        bool _dirty;
-
-       static SessionDictionary ()
+       
+       public SessionDictionary ()
        {
-               types = new ArrayList ();
-               types.Add ("");
-               types.Add (typeof (string));
-               types.Add (typeof (int));
-               types.Add (typeof (bool));
-               types.Add (typeof (DateTime));
-               types.Add (typeof (Decimal));
-               types.Add (typeof (Byte));
-               types.Add (typeof (Char));
-               types.Add (typeof (Single));
-               types.Add (typeof (Double));
-               types.Add (typeof (short));
-               types.Add (typeof (long));
-               types.Add (typeof (ushort));
-               types.Add (typeof (uint));
-               types.Add (typeof (ulong));
        }
 
-       public SessionDictionary ()
+       internal SessionDictionary Clone ()
        {
-       }
+               SessionDictionary sess = new SessionDictionary ();
+               int last = sess.Count;
+               for (int i = 0; i < last; i++) {
+                       string key = GetKey (i);
+                       sess [key] = this [key];
+               }
 
+               return sess;
+       }
+       
        internal void Clear ()
        {
                _dirty = true;
-               BaseClear ();
+               lock (this)
+                       BaseClear ();
        }
 
        internal string GetKey (int index)
        {
-               return BaseGetKey (index);
+               string value;
+               lock (this)
+                       value = BaseGetKey (index);
+                       
+               return value;
        }
 
        internal static bool IsInmutable (object o)
@@ -62,86 +78,32 @@ internal class SessionDictionary : NameObjectCollectionBase
 
        internal void Remove (string s)
        {
-               BaseRemove (s);
+               lock (this)
+                       BaseRemove (s);
                _dirty = true;
        }
 
        internal void RemoveAt (int index)
        {
-               BaseRemoveAt (index);
+               lock (this)
+                       BaseRemoveAt (index);
                _dirty = true;
        }
 
        internal void Serialize (BinaryWriter w)
        {
-               w.Write (Count);
-               foreach (string key in Keys) {
-                       w.Write (key);
-                       object value = BaseGet (key);
-                       if (value == null) {
-                               w.Write (16); // types.Count + 1
-                               continue;
+               lock (this) {
+                       w.Write (Count);
+                       foreach (string key in Keys) {
+                               w.Write (key);
+                               object value = BaseGet (key);
+                               if (value == null) {
+                                       w.Write (System.Web.Util.AltSerialization.NullIndex);
+                                       continue;
+                               }
+
+                               System.Web.Util.AltSerialization.SerializeByType (w, value);
                        }
-
-                       SerializeByType (w, value);
-               }
-       }
-
-       static void SerializeByType (BinaryWriter w, object value)
-       {
-               Type type = value.GetType ();
-               int i = types.IndexOf (type);
-               if (i == -1) {
-                       w.Write (15); // types.Count
-                       BinaryFormatter bf = new BinaryFormatter ();
-                       bf.Serialize (w.BaseStream, value);
-                       return;
-               }
-
-               w.Write (i);
-               switch (i) {
-               case 1:
-                       w.Write ((string) value);
-                       break;
-               case 2:
-                       w.Write ((int) value);
-                       break;
-               case 3:
-                       w.Write ((bool) value);
-                       break;
-               case 4:
-                       w.Write (((DateTime) value).Ticks);
-                       break;
-               case 5:
-                       w.Write ((decimal) value);
-                       break;
-               case 6:
-                       w.Write ((byte) value);
-                       break;
-               case 7:
-                       w.Write ((char) value);
-                       break;
-               case 8:
-                       w.Write ((float) value);
-                       break;
-               case 9:
-                       w.Write ((double) value);
-                       break;
-               case 10:
-                       w.Write ((short) value);
-                       break;
-               case 11:
-                       w.Write ((long) value);
-                       break;
-               case 12:
-                       w.Write ((ushort) value);
-                       break;
-               case 13:
-                       w.Write ((uint) value);
-                       break;
-               case 14:
-                       w.Write ((ulong) value);
-                       break;
                }
        }
 
@@ -151,72 +113,15 @@ internal class SessionDictionary : NameObjectCollectionBase
                for (int i = r.ReadInt32 (); i > 0; i--) {
                        string key = r.ReadString ();
                        int index = r.ReadInt32 ();
-                       if (index == 16)
+                       if (index == System.Web.Util.AltSerialization.NullIndex)
                                result [key] = null;
                        else
-                               result [key] = DeserializeFromIndex (index, r);
+                               result [key] = System.Web.Util.AltSerialization.DeserializeFromIndex (index, r);
                }
 
                return result;
        }
 
-       static object DeserializeFromIndex (int index, BinaryReader r)
-       {
-               if (index == 15){
-                       BinaryFormatter bf = new BinaryFormatter ();
-                       return bf.Deserialize (r.BaseStream);
-               }
-
-               object value = null;
-               switch (index) {
-               case 1:
-                       value = r.ReadString ();
-                       break;
-               case 2:
-                       value = r.ReadInt32 ();
-                       break;
-               case 3:
-                       value = r.ReadBoolean ();
-                       break;
-               case 4:
-                       value = new DateTime (r.ReadInt64 ());
-                       break;
-               case 5:
-                       value = r.ReadDecimal ();
-                       break;
-               case 6:
-                       value = r.ReadByte ();
-                       break;
-               case 7:
-                       value = r.ReadChar ();
-                       break;
-               case 8:
-                       value = r.ReadSingle ();
-                       break;
-               case 9:
-                       value = r.ReadDouble ();
-                       break;
-               case 10:
-                       value = r.ReadInt16 ();
-                       break;
-               case 11:
-                       value = r.ReadInt64 ();
-                       break;
-               case 12:
-                       value = r.ReadUInt16 ();
-                       break;
-               case 13:
-                       value = r.ReadUInt32 ();
-                       break;
-               case 14:
-                       value = r.ReadUInt64 ();
-                       break;
-               }
-
-               return value;
-       }
-
-
        internal bool Dirty
        {
                get { return _dirty; }
@@ -225,21 +130,79 @@ internal class SessionDictionary : NameObjectCollectionBase
 
        internal object this [string s]
        {
-               get { return BaseGet (s); }
+               get {
+                       object o;
+                       lock (this)
+                               o = BaseGet (s);
+
+                       return o;
+               }
+
                set {
-                       BaseSet (s, value);
+                       lock (this)\r
+                       {                                \r
+                               object obj = BaseGet(s);\r
+                               if ((obj == null) && (value == null))\r
+                                       return; \r
+                               BaseSet (s, value);
+                       }
+
                        _dirty = true;
                }
        }
 
        public object this [int index]
        {
-               get { return BaseGet (index); }
+               get {
+                       object o;
+                       lock (this)
+                               o = BaseGet (index);
+
+                       return o;
+               }
                set {
-                       BaseSet (index, value);
+                       lock (this)
+                       {                                \r
+                               object obj = BaseGet(index);\r
+                               if ((obj == null) && (value == null))\r
+                                       return; \r
+                               BaseSet (index, value);
+                       }
+
                        _dirty = true;
                }
        }
+
+       internal byte [] ToByteArray ()
+       {
+               MemoryStream stream = null;
+               try {
+                       stream = new MemoryStream ();
+                       Serialize (new BinaryWriter (stream));
+                       return stream.GetBuffer ();
+               } catch {
+                       throw;
+               } finally {
+                       if (stream != null)
+                               stream.Close ();
+               }
+       }
+
+       internal static SessionDictionary FromByteArray (byte [] data)
+       {
+               SessionDictionary result = null;
+               MemoryStream stream = null;
+               try {
+                       stream = new MemoryStream (data);
+                       result = Deserialize (new BinaryReader (stream));
+               } catch {
+                       throw;
+               } finally {
+                       if (stream != null)
+                               stream.Close ();
+               }
+               return result;
+       }
 }
 
 }