| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Channels
- {
- using System.Globalization;
- using System.IO;
- using System.Runtime;
- using System.ServiceModel;
- using System.ServiceModel.Description;
- using System.ServiceModel.Diagnostics;
- using System.Text;
- using System.Threading;
- using System.Xml;
- using System.ServiceModel.Diagnostics.Application;
- using System.Runtime.Diagnostics;
- class MtomMessageEncoderFactory : MessageEncoderFactory
- {
- MtomMessageEncoder messageEncoder;
- public MtomMessageEncoderFactory(MessageVersion version, Encoding writeEncoding, int maxReadPoolSize, int maxWritePoolSize, int maxBufferSize, XmlDictionaryReaderQuotas quotas)
- {
- messageEncoder = new MtomMessageEncoder(version, writeEncoding, maxReadPoolSize, maxWritePoolSize, maxBufferSize, quotas);
- }
- public override MessageEncoder Encoder
- {
- get { return messageEncoder; }
- }
- public override MessageVersion MessageVersion
- {
- get { return messageEncoder.MessageVersion; }
- }
- public int MaxWritePoolSize
- {
- get { return messageEncoder.MaxWritePoolSize; }
- }
- public int MaxReadPoolSize
- {
- get { return messageEncoder.MaxReadPoolSize; }
- }
- public XmlDictionaryReaderQuotas ReaderQuotas
- {
- get
- {
- return messageEncoder.ReaderQuotas;
- }
- }
- public int MaxBufferSize
- {
- get { return messageEncoder.MaxBufferSize; }
- }
- public static Encoding[] GetSupportedEncodings()
- {
- Encoding[] supported = TextEncoderDefaults.SupportedEncodings;
- Encoding[] enc = new Encoding[supported.Length];
- Array.Copy(supported, enc, supported.Length);
- return enc;
- }
- }
- // Some notes:
- // The Encoding passed in is used for the SOAP envelope
- class MtomMessageEncoder : MessageEncoder, ITraceSourceStringProvider
- {
- Encoding writeEncoding;
- // Double-checked locking pattern requires volatile for read/write synchronization
- volatile SynchronizedPool<XmlDictionaryWriter> streamedWriterPool;
- volatile SynchronizedPool<XmlDictionaryReader> streamedReaderPool;
- volatile SynchronizedPool<MtomBufferedMessageData> bufferedReaderPool;
- volatile SynchronizedPool<MtomBufferedMessageWriter> bufferedWriterPool;
- volatile SynchronizedPool<RecycledMessageState> recycledStatePool;
- object thisLock;
- MessageVersion version;
- const int maxPooledXmlReadersPerMessage = 2;
- int maxReadPoolSize;
- int maxWritePoolSize;
- static UriGenerator mimeBoundaryGenerator;
- XmlDictionaryReaderQuotas readerQuotas;
- XmlDictionaryReaderQuotas bufferedReadReaderQuotas;
- int maxBufferSize;
- OnXmlDictionaryReaderClose onStreamedReaderClose;
- internal TextMessageEncoderFactory.ContentEncoding[] contentEncodingMap;
- const string mtomMediaType = "multipart/related";
- const string mtomContentType = mtomMediaType + "; type=\"application/xop+xml\"";
- const string mtomStartUri = NamingHelper.DefaultNamespace + "0";
- public MtomMessageEncoder(MessageVersion version, Encoding writeEncoding, int maxReadPoolSize, int maxWritePoolSize, int maxBufferSize, XmlDictionaryReaderQuotas quotas)
- {
- if (version == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
- if (writeEncoding == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writeEncoding");
- TextEncoderDefaults.ValidateEncoding(writeEncoding);
- this.writeEncoding = writeEncoding;
- this.maxReadPoolSize = maxReadPoolSize;
- this.maxWritePoolSize = maxWritePoolSize;
- this.readerQuotas = new XmlDictionaryReaderQuotas();
- quotas.CopyTo(this.readerQuotas);
- this.bufferedReadReaderQuotas = EncoderHelpers.GetBufferedReadQuotas(this.readerQuotas);
- this.maxBufferSize = maxBufferSize;
- this.onStreamedReaderClose = new OnXmlDictionaryReaderClose(ReturnStreamedReader);
- this.thisLock = new object();
- if (version.Envelope == EnvelopeVersion.Soap12)
- {
- this.contentEncodingMap = TextMessageEncoderFactory.Soap12Content;
- }
- else if (version.Envelope == EnvelopeVersion.Soap11)
- {
- this.contentEncodingMap = TextMessageEncoderFactory.Soap11Content;
- }
- else
- {
- Fx.Assert("Invalid MessageVersion");
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid MessageVersion")));
- }
- this.version = version;
- }
- static UriGenerator MimeBoundaryGenerator
- {
- get
- {
- if (mimeBoundaryGenerator == null)
- mimeBoundaryGenerator = new UriGenerator("uuid", "+");
- return mimeBoundaryGenerator;
- }
- }
- public override string ContentType
- {
- get { return mtomContentType; }
- }
- public int MaxWritePoolSize
- {
- get { return maxWritePoolSize; }
- }
- public int MaxReadPoolSize
- {
- get { return maxReadPoolSize; }
- }
- public XmlDictionaryReaderQuotas ReaderQuotas
- {
- get
- {
- return readerQuotas;
- }
- }
- public int MaxBufferSize
- {
- get { return maxBufferSize; }
- }
- public override string MediaType
- {
- get { return mtomMediaType; }
- }
- public override MessageVersion MessageVersion
- {
- get { return version; }
- }
- internal bool IsMTOMContentType(string contentType)
- {
- // check for MTOM contentType: multipart/related; type=\"application/xop+xml\"
- return IsContentTypeSupported(contentType, this.ContentType, this.MediaType);
- }
- internal bool IsTextContentType(string contentType)
- {
- // check for Text contentType: text/xml or application/soap+xml
- string textMediaType = TextMessageEncoderFactory.GetMediaType(version);
- string textContentType = TextMessageEncoderFactory.GetContentType(textMediaType, writeEncoding);
- return IsContentTypeSupported(contentType, textContentType, textMediaType);
- }
- public override bool IsContentTypeSupported(string contentType)
- {
- if (contentType == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("contentType"));
- return (IsMTOMContentType(contentType) || IsTextContentType(contentType));
- }
- internal override bool IsCharSetSupported(string charSet)
- {
- if (charSet == null || charSet.Length == 0)
- return true;
- Encoding tmp;
- return TextEncoderDefaults.TryGetEncoding(charSet, out tmp);
- }
- string GenerateStartInfoString()
- {
- return (version.Envelope == EnvelopeVersion.Soap12) ? TextMessageEncoderFactory.Soap12MediaType : TextMessageEncoderFactory.Soap11MediaType;
- }
- public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
- {
- if (bufferManager == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bufferManager");
- if (contentType == this.ContentType)
- contentType = null;
- if (TD.MtomMessageDecodingStartIsEnabled())
- {
- TD.MtomMessageDecodingStart();
- }
- MtomBufferedMessageData messageData = TakeBufferedReader();
- messageData.ContentType = contentType;
- messageData.Open(buffer, bufferManager);
- RecycledMessageState messageState = messageData.TakeMessageState();
- if (messageState == null)
- messageState = new RecycledMessageState();
- Message message = new BufferedMessage(messageData, messageState);
- message.Properties.Encoder = this;
- if (MessageLogger.LogMessagesAtTransportLevel)
- MessageLogger.LogMessage(ref message, MessageLoggingSource.TransportReceive);
- if (TD.MessageReadByEncoderIsEnabled() && buffer != null)
- {
- TD.MessageReadByEncoder(
- EventTraceActivityHelper.TryExtractActivity(message, true),
- buffer.Count,
- this);
- }
- return message;
- }
- public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
- {
- if (stream == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream"));
- if (contentType == this.ContentType)
- contentType = null;
- if (TD.MtomMessageDecodingStartIsEnabled())
- {
- TD.MtomMessageDecodingStart();
- }
- XmlReader reader = TakeStreamedReader(stream, contentType);
- Message message = Message.CreateMessage(reader, maxSizeOfHeaders, version);
- message.Properties.Encoder = this;
- if (TD.StreamedMessageReadByEncoderIsEnabled())
- {
- TD.StreamedMessageReadByEncoder(EventTraceActivityHelper.TryExtractActivity(message, true));
- }
- if (MessageLogger.LogMessagesAtTransportLevel)
- MessageLogger.LogMessage(ref message, MessageLoggingSource.TransportReceive);
- return message;
- }
- public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
- {
- return WriteMessage(message, maxMessageSize, bufferManager, messageOffset, GenerateStartInfoString(), null, null, true /*writeMessageHeaders*/);
- }
- internal string GetContentType(out string boundary)
- {
- string startInfo = GenerateStartInfoString();
- boundary = MimeBoundaryGenerator.Next();
- return FormatContentType(boundary, startInfo);
- }
- internal string FormatContentType(string boundary, string startInfo)
- {
- return String.Format(CultureInfo.InvariantCulture,
- "{0};start=\"<{1}>\";boundary=\"{2}\";start-info=\"{3}\"",
- mtomContentType, mtomStartUri, boundary, startInfo);
- }
- internal ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset, string boundary)
- {
- return WriteMessage(message, maxMessageSize, bufferManager, messageOffset, GenerateStartInfoString(), boundary, mtomStartUri, false /*writeMessageHeaders*/);
- }
- ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset, string startInfo, string boundary, string startUri, bool writeMessageHeaders)
- {
- if (message == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
- if (bufferManager == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bufferManager");
- if (maxMessageSize < 0)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxMessageSize", maxMessageSize,
- SR.GetString(SR.ValueMustBeNonNegative)));
- if (messageOffset < 0 || messageOffset > maxMessageSize)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("messageOffset", messageOffset,
- SR.GetString(SR.ValueMustBeInRange, 0, maxMessageSize)));
- ThrowIfMismatchedMessageVersion(message);
- EventTraceActivity eventTraceActivity = null;
- if (TD.MtomMessageEncodingStartIsEnabled())
- {
- eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message);
- TD.MtomMessageEncodingStart(eventTraceActivity);
- }
- message.Properties.Encoder = this;
- MtomBufferedMessageWriter messageWriter = TakeBufferedWriter();
- messageWriter.StartInfo = startInfo;
- messageWriter.Boundary = boundary;
- messageWriter.StartUri = startUri;
- messageWriter.WriteMessageHeaders = writeMessageHeaders;
- messageWriter.MaxSizeInBytes = maxMessageSize;
- ArraySegment<byte> messageData = messageWriter.WriteMessage(message, bufferManager, messageOffset, maxMessageSize);
- ReturnMessageWriter(messageWriter);
- if (TD.MessageWrittenByEncoderIsEnabled() && messageData != null)
- {
- TD.MessageWrittenByEncoder(
- eventTraceActivity ?? EventTraceActivityHelper.TryExtractActivity(message),
- messageData.Count,
- this);
- }
- if (MessageLogger.LogMessagesAtTransportLevel)
- {
- string contentType = null;
- if (boundary != null)
- contentType = FormatContentType(boundary, startInfo ?? GenerateStartInfoString());
- XmlDictionaryReader xmlDictionaryReader = XmlDictionaryReader.CreateMtomReader(messageData.Array, messageData.Offset, messageData.Count, MtomMessageEncoderFactory.GetSupportedEncodings(), contentType, XmlDictionaryReaderQuotas.Max, int.MaxValue, null);
- MessageLogger.LogMessage(ref message, xmlDictionaryReader, MessageLoggingSource.TransportSend);
- }
- return messageData;
- }
- public override void WriteMessage(Message message, Stream stream)
- {
- WriteMessage(message, stream, GenerateStartInfoString(), null, null, true /*writeMessageHeaders*/);
- }
- internal void WriteMessage(Message message, Stream stream, string boundary)
- {
- WriteMessage(message, stream, GenerateStartInfoString(), boundary, mtomStartUri, false /*writeMessageHeaders*/);
- }
- public override IAsyncResult BeginWriteMessage(Message message, Stream stream, AsyncCallback callback, object state)
- {
- return new WriteMessageAsyncResult(message, stream, this, callback, state);
- }
- internal IAsyncResult BeginWriteMessage(Message message, Stream stream, string boundary, AsyncCallback callback, object state)
- {
- return new WriteMessageAsyncResult(message, stream, boundary, this, callback, state);
- }
- public override void EndWriteMessage(IAsyncResult result)
- {
- WriteMessageAsyncResult.End(result);
- }
- void WriteMessage(Message message, Stream stream, string startInfo, string boundary, string startUri, bool writeMessageHeaders)
- {
- if (message == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("message"));
- if (stream == null)
- throw TraceUtility.ThrowHelperError(new ArgumentNullException("stream"), message);
- ThrowIfMismatchedMessageVersion(message);
- EventTraceActivity eventTraceActivity = null;
- if (TD.MtomMessageEncodingStartIsEnabled())
- {
- eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message);
- TD.MtomMessageEncodingStart(eventTraceActivity);
- }
- message.Properties.Encoder = this;
- if (MessageLogger.LogMessagesAtTransportLevel)
- MessageLogger.LogMessage(ref message, MessageLoggingSource.TransportSend);
- XmlDictionaryWriter xmlWriter = TakeStreamedWriter(stream, startInfo, boundary, startUri, writeMessageHeaders);
- if (this.writeEncoding.WebName == "utf-8")
- {
- message.WriteMessage(xmlWriter);
- }
- else
- {
- xmlWriter.WriteStartDocument();
- message.WriteMessage(xmlWriter);
- xmlWriter.WriteEndDocument();
- }
- xmlWriter.Flush();
- ReturnStreamedWriter(xmlWriter);
- if (TD.StreamedMessageWrittenByEncoderIsEnabled())
- {
- TD.StreamedMessageWrittenByEncoder(eventTraceActivity ?? EventTraceActivityHelper.TryExtractActivity(message));
- }
- }
- XmlDictionaryWriter TakeStreamedWriter(Stream stream, string startInfo, string boundary, string startUri, bool writeMessageHeaders)
- {
- if (streamedWriterPool == null)
- {
- lock (thisLock)
- {
- if (streamedWriterPool == null)
- {
- streamedWriterPool = new SynchronizedPool<XmlDictionaryWriter>(maxWritePoolSize);
- }
- }
- }
- XmlDictionaryWriter xmlWriter = streamedWriterPool.Take();
- if (xmlWriter == null)
- {
- xmlWriter = XmlDictionaryWriter.CreateMtomWriter(stream, this.writeEncoding, int.MaxValue, startInfo, boundary, startUri, writeMessageHeaders, false);
- if (TD.WritePoolMissIsEnabled())
- {
- TD.WritePoolMiss(xmlWriter.GetType().Name);
- }
- }
- else
- {
- ((IXmlMtomWriterInitializer)xmlWriter).SetOutput(stream, this.writeEncoding, int.MaxValue, startInfo, boundary, startUri, writeMessageHeaders, false);
- }
- return xmlWriter;
- }
- void ReturnStreamedWriter(XmlDictionaryWriter xmlWriter)
- {
- xmlWriter.Close();
- streamedWriterPool.Return(xmlWriter);
- }
- MtomBufferedMessageWriter TakeBufferedWriter()
- {
- if (bufferedWriterPool == null)
- {
- lock (thisLock)
- {
- if (bufferedWriterPool == null)
- {
- bufferedWriterPool = new SynchronizedPool<MtomBufferedMessageWriter>(maxWritePoolSize);
- }
- }
- }
- MtomBufferedMessageWriter messageWriter = bufferedWriterPool.Take();
- if (messageWriter == null)
- {
- messageWriter = new MtomBufferedMessageWriter(this);
- if (TD.WritePoolMissIsEnabled())
- {
- TD.WritePoolMiss(messageWriter.GetType().Name);
- }
- }
- return messageWriter;
- }
- void ReturnMessageWriter(MtomBufferedMessageWriter messageWriter)
- {
- bufferedWriterPool.Return(messageWriter);
- }
- MtomBufferedMessageData TakeBufferedReader()
- {
- if (bufferedReaderPool == null)
- {
- lock (thisLock)
- {
- if (bufferedReaderPool == null)
- {
- bufferedReaderPool = new SynchronizedPool<MtomBufferedMessageData>(maxReadPoolSize);
- }
- }
- }
- MtomBufferedMessageData messageData = bufferedReaderPool.Take();
- if (messageData == null)
- {
- messageData = new MtomBufferedMessageData(this, maxPooledXmlReadersPerMessage);
- if (TD.ReadPoolMissIsEnabled())
- {
- TD.ReadPoolMiss(messageData.GetType().Name);
- }
- }
- return messageData;
- }
- void ReturnBufferedData(MtomBufferedMessageData messageData)
- {
- bufferedReaderPool.Return(messageData);
- }
- XmlReader TakeStreamedReader(Stream stream, string contentType)
- {
- if (streamedReaderPool == null)
- {
- lock (thisLock)
- {
- if (streamedReaderPool == null)
- {
- streamedReaderPool = new SynchronizedPool<XmlDictionaryReader>(maxReadPoolSize);
- }
- }
- }
- XmlDictionaryReader xmlReader = streamedReaderPool.Take();
- try
- {
- if (contentType == null || IsMTOMContentType(contentType))
- {
- if (xmlReader != null && xmlReader is IXmlMtomReaderInitializer)
- {
- ((IXmlMtomReaderInitializer)xmlReader).SetInput(stream, MtomMessageEncoderFactory.GetSupportedEncodings(), contentType, this.readerQuotas, this.maxBufferSize, onStreamedReaderClose);
- }
- else
- {
- xmlReader = XmlDictionaryReader.CreateMtomReader(stream, MtomMessageEncoderFactory.GetSupportedEncodings(), contentType, this.readerQuotas, this.maxBufferSize, onStreamedReaderClose);
- if (TD.ReadPoolMissIsEnabled())
- {
- TD.ReadPoolMiss(xmlReader.GetType().Name);
- }
- }
- }
- else
- {
- if (xmlReader != null && xmlReader is IXmlTextReaderInitializer)
- {
- ((IXmlTextReaderInitializer)xmlReader).SetInput(stream, TextMessageEncoderFactory.GetEncodingFromContentType(contentType, this.contentEncodingMap), this.readerQuotas, onStreamedReaderClose);
- }
- else
- {
- xmlReader = XmlDictionaryReader.CreateTextReader(stream, TextMessageEncoderFactory.GetEncodingFromContentType(contentType, this.contentEncodingMap), this.readerQuotas, onStreamedReaderClose);
- if (TD.ReadPoolMissIsEnabled())
- {
- TD.ReadPoolMiss(xmlReader.GetType().Name);
- }
- }
- }
- }
- catch (FormatException fe)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
- SR.GetString(SR.SFxErrorCreatingMtomReader), fe));
- }
- catch (XmlException xe)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
- SR.GetString(SR.SFxErrorCreatingMtomReader), xe));
- }
- return xmlReader;
- }
- void ReturnStreamedReader(XmlDictionaryReader xmlReader)
- {
- streamedReaderPool.Return(xmlReader);
- }
- SynchronizedPool<RecycledMessageState> RecycledStatePool
- {
- get
- {
- if (recycledStatePool == null)
- {
- lock (thisLock)
- {
- if (recycledStatePool == null)
- {
- recycledStatePool = new SynchronizedPool<RecycledMessageState>(maxReadPoolSize);
- }
- }
- }
- return recycledStatePool;
- }
- }
- string ITraceSourceStringProvider.GetSourceString()
- {
- return base.GetTraceSourceString();
- }
- class MtomBufferedMessageData : BufferedMessageData
- {
- MtomMessageEncoder messageEncoder;
- Pool<XmlDictionaryReader> readerPool;
- internal string ContentType;
- OnXmlDictionaryReaderClose onClose;
- public MtomBufferedMessageData(MtomMessageEncoder messageEncoder, int maxReaderPoolSize)
- : base(messageEncoder.RecycledStatePool)
- {
- this.messageEncoder = messageEncoder;
- readerPool = new Pool<XmlDictionaryReader>(maxReaderPoolSize);
- onClose = new OnXmlDictionaryReaderClose(OnXmlReaderClosed);
- }
- public override MessageEncoder MessageEncoder
- {
- get { return messageEncoder; }
- }
- public override XmlDictionaryReaderQuotas Quotas
- {
- get { return messageEncoder.bufferedReadReaderQuotas; }
- }
- protected override void OnClosed()
- {
- messageEncoder.ReturnBufferedData(this);
- }
- protected override XmlDictionaryReader TakeXmlReader()
- {
- try
- {
- ArraySegment<byte> buffer = this.Buffer;
- XmlDictionaryReader xmlReader = readerPool.Take();
- if (ContentType == null || messageEncoder.IsMTOMContentType(ContentType))
- {
- if (xmlReader != null && xmlReader is IXmlMtomReaderInitializer)
- {
- ((IXmlMtomReaderInitializer)xmlReader).SetInput(buffer.Array, buffer.Offset, buffer.Count, MtomMessageEncoderFactory.GetSupportedEncodings(), ContentType, this.Quotas, this.messageEncoder.MaxBufferSize, onClose);
- }
- else
- {
- xmlReader = XmlDictionaryReader.CreateMtomReader(buffer.Array, buffer.Offset, buffer.Count, MtomMessageEncoderFactory.GetSupportedEncodings(), ContentType, this.Quotas, this.messageEncoder.MaxBufferSize, onClose);
- if (TD.ReadPoolMissIsEnabled())
- {
- TD.ReadPoolMiss(xmlReader.GetType().Name);
- }
- }
- }
- else
- {
- if (xmlReader != null && xmlReader is IXmlTextReaderInitializer)
- {
- ((IXmlTextReaderInitializer)xmlReader).SetInput(buffer.Array, buffer.Offset, buffer.Count, TextMessageEncoderFactory.GetEncodingFromContentType(ContentType, this.messageEncoder.contentEncodingMap), this.Quotas, onClose);
- }
- else
- {
- xmlReader = XmlDictionaryReader.CreateTextReader(buffer.Array, buffer.Offset, buffer.Count, TextMessageEncoderFactory.GetEncodingFromContentType(ContentType, this.messageEncoder.contentEncodingMap), this.Quotas, onClose);
- if (TD.ReadPoolMissIsEnabled())
- {
- TD.ReadPoolMiss(xmlReader.GetType().Name);
- }
- }
- }
- return xmlReader;
- }
- catch (FormatException fe)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
- SR.GetString(SR.SFxErrorCreatingMtomReader), fe));
- }
- catch (XmlException xe)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
- SR.GetString(SR.SFxErrorCreatingMtomReader), xe));
- }
- }
- protected override void ReturnXmlReader(XmlDictionaryReader xmlReader)
- {
- if (xmlReader != null)
- readerPool.Return(xmlReader);
- }
- }
- class MtomBufferedMessageWriter : BufferedMessageWriter
- {
- MtomMessageEncoder messageEncoder;
- internal bool WriteMessageHeaders;
- internal string StartInfo;
- internal string StartUri;
- internal string Boundary;
- internal int MaxSizeInBytes = int.MaxValue;
- XmlDictionaryWriter writer;
- public MtomBufferedMessageWriter(MtomMessageEncoder messageEncoder)
- {
- this.messageEncoder = messageEncoder;
- }
- protected override XmlDictionaryWriter TakeXmlWriter(Stream stream)
- {
- XmlDictionaryWriter returnedWriter = writer;
- if (returnedWriter == null)
- {
- returnedWriter = XmlDictionaryWriter.CreateMtomWriter(stream, messageEncoder.writeEncoding, MaxSizeInBytes, StartInfo, Boundary, StartUri, WriteMessageHeaders, false);
- }
- else
- {
- writer = null;
- ((IXmlMtomWriterInitializer)returnedWriter).SetOutput(stream, messageEncoder.writeEncoding, MaxSizeInBytes, StartInfo, Boundary, StartUri, WriteMessageHeaders, false);
- }
- if (messageEncoder.writeEncoding.WebName != "utf-8")
- returnedWriter.WriteStartDocument();
- return returnedWriter;
- }
- protected override void ReturnXmlWriter(XmlDictionaryWriter writer)
- {
- writer.Close();
- if (this.writer == null)
- this.writer = writer;
- }
- }
- class WriteMessageAsyncResult : ScheduleActionItemAsyncResult
- {
- string boundary;
- MtomMessageEncoder encoder;
- Message message;
- Stream stream;
- bool writeBoundary;
- public WriteMessageAsyncResult(Message message, Stream stream, MtomMessageEncoder encoder, AsyncCallback callback, object state)
- : base(callback, state)
- {
- Fx.Assert(encoder != null, "encoder should never be null");
- this.encoder = encoder;
- this.message = message;
- this.stream = stream;
- Schedule();
- }
- public WriteMessageAsyncResult(Message message, Stream stream, string boundary, MtomMessageEncoder encoder, AsyncCallback callback, object state)
- : base(callback, state)
- {
- Fx.Assert(encoder != null, "encoder should never be null");
- this.encoder = encoder;
- this.message = message;
- this.stream = stream;
- this.boundary = boundary;
- this.writeBoundary = true;
- Schedule();
- }
- protected override void OnDoWork()
- {
- this.encoder.WriteMessage(this.message, this.stream, this.encoder.GenerateStartInfoString(), string.IsNullOrEmpty(this.boundary) ? null : this.boundary, this.writeBoundary ? MtomMessageEncoder.mtomStartUri : null, !this.writeBoundary /*writeMessageHeaders*/);
- }
- }
- }
- }
|