قم بتشغيل هذا الرمز:
#include <stdio.h> // printf
#include <zstd.h> // presumes zstd library is installed
void compress()
{
char buffer[256];
ZSTD_inBuffer in;
ZSTD_outBuffer out;
ZSTD_CCtx *cctx;
in.src = ∈
in.size = 0;
in.pos = 0;
out.dst = buffer;
out.size = sizeof(buffer);
out.pos = 0;
cctx = ZSTD_createCCtx();
ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush);
printf("ZSTD_e_flush, total output size: %zd\n", out.pos);
ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush);
printf("ZSTD_e_flush, total output size: %zd\n", out.pos);
ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end);
printf("ZSTD_e_end, total output size: %zd\n", out.pos);
ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end);
printf("ZSTD_e_end, total output size: %zd\n", out.pos);
ZSTD_freeCCtx(cctx);
}
int main(int argc, const char** argv)
{
compress();
return 0;
}
انتاج:
ZSTD_e_flush, total output size: 0
ZSTD_e_flush, total output size: 0
ZSTD_e_end, total output size: 9
ZSTD_e_end, total output size: 18
يبدو أنه لم يتم إنشاء الكتل الفارغة ، ولكن يتم إنشاء إطارات فارغة ، تبدو غير متسقة بعض الشيء.
إذا كان الإطار الحالي لا يحتوي على محتوى ، ألا يمكنه إنشاء إطار فارغ؟
إذا كان الإطار الحالي لا يحتوي على محتوى ، ألا يمكنه إنشاء إطار فارغ؟
صحيح ، لا يمكن إنشاء الإطار الفارغ. تخيل الحالة التي قام فيها شخص ما بتجميع 3 إطارات zstd ، وكان الإطار الثاني فارغًا. إذا لم يكن الإطار الثاني موجودًا لأنه كان فارغًا ، فسنفسر الدفق الثالث على أنه التدفق الثاني ، ونفترض أن الدفق الثالث فارغ. لكن هذا سيكون غير صحيح.
يقوم Zstd دائمًا بإنشاء إطار صالح ، وهو إطار غير فارغ.
إذا كنت ترغب في ذلك ، يمكنك إضافة بعض التعليمات البرمجية أعلى zstd والتي تعين الإدخال الفارغ إلى الإخراج الفارغ. لكن zstd لا يمكنه فعل ذلك.
لا يؤدي التنفيذ الحالي للبث المتدفق zstd
إنشاء كتلة فارغة عند إرشادك إلى flush()
بدون أي محتوى لإرساله. نتيجة لذلك ، فإنه لا يولد كتل فارغة.
إذا كانت هناك حاجة لهذه الإمكانية ، فيمكن تحديث التنفيذ المرجعي لإضافتها ، على الأرجح كمعامل اختياري لعملية التدفق.
ومع ذلك ، هناك مشكلة أخرى: المتغيرات القديمة من وحدة فك الترميز zstd
بها خطأ يجعلها غير قادرة على التعامل مع الكتل الخام الفارغة. تم إصلاح هذا الخطأ حاليًا ، ولكن لدينا قاعدة مستخدمين كبيرة بما يكفي بحيث لا يمكننا اعتبار هذا الإصلاح أمرًا مفروغًا منه. لذلك ، لتحقيق أقصى قدر من التوافق ، يجب ألا ينتج عن تنفيذ zstd
كتل خام فارغة.
يمكن أن يكون الحل البديل هو إرسال كتل فارغة مضغوطة ، والتي من المفارقات أنها أكبر بمقدار 1 بايت. إذا تم طلب إنشاء كتل فارغة ، فستعمل هذه التقنية وستظل متوافقة مع جميع أجهزة فك التشفير التي تم نشرها.
على أي حال ، بدون سبب وجيه كافٍ (سيناريو مهم لدعمه) ، ليس لدينا حافز لجعل تنفيذ المرجع أكثر تعقيدًا ، وبالتالي سنلتزم افتراضيًا بالسياسة الحالية لعدم إنشاء كتل فارغة.
هذا يختلف عن الإطارات الفارغة.
لقد تلقينا الكثير من الطلبات للقدرة على إنشاء إطار zstd
NULL
بمحتوى v1.0
.
هذا مفهوم من منظور خط الأنابيب.
التدفق المعتاد هو input -> zstd compression -> zstd format -> transmit -> assume zstd format -> zstd decompress -> regenerated content
.
يمكن أن يكون الإدخال أي شيء ، بما في ذلك فارغة. وتفضل خطوط الأنابيب المبسطة تجنب الحالات الخاصة ، وبالتالي تفضل إرسال كل شيء إلى zstd
، بدون التفريع الخاص بها لحالات الزاوية.
لذلك يجب أن يكون خط الأنابيب أعلاه متوافقًا مع محتوى null
، والذي يتطلب القدرة على إنشاء وفك تشفير الإطارات الفارغة.
إذا كان السؤال هو بالأحرى: لماذا zstd
فك لا يفسر ل null
مساهمة في فك ضغط باعتباره null
جيل الإخراج،
ثم يكون الرد أكثر تعقيدًا ، ولكن هناك العديد من الأسباب التي تجعلنا نرغب في التمييز بشدة بين حالات الخطأ وغياب الإشارة من الإرسال أو التخزين الصالح للمحتوى الفارغ. على رأس مختلف قيود تحليل حركة المرور. وجعل إدخال null
إدخالًا صالحًا لإلغاء الضغط سيؤدي إلى العبث بهذه الأهداف.
شكرا لك على شرحك.
إذا كنت ترغب في ذلك ، يمكنك إضافة بعض التعليمات البرمجية أعلى zstd والتي تعين الإدخال الفارغ إلى الإخراج الفارغ.
حسنًا ، بالنسبة للأشخاص الذين لديهم مثل هذه الحاجة ، فإن هذا الرمز ليس صعب التنفيذ.