/// <summary> /// Writes the specified binary value to the <paramref name="asyncBufferedStream"/>. /// </summary> /// <param name="asyncBufferedStream">The stream to write the raw value to.</param> /// <param name="bytes">The binary value to write.</param> /// <returns>The <see cref="TextWriter"/> instance that was used to write the value or null if a binary value was written directly to the stream.</returns> internal static TextWriter WriteBinaryValue(AsyncBufferedStream asyncBufferedStream, byte[] bytes) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(asyncBufferedStream != null, "asyncBufferedStream != null"); Debug.Assert(bytes != null, "bytes != null"); // write the bytes directly asyncBufferedStream.Write(bytes, 0, bytes.Length); return null; }
/// <summary> /// Converts the specified <paramref name="value"/> into its raw format and writes it to the <paramref name="asyncBufferedStream"/>. /// The value has to be of primitive type. /// </summary> /// <param name="asyncBufferedStream">The stream to write the raw value to.</param> /// <param name="value">The (non-binary) value to write.</param> /// <param name="encoding">The encoding to use when writing raw values (except for binary values).</param> /// <returns>The <see cref="TextWriter"/> instance that was used to write the value or null if a binary value was written directly to the stream.</returns> /// <remarks>We do not accept binary values here; WriteBinaryValue should be used for binary data.</remarks> internal static TextWriter WriteRawValue(AsyncBufferedStream asyncBufferedStream, object value, Encoding encoding) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(asyncBufferedStream != null, "asyncBufferedStream != null"); Debug.Assert(!(value is byte[]), "!(value is byte[])"); string valueAsString; bool preserveWhitespace; if (!AtomValueUtils.TryConvertPrimitiveToString(value, out valueAsString, out preserveWhitespace)) { // throw an exception because the value is not primitive throw new ODataException(Strings.ODataUtils_CannotConvertValueToRawPrimitive(value.GetType().FullName)); } StreamWriter textWriter = new StreamWriter(asyncBufferedStream, encoding); textWriter.Write(valueAsString); return textWriter; }
/// <summary> /// Creates a new <see cref="AsyncWriter"/> based on an Xml ATOM writer. /// </summary> /// <param name="asyncBufferedStream">The async buffered stream to use.</param> /// <param name="atomWriter">The Xml writer to write to.</param> internal AsyncWriter(AsyncBufferedStream asyncBufferedStream, XmlWriter atomWriter) { Debug.Assert(asyncBufferedStream != null, "asyncBufferedStream != null"); Debug.Assert(atomWriter != null, "atomWriter != null"); this.asyncBufferedStream = asyncBufferedStream; this.atomWriter = atomWriter; }
private AsyncWriter WriteTopLevelContent( Stream stream, Action<XmlWriter> writeAtomAction, Action<JsonWriter> writeJsonAction, Func<object, string> invalidContentTypeErrorMessageFunction, InternalErrorCodes internalErrorCode) { Debug.Assert(this.writerPayloadKind != ODataPayloadKind.Unsupported, "Expected payload kind, format and encoding to be set by now."); AsyncBufferedStream asyncBufferedStream = new AsyncBufferedStream(stream); switch (this.format) { case ODataFormat.Json: StreamWriter textWriter = new StreamWriter(asyncBufferedStream, this.encoding); JsonWriter jsonWriter = new JsonWriter(textWriter, this.settings.Indent); writeJsonAction(jsonWriter); return new AsyncWriter(asyncBufferedStream, textWriter, jsonWriter); case ODataFormat.Atom: XmlWriter xmlWriter = ODataAtomWriterUtils.CreateXmlWriter(asyncBufferedStream, this.settings, this.encoding); writeAtomAction(xmlWriter); return new AsyncWriter(asyncBufferedStream, xmlWriter); case ODataFormat.Default: Debug.Assert(false, "Should never get here as content-type negotiation should not return Default format for top level content."); string contentType = this.message.GetHeader(ODataHttpHeaders.ContentType); throw new ODataException(invalidContentTypeErrorMessageFunction(contentType)); default: throw new ODataException(Strings.General_InternalError(internalErrorCode)); } }
private AsyncWriter WriteValue(Stream stream, object value) { if (value == null) { // TODO: Bug 84434: OIPI doc seems to indicate in Section 2.2.6.4.1 that 'null' is permissible but the product does not support it. // We also throw in this case. throw new ODataException(Strings.ODataMessageWriter_CannotWriteNullInRawFormat); } TextWriter textWriter; AsyncBufferedStream asyncBufferedStream = new AsyncBufferedStream(stream); if (this.writerPayloadKind == ODataPayloadKind.BinaryValue) { textWriter = WriterUtils.WriteBinaryValue(asyncBufferedStream, (byte[])value); } else { textWriter = WriterUtils.WriteRawValue(asyncBufferedStream, value, this.encoding); } return new AsyncWriter(asyncBufferedStream, textWriter); }
/// <summary> /// Dispose the writer and the underlying stream. /// </summary> public void Dispose() { try { if (this.atomWriter == null) { if (this.textWriter == null) { this.asyncBufferedStream.Dispose(); } else { // The text writer will also dispose the this.asyncBufferedStream since it owns that stream // which in turn will dispose the real output stream underneath it. this.textWriter.Dispose(); } } else { Utils.TryDispose(this.atomWriter); this.asyncBufferedStream.Dispose(); } } finally { this.asyncBufferedStream = null; this.jsonWriter = null; this.atomWriter = null; } }
/// <summary> /// Creates a new <see cref="AsyncWriter"/> based on a text writer. /// </summary> /// <param name="asyncBufferedStream">The async buffered stream to use.</param> /// <param name="textWriter">The text writer for writing raw values.</param> internal AsyncWriter(AsyncBufferedStream asyncBufferedStream, TextWriter textWriter) { Debug.Assert(asyncBufferedStream != null, "asyncBufferedStream != null"); this.asyncBufferedStream = asyncBufferedStream; this.textWriter = textWriter; }
/// <summary> /// Creates a new <see cref="AsyncWriter"/> based on a JSON writer. /// </summary> /// <param name="asyncBufferedStream">The async buffered stream to use.</param> /// <param name="textWriter">The text writer backing the <see cref="jsonWriter"/>.</param> /// <param name="jsonWriter">The JSON writer to write to.</param> internal AsyncWriter(AsyncBufferedStream asyncBufferedStream, TextWriter textWriter, JsonWriter jsonWriter) { Debug.Assert(asyncBufferedStream != null, "asyncBufferedStream != null"); Debug.Assert(textWriter != null, "textWriter != null"); Debug.Assert(jsonWriter != null, "jsonWriter != null"); this.asyncBufferedStream = asyncBufferedStream; this.textWriter = textWriter; this.jsonWriter = jsonWriter; }
private void Dispose(bool disposing) { if (!this.IsDisposed) { if (disposing) { if (!IsErrorState(this.state) && this.state != BatchWriterState.Start && this.state != BatchWriterState.BatchCompleted) { this.ThrowODataException(Strings.ODataBatchWriter_WriterDisposedWithoutProperBatchEnd); } // if the writer is disposed after a fatal exception has been thrown discard all buffered data // of the underlying output stream so we can safely dispose it (below). bool discardBufferedData = this.state == BatchWriterState.FatalExceptionThrown || this.state == BatchWriterState.Start; try { // flush any active text writer to the underlying stream so we guarantee that there is no data buffered in the text writer; // the underlying async buffered stream will ignore the call to Dispose() that is triggered by disposing this StreamWriter. if (this.batchWriter != null) { this.batchWriter.Flush(); this.batchWriter.Dispose(); } if (discardBufferedData) { this.asyncBufferedStream.Clear(); } this.asyncBufferedStream.DisposeExplicitly(); } finally { this.batchWriter = null; this.asyncBufferedStream = null; this.outputStream = null; } } } this.outputStream = null; }
/// <summary> /// Constructor. /// </summary> /// <param name="stream">The stream to write to.</param> /// <param name="settings">The <see cref="ODataWriterSettings"/> for the batch writer.</param> /// <param name="encoding">The encoding to use for writing.</param> /// <param name="writingResponse">A flag indicating whether we are writing a request or a response message.</param> /// <param name="batchBoundary">The boundary string for the batch structure itself.</param> /// <param name="synchronous">True if the writer is created for synchronous operation; false for asynchronous.</param> private ODataBatchWriter( Stream stream, ODataWriterSettings settings, Encoding encoding, bool writingResponse, string batchBoundary, bool synchronous) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(stream != null, "stream != null"); if (batchBoundary == null) { ExceptionUtils.CheckArgumentNotNull(batchBoundary, "batchBoundary"); } this.settings = settings; this.encoding = encoding; this.outputStream = stream; this.writingResponse = writingResponse; this.batchBoundary = batchBoundary; this.synchronous = synchronous; this.asyncBufferedStream = new AsyncBufferedStream(stream, true); this.batchWriter = new StreamWriter(this.asyncBufferedStream, this.encoding); }