Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1149 diamond 1
archiver.obj экспортирует две функции для распаковки deflate-данных.
2
 
3
Первая: deflate_unpack
4
Объявление в стиле Си: void* __stdcall deflate_unpack(const void* data, unsigned* pLength);
5
Аргументы:
6
	data - указатель на упакованные данные
7
	pLength - указатель на переменную длины:
8
		на входе *pLength должно содержать длину входных данных data,
9
		на выходе *pLength заполнится длиной выходных данных
10
Возвращаемое значение:
11
	указатель на распакованные данные, NULL при нехватке памяти
12
	память выделяет сам распаковщик, освободить её можно стандартной
13
		функцией 68.13
14
Пример вызова из ассемблерного кода:
15
; пусть esi = указатель на данные, ecx = длина упакованных данных
16
	push	ecx	; переменная *pLength будет в стеке
17
	push	esp	; а вот и указатель на неё pLength
18
	push	esi	; а это данные
19
	call	[deflate_unpack]
20
	pop	ecx	; вытолкнем из стека переменную *pLength
21
			; два аргумента вытолкнет сама deflate_unpack
22
; теперь eax = указатель на распакованные данные, ecx = их длина
23
 
24
Вторая: deflate_unpack2
25
Объявление в стиле Си: void* __stdcall deflate_unpack2(const void* get_next_chunk, void* parameter, unsigned* pUnpackedLength);
26
	void* __stdcall get_next_chunk(void* parameter, unsigned* pLength);
27
Аргументы:
28
	get_next_chunk - указатель на функцию, возвращающую указатель и длину
29
		очередного блока упакованных данных; когда данные
30
		заканчиваются, должна возвращать NULL (при корректных
31
		упакованных данных такой ситуации не может быть в принципе,
32
		при некорректных данных если функция вернула NULL, то
33
		дальнейших вызовов не будет)
34
	parameter - сущность, которая не используется самим распаковщиком
35
		и без изменений передаётся в get_next_chunk
36
		(если callback-функции она тоже не нужна, можно передавать
37
		в этом параметре всё, что угодно)
38
	pUnpackedLength - указатель на переменную, куда будет записана
39
		длина распакованных данных
40
Возвращаемое значение:
41
	указатель на распакованные данные, NULL при нехватке памяти
42
	память выделяет сам распаковщик, освободить её можно стандартной
43
		функцией 68.13
44
Пример вызова из ассемблерного кода:
45
	push	eax	; выделяем в стеке переменную для *pUnpackedLength
46
			; поскольку значение неважно, короче и быстрее всего
47
			; сделать это однобайтовым push <регистр>
48
	push	esp	; а вот и сам указатель pUnpackedLength
49
	push	esi	; какой-нибудь параметр
50
	push	deflate_callback
51
	call	[deflate_unpack2]
52
	pop	ecx	; выталкиваем UnpackedLength
53
; как и в первом случае, eax = указатель на распакованные данные, ecx = размер
54
 
55
...
56
 
57
; а это функция получения следующего куска упакованных данных
58
deflate_callback:
59
; если нужен параметр, то достать его можно так:
60
;	mov	esi, [esp+4]	; esi = параметр
61
; тут какие-то действия
62
; и вот результат
63
	mov	ecx, [esp+8]	; в [ecx] нужно записать длину
64
	mov	[ecx], length
65
	mov	eax, buffer
66
	ret	8