]> git.mxchange.org Git - simgear.git/blob - simgear/package/ioapi_mem.c
HTTP request cancellation
[simgear.git] / simgear / package / ioapi_mem.c
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.h"
28
29
30
31 voidpf ZCALLBACK fopen_mem_func OF((
32    voidpf opaque,
33    const char* filename,
34    int mode));
35
36 uLong ZCALLBACK fread_mem_func OF((
37    voidpf opaque,
38    voidpf stream,
39    void* buf,
40    uLong size));
41
42 uLong ZCALLBACK fwrite_mem_func OF((
43    voidpf opaque,
44    voidpf stream,
45    const void* buf,
46    uLong size));
47
48 long ZCALLBACK ftell_mem_func OF((
49    voidpf opaque,
50    voidpf stream));
51
52 long ZCALLBACK fseek_mem_func OF((
53    voidpf opaque,
54    voidpf stream,
55    uLong offset,
56    int origin));
57
58 int ZCALLBACK fclose_mem_func OF((
59    voidpf opaque,
60    voidpf stream));
61
62 int ZCALLBACK ferror_mem_func OF((
63    voidpf opaque,
64    voidpf stream));
65
66
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 */
72 } ourmemory_t;
73
74 voidpf ZCALLBACK fopen_mem_func (opaque, filename, mode)
75    voidpf opaque;
76    const char* filename;
77    int mode;
78 {
79     ourmemory_t *mem = malloc(sizeof(*mem));
80     if (mem==NULL)
81       return NULL; /* Can't allocate space, so failed */
82
83     memset(mem, 0, sizeof(ourmemory_t));
84
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
89      * architectures
90      */
91     if (sscanf(filename,"%p+%lx",&mem->base,&mem->size)!=2)
92       return NULL;
93
94     if (mode & ZLIB_FILEFUNC_MODE_CREATE)
95       mem->limit=0; /* When writing we start with 0 bytes written */
96     else
97       mem->limit=mem->size;
98
99     mem->cur_offset = 0;
100
101     return mem;
102 }
103
104
105 uLong ZCALLBACK fread_mem_func (opaque, stream, buf, size)
106    voidpf opaque;
107    voidpf stream;
108    void* buf;
109    uLong size;
110 {
111     ourmemory_t *mem = (ourmemory_t *)stream;
112
113     if (size > mem->size - mem->cur_offset)
114       size = mem->size - mem->cur_offset;
115
116     memcpy(buf, mem->base + mem->cur_offset, size);
117     mem->cur_offset+=size;
118
119     return size;
120 }
121
122
123 uLong ZCALLBACK fwrite_mem_func (opaque, stream, buf, size)
124    voidpf opaque;
125    voidpf stream;
126    const void* buf;
127    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     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;
138
139     return size;
140 }
141
142 long ZCALLBACK ftell_mem_func (opaque, stream)
143    voidpf opaque;
144    voidpf stream;
145 {
146     ourmemory_t *mem = (ourmemory_t *)stream;
147
148     return mem->cur_offset;
149 }
150
151 long ZCALLBACK fseek_mem_func (opaque, stream, offset, origin)
152    voidpf opaque;
153    voidpf stream;
154    uLong offset;
155    int origin;
156 {
157     ourmemory_t *mem = (ourmemory_t *)stream;
158     uLong new_pos;
159     switch (origin)
160     {
161     case ZLIB_FILEFUNC_SEEK_CUR :
162         new_pos = mem->cur_offset + offset;
163         break;
164     case ZLIB_FILEFUNC_SEEK_END :
165         new_pos = mem->limit + offset;
166         break;
167     case ZLIB_FILEFUNC_SEEK_SET :
168         new_pos = offset;
169         break;
170     default: return -1;
171     }
172
173     if (new_pos > mem->size)
174       return 1; /* Failed to seek that far */
175
176     if (new_pos > mem->limit)
177       memset(mem->base + mem->limit, 0, new_pos - mem->limit);
178
179     mem->cur_offset = new_pos;
180     return 0;
181 }
182
183 int ZCALLBACK fclose_mem_func (opaque, stream)
184    voidpf opaque;
185    voidpf stream;
186 {
187     ourmemory_t *mem = (ourmemory_t *)stream;
188
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.
192
193        This, and other aspects of writing through this interface, has
194        not been tested.
195      */
196
197     free (mem);
198     return 0;
199 }
200
201 int ZCALLBACK ferror_mem_func (opaque, stream)
202    voidpf opaque;
203    voidpf stream;
204 {
205     // ourmemory_t *mem = (ourmemory_t *)stream;
206     /* We never return errors */
207     return 0;
208 }
209
210 void fill_memory_filefunc (pzlib_filefunc_def)
211   zlib_filefunc_def* pzlib_filefunc_def;
212 {
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;
221 }