| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040 |
- //
- // System.Web.UI.ObjectStateFormatter
- //
- // Authors:
- // Ben Maurer ([email protected])
- // Gonzalo Paniagua ([email protected])
- //
- // (C) 2003 Ben Maurer
- // (c) Copyright 2004-2010 Novell, Inc. (http://www.novell.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.
- //
- //#define TRACE
- using System.Collections;
- using System.ComponentModel;
- using System.Globalization;
- using System.Drawing;
- using System.IO;
- using System.Reflection;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Runtime.Serialization;
- using System.Text;
- using System.Web.UI.WebControls;
- using System.Web.Util;
- using System.Diagnostics;
- using System.Web.Configuration;
- namespace System.Web.UI
- {
- public sealed class ObjectStateFormatter : IFormatter, IStateFormatter
- {
- Page page;
- MachineKeySection section;
- public ObjectStateFormatter ()
- {
- }
-
- internal ObjectStateFormatter (Page page)
- {
- this.page = page;
- }
- bool EnableMac {
- get {
- return (page == null) ? (section != null) : page.EnableViewStateMac;
- }
- }
- bool NeedViewStateEncryption {
- get {
- return (page == null) ? false : page.NeedViewStateEncryption;
- }
- }
- internal MachineKeySection Section {
- get {
- if (section == null)
- section = (MachineKeySection) WebConfigurationManager.GetWebApplicationSection ("system.web/machineKey");
- return section;
- }
- set {
- section = value;
- }
- }
- public object Deserialize (Stream inputStream)
- {
- if (inputStream == null)
- throw new ArgumentNullException ("inputStream");
- return DeserializeObject (new BinaryReader (inputStream));
- }
-
- public object Deserialize (string inputString)
- {
- if (inputString == null)
- throw new ArgumentNullException ("inputString");
- if (inputString.Length == 0)
- throw new ArgumentNullException ("inputString");
- byte [] data = Convert.FromBase64String (inputString);
- if (data == null || (data.Length) == 0)
- throw new ArgumentNullException ("inputString");
- if (NeedViewStateEncryption) {
- if (EnableMac) {
- data = MachineKeySectionUtils.VerifyDecrypt (Section, data);
- } else {
- data = MachineKeySectionUtils.Decrypt (Section, data);
- }
- } else if (EnableMac) {
- data = MachineKeySectionUtils.Verify (Section, data);
- }
- if (data == null)
- throw new HttpException ("Unable to validate data.");
- using (MemoryStream ms = new MemoryStream (data)) {
- return Deserialize (ms);
- }
- }
-
- public string Serialize (object stateGraph)
- {
- if (stateGraph == null)
- return String.Empty;
- byte[] data = null;
- using (MemoryStream ms = new MemoryStream ()) {
- Serialize (ms, stateGraph);
- data = ms.GetBuffer ();
- }
- if (NeedViewStateEncryption) {
- if (EnableMac) {
- data = MachineKeySectionUtils.EncryptSign (Section, data);
- } else {
- data = MachineKeySectionUtils.Encrypt (Section, data);
- }
- } else if (EnableMac) {
- data = MachineKeySectionUtils.Sign (Section, data);
- }
-
- return Convert.ToBase64String (data, 0, data.Length);
- }
-
- public void Serialize (Stream outputStream, object stateGraph)
- {
- if (outputStream == null)
- throw new ArgumentNullException ("outputStream");
- if (stateGraph == null)
- throw new ArgumentNullException ("stateGraph");
- SerializeValue (new BinaryWriter (outputStream), stateGraph);
- }
-
- void SerializeValue (BinaryWriter w, object o)
- {
- ObjectFormatter.WriteObject (w, o, new WriterContext ());
- }
-
- object DeserializeObject (BinaryReader r)
- {
- return ObjectFormatter.ReadObject (r, new ReaderContext ());
- }
-
- #region IFormatter
-
- object IFormatter.Deserialize (Stream serializationStream)
- {
- return Deserialize (serializationStream);
- }
-
- void IFormatter.Serialize (Stream serializationStream, object stateGraph)
- {
- Serialize (serializationStream, stateGraph);
- }
-
- SerializationBinder IFormatter.Binder {
- get { return null; }
- set { }
- }
-
- StreamingContext IFormatter.Context {
- get { return new StreamingContext (StreamingContextStates.All); }
- set { }
- }
-
- ISurrogateSelector IFormatter.SurrogateSelector {
- get { return null; }
- set { }
- }
-
- #endregion
- #region Object Readers/Writers
-
- sealed class WriterContext
- {
- Hashtable cache;
- short nextKey = 0;
- short key = 0;
- public short Key {
- get { return key; }
- }
- public bool RegisterCache (object o)
- {
- if (nextKey == short.MaxValue)
- return false;
- if (cache == null) {
- cache = new Hashtable ();
- cache.Add (o, key = nextKey++);
- return false;
- }
-
- object posKey = cache [o];
- if (posKey == null) {
- cache.Add (o, key = nextKey++);
- return false;
- }
-
- key = (short) posKey;
- return true;
- }
- }
-
- sealed class ReaderContext
- {
- ArrayList cache;
-
- public void CacheItem (object o)
- {
- if (cache == null)
- cache = new ArrayList ();
-
- cache.Add (o);
- }
-
- public object GetCache (short key)
- {
- return cache [key];
- }
- }
-
- abstract class ObjectFormatter
- {
- static readonly Hashtable writeMap = new Hashtable ();
- static ObjectFormatter [] readMap = new ObjectFormatter [256];
- static BinaryObjectFormatter binaryObjectFormatter;
- static TypeFormatter typeFormatter;
- static EnumFormatter enumFormatter;
- static SingleRankArrayFormatter singleRankArrayFormatter;
- static TypeConverterFormatter typeConverterFormatter;
-
- static ObjectFormatter ()
- {
- new StringFormatter ().Register ();
- new Int64Formatter ().Register ();
- new Int32Formatter ().Register ();
- new Int16Formatter ().Register ();
- new ByteFormatter ().Register ();
- new BooleanFormatter ().Register ();
- new CharFormatter ().Register ();
- new DateTimeFormatter ().Register ();
- new PairFormatter ().Register ();
- new TripletFormatter ().Register ();
- new ArrayListFormatter ().Register ();
- new HashtableFormatter ().Register ();
- new ObjectArrayFormatter ().Register ();
- new UnitFormatter ().Register ();
- new FontUnitFormatter ().Register ();
- new IndexedStringFormatter ().Register ();
- new ColorFormatter ().Register ();
- enumFormatter = new EnumFormatter ();
- enumFormatter.Register ();
- typeFormatter = new TypeFormatter ();
- typeFormatter.Register ();
- singleRankArrayFormatter = new SingleRankArrayFormatter ();
- singleRankArrayFormatter.Register ();
- typeConverterFormatter = new TypeConverterFormatter ();
- typeConverterFormatter.Register ();
- binaryObjectFormatter = new BinaryObjectFormatter ();
- binaryObjectFormatter.Register ();
- }
-
- // 0 == null
- static byte nextId = 1;
-
- public ObjectFormatter ()
- {
- PrimaryId = nextId ++;
- if (NumberOfIds == 1)
- return;
-
- SecondaryId = nextId ++;
- if (NumberOfIds == 2)
- return;
-
- TertiaryId = nextId ++;
- if (NumberOfIds == 3)
- return;
-
- throw new Exception ();
- }
-
- protected readonly byte PrimaryId, SecondaryId = 255, TertiaryId = 255;
-
- protected abstract void Write (BinaryWriter w, object o, WriterContext ctx);
- protected abstract object Read (byte token, BinaryReader r, ReaderContext ctx);
- protected abstract Type Type { get; }
- protected virtual int NumberOfIds { get { return 1; } }
-
- public virtual void Register ()
- {
- writeMap [Type] = this;
- readMap [PrimaryId] = this;
- if (SecondaryId != 255) {
- readMap [SecondaryId] = this;
- if (TertiaryId != 255)
- readMap [TertiaryId] = this;
- }
- }
-
- public static void WriteObject (BinaryWriter w, object o, WriterContext ctx)
- {
- #if TRACE && !TARGET_J2EE
- if (o != null) {
- Trace.WriteLine (String.Format ("Writing {0} (type: {1})", o, o.GetType ()));
- Trace.Indent ();
- } else {
- Trace.WriteLine ("Writing null");
- }
- long pos = w.BaseStream.Position;
- #endif
-
- if (o == null) {
- w.Write ((byte) 0);
- return;
- }
-
- Type t = o.GetType ();
- #if TRACE
- Trace.WriteLine (String.Format ("Looking up formatter for type {0}", t));
- #endif
- ObjectFormatter fmt = writeMap [t] as ObjectFormatter;
- #if TRACE
- Trace.WriteLine (String.Format ("Formatter from writeMap: '{0}'", fmt));
- #endif
- if (fmt == null) {
- // Handle abstract types here
-
- if (o is Type)
- fmt = typeFormatter;
- else if (t.IsEnum)
- fmt = enumFormatter;
- else if (t.IsArray && ((Array) o).Rank == 1)
- fmt = singleRankArrayFormatter;
- else {
- TypeConverter converter;
- converter = TypeDescriptor.GetConverter (o);
- #if TRACE
- Trace.WriteLine (String.Format ("Type converter: '{0}' (to string: {1}; from {2}: {3})",
- converter,
- converter != null ? converter.CanConvertTo (typeof (string)) : false,
- t,
- converter != null ? converter.CanConvertFrom (t) : false));
- #endif
- // Do not use the converter if it's an instance of
- // TypeConverter itself - it reports it is able to
- // convert to string, but it's only a conversion
- // consisting of a call to ToString() with no
- // reverse conversion supported. This leads to
- // problems when deserializing the object.
- if (converter == null || converter.GetType () == typeof (TypeConverter) ||
- !converter.CanConvertTo (typeof (string)) || !converter.CanConvertFrom (typeof (string)))
- fmt = binaryObjectFormatter;
- else {
- typeConverterFormatter.Converter = converter;
- fmt = typeConverterFormatter;
- }
- }
- }
- #if TRACE
- Trace.WriteLine (String.Format ("Writing with formatter '{0}'", fmt.GetType ()));
- #endif
- fmt.Write (w, o, ctx);
- #if TRACE && !TARGET_J2EE
- Trace.Unindent ();
- Trace.WriteLine (String.Format ("Wrote {0} (type: {1}) {2} bytes", o, o.GetType (), w.BaseStream.Position - pos));
- #endif
- }
-
- public static object ReadObject (BinaryReader r, ReaderContext ctx)
- {
- byte sig = r.ReadByte ();
-
- if (sig == 0)
- return null;
-
- return readMap [sig].Read (sig, r, ctx);
- }
-
- protected void Write7BitEncodedInt (BinaryWriter w, int value)
- {
- do {
- int high = (value >> 7) & 0x01ffffff;
- byte b = (byte)(value & 0x7f);
-
- if (high != 0)
- b = (byte)(b | 0x80);
-
- w.Write(b);
- value = high;
- } while(value != 0);
- }
-
- protected int Read7BitEncodedInt (BinaryReader r)
- {
- int ret = 0;
- int shift = 0;
- byte b;
-
- do {
- b = r.ReadByte();
-
- ret = ret | ((b & 0x7f) << shift);
- shift += 7;
- } while ((b & 0x80) == 0x80);
-
- return ret;
- }
- }
-
- #region Primitive Formatters
- class StringFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- if (ctx.RegisterCache (o)) {
- w.Write (SecondaryId);
- w.Write (ctx.Key);
- } else {
- w.Write (PrimaryId);
- w.Write ((string)o);
- }
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- if (token == PrimaryId) {
- string s = r.ReadString ();
- ctx.CacheItem (s);
- return s;
- } else {
- return ctx.GetCache (r.ReadInt16 ());
- }
- }
- protected override Type Type {
- get { return typeof (string); }
- }
-
- protected override int NumberOfIds {
- get { return 2; }
- }
- }
- class IndexedStringFormatter : StringFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- IndexedString s = o as IndexedString;
- if (s == null)
- throw new InvalidOperationException ("object is not of the IndexedString type");
-
- base.Write (w, s.Value, ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- string s = base.Read (token, r, ctx) as string;
- if (String.IsNullOrEmpty (s))
- throw new InvalidOperationException ("string must not be null or empty.");
-
- return new IndexedString (s);
- }
-
- protected override Type Type {
- get { return typeof (IndexedString); }
- }
-
- protected override int NumberOfIds {
- get { return 2; }
- }
- }
-
- class Int64Formatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- w.Write (PrimaryId);
- w.Write ((long)o);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- return r.ReadInt64 ();
- }
- protected override Type Type {
- get { return typeof (long); }
- }
- }
-
- class Int32Formatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- int i = (int) o;
- if ((int)(byte) i == i) {
- w.Write (SecondaryId);
- w.Write ((byte) i);
- } else {
- w.Write (PrimaryId);
- w.Write (i);
- }
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- if (token == PrimaryId)
- return r.ReadInt32 ();
- else
- return (int) r.ReadByte ();
- }
-
- protected override Type Type {
- get { return typeof (int); }
- }
-
- protected override int NumberOfIds {
- get { return 2; }
- }
- }
-
- class Int16Formatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- w.Write (PrimaryId);
- w.Write ((short)o);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- return r.ReadInt16 ();
- }
- protected override Type Type {
- get { return typeof (short); }
- }
- }
-
- class ByteFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- w.Write (PrimaryId);
- w.Write ((byte)o);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- return r.ReadByte ();
- }
- protected override Type Type {
- get { return typeof (byte); }
- }
- }
-
- class BooleanFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- if ((bool)o == true)
- w.Write (PrimaryId);
- else
- w.Write (SecondaryId);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- return token == PrimaryId;
- }
-
- protected override Type Type {
- get { return typeof (bool); }
- }
-
- protected override int NumberOfIds {
- get { return 2; }
- }
- }
-
- class CharFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- w.Write (PrimaryId);
- w.Write ((char) o);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- return r.ReadChar ();
- }
-
- protected override Type Type {
- get { return typeof (char); }
- }
- }
-
- class DateTimeFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- w.Write (PrimaryId);
- w.Write (((DateTime) o).Ticks);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- return new DateTime (r.ReadInt64 ());
- }
-
- protected override Type Type {
- get { return typeof (DateTime); }
- }
- }
-
- class PairFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- Pair p = (Pair) o;
- w.Write (PrimaryId);
- WriteObject (w, p.First, ctx);
- WriteObject (w, p.Second, ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- Pair p = new Pair ();
- p.First = ReadObject (r, ctx);
- p.Second = ReadObject (r, ctx);
- return p;
- }
-
- protected override Type Type {
- get { return typeof (Pair); }
- }
- }
-
- class TripletFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- Triplet t = (Triplet) o;
- w.Write (PrimaryId);
- WriteObject (w, t.First, ctx);
- WriteObject (w, t.Second, ctx);
- WriteObject (w, t.Third, ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- Triplet t = new Triplet ();
- t.First = ReadObject (r, ctx);
- t.Second = ReadObject (r, ctx);
- t.Third = ReadObject (r, ctx);
- return t;
- }
-
- protected override Type Type {
- get { return typeof (Triplet); }
- }
- }
-
- class ArrayListFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- ArrayList l = (ArrayList) o;
-
- w.Write (PrimaryId);
- Write7BitEncodedInt (w, l.Count);
- for (int i = 0; i < l.Count; i++)
- WriteObject (w, l [i], ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- int len = Read7BitEncodedInt (r);
- ArrayList l = new ArrayList (len);
-
- for (int i = 0; i < len; i++)
- l.Add (ReadObject (r, ctx));
-
- return l;
- }
-
- protected override Type Type {
- get { return typeof (ArrayList); }
- }
- }
-
- class HashtableFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- Hashtable ht = (Hashtable) o;
-
- w.Write (PrimaryId);
- Write7BitEncodedInt (w, ht.Count);
- foreach (DictionaryEntry de in ht) {
- WriteObject (w, de.Key, ctx);
- WriteObject (w, de.Value, ctx);
- }
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- int len = Read7BitEncodedInt (r);
- Hashtable ht = new Hashtable (len);
-
- for (int i = 0; i < len; i++) {
- object key = ReadObject (r, ctx);
- object val = ReadObject (r, ctx);
-
- ht.Add (key, val);
- }
-
- return ht;
- }
-
- protected override Type Type {
- get { return typeof (Hashtable); }
- }
- }
-
- class ObjectArrayFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- object [] val = (object []) o;
-
- w.Write (PrimaryId);
- Write7BitEncodedInt (w, val.Length);
- for (int i = 0; i < val.Length; i++)
- WriteObject (w, val [i], ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- int len = Read7BitEncodedInt (r);
- object [] ret = new object [len];
-
- for (int i = 0; i < len; i++)
- ret [i] = ReadObject (r, ctx);
-
- return ret;
- }
-
- protected override Type Type {
- get { return typeof (object []); }
- }
- }
-
- #endregion
-
- #region System.Web Optimizations
- class ColorFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- Color c = (Color) o;
-
- if (c.IsEmpty || c.IsKnownColor) {
- w.Write (SecondaryId);
- if (c.IsEmpty)
- w.Write (-1); //isempty marker
- else
- w.Write ((int) c.ToKnownColor ());
- } else {
- w.Write (PrimaryId);
- w.Write (c.ToArgb ());
- }
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- int value = r.ReadInt32 ();
- if (token == PrimaryId)
- return Color.FromArgb (value);
- else {
- if (value == -1) //isempty marker
- return Color.Empty;
- return Color.FromKnownColor ((KnownColor)value);
- }
- }
-
- protected override Type Type {
- get { return typeof (Color); }
- }
-
- protected override int NumberOfIds {
- get { return 2; }
- }
- }
-
- #endregion
-
- #region Special Formatters
- class EnumFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- object value = Convert.ChangeType (o, ((Enum) o).GetTypeCode ());
- w.Write (PrimaryId);
- WriteObject (w, o.GetType (), ctx);
- WriteObject (w, value, ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- Type t = (Type) ReadObject (r, ctx);
- object value = ReadObject (r, ctx);
-
- return Enum.ToObject (t, value);
- }
- protected override Type Type {
- get { return typeof (Enum); }
- }
- }
-
- class TypeFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- if (ctx.RegisterCache (o)) {
- w.Write (SecondaryId);
- w.Write (ctx.Key);
- } else {
- w.Write (PrimaryId);
- w.Write (((Type) o).FullName);
- // We should cache the name of the assembly
- w.Write (((Type) o).Assembly.FullName);
- }
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- if (token == PrimaryId) {
- string type = r.ReadString ();
- string assembly = r.ReadString ();
- Type t = Assembly.Load (assembly).GetType (type);
- ctx.CacheItem (t);
- return t;
- } else {
- return ctx.GetCache (r.ReadInt16 ());
- }
- }
-
- protected override Type Type {
- get { return typeof (Type); }
- }
-
- protected override int NumberOfIds {
- get { return 2; }
- }
- }
-
- class SingleRankArrayFormatter : ObjectFormatter
- {
- readonly BinaryFormatter _binaryFormatter = new BinaryFormatter ();
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- Array val = (Array) o;
- if (val.GetType ().GetElementType ().IsPrimitive) {
- w.Write (SecondaryId);
- _binaryFormatter.Serialize (w.BaseStream, o);
- return;
- }
-
- w.Write (PrimaryId);
- WriteObject (w, val.GetType ().GetElementType (), ctx);
-
- Write7BitEncodedInt (w, val.Length);
- for (int i = 0; i < val.Length; i++)
- WriteObject (w, val.GetValue (i), ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- if (token == SecondaryId)
- return _binaryFormatter.Deserialize (r.BaseStream);
- Type t = (Type) ReadObject (r, ctx);
- int len = Read7BitEncodedInt (r);
- Array val = Array.CreateInstance (t, len);
-
- for (int i = 0; i < len; i++)
- val.SetValue (ReadObject (r, ctx), i);
-
- return val;
- }
-
- protected override Type Type {
- get { return typeof (Array); }
- }
- protected override int NumberOfIds {
- get { return 2; }
- }
- }
-
- class FontUnitFormatter : StringFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- base.Write (w, o.ToString (), ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- return FontUnit.Parse ((string) base.Read (token, r, ctx));
- }
-
- protected override Type Type {
- get { return typeof (FontUnit); }
- }
- }
- class UnitFormatter : StringFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- base.Write (w, o.ToString (), ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- return Unit.Parse ((string) base.Read (token, r, ctx));
- }
-
- protected override Type Type {
- get { return typeof (Unit); }
- }
- }
- class TypeConverterFormatter : StringFormatter
- {
- TypeConverter converter;
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- w.Write (PrimaryId);
- ObjectFormatter.WriteObject (w, o.GetType (), ctx);
- string v = (string) converter.ConvertTo (null, Helpers.InvariantCulture,
- o, typeof (string));
- base.Write (w, v, ctx);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- Type t = (Type) ObjectFormatter.ReadObject (r, ctx);
- converter = TypeDescriptor.GetConverter (t);
- token = r.ReadByte ();
- string v = (string) base.Read (token, r, ctx);
- return converter.ConvertFrom (null, Helpers.InvariantCulture, v);
- }
-
- protected override Type Type {
- get { return typeof (TypeConverter); }
- }
- public TypeConverter Converter {
- set { converter = value; }
- }
- }
- class BinaryObjectFormatter : ObjectFormatter
- {
- protected override void Write (BinaryWriter w, object o, WriterContext ctx)
- {
- w.Write (PrimaryId);
-
- MemoryStream ms = new MemoryStream (128);
- new BinaryFormatter ().Serialize (ms, o);
-
- byte [] buf = ms.GetBuffer ();
- Write7BitEncodedInt (w, buf.Length);
- w.Write (buf, 0, buf.Length);
- }
-
- protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
- {
- int len = Read7BitEncodedInt (r);
- byte [] buf = r.ReadBytes (len);
- if (buf.Length != len)
- throw new Exception ();
-
- return new BinaryFormatter ().Deserialize (new MemoryStream (buf));
- }
-
- protected override Type Type {
- get { return typeof (object); }
- }
- }
-
- #endregion
-
- #endregion
- }
- }
|