Exemplo n.º 1
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="odataWriterSettings">Configuration settings for the writer to create.</param>
        /// <param name="encoding">The encoding to use for writing.</param>
        /// <param name="writingResponse">True if the writer is to write a response payload; false if it's to write a request payload.</param>
        /// <param name="metadataProvider">The metadata provider to use.</param>
        /// <param name="writingFeed">True if the writer is created for writing a feed; false when it is created for writing an entry.</param>
        /// <param name="synchronous">True if the writer is created for synchronous operation; false for asynchronous.</param>
        internal ODataJsonWriter(
            Stream stream, 
            ODataWriterSettings odataWriterSettings, 
            Encoding encoding, 
            bool writingResponse,
            DataServiceMetadataProviderWrapper metadataProvider,
            bool writingFeed,
            bool synchronous)
            : base(
                odataWriterSettings.Version, 
                odataWriterSettings.BaseUri, 
                writingResponse, 
                metadataProvider,
                writingFeed,
                synchronous)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(stream != null, "stream != null");
            Debug.Assert(odataWriterSettings != null, "odataWriterSettings != null");

            this.outputStream = new AsyncBufferedStream(stream);
            this.textWriter = new StreamWriter(this.outputStream, encoding);

            this.jsonWriter = new JsonWriter(this.textWriter, odataWriterSettings.Indent);
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="writerSettings">Configuration settings for the writer to create.</param>
        /// <param name="encoding">The encoding to use for writing.</param>
        /// <param name="metadataProvider">The metadata provider to use.</param>
        /// <param name="synchronous">True if the writer is created for synchronous operation; false for asynchronous.</param>
        internal ODataAtomCollectionWriter(
            Stream stream, 
            ODataWriterSettings writerSettings, 
            Encoding encoding, 
            DataServiceMetadataProviderWrapper metadataProvider,
            bool synchronous)
            : base(writerSettings.Version, metadataProvider, synchronous)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(stream != null, "stream != null");
            Debug.Assert(writerSettings != null, "writerSettings != null");

            this.outputStream = new AsyncBufferedStream(stream);
            this.writer = ODataAtomWriterUtils.CreateXmlWriter(this.outputStream, writerSettings, encoding);
        }
