aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/src/stream_gsf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/src/stream_gsf.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/src/stream_gsf.c355
1 files changed, 355 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/src/stream_gsf.c b/src/others/mimesh/libg3d-0.0.8/src/stream_gsf.c
new file mode 100644
index 0000000..d059a62
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/src/stream_gsf.c
@@ -0,0 +1,355 @@
1/* $Id:$ */
2
3/*
4 libg3d - 3D object loading library
5
6 Copyright (C) 2005-2009 Markus Dahms <mad@automagically.de>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21*/
22
23#include <string.h>
24
25#include <gsf/gsf-input.h>
26#include <gsf/gsf-infile.h>
27#include <gsf/gsf-input-stdio.h>
28#include <gsf/gsf-input-memory.h>
29#include <gsf/gsf-input-gzip.h>
30#include <gsf/gsf-infile-msole.h>
31#include <gsf/gsf-infile-zip.h>
32
33#include <g3d/stream.h>
34
35#include "stream_gsf_class.h"
36
37typedef struct {
38 GsfInput *input_container;
39 GsfInfile *infile_msole;
40 GsfInfile *infile_zip;
41 GsfInput *input_subfile;
42 gchar *uri;
43} G3DStreamGsf;
44
45static gsize g3d_stream_gsf_read(gpointer ptr, gsize size, gpointer data)
46{
47 G3DStreamGsf *sg = (G3DStreamGsf *)data;
48 gsize n;
49
50 n = MIN(size, gsf_input_remaining(sg->input_subfile));
51 gsf_input_read(sg->input_subfile, n, (guint8 *)ptr);
52 return n;
53}
54
55static gint g3d_stream_gsf_seek(gpointer data, goffset offset,
56 GSeekType whence)
57{
58 G3DStreamGsf *sg = (G3DStreamGsf *)data;
59 return gsf_input_seek(sg->input_subfile, offset, whence);
60}
61
62static goffset g3d_stream_gsf_tell(gpointer data)
63{
64 G3DStreamGsf *sg = (G3DStreamGsf *)data;
65 return gsf_input_tell(sg->input_subfile);
66}
67
68static goffset g3d_stream_gsf_size(gpointer data)
69{
70 G3DStreamGsf *sg = (G3DStreamGsf *)data;
71 return gsf_input_size(sg->input_subfile);
72}
73
74static gboolean g3d_stream_gsf_eof(gpointer data)
75{
76 G3DStreamGsf *sg = (G3DStreamGsf *)data;
77 if(gsf_input_remaining(sg->input_subfile) <= 0)
78 return TRUE;
79 return gsf_input_eof(sg->input_subfile);
80}
81
82static gint g3d_stream_gsf_close(gpointer data)
83{
84 G3DStreamGsf *sg = (G3DStreamGsf *)data;
85 g_object_unref(sg->input_subfile);
86 if(sg->infile_msole)
87 g_object_unref(sg->infile_msole);
88 if(sg->infile_zip)
89 g_object_unref(sg->infile_zip);
90 if(sg->uri)
91 g_free(sg->uri);
92 g_object_unref(sg->input_container);
93 g_free(sg);
94 return 0;
95}
96
97/****************************************************************************/
98
99static GsfInput *stream_gsf_chdir(GsfInput *input, gchar *dirname)
100{
101 GsfInput *parent = input, *newinput = NULL;
102 gchar **dirs, **dir;
103
104 dirs = g_strsplit(dirname, "/", 0);
105 for(dir = dirs; *dir != NULL; dir ++) {
106 newinput = gsf_infile_child_by_name(GSF_INFILE(parent),
107 *dir);
108 if((newinput == NULL) || (!GSF_IS_INFILE(newinput))) {
109 g_strfreev(dirs);
110 return NULL;
111 }
112 parent = newinput;
113 }
114 g_strfreev(dirs);
115 return newinput;
116}
117
118/*****************************************************************************/
119
120EAPI
121G3DStream *g3d_stream_open_gzip_from_stream(G3DStream *stream)
122{
123 G3DStreamGsf *sg;
124 GsfInput *source;
125 GError *error = NULL;
126 guint32 flags = 0;
127
128 source = g3d_gsf_input_stream_new(stream);
129 if(source == NULL)
130 return NULL;
131
132 sg = g_new0(G3DStreamGsf, 1);
133 sg->input_container = source;
134
135 sg->input_subfile = gsf_input_gzip_new(source, &error);
136 if(error) {
137 g_warning("failed to read gzipped data from %s: %s", stream->uri,
138 error->message);
139 g_object_unref(sg->input_container);
140 g_error_free(error);
141 g_free(sg);
142 }
143
144 sg->uri = g_strdup_printf("%s#gzip@0x%08x", stream->uri,
145 (guint32)g3d_stream_tell(stream));
146
147 flags |= (1 << G3D_STREAM_READABLE);
148 flags |= (1 << G3D_STREAM_SEEKABLE);
149
150 return g3d_stream_new_custom(flags, sg->uri,
151 g3d_stream_gsf_read, NULL,
152 g3d_stream_gsf_seek, g3d_stream_gsf_tell,
153 g3d_stream_gsf_size, g3d_stream_gsf_eof,
154 g3d_stream_gsf_close, sg, NULL);
155}
156
157
158/*****************************************************************************/
159/* Zip stuff */
160
161static G3DStream *g3d_stream_open_zip_from_input(GsfInput *input,
162 const gchar *subfile) {
163 G3DStreamGsf *sg;
164 GError *error = NULL;
165 guint32 flags = 0;
166 GsfInput *input_dir;
167 gchar *basename, *dirname;
168 G3DStream *zip_stream = g3d_gsf_input_stream_get_stream(input);
169
170 sg = g_new0(G3DStreamGsf, 1);
171 sg->input_container = input;
172
173 sg->infile_zip = gsf_infile_zip_new(sg->input_container, &error);
174 if(error != NULL) {
175 g_warning("error reading ZIP data from '%s': %s",
176 gsf_input_name(input), error->message);
177 g_object_unref(sg->input_container);
178 g_error_free(error);
179 g_free(sg);
180 return NULL;
181 }
182
183 if(strchr(subfile, '/')) {
184 basename = g_path_get_basename(subfile);
185 dirname = g_path_get_dirname(subfile);
186 input_dir = stream_gsf_chdir(GSF_INPUT(sg->infile_zip), dirname);
187 sg->input_subfile = gsf_infile_child_by_name(GSF_INFILE(input_dir),
188 basename);
189 g_free(basename);
190 g_free(dirname);
191 } else {
192 sg->input_subfile = gsf_infile_child_by_name(sg->infile_zip, subfile);
193 }
194
195 if(!GSF_IS_INPUT(sg->input_subfile)) {
196 g_warning("error: %s is not an input file", subfile);
197 g_object_unref(sg->infile_zip);
198 g_object_unref(sg->input_container);
199 g_free(sg);
200 return NULL;
201 }
202
203 flags |= (1 << G3D_STREAM_READABLE);
204 flags |= (1 << G3D_STREAM_SEEKABLE);
205
206 sg->uri = g_strdup_printf("zip://%s|%s", gsf_input_name(input), subfile);
207
208 if (NULL != zip_stream->zip_container)
209 zip_stream = zip_stream->zip_container;
210
211 return g3d_stream_new_custom(flags, sg->uri,
212 g3d_stream_gsf_read, NULL,
213 g3d_stream_gsf_seek, g3d_stream_gsf_tell,
214 g3d_stream_gsf_size, g3d_stream_gsf_eof,
215 g3d_stream_gsf_close, sg, zip_stream);
216}
217
218EAPI
219G3DStream *g3d_stream_open_zip(const gchar *filename, const gchar *subfile)
220{
221 GsfInput *input;
222 GError *error = NULL;
223
224/* FIXME: This wont work if the "file" is a buffer. */
225 input = gsf_input_stdio_new(filename, &error);
226 if(error != NULL) {
227 g_warning("error opening container file '%s': %s", filename,
228 error->message);
229 g_error_free(error);
230 return NULL;
231 }
232
233 return g3d_stream_open_zip_from_input(input, subfile);
234}
235
236EAPI
237G3DStream *g3d_stream_open_zip_from_stream(G3DStream *stream,
238 const gchar *subfile)
239{
240 GsfInput *input;
241
242 input = g3d_gsf_input_stream_new(stream);
243 if(!input)
244 return NULL;
245
246 return g3d_stream_open_zip_from_input(input, subfile);
247}
248
249/*****************************************************************************/
250/* Structured File stuff */
251
252static G3DStream *g3d_stream_open_structured_file_from_input(GsfInput *input,
253 const gchar *subfile)
254{
255 G3DStreamGsf *sg;
256 GsfInput *input_gzipped, *input_tmp;
257 GError *error = NULL;
258 guint32 flags = 0;
259
260 sg = g_new0(G3DStreamGsf, 1);
261 sg->input_container = input;
262
263 sg->infile_msole = gsf_infile_msole_new(sg->input_container, &error);
264 if(error != NULL) {
265 g_warning("error reading OLE data from '%s': %s",
266 gsf_input_name(input), error->message);
267 g_object_unref(sg->input_container);
268 g_error_free(error);
269 g_free(sg);
270 return NULL;
271 }
272#if DEBUG > 2
273 g_debug("GSF: new MSOLE infile");
274#endif
275 sg->input_subfile = gsf_infile_child_by_name(sg->infile_msole, subfile);
276 if(error != NULL) {
277 g_warning("error opening contained file '%s' in '%s': %s",
278 subfile, gsf_input_name(input), error->message);
279 g_object_unref(sg->infile_msole);
280 g_object_unref(sg->input_container);
281 g_error_free(error);
282 g_free(sg);
283 return NULL;
284 }
285 if(!GSF_IS_INPUT(sg->input_subfile)) {
286 g_object_unref(sg->infile_msole);
287 g_object_unref(sg->input_container);
288 g_free(sg);
289 return NULL;
290 }
291
292 /* try to open subfile as gzipped */
293 input_gzipped = gsf_input_gzip_new(sg->input_subfile, &error);
294 if(error != NULL) {
295 /* failed to open gzip data */
296 g_error_free(error);
297 } else {
298 /* succeeded to open gzip data */
299 input_tmp = sg->input_subfile;
300 sg->input_subfile = input_gzipped;
301 g_object_unref(input_tmp);
302 }
303
304#if DEBUG > 2
305 g_debug("GSF: got subfile '%s'", subfile);
306#endif
307 flags |= (1 << G3D_STREAM_READABLE);
308 flags |= (1 << G3D_STREAM_SEEKABLE);
309
310 sg->uri = g_strdup_printf("wsf://%s/%s", gsf_input_name(input), subfile);
311 return g3d_stream_new_custom(flags, sg->uri,
312 g3d_stream_gsf_read, NULL,
313 g3d_stream_gsf_seek, g3d_stream_gsf_tell,
314 g3d_stream_gsf_size, g3d_stream_gsf_eof,
315 g3d_stream_gsf_close, sg, NULL);
316}
317
318EAPI
319G3DStream *g3d_stream_open_structured_file(const gchar *filename,
320 const gchar *subfile)
321{
322 GsfInput *container;
323 GError *error = NULL;
324
325#if DEBUG > 2
326 g_debug("GSF: Hello, World!");
327#endif
328
329 container = gsf_input_stdio_new(filename, &error);
330 if(error != NULL) {
331 g_warning("error opening structured file '%s': %s", filename,
332 error->message);
333 g_error_free(error);
334 return NULL;
335 }
336#if DEBUG > 2
337 g_debug("GSF: opened file '%s'", filename);
338#endif
339
340 return g3d_stream_open_structured_file_from_input(container, subfile);
341}
342
343EAPI
344G3DStream *g3d_stream_open_structured_file_from_stream(G3DStream *stream,
345 const gchar *subfile)
346{
347 GsfInput *input;
348
349 input = g3d_gsf_input_stream_new(stream);
350 if(!input)
351 return NULL;
352
353 return g3d_stream_open_structured_file_from_input(input, subfile);
354}
355