Skip to content

Commit c5f69e4

Browse files
author
minggo
committed
Merge pull request #16 from SunLightJuly/Add_unzip_OpenBuffer
added unzip function: unzOpenBuffer
2 parents 4cf3a8b + 8602315 commit c5f69e4

File tree

4 files changed

+303
-0
lines changed

4 files changed

+303
-0
lines changed

unzip/ioapi_mem.cpp

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/* ioapi_mem.c -- IO base function header for compress/uncompress .zip
2+
files using zlib + zip or unzip API
3+
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.
11+
12+
Based on Unzip ioapi.c version 0.22, May 19th, 2003
13+
14+
Copyright (C) 1998-2003 Gilles Vollant
15+
(C) 2003 Justin Fletcher
16+
17+
This file is under the same license as the Unzip tool it is distributed
18+
with.
19+
*/
20+
21+
22+
#include <stdio.h>
23+
#include <stdlib.h>
24+
#include <string.h>
25+
26+
#include "zlib.h"
27+
#include "ioapi_mem.h"
28+
29+
#ifdef _MSC_VER
30+
31+
#define strtoull _strtoui64
32+
33+
#endif
34+
35+
namespace cocos2d {
36+
37+
voidpf ZCALLBACK fopen_mem_func (voidpf opaque,
38+
const char* filename,
39+
int mode)
40+
{
41+
ourmemory_t *mem = (ourmemory_t*)malloc(sizeof(ourmemory_t));
42+
43+
if (mem==NULL) return NULL; /* Can't allocate space, so failed */
44+
45+
/* Filenames are specified in the form :
46+
* <hex base of zip file>+<hex size of zip file>
47+
* This may not work where memory addresses are longer than the
48+
* size of an int and therefore may need addressing for 64bit
49+
* architectures
50+
*/
51+
memset(mem, 0, sizeof(ourmemory_t));
52+
char *pEnd = NULL;
53+
void *base = NULL;
54+
unsigned long size = 0;
55+
56+
base = (void*)strtoull(filename, &pEnd, 16);
57+
if (!base) return NULL;
58+
size = strtoul(pEnd, &pEnd, 16);
59+
if (!size) return NULL;
60+
61+
mem->base = base;
62+
mem->size = size;
63+
64+
if (mode & ZLIB_FILEFUNC_MODE_CREATE) {
65+
mem->limit = 0; /* When writing we start with 0 bytes written */
66+
} else {
67+
mem->limit = mem->size;
68+
}
69+
mem->cur_offset = 0;
70+
71+
return mem;
72+
}
73+
74+
voidpf ZCALLBACK fopen_mem_func64_32 (voidpf opaque,
75+
const void* filename,
76+
int mode)
77+
{
78+
ourmemory_t *mem = (ourmemory_t*)malloc(sizeof(ourmemory_t));
79+
80+
if (mem==NULL) return NULL; /* Can't allocate space, so failed */
81+
82+
/* Filenames are specified in the form :
83+
* <hex base of zip file>+<hex size of zip file>
84+
* This may not work where memory addresses are longer than the
85+
* size of an int and therefore may need addressing for 64bit
86+
* architectures
87+
*/
88+
memset(mem, 0, sizeof(ourmemory_t));
89+
char *pEnd = NULL;
90+
void *base = NULL;
91+
unsigned long size = 0;
92+
93+
base = (void*)strtoull((const char*)filename, &pEnd, 16);
94+
if (!base) return NULL;
95+
size = strtoul(pEnd, &pEnd, 16);
96+
if (!size) return NULL;
97+
98+
mem->base = base;
99+
mem->size = size;
100+
101+
if (mode & ZLIB_FILEFUNC_MODE_CREATE) {
102+
mem->limit=0; /* When writing we start with 0 bytes written */
103+
} else {
104+
mem->limit=mem->size;
105+
}
106+
107+
mem->cur_offset = 0;
108+
109+
return mem;
110+
}
111+
112+
uLong ZCALLBACK fread_mem_func (voidpf opaque, voidpf stream, void* buf, uLong size)
113+
{
114+
ourmemory_t *mem = (ourmemory_t *)stream;
115+
116+
if (size > mem->size - mem->cur_offset) {
117+
size = mem->size - mem->cur_offset;
118+
}
119+
120+
memcpy(buf, (char*)mem->base + mem->cur_offset, size);
121+
mem->cur_offset+=size;
122+
123+
return size;
124+
}
125+
126+
127+
uLong ZCALLBACK fwrite_mem_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
128+
{
129+
ourmemory_t *mem = (ourmemory_t *)stream;
130+
131+
if (size > mem->size - mem->cur_offset) {
132+
size = mem->size - mem->cur_offset;
133+
}
134+
135+
memcpy((char*)mem->base + mem->cur_offset, buf, size);
136+
mem->cur_offset+=size;
137+
if (mem->cur_offset > mem->limit) {
138+
mem->limit = mem->cur_offset;
139+
}
140+
141+
return size;
142+
}
143+
144+
long ZCALLBACK ftell_mem_func (voidpf opaque, voidpf stream)
145+
{
146+
ourmemory_t *mem = (ourmemory_t *)stream;
147+
148+
return mem->cur_offset;
149+
}
150+
151+
long ZCALLBACK fseek_mem_func (voidpf opaque, voidpf stream, uLong offset, int origin)
152+
{
153+
ourmemory_t *mem = (ourmemory_t *)stream;
154+
uLong new_pos;
155+
switch (origin) {
156+
case ZLIB_FILEFUNC_SEEK_CUR : {
157+
new_pos = mem->cur_offset + offset;
158+
break;
159+
}
160+
case ZLIB_FILEFUNC_SEEK_END : {
161+
new_pos = mem->limit + offset;
162+
break;
163+
}
164+
case ZLIB_FILEFUNC_SEEK_SET : {
165+
new_pos = offset;
166+
break;
167+
}
168+
default: {
169+
return -1;
170+
}
171+
}
172+
173+
if (new_pos > mem->size) return 1; /* Failed to seek that far */
174+
175+
if (new_pos > mem->limit) {
176+
memset((char*)mem->base + mem->limit, 0, new_pos - mem->limit);
177+
}
178+
179+
mem->cur_offset = new_pos;
180+
return 0;
181+
}
182+
183+
int ZCALLBACK fclose_mem_func (voidpf opaque, voidpf stream)
184+
{
185+
ourmemory_t *mem = (ourmemory_t *)stream;
186+
187+
/* Note that once we've written to the buffer we don't tell anyone
188+
about it here. Probably the opaque handle could be used to inform
189+
some other component of how much data was written.
190+
191+
This, and other aspects of writing through this interface, has
192+
not been tested.
193+
*/
194+
195+
free (mem);
196+
return 0;
197+
}
198+
199+
int ZCALLBACK ferror_mem_func (voidpf opaque, voidpf stream)
200+
{
201+
/* We never return errors */
202+
return 0;
203+
}
204+
205+
void fill_memory_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
206+
{
207+
pzlib_filefunc_def->zopen_file = fopen_mem_func;
208+
pzlib_filefunc_def->zread_file = fread_mem_func;
209+
pzlib_filefunc_def->zwrite_file = fwrite_mem_func;
210+
pzlib_filefunc_def->ztell_file = ftell_mem_func;
211+
pzlib_filefunc_def->zseek_file = fseek_mem_func;
212+
pzlib_filefunc_def->zclose_file = fclose_mem_func;
213+
pzlib_filefunc_def->zerror_file = ferror_mem_func;
214+
pzlib_filefunc_def->opaque = NULL;
215+
}
216+
217+
void fill_memory_filefunc64_32 (zlib_filefunc64_32_def* pzlib_filefunc_def)
218+
{
219+
pzlib_filefunc_def->zopen32_file = fopen_mem_func;
220+
pzlib_filefunc_def->zfile_func64.zopen64_file = fopen_mem_func64_32;
221+
pzlib_filefunc_def->zfile_func64.zread_file = fread_mem_func;
222+
pzlib_filefunc_def->zfile_func64.zwrite_file = fwrite_mem_func;
223+
pzlib_filefunc_def->ztell32_file = ftell_mem_func;
224+
pzlib_filefunc_def->zseek32_file = fseek_mem_func;
225+
pzlib_filefunc_def->zfile_func64.zseek64_file = NULL;
226+
pzlib_filefunc_def->zfile_func64.zclose_file = fclose_mem_func;
227+
pzlib_filefunc_def->zfile_func64.zerror_file = ferror_mem_func;
228+
pzlib_filefunc_def->zfile_func64.opaque = NULL;
229+
}
230+
231+
}; // namespace cocos2d

