/// <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); }
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; } }
/// <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; } }
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; } }
/// <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; } }