1 /*
2 * Copyright (c) 2001 Guido Draheim <guidod@gmx.de>
3 * Use freely under the restrictions of the ZLIB License
4 *
5 * (this example uses errno which might not be multithreaded everywhere)
6 */
7
8 #include "SDL_rwops_libzip.h"
9 #include <zip.h>
10 #include <string.h> /* strchr */
11 #include <errno.h>
12
13 #if 0
14 static int rwops_libzip_seek(SDL_RWops *context, int offset, int whence)
15 {
16 printf("rwops_libzip_seek(context=%p, offset=%d, whence=", context, offset);
17 switch(whence)
18 {
19 case SEEK_SET:
20 printf("SEEK_SET");
21 break;
22 case SEEK_CUR:
23 printf("SEEK_CUR");
24 break;
25 case SEEK_END:
26 printf("SEEK_END");
27 break;
28 }
29 printf(");\n");
30 return 0; /* ignored */
31 }
32
33 static int rwops_libzip_read(SDL_RWops *context, void *ptr, int size, int maxnum)
34 {
35 printf("rwops_libzip_read(context=%p, ptr=%p, size=%d, maxnum=%d);\n", context, ptr, size, maxnum);
36 return zip_fread(context->hidden.unknown.data1, ptr, size*maxnum) / size;
37 }
38
39 static int rwops_libzip_write(SDL_RWops *context, const void *ptr, int size, int num)
40 {
41 return -1; /* not supported */
42 }
43
44 static int rwops_libzip_close(SDL_RWops *context)
45 {
46 printf("rwops_libzip_close(context=%p);\n", context);
47
48 if (context == NULL)
49 return 0; /* may be SDL_RWclose is called by atexit */
50
51 zip_fclose(context->hidden.unknown.data1);
52 /* SDL_FreeRW (context); */
53 /* TODO: zip_close(zarchive); */
54 return 0;
55 }
56 #endif
57
58
SDL_RWFromZIP(const char * archivename,const char * filename)59 SDL_RWops *SDL_RWFromZIP(const char* archivename, const char* filename)
60 {
61 SDL_RWops* rwops;
62 struct zip* zarchive;
63 struct zip_file* zfile;
64 int errorp = 0;
65
66 zarchive = zip_open(archivename, ZIP_CHECKCONS, &errorp);
67 if (errorp != 0)
68 {
69 char *errorbuf = NULL;
70 int len = 1;
71 errorbuf = malloc(len);
72 len = zip_error_to_str(errorbuf, len, errorp, errno);
73 errorbuf = realloc(errorbuf, len + 1);
74 len = zip_error_to_str(errorbuf, len, errorp, errno);
75 fprintf(stderr, "zip_open: %s\n", errorbuf);
76 free(errorbuf);
77 return NULL;
78 }
79 zfile = zip_fopen(zarchive, filename, 0);
80 if (zfile == NULL)
81 {
82 fprintf(stderr, "zip_open: %s\n", zip_strerror(zarchive));
83 zip_close(zarchive);
84 return NULL;
85 }
86
87 /* libzip does not support seek()ing in file, so we can't use it -
88 TTF_OpenFontRW needs it to read data at the end of files. */
89 #if 0
90 rwops = SDL_AllocRW();
91 if (rwops == NULL)
92 { errno=ENOMEM;
93 zip_close(zarchive);
94 return NULL;
95 }
96
97 rwops->hidden.unknown.data1 = zfile;
98 rwops->read = rwops_libzip_read;
99 rwops->write = rwops_libzip_write;
100 rwops->seek = rwops_libzip_seek;
101 rwops->close = rwops_libzip_close;
102 return rwops;
103 #endif
104
105 struct zip_stat zfilestat;
106 if (zip_stat(zarchive, filename, 0, &zfilestat) < 0)
107 {
108 fprintf(stderr, "zip_open: %s\n", zip_strerror(zarchive));
109 zip_close(zarchive);
110 return NULL;
111 }
112
113 char *content = malloc(zfilestat.size);
114 zip_fread(zfile, content, zfilestat.size);
115 rwops = SDL_RWFromMem(content, zfilestat.size);
116 zip_fclose(zfile);
117 zip_close(zarchive);
118
119 return rwops;
120 }
121