I need to do various reads on a stream for a decryption process. (for WinRT project) For one, I'd like to do a ReadByte() to get the first byte of the stream. There-after I'd like to read a few bytes into an array, and then read the rest of the bytes into a buffer.
I open up a DataReader on a passed IInputStream object. Which in turn was created from a System.IO.Stream object using the .AsInputStream() method. When I look at the DataReader object during debugging I see that the UnconsumedBufferLength is 0, and I am unable to do ReadByte() or ReadBytes() lest I want to get a "The operation attempted to access data outside the valid range" exception.
Why does the DataReader object seem empty? I've had issues with the AsInputStream() method not returning an actual IInputStream before. How can I ultimately open a DataReader object on a System.IO.Stream object.
Code where the DataReader is assigned:
private Stream DecryptStream(IInputStream streamToDecrypt, byte[] key)
{
try
{
var dataReader = new DataReader(streamToDecrypt);
int ivLength = dataReader.ReadByte(); //Throws exception (UnconsumedBufferLength = 0 remember)
byte[] iv = new byte[ivLength];
dataReader.ReadBytes(iv); //Throws exception (UnconsumedBufferLength = 0 remember)
IBuffer toDecryptBuffer = new Windows.Storage.Streams.Buffer(dataReader.UnconsumedBufferLength);
toDecryptBuffer = dataReader.ReadBuffer(dataReader.UnconsumedBufferLength); //Works, but only because toDecryptBuffer is of length 0. which is still useless.
Code that calls the above method:
Stream plainStream = DecryptStream(streamToDecrypt.AsInputStream(),key);
Update: Code which created the stream This is where the stream is first created, from a System.IO.Compression.ZipArchive object. This is then passed to the interim Decryption funciton as "streamToDecrypt"
ZipArchiveEntry metaEntry = archive.Entries.Where(x => x.FullName == "myFullNameHere").FirstOrDefault();
Stream returnStream = metaEntry.Open();
You need to call datareader.LoadAsync(size) to load the file into the buffer before reading it.
Change your decrypt method to something like this:
private async Task<Stream> DecryptStream(IInputStream streamToDecrypt, byte[] key, int uncompressedSize)
{
try
{
var dataReader = new DataReader(streamToDecrypt);
await datareader.LoadAsync(uncompressedSize);
int ivLength = dataReader.ReadByte(); //Throws exception (UnconsumedBufferLength = 0 remember)
byte[] iv = new byte[ivLength];
dataReader.ReadBytes(iv); //Throws exception (UnconsumedBufferLength = 0 remember)
Then when you call it, pass in the uncompressed size from the ZipArchiveEntry:
await DecryptStream(streamToDecrypt.AsInputStream(),key, streamToDecrypt.Length);