2
2
title: "REBOL 3 codec for ZIP files"
3
3
name: 'codec-zip
4
4
author: rights: "Oldes"
5
- version: 0.0.3
5
+ version: 0.0.4
6
6
specification: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
7
7
history: [
8
+ 30-Nov-2021 "Oldes" {
9
+ * Access to comment and extra field of uncompressed data
10
+ * Added support to include file comments, extras or insternal and external attributes
11
+ * Added support to include uncompressed data (useful when making APK targeting version 30 and above)
12
+ }
8
13
24-Oct-2019 "Oldes" {
9
14
* Refactored decoder so it is using central directory structure
10
15
* Added decode/info refinement used to resolve just the info about files without decompressing
@@ -78,7 +83,7 @@ register-codec [
78
83
cheader: binary/read bin [
79
84
UI16LE ; version made by
80
85
UI16LE ; version needed to extract
81
- BITSET16 ; general purpose bit flag
86
+ flags: BITSET16 ; general purpose bit flag
82
87
method: UI16LE ; compression method
83
88
modified: MSDOS-DATETIME ; last modified
84
89
crc: SI32LE ; crc-32
@@ -131,7 +136,12 @@ register-codec [
131
136
sys/log/error 'ZIP ["CRC check failed!" crc "<>" crc2]
132
137
]
133
138
]
134
- repend result [name reduce [modified data crc]]
139
+ data: reduce [modified data crc]
140
+ unless empty? extr [append append data quote extra: extr]
141
+ unless empty? comm [append append data quote comment: comm]
142
+ if att-int <> 0 [append append data quote att-int: att-int]
143
+ if att-ext <> 0 [append append data quote att-ext: att-ext]
144
+ append /only append result name data
135
145
]
136
146
137
147
if only [
@@ -149,7 +159,7 @@ register-codec [
149
159
150
160
encode: wrap [
151
161
bin: dir: data: date: file: add-data: root: none
152
- compressed-data: method:
162
+ compressed-data: method: att-ext: att-int:
153
163
compressed-size: size: crc: entries: filename-length: offset: 0
154
164
155
165
add-file : func [ file [file! ] /local dir spec] [
@@ -178,12 +188,12 @@ register-codec [
178
188
]
179
189
]
180
190
181
- add-data : func [ file spec] [
191
+ add-data : func [ file spec /local no-compress? extra extra-length comm comm-length ] [
182
192
sys/log/info 'ZIP ["Adding:" as-green file]
183
193
184
194
any [file? file cause-error 'user 'message reduce [reform ["found" type? file "where file! expected" ]]]
185
195
data: date: none
186
- compressed-size: size: crc: filename-length: 0
196
+ compressed-size: size: crc: filename-length: extra-length: comm-length: att-ext: att-int: 0
187
197
any [
188
198
all [
189
199
block? spec
@@ -192,6 +202,14 @@ register-codec [
192
202
date! (date: spec/1 )
193
203
| string! (data: to binary! spec/1 )
194
204
| binary! (data: spec/1 )
205
+ | 'store (no-compress?: true)
206
+ | quote extra: set extra binary! (extra-length: length? extra)
207
+ | quote comment: set comm [binary! | any-string! ] (
208
+ if string? comm [comm: to binary! comm]
209
+ comm-length: length? comm
210
+ )
211
+ | quote att-int: set att-int integer!
212
+ | quote att-ext: set att-ext integer!
195
213
| 1 skip
196
214
]]
197
215
]
@@ -205,9 +223,13 @@ register-codec [
205
223
continue
206
224
]
207
225
]
226
+ data: any [data #{} ]
227
+ crc: checksum data 'CRC32
228
+ size: length? data
208
229
method: either any [
209
- none? data
210
- lesser-or-equal? size: length? data length? compressed-data: compress data 'deflate
230
+ no-compress?
231
+ zero? size
232
+ lesser-or-equal? size length? compressed-data: compress data 'deflate
211
233
][
212
234
compressed-data: data
213
235
0 ;store
@@ -216,18 +238,21 @@ register-codec [
216
238
]
217
239
218
240
either compressed-data [
219
- crc: checksum data 'CRC32
220
241
compressed-size: length? compressed-data
221
242
][ compressed-data: #{}
222
243
compressed-size: 0
223
244
]
245
+
224
246
if any [
225
247
none? date
226
248
"?date?" = form date ; temp fix for invalid date!
227
249
][ date: now ]
228
250
229
251
filename-length: length? file
230
- offset: -1 + index? bin/buffer-write
252
+ offset: indexZ? bin/buffer-write
253
+
254
+ unless extra [extra: #{} ]
255
+ unless comm [comm: #{} ]
231
256
232
257
binary/write bin [
233
258
#{ 504B0304 1400 0000 } ;signature / version / flags
@@ -242,22 +267,22 @@ register-codec [
242
267
BYTES :compressed-data
243
268
]
244
269
binary/write dir [
245
- #{ 504B0102 1400 1400 0000 } ; signature / version made / version needed / flags
270
+ #{ 504B0102 1703 1400 0000 } ; signature / version made / version needed / flags
246
271
UI16LE :method
247
272
MSDOS-DATETIME :date
248
273
UI32LE :crc
249
274
UI32LE :compressed-size
250
275
UI32LE :size
251
276
UI16LE :filename-length
252
- UI16LE 0 ; Extra field length
253
- UI16LE 0 ; File comment length
254
- UI16LE 0 ; Disk number where file starts
255
- UI16LE 0 ; Internal file attributes
256
- UI32LE 0 ; External file attributes
257
- UI32LE :offset ; Relative offset of local file header
277
+ UI16LE :extra-length ; Extra field length
278
+ UI16LE :comm-length ; File comment length
279
+ UI16LE 0 ; Disk number where file starts
280
+ UI16LE :att-int ; Internal file attributes
281
+ UI32LE :att-ext ; External file attributes
282
+ UI32LE :offset ; Relative offset of local file header
258
283
BYTES :file
259
- ;#{} ; Extra field
260
- ;#{} ; File comment
284
+ BYTES :extra ; Extra field
285
+ BYTES :comm ; File comment
261
286
]
262
287
++ entries
263
288
]
@@ -312,7 +337,7 @@ register-codec [
312
337
header [block! ] "[method cmp-size unc-size]"
313
338
] [
314
339
bin: binary buffer
315
- unless 67324752 = binary/read bin 'UI32LE [
340
+ unless 67324752 = binary/read bin 'UI32LE [ ;#{504B0304}
316
341
sys/log/error 'ZIP {Offset is not pointing to the "Local file header"}
317
342
return none
318
343
]
0 commit comments