Exemplo n.º 3
0
        internal ODataAtomOutputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "stream != null");

            try
            {
                this.messageOutputStream = messageStream;

                Stream outputStream;
                if (synchronous)
                {
                    outputStream = messageStream;
                }
                else
                {
                    this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
                    outputStream = this.asynchronousOutputStream;
                }

                this.xmlWriter = ODataAtomWriterUtils.CreateXmlWriter(outputStream, messageWriterSettings, encoding);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Flush and close the writer.
        /// </summary>
        /// <param name="discardBufferedData">If true discard any buffered data before closing the writer.</param>
        /// <remarks>This is only called during disposal of the writer.</remarks>
        protected override void FlushAndCloseWriter(bool discardBufferedData)
        {
            try
            {
                // Flush the JSON writer so that we guarantee that there's no data buffered in the JSON writer;
                // the underlying stream verifies that no data is still buffered when disposed below.
                this.jsonWriter.Flush();

                if (discardBufferedData)
                {
                    this.outputStream.Clear();
                }

                // The text writer will also dispose the this.outputStream since it owns that stream
                // which in turn will dispose the real output stream underneath it.
                this.textWriter.Dispose();
            }
            finally
            {
                this.jsonWriter   = null;
                this.textWriter   = null;
                this.outputStream = null;
            }
        }
Exemplo n.º 5
0
 protected override void Dispose(bool disposing)
 {
     base.Dispose(disposing);
     try
     {
         if (this.messageOutputStream != null)
         {
             this.jsonWriter.Flush();
             if (this.asynchronousOutputStream != null)
             {
                 this.asynchronousOutputStream.FlushSync();
                 this.asynchronousOutputStream.Dispose();
             }
             this.messageOutputStream.Dispose();
         }
     }
     finally
     {
         this.messageOutputStream      = null;
         this.asynchronousOutputStream = null;
         this.textWriter = null;
         this.jsonWriter = null;
     }
 }
        protected internal ODataJsonOutputContextBase(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            bool isIeee754Compatible,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "messageStream != null");

            try
            {
                this.messageOutputStream = messageStream;

                Stream outputStream;
                if (synchronous)
                {
                    outputStream = messageStream;
                }
                else
                {
                    this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
                    outputStream = this.asynchronousOutputStream;
                }

                this.textWriter = new StreamWriter(outputStream, encoding);
                
                // COMPAT 2: JSON indentation - WCFDS indents only partially, it inserts newlines but doesn't actually insert spaces for indentation
                // in here we allow the user to specify if true indentation should be used or if the limited functionality is enough.
                this.jsonWriter = new JsonWriter(this.textWriter, messageWriterSettings.Indent, format, isIeee754Compatible);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
        protected override void Dispose(bool disposing)
        {
            try
            {
                if (this.messageOutputStream != null)
                {
                    // JsonWriter.Flush will call the underlying TextWriter.Flush.
                    // The TextWriter.Flush (Which is in fact StreamWriter.Flush) will call the underlying Stream.Flush.
                    this.jsonWriter.Flush();

                    // In the async case the underlying stream is the async buffered stream, so we have to flush that explicitly.
                    if (this.asynchronousOutputStream != null)
                    {
                        this.asynchronousOutputStream.FlushSync();
                        this.asynchronousOutputStream.Dispose();
                    }

                    // Dipose the message stream (note that we OWN this stream, so we always dispose it).
                    this.messageOutputStream.Dispose();
                }
            }
            finally
            {
                this.messageOutputStream = null;
                this.asynchronousOutputStream = null;
                this.textWriter = null;
                this.jsonWriter = null;
            }

            base.Dispose(disposing);
        }
        /// <summary>
        /// Perform the actual cleanup work.
        /// </summary>
        /// <param name="disposing">If 'true' this method is called from user code; if 'false' it is called by the runtime.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            try
            {
                if (this.messageOutputStream != null)
                {
                    // Note that the this.xmlWriter might be one of the XML customization writers, but since we don't own those
                    // we won't be flushing or disposing them. We just own the root writer which we created.

                    // XmlWriter.Flush will call the underlying Stream.Flush.
                    this.xmlRootWriter.Flush();

                    // XmlWriter.Dispose calls XmlWriter.Close which writes missing end elements.
                    // Thus we can't dispose the XmlWriter since that might end up writing more data into the stream right here
                    // and thus callers would have no way to prevent us from writing synchronously into the underlying stream.
                    // (note that all other cases where we write to the stream can be followed by FlushAsync which will perform
                    //  async write to the stream, but Dispose is the only case where that's not true).
                    // Also in case of in-stream error we intentionally want to not write the end elements to keep the payload invalid.
                    // In the async case the underlying stream is the async buffered stream, so we have to flush that explicitely.
                    if (this.asynchronousOutputStream != null)
                    {
                        this.asynchronousOutputStream.FlushSync();
                        this.asynchronousOutputStream.Dispose();
                    }

                    // Dipose the message stream (note that we OWN this stream, so we always dispose it).
                    this.messageOutputStream.Dispose();
                }
            }
            finally
            {
                this.messageOutputStream = null;
                this.asynchronousOutputStream = null;
                this.xmlWriter = null;
            }
        }
        /// <summary>
        /// Flushes and closes the writer. This method is only called during disposing the ODataCollectionWriter.
        /// </summary>
        /// <param name="discardBufferedData">
        /// If this parameter is true the close of the writer should not throw if some data is still buffered.
        /// If the argument is false the writer is expected to throw if data is still buffered and the writer is closed.
        /// </param>
        protected override void FlushAndCloseWriter(bool discardBufferedData)
        {
            try
            {
                // flush the Xml writer to the underlying stream so we guarantee that there is no data buffered in the Xml writer;
                // the underlying stream verifies that no data is still buffered when disposed below.
                this.writer.Flush();

                if (!IsErrorState(this.State))
                {
                    // XmlWriter.Close() guarantees that well-formed xml is produced by injecting close elements
                    // if any is missing.  In the case of an exception, we want the stream to end at the close
                    // element </m:error>.  So we skip writer.Dispose here if we are in error state.
                    Utils.TryDispose(this.writer);
                }

                if (discardBufferedData)
                {
                    this.outputStream.Clear();
                }

                this.outputStream.Dispose();
            }
            finally
            {
                this.writer = null;
                this.outputStream = null;
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageStream">The message stream to write the payload to.</param>
        /// <param name="encoding">The encoding to use for the payload.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        private ODataJsonOutputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            try
            {
                this.messageOutputStream = messageStream;

                Stream outputStream;
                if (synchronous)
                {
                    outputStream = messageStream;
                }
                else
                {
                    this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
                    outputStream = this.asynchronousOutputStream;
                }

                this.textWriter = new StreamWriter(outputStream, encoding);

                this.jsonWriter = new JsonWriter(this.textWriter, messageWriterSettings.Indent);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Flush and close the writer.
        /// </summary>
        /// <param name="discardBufferedData">If true discard any buffered data before closing the writer.</param>
        /// <remarks>This is only called during disposal of the writer.</remarks>
        protected override void FlushAndCloseWriter(bool discardBufferedData)
        {
            try
            {
                // Flush the JSON writer so that we guarantee that there's no data buffered in the JSON writer;
                // the underlying stream verifies that no data is still buffered when disposed below.
                this.jsonWriter.Flush();

                if (discardBufferedData)
                {
                    this.outputStream.Clear();
                }

                // The text writer will also dispose the this.outputStream since it owns that stream
                // which in turn will dispose the real output stream underneath it.
                this.textWriter.Dispose();
            }
            finally
            {
                this.jsonWriter = null;
                this.textWriter = null;
                this.outputStream = null;
            }
        }