BinaryFormatter.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // BinaryFormatter.cs
  2. //
  3. // Author:
  4. // Dick Porter ([email protected])
  5. // Lluis Sanchez Gual ([email protected])
  6. //
  7. // (C) 2002 Ximian, Inc. http://www.ximian.com
  8. using System.Runtime.Serialization.Formatters;
  9. using System.Runtime.Serialization;
  10. using System.Reflection;
  11. using System.Collections;
  12. using System.IO;
  13. using System.Runtime.Remoting.Messaging;
  14. namespace System.Runtime.Serialization.Formatters.Binary {
  15. public sealed class BinaryFormatter : IRemotingFormatter, IFormatter
  16. {
  17. private FormatterAssemblyStyle assembly_format;
  18. private SerializationBinder binder;
  19. private StreamingContext context;
  20. private ISurrogateSelector surrogate_selector;
  21. private FormatterTypeStyle type_format;
  22. public BinaryFormatter()
  23. {
  24. surrogate_selector=null;
  25. context=new StreamingContext(StreamingContextStates.All);
  26. }
  27. public BinaryFormatter(ISurrogateSelector selector, StreamingContext context)
  28. {
  29. surrogate_selector=selector;
  30. this.context=context;
  31. }
  32. public FormatterAssemblyStyle AssemblyFormat
  33. {
  34. get {
  35. return(assembly_format);
  36. }
  37. set {
  38. assembly_format=value;
  39. }
  40. }
  41. public SerializationBinder Binder
  42. {
  43. get {
  44. return(binder);
  45. }
  46. set {
  47. binder=value;
  48. }
  49. }
  50. public StreamingContext Context
  51. {
  52. get {
  53. return(context);
  54. }
  55. set {
  56. context=value;
  57. }
  58. }
  59. public ISurrogateSelector SurrogateSelector
  60. {
  61. get {
  62. return(surrogate_selector);
  63. }
  64. set {
  65. surrogate_selector=value;
  66. }
  67. }
  68. public FormatterTypeStyle TypeFormat
  69. {
  70. get {
  71. return(type_format);
  72. }
  73. set {
  74. type_format=value;
  75. }
  76. }
  77. public object Deserialize(Stream serializationStream)
  78. {
  79. return Deserialize (serializationStream, null);
  80. }
  81. public object Deserialize(Stream serializationStream, HeaderHandler handler)
  82. {
  83. if(serializationStream==null)
  84. {
  85. throw new ArgumentNullException("serializationStream is null");
  86. }
  87. if(serializationStream.CanSeek &&
  88. serializationStream.Length==0)
  89. {
  90. throw new SerializationException("serializationStream supports seeking, but its length is 0");
  91. }
  92. BinaryReader reader = new BinaryReader (serializationStream);
  93. bool hasHeader;
  94. ReadBinaryHeader (reader, out hasHeader);
  95. // Messages are read using a special static method, which does not use ObjectReader
  96. // if it is not needed. This saves time and memory.
  97. BinaryElement elem = (BinaryElement) reader.PeekChar();
  98. if (elem == BinaryElement.MethodCall) {
  99. return MessageFormatter.ReadMethodCall (reader, hasHeader, handler, surrogate_selector, context);
  100. }
  101. else if (elem == BinaryElement.MethodResponse) {
  102. return MessageFormatter.ReadMethodResponse (reader, hasHeader, handler, null, surrogate_selector, context);
  103. }
  104. else {
  105. ObjectReader serializer = new ObjectReader (surrogate_selector, context);
  106. return serializer.ReadObjectGraph (reader, hasHeader, handler);
  107. }
  108. }
  109. public object DeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallmessage)
  110. {
  111. if(serializationStream==null) {
  112. throw new ArgumentNullException("serializationStream is null");
  113. }
  114. if(serializationStream.CanSeek &&
  115. serializationStream.Length==0) {
  116. throw new SerializationException("serializationStream supports seeking, but its length is 0");
  117. }
  118. BinaryReader reader = new BinaryReader (serializationStream);
  119. bool hasHeader;
  120. ReadBinaryHeader (reader, out hasHeader);
  121. return MessageFormatter.ReadMethodResponse (reader, hasHeader, handler, methodCallmessage, surrogate_selector, context);
  122. }
  123. public void Serialize(Stream serializationStream, object graph)
  124. {
  125. Serialize (serializationStream, graph, null);
  126. }
  127. public void Serialize(Stream serializationStream, object graph, Header[] headers)
  128. {
  129. if(serializationStream==null) {
  130. throw new ArgumentNullException("serializationStream is null");
  131. }
  132. BinaryWriter writer = new BinaryWriter (serializationStream);
  133. WriteBinaryHeader (writer, headers!=null);
  134. if (graph is IMethodCallMessage) {
  135. MessageFormatter.WriteMethodCall (writer, graph, headers, surrogate_selector, context);
  136. }
  137. else if (graph is IMethodReturnMessage) {
  138. MessageFormatter.WriteMethodResponse (writer, graph, headers, surrogate_selector, context);
  139. }
  140. else {
  141. ObjectWriter serializer = new ObjectWriter (surrogate_selector, context);
  142. serializer.WriteObjectGraph (writer, graph, headers);
  143. }
  144. writer.Flush();
  145. }
  146. public void WriteBinaryHeader (BinaryWriter writer, bool hasHeaders)
  147. {
  148. writer.Write ((byte)BinaryElement.Header);
  149. writer.Write ((int)1);
  150. if (hasHeaders) writer.Write ((int)2);
  151. else writer.Write ((int)-1);
  152. writer.Write ((int)1);
  153. writer.Write ((int)0);
  154. }
  155. private void ReadBinaryHeader (BinaryReader reader, out bool hasHeaders)
  156. {
  157. reader.ReadByte();
  158. reader.ReadInt32();
  159. int val = reader.ReadInt32();
  160. hasHeaders = (val==2);
  161. reader.ReadInt32();
  162. reader.ReadInt32();
  163. }
  164. }
  165. }