Skip to content

Commit 85f69a1

Browse files
committed
Various tweaks and cleanups of the zip file reader.
1 parent 28df892 commit 85f69a1

File tree

3 files changed

+78
-69
lines changed

3 files changed

+78
-69
lines changed

lws-term/io.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66

77
#ifdef LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP
88
#define USE_NEW_FOPS 1
9+
#define LWS_INVALID_FILEFD NULL
10+
static struct lws_plat_file_ops zip_fops;
911
#else
1012
#define USE_NEW_FOPS 0
13+
#define LWS_INVALID_FILEFD LWS_INVALID_FILE
1114
#endif
1215

1316
struct junzip_mem_handle {
@@ -47,7 +50,7 @@ junzip_mem_close(JZFile *zfile)
4750
close(handle->fd);
4851
}
4952

50-
JZFile *
53+
static JZFile *
5154
init_junzip_handle(struct junzip_mem_handle *handle,
5255
char *start, off_t length, int fd)
5356
{
@@ -98,7 +101,7 @@ domserver_fops_open(struct lws *wsi, const char *filename,
98101
fop_fd = xmalloc(sizeof(*fop_fd)+sizeof(struct open_mem_file));
99102
mem = (struct open_mem_file*) (fop_fd+1);
100103
fop_fd->filesystem_priv = mem;
101-
fop_fd->fops = fops;
104+
fop_fd->fops = &zip_fops;
102105
#else
103106
int j = MAX_OPEN_MEM_FILES;
104107
for (;;) {
@@ -114,9 +117,10 @@ domserver_fops_open(struct lws *wsi, const char *filename,
114117
mem->handle = &junzip_handler;
115118
mem->index = i;
116119
mem->position = 0;
117-
size_t offset = entry->offset;
118-
offset += ZIP_LOCAL_FILE_HEADER_LENGTH;
119-
offset += entry->fileNameLength + entry->extraFieldLength;
120+
if (jzSeekData(&junzip_handler.handle, entry) != Z_OK) {
121+
return LWS_INVALID_FILEFD;
122+
}
123+
size_t offset = zip->position;
120124
unsigned long rsize;
121125
int sentCompressed = 0;
122126
#ifdef LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP
@@ -150,19 +154,14 @@ domserver_fops_open(struct lws *wsi, const char *filename,
150154
}
151155
#endif
152156
if (! sentCompressed) {
153-
zf_seek_set(zip, offset);
154157
rsize = uncompressedSize;
155158
char *data = xmalloc(rsize);
156159
mem->data = data;
157160
if (jzReadData(&junzip_handler.handle,
158-
entry, data) != Z_OK) {
161+
entry, data) != Z_OK) {
159162
fprintf(stderr, "Couldn't read file data!");
160163
free(data);
161-
#if USE_NEW_FOPS
162-
return NULL;
163-
#else
164-
return LWS_INVALID_FILE;
165-
#endif
164+
return LWS_INVALID_FILEFD;
166165
}
167166
}
168167
mem->length = rsize;
@@ -175,11 +174,7 @@ domserver_fops_open(struct lws *wsi, const char *filename,
175174
}
176175
}
177176
errno = EMFILE;
178-
#if USE_NEW_FOPS
179-
return NULL;
180-
#else
181-
return LWS_INVALID_FILE;
182-
#endif
177+
return LWS_INVALID_FILEFD;
183178
}
184179

185180
/* call through to original platform implementation */
@@ -264,6 +259,14 @@ domserver_fops_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
264259
#endif
265260
}
266261

262+
static struct lws_plat_file_ops zip_fops = {
263+
domserver_fops_open,
264+
domserver_fops_close,
265+
domserver_fops_seek_cur,
266+
domserver_fops_read,
267+
NULL
268+
};
269+
267270
void
268271
initialize_resource_map(struct lws_context *context,
269272
const char *domterm_jar_path)
@@ -301,7 +304,9 @@ initialize_resource_map(struct lws_context *context,
301304
fops_plat = *(lws_get_fops(context));
302305
/* override the active fops */
303306
lws_get_fops(context)->open = domserver_fops_open;
307+
#if ! USE_NEW_FOPS
304308
lws_get_fops(context)->close = domserver_fops_close;
305309
lws_get_fops(context)->seek_cur = domserver_fops_seek_cur;
306310
lws_get_fops(context)->read = domserver_fops_read;
311+
#endif
307312
}

