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) 1998-2003 Gilles Vollant
15 (C) 2003 Justin Fletcher
17 This file is under the same license as the Unzip tool it is distributed
31 voidpf ZCALLBACK fopen_mem_func OF((
36 uLong ZCALLBACK fread_mem_func OF((
42 uLong ZCALLBACK fwrite_mem_func OF((
48 long ZCALLBACK ftell_mem_func OF((
52 long ZCALLBACK fseek_mem_func OF((
58 int ZCALLBACK fclose_mem_func OF((
62 int ZCALLBACK ferror_mem_func OF((
67 typedef struct ourmemory_s {
68 char *base; /* Base of the region of memory we're using */
69 uLong size; /* Size of the region of memory we're using */
70 uLong limit; /* Furthest we've written */
71 uLong cur_offset; /* Current offset in the area */
74 voidpf ZCALLBACK fopen_mem_func (opaque, filename, mode)
79 ourmemory_t *mem = malloc(sizeof(*mem));
81 return NULL; /* Can't allocate space, so failed */
83 memset(mem, 0, sizeof(ourmemory_t));
85 /* Filenames are specified in the form :
86 * <hex base of zip file>+<hex size of zip file>
87 * This may not work where memory addresses are longer than the
88 * size of an int and therefore may need addressing for 64bit
91 if (sscanf(filename,"%p+%lx",&mem->base,&mem->size)!=2)
94 if (mode & ZLIB_FILEFUNC_MODE_CREATE)
95 mem->limit=0; /* When writing we start with 0 bytes written */
105 uLong ZCALLBACK fread_mem_func (opaque, stream, buf, size)
111 ourmemory_t *mem = (ourmemory_t *)stream;
113 if (size > mem->size - mem->cur_offset)
114 size = mem->size - mem->cur_offset;
116 memcpy(buf, mem->base + mem->cur_offset, size);
117 mem->cur_offset+=size;
123 uLong ZCALLBACK fwrite_mem_func (opaque, stream, buf, size)
129 ourmemory_t *mem = (ourmemory_t *)stream;
131 if (size > mem->size - mem->cur_offset)
132 size = mem->size - mem->cur_offset;
134 memcpy(mem->base + mem->cur_offset, buf, size);
135 mem->cur_offset+=size;
136 if (mem->cur_offset > mem->limit)
137 mem->limit = mem->cur_offset;
142 long ZCALLBACK ftell_mem_func (opaque, stream)
146 ourmemory_t *mem = (ourmemory_t *)stream;
148 return mem->cur_offset;
151 long ZCALLBACK fseek_mem_func (opaque, stream, offset, origin)
157 ourmemory_t *mem = (ourmemory_t *)stream;
161 case ZLIB_FILEFUNC_SEEK_CUR :
162 new_pos = mem->cur_offset + offset;
164 case ZLIB_FILEFUNC_SEEK_END :
165 new_pos = mem->limit + offset;
167 case ZLIB_FILEFUNC_SEEK_SET :
173 if (new_pos > mem->size)
174 return 1; /* Failed to seek that far */
176 if (new_pos > mem->limit)
177 memset(mem->base + mem->limit, 0, new_pos - mem->limit);
179 mem->cur_offset = new_pos;
183 int ZCALLBACK fclose_mem_func (opaque, stream)
187 ourmemory_t *mem = (ourmemory_t *)stream;
189 /* Note that once we've written to the buffer we don't tell anyone
190 about it here. Probably the opaque handle could be used to inform
191 some other component of how much data was written.
193 This, and other aspects of writing through this interface, has
201 int ZCALLBACK ferror_mem_func (opaque, stream)
205 // ourmemory_t *mem = (ourmemory_t *)stream;
206 /* We never return errors */
210 void fill_memory_filefunc (pzlib_filefunc_def)
211 zlib_filefunc_def* pzlib_filefunc_def;
213 pzlib_filefunc_def->zopen_file = fopen_mem_func;
214 pzlib_filefunc_def->zread_file = fread_mem_func;
215 pzlib_filefunc_def->zwrite_file = fwrite_mem_func;
216 pzlib_filefunc_def->ztell_file = ftell_mem_func;
217 pzlib_filefunc_def->zseek_file = fseek_mem_func;
218 pzlib_filefunc_def->zclose_file = fclose_mem_func;
219 pzlib_filefunc_def->zerror_file = ferror_mem_func;
220 pzlib_filefunc_def->opaque = NULL;