ObjectStateFormatter.cs 21 KB

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