lws-term/junzip.c

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,46 @@
1-
// JUnzip library by Joonas Pihlajamaa. See junzip.h for license and details.
1+
// Unzip library by Per Bothner and Joonas Pihlajamaa.
2+
// See junzip.h for license and details.
23

3-
#include <stdio.h>
44
#include <stdlib.h>
55
#include <string.h>
66

77
#include <zlib.h>
88

99
#include "junzip.h"
1010

11-
int
11+
#define ZIP_CENTRAL_SIGNATURE 0
12+
#define ZIP_CENTRAL_VERSION_MADE_BY 4
13+
#define ZIP_CENTRAL_VERSION_NEEDED_TO_EXTRACT 6
14+
#define ZIP_CENTRAL_GENERAL_PURPOSE_BIT_FLAG 8
15+
#define ZIP_CENTRAL_COMPRESSION_METHOD 10
16+
#define ZIP_CENTRAL_LAST_MOD_FILE_TIME 12
17+
#define ZIP_CENTRAL_LAST_MOD_FILE_DATE 14
18+
#define ZIP_CENTRAL_CRC32 16
19+
#define ZIP_CENTRAL_COMPRESSED_SIZE 20
20+
#define ZIP_CENTRAL_UNCOMPRESSED_SIZE 24
21+
#define ZIP_CENTRAL_FILE_NAME_LENGTH 28
22+
#define ZIP_CENTRAL_EXTRA_FIELD_LENGTH 30
23+
#define ZIP_CENTRAL_FILE_COMMENT_LENGTH 32
24+
#define ZIP_CENTRAL_DISK_NUMBER_START 34
25+
#define ZIP_CENTRAL_INTERNAL_FILE_ATTRIBUTES 36
26+
#define ZIP_CENTRAL_EXTERNAL_FILE_ATTRIBUTES 38
27+
#define ZIP_CENTRAL_RELATIVE_OFFSET_OF_LOCAL_HEADER 42
28+
#define ZIP_CENTRAL_DIRECTORY_LENGTH 46
29+
30+
#define ZIP_END_SIGNATURE_OFFSET 0
31+
#define ZIP_END_DESK_NUMBER 4
32+
#define ZIP_END_CENTRAL_DIRECTORY_DISK_NUMBER 6
33+
#define ZIP_END_NUM_ENTRIES_THIS_DISK 8
34+
#define ZIP_END_NUM_ENTRIES 10
35+
#define ZIP_END_CENTRAL_DIRECTORY_SIZE 12
36+
#define ZIP_END_CENTRAL_DIRECTORY_OFFSET 16
37+
#define ZIP_END_ZIP_COMMENT_LENGTH 20
38+
#define ZIP_END_DIRECTORY_LENGTH 22
39+
40+
#define get_u16(PTR) ((PTR)[0] | ((PTR)[1] << 8))
41+
#define get_u32(PTR) ((PTR)[0] | ((PTR)[1]<<8) | ((PTR)[2]<<16) | ((PTR)[3]<<24))
42+
43+
static int
1244
zf_seek_set(JZFile *zfile, size_t offset)
1345
{
1446
int new_position = offset;
@@ -18,7 +50,7 @@ zf_seek_set(JZFile *zfile, size_t offset)
1850
return 0;
1951
}
2052

21-
int
53+
static int
2254
zf_seek_cur(JZFile *zfile, size_t offset)
2355
{
2456
int new_position = zfile->position + offset;
@@ -28,7 +60,7 @@ zf_seek_cur(JZFile *zfile, size_t offset)
2860
return 0;
2961
}
3062

