mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
junzip: style and migrate header into private-libwebsockets.h
Also introduce CMake LWS_WITH_ZIP_FOPS defaulting to ON that builds junzip.c and make sure this is exported in lws_config.h (included by libwebsockets.h) Improve lws handling of stdint.h import or simulate it.
This commit is contained in:
parent
cb35969fce
commit
753f1d642c
6 changed files with 299 additions and 248 deletions
|
@ -114,6 +114,7 @@ option(LWS_WITH_NO_LOGS "Disable all logging from being compiled in" OFF)
|
|||
option(LWS_STATIC_PIC "Build the static version of the library with position-independent code" OFF)
|
||||
option(LWS_WITH_RANGES "Support http ranges (RFC7233)" ON)
|
||||
option(LWS_FALLBACK_GETHOSTBYNAME "Also try to do dns resolution using gethostbyname if getaddrinfo fails" OFF)
|
||||
option(LWS_WITH_ZIP_FOPS "Support serving pre-zipped files" ON)
|
||||
|
||||
if (LWS_WITH_LWSWS)
|
||||
message(STATUS "LWS_WITH_LWSWS --> Enabling LWS_WITH_PLUGINS and LWS_WITH_LIBUV")
|
||||
|
@ -652,6 +653,11 @@ if (LWS_WITH_RANGES)
|
|||
lib/ranges.c)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_ZIP_FOPS)
|
||||
list(APPEND SOURCES
|
||||
lib/junzip.c)
|
||||
endif()
|
||||
|
||||
# Add helper files for Windows.
|
||||
if (WIN32)
|
||||
set(WIN32_HELPERS_PATH win32port/win32helpers)
|
||||
|
@ -1670,6 +1676,7 @@ message(" LWS_STATIC_PIC = ${LWS_STATIC_PIC}")
|
|||
message(" LWS_WITH_RANGES = ${LWS_WITH_RANGES}")
|
||||
message(" LWS_PLAT_OPTEE = ${LWS_PLAT_OPTEE}")
|
||||
message(" LWS_WITH_ESP32 = ${LWS_WITH_ESP32}")
|
||||
message(" LWS_WITH_ZIP_FOPS = ${LWS_WITH_ZIP_FOPS}")
|
||||
|
||||
message("---------------------------------------------------------------------")
|
||||
|
||||
|
|
404
lib/junzip.c
404
lib/junzip.c
|
@ -6,218 +6,262 @@
|
|||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "junzip.h"
|
||||
#include "private-libwebsockets.h"
|
||||
|
||||
#define ZIP_CENTRAL_SIGNATURE 0
|
||||
#define ZIP_CENTRAL_VERSION_MADE_BY 4
|
||||
#define ZIP_CENTRAL_VERSION_NEEDED_TO_EXTRACT 6
|
||||
#define ZIP_CENTRAL_GENERAL_PURPOSE_BIT_FLAG 8
|
||||
#define ZIP_CENTRAL_COMPRESSION_METHOD 10
|
||||
#define ZIP_CENTRAL_LAST_MOD_FILE_TIME 12
|
||||
#define ZIP_CENTRAL_LAST_MOD_FILE_DATE 14
|
||||
#define ZIP_CENTRAL_CRC32 16
|
||||
#define ZIP_CENTRAL_COMPRESSED_SIZE 20
|
||||
#define ZIP_CENTRAL_UNCOMPRESSED_SIZE 24
|
||||
#define ZIP_CENTRAL_FILE_NAME_LENGTH 28
|
||||
#define ZIP_CENTRAL_EXTRA_FIELD_LENGTH 30
|
||||
#define ZIP_CENTRAL_FILE_COMMENT_LENGTH 32
|
||||
#define ZIP_CENTRAL_DISK_NUMBER_START 34
|
||||
#define ZIP_CENTRAL_INTERNAL_FILE_ATTRIBUTES 36
|
||||
#define ZIP_CENTRAL_EXTERNAL_FILE_ATTRIBUTES 38
|
||||
#define ZIP_CENTRAL_RELATIVE_OFFSET_OF_LOCAL_HEADER 42
|
||||
#define ZIP_CENTRAL_DIRECTORY_LENGTH 46
|
||||
enum {
|
||||
ZC_SIGNATURE = 0,
|
||||
ZC_VERSION_MADE_BY = 4,
|
||||
ZC_VERSION_NEEDED_TO_EXTRACT = 6,
|
||||
ZC_GENERAL_PURPOSE_BIT_FLAG = 8,
|
||||
ZC_COMPRESSION_METHOD = 10,
|
||||
ZC_LAST_MOD_FILE_TIME = 12,
|
||||
ZC_LAST_MOD_FILE_DATE = 14,
|
||||
ZC_CRC32 = 16,
|
||||
ZC_COMPRESSED_SIZE = 20,
|
||||
ZC_UNCOMPRESSED_SIZE = 24,
|
||||
ZC_FILE_NAME_LENGTH = 28,
|
||||
ZC_EXTRA_FIELD_LENGTH = 30,
|
||||
ZC_FILE_COMMENT_LENGTH = 32,
|
||||
ZC_DISK_NUMBER_START = 34,
|
||||
ZC_INTERNAL_FILE_ATTRIBUTES = 36,
|
||||
ZC_EXTERNAL_FILE_ATTRIBUTES = 38,
|
||||
ZC_RELATIVE_OFFSET_OF_LOCAL_HEADER = 42,
|
||||
ZC_DIRECTORY_LENGTH = 46,
|
||||
|
||||
#define ZIP_END_SIGNATURE_OFFSET 0
|
||||
#define ZIP_END_DESK_NUMBER 4
|
||||
#define ZIP_END_CENTRAL_DIRECTORY_DISK_NUMBER 6
|
||||
#define ZIP_END_NUM_ENTRIES_THIS_DISK 8
|
||||
#define ZIP_END_NUM_ENTRIES 10
|
||||
#define ZIP_END_CENTRAL_DIRECTORY_SIZE 12
|
||||
#define ZIP_END_CENTRAL_DIRECTORY_OFFSET 16
|
||||
#define ZIP_END_ZIP_COMMENT_LENGTH 20
|
||||
#define ZIP_END_DIRECTORY_LENGTH 22
|
||||
ZE_SIGNATURE_OFFSET = 0,
|
||||
ZE_DESK_NUMBER = 4,
|
||||
ZE_CENTRAL_DIRECTORY_DISK_NUMBER = 6,
|
||||
ZE_NUM_ENTRIES_THIS_DISK = 8,
|
||||
ZE_NUM_ENTRIES = 10,
|
||||
ZE_CENTRAL_DIRECTORY_SIZE = 12,
|
||||
ZE_CENTRAL_DIRECTORY_OFFSET = 16,
|
||||
ZE_ZIP_COMMENT_LENGTH = 20,
|
||||
ZE_DIRECTORY_LENGTH = 22,
|
||||
};
|
||||
|
||||
#define get_u16(PTR) ((PTR)[0] | ((PTR)[1] << 8))
|
||||
#define get_u32(PTR) ((PTR)[0] | ((PTR)[1]<<8) | ((PTR)[2]<<16) | ((PTR)[3]<<24))
|
||||
|
||||
static int
|
||||
zf_seek_set(JZFile *zfile, size_t offset)
|
||||
static uint16_t
|
||||
get_u16(void *p)
|
||||
{
|
||||
int new_position = offset;
|
||||
if (new_position < 0 || new_position > zfile->length)
|
||||
return -1;
|
||||
zfile->position = new_position;
|
||||
return 0;
|
||||
const uint8_t *c = (const uint8_t *)p;
|
||||
|
||||
return (uint16_t)((c[0] | (c[1] << 8)));
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_u32(void *p)
|
||||
{
|
||||
const uint8_t *c = (const uint8_t *)p;
|
||||
|
||||
return (uint32_t)((c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)));
|
||||
}
|
||||
|
||||
static int
|
||||
zf_seek_cur(JZFile *zfile, size_t offset)
|
||||
zf_seek_set(jzfile_t *zfile, size_t offset)
|
||||
{
|
||||
int new_position = zfile->position + offset;
|
||||
if (new_position < 0 || new_position > zfile->length)
|
||||
return -1;
|
||||
zfile->position = new_position;
|
||||
return 0;
|
||||
int new_position = offset;
|
||||
|
||||
if (new_position < 0 || new_position > zfile->length)
|
||||
return -1;
|
||||
zfile->position = new_position;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
zf_seek_end(JZFile *zfile, size_t offset)
|
||||
zf_seek_cur(jzfile_t *zfile, size_t offset)
|
||||
{
|
||||
int new_position = zfile->length + offset;
|
||||
if (new_position < 0 || new_position > zfile->length)
|
||||
return -1;
|
||||
zfile->position = new_position;
|
||||
return 0;
|
||||
int new_position = zfile->position + offset;
|
||||
|
||||
if (new_position < 0 || new_position > zfile->length)
|
||||
return -1;
|
||||
zfile->position = new_position;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t zf_read(JZFile *zfile, void *buf, size_t size)
|
||||
static int
|
||||
zf_seek_end(jzfile_t *zfile, size_t offset)
|
||||
{
|
||||
size_t avail = zfile->length - zfile->position;
|
||||
if (size > avail)
|
||||
size = avail;
|
||||
memcpy(buf, zfile->start + zfile->position, size);
|
||||
zfile->position += size;
|
||||
return size;
|
||||
int new_position = zfile->length + offset;
|
||||
|
||||
if (new_position < 0 || new_position > zfile->length)
|
||||
return -1;
|
||||
zfile->position = new_position;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read ZIP file end record. Will move within file.
|
||||
int jzReadEndRecord(JZFile *zip) {
|
||||
long fileSize, readBytes, i;
|
||||
size_t
|
||||
zf_read(jzfile_t *zfile, void *buf, size_t size)
|
||||
{
|
||||
size_t avail = zfile->length - zfile->position;
|
||||
|
||||
if(zf_seek_end(zip, -ZIP_END_DIRECTORY_LENGTH)) {
|
||||
return Z_ERRNO;
|
||||
}
|
||||
if (size > avail)
|
||||
size = avail;
|
||||
memcpy(buf, zfile->start + zfile->position, size);
|
||||
zfile->position += size;
|
||||
|
||||
unsigned char *ptr = zf_current(zip);
|
||||
while (ptr[0] != 0x50 || ptr[1] != 0x4B || ptr[2] != 0x05 || ptr[3] != 0x06) {
|
||||
if (ptr == zip->start) {
|
||||
return Z_ERRNO;
|
||||
}
|
||||
ptr--;
|
||||
}
|
||||
zip->numEntries = get_u16(ptr + ZIP_END_NUM_ENTRIES);
|
||||
zip->centralDirectoryOffset= get_u32(ptr + ZIP_END_CENTRAL_DIRECTORY_OFFSET);
|
||||
if (get_u16(ptr + ZIP_END_DESK_NUMBER)
|
||||
|| get_u16(ptr + ZIP_END_CENTRAL_DIRECTORY_DISK_NUMBER)
|
||||
|| zip->numEntries != get_u16(ptr + ZIP_END_NUM_ENTRIES_THIS_DISK)) {
|
||||
return Z_ERRNO;
|
||||
}
|
||||
|
||||
return Z_OK;
|
||||
return size;
|
||||
}
|
||||
|
||||
// Read ZIP file global directory. Will move within file.
|
||||
int jzReadCentralDirectory(JZFile *zip, JZRecordCallback callback) {
|
||||
JZFileHeader header;
|
||||
int i;
|
||||
/* Read ZIP file end record. Will move within file. */
|
||||
int
|
||||
jzReadEndRecord(jzfile_t *zip)
|
||||
{
|
||||
unsigned char *ptr = zf_current(zip);
|
||||
|
||||
if(zf_seek_set(zip, zip->centralDirectoryOffset)) {
|
||||
return Z_ERRNO;
|
||||
}
|
||||
if (zf_seek_end(zip, -ZE_DIRECTORY_LENGTH))
|
||||
return Z_ERRNO;
|
||||
|
||||
for(i=0; i < zip->numEntries; i++) {
|
||||
unsigned char *ptr = zf_current(zip);
|
||||
if (zf_available(zip) < ZIP_CENTRAL_DIRECTORY_LENGTH) {
|
||||
return Z_ERRNO;
|
||||
}
|
||||
zf_seek_cur(zip, ZIP_CENTRAL_DIRECTORY_LENGTH);
|
||||
if (get_u32(ptr + ZIP_CENTRAL_SIGNATURE) != 0x02014B50) {
|
||||
return Z_ERRNO;
|
||||
}
|
||||
// Construct JZFileHeader from global file header
|
||||
header.compressionMethod = get_u16(ptr + ZIP_CENTRAL_COMPRESSION_METHOD);
|
||||
header.crc32 = get_u32(ptr + ZIP_CENTRAL_CRC32);
|
||||
header.compressedSize = get_u32(ptr + ZIP_CENTRAL_COMPRESSED_SIZE);
|
||||
header.uncompressedSize = get_u32(ptr + ZIP_CENTRAL_UNCOMPRESSED_SIZE);
|
||||
header.fileNameLength = get_u16(ptr + ZIP_CENTRAL_FILE_NAME_LENGTH);
|
||||
header.extraFieldLength = get_u16(ptr + ZIP_CENTRAL_EXTRA_FIELD_LENGTH);
|
||||
header.offset = get_u32(ptr + ZIP_CENTRAL_RELATIVE_OFFSET_OF_LOCAL_HEADER);
|
||||
while (ptr[0] != 0x50 || ptr[1] != 0x4B || ptr[2] != 5 || ptr[3] != 6)
|
||||
if (ptr-- == zip->start)
|
||||
return Z_ERRNO;
|
||||
|
||||
header.fileNameStart = zf_tell(zip);
|
||||
if (zf_seek_cur(zip, header.fileNameLength + header.extraFieldLength + get_u16(ptr + ZIP_CENTRAL_FILE_COMMENT_LENGTH))) {
|
||||
return Z_ERRNO;
|
||||
}
|
||||
zip->numEntries = get_u16(ptr + ZE_NUM_ENTRIES);
|
||||
zip->centralDirectoryOffset= get_u32(ptr + ZE_CENTRAL_DIRECTORY_OFFSET);
|
||||
|
||||
if(!callback(zip, i, &header))
|
||||
break; // end if callback returns zero
|
||||
}
|
||||
if (get_u16(ptr + ZE_DESK_NUMBER) ||
|
||||
get_u16(ptr + ZE_CENTRAL_DIRECTORY_DISK_NUMBER) ||
|
||||
zip->numEntries != get_u16(ptr + ZE_NUM_ENTRIES_THIS_DISK))
|
||||
return Z_ERRNO;
|
||||
|
||||
return Z_OK;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int jzSeekData(JZFile *zip, JZFileHeader *entry) {
|
||||
size_t offset = entry->offset;
|
||||
offset += ZIP_LOCAL_FILE_HEADER_LENGTH;
|
||||
offset += entry->fileNameLength + entry->extraFieldLength;
|
||||
if (offset < 0 || offset > zip->length)
|
||||
return Z_STREAM_END;
|
||||
zip->position = offset;
|
||||
return Z_OK;
|
||||
/* Read ZIP file global directory. Will move within file. */
|
||||
int
|
||||
jzReadCentralDirectory(jzfile_t *zip, jzcb_t callback)
|
||||
{
|
||||
jzfile_hdr_t h;
|
||||
int i;
|
||||
|
||||
if (zf_seek_set(zip, zip->centralDirectoryOffset))
|
||||
return Z_ERRNO;
|
||||
|
||||
for (i = 0; i < zip->numEntries; i++) {
|
||||
unsigned char *ptr = zf_current(zip);
|
||||
|
||||
if (zf_available(zip) < ZC_DIRECTORY_LENGTH)
|
||||
return Z_ERRNO;
|
||||
|
||||
zf_seek_cur(zip, ZC_DIRECTORY_LENGTH);
|
||||
if (get_u32(ptr + ZC_SIGNATURE) != 0x02014B50)
|
||||
return Z_ERRNO;
|
||||
|
||||
// Construct jzfile_hdr_t from global file h
|
||||
h.compressionMethod = get_u16(ptr + ZC_COMPRESSION_METHOD);
|
||||
h.crc32 = get_u32(ptr + ZC_CRC32);
|
||||
h.compressedSize = get_u32(ptr + ZC_COMPRESSED_SIZE);
|
||||
h.uncompressedSize = get_u32(ptr + ZC_UNCOMPRESSED_SIZE);
|
||||
h.fileNameLength = get_u16(ptr + ZC_FILE_NAME_LENGTH);
|
||||
h.extraFieldLength = get_u16(ptr + ZC_EXTRA_FIELD_LENGTH);
|
||||
h.offset = get_u32(ptr + ZC_RELATIVE_OFFSET_OF_LOCAL_HEADER);
|
||||
|
||||
h.fileNameStart = zf_tell(zip);
|
||||
if (zf_seek_cur(zip, h.fileNameLength + h.extraFieldLength +
|
||||
get_u16(ptr + ZC_FILE_COMMENT_LENGTH)))
|
||||
return Z_ERRNO;
|
||||
|
||||
if (!callback(zip, i, &h))
|
||||
break; // end if callback returns zero
|
||||
}
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
// Read data from file stream, described by header, to preallocated buffer
|
||||
int jzReadData(JZFile *zip, JZFileHeader *header, void *buffer) {
|
||||
unsigned char *bytes = (unsigned char *)buffer; // cast
|
||||
long compressedLeft, uncompressedLeft;
|
||||
z_stream strm;
|
||||
int ret;
|
||||
int jzSeekData(jzfile_t *zip, jzfile_hdr_t *entry)
|
||||
{
|
||||
size_t offset = entry->offset;
|
||||
|
||||
if(header->compressionMethod == 0) { // Store - just read it
|
||||
if (zf_read(zip, buffer, header->uncompressedSize) <
|
||||
header->uncompressedSize)
|
||||
return Z_ERRNO;
|
||||
} else if (header->compressionMethod == 8) { // Deflate - using zlib
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
offset += ZIP_LOCAL_FILE_HEADER_LENGTH;
|
||||
offset += entry->fileNameLength + entry->extraFieldLength;
|
||||
|
||||
strm.avail_in = 0;
|
||||
strm.next_in = Z_NULL;
|
||||
if (offset < 0 || offset > zip->length)
|
||||
return Z_STREAM_END;
|
||||
|
||||
// Use inflateInit2 with negative window bits to indicate raw data
|
||||
if ((ret = inflateInit2(&strm, -MAX_WBITS)) != Z_OK)
|
||||
return ret; // Zlib errors are negative
|
||||
zip->position = offset;
|
||||
|
||||
// Inflate compressed data
|
||||
for (compressedLeft = header->compressedSize,
|
||||
uncompressedLeft = header->uncompressedSize;
|
||||
compressedLeft && uncompressedLeft && ret != Z_STREAM_END;
|
||||
compressedLeft -= strm.avail_in) {
|
||||
// Read next chunk
|
||||
unsigned char *ptr = zf_current(zip);
|
||||
strm.avail_in = compressedLeft;
|
||||
zf_seek_cur(zip, compressedLeft);
|
||||
if(strm.avail_in == 0) {
|
||||
inflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
|
||||
strm.next_in = ptr;
|
||||
strm.avail_out = uncompressedLeft;
|
||||
strm.next_out = bytes;
|
||||
|
||||
compressedLeft -= strm.avail_in; // inflate will change avail_in
|
||||
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
|
||||
if(ret == Z_STREAM_ERROR) return ret; // shouldn't happen
|
||||
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR; /* and fall through */
|
||||
case Z_DATA_ERROR: case Z_MEM_ERROR:
|
||||
(void)inflateEnd(&strm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bytes += uncompressedLeft - strm.avail_out; // bytes uncompressed
|
||||
uncompressedLeft = strm.avail_out;
|
||||
}
|
||||
|
||||
inflateEnd(&strm);
|
||||
} else {
|
||||
return Z_ERRNO;
|
||||
}
|
||||
|
||||
return Z_OK;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* Read data from file stream, described by h, to preallocated buffer */
|
||||
int
|
||||
jzReadData(jzfile_t *zip, jzfile_hdr_t *h, void *buffer)
|
||||
{
|
||||
unsigned char *bytes = (unsigned char *)buffer;
|
||||
long compressedLeft, uncompressedLeft;
|
||||
z_stream strm;
|
||||
int ret;
|
||||
|
||||
switch (h->compressionMethod) {
|
||||
case 0: /* Store - just read it */
|
||||
if (zf_read(zip, buffer, h->uncompressedSize) <
|
||||
h->uncompressedSize)
|
||||
return Z_ERRNO;
|
||||
break;
|
||||
case 8: /* Deflate - using zlib */
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
|
||||
strm.avail_in = 0;
|
||||
strm.next_in = Z_NULL;
|
||||
|
||||
/*
|
||||
* Use inflateInit2 with negative window bits to
|
||||
* indicate raw data
|
||||
*/
|
||||
if ((ret = inflateInit2(&strm, -MAX_WBITS)) != Z_OK)
|
||||
return ret; /* Zlib errors are negative */
|
||||
|
||||
/* Inflate compressed data */
|
||||
for (compressedLeft = h->compressedSize,
|
||||
uncompressedLeft = h->uncompressedSize;
|
||||
compressedLeft && uncompressedLeft && ret != Z_STREAM_END;
|
||||
compressedLeft -= strm.avail_in) {
|
||||
/* Read next chunk */
|
||||
unsigned char *ptr = zf_current(zip);
|
||||
|
||||
strm.avail_in = compressedLeft;
|
||||
zf_seek_cur(zip, compressedLeft);
|
||||
if (strm.avail_in == 0) {
|
||||
inflateEnd(&strm);
|
||||
|
||||
return Z_ERRNO;
|
||||
}
|
||||
|
||||
strm.next_in = ptr;
|
||||
strm.avail_out = uncompressedLeft;
|
||||
strm.next_out = bytes;
|
||||
|
||||
compressedLeft -= strm.avail_in;
|
||||
/* inflate will change avail_in */
|
||||
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
|
||||
if (ret == Z_STREAM_ERROR)
|
||||
return ret;
|
||||
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR;
|
||||
/* and fall through */
|
||||
case Z_DATA_ERROR: case Z_MEM_ERROR:
|
||||
(void)inflateEnd(&strm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* bytes uncompressed */
|
||||
bytes += uncompressedLeft - strm.avail_out;
|
||||
uncompressedLeft = strm.avail_out;
|
||||
}
|
||||
|
||||
inflateEnd(&strm);
|
||||
break;
|
||||
default:
|
||||
return Z_ERRNO;
|
||||
}
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
|
68
lib/junzip.h
68
lib/junzip.h
|
@ -1,68 +0,0 @@
|
|||
/**
|
||||
* Unzip library by Per Bothner.
|
||||
* Loosely based on Joonas Pihlajamaa's JUnzip.
|
||||
* Released into public domain. https://github.com/jokkebk/JUnzip
|
||||
*/
|
||||
|
||||
#ifndef __JUNZIP_H
|
||||
#define __JUNZIP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// If you don't have stdint.h, the following two lines should work for most 32/64 bit systems
|
||||
// typedef unsigned int uint32_t;
|
||||
// typedef unsigned short uint16_t;
|
||||
|
||||
typedef struct JZFile JZFile;
|
||||
|
||||
struct JZFile {
|
||||
unsigned char *start;
|
||||
off_t length;
|
||||
long position;
|
||||
int numEntries;
|
||||
uint32_t centralDirectoryOffset;
|
||||
};
|
||||
|
||||
#define zf_tell(ZF) ((ZF)->position)
|
||||
#define zf_available(ZF) ((ZF)->length - (ZF)->position)
|
||||
#define zf_current(ZF) ((ZF)->start + (ZF)->position)
|
||||
|
||||
#define ZIP_LOCAL_FILE_HEADER_LENGTH 30
|
||||
|
||||
typedef struct {
|
||||
uint16_t compressionMethod;
|
||||
uint32_t crc32;
|
||||
uint32_t compressedSize;
|
||||
uint32_t uncompressedSize;
|
||||
long fileNameStart;
|
||||
uint16_t fileNameLength;
|
||||
uint16_t extraFieldLength; // unsupported
|
||||
uint32_t offset;
|
||||
} JZFileHeader;
|
||||
|
||||
// Callback prototype for central and local file record reading functions
|
||||
typedef int (*JZRecordCallback)(JZFile *zip, int index, JZFileHeader *header);
|
||||
|
||||
// Read ZIP file end record. Will move within file.
|
||||
int jzReadEndRecord(JZFile *zip);
|
||||
|
||||
// Read ZIP file global directory. Will move within file.
|
||||
// Callback is called for each record, until callback returns zero
|
||||
int jzReadCentralDirectory(JZFile *zip, JZRecordCallback callback);
|
||||
|
||||
// See to the start of the actual data of the given entry.
|
||||
int jzSeekData(JZFile *zip, JZFileHeader *header);
|
||||
|
||||
// Read data from file stream, described by header, to preallocated buffer
|
||||
// Return value is zlib coded, e.g. Z_OK, or error code
|
||||
int jzReadData(JZFile *zip, JZFileHeader *header, void *buffer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
|
@ -4296,10 +4296,23 @@ struct lws_fop_fd {
|
|||
#if !defined(ssize_t)
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LWS_HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
/* !!! >:-[ */
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
#else
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct lws_fop_fd *lws_fop_fd_t;
|
||||
typedef size_t lws_filepos_t;
|
||||
typedef ssize_t lws_fileofs_t;
|
||||
|
|
|
@ -439,6 +439,57 @@ extern "C" {
|
|||
#define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Unzip library by Per Bothner.
|
||||
* Loosely based on Joonas Pihlajamaa's JUnzip.
|
||||
* Released into public domain. https://github.com/jokkebk/JUnzip
|
||||
* ------->
|
||||
*/
|
||||
|
||||
typedef struct jzfile {
|
||||
unsigned char *start;
|
||||
off_t length;
|
||||
long position;
|
||||
int numEntries;
|
||||
uint32_t centralDirectoryOffset;
|
||||
} jzfile_t;
|
||||
|
||||
#define zf_tell(ZF) ((ZF)->position)
|
||||
#define zf_available(ZF) ((ZF)->length - (ZF)->position)
|
||||
#define zf_current(ZF) ((ZF)->start + (ZF)->position)
|
||||
|
||||
#define ZIP_LOCAL_FILE_HEADER_LENGTH 30
|
||||
|
||||
typedef struct {
|
||||
uint16_t compressionMethod;
|
||||
uint32_t crc32;
|
||||
uint32_t compressedSize;
|
||||
uint32_t uncompressedSize;
|
||||
long fileNameStart;
|
||||
uint16_t fileNameLength;
|
||||
uint16_t extraFieldLength; // unsupported
|
||||
uint32_t offset;
|
||||
} jzfile_hdr_t;
|
||||
|
||||
// Callback prototype for central and local file record reading functions
|
||||
typedef int (*jzcb_t)(jzfile_t *zip, int index, jzfile_hdr_t *header);
|
||||
|
||||
// Read ZIP file end record. Will move within file.
|
||||
int jzReadEndRecord(jzfile_t *zip);
|
||||
|
||||
// Read ZIP file global directory. Will move within file.
|
||||
// Callback is called for each record, until callback returns zero
|
||||
int jzReadCentralDirectory(jzfile_t *zip, jzcb_t callback);
|
||||
|
||||
// See to the start of the actual data of the given entry.
|
||||
int jzSeekData(jzfile_t *zip, jzfile_hdr_t *header);
|
||||
|
||||
// Read data from file stream, described by header, to preallocated buffer
|
||||
// Return value is zlib coded, e.g. Z_OK, or error code
|
||||
int jzReadData(jzfile_t *zip, jzfile_hdr_t *header, void *buffer);
|
||||
|
||||
/* <------ */
|
||||
|
||||
enum lws_websocket_opcodes_07 {
|
||||
LWSWSOPC_CONTINUATION = 0,
|
||||
LWSWSOPC_TEXT_FRAME = 1,
|
||||
|
|
|
@ -122,5 +122,9 @@
|
|||
/* OPTEE */
|
||||
#cmakedefine LWS_PLAT_OPTEE
|
||||
|
||||
/* ZIP FOPS */
|
||||
#cmakedefine LWS_WITH_ZIP_FOPS
|
||||
#cmakedefine LWS_HAVE_STDINT_H
|
||||
|
||||
#cmakedefine LWS_FALLBACK_GETHOSTBYNAME
|
||||
${LWS_SIZEOFPTR_CODE}
|
||||
|
|
Loading…
Add table
Reference in a new issue