From COM IStream to concurrent::streams::istream

Mar 22, 2014 at 7:28 PM
Hello,
I do have a COM API that accept an IStream to write the content into it. I would like to be able to write into the concurrency::streams::istream being sent to http_response.

What is the best strategy I should pursue?

Thanks,
Pedro
Coordinator
Mar 29, 2014 at 12:22 AM
Hi Pedro,

I'm not really to familiar with the API you mention. But basically it looks like you would need to implement the COM IStream interface on top of Casablanca's stream. Not a ton of work, but probably just involves wrapping the functionality you need. We've already created streams for integrating with C++ standard I/O streams and WinRT streams. Take a look at Release\include\cpprest\interopstream.h, it could be helpful to see what might be involved.

Once this is done you can just supply your wrapper around the http_response stream.

Steve
Mar 31, 2014 at 2:24 PM
Thank you Steve,
I will look at that implementation.

Regards,
Pedro
Apr 1, 2014 at 4:29 AM
Hi Steve,
I managed implementing the COM IStream (OutboundAudioStream) where I defined the basic read, write and seek. I am having trouble how to wrap around http_response stream. I looked at the source code and I got a bit lost.

In other words something like:
CComObject<OutboundAudioStream> *pAudioOut = NULL;
if (SUCCEEDED(hr = CComObject<OutboundAudioStream>::CreateInstance(&pAudioOut)))
{
        pVoice->SetOutput(pAudioOut, FALSE);
    pVoice->Speak(text.c_str(), 0, NULL);

        web::http::http_response response(web::http::status_codes::OK);
    response.set_body(?????, L"audio/vnd.wave");
    request.reply(response);
}
Thanks,
Pedro
Apr 1, 2014 at 5:47 AM
Hi Steve,
I believe I found the way, perhaps not the most elegant way:
concurrency::streams::producer_consumer_buffer<uint8_t> buff;
concurrency::streams::basic_istream<uint8_t> is(buff);  
    
web::http::http_response response(web::http::status_codes::OK);
response.set_body(is, L"audio/vnd.wave");

pAudioOut->SetBuffer(buff);

request.reply(response);    
then in my write I do have something like (simplified):
STDMETHOD(Write)(const void * pv, ULONG cb, ULONG *pcbWritten)
    {
        buffer.putn((uint8_t*)pv, cb);
        return S_OK;
    }
and in the destructor:
buffer.close(std::ios::out).wait();
Thanks,
Pierre
Coordinator
Apr 1, 2014 at 2:30 PM
Hi Pierre,

Yes everything you have here looks good. One thing to note, in your Write method, the call to putn is asynchronous so it might not actually be completed by the time you return and you probably want to handle any exceptions from that write operation. You mention this is the simplified version so perhaps you already are.

Steve
Jul 10, 2014 at 2:54 AM
Hello Pierre, I am working on an application where my task is to retrieve the COM IStream for a file which is on the server.
I am just a beginner so can you please help me with it.

My email id is : utsav2601@gmail.com Thanks
Utsav