StreamFormatter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / StreamFormatter.cs / 1 / StreamFormatter.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{ 
    using System.Collections;
    using System.ServiceModel; 
    using System.ServiceModel.Description; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.Diagnostics;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Reflection; 
    using System.Xml;
    using System.ServiceModel.Diagnostics; 
    using System.ServiceModel.Channels; 

 
    class StreamFormatter
    {
        string wrapperName;
        string wrapperNS; 
        string partName;
        string partNS; 
        int streamIndex; 
        bool isRequest;
        string operationName; 
        const int returnValueIndex = -1;

        internal static StreamFormatter Create(MessageDescription messageDescription, string operationName, bool isRequest)
        { 
            MessagePartDescription streamPart = ValidateAndGetStreamPart(messageDescription, isRequest, operationName);
            if (streamPart == null) 
                return null; 
            return new StreamFormatter(messageDescription, streamPart, operationName, isRequest);
        } 

        StreamFormatter(MessageDescription messageDescription, MessagePartDescription streamPart, string operationName, bool isRequest)
        {
            if((object)streamPart == (object)messageDescription.Body.ReturnValue) 
                this.streamIndex = returnValueIndex;
            else 
                this.streamIndex = streamPart.Index; 
            wrapperName = messageDescription.Body.WrapperName;
            wrapperNS = messageDescription.Body.WrapperNamespace; 
            partName = streamPart.Name;
            partNS = streamPart.Namespace;
            this.isRequest = isRequest;
            this.operationName = operationName; 
        }
 
        internal void Serialize(XmlDictionaryWriter writer, object[] parameters, object returnValue) 
        {
            Stream streamValue = GetStreamValue(parameters, returnValue); 
            if (streamValue == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(partName);
            if (WrapperName != null)
                writer.WriteStartElement(WrapperName, WrapperNamespace); 
            writer.WriteStartElement(PartName, PartNamespace);
            writer.WriteValue(new OperationStreamProvider(streamValue)); 
            writer.WriteEndElement(); 
            if (wrapperName != null)
                writer.WriteEndElement(); 
        }

        internal void Deserialize(object[] parameters, ref object retVal, Message message)
        { 
            SetStreamValue(parameters, ref retVal, new MessageBodyStream(message, WrapperName, WrapperNamespace, PartName, PartNamespace, isRequest));
        } 
 
        internal string WrapperName
        { 
            get { return wrapperName; }
            set { wrapperName = value; }
        }
 
        internal string WrapperNamespace
        { 
            get { return wrapperNS; } 
            set { wrapperNS = value; }
        } 

        internal string PartName
        {
            get { return partName; } 
        }
 
        internal string PartNamespace 
        {
            get { return partNS; } 
        }


        Stream GetStreamValue(object[] parameters, object returnValue) 
        {
            if (streamIndex == returnValueIndex) 
                return (Stream)returnValue; 
            return (Stream)parameters[streamIndex];
        } 

        void SetStreamValue(object[] parameters, ref object returnValue, Stream streamValue)
        {
            if (streamIndex == returnValueIndex) 
                returnValue = streamValue;
            else 
                parameters[streamIndex] = streamValue; 
        }
 
        static MessagePartDescription ValidateAndGetStreamPart(MessageDescription messageDescription, bool isRequest, string operationName)
        {
            MessagePartDescription part = GetStreamPart(messageDescription);
            if (part != null) 
                return part;
            if (HasStream(messageDescription)) 
            { 
                if (messageDescription.IsTypedMessage)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidStreamInTypedMessage, messageDescription.MessageName))); 
                else if (isRequest)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidStreamInRequest, operationName)));
                else
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidStreamInResponse, operationName))); 
            }
            return null; 
        } 

        private static bool HasStream(MessageDescription messageDescription) 
        {
            if (messageDescription.Body.ReturnValue != null && messageDescription.Body.ReturnValue.Type == typeof(Stream))
                return true;
            foreach (MessagePartDescription part in messageDescription.Body.Parts) 
            {
                if (part.Type == typeof(Stream)) 
                    return true; 
            }
            return false; 
        }

        static MessagePartDescription GetStreamPart(MessageDescription messageDescription)
        { 
            if (OperationFormatter.IsValidReturnValue(messageDescription.Body.ReturnValue))
            { 
                if (messageDescription.Body.Parts.Count == 0) 
                    if (messageDescription.Body.ReturnValue.Type == typeof(Stream))
                        return messageDescription.Body.ReturnValue; 
            }
            else
            {
                if (messageDescription.Body.Parts.Count == 1) 
                    if (messageDescription.Body.Parts[0].Type == typeof(Stream))
                        return messageDescription.Body.Parts[0]; 
            } 
            return null;
        } 

        internal static bool IsStream(MessageDescription messageDescription)
        {
            return GetStreamPart(messageDescription) != null; 
        }
 
        internal class MessageBodyStream : Stream 
        {
            Message message; 
            XmlDictionaryReader reader;
            long position;
            string wrapperName, wrapperNs;
            string elementName, elementNs; 
            bool isRequest;
            internal MessageBodyStream(Message message, string wrapperName, string wrapperNs, string elementName, string elementNs, bool isRequest) 
            { 
                this.message = message;
                this.position = 0; 
                this.wrapperName = wrapperName;
                this.wrapperNs = wrapperNs;
                this.elementName = elementName;
                this.elementNs = elementNs; 
                this.isRequest = isRequest;
            } 
 
            public override int Read(byte[] buffer, int offset, int count)
            { 
                EnsureStreamIsOpen();
                if (buffer == null)
                    throw TraceUtility.ThrowHelperError(new ArgumentNullException("buffer"), this.message);
                if (offset < 0) 
                    throw TraceUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", offset,
                                                    SR.GetString(SR.ValueMustBeNonNegative)), this.message); 
                if (count < 0) 
                    throw TraceUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", count,
                                                    SR.GetString(SR.ValueMustBeNonNegative)), this.message); 
                if (buffer.Length - offset < count)
                    throw TraceUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFxInvalidStreamOffsetLength, offset + count)), this.message);

                try 
                {
 
                    if (reader == null) 
                    {
                        reader = message.GetReaderAtBodyContents(); 
                        if (wrapperName != null)
                        {
                            reader.MoveToContent();
                            reader.ReadStartElement(wrapperName, wrapperNs); 
                        }
                        reader.MoveToContent(); 
                        if (reader.NodeType == XmlNodeType.EndElement) 
                        {
                            return 0; 
                        }

                        reader.ReadStartElement(elementName, elementNs);
                    } 
                    if (reader.MoveToContent() != XmlNodeType.Text)
                    { 
                        Exhaust(reader); 
                        return 0;
                    } 
                    int bytesRead = reader.ReadContentAsBase64(buffer, offset, count);
                    position += bytesRead;
                    if (bytesRead == 0)
                    { 
                        Exhaust(reader);
                    } 
                    return bytesRead; 
                }
                catch (Exception ex) 
                {
                    if (DiagnosticUtility.IsFatal(ex))
                        throw;
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new IOException(SR.GetString(SR.SFxStreamIOException), ex)); 
                }
            } 
 
            private void EnsureStreamIsOpen()
            { 
                if (message.State == MessageState.Closed)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(SR.GetString(
                        isRequest ? SR.SFxStreamRequestMessageClosed : SR.SFxStreamResponseMessageClosed)));
            } 

            static void Exhaust(XmlDictionaryReader reader) 
            { 
                if (reader != null)
                { 
                    while (reader.Read())
                    {
                        // drain
                    } 
                }
            } 
 
            public override long Position
            { 
                get
                {
                    EnsureStreamIsOpen();
                    return position; 
                }
                set { throw TraceUtility.ThrowHelperError(new NotSupportedException(), message); } 
            } 

            public override void Close() 
            {
                message.Close();
                if (reader != null)
                { 
                    reader.Close();
                    reader = null; 
                } 
                base.Close();
            } 
            public override bool CanRead { get { return message.State != MessageState.Closed; } }
            public override bool CanSeek { get { return false; } }
            public override bool CanWrite { get { return false; } }
            public override long Length 
            {
                get 
                { 
#pragma warning suppress 56503 // [....], not a seekable stream, it is ok to throw NotSupported in this case
                    throw TraceUtility.ThrowHelperError(new NotSupportedException(), this.message); 
                }
            }
            public override void Flush() { throw TraceUtility.ThrowHelperError(new NotSupportedException(), this.message); }
            public override long Seek(long offset, SeekOrigin origin) { throw TraceUtility.ThrowHelperError(new NotSupportedException(), this.message); } 
            public override void SetLength(long value) { throw TraceUtility.ThrowHelperError(new NotSupportedException(), this.message); }
            public override void Write(byte[] buffer, int offset, int count) { throw TraceUtility.ThrowHelperError(new NotSupportedException(), this.message); } 
        } 

        class OperationStreamProvider : IStreamProvider 
        {
            Stream stream;

            internal OperationStreamProvider(Stream stream) 
            {
                this.stream = stream; 
            } 

            public Stream GetStream() 
            {
                return stream;
            }
            public void ReleaseStream(Stream stream) 
            {
                //Noop 
            } 
        }
    } 



} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK