1 /******************************************************************************
2 *
3 * Copyright (C) 2009, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * Author: Alexey Krivonogov ( gentee )
11 *
12 ******************************************************************************/
13
14 type lzge
15 {
16 uint hufblock // Размер блока для построения дерева Хафмана
17 // Определяемые для сжатия
18 uint order // Скорость сжатия от 1 до 10
19 // Вычисляемые параметры
20 uint numoff // Количество элементов смещений из rng
21 uint maxbit // Количество bit на размер окна
22 uint solidoff // Solid смещение
23 uint mft0 // ПОследние базы смещений
24 uint mft1
25 uint mft2
26 uint userfunc
27 uint pgeaparam
28 }
29
30 type ppmd
31 {
32 // uint memory
33 uint order
34 uint userfunc
35 uint pgeaparam
36 }
37
38 type geavolume
39 {
40 uint name // GEA\x0
41 ushort number // The number of the volume 0 for the main volume
42 uint unique // Unique number to detect the volumes
43 }
44
45 // The strcuture of the first volume
46 type geahead
47 {
48 byte majorver // Major version
49 byte minorver // Minor version
50 filetime date // System data of the creation
51 uint flags // Flags
52 ushort count // The count of volumes.
53 uint size // Header size ( till data )
54 long summary // The summary compressed size
55 uint infosize // The unpacked size of file descriptions
56 long geasize // The full size of the main file
57 long volsize // The size of the each volume
58 long lastsize // The size of the last volume file
59 uint movedsize // The moved size from the end to the head
60 byte memory // Memory for PPMD compression ( * MB )
61 byte blocksize // The default size of the block ( * 0x40000 KB )
62 byte solidsize // The previous solid size for LZGE (* 0x40000 KB )
63 }
64
65 type geafile
66 {
67 uint flags // Flags
68 filetime ft // File time
69 uint size // File size
70 uint attrib // File attribute
71 uint crc // File CRC
72 uint hiver // Hi version
73 uint lowver // Low version
74 uint idgroup // id of the group
75 uint idpass // id of the password
76 uint compsize // The compressed size
77 str name // the name of the file
78 str subfolder // the name of the subfolder
79 }
80
81 define <export>
82 {
83 GEA_MAJOR = 1
84 GEA_MINOR = 0
85 GEA_MINVOLSIZE = 0xFFFF // The minimum size of the volume
86 GEA_MAXVOLUMES = 0xFFFF // The maximum count of volumes
87 GEA_DESCRESERVE = 0x200000 // 2 MB резервировать для записи информации
88 // о файлах
89 GEA_NAME = 0x414547 // GEA/x0
90 // geahead.flags
91 GEAH_PASSWORD = 0x0001 // There are protected files
92 GEAH_COMPRESS = 0x0002 // File descriptions are compressed
93
94 // geafile.flags
95 GEAF_ATTRIB = 0x0001 // There is an attribute
96 GEAF_FOLDER = 0x0010 // There is a relative path
97 GEAF_VERSION = 0x0020 // There is a version
98 GEAF_GROUP = 0x0040 // There is a group id
99 GEAF_PROTECT = 0x0080 // There is the number of password
100 GEAF_SOLID = 0x0100 // Uses the information of the previous file
101 }
102
103 // Further
104 // name\x0 - the pattern name of the volumes - geaname.g%02i
105
106 // 3. if geahead.flag & $GEAH_PASSWORD
107 type geapassinfo
108 {
109 ushort count // The count of passwords
110 }
111 // 3.1. array [ geapassinfo.count ] of uint
112 // CRC of passwords
113
114 // 4. The sequence of file descriptions
115
116 type geacompfile
117 {
118 ushort flags // Flags
119 filetime ft // File time
120 uint size // File size
121 uint compsize // The compressed size
122 uint crc
123 }
124 // 1. if geafile.flag & $GEAF_ATTRIB
125 // uint - file attribute - valid for next items
126 // 2. if geafile.flag & $GEAF_VERSION
127 // uint - hi version
128 // uint - low version
129 // 3. if geafile.flag & $GEAF_GROUP
130 // uint - id of the group - valid for next items
131 // 4. if geafile.flag & $GEAF_PROTECT
132 // id - of geapassinfo - valid for next items
133 // from 1. Use 0 for disable protection.
134 // 5. name\x0 - the name of the file
135 // 6. if geafile.flag & $GEAF_FOLDER
136 // subfolder\x0 - the name of the subfolder - valid for next items
137
138 type geadata
139 {
140 byte order
141 uint size
142 }
143
144 // Data blocks
145 // 1. byte - order
146 // 0 - store
147 // 1 - LZGE
148 // 2 - PPMD
149 // * 16 + order если 0 то solid
150 // 17 - LZGE with order 1
151 // 32 - PPMD solid
152 // Старший бит установлен 1 если блок является началом файла
153 // 2. uint - the block's size without sizeof( geadata )
154
155 type geaparam
156 {
157 uint process // packing/unpacking process size
158 uint done // The packed/unpacked size
159 str name // Filename
160 uint info // geafile
161 uint mode // 0 - encoding 1 - decoding
162 }
163
164 define <export>
165 {
166 // Compression algorithms
167 GEA_STORE = 0
168 GEA_LZGE = 1
169 GEA_PPMD = 2
170 // GEA_LZGEOSOLID = 32
171 // GEA_LZGEO = 33
172
173 // IDOK = 1
174 // IDCANCEL = 2
175 GEA_OK = 1
176 GEA_ABORT = 3
177 GEA_RETRY = 4
178 GEA_IGNORE = 5
179 /* IDYES = 6
180 IDNO = 7*/
181
182 GEAERR_PATTERN = 0 // Wrong pattern
183 GEAERR_FILEOPEN // Cannot open file
184 GEAERR_FILEREAD // Cannot read file
185 GEAERR_FILEWRITE // Cannot write file
186 GEAERR_TOOBIG // Too big file
187 GEAERR_MANYVOLUMES // Too many volumes
188 GEAERR_NOTGEA // The file is not GEA archive
189 GEAERR_WRONGVOLUME // The wrong volume
190 GEAERR_WRONGSIZE // The wrong size of the volume
191 GEAERR_INTERNAL // The internal error
192 GEAERR_CRC // The wrong CRC
193 GEAERR_LAST = 100
194 GEAMESS_BEGIN // Beginning of creating GEA file
195 GEAMESS_END // GEA file was created successfully
196 GEAMESS_COPY // Файл уже был включен
197 GEAMESS_ENBEGIN // Начать процесс упаковки файла
198 GEAMESS_DEBEGIN // Начать процесс распаковки файла
199 GEAMESS_WRITEHEAD // Запись GEA заголовка
200 GEAMESS_ENEND // Файл упакован
201 GEAMESS_DEEND // Файл распакован
202 GEAMESS_WRONGVER // The unsupported version of GEA file
203 GEAMESS_GETVOLUME // Get the file of the volume. The application must set
204 // the current directory with the volume
205 GEAMESS_PASSWORD // Требуется пароль
206 GEAMESS_PROCESS = 200 // Процесс упаковки/распаковки
207 }
208
209 func uint geafunc( uint userfunc code, collection cl )
210 {
211 geaparam geap
212
213 if !userfunc : return 0
214 if *cl
215 {
216 geap.name = cl[ 0 ]->str
217 if *cl > 1
218 {
219 geap.info = cl[ 1 ]
220 if *cl > 2 : geap.process = cl[ 2 ]
221 }
222 }
223 return userfunc->func( code, geap )
224 }
225
226 //--------------------------------------------------------------------------
227
228 func gea_passgen( buf pass, str srcpass )
229 {
230 uint icrc i count
231 reserved crcb[4]
232
233 icrc = crc( srcpass.ptr(), *srcpass, 0xFFFFFFFF )
234 pass.expand( 256 )
235 pass.use = 256
236
237 fornum count, 64
238 {
239 crcb[0] = icrc & 0xFF
240 crcb[1] = ( icrc >> 8 ) & 0xFF
241 crcb[2] = ( icrc >> 16 ) & 0xFF
242 crcb[3] = ( icrc >> 24 ) & 0xFF
243
244 fornum i = 0, 4
245 {
246 pass[ ( count << 2 ) + i ] = uint( crcb[ i ] ) & 0xFF
247 }
248 icrc = crc( pass.ptr(), ( count + 1 ) << 2, ?( count,
249 icrc, icrc >> 1 ))
250 }
251 }
252
253 //--------------------------------------------------------------------------
254
255 func gea_protect( uint ptr size, buf password )
256 {
257 reserved crcb[4]
258 uint psw
259
260 crcb[0] = size & 0xFF
261 crcb[1] = ( size >> 8 ) & 0xFF
262 crcb[2] = ( size >> 16 ) & 0xFF
263 crcb[3] = ( size >> 24 ) & 0xFF
264 fornum psw, size
265 {
266 ( ptr + psw )->byte ^= password[ psw & 0xFF ]
267 }
268 }
269
270 //--------------------------------------------------------------------------
271
272 func uint gea_fileopen( str filename, uint flag, uint userfunc )
273 {
274 uint result
275
276 while !( result = open( filename, flag ))
277 {
278 /* switch geafunc( userfunc, $GEAERR_FILEOPEN, %{ filename })
279 {
280 case $GEA_RETRY : goto again
281 case $GEA_ABORT : return 0
282 }*/
283 if geafunc( userfunc, $GEAERR_FILEOPEN, %{ filename }) == $GEA_ABORT
284 {
285 return 0
286 }
287 }
288 return result
289 }
290
291 //--------------------------------------------------------------------------
292