| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Channels
- {
- using System.Xml;
- using System.ServiceModel;
- using System.ServiceModel.Dispatcher;
- using System.Xml.XPath;
- using System.Diagnostics;
- using System.IO;
- using System.Collections.Generic;
- public abstract class MessageBuffer : IXPathNavigable, IDisposable
- {
- public abstract int BufferSize { get; }
- void IDisposable.Dispose()
- {
- Close();
- }
- public abstract void Close();
- public virtual void WriteMessage(Stream stream)
- {
- if (stream == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream"));
- Message message = CreateMessage();
- using (message)
- {
- XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream, XD.Dictionary, null, false);
- using (writer)
- {
- message.WriteMessage(writer);
- }
- }
- }
- public virtual string MessageContentType
- {
- get { return FramingEncodingString.Binary; }
- }
- public abstract Message CreateMessage();
- internal Exception CreateBufferDisposedException()
- {
- return new ObjectDisposedException("", SR.GetString(SR.MessageBufferIsClosed));
- }
- public XPathNavigator CreateNavigator()
- {
- return CreateNavigator(int.MaxValue, XmlSpace.None);
- }
- public XPathNavigator CreateNavigator(int nodeQuota)
- {
- return CreateNavigator(nodeQuota, XmlSpace.None);
- }
- public XPathNavigator CreateNavigator(XmlSpace space)
- {
- return CreateNavigator(int.MaxValue, space);
- }
- public XPathNavigator CreateNavigator(int nodeQuota, XmlSpace space)
- {
- if (nodeQuota <= 0)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("nodeQuota", SR.GetString(SR.FilterQuotaRange)));
- return new SeekableMessageNavigator(this.CreateMessage(), nodeQuota, space, true, true);
- }
- }
- class DefaultMessageBuffer : MessageBuffer
- {
- XmlBuffer msgBuffer;
- KeyValuePair<string, object>[] properties;
- bool[] understoodHeaders;
- bool closed;
- MessageVersion version;
- Uri to;
- string action;
- bool isNullMessage;
- public DefaultMessageBuffer(Message message, XmlBuffer msgBuffer)
- {
- this.msgBuffer = msgBuffer;
- this.version = message.Version;
- this.isNullMessage = message is NullMessage;
- properties = new KeyValuePair<string, object>[message.Properties.Count];
- ((ICollection<KeyValuePair<string, object>>)message.Properties).CopyTo(properties, 0);
- understoodHeaders = new bool[message.Headers.Count];
- for (int i = 0; i < understoodHeaders.Length; ++i)
- understoodHeaders[i] = message.Headers.IsUnderstood(i);
- //CSDMain 17837: CreateBufferedCopy should have code to copy over the To and Action headers
- if (version == MessageVersion.None)
- {
- this.to = message.Headers.To;
- this.action = message.Headers.Action;
- }
- }
- object ThisLock
- {
- get { return msgBuffer; }
- }
- public override int BufferSize
- {
- get { return msgBuffer.BufferSize; }
- }
- public override void Close()
- {
- lock (ThisLock)
- {
- if (closed)
- return;
- closed = true;
- for (int i = 0; i < this.properties.Length; i++)
- {
- IDisposable disposable = this.properties[i].Value as IDisposable;
- if (disposable != null)
- disposable.Dispose();
- }
- }
- }
- public override Message CreateMessage()
- {
- if (closed)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
- Message msg;
- if (this.isNullMessage)
- {
- msg = new NullMessage();
- }
- else
- {
- msg = Message.CreateMessage(msgBuffer.GetReader(0), int.MaxValue, this.version);
- }
- lock (ThisLock)
- {
- msg.Properties.CopyProperties(properties);
- }
- for (int i = 0; i < understoodHeaders.Length; ++i)
- {
- if (understoodHeaders[i])
- msg.Headers.AddUnderstood(i);
- }
- if (this.to != null)
- {
- msg.Headers.To = this.to;
- }
- if (this.action != null)
- {
- msg.Headers.Action = this.action;
- }
- return msg;
- }
- }
- class BufferedMessageBuffer : MessageBuffer
- {
- IBufferedMessageData messageData;
- KeyValuePair<string, object>[] properties;
- bool closed;
- object thisLock = new object();
- bool[] understoodHeaders;
- bool understoodHeadersModified;
- public BufferedMessageBuffer(IBufferedMessageData messageData,
- KeyValuePair<string, object>[] properties, bool[] understoodHeaders, bool understoodHeadersModified)
- {
- this.messageData = messageData;
- this.properties = properties;
- this.understoodHeaders = understoodHeaders;
- this.understoodHeadersModified = understoodHeadersModified;
- messageData.Open();
- }
- public override int BufferSize
- {
- get
- {
- lock (ThisLock)
- {
- if (closed)
- #pragma warning suppress 56503 // [....], Invalid State after dispose
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
- return messageData.Buffer.Count;
- }
- }
- }
- public override void WriteMessage(Stream stream)
- {
- if (stream == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream"));
- lock (ThisLock)
- {
- if (closed)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
- ArraySegment<byte> buffer = messageData.Buffer;
- stream.Write(buffer.Array, buffer.Offset, buffer.Count);
- }
- }
- public override string MessageContentType
- {
- get
- {
- lock (ThisLock)
- {
- if (closed)
- #pragma warning suppress 56503 // [....], Invalid State after dispose
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
- return messageData.MessageEncoder.ContentType;
- }
- }
- }
- object ThisLock
- {
- get { return thisLock; }
- }
- public override void Close()
- {
- lock (ThisLock)
- {
- if (!closed)
- {
- closed = true;
- messageData.Close();
- messageData = null;
- }
- }
- }
- public override Message CreateMessage()
- {
- lock (ThisLock)
- {
- if (closed)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
- RecycledMessageState recycledMessageState = messageData.TakeMessageState();
- if (recycledMessageState == null)
- recycledMessageState = new RecycledMessageState();
- BufferedMessage bufferedMessage = new BufferedMessage(messageData, recycledMessageState, this.understoodHeaders, this.understoodHeadersModified);
- bufferedMessage.Properties.CopyProperties(this.properties);
- messageData.Open();
- return bufferedMessage;
- }
- }
- }
- class BodyWriterMessageBuffer : MessageBuffer
- {
- BodyWriter bodyWriter;
- KeyValuePair<string, object>[] properties;
- MessageHeaders headers;
- bool closed;
- object thisLock = new object();
- public BodyWriterMessageBuffer(MessageHeaders headers,
- KeyValuePair<string, object>[] properties, BodyWriter bodyWriter)
- {
- this.bodyWriter = bodyWriter;
- this.headers = new MessageHeaders(headers);
- this.properties = properties;
- }
- protected object ThisLock
- {
- get { return thisLock; }
- }
- public override int BufferSize
- {
- get { return 0; }
- }
- public override void Close()
- {
- lock (ThisLock)
- {
- if (!closed)
- {
- closed = true;
- bodyWriter = null;
- headers = null;
- properties = null;
- }
- }
- }
- public override Message CreateMessage()
- {
- lock (ThisLock)
- {
- if (closed)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException());
- return new BodyWriterMessage(headers, properties, bodyWriter);
- }
- }
- protected BodyWriter BodyWriter
- {
- get { return bodyWriter; }
- }
- protected MessageHeaders Headers
- {
- get { return headers; }
- }
- protected KeyValuePair<string, object>[] Properties
- {
- get { return properties; }
- }
- protected bool Closed
- {
- get { return closed; }
- }
- }
- }
|