1 /**
2 * zziplib data source for SDL_RWops
3
4 * Copyright (C) 2001 Guido Draheim <guidod@gmx.de>
5 * Copyright (C) 2007, 2008, 2009 Sylvain Beucler
6
7 * This file is part of GNU FreeDink
8
9 * GNU FreeDink is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 3 of the
12 * License, or (at your option) any later version.
13
14 * GNU FreeDink is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see
21 * <http://www.gnu.org/licenses/>.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 /* Order headers appropriately:
29 http://lists.gnu.org/archive/html/bug-gnulib/2007-12/msg00152.html */
30 #include <unistd.h> /* close->rpl_close */
31 #include <zzip/zzip.h> /* also sources unistd.h */
32 #include <SDL_rwops.h> /* has a 'close' member, replaced by
33 'rpl_close' */
34
35 #include "SDL_rwops_zzip.h"
36 #include <string.h> /* strchr */
37
38
39 /* MSVC can not take a casted variable as an lvalue ! */
40 #define SDL_RWOPS_ZZIP_DATA(_context) \
41 ((_context)->hidden.unknown.data1)
42 #define SDL_RWOPS_ZZIP_FILE(_context) (ZZIP_FILE*) \
43 ((_context)->hidden.unknown.data1)
44
rwops_zzip_seek(SDL_RWops * context,int offset,int whence)45 static int rwops_zzip_seek(SDL_RWops *context, int offset, int whence)
46 {
47 return zzip_seek(SDL_RWOPS_ZZIP_FILE(context), offset, whence);
48 }
49
rwops_zzip_read(SDL_RWops * context,void * ptr,int size,int maxnum)50 static int rwops_zzip_read(SDL_RWops *context, void *ptr, int size, int maxnum)
51 {
52 return zzip_read(SDL_RWOPS_ZZIP_FILE(context), ptr, size*maxnum) / size;
53 }
54
rwops_zzip_write(SDL_RWops * context,const void * ptr,int size,int num)55 static int rwops_zzip_write(SDL_RWops *context, const void *ptr, int size, int num)
56 {
57 return 0; /* ignored */
58 }
59
rwops_zzip_close(SDL_RWops * context)60 static int rwops_zzip_close(SDL_RWops *context)
61 {
62 if (! context) return 0; /* may be SDL_RWclose is called by atexit */
63
64 zzip_close (SDL_RWOPS_ZZIP_FILE(context));
65 SDL_FreeRW (context);
66 return 0;
67 }
68
SDL_RWFromZZIP(const char * file,const char * mode)69 SDL_RWops *SDL_RWFromZZIP(const char* file, const char* mode)
70 {
71 register SDL_RWops* rwops;
72 register ZZIP_FILE* zzip_file;
73
74 if (! strchr (mode, 'r'))
75 return SDL_RWFromFile(file, mode);
76
77 /* zzip_file = zzip_fopen (file, mode); */
78 zzip_strings_t xor_fileext[] = { "", 0 };
79 zzip_file = zzip_open_ext_io(file,
80 0, ZZIP_CASELESS|ZZIP_ONLYZIP,
81 xor_fileext, 0);
82 if (! zzip_file) return 0;
83
84 rwops = SDL_AllocRW ();
85 if (! rwops) { errno=ENOMEM; zzip_close (zzip_file); return 0; }
86
87 SDL_RWOPS_ZZIP_DATA(rwops) = zzip_file;
88 rwops->read = rwops_zzip_read;
89 rwops->write = rwops_zzip_write;
90 rwops->seek = rwops_zzip_seek;
91 rwops->close = rwops_zzip_close;
92 return rwops;
93 }
94