unzip/ioapi_mem.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
2+
#ifndef quickcocos2dx_ioapi_mem_h
3+
#define quickcocos2dx_ioapi_mem_h
4+
5+
#include "ioapi.h"
6+
7+
8+
namespace cocos2d {
9+
voidpf ZCALLBACK fopen_mem_func OF((
10+
voidpf opaque,
11+
const char* filename,
12+
int mode));
13+
14+
voidpf ZCALLBACK fopen_mem_func64_32 OF((
15+
voidpf opaque,
16+
const void* filename,
17+
int mode));
18+
19+
uLong ZCALLBACK fread_mem_func OF((
20+
voidpf opaque,
21+
voidpf stream,
22+
void* buf,
23+
uLong size));
24+
25+
uLong ZCALLBACK fwrite_mem_func OF((
26+
voidpf opaque,
27+
voidpf stream,
28+
const void* buf,
29+
uLong size));
30+
31+
long ZCALLBACK ftell_mem_func OF((
32+
voidpf opaque,
33+
voidpf stream));
34+
35+
long ZCALLBACK fseek_mem_func OF((
36+
voidpf opaque,
37+
voidpf stream,
38+
uLong offset,
39+
int origin));
40+
41+
int ZCALLBACK fclose_mem_func OF((
42+
voidpf opaque,
43+
voidpf stream));
44+
45+
int ZCALLBACK ferror_mem_func OF((
46+
voidpf opaque,
47+
voidpf stream));
48+
49+
void fill_memory_filefunc64_32 (zlib_filefunc64_32_def* pzlib_filefunc_def);
50+
51+
52+
typedef struct ourmemory_s {
53+
void *base; /* Base of the region of memory we're using */
54+
uLong size; /* Size of the region of memory we're using */
55+
uLong limit; /* Furthest we've written */
56+
uLong cur_offset; /* Current offset in the area */
57+
} ourmemory_t;
58+
59+
}
60+
61+
#endif

