-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: reading bytes from a stream #51
- Loading branch information
1 parent
f2bbd51
commit 21c8e83
Showing
8 changed files
with
176 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace PeerTalk | ||
{ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
public static class StreamExtensions | ||
{ | ||
/// <summary> | ||
/// Asynchronously reads a sequence of bytes from the stream and advances | ||
/// the position within the stream by the number of bytes read. | ||
/// </summary> | ||
/// <param name="stream"> | ||
/// The stream to read from. | ||
/// </param> | ||
/// <param name="buffer"> | ||
/// The buffer to write the data into. | ||
/// </param> | ||
/// <param name="offset"> | ||
/// The byte offset in <paramref name="buffer"/> at which to begin | ||
/// writing data from the <paramref name="stream"/>. | ||
/// </param> | ||
/// <param name="length"> | ||
/// The number of bytes to read. | ||
/// </param> | ||
/// <returns> | ||
/// A task that represents the asynchronous operation. | ||
/// </returns> | ||
/// <exception cref="EndOfStreamException"> | ||
/// When the <paramref name="stream"/> does not have | ||
/// <paramref name="length"/> bytes. | ||
/// </exception> | ||
public static async Task ReadExactAsync(this Stream stream, byte[] buffer, int offset, int length) | ||
{ | ||
while (0 < length) | ||
{ | ||
var n = await stream.ReadAsync(buffer, offset, length); | ||
if (n == 0) | ||
{ | ||
throw new EndOfStreamException(); | ||
} | ||
offset += n; | ||
length -= n; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Asynchronously reads a sequence of bytes from the stream and advances | ||
/// the position within the stream by the number of bytes read. | ||
/// </summary> | ||
/// <param name="stream"> | ||
/// The stream to read from. | ||
/// </param> | ||
/// <param name="buffer"> | ||
/// The buffer to write the data into. | ||
/// </param> | ||
/// <param name="offset"> | ||
/// The byte offset in <paramref name="buffer"/> at which to begin | ||
/// writing data from the <paramref name="stream"/>. | ||
/// </param> | ||
/// <param name="length"> | ||
/// The number of bytes to read. | ||
/// </param> | ||
/// <param name="cancel"> | ||
/// Is used to stop the task. | ||
/// </param> | ||
/// <returns> | ||
/// A task that represents the asynchronous operation. | ||
/// </returns> | ||
/// <exception cref="EndOfStreamException"> | ||
/// When the <paramref name="stream"/> does not have | ||
/// <paramref name="length"/> bytes. | ||
/// </exception> | ||
public static async Task ReadExactAsync(this Stream stream, byte[] buffer, int offset, int length, CancellationToken cancel) | ||
{ | ||
while (0 < length) | ||
{ | ||
var n = await stream.ReadAsync(buffer, offset, length, cancel); | ||
if (n == 0) | ||
{ | ||
throw new EndOfStreamException(); | ||
} | ||
offset += n; | ||
length -= n; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using Ipfs; | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using System.Net.Sockets; | ||
|
||
namespace PeerTalk | ||
{ | ||
[TestClass] | ||
public class StreamExtensionsTest | ||
{ | ||
[TestMethod] | ||
public async Task ReadAsync() | ||
{ | ||
var expected = new byte[] { 1, 2, 3, 4 }; | ||
using (var ms = new MemoryStream(expected)) | ||
{ | ||
var actual = new byte[expected.Length]; | ||
await ms.ReadExactAsync(actual, 0, actual.Length); | ||
CollectionAssert.AreEqual(expected, actual); | ||
} | ||
} | ||
|
||
[TestMethod] | ||
public void ReadAsync_EOS() | ||
{ | ||
var expected = new byte[] { 1, 2, 3, 4 }; | ||
var actual = new byte[expected.Length + 1]; | ||
|
||
using (var ms = new MemoryStream(expected)) | ||
{ | ||
ExceptionAssert.Throws<EndOfStreamException>(() => | ||
{ | ||
ms.ReadExactAsync(actual, 0, actual.Length).Wait(); | ||
}); | ||
} | ||
|
||
var cancel = new CancellationTokenSource(); | ||
using (var ms = new MemoryStream(expected)) | ||
{ | ||
ExceptionAssert.Throws<EndOfStreamException>(() => | ||
{ | ||
ms.ReadExactAsync(actual, 0, actual.Length, cancel.Token).Wait(); | ||
}); | ||
} | ||
} | ||
|
||
[TestMethod] | ||
public async Task ReadAsync_Cancel() | ||
{ | ||
var expected = new byte[] { 1, 2, 3, 4 }; | ||
var actual = new byte[expected.Length]; | ||
var cancel = new CancellationTokenSource(); | ||
using (var ms = new MemoryStream(expected)) | ||
{ | ||
await ms.ReadExactAsync(actual, 0, actual.Length, cancel.Token); | ||
CollectionAssert.AreEqual(expected, actual); | ||
} | ||
|
||
cancel.Cancel(); | ||
using (var ms = new MemoryStream(expected)) | ||
{ | ||
ExceptionAssert.Throws<TaskCanceledException>(() => | ||
{ | ||
ms.ReadExactAsync(actual, 0, actual.Length, cancel.Token).Wait(); | ||
}); | ||
} | ||
} | ||
} | ||
} |