* SchemaTypes.cs: Changed DataSet type for a more generic XmlSerializable.
[mono.git] / mcs / class / System.Web / System.Web.UI / LosFormatter.cs
index 2524681381c2c65cace9a617a35f64b2eb02105b..d06317cfd97e93e4d052ef9f2edad187092c00a4 100644 (file)
@@ -11,8 +11,10 @@ using System;
 using System.Collections;
 using System.Drawing;
 using System.IO;
+using System.Runtime.Serialization.Formatters.Binary;
 using System.Text;
 using System.Web.UI;
+using System.Web.Util;
 
 namespace System.Web.UI
 {
@@ -32,6 +34,9 @@ namespace System.Web.UI
                const char tripletID = 't';
                const char arrayListID = 'L';
                const char hashtableID = 'h';
+               const char binaryID = 'b';
+               const char arrayID = 'a';
+               const char dateTimeID = 'd';
                
                static Hashtable specialTypes;
                static Hashtable idToType;
@@ -45,6 +50,8 @@ namespace System.Web.UI
                        specialTypes.Add (typeof (Color), new WriteObject (WriteColor));
                        specialTypes.Add (typeof (ArrayList), new WriteObject (WriteArrayList));
                        specialTypes.Add (typeof (Hashtable), new WriteObject (WriteHashtable));
+                       specialTypes.Add (typeof (Array), new WriteObject (WriteArray));
+                       specialTypes.Add (typeof (DateTime), new WriteObject (WriteDateTime));
 
                        idToType = new Hashtable ();
                        idToType.Add (typeof (string), stringID);
@@ -58,6 +65,7 @@ namespace System.Web.UI
                        idToType.Add (typeof (Color), colorID);
                        idToType.Add (typeof (ArrayList), arrayListID);
                        idToType.Add (typeof (Hashtable), hashtableID);
+                       idToType.Add (typeof (Array), arrayID);
                }
                
                public object Deserialize (Stream stream)
@@ -81,8 +89,7 @@ namespace System.Web.UI
                        if (input == null)
                                throw new ArgumentNullException ("input");
 
-                       string real_input = Encoding.UTF8.GetString (Convert.FromBase64String (input));
-                       Console.WriteLine (real_input);
+                       string real_input = WebEncoding.Encoding.GetString (Convert.FromBase64String (input));
                        return DeserializeObject (real_input);
                }
 
@@ -121,7 +128,6 @@ namespace System.Web.UI
                        }
 
                        result.Length--;
-                       Console.WriteLine ("\t\tenclosed: " + result);
                        return result.ToString ();
                }
                
@@ -130,7 +136,6 @@ namespace System.Web.UI
                        if (input == null || input.Length == 0)
                                return new string [0];
 
-                       Console.WriteLine ("Recibo: " + input);
                        int length = input.Length;
                        bool escaped = false;
                        int opened = 0;
@@ -159,8 +164,6 @@ namespace System.Web.UI
 
                        string [] result = new string [list.Count];
                        list.CopyTo (result, 0);
-                       foreach (string s in result)
-                               Console.WriteLine ("\t->" + s);
                        return result;
                }
 
@@ -217,6 +220,7 @@ namespace System.Web.UI
                                triplet.Third = DeserializeObject (splitted [2]);
                                break;
                        case arrayListID:
+                       case arrayID:
                                ArrayList list = new ArrayList ();
                                obj = list;
                                splitted = GetStringValues (enclosed);
@@ -224,6 +228,10 @@ namespace System.Web.UI
                                        object o = DeserializeObject (s);
                                        list.Add (o);
                                }
+
+                               if (input [0] == arrayID)
+                                       obj = list.ToArray (typeof (object));
+
                                break;
                        case hashtableID:
                                object key;
@@ -242,6 +250,15 @@ namespace System.Web.UI
                                        hash.Add (key, value);
                                }
                                break;
+                       case binaryID:
+                               byte [] buffer = Convert.FromBase64String (enclosed);
+                               MemoryStream ms = new MemoryStream (buffer);
+                               BinaryFormatter fmt = new BinaryFormatter ();
+                               obj = fmt.Deserialize (ms);
+                               break;
+                       case dateTimeID:
+                               obj = new DateTime (Int64.Parse (enclosed));
+                               break;
                        default:
                                throw new ArgumentException ("input");
                        }
