Skip to content

Commit

Permalink
Capability to close ODataBinaryStreamValue stream after serialization (
Browse files Browse the repository at this point in the history
…#2597)

* Capability for JsonLightSerializer to close ODataBinaryStreamValue streams once processed.

* Use of DisposeAsync in runtimes where it's available.

* Update public API

* Undo change to Unshipped.txt

* Update PublicAPI.Shipped.txt

* Update PublicAPI.shipped.txt for 3.1

Co-authored-by: Sylvain Prieur <syprieur@microsoft.com>
Co-authored-by: Clement Habinshuti <clhabins@microsoft.com>
  • Loading branch information
3 people authored Jan 25, 2023
1 parent ecd0850 commit 0770ead
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,11 @@ public virtual void WriteStreamValue(ODataBinaryStreamValue streamValue)
stream.Dispose();
streamWriter.EndStreamValueScope();
}

if (!streamValue.LeaveOpen)
{
streamValue.Stream.Dispose();
}
}

/// <summary>
Expand Down Expand Up @@ -720,7 +725,6 @@ public virtual async Task WriteStreamValueAsync(ODataBinaryStreamValue streamVal
IJsonStreamWriterAsync streamWriter = this.AsynchronousJsonWriter as IJsonStreamWriterAsync;
if (streamWriter == null)
{
// write as a string
byte[] value = await streamValue.Stream.ReadAllBytesAsync().ConfigureAwait(false);
await this.AsynchronousJsonWriter.WritePrimitiveValueAsync(value).ConfigureAwait(false);
}
Expand All @@ -729,9 +733,22 @@ public virtual async Task WriteStreamValueAsync(ODataBinaryStreamValue streamVal
Stream stream = await streamWriter.StartStreamValueScopeAsync().ConfigureAwait(false);
await streamValue.Stream.CopyToAsync(stream).ConfigureAwait(false);
await stream.FlushAsync().ConfigureAwait(false);
#if NETCOREAPP3_1_OR_GREATER
await stream.DisposeAsync();
#else
stream.Dispose();
#endif
await streamWriter.EndStreamValueScopeAsync().ConfigureAwait(false);
}

if (!streamValue.LeaveOpen)
{
#if NETCOREAPP3_1_OR_GREATER
await streamValue.Stream.DisposeAsync();
#else
streamValue.Stream.Dispose();
#endif
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ Microsoft.OData.ODataBatchWriter.WriteStartChangesetAsync() -> System.Threading.
Microsoft.OData.ODataBatchWriter.WriteStartChangesetAsync(string changesetId) -> System.Threading.Tasks.Task
Microsoft.OData.ODataBinaryStreamValue
Microsoft.OData.ODataBinaryStreamValue.ODataBinaryStreamValue(System.IO.Stream stream) -> void
Microsoft.OData.ODataBinaryStreamValue.ODataBinaryStreamValue(System.IO.Stream stream, bool leaveOpen) -> void
Microsoft.OData.ODataBinaryStreamValue.Stream.get -> System.IO.Stream
Microsoft.OData.ODataCollectionReader
Microsoft.OData.ODataCollectionReader.ODataCollectionReader() -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ Microsoft.OData.ODataBatchWriter.WriteStartChangesetAsync() -> System.Threading.
Microsoft.OData.ODataBatchWriter.WriteStartChangesetAsync(string changesetId) -> System.Threading.Tasks.Task
Microsoft.OData.ODataBinaryStreamValue
Microsoft.OData.ODataBinaryStreamValue.ODataBinaryStreamValue(System.IO.Stream stream) -> void
Microsoft.OData.ODataBinaryStreamValue.ODataBinaryStreamValue(System.IO.Stream stream, bool leaveOpen) -> void
Microsoft.OData.ODataBinaryStreamValue.Stream.get -> System.IO.Stream
Microsoft.OData.ODataCollectionReader
Microsoft.OData.ODataCollectionReader.ODataCollectionReader() -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ Microsoft.OData.ODataBatchWriter.WriteStartChangesetAsync() -> System.Threading.
Microsoft.OData.ODataBatchWriter.WriteStartChangesetAsync(string changesetId) -> System.Threading.Tasks.Task
Microsoft.OData.ODataBinaryStreamValue
Microsoft.OData.ODataBinaryStreamValue.ODataBinaryStreamValue(System.IO.Stream stream) -> void
Microsoft.OData.ODataBinaryStreamValue.ODataBinaryStreamValue(System.IO.Stream stream, bool leaveOpen) -> void
Microsoft.OData.ODataBinaryStreamValue.Stream.get -> System.IO.Stream
Microsoft.OData.ODataCollectionReader
Microsoft.OData.ODataCollectionReader.ODataCollectionReader() -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ Microsoft.OData.ODataBatchWriter.WriteStartChangesetAsync() -> System.Threading.
Microsoft.OData.ODataBatchWriter.WriteStartChangesetAsync(string changesetId) -> System.Threading.Tasks.Task
Microsoft.OData.ODataBinaryStreamValue
Microsoft.OData.ODataBinaryStreamValue.ODataBinaryStreamValue(System.IO.Stream stream) -> void
Microsoft.OData.ODataBinaryStreamValue.ODataBinaryStreamValue(System.IO.Stream stream, bool leaveOpen) -> void
Microsoft.OData.ODataBinaryStreamValue.Stream.get -> System.IO.Stream
Microsoft.OData.ODataCollectionReader
Microsoft.OData.ODataCollectionReader.ODataCollectionReader() -> void
Expand Down
18 changes: 17 additions & 1 deletion src/Microsoft.OData.Core/Value/ODataBinaryStreamValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,32 @@ public sealed class ODataBinaryStreamValue : ODataValue
/// Constructor
/// </summary>
/// <param name="stream">Input stream</param>
public ODataBinaryStreamValue(Stream stream)
public ODataBinaryStreamValue(Stream stream) :
this(stream, true) // Leaves the stream open by default, for backward compatibility.
{
}

/// <summary>
/// Constructor
/// </summary>
/// <param name="stream">Input stream</param>
/// <param name="leaveOpen">Whether the provided stream should be left open.</param>
public ODataBinaryStreamValue(Stream stream, bool leaveOpen)
{
ExceptionUtils.CheckArgumentNotNull(stream, "stream");

this.Stream = stream;
this.LeaveOpen = leaveOpen;
}

/// <summary>
/// The Stream wrapped by the ODataBinaryStreamValue
/// </summary>
public Stream Stream { get; private set; }

/// <summary>
/// Whether this instance's <see cref="Stream"/> should be left open.
/// </summary>
internal bool LeaveOpen { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,17 @@ public void WritingMultipleInstanceAnnotationInResourceValueShouldWrite(string f
Assert.Equal(expect, result);
}

[Fact]
public void WriteStreamValue_WritesStreamValue()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void WriteStreamValue_WritesStreamValue(bool leaveOpen)
{
var stream = new MemoryStream();
var stream = new DisposeTrackingMemoryStream();
var writer = new BinaryWriter(stream);
writer.Write("1234567890");
writer.Flush();
stream.Position = 0;
var streamValue = new ODataBinaryStreamValue(stream);
var streamValue = new ODataBinaryStreamValue(stream, leaveOpen);

var result = this.SetupSerializerAndRunTest(
(jsonLightValueSerializer) =>
Expand All @@ -331,6 +333,7 @@ public void WriteStreamValue_WritesStreamValue()
});

Assert.Equal("\"CjEyMzQ1Njc4OTA=\"", result);
Assert.Equal(leaveOpen, !stream.Disposed);
}

#if NETCOREAPP3_1_OR_GREATER
Expand Down Expand Up @@ -395,5 +398,20 @@ private string SetupSerializerAndRunTest(Action<ODataJsonLightValueSerializer> a
var streamReader = new StreamReader(stream);
return streamReader.ReadToEnd();
}

private class DisposeTrackingMemoryStream : MemoryStream
{
public bool Disposed { get; private set; } = false;

protected override void Dispose(bool disposing)
{
if (disposing)
{
this.Disposed = true;
}

base.Dispose(disposing);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5222,6 +5222,7 @@ public sealed class Microsoft.OData.ODataBatchOperationResponseMessage : IContai

public sealed class Microsoft.OData.ODataBinaryStreamValue : Microsoft.OData.ODataValue {
public ODataBinaryStreamValue (System.IO.Stream stream)
public ODataBinaryStreamValue (System.IO.Stream stream, bool leaveOpen)

System.IO.Stream Stream { public get; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5222,6 +5222,7 @@ public sealed class Microsoft.OData.ODataBatchOperationResponseMessage : IContai

public sealed class Microsoft.OData.ODataBinaryStreamValue : Microsoft.OData.ODataValue {
public ODataBinaryStreamValue (System.IO.Stream stream)
public ODataBinaryStreamValue (System.IO.Stream stream, bool leaveOpen)

System.IO.Stream Stream { public get; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5222,6 +5222,7 @@ public sealed class Microsoft.OData.ODataBatchOperationResponseMessage : IContai

public sealed class Microsoft.OData.ODataBinaryStreamValue : Microsoft.OData.ODataValue {
public ODataBinaryStreamValue (System.IO.Stream stream)
public ODataBinaryStreamValue (System.IO.Stream stream, bool leaveOpen)

System.IO.Stream Stream { public get; }
}
Expand Down

0 comments on commit 0770ead

Please sign in to comment.