Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / MtomMessageEncoder.cs / 1 / MtomMessageEncoder.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.IO; using System.ServiceModel.Description; using System.Collections.Generic; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Diagnostics; using System.Text; using System.Xml; using System.Globalization; using System.Threading; 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 { Encoding writeEncoding; SynchronizedPoolstreamedWriterPool; SynchronizedPool streamedReaderPool; SynchronizedPool bufferedReaderPool; SynchronizedPool bufferedWriterPool; SynchronizedPool recycledStatePool; object thisLock; MessageVersion version; const int maxPooledXmlReadersPerMessage = 2; int maxReadPoolSize; int maxWritePoolSize; static UriGenerator mimeBoundaryGenerator; XmlDictionaryReaderQuotas readerQuotas; 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.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 { DiagnosticUtility.DebugAssert("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 buffer, BufferManager bufferManager, string contentType) { if (bufferManager == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bufferManager"); if (contentType == this.ContentType) contentType = null; 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); 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; XmlReader reader = TakeStreamedReader(stream, contentType); Message message = Message.CreateMessage(reader, maxSizeOfHeaders, version); message.Properties.Encoder = this; if (MessageLogger.LogMessagesAtTransportLevel) MessageLogger.LogMessage(ref message, MessageLoggingSource.TransportReceive); return message; } public override ArraySegment 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 WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset, string boundary) { return WriteMessage(message, maxMessageSize, bufferManager, messageOffset, GenerateStartInfoString(), boundary, mtomStartUri, false /*writeMessageHeaders*/); } ArraySegment 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); message.Properties.Encoder = this; MtomBufferedMessageWriter messageWriter = TakeBufferedWriter(); messageWriter.StartInfo = startInfo; messageWriter.Boundary = boundary; messageWriter.StartUri = startUri; messageWriter.WriteMessageHeaders = writeMessageHeaders; messageWriter.MaxSizeInBytes = maxMessageSize; ArraySegment messageData = messageWriter.WriteMessage(message, bufferManager, messageOffset, maxMessageSize); ReturnMessageWriter(messageWriter); 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*/); } 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); 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); } XmlDictionaryWriter TakeStreamedWriter(Stream stream, string startInfo, string boundary, string startUri, bool writeMessageHeaders) { if (streamedWriterPool == null) { lock (thisLock) { if (streamedWriterPool == null) { streamedWriterPool = new SynchronizedPool (maxWritePoolSize); } } } XmlDictionaryWriter xmlWriter = streamedWriterPool.Take(); if (xmlWriter == null) { xmlWriter = XmlDictionaryWriter.CreateMtomWriter(stream, this.writeEncoding, int.MaxValue, startInfo, boundary, startUri, writeMessageHeaders, false); } 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 (maxWritePoolSize); } } } MtomBufferedMessageWriter messageWriter = bufferedWriterPool.Take(); if (messageWriter == null) messageWriter = new MtomBufferedMessageWriter(this); return messageWriter; } void ReturnMessageWriter(MtomBufferedMessageWriter messageWriter) { bufferedWriterPool.Return(messageWriter); } MtomBufferedMessageData TakeBufferedReader() { if (bufferedReaderPool == null) { lock (thisLock) { if (bufferedReaderPool == null) { bufferedReaderPool = new SynchronizedPool (maxReadPoolSize); } } } MtomBufferedMessageData messageData = bufferedReaderPool.Take(); if (messageData == null) messageData = new MtomBufferedMessageData(this, maxPooledXmlReadersPerMessage); 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 (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); } } 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); } } } 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 RecycledStatePool { get { if (recycledStatePool == null) { lock (thisLock) { if (recycledStatePool == null) { recycledStatePool = new SynchronizedPool (maxReadPoolSize); } } } return recycledStatePool; } } class MtomBufferedMessageData : BufferedMessageData { MtomMessageEncoder messageEncoder; Pool readerPool; internal string ContentType; OnXmlDictionaryReaderClose onClose; public MtomBufferedMessageData(MtomMessageEncoder messageEncoder, int maxReaderPoolSize) : base(messageEncoder.RecycledStatePool) { this.messageEncoder = messageEncoder; readerPool = new Pool (maxReaderPoolSize); onClose = new OnXmlDictionaryReaderClose(OnXmlReaderClosed); } public override MessageEncoder MessageEncoder { get { return messageEncoder; } } public override XmlDictionaryReaderQuotas Quotas { get { return messageEncoder.ReaderQuotas; } } protected override void OnClosed() { messageEncoder.ReturnBufferedData(this); } protected override XmlDictionaryReader TakeXmlReader() { try { ArraySegment 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.messageEncoder.ReaderQuotas, this.messageEncoder.MaxBufferSize, onClose); } else { xmlReader = XmlDictionaryReader.CreateMtomReader(buffer.Array, buffer.Offset, buffer.Count, MtomMessageEncoderFactory.GetSupportedEncodings(), ContentType, this.messageEncoder.ReaderQuotas, this.messageEncoder.MaxBufferSize, onClose); } } else { if (xmlReader != null && xmlReader is IXmlTextReaderInitializer) { ((IXmlTextReaderInitializer)xmlReader).SetInput(buffer.Array, buffer.Offset, buffer.Count, TextMessageEncoderFactory.GetEncodingFromContentType(ContentType, this.messageEncoder.contentEncodingMap), this.messageEncoder.ReaderQuotas, onClose); } else { xmlReader = XmlDictionaryReader.CreateTextReader(buffer.Array, buffer.Offset, buffer.Count, TextMessageEncoderFactory.GetEncodingFromContentType(ContentType, this.messageEncoder.contentEncodingMap), this.messageEncoder.ReaderQuotas, onClose); } } 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; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RectIndependentAnimationStorage.cs
- SerTrace.cs
- JpegBitmapDecoder.cs
- ThicknessKeyFrameCollection.cs
- ControlBuilder.cs
- InteropExecutor.cs
- Simplifier.cs
- HashMembershipCondition.cs
- DataObject.cs
- RemoteWebConfigurationHostServer.cs
- DragSelectionMessageFilter.cs
- Exceptions.cs
- DataSourceProvider.cs
- ClientScriptItemCollection.cs
- FixedPage.cs
- Win32NamedPipes.cs
- basenumberconverter.cs
- CodeDirectoryCompiler.cs
- UnsafeMethods.cs
- Size3DConverter.cs
- XmlSchemaGroupRef.cs
- HttpCacheVaryByContentEncodings.cs
- CustomError.cs
- AbsoluteQuery.cs
- CellCreator.cs
- DynamicValueConverter.cs
- StringComparer.cs
- DesignerHelpers.cs
- MimeParameter.cs
- CodeCompiler.cs
- MinMaxParagraphWidth.cs
- WebServiceClientProxyGenerator.cs
- WrappedIUnknown.cs
- WebZone.cs
- TemplateControlBuildProvider.cs
- DeploymentSection.cs
- UxThemeWrapper.cs
- WeakEventTable.cs
- IsolationInterop.cs
- XsltContext.cs
- NetworkAddressChange.cs
- ScriptComponentDescriptor.cs
- ToolStripItem.cs
- SecureUICommand.cs
- BoolLiteral.cs
- DataServiceBehavior.cs
- XmlSchemaResource.cs
- WriteTimeStream.cs
- UrlMappingCollection.cs
- Attributes.cs
- CacheRequest.cs
- WebCategoryAttribute.cs
- Italic.cs
- XmlDataImplementation.cs
- EditBehavior.cs
- PolyBezierSegment.cs
- FormsAuthenticationEventArgs.cs
- ReferenceEqualityComparer.cs
- ListItemCollection.cs
- UpdateProgress.cs
- FlowDocumentView.cs
- CodeTypeParameter.cs
- SecurityManager.cs
- _UncName.cs
- DeobfuscatingStream.cs
- __FastResourceComparer.cs
- ConfigurationLocationCollection.cs
- XmlSchemaAnyAttribute.cs
- NavigationEventArgs.cs
- ClientScriptManager.cs
- DSASignatureFormatter.cs
- _BasicClient.cs
- PropertySegmentSerializer.cs
- StrokeDescriptor.cs
- DataGridDetailsPresenterAutomationPeer.cs
- SerTrace.cs
- NumberFormatter.cs
- RulePatternOps.cs
- XmlWriterTraceListener.cs
- DesignTimeTemplateParser.cs
- AsymmetricKeyExchangeDeformatter.cs
- RtfFormatStack.cs
- CharStorage.cs
- TypeBuilder.cs
- SiteMapNodeItem.cs
- FindSimilarActivitiesVerb.cs
- DataViewListener.cs
- DragCompletedEventArgs.cs
- HostVisual.cs
- FileUtil.cs
- StartUpEventArgs.cs
- QueryExtender.cs
- KeyEvent.cs
- BindToObject.cs
- ContentPosition.cs
- PropertyKey.cs
- MultiDataTrigger.cs
- XmlDataDocument.cs
- InkCollectionBehavior.cs
- SvcFileManager.cs