archiver.obj ýêñïîðòèðóåò äâå ôóíêöèè äëÿ ðàñïàêîâêè deflate-äàííûõ.
À òàêæå ôóíêöèè: deflateInit, deflateInit2, deflateReset, deflate,
deflateEnd äëÿ óïàêîâêè deflate-äàííûõ, ñäåëàííûå íà îñíîâå ñâîáîäíî
ðàñïðîñòðàíÿåìîé áèáëèîòåêè zlib.
Ïåðâàÿ: 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
Àëãîðèòì äëÿ óïàêîâêè äàííûõ:
1) Âûçîâ ôóíêöèè deflateInit èëè deflateInit2.
2) Ðàçáèåíèå âõîäíîãî ïîòîêà äàííûõ íà ïîðöèè ïî 64 Êá.
Äëÿ êàæäîãî áëîêà â 64 Êá â öèêëå äîëæåí äåëàòüñÿ âûçîâ ôóíêöèè deflate.
Çà îäèí âûçîâ ôóíêöèè deflate ñæàòûõ äàííûõ îáðàçóåòñÿ íå áîëåå 16 Êá.
Ò. å. åñëè ñæèìàåìûõ äàííûõ ìåíåå 16 Êá, òî èõ ìîæíî óïàêîâàòü çà îäèí âûçîâ deflate.
Åñëè ñæèìàåìûõ äàííûõ ìåíåå 64 Êá, òî èõ ìîæíî óïàêîâàòü îðãàíèçîâàâ îäèí öèêë ñ âûçîâîì deflate.
Åñëè ñæèìàåìûõ äàííûõ áîëåå 64 Êá, òî èõ ìîæíî óïàêîâàòü îðãàíèçîâàâ äâîéíîé öèêë ñ âûçîâîì deflate.
3) Âûçîâ ôóíêöèè deflateEnd äëÿ î÷èñòêè ïàìÿòè.
Çàìå÷àíèÿ:
Áîëüøèå óðîâíè ñæàòèÿ ïîêà ÷òî íå ïîääåðæèâàþòñÿ.
Ôóíêöèÿ deflate íå êîðåêòíî ðàáîòàåò ñ ïàðàìåòðîì Z_NO_FLUSH.
(Ïîêà ïðîáëåìà íå óñòðàíåíà ðåêîìåíäóåòñÿ âñåãäà ñòàâèòü Z_FINISH)