_positionSetFunc = positionSetFunc ?? (_ => { throw new NotSupportedException(); });
_positionGetFunc = positionGetFunc ?? (() => { throw new NotSupportedException(); });
- _readFunc = readFunc ?? ((buffer, offset, count) => readAsyncFunc(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult());
+ if (readAsyncFunc != null && readFunc == null)
+ throw new InvalidOperationException("If reads are supported, must provide a synchronous read implementation");
+ _readFunc = readFunc;
_readAsyncFunc = readAsyncFunc ?? ((buffer, offset, count, token) => base.ReadAsync(buffer, offset, count, token));
_seekFunc = seekFunc ?? ((_, __) => { throw new NotSupportedException(); });
_setLengthFunc = setLengthFunc ?? (_ => { throw new NotSupportedException(); });
- _writeFunc = writeFunc ?? ((buffer, offset, count) => writeAsyncFunc(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult());
+ if (writeAsyncFunc != null && writeFunc == null)
+ throw new InvalidOperationException("If writes are supported, must provide a synchronous write implementation");
+ _writeFunc = writeFunc;
_writeAsyncFunc = writeAsyncFunc ?? ((buffer, offset, count, token) => base.WriteAsync(buffer, offset, count, token));
}
lengthFunc: () => wrappedMemStream.Length,
positionGetFunc: () => wrappedMemStream.Position,
positionSetFunc: p => wrappedMemStream.Position = p,
+ readFunc: (buffer, offset, count) => wrappedMemStream.Read(buffer, offset, count),
readAsyncFunc: (buffer, offset, count, token) => wrappedMemStream.ReadAsync(buffer, offset, count, token));
yield return new object[] { server, new StreamContentWithSyncAsyncCopy(syncKnownLengthStream, syncCopy: syncCopy), data };
}
// A stream that provides the data synchronously and has an unknown length
{
int syncUnknownLengthStreamOffset = 0;
+
+ Func<byte[], int, int, int> readFunc = (buffer, offset, count) =>
+ {
+ int bytesRemaining = data.Length - syncUnknownLengthStreamOffset;
+ int bytesToCopy = Math.Min(bytesRemaining, count);
+ Array.Copy(data, syncUnknownLengthStreamOffset, buffer, offset, bytesToCopy);
+ syncUnknownLengthStreamOffset += bytesToCopy;
+ return bytesToCopy;
+ };
+
var syncUnknownLengthStream = new DelegateStream(
canReadFunc: () => true,
canSeekFunc: () => false,
- readAsyncFunc: (buffer, offset, count, token) =>
- {
- int bytesRemaining = data.Length - syncUnknownLengthStreamOffset;
- int bytesToCopy = Math.Min(bytesRemaining, count);
- Array.Copy(data, syncUnknownLengthStreamOffset, buffer, offset, bytesToCopy);
- syncUnknownLengthStreamOffset += bytesToCopy;
- return Task.FromResult(bytesToCopy);
- });
+ readFunc: readFunc,
+ readAsyncFunc: (buffer, offset, count, token) => Task.FromResult(readFunc(buffer, offset, count)));
yield return new object[] { server, new StreamContentWithSyncAsyncCopy(syncUnknownLengthStream, syncCopy: syncCopy), data };
}
// A stream that provides the data asynchronously
{
int asyncStreamOffset = 0, maxDataPerRead = 100;
+
+ Func<byte[], int, int, int> readFunc = (buffer, offset, count) =>
+ {
+ int bytesRemaining = data.Length - asyncStreamOffset;
+ int bytesToCopy = Math.Min(bytesRemaining, Math.Min(maxDataPerRead, count));
+ Array.Copy(data, asyncStreamOffset, buffer, offset, bytesToCopy);
+ asyncStreamOffset += bytesToCopy;
+ return bytesToCopy;
+ };
+
var asyncStream = new DelegateStream(
canReadFunc: () => true,
canSeekFunc: () => false,
+ readFunc: readFunc,
readAsyncFunc: async (buffer, offset, count, token) =>
{
await Task.Delay(1).ConfigureAwait(false);
- int bytesRemaining = data.Length - asyncStreamOffset;
- int bytesToCopy = Math.Min(bytesRemaining, Math.Min(maxDataPerRead, count));
- Array.Copy(data, asyncStreamOffset, buffer, offset, bytesToCopy);
- asyncStreamOffset += bytesToCopy;
- return bytesToCopy;
+ return readFunc(buffer, offset, count);
});
yield return new object[] { server, new StreamContentWithSyncAsyncCopy(asyncStream, syncCopy: syncCopy), data };
}