1 /* ioapi_mem.c -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API
4 This version of ioapi is designed to access memory rather than files.
5 We do use a region of memory to put data in to and take it out of. We do
6 not have auto-extending buffers and do not inform anyone else that the
7 data has been written. It is really intended for accessing a zip archive
8 embedded in an application such that I can write an installer with no
9 external files. Creation of archives has not been attempted, although
10 parts of the framework are present.
12 Based on Unzip ioapi.c version 0.22, May 19th, 2003
14 Copyright (C) 2012-2017 Nathan Moinvaziri
15 https://github.com/nmoinvaz/minizip
16 Copyright (C) 2003 Justin Fletcher
17 Copyright (C) 1998-2003 Gilles Vollant
18 http://www.winimage.com/zLibDll/minizip.html
20 This file is under the same license as the Unzip tool it is distributed
32 #include "ioapi_mem.h"
34 #ifndef IOMEM_BUFFERSIZE
35 # define IOMEM_BUFFERSIZE (UINT16_MAX)
38 voidpf ZCALLBACK fopen_mem_func(voidpf opaque, ZIP_UNUSED const char *filename, int mode)
40 ourmemory_t *mem = (ourmemory_t *)opaque;
42 return NULL; /* Mem structure passed in was null */
44 if (mode & ZLIB_FILEFUNC_MODE_CREATE)
48 mem->size = IOMEM_BUFFERSIZE;
49 mem->base = (char *)malloc(mem->size);
52 mem->limit = 0; /* When writing we start with 0 bytes written */
55 mem->limit = mem->size;
62 voidpf ZCALLBACK fopendisk_mem_func(ZIP_UNUSED voidpf opaque, ZIP_UNUSED voidpf stream, ZIP_UNUSED uint32_t number_disk, ZIP_UNUSED int mode)
68 uint32_t ZCALLBACK fread_mem_func(ZIP_UNUSED voidpf opaque, voidpf stream, void *buf, uint32_t size)
70 ourmemory_t *mem = (ourmemory_t *)stream;
72 if (size > mem->size - mem->cur_offset)
73 size = mem->size - mem->cur_offset;
75 memcpy(buf, mem->base + mem->cur_offset, size);
76 mem->cur_offset += size;
81 uint32_t ZCALLBACK fwrite_mem_func(ZIP_UNUSED voidpf opaque, voidpf stream, const void *buf, uint32_t size)
83 ourmemory_t *mem = (ourmemory_t *)stream;
84 uint32_t newmemsize = 0;
87 if (size > mem->size - mem->cur_offset)
91 newmemsize = mem->size;
92 if (size < IOMEM_BUFFERSIZE)
93 newmemsize += IOMEM_BUFFERSIZE;
96 newbase = (char *)malloc(newmemsize);
97 memcpy(newbase, mem->base, mem->size);
100 mem->size = newmemsize;
103 size = mem->size - mem->cur_offset;
105 memcpy(mem->base + mem->cur_offset, buf, size);
106 mem->cur_offset += size;
107 if (mem->cur_offset > mem->limit)
108 mem->limit = mem->cur_offset;
113 long ZCALLBACK ftell_mem_func(ZIP_UNUSED voidpf opaque, voidpf stream)
115 ourmemory_t *mem = (ourmemory_t *)stream;
116 return mem->cur_offset;
119 long ZCALLBACK fseek_mem_func(ZIP_UNUSED voidpf opaque, voidpf stream, uint32_t offset, int origin)
121 ourmemory_t *mem = (ourmemory_t *)stream;
122 uint32_t new_pos = 0;
125 case ZLIB_FILEFUNC_SEEK_CUR:
126 new_pos = mem->cur_offset + offset;
128 case ZLIB_FILEFUNC_SEEK_END:
129 new_pos = mem->limit + offset;
131 case ZLIB_FILEFUNC_SEEK_SET:
138 if (new_pos > mem->size)
139 return 1; /* Failed to seek that far */
140 mem->cur_offset = new_pos;
144 int ZCALLBACK fclose_mem_func(ZIP_UNUSED voidpf opaque, ZIP_UNUSED voidpf stream)
146 /* Even with grow = 1, caller must always free() memory */
150 int ZCALLBACK ferror_mem_func(ZIP_UNUSED voidpf opaque, ZIP_UNUSED voidpf stream)
152 /* We never return errors */
156 void fill_memory_filefunc(zlib_filefunc_def *pzlib_filefunc_def, ourmemory_t *ourmem)
158 pzlib_filefunc_def->zopen_file = fopen_mem_func;
159 pzlib_filefunc_def->zopendisk_file = fopendisk_mem_func;
160 pzlib_filefunc_def->zread_file = fread_mem_func;
161 pzlib_filefunc_def->zwrite_file = fwrite_mem_func;
162 pzlib_filefunc_def->ztell_file = ftell_mem_func;
163 pzlib_filefunc_def->zseek_file = fseek_mem_func;
164 pzlib_filefunc_def->zclose_file = fclose_mem_func;
165 pzlib_filefunc_def->zerror_file = ferror_mem_func;
166 pzlib_filefunc_def->opaque = ourmem;