libcurl-ի բինար պատասխանները C++ std::string-ում ստանալը
Փոխանցեք std::string որպես callback-ի կոնտեքստ և ավելացրեք բացահայտ բայթերի հաշվարկներ, երբ libcurl-ով բինար տվյալներ եք ստանում։
Պրոքսին կարող է հաջողությամբ բերել HTML և միևնույն ժամանակ վնասել պատկերը՝ այն C++ բուֆեր պատճենելիս։ Նախքան պրոքսի արձանագրությունը փոխելը, ստուգեք ստացման callback-ը և որպես դրա կոնտեքստ փոխանցված օբյեկտը։
CURLOPT_WRITEDATA ցուցիչ է տրամադրում գրելու callback-ին։ Առանց հատուկ callback-ի, libcurl-ի լռելյայն գրիչը սպասում է FILE *։ &response-ի նման հասցեն, որտեղ response-ը std::string է, իմաստ ունի միայն այն դեպքում, երբ ձեր callback-ը այդ կոնտեքստը վերափոխում է նախատեսված տիպի։
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;
}Գրանցեք երկու մասերն էլ փոխանցման համար օգտագործվող պարզ բռնակի վրա։
std::string response;
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response);append կանչը օգտագործում է տրամադրված բայթերի քանակը։ Callback-ի տվյալները զրոյով չեն ավարտվում, և պատկերը կարող է պարունակել զրոյական բայթեր. strlen-ով չափելը կկորցնի մարմնի մի մասը։ Պատասխանը կարող է գալ նաև տարբեր չափերի բազմաթիվ callback կանչերի միջոցով։
Սպառված բայթերի քանակը վերադարձնելը ընդունում է հատվածը։ Այլ քանակ վերադարձնելը դադարեցնում է փոխանցումը գրելու սխալով։ Բացառությունների պահապանը թույլ չի տալիս հիշողության բաշխման ձախողմանը դուրս գալ C callback-ի սահմանից. կանչողը դեռ պետք է ստուգի փոխանցման արդյունքը նախքան response-ը որպես ամբողջական ֆայլ դիտարկելը։
Պահեք տողը կենդանի, մինչև փոխանցումը ավարտվի։ Եթե ասինխրոն սոկետի գրառումը հետո փոխանցում է դրա բովանդակությունը, պահեք այդ բայթերը կենդանի, մինչև այդ գրառումն էլ ավարտվի։ Մեծ պատասխանների համար սահմանափակ հոսքային կարգավորումը նախընտրելի է ամբողջ մարմնի կուտակումից։