@@ -273,7 +290,7 @@ namespace System.Web.UI
                        StringBuilder builder = new StringBuilder ();
                        StringWriter writer = new StringWriter (builder);
                        SerializeObject (writer, value);
-                       byte [] bytes = Encoding.UTF8.GetBytes (builder.ToString ());
+                       byte [] bytes = WebEncoding.Encoding.GetBytes (builder.ToString ());
                        output.Write (Convert.ToBase64String (bytes));
                }
 
@@ -342,6 +359,22 @@ namespace System.Web.UI
                        output.Write('>');
                }
 
+               private static void WriteArray (LosFormatter formatter, TextWriter output, object value)
+               {
+                       if (value == null)
+                               return;
+                       
+                       output.Write (arrayID);
+                       output.Write ('<');
+                       Array array = (Array) value;
+                       for (int i = 0; i < array.Length; i++) {
+                               formatter.SerializeObject (output, array.GetValue (i));
+                               if (i != array.Length - 1)
+                                       output.Write (';');
+                       }
+                       output.Write('>');
+               }
+
                private static void WriteHashtable (LosFormatter formatter, TextWriter output, object value)
                {
                        if (value == null)
@@ -362,6 +395,17 @@ namespace System.Web.UI
                        output.Write('>');
                }
 
+               private static void WriteDateTime (LosFormatter formatter, TextWriter output, object value)
+               {
+                       if (value == null)
+                               return;
+                       
+                       output.Write (dateTimeID);
+                       output.Write ('<');
+                       output.Write (((DateTime) value).Ticks);
+                       output.Write('>');
+               }
+
                private static string EscapeSpecialChars (string str)
                {
                        if (str.IndexOfAny (specialChars) == -1)
@@ -374,15 +418,53 @@ namespace System.Web.UI
                        return result;
                }
                
+               private void SerializeBinary (TextWriter output, object value)
+               {
+                       WebTrace.PushContext ("LosFormatter.SerializeBinary");
+                       /* This is just for debugging purposes */
+                       /*if (value is Array) {
+                               Array array = (Array) value;
+                               for (int i = 0; i < array.Length; i++) {
+                                       object o = array.GetValue (i);
+                                       if (o == null)
+                                               WebTrace.WriteLine ("\t{0} is null", i);
+                                       else
+                                               WebTrace.WriteLine ("\t{0} {1} {2}", i, o.GetType (), o);
+                               }
+                       }
+                       */
+                       
+                       BinaryFormatter fmt = new BinaryFormatter ();
+                       MemoryStream stream = new MemoryStream ();
+
+                       fmt.Serialize (stream, value);
+                       output.Write (binaryID);
+                       output.Write ('<');
+                       byte [] buffer = stream.GetBuffer ();
+                       output.Write (Convert.ToBase64String (buffer));
+                       output.Write ('>');
+                       
+                       WebTrace.PopContext ();
+               }
+
                private void SerializeObject (TextWriter output, object value)
                {
-                       if (value == null)
+                       WebTrace.PushContext ("LosFormatter.SerializeObject");
+                       if (value == null) {
+                               WebTrace.WriteLine ("value is null");
+                               WebTrace.PopContext ();
                                return;
+                       }
 
                        Type t = value.GetType ();
+                       if (t.IsArray)
+                               t = typeof (Array);
+
                        if (specialTypes.Contains (t)) {
                                WriteObject w = (WriteObject) specialTypes [t];
                                w (this, output, value);
+                               WebTrace.WriteLine ("special type: {0}", value.GetType ());
+                               WebTrace.PopContext ();
                                return;
                        }
 
@@ -390,11 +472,13 @@ namespace System.Web.UI
                                char c = (char) idToType [t];
                                string s = EscapeSpecialChars (value.ToString ());
                                output.Write (String.Format ("{0}<{1}>", c, value.ToString ()));
+                               WebTrace.WriteLine ("regular type: {0}", value.GetType ());
+                               WebTrace.PopContext ();
                                return;
                        }
 
-                       //TODO: support more types. Serialize if serializable?
-                       throw new NotImplementedException (String.Format ("Type {0} not supported yet.", t));
+                       SerializeBinary (output, value);
+                       WebTrace.PopContext ();
                }
        }
 }