ObjectStateFormatter.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. //
  2. // System.Web.UI.ObjectStateFormatter
  3. //
  4. // Authors:
  5. // Ben Maurer ([email protected])
  6. // Gonzalo Paniagua ([email protected])
  7. //
  8. // (C) 2003 Ben Maurer
  9. // (c) Copyright 2004 Novell, Inc. (http://www.novell.com)
  10. //
  11. //#define TRACE
  12. using System.Collections;
  13. using System.ComponentModel;
  14. using System.Globalization;
  15. using System.Drawing;
  16. using System.IO;
  17. using System.Reflection;
  18. using System.Runtime.Serialization.Formatters.Binary;
  19. using System.Runtime.Serialization;
  20. using System.Text;
  21. using System.Web.UI.WebControls;
  22. using System.Web.Util;
  23. using System.Diagnostics;
  24. namespace System.Web.UI {
  25. #if NET_2_0
  26. public
  27. #else
  28. internal
  29. #endif
  30. sealed class ObjectStateFormatter : IFormatter {
  31. public object Deserialize (Stream inputStream)
  32. {
  33. if (inputStream == null)
  34. throw new ArgumentNullException ("inputStream");
  35. return DeserializeObject (new BinaryReader (inputStream));
  36. }
  37. public object Deserialize (string inputString)
  38. {
  39. if (inputString == null)
  40. throw new ArgumentNullException ("inputString");
  41. if (inputString == "")
  42. return null;
  43. return Deserialize (new MemoryStream (Convert.FromBase64String (inputString)));
  44. }
  45. public string Serialize (object stateGraph)
  46. {
  47. if (stateGraph == null)
  48. return "";
  49. MemoryStream ms = new MemoryStream ();
  50. Serialize (ms, stateGraph);
  51. #if TRACE
  52. ms.WriteTo (File.OpenWrite (Path.GetTempFileName ()));
  53. #endif
  54. return Convert.ToBase64String (ms.GetBuffer (), 0, (int) ms.Length);
  55. }
  56. public void Serialize (Stream outputStream, object stateGraph)
  57. {
  58. if (outputStream == null)
  59. throw new ArgumentNullException ("outputStream");
  60. if (stateGraph == null)
  61. throw new ArgumentNullException ("stateGraph");
  62. SerializeValue (new BinaryWriter (outputStream), stateGraph);
  63. }
  64. void SerializeValue (BinaryWriter w, object o)
  65. {
  66. ObjectFormatter.WriteObject (w, o, new WriterContext ());
  67. }
  68. object DeserializeObject (BinaryReader r)
  69. {
  70. return ObjectFormatter.ReadObject (r, new ReaderContext ());
  71. }
  72. #region IFormatter
  73. object IFormatter.Deserialize (Stream serializationStream)
  74. {
  75. return Deserialize (serializationStream);
  76. }
  77. void IFormatter.Serialize (Stream serializationStream, object stateGraph)
  78. {
  79. Serialize (serializationStream, stateGraph);
  80. }
  81. SerializationBinder IFormatter.Binder {
  82. get { return null; }
  83. set { }
  84. }
  85. StreamingContext IFormatter.Context {
  86. get { return new StreamingContext (StreamingContextStates.All); }
  87. set { }
  88. }
  89. ISurrogateSelector IFormatter.SurrogateSelector {
  90. get { return null; }
  91. set { }
  92. }
  93. #endregion
  94. #region Object Readers/Writers
  95. class WriterContext {
  96. Hashtable cache;
  97. short nextKey = 0;
  98. public bool RegisterCache (object o, out short key)
  99. {
  100. if (cache == null) {
  101. cache = new Hashtable ();
  102. cache.Add (o, key = nextKey++);
  103. return false;
  104. }
  105. object posKey = cache [o];
  106. if (posKey == null) {
  107. cache.Add (o, key = nextKey++);
  108. return false;
  109. }
  110. key = (short) posKey;
  111. return true;
  112. }
  113. }
  114. class ReaderContext {
  115. ArrayList cache;
  116. public void CacheItem (object o)
  117. {
  118. if (cache == null)
  119. cache = new ArrayList ();
  120. cache.Add (o);
  121. }
  122. public object GetCache (short key)
  123. {
  124. return cache [key];
  125. }
  126. }
  127. abstract class ObjectFormatter {
  128. static readonly Hashtable writeMap = new Hashtable ();
  129. static ObjectFormatter [] readMap = new ObjectFormatter [256];
  130. static BinaryObjectFormatter binaryObjectFormatter;
  131. static TypeFormatter typeFormatter;
  132. static EnumFormatter enumFormatter;
  133. static SingleRankArrayFormatter singleRankArrayFormatter;
  134. static TypeConverterFormatter typeConverterFormatter;
  135. static ObjectFormatter ()
  136. {
  137. new StringFormatter ().Register ();
  138. new Int64Formatter ().Register ();
  139. new Int32Formatter ().Register ();
  140. new Int16Formatter ().Register ();
  141. new ByteFormatter ().Register ();
  142. new BooleanFormatter ().Register ();
  143. new CharFormatter ().Register ();
  144. new DateTimeFormatter ().Register ();
  145. new PairFormatter ().Register ();
  146. new TripletFormatter ().Register ();
  147. new ArrayListFormatter ().Register ();
  148. new HashtableFormatter ().Register ();
  149. new ObjectArrayFormatter ().Register ();
  150. new UnitFormatter ().Register ();
  151. new FontUnitFormatter ().Register ();
  152. new ColorFormatter ().Register ();
  153. enumFormatter = new EnumFormatter ();
  154. enumFormatter.Register ();
  155. typeFormatter = new TypeFormatter ();
  156. typeFormatter.Register ();
  157. singleRankArrayFormatter = new SingleRankArrayFormatter ();
  158. singleRankArrayFormatter.Register ();
  159. typeConverterFormatter = new TypeConverterFormatter ();
  160. typeConverterFormatter.Register ();
  161. binaryObjectFormatter = new BinaryObjectFormatter ();
  162. binaryObjectFormatter.Register ();
  163. }
  164. // 0 == null
  165. static byte nextId = 1;
  166. public ObjectFormatter ()
  167. {
  168. PrimaryId = nextId ++;
  169. if (NumberOfIds == 1)
  170. return;
  171. SecondaryId = nextId ++;
  172. if (NumberOfIds == 2)
  173. return;
  174. TertiaryId = nextId ++;
  175. if (NumberOfIds == 3)
  176. return;
  177. throw new Exception ();
  178. }
  179. protected readonly byte PrimaryId, SecondaryId = 255, TertiaryId = 255;
  180. protected abstract void Write (BinaryWriter w, object o, WriterContext ctx);
  181. protected abstract object Read (byte token, BinaryReader r, ReaderContext ctx);
  182. protected abstract Type Type { get; }
  183. protected virtual int NumberOfIds { get { return 1; } }
  184. public virtual void Register ()
  185. {
  186. writeMap [Type] = this;
  187. readMap [PrimaryId] = this;
  188. if (SecondaryId != 255) {
  189. readMap [SecondaryId] = this;
  190. if (TertiaryId != 255)
  191. readMap [TertiaryId] = this;
  192. }
  193. }
  194. public static void WriteObject (BinaryWriter w, object o, WriterContext ctx)
  195. {
  196. #if TRACE
  197. if (o != null) {
  198. Trace.WriteLine (String.Format ("Writing {0} (type: {1})", o, o.GetType ()));
  199. Trace.Indent ();
  200. } else {
  201. Trace.WriteLine ("Writing null");
  202. }
  203. long pos = w.BaseStream.Position;
  204. #endif
  205. if (o == null) {
  206. w.Write ((byte) 0);
  207. return;
  208. }
  209. Type t = o.GetType ();
  210. ObjectFormatter fmt = writeMap [t] as ObjectFormatter;
  211. if (fmt == null) {
  212. // Handle abstract types here
  213. if (o is Type)
  214. fmt = typeFormatter;
  215. else if (t.IsEnum)
  216. fmt = enumFormatter;
  217. else if (t.IsArray && ((Array) o).Rank == 1)
  218. fmt = singleRankArrayFormatter;
  219. else {
  220. TypeConverter converter;
  221. converter = TypeDescriptor.GetConverter (o);
  222. if (converter == null ||
  223. !converter.CanConvertTo (typeof (string)) ||
  224. !converter.CanConvertFrom (typeof (string))) {
  225. fmt = binaryObjectFormatter;
  226. } else {
  227. typeConverterFormatter.Converter = converter;
  228. fmt = typeConverterFormatter;
  229. }
  230. }
  231. }
  232. fmt.Write (w, o, ctx);
  233. #if TRACE
  234. Trace.Unindent ();
  235. Trace.WriteLine (String.Format ("Wrote {0} (type: {1}) {2} bytes", o, o.GetType (), w.BaseStream.Position - pos));
  236. #endif
  237. }
  238. public static object ReadObject (BinaryReader r, ReaderContext ctx)
  239. {
  240. byte sig = r.ReadByte ();
  241. if (sig == 0)
  242. return null;
  243. return readMap [sig].Read (sig, r, ctx);
  244. }
  245. protected void Write7BitEncodedInt (BinaryWriter w, int value)
  246. {
  247. do {
  248. int high = (value >> 7) & 0x01ffffff;
  249. byte b = (byte)(value & 0x7f);
  250. if (high != 0) {
  251. b = (byte)(b | 0x80);
  252. }
  253. w.Write(b);
  254. value = high;
  255. } while(value != 0);
  256. }
  257. protected int Read7BitEncodedInt (BinaryReader r)
  258. {
  259. int ret = 0;
  260. int shift = 0;
  261. byte b;
  262. do {
  263. b = r.ReadByte();
  264. ret = ret | ((b & 0x7f) << shift);
  265. shift += 7;
  266. } while ((b & 0x80) == 0x80);
  267. return ret;
  268. }
  269. }
  270. #region Primitive Formatters
  271. class StringFormatter : ObjectFormatter {
  272. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  273. {
  274. short key;
  275. if (ctx.RegisterCache (o, out key)) {
  276. w.Write (SecondaryId);
  277. w.Write (key);
  278. } else {
  279. w.Write (PrimaryId);
  280. w.Write ((string)o);
  281. }
  282. }
  283. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  284. {
  285. if (token == PrimaryId) {
  286. string s = r.ReadString ();
  287. ctx.CacheItem (s);
  288. return s;
  289. } else {
  290. return ctx.GetCache (r.ReadInt16 ());
  291. }
  292. }
  293. protected override Type Type {
  294. get { return typeof (string); }
  295. }
  296. protected override int NumberOfIds {
  297. get { return 2; }
  298. }
  299. }
  300. class Int64Formatter : ObjectFormatter {
  301. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  302. {
  303. w.Write (PrimaryId);
  304. w.Write ((long)o);
  305. }
  306. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  307. {
  308. return r.ReadInt64 ();
  309. }
  310. protected override Type Type {
  311. get { return typeof (long); }
  312. }
  313. }
  314. class Int32Formatter : ObjectFormatter {
  315. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  316. {
  317. int i = (int) o;
  318. if ((int)(byte) i == i) {
  319. w.Write (SecondaryId);
  320. w.Write ((byte) i);
  321. } else {
  322. w.Write (PrimaryId);
  323. w.Write (i);
  324. }
  325. }
  326. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  327. {
  328. if (token == PrimaryId)
  329. return r.ReadInt32 ();
  330. else
  331. return (int) r.ReadByte ();
  332. }
  333. protected override Type Type {
  334. get { return typeof (int); }
  335. }
  336. protected override int NumberOfIds {
  337. get { return 2; }
  338. }
  339. }
  340. class Int16Formatter : ObjectFormatter {
  341. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  342. {
  343. w.Write (PrimaryId);
  344. w.Write ((short)o);
  345. }
  346. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  347. {
  348. return r.ReadInt16 ();
  349. }
  350. protected override Type Type {
  351. get { return typeof (short); }
  352. }
  353. }
  354. class ByteFormatter : ObjectFormatter {
  355. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  356. {
  357. w.Write (PrimaryId);
  358. w.Write ((byte)o);
  359. }
  360. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  361. {
  362. return r.ReadByte ();
  363. }
  364. protected override Type Type {
  365. get { return typeof (byte); }
  366. }
  367. }
  368. class BooleanFormatter : ObjectFormatter {
  369. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  370. {
  371. if ((bool)o == true)
  372. w.Write (PrimaryId);
  373. else
  374. w.Write (SecondaryId);
  375. }
  376. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  377. {
  378. return token == PrimaryId;
  379. }
  380. protected override Type Type {
  381. get { return typeof (bool); }
  382. }
  383. protected override int NumberOfIds {
  384. get { return 2; }
  385. }
  386. }
  387. class CharFormatter : ObjectFormatter {
  388. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  389. {
  390. w.Write (PrimaryId);
  391. w.Write ((char) o);
  392. }
  393. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  394. {
  395. return r.ReadChar ();
  396. }
  397. protected override Type Type {
  398. get { return typeof (char); }
  399. }
  400. }
  401. class DateTimeFormatter : ObjectFormatter {
  402. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  403. {
  404. w.Write (PrimaryId);
  405. w.Write (((DateTime) o).Ticks);
  406. }
  407. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  408. {
  409. return new DateTime (r.ReadInt64 ());
  410. }
  411. protected override Type Type {
  412. get { return typeof (DateTime); }
  413. }
  414. }
  415. class PairFormatter : ObjectFormatter {
  416. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  417. {
  418. Pair p = (Pair) o;
  419. w.Write (PrimaryId);
  420. WriteObject (w, p.First, ctx);
  421. WriteObject (w, p.Second, ctx);
  422. }
  423. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  424. {
  425. Pair p = new Pair ();
  426. p.First = ReadObject (r, ctx);
  427. p.Second = ReadObject (r, ctx);
  428. return p;
  429. }
  430. protected override Type Type {
  431. get { return typeof (Pair); }
  432. }
  433. }
  434. class TripletFormatter : ObjectFormatter {
  435. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  436. {
  437. Triplet t = (Triplet) o;
  438. w.Write (PrimaryId);
  439. WriteObject (w, t.First, ctx);
  440. WriteObject (w, t.Second, ctx);
  441. WriteObject (w, t.Third, ctx);
  442. }
  443. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  444. {
  445. Triplet t = new Triplet ();
  446. t.First = ReadObject (r, ctx);
  447. t.Second = ReadObject (r, ctx);
  448. t.Third = ReadObject (r, ctx);
  449. return t;
  450. }
  451. protected override Type Type {
  452. get { return typeof (Triplet); }
  453. }
  454. }
  455. class ArrayListFormatter : ObjectFormatter {
  456. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  457. {
  458. ArrayList l = (ArrayList) o;
  459. w.Write (PrimaryId);
  460. Write7BitEncodedInt (w, l.Count);
  461. foreach (object i in l)
  462. WriteObject (w, i, ctx);
  463. }
  464. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  465. {
  466. int len = Read7BitEncodedInt (r);
  467. ArrayList l = new ArrayList (len);
  468. for (int i = 0; i < len; i++)
  469. l.Add (ReadObject (r, ctx));
  470. return l;
  471. }
  472. protected override Type Type {
  473. get { return typeof (ArrayList); }
  474. }
  475. }
  476. class HashtableFormatter : ObjectFormatter {
  477. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  478. {
  479. Hashtable ht = (Hashtable) o;
  480. w.Write (PrimaryId);
  481. Write7BitEncodedInt (w, ht.Count);
  482. foreach (DictionaryEntry de in ht) {
  483. WriteObject (w, de.Key, ctx);
  484. WriteObject (w, de.Value, ctx);
  485. }
  486. }
  487. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  488. {
  489. int len = Read7BitEncodedInt (r);
  490. Hashtable ht = new Hashtable (len);
  491. for (int i = 0; i < len; i++) {
  492. object key = ReadObject (r, ctx);
  493. object val = ReadObject (r, ctx);
  494. ht.Add (key, val);
  495. }
  496. return ht;
  497. }
  498. protected override Type Type {
  499. get { return typeof (Hashtable); }
  500. }
  501. }
  502. class ObjectArrayFormatter : ObjectFormatter {
  503. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  504. {
  505. object [] val = (object []) o;
  506. w.Write (PrimaryId);
  507. Write7BitEncodedInt (w, val.Length);
  508. foreach (object i in val)
  509. WriteObject (w, i, ctx);
  510. }
  511. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  512. {
  513. int len = Read7BitEncodedInt (r);
  514. object [] ret = new object [len];
  515. for (int i = 0; i < len; i++)
  516. ret [i] = ReadObject (r, ctx);
  517. return ret;
  518. }
  519. protected override Type Type {
  520. get { return typeof (object []); }
  521. }
  522. }
  523. #endregion
  524. #region System.Web Optimizations
  525. class ColorFormatter : ObjectFormatter {
  526. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  527. {
  528. Color c = (Color) o;
  529. if (!c.IsKnownColor) {
  530. w.Write (PrimaryId);
  531. w.Write (c.ToArgb ());
  532. } else {
  533. w.Write (SecondaryId);
  534. w.Write ((int) c.ToKnownColor ());
  535. }
  536. }
  537. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  538. {
  539. if (token == PrimaryId)
  540. return Color.FromArgb (r.ReadInt32 ());
  541. else
  542. return Color.FromKnownColor ((KnownColor) r.ReadInt32 ());
  543. }
  544. protected override Type Type {
  545. get { return typeof (Color); }
  546. }
  547. protected override int NumberOfIds {
  548. get { return 2; }
  549. }
  550. }
  551. #endregion
  552. #region Special Formatters
  553. class EnumFormatter : ObjectFormatter {
  554. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  555. {
  556. object value = Convert.ChangeType (o, ((Enum) o).GetTypeCode ());
  557. w.Write (PrimaryId);
  558. WriteObject (w, o.GetType (), ctx);
  559. WriteObject (w, value, ctx);
  560. }
  561. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  562. {
  563. Type t = (Type) ReadObject (r, ctx);
  564. object value = ReadObject (r, ctx);
  565. return Enum.ToObject (t, value);
  566. }
  567. protected override Type Type {
  568. get { return typeof (Enum); }
  569. }
  570. }
  571. class TypeFormatter : ObjectFormatter {
  572. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  573. {
  574. short key;
  575. if (ctx.RegisterCache (o, out key)) {
  576. w.Write (SecondaryId);
  577. w.Write (key);
  578. } else {
  579. w.Write (PrimaryId);
  580. w.Write (((Type) o).FullName);
  581. // We should cache the name of the assembly
  582. w.Write (((Type) o).Assembly.FullName);
  583. }
  584. }
  585. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  586. {
  587. if (token == PrimaryId) {
  588. string type = r.ReadString ();
  589. string assembly = r.ReadString ();
  590. Type t = Assembly.Load (assembly).GetType (type);
  591. ctx.CacheItem (t);
  592. return t;
  593. } else {
  594. return ctx.GetCache (r.ReadInt16 ());
  595. }
  596. }
  597. protected override Type Type {
  598. get { return typeof (Type); }
  599. }
  600. protected override int NumberOfIds {
  601. get { return 2; }
  602. }
  603. }
  604. class SingleRankArrayFormatter : ObjectFormatter {
  605. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  606. {
  607. Array val = (Array) o;
  608. w.Write (PrimaryId);
  609. WriteObject (w, val.GetType ().GetElementType (), ctx);
  610. Write7BitEncodedInt (w, val.Length);
  611. foreach (object i in val)
  612. WriteObject (w, i, ctx);
  613. }
  614. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  615. {
  616. Type t = (Type) ReadObject (r, ctx);
  617. int len = Read7BitEncodedInt (r);
  618. Array val = Array.CreateInstance (t, len);
  619. for (int i = 0; i < len; i++)
  620. val.SetValue (ReadObject (r, ctx), i);
  621. return val;
  622. }
  623. protected override Type Type {
  624. get { return typeof (Array); }
  625. }
  626. }
  627. class FontUnitFormatter : StringFormatter {
  628. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  629. {
  630. base.Write (w, o.ToString (), ctx);
  631. }
  632. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  633. {
  634. return FontUnit.Parse ((string) base.Read (token, r, ctx));
  635. }
  636. protected override Type Type {
  637. get { return typeof (FontUnit); }
  638. }
  639. }
  640. class UnitFormatter : StringFormatter {
  641. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  642. {
  643. base.Write (w, o.ToString (), ctx);
  644. }
  645. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  646. {
  647. return Unit.Parse ((string) base.Read (token, r, ctx));
  648. }
  649. protected override Type Type {
  650. get { return typeof (Unit); }
  651. }
  652. }
  653. class TypeConverterFormatter : StringFormatter {
  654. TypeConverter converter;
  655. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  656. {
  657. w.Write (PrimaryId);
  658. ObjectFormatter.WriteObject (w, o.GetType (), ctx);
  659. string v = (string) converter.ConvertTo (null, CultureInfo.InvariantCulture,
  660. o, typeof (string));
  661. base.Write (w, v, ctx);
  662. }
  663. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  664. {
  665. Type t = (Type) ObjectFormatter.ReadObject (r, ctx);
  666. converter = TypeDescriptor.GetConverter (t);
  667. token = r.ReadByte ();
  668. string v = (string) base.Read (token, r, ctx);
  669. return converter.ConvertFrom (null, CultureInfo.InvariantCulture, v);
  670. }
  671. protected override Type Type {
  672. get { return typeof (TypeConverter); }
  673. }
  674. public TypeConverter Converter {
  675. set { converter = value; }
  676. }
  677. }
  678. class BinaryObjectFormatter : ObjectFormatter {
  679. protected override void Write (BinaryWriter w, object o, WriterContext ctx)
  680. {
  681. w.Write (PrimaryId);
  682. MemoryStream ms = new MemoryStream (128);
  683. new BinaryFormatter ().Serialize (ms, o);
  684. byte [] buf = ms.GetBuffer ();
  685. Write7BitEncodedInt (w, buf.Length);
  686. w.Write (buf, 0, buf.Length);
  687. }
  688. protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
  689. {
  690. int len = Read7BitEncodedInt (r);
  691. byte [] buf = r.ReadBytes (len);
  692. if (buf.Length != len)
  693. throw new Exception ();
  694. return new BinaryFormatter ().Deserialize (new MemoryStream (buf));
  695. }
  696. protected override Type Type {
  697. get { return typeof (object); }
  698. }
  699. }
  700. #endregion
  701. #endregion
  702. }
  703. }