Download Callback interface issue
I am trying to async callback download image to memory and Download interface is not user-friendly for me.
so we have write callback for DownloadAsync method but we don't have DownloadCallback method where I could have response ctx or some sort where I could just do:
const auto buffer = std::make_shared<std::vector<uint8_t>>();
auto f = session->DownloadAsync( cpr::WriteCallback{
[buffer]( std::string_view data, intptr_t /*userdata*/, auto ctx ) -> bool
{
buffer->insert( buffer->end(), data.begin(), data.end() );
if ( ctx->finished && ctx->status_code == 200 )
{
//somelogic
}
return true;
} } );
or just DownloadCallback that accepts cpr::Response& and called when download finished where body has payload bytes
Currently, I don't know how conveniently do such thing. session->GetDownloadFileLength() - it does request inside, so the logic is not async anymore SetProgressCallback - sure we can use it but why do we need two callbacks to simply downloading file?
So am I missing something here to conveniently download the file in a callback way?
You are right @Chrys4lisfag out of the box cpr does not directly support this use case. You could try something like this:
#include <future>
#include <cpr/async_wrapper.h>
#include <cpr/cpr.h>
template <typename... Ts>
cpr::AsyncResponse fancyDownloadAsync(const cpr::WriteCallback&& writeCb, const std::function<void(const cpr::Response&)>&& responseCb, Ts&&... ts) {
return cpr::AsyncWrapper{std::async(
std::launch::async,
[](const cpr::WriteCallback&& writeCb, const std::function<void(const cpr::Response&)>&& responseCb, Ts&&... ts) {
const cpr::Response response = cpr::Download(std::move(writeCb), std::forward<Ts>(ts)...);
responseCb(response);
return response;
},
std::move(writeCb), std::move(responseCb), std::move(ts)...)};
}
Yeah. I did something similar in the end. Would be cool to see some fancy build in way in the future