archive-zip: write ZIP dir entry directly to strbuf
Write all fields of the ZIP directory record for an archive entry in the right order directly into the strbuf instead of taking a detour through a struct. Do that at end, when we have all necessary data like checksum and compressed size. The fields are documented just as well, the code becomes shorter and we save an extra copy. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe committed
Apr 24, 2017 at 19:31 UTC
3c78fd808d8ed8848fe09735c7755ddd35cfe83f
1 file changed
+27
-54
archive-zip.c
+27
-54
@@ -45,27 +45,6 @@ struct zip_data_desc {
45
unsigned char _end[1];
46
};
47
48
-struct zip_dir_header {
49
- unsigned char magic[4];
50
- unsigned char creator_version[2];
51
- unsigned char version[2];
52
- unsigned char flags[2];
53
- unsigned char compression_method[2];
54
- unsigned char mtime[2];
55
- unsigned char mdate[2];
56
- unsigned char crc32[4];
57
- unsigned char compressed_size[4];
58
- unsigned char size[4];
59
- unsigned char filename_length[2];
60
- unsigned char extra_length[2];
61
- unsigned char comment_length[2];
62
- unsigned char disk[2];
63
- unsigned char attr1[2];
64
- unsigned char attr2[4];
65
- unsigned char offset[4];
66
- unsigned char _end[1];
67
-};
68
-
48
struct zip_dir_trailer {
49
unsigned char magic[4];
50
unsigned char disk[2];
@@ -166,6 +145,15 @@ static void copy_le16_clamp(unsigned char *dest, uint64_t n, int *clamped)
145
copy_le16(dest, clamp_max(n, 0xffff, clamped));
146
}
147
148
+static int strbuf_add_le(struct strbuf *sb, size_t size, uintmax_t n)
149
+{
150
+ while (size-- > 0) {
151
+ strbuf_addch(sb, n & 0xff);
152
+ n >>= 8;
153
+ }
154
+ return -!!n;
155
+}
156
+
157
static void *zlib_deflate_raw(void *data, unsigned long size,
158
int compression_level,
159
unsigned long *compressed_size)
@@ -212,16 +200,6 @@ static void write_zip_data_desc(unsigned long size,
200
write_or_die(1, &trailer, ZIP_DATA_DESC_SIZE);
201
}
202
215
-static void set_zip_dir_data_desc(struct zip_dir_header *header,
216
- unsigned long size,
217
- unsigned long compressed_size,
218
- unsigned long crc)
219
-{
220
- copy_le32(header->crc32, crc);
221
- copy_le32(header->compressed_size, compressed_size);
222
- copy_le32(header->size, size);
223
-}
224
-
203
static void set_zip_header_data_desc(struct zip_local_header *header,
204
unsigned long size,
205
unsigned long compressed_size,
@@ -261,7 +239,7 @@ static int write_zip_entry(struct archiver_args *args,
239
unsigned int mode)
240
{
241
struct zip_local_header header;
264
- struct zip_dir_header dirent;
242
+ uintmax_t offset = zip_offset;
243
struct zip_extra_mtime extra;
244
unsigned long attr2;
245
unsigned long compressed_size;
@@ -353,21 +331,6 @@ static int write_zip_entry(struct archiver_args *args,
331
extra.flags[0] = 1; /* just mtime */
332
copy_le32(extra.mtime, args->time);
333
356
- copy_le32(dirent.magic, 0x02014b50);
357
- copy_le16(dirent.creator_version, creator_version);
358
- copy_le16(dirent.version, 10);
359
- copy_le16(dirent.flags, flags);
360
- copy_le16(dirent.compression_method, method);
361
- copy_le16(dirent.mtime, zip_time);
362
- copy_le16(dirent.mdate, zip_date);
363
- set_zip_dir_data_desc(&dirent, size, compressed_size, crc);
364
- copy_le16(dirent.filename_length, pathlen);
365
- copy_le16(dirent.extra_length, ZIP_EXTRA_MTIME_SIZE);
366
- copy_le16(dirent.comment_length, 0);
367
- copy_le16(dirent.disk, 0);
368
- copy_le32(dirent.attr2, attr2);
369
- copy_le32(dirent.offset, zip_offset);
370
-
334
copy_le32(header.magic, 0x04034b50);
335
copy_le16(header.version, 10);
336
copy_le16(header.flags, flags);
@@ -406,8 +369,6 @@ static int write_zip_entry(struct archiver_args *args,
369
370
write_zip_data_desc(size, compressed_size, crc);
371
zip_offset += ZIP_DATA_DESC_SIZE;
409
-
410
- set_zip_dir_data_desc(&dirent, size, compressed_size, crc);
372
} else if (stream && method == 8) {
373
unsigned char buf[STREAM_BUFFER_SIZE];
374
ssize_t readlen;
@@ -464,8 +425,6 @@ static int write_zip_entry(struct archiver_args *args,
425
426
write_zip_data_desc(size, compressed_size, crc);
427
zip_offset += ZIP_DATA_DESC_SIZE;
467
-
468
- set_zip_dir_data_desc(&dirent, size, compressed_size, crc);
428
} else if (compressed_size > 0) {
429
write_or_die(1, out, compressed_size);
430
zip_offset += compressed_size;
@@ -474,9 +433,23 @@ static int write_zip_entry(struct archiver_args *args,
433
free(deflated);
434
free(buffer);
435
477
- copy_le16(dirent.attr1, !is_binary);
478
-
479
- strbuf_add(&zip_dir, &dirent, ZIP_DIR_HEADER_SIZE);
436
+ strbuf_add_le(&zip_dir, 4, 0x02014b50); /* magic */
437
+ strbuf_add_le(&zip_dir, 2, creator_version);
438
+ strbuf_add_le(&zip_dir, 2, 10); /* version */
439
+ strbuf_add_le(&zip_dir, 2, flags);
440
+ strbuf_add_le(&zip_dir, 2, method);
441
+ strbuf_add_le(&zip_dir, 2, zip_time);
442
+ strbuf_add_le(&zip_dir, 2, zip_date);
443
+ strbuf_add_le(&zip_dir, 4, crc);
444
+ strbuf_add_le(&zip_dir, 4, compressed_size);
445
+ strbuf_add_le(&zip_dir, 4, size);
446
+ strbuf_add_le(&zip_dir, 2, pathlen);
447
+ strbuf_add_le(&zip_dir, 2, ZIP_EXTRA_MTIME_SIZE);
448
+ strbuf_add_le(&zip_dir, 2, 0); /* comment length */
449
+ strbuf_add_le(&zip_dir, 2, 0); /* disk */
450
+ strbuf_add_le(&zip_dir, 2, !is_binary);
451
+ strbuf_add_le(&zip_dir, 4, attr2);
452
+ strbuf_add_le(&zip_dir, 4, offset);
453
strbuf_add(&zip_dir, path, pathlen);
454
strbuf_add(&zip_dir, &extra, ZIP_EXTRA_MTIME_SIZE);
455
zip_dir_entries++;