diff --git a/programs/fs/kfar/trunk/kfar_arc/archiver_deflate.txt b/programs/fs/kfar/trunk/kfar_arc/archiver_deflate.txt new file mode 100644 index 0000000000..7fbc83a372 --- /dev/null +++ b/programs/fs/kfar/trunk/kfar_arc/archiver_deflate.txt @@ -0,0 +1,66 @@ +archiver.obj экспортирует две функции для распаковки deflate-данных. + +Первая: deflate_unpack +Объявление в стиле Си: void* __stdcall deflate_unpack(const void* data, unsigned* pLength); +Аргументы: + data - указатель на упакованные данные + pLength - указатель на переменную длины: + на входе *pLength должно содержать длину входных данных data, + на выходе *pLength заполнится длиной выходных данных +Возвращаемое значение: + указатель на распакованные данные, NULL при нехватке памяти + память выделяет сам распаковщик, освободить её можно стандартной + функцией 68.13 +Пример вызова из ассемблерного кода: +; пусть esi = указатель на данные, ecx = длина упакованных данных + push ecx ; переменная *pLength будет в стеке + push esp ; а вот и указатель на неё pLength + push esi ; а это данные + call [deflate_unpack] + pop ecx ; вытолкнем из стека переменную *pLength + ; два аргумента вытолкнет сама deflate_unpack +; теперь eax = указатель на распакованные данные, ecx = их длина + +Вторая: deflate_unpack2 +Объявление в стиле Си: void* __stdcall deflate_unpack2(const void* get_next_chunk, void* parameter, unsigned* pUnpackedLength); + void* __stdcall get_next_chunk(void* parameter, unsigned* pLength); +Аргументы: + get_next_chunk - указатель на функцию, возвращающую указатель и длину + очередного блока упакованных данных; когда данные + заканчиваются, должна возвращать NULL (при корректных + упакованных данных такой ситуации не может быть в принципе, + при некорректных данных если функция вернула NULL, то + дальнейших вызовов не будет) + parameter - сущность, которая не используется самим распаковщиком + и без изменений передаётся в get_next_chunk + (если callback-функции она тоже не нужна, можно передавать + в этом параметре всё, что угодно) + pUnpackedLength - указатель на переменную, куда будет записана + длина распакованных данных +Возвращаемое значение: + указатель на распакованные данные, NULL при нехватке памяти + память выделяет сам распаковщик, освободить её можно стандартной + функцией 68.13 +Пример вызова из ассемблерного кода: + push eax ; выделяем в стеке переменную для *pUnpackedLength + ; поскольку значение неважно, короче и быстрее всего + ; сделать это однобайтовым push <регистр> + push esp ; а вот и сам указатель pUnpackedLength + push esi ; какой-нибудь параметр + push deflate_callback + call [deflate_unpack2] + pop ecx ; выталкиваем UnpackedLength +; как и в первом случае, eax = указатель на распакованные данные, ecx = размер + +... + +; а это функция получения следующего куска упакованных данных +deflate_callback: +; если нужен параметр, то достать его можно так: +; mov esi, [esp+4] ; esi = параметр +; тут какие-то действия +; и вот результат + mov ecx, [esp+8] ; в [ecx] нужно записать длину + mov [ecx], length + mov eax, buffer + ret 8