Odbieranie binarnych odpowiedzi libcurl do C++ std::string
Przekaż std::string jako kontekst wywołania zwrotnego i dodawaj jawne liczby bajtów podczas odbierania danych binarnych za pomocą libcurl.
Serwer proxy może z powodzeniem pobrać HTML, a mimo to uszkodzić obraz podczas kopiowania go do bufora C++. Przed zmianą protokołu proxy sprawdź wywołanie zwrotne odbioru i obiekt przekazany jako jego kontekst.
CURLOPT_WRITEDATA dostarcza wskaźnik do wywołania zwrotnego zapisu. Bez niestandardowego wywołania zwrotnego domyślny zapisujący libcurl oczekuje FILE *. Adres taki jak &response, gdzie response jest std::string, ma sens tylko wtedy, gdy wywołanie zwrotne rzutuje ten kontekst z powrotem na zamierzony typ.
static size_t receive(char* data, size_t size,
size_t count, void* context) {
const size_t bytes = size * count;
auto* body = static_cast<std::string*>(context);
try {
body->append(data, bytes);
} catch (...) {
return 0;
}
return bytes;
}Zarejestruj obie połowy na prostym uchwycie używanym do transferu:
std::string response;
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response);Wywołanie append używa dostarczonej liczby bajtów. Dane wywołania zwrotnego nie są zakończone zerem, a obraz może zawierać bajty zerowe; pomiar za pomocą strlen utraciłby część treści. Odpowiedź może też nadchodzić przez wiele wywołań o różnych rozmiarach.
Zwrócenie zużytej liczby bajtów akceptuje fragment. Zwrócenie innej liczby przerywa transfer błędem zapisu. Strażnik wyjątków nie pozwala, by błąd alokacji wydostał się przez granicę wywołania zwrotnego C; wywołujący nadal musi sprawdzić wynik transferu, zanim uzna response za kompletny plik.
Utrzymuj ciąg przy życiu, dopóki transfer się nie zakończy. Jeśli asynchroniczny zapis do gniazda przekazuje następnie jego zawartość, utrzymuj te bajty przy życiu, dopóki ten zapis również się nie zakończy. W przypadku dużych odpowiedzi ograniczony układ strumieniowania jest lepszy niż gromadzenie całej treści.