قد يجلب الوكيل HTML بنجاح ومع ذلك يفسد صورة أثناء نسخها إلى مخزن مؤقت بلغة C++. قبل تغيير بروتوكول الوكيل، افحص نداء الاستدعاء الخاص بالاستقبال والكائن الذي يُمرر كسياق له.

CURLOPT_WRITEDATA يزوّد مؤشرًا إلى نداء الكتابة. من دون نداء مخصص، يتوقع كاتب libcurl الافتراضي FILE *. عنوان مثل &response، حيث response من نوع std::string، لا يكون منطقيًا إلا عندما يعيد نداءك تحويل ذلك السياق إلى النوع المقصود.

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);

يستخدم استدعاء الإلحاق عدد البايتات المسلَّم. بيانات نداء الاستدعاء لا تنتهي ببايت صفري، وقد تحتوي الصورة على بايتات صفرية؛ وقياسها باستخدام strlen سيفقد جزءًا من الجسم. وقد تصل الاستجابة عبر العديد من نداءات الاستدعاء بأحجام مختلفة.

إرجاع عدد البايتات المستهلكة يقبل القطعة. وإرجاع عدد مختلف يوقف النقل بخطأ كتابة. يحول حارس الاستثناء دون تسرب فشل تخصيص عبر حدود نداء C؛ وعلى المستدعي أن يتحقق من نتيجة النقل قبل اعتبار response ملفًا كاملًا.

أبقِ السلسلة حية حتى ينتهي النقل. وإذا كانت كتابة مقبس غير متزامنة تمرر محتوياتها بعد ذلك، فأبقِ تلك البايتات حية حتى تكتمل تلك الكتابة أيضًا. للاستجابات الكبيرة، يُفضَّل ترتيب بث محدود بدل تجميع الجسم بأكمله.

مقالات ذات صلة