locked
How to properly implement IInputStream

    Question

  • Hi,

    I would like to know how to properly implement a class implementing the IInputStream interface.
    So let's start with the IInputstream definition, it says it has a single method declared like this

    IAsyncOperationWithProgress<IBuffer^, unsigned int>^ ZipAccessStream::ReadAsync(IBuffer^ aBuffer, uint32_t aCount, InputStreamOptions anOptions)

    1) So as you can see it takes a IBUffer as first parameter and it returns a Ibuffer so my first question is : should I create another IBUffer or can I write directly inside the given buffer ?

    2) If I can write directly inside the passed IBuffer, if the data I can read is lesser than the aCount parameter, how do I inform the IBuffer ? Can I resize the IBUffer

    3) If the caller asks for xxx bytes and I don't have any bytes, should I return an empty IBuffer or a null IBuffer

    4) Is it mandatory to implement  the progress_reporter and to call it to signal how much data has been read ?

    5) If no data have been read should I call it with 0 ?

    6) Should I protect the synchronous call responsible for reading data or is guaranted that only the same thread will access it ?

    So now here is what I have implemented for the moment and it seems to work but I would like some feeback/critics about it, how can I improve it, should I use a try catch inside, Should I write directly inside the IBuffer, should I use a create_task ...

    IAsyncOperationWithProgress<IBuffer^, unsigned int>^ ZipAccessStream::ReadAsync(IBuffer^ aBuffer, uint32_t aCount, InputStreamOptions anOptions)
    {
    	return create_async([=](progress_reporter<unsigned int> reporter) -> IBuffer^ {
    
    		IBuffer^ buffer = nullptr;
    		
    		unsigned char *pBuffer = nullptr;
    		uint32_t bytesRead = 0;
    
    		// How much remaining data can we read
    		uint32_t remaining_data = _nativeZipEntry->uncompressed_size() - _nativeZipEntry->tcount();
    		uint32_t count = min(remaining_data, aCount);
    		if (count != 0)
    		{
    			// Allocate a buffer for the native method to read data
    			pBuffer = (unsigned char *)malloc(count);
    			if (pBuffer != nullptr)
    			{
    
    				// Read data
    				_nativeZipEntry->read((unsigned char*)pBuffer, count);
    				// Get how much data was read
    
    				bytesRead = _nativeZipEntry->gcount();
    				if (bytesRead != 0)
    				{
    					Platform::Array<unsigned char>^ arr = ref new Platform::Array<unsigned char>(pBuffer, bytesRead);
    
    					// Copy read data inside the IBuffer through DataWriter (IBufferByteAccess maybe better ??)
    					DataWriter^ writer = ref new DataWriter();
    					writer->WriteBytes(arr);
    
    					// Make sure that the DataWriter destructor does not free the buffer.
    					buffer = writer->DetachBuffer();
    				}
    				free(pBuffer);
    			}
    		}
    		
    		// Report progress
    		reporter.report(bytesRead);
    
    		return buffer;
    	});
    }
    Thanks for answering because I am sure it will help people trying to do the same.


    • Edited by Vincent Rich Tuesday, January 28, 2014 6:10 PM good
    Tuesday, January 28, 2014 6:08 PM

Answers

  • This is a really specific question about what the "right" way to do something is.  Are you designing an API or is it just for an app?  I say this because what you're asking is academic for most people who wouldn't look past "it works", and that's why you're not getting much in the way of responses.  What's your real concern in this issue?

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    • Marked as answer by Vincent Rich Wednesday, January 29, 2014 8:54 PM
    Wednesday, January 29, 2014 1:35 PM
    Moderator

All replies

  • This is a really specific question about what the "right" way to do something is.  Are you designing an API or is it just for an app?  I say this because what you're asking is academic for most people who wouldn't look past "it works", and that's why you're not getting much in the way of responses.  What's your real concern in this issue?

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    • Marked as answer by Vincent Rich Wednesday, January 29, 2014 8:54 PM
    Wednesday, January 29, 2014 1:35 PM
    Moderator
  • Hi,

    I just wanted to know if this code was good and if it could be improved but as you said I won't have lots of answers here. This code is used Inside ZipAccessStream class that I have delopped to return an IInputStream from a zip entry.
    For instance in this code I am using a DataWriter but wouldn't be better to use access the IBuffer directly through the IBufferByteAccess, ... 

     

    Wednesday, January 29, 2014 3:37 PM