BinaryClientFormatterSink.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //
  2. // System.Runtime.Remoting.Channels.BinaryClientFormatterSink.cs
  3. //
  4. // Author: Rodrigo Moya ([email protected])
  5. // Dietmar Maurer ([email protected])
  6. // Lluis Sanchez Gual ([email protected])
  7. //
  8. // 2002 (C) Copyright, Ximian, Inc.
  9. //
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining
  12. // a copy of this software and associated documentation files (the
  13. // "Software"), to deal in the Software without restriction, including
  14. // without limitation the rights to use, copy, modify, merge, publish,
  15. // distribute, sublicense, and/or sell copies of the Software, and to
  16. // permit persons to whom the Software is furnished to do so, subject to
  17. // the following conditions:
  18. //
  19. // The above copyright notice and this permission notice shall be
  20. // included in all copies or substantial portions of the Software.
  21. //
  22. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. //
  30. using System.Collections;
  31. using System.IO;
  32. using System.Runtime.Remoting.Messaging;
  33. using System.Runtime.Serialization;
  34. using System.Runtime.Serialization.Formatters.Binary;
  35. namespace System.Runtime.Remoting.Channels
  36. {
  37. public class BinaryClientFormatterSink : IClientFormatterSink,
  38. IMessageSink, IClientChannelSink, IChannelSinkBase
  39. {
  40. BinaryCore _binaryCore = BinaryCore.DefaultInstance;
  41. IClientChannelSink _nextInChain;
  42. public BinaryClientFormatterSink (IClientChannelSink nextSink)
  43. {
  44. _nextInChain = nextSink;
  45. }
  46. internal BinaryCore BinaryCore
  47. {
  48. get { return _binaryCore; }
  49. set { _binaryCore = value; }
  50. }
  51. public IClientChannelSink NextChannelSink
  52. {
  53. get {
  54. return _nextInChain;
  55. }
  56. }
  57. public IMessageSink NextSink
  58. {
  59. get {
  60. // This is the last sink in the IMessageSink sink chain
  61. return null;
  62. }
  63. }
  64. public IDictionary Properties
  65. {
  66. get {
  67. return null;
  68. }
  69. }
  70. public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
  71. IMessage msg,
  72. ITransportHeaders headers,
  73. Stream stream)
  74. {
  75. // never called because the formatter sink is
  76. // always the first in the chain
  77. throw new NotSupportedException("BinaryClientFormatterSink must be the first sink in the IClientChannelSink chain");
  78. }
  79. public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
  80. object state,
  81. ITransportHeaders headers,
  82. Stream stream)
  83. {
  84. IMessage replyMessage = (IMessage)_binaryCore.Deserializer.DeserializeMethodResponse (stream, null, (IMethodCallMessage)state);
  85. sinkStack.DispatchReplyMessage (replyMessage);
  86. }
  87. public Stream GetRequestStream (IMessage msg,
  88. ITransportHeaders headers)
  89. {
  90. // never called
  91. throw new NotSupportedException ();
  92. }
  93. public void ProcessMessage (IMessage msg,
  94. ITransportHeaders requestHeaders,
  95. Stream requestStream,
  96. out ITransportHeaders responseHeaders,
  97. out Stream responseStream)
  98. {
  99. // never called because the formatter sink is
  100. // always the first in the chain
  101. throw new NotSupportedException ();
  102. }
  103. public IMessageCtrl AsyncProcessMessage (IMessage msg,
  104. IMessageSink replySink)
  105. {
  106. ITransportHeaders transportHeaders = new TransportHeaders();
  107. Stream stream = _nextInChain.GetRequestStream(msg, transportHeaders);
  108. if (stream == null) stream = new MemoryStream ();
  109. _binaryCore.Serializer.Serialize (stream, msg, null);
  110. if (stream is MemoryStream) stream.Position = 0;
  111. ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);
  112. stack.Push (this, msg);
  113. _nextInChain.AsyncProcessRequest (stack, msg, transportHeaders, stream);
  114. // FIXME: No idea about how to implement IMessageCtrl
  115. return null;
  116. }
  117. public IMessage SyncProcessMessage (IMessage msg)
  118. {
  119. try {
  120. ITransportHeaders call_headers = new TransportHeaders();
  121. call_headers[CommonTransportKeys.RequestUri] = ((IMethodCallMessage)msg).Uri;
  122. call_headers["Content-Type"] = "application/octet-stream";
  123. Stream call_stream = _nextInChain.GetRequestStream(msg, call_headers);
  124. if (call_stream == null) call_stream = new MemoryStream ();
  125. // Serialize msg to the stream
  126. _binaryCore.Serializer.Serialize (call_stream, msg, null);
  127. if (call_stream is MemoryStream) call_stream.Position = 0;
  128. Stream response_stream;
  129. ITransportHeaders response_headers;
  130. _nextInChain.ProcessMessage (msg, call_headers, call_stream, out response_headers,
  131. out response_stream);
  132. // Deserialize response_stream
  133. return (IMessage) _binaryCore.Deserializer.DeserializeMethodResponse (response_stream, null, (IMethodCallMessage)msg);
  134. } catch (Exception e) {
  135. return new ReturnMessage (e, (IMethodCallMessage)msg);
  136. }
  137. }
  138. }
  139. }