1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
#include "NXFileObject.h"
#include <new>
#include "minizip/unzip.h"
#include <nx/nxfile.h>
#include <assert.h>
class NXZipFile : NXFileObject
{
public:
NXZipFile(unzFile zip_file);
~NXZipFile();
/* NXFileObject implementation */
ns_error_t Read(void *buffer, size_t bytes_requested, size_t *bytes_read);
ns_error_t Write(const void *buffer, size_t bytes);
ns_error_t Seek(uint64_t position);
ns_error_t Tell(uint64_t *position);
ns_error_t PeekByte(uint8_t *byte);
ns_error_t Sync();
ns_error_t Truncate();
// TODO(benski) implementation EOF
// TODO(benski) implement region locking
private:
unzFile zip_file;
};
NXZipFile::NXZipFile(unzFile zip_file) : zip_file(zip_file)
{
}
NXZipFile::~NXZipFile()
{
if (zip_file) {
unzCloseCurrentFile(zip_file);
unzClose(zip_file);
zip_file=0;
}
}
/* NXFileObject implementation */
ns_error_t NXZipFile::Read(void *buffer, size_t bytes_requested, size_t *bytes_read)
{
int zret = unzReadCurrentFile(zip_file, buffer, (unsigned int)bytes_requested);
if (zret == 0) {
if (bytes_read) {
*bytes_read = 0;
}
return NErr_EndOfFile;
} else if (zret > 0) {
if (bytes_read) {
*bytes_read = (size_t)zret;
}
return NErr_Success;
} else {
if (bytes_read) {
*bytes_read = 0;
}
return NErr_Error;
}
}
ns_error_t NXZipFile::Write(const void *buffer, size_t bytes)
{
return NErr_NotImplemented;
}
ns_error_t NXZipFile::Seek(uint64_t position)
{
// TODO(benski) error check)
unzSetOffset64(zip_file, position);
return NErr_Success;
}
ns_error_t NXZipFile::Tell(uint64_t *position)
{
*position = unzGetOffset64(zip_file);
return NErr_Success;
}
ns_error_t NXZipFile::PeekByte(uint8_t *byte)
{
return NErr_NotImplemented;
}
ns_error_t NXZipFile::Sync()
{
return NErr_NotImplemented;
}
ns_error_t NXZipFile::Truncate()
{
return NErr_NotImplemented;
}
static voidpf ZCALLBACK unzip_nxfile_open OF((voidpf opaque, const void* filename, int mode))
{
nx_file_t f;
if (NXFileOpenFile(&f, (nx_uri_t)filename, nx_file_FILE_read_binary) != NErr_Success) {
return 0;
}
return f;
}
static uLong ZCALLBACK unzip_nxfile_read OF((voidpf opaque, voidpf stream, void* buf, uLong size))
{
nx_file_t f = (nx_file_t)stream;
size_t bytes_read;
if (NXFileRead(f, buf, size, &bytes_read) != NErr_Success) {
return 0;
}
return (uLong)bytes_read;
}
static int ZCALLBACK unzip_nxfile_close OF((voidpf opaque, voidpf stream))
{
NXFileRelease((nx_file_t)stream);
return 0;
}
static ZPOS64_T ZCALLBACK unzip_nxfile_tell OF((voidpf opaque, voidpf stream))
{
nx_file_t f = (nx_file_t)stream;
uint64_t position;
if (NXFileTell(f, &position) == NErr_Success) {
return (int64_t)position;
} else {
return -1;
}
}
static long ZCALLBACK unzip_nxfile_seek OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int whence))
{
nx_file_t f = (nx_file_t)stream;
uint64_t position;
if (whence == SEEK_SET) {
position = offset;
} else if (whence == SEEK_CUR) {
ns_error_t err = NXFileTell(f, &position);
if (err != NErr_Success) {
return -1;
}
position += offset;
} else if (whence == SEEK_END) {
uint64_t length;
NXFileLength(f, &length);
position = length + offset;
} else {
return -1;
}
ns_error_t err = NXFileSeek(f, position);
if (err == NErr_Success) {
return 0;
} else {
return -1;
}
}
#if 0
open64_file_func zopen64_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell64_file_func ztell64_file;
seek64_file_func zseek64_file;
close_file_func zclose_file;
testerror_file_func zerror_file;
#endif
ns_error_t NXFileOpenZip(nx_file_t *out_file, nx_uri_t filename, nx_string_t extension_hint)
{
#if 0
typedef struct zlib_filefunc_def_s
{
open_file_func zopen_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell_file_func ztell_file;
seek_file_func zseek_file;
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
} zlib_filefunc_def;
#endif
zlib_filefunc64_def file_func = {0, };
file_func.zopen64_file = unzip_nxfile_open;
file_func.zread_file = unzip_nxfile_read;
file_func.ztell64_file = unzip_nxfile_tell;
file_func.zseek64_file = unzip_nxfile_seek;
file_func.zclose_file = unzip_nxfile_close;
unzFile zip_file = unzOpen2_64(filename, &file_func);
if (zip_file == NULL) {
return NErr_Error;
}
unzGoToFirstFile(zip_file);
// TODO(benski): look for filename with extension_hint as extension
// TODO(benski): search for anything with extension
unzOpenCurrentFile(zip_file);
NXZipFile *nx_zip_file = new (std::nothrow) NXZipFile(zip_file);
if (!nx_zip_file) {
unzCloseCurrentFile(zip_file);
unzClose(zip_file);
return NErr_OutOfMemory;
}
*out_file = (nx_file_t)nx_zip_file;
return NErr_Success;
}
|