unzip/unzip.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474

7575
#include "zlib.h"
7676
#include "unzip.h"
77+
#include "ioapi_mem.h"
7778

7879
#ifdef STDC
7980
# include <stddef.h>
@@ -801,6 +802,15 @@ unzFile ZEXPORT unzOpen64 (const void *path)
801802
return unzOpenInternal(path, NULL, 1);
802803
}
803804

805+
unzFile ZEXPORT unzOpenBuffer (const void* buffer, uLong size)
806+
{
807+
char path[48] = {0};
808+
zlib_filefunc64_32_def memory_file;
809+
sprintf(path, "%llx %lx", (unsigned long long)buffer, (unsigned long)size);
810+
fill_memory_filefunc64_32(&memory_file);
811+
return unzOpenInternal(path, &memory_file, 0);
812+
}
813+
804814
/*
805815
Close a ZipFile opened with unzipOpen.
806816
If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),

unzip/unzip.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ unzFile CC_DLL unzOpen64 OF((const void *path));
180180
does not describe the reality
181181
*/
182182

183+
unzFile CC_DLL unzOpenBuffer OF((const void* buffer, uLong size));
183184

184185
unzFile CC_DLL unzOpen2 OF((const char *path,
185186
zlib_filefunc_def* pzlib_filefunc_def));

0 commit comments

Comments
 (0)