How can I implement IRandomAccessStream in C #?

I would like to implement an instance of IRandomAccessStream in C # (it will return the data generated in real time). The stream should not actually be writable or searchable, but I want to return my own data to the ReadAsync method (which is actually part of IInputStream ).

 public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options) { throw new NotImplementedException("To be done"); } 

My two main questions:

  • how do i return something that implements IAsyncOperationWithProgress ? Is there something built into the structure to help with this?
  • How can I write data to the buffer? IBuffer has only the Length and Capacity properties (a specific buffer class does not offer more).
+7
source share
2 answers

How to convert byte array to IRandomAccessStream

I found this blog article, hope this IRandomAccessStream implementation may be the starting point for you.

 class MemoryRandomAccessStream : IRandomAccessStream { private Stream m_InternalStream; public MemoryRandomAccessStream(Stream stream) { this.m_InternalStream = stream; } public MemoryRandomAccessStream(byte[] bytes) { this.m_InternalStream = new MemoryStream(bytes); } public IInputStream GetInputStreamAt(ulong position) { this.m_InternalStream.Seek((long)position, SeekOrigin.Begin); return this.m_InternalStream.AsInputStream(); } public IOutputStream GetOutputStreamAt(ulong position) { this.m_InternalStream.Seek((long)position, SeekOrigin.Begin); return this.m_InternalStream.AsOutputStream(); } public ulong Size { get { return (ulong)this.m_InternalStream.Length; } set { this.m_InternalStream.SetLength((long)value); } } public bool CanRead { get { return true; } } public bool CanWrite { get { return true; } } public IRandomAccessStream CloneStream() { throw new NotSupportedException(); } public ulong Position { get { return (ulong)this.m_InternalStream.Position; } } public void Seek(ulong position) { this.m_InternalStream.Seek((long)position, 0); } public void Dispose() { this.m_InternalStream.Dispose(); } public Windows.Foundation.IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options) { var inputStream = this.GetInputStreamAt(0); return inputStream.ReadAsync(buffer, count, options); } public Windows.Foundation.IAsyncOperation<bool> FlushAsync() { var outputStream = this.GetOutputStreamAt(0); return outputStream.FlushAsync(); } public Windows.Foundation.IAsyncOperationWithProgress<uint, uint> WriteAsync(IBuffer buffer) { var outputStream = this.GetOutputStreamAt(0); return outputStream.WriteAsync(buffer); } } 
+4
source
  • Use the AsyncInfo.Run(Func<CancellationToken, IProgress<uint>, Task<IBuffer>>) method AsyncInfo.Run(Func<CancellationToken, IProgress<uint>, Task<IBuffer>>) to create an IAsyncOperationWithProgress instance from the delegate.

     public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options) { if (buffer == null) throw new ArgumentNullException("buffer"); Func<CancellationToken, IProgress<uint>, Task<IBuffer>> taskProvider = (token, progress) => ReadBytesAsync(buffer, count, token, progress, options); return AsyncInfo.Run(taskProvider); } private async Task<IBuffer> ReadBytesAsync(IBuffer buffer, uint count, CancellationToken token, IProgress<uint> progress, InputStreamOptions options) { ... Fill the buffer here. Report the progress. return buffer; } 
  • Usually you do not need to access the buffer data directly. But in case you need to do this in C #, you can use the System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions class to copy data to the buffer from the buffer.

+1
source

All Articles