31-
int
63+
static int
3264
zf_seek_end(JZFile *zfile, size_t offset)
3365
{
3466
int new_position = zfile->length + offset;
@@ -53,14 +85,12 @@ int jzReadEndRecord(JZFile *zip) {
5385
long fileSize, readBytes, i;
5486

5587
if(zf_seek_end(zip, -ZIP_END_DIRECTORY_LENGTH)) {
56-
fprintf(stderr, "Too small file to be a zip!");
5788
return Z_ERRNO;
5889
}
5990

6091
unsigned char *ptr = zf_current(zip);
6192
while (ptr[0] != 0x50 || ptr[1] != 0x4B || ptr[2] != 0x05 || ptr[3] != 0x06) {
6293
if (ptr == zip->start) {
63-
fprintf(stderr, "End record signature not found in zip!");
6494
return Z_ERRNO;
6595
}
6696
ptr--;
@@ -70,7 +100,6 @@ int jzReadEndRecord(JZFile *zip) {
70100
if (get_u16(ptr + ZIP_END_DESK_NUMBER)
71101
|| get_u16(ptr + ZIP_END_CENTRAL_DIRECTORY_DISK_NUMBER)
72102
|| zip->numEntries != get_u16(ptr + ZIP_END_NUM_ENTRIES_THIS_DISK)) {
73-
fprintf(stderr, "Multifile zips not supported!");
74103
return Z_ERRNO;
75104
}
76105

@@ -83,19 +112,16 @@ int jzReadCentralDirectory(JZFile *zip, JZRecordCallback callback) {
83112
int i;
84113

85114
if(zf_seek_set(zip, zip->centralDirectoryOffset)) {
86-
fprintf(stderr, "Cannot seek in zip file!");
87115
return Z_ERRNO;
88116
}
89117

90118
for(i=0; i < zip->numEntries; i++) {
91119
unsigned char *ptr = zf_current(zip);
92120
if (zf_available(zip) < ZIP_CENTRAL_DIRECTORY_LENGTH) {
93-
fprintf(stderr, "Couldn't read file header %d!", i);
94121
return Z_ERRNO;
95122
}
96123
zf_seek_cur(zip, ZIP_CENTRAL_DIRECTORY_LENGTH);
97124
if (get_u32(ptr + ZIP_CENTRAL_SIGNATURE) != 0x02014B50) {
98-
fprintf(stderr, "Invalid file header signature %d!", i);
99125
return Z_ERRNO;
100126
}
101127
// Construct JZFileHeader from global file header
@@ -109,7 +135,6 @@ int jzReadCentralDirectory(JZFile *zip, JZRecordCallback callback) {
109135

110136
header.fileNameStart = zf_tell(zip);
111137
if (zf_seek_cur(zip, header.fileNameLength + header.extraFieldLength + get_u16(ptr + ZIP_CENTRAL_FILE_COMMENT_LENGTH))) {
112-
fprintf(stderr, "Couldn't skip extra field or file comment %d", i);
113138
return Z_ERRNO;
114139
}
115140

@@ -120,6 +145,16 @@ int jzReadCentralDirectory(JZFile *zip, JZRecordCallback callback) {
120145
return Z_OK;
121146
}
122147

148+
int jzSeekData(JZFile *zip, JZFileHeader *entry) {
149+
size_t offset = entry->offset;
150+
offset += ZIP_LOCAL_FILE_HEADER_LENGTH;
151+
offset += entry->fileNameLength + entry->extraFieldLength;
152+
if (offset < 0 || offset > zip->length)
153+
return Z_STREAM_END;
154+
zip->position = offset;
155+
return Z_OK;
156+
}
157+
123158
// Read data from file stream, described by header, to preallocated buffer
124159
int jzReadData(JZFile *zip, JZFileHeader *header, void *buffer) {
125160
unsigned char *bytes = (unsigned char *)buffer; // cast
@@ -128,10 +163,10 @@ int jzReadData(JZFile *zip, JZFileHeader *header, void *buffer) {
128163
int ret;
129164

130165
if(header->compressionMethod == 0) { // Store - just read it
131-
if(zf_read(zip, buffer, header->uncompressedSize) <
166+
if (zf_read(zip, buffer, header->uncompressedSize) <
132167
header->uncompressedSize)
133168
return Z_ERRNO;
134-
} else if(header->compressionMethod == 8) { // Deflate - using zlib
169+
} else if (header->compressionMethod == 8) { // Deflate - using zlib
135170
strm.zalloc = Z_NULL;
136171
strm.zfree = Z_NULL;
137172
strm.opaque = Z_NULL;
@@ -140,11 +175,11 @@ int jzReadData(JZFile *zip, JZFileHeader *header, void *buffer) {
140175
strm.next_in = Z_NULL;
141176

142177
// Use inflateInit2 with negative window bits to indicate raw data
143-
if((ret = inflateInit2(&strm, -MAX_WBITS)) != Z_OK)
178+
if ((ret = inflateInit2(&strm, -MAX_WBITS)) != Z_OK)
144179
return ret; // Zlib errors are negative
145180

146181
// Inflate compressed data
147-
for(compressedLeft = header->compressedSize,
182+
for (compressedLeft = header->compressedSize,
148183
uncompressedLeft = header->uncompressedSize;
149184
compressedLeft && uncompressedLeft && ret != Z_STREAM_END;
150185
compressedLeft -= strm.avail_in) {

lws-term/junzip.h

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/**
2-
* JUnzip library by Joonas Pihlajamaa ([email protected]).
2+
* Unzip library by Per Bothner.
3+
* Loosely based on Joonas Pihlajamaa's JUnzip.
34
* Released into public domain. https://github.com/jokkebk/JUnzip
45
*/
56

@@ -29,34 +30,9 @@ struct JZFile {
2930
#define zf_tell(ZF) ((ZF)->position)
3031
#define zf_available(ZF) ((ZF)->length - (ZF)->position)
3132
#define zf_current(ZF) ((ZF)->start + (ZF)->position)
32-
extern size_t zf_read(JZFile *zfile, void *buf, size_t size);
33-
extern int zf_seek_set(JZFile *zfile, size_t offset);
34-
extern int zf_seek_cur(JZFile *zfile, size_t offset);
35-
extern int zf_seek_end(JZFile *zfile, size_t offset);
36-
#define get_u16(PTR) ((PTR)[0] | ((PTR)[1] << 8))
37-
#define get_u32(PTR) ((PTR)[0] | ((PTR)[1]<<8) | ((PTR)[2]<<16) | ((PTR)[3]<<24))
3833

3934
#define ZIP_LOCAL_FILE_HEADER_LENGTH 30
4035

41-
#define ZIP_CENTRAL_SIGNATURE 0
42-
#define ZIP_CENTRAL_VERSION_MADE_BY 4
43-
#define ZIP_CENTRAL_VERSION_NEEDED_TO_EXTRACT 6
44-
#define ZIP_CENTRAL_GENERAL_PURPOSE_BIT_FLAG 8
45-
#define ZIP_CENTRAL_COMPRESSION_METHOD 10
46-
#define ZIP_CENTRAL_LAST_MOD_FILE_TIME 12
47-
#define ZIP_CENTRAL_LAST_MOD_FILE_DATE 14
48-
#define ZIP_CENTRAL_CRC32 16
49-
#define ZIP_CENTRAL_COMPRESSED_SIZE 20
50-
#define ZIP_CENTRAL_UNCOMPRESSED_SIZE 24
51-
#define ZIP_CENTRAL_FILE_NAME_LENGTH 28
52-
#define ZIP_CENTRAL_EXTRA_FIELD_LENGTH 30
53-
#define ZIP_CENTRAL_FILE_COMMENT_LENGTH 32
54-
#define ZIP_CENTRAL_DISK_NUMBER_START 34
55-
#define ZIP_CENTRAL_INTERNAL_FILE_ATTRIBUTES 36
56-
#define ZIP_CENTRAL_EXTERNAL_FILE_ATTRIBUTES 38
57-
#define ZIP_CENTRAL_RELATIVE_OFFSET_OF_LOCAL_HEADER 42
58-
#define ZIP_CENTRAL_DIRECTORY_LENGTH 46
59-
6036
typedef struct {
6137
uint16_t compressionMethod;
6238
uint32_t crc32;
@@ -68,16 +44,6 @@ typedef struct {
6844
uint32_t offset;
6945
} JZFileHeader;
7046

71-
#define ZIP_END_SIGNATURE_OFFSET 0
72-
#define ZIP_END_DESK_NUMBER 4
73-
#define ZIP_END_CENTRAL_DIRECTORY_DISK_NUMBER 6
74-
#define ZIP_END_NUM_ENTRIES_THIS_DISK 8
75-
#define ZIP_END_NUM_ENTRIES 10
76-
#define ZIP_END_CENTRAL_DIRECTORY_SIZE 12
77-
#define ZIP_END_CENTRAL_DIRECTORY_OFFSET 16
78-
#define ZIP_END_ZIP_COMMENT_LENGTH 20
79-
#define ZIP_END_DIRECTORY_LENGTH 22
80-
8147
// Callback prototype for central and local file record reading functions
8248
typedef int (*JZRecordCallback)(JZFile *zip, int index, JZFileHeader *header);
8349

@@ -88,6 +54,9 @@ int jzReadEndRecord(JZFile *zip);
8854
// Callback is called for each record, until callback returns zero
8955
int jzReadCentralDirectory(JZFile *zip, JZRecordCallback callback);
9056

57+
// See to the start of the actual data of the given entry.
58+
int jzSeekData(JZFile *zip, JZFileHeader *header);
59+
9160
// Read data from file stream, described by header, to preallocated buffer
9261
// Return value is zlib coded, e.g. Z_OK, or error code
9362
int jzReadData(JZFile *zip, JZFileHeader *header, void *buffer);

0 commit comments

Comments
 (0)