Mercurial > audlegacy-plugins
comparison src/console/Data_Reader.cxx @ 316:fb513e10174e trunk
[svn] - merge libconsole-blargg into mainline libconsole:
+ obsoletes plugins-ugly:sapplug
author | nenolod |
---|---|
date | Thu, 30 Nov 2006 19:54:33 -0800 |
parents | |
children | 986f098da058 |
comparison
equal
deleted
inserted
replaced
315:2294f3a6f136 | 316:fb513e10174e |
---|---|
1 // File_Extractor 0.4.0. http://www.slack.net/~ant/ | |
2 | |
3 #include "Data_Reader.h" | |
4 | |
5 #include <assert.h> | |
6 #include <string.h> | |
7 #include <stdio.h> | |
8 | |
9 /* Copyright (C) 2005-2006 Shay Green. This module is free software; you | |
10 can redistribute it and/or modify it under the terms of the GNU Lesser | |
11 General Public License as published by the Free Software Foundation; either | |
12 version 2.1 of the License, or (at your option) any later version. This | |
13 module is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | |
16 details. You should have received a copy of the GNU Lesser General Public | |
17 License along with this module; if not, write to the Free Software Foundation, | |
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | |
19 | |
20 const char Data_Reader::eof_error [] = "Unexpected end of file"; | |
21 | |
22 typedef Data_Reader::error_t error_t; | |
23 | |
24 error_t Data_Reader::read( void* p, long s ) | |
25 { | |
26 long result = read_avail( p, s ); | |
27 if ( result != s ) | |
28 { | |
29 if ( result >= 0 && result < s ) | |
30 return eof_error; | |
31 | |
32 return "Read error"; | |
33 } | |
34 | |
35 return 0; | |
36 } | |
37 | |
38 error_t Data_Reader::skip( long count ) | |
39 { | |
40 char buf [512]; | |
41 while ( count ) | |
42 { | |
43 long n = sizeof buf; | |
44 if ( n > count ) | |
45 n = count; | |
46 count -= n; | |
47 error_t err = read( buf, n ); | |
48 if ( err ) | |
49 return err; | |
50 } | |
51 return 0; | |
52 } | |
53 | |
54 long File_Reader::remain() const { return size() - tell(); } | |
55 | |
56 error_t File_Reader::skip( long n ) | |
57 { | |
58 assert( n >= 0 ); | |
59 return n ? seek( tell() + n ) : 0; | |
60 } | |
61 | |
62 // Subset_Reader | |
63 | |
64 Subset_Reader::Subset_Reader( Data_Reader* dr, long size ) | |
65 { | |
66 in = dr; | |
67 remain_ = dr->remain(); | |
68 if ( remain_ > size ) | |
69 remain_ = size; | |
70 } | |
71 | |
72 long Subset_Reader::remain() const { return remain_; } | |
73 | |
74 long Subset_Reader::read_avail( void* p, long s ) | |
75 { | |
76 if ( s > remain_ ) | |
77 s = remain_; | |
78 remain_ -= s; | |
79 return in->read_avail( p, s ); | |
80 } | |
81 | |
82 // Remaining_Reader | |
83 | |
84 Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r ) | |
85 { | |
86 header = (char const*) h; | |
87 header_end = header + size; | |
88 in = r; | |
89 } | |
90 | |
91 long Remaining_Reader::remain() const { return header_end - header + in->remain(); } | |
92 | |
93 long Remaining_Reader::read_first( void* out, long count ) | |
94 { | |
95 long first = header_end - header; | |
96 if ( first ) | |
97 { | |
98 if ( first > count ) | |
99 first = count; | |
100 void const* in = header; | |
101 header += first; | |
102 memcpy( out, in, first ); | |
103 } | |
104 return first; | |
105 } | |
106 | |
107 long Remaining_Reader::read_avail( void* out, long count ) | |
108 { | |
109 long first = read_first( out, count ); | |
110 long remain = count - first; | |
111 if ( remain ) | |
112 { | |
113 remain = in->read_avail( (char*) out + first, remain ); | |
114 if ( remain <= 0 ) | |
115 return remain; | |
116 } | |
117 return first + remain; | |
118 } | |
119 | |
120 error_t Remaining_Reader::read( void* out, long count ) | |
121 { | |
122 long first = read_first( out, count ); | |
123 long remain = count - first; | |
124 if ( !remain ) | |
125 return 0; | |
126 return in->read( (char*) out + first, remain ); | |
127 } | |
128 | |
129 // Mem_File_Reader | |
130 | |
131 Mem_File_Reader::Mem_File_Reader( const void* p, long s ) : | |
132 begin( (const char*) p ), | |
133 size_( s ) | |
134 { | |
135 pos = 0; | |
136 } | |
137 | |
138 long Mem_File_Reader::size() const { return size_; } | |
139 | |
140 long Mem_File_Reader::read_avail( void* p, long s ) | |
141 { | |
142 long r = remain(); | |
143 if ( s > r ) | |
144 s = r; | |
145 memcpy( p, begin + pos, s ); | |
146 pos += s; | |
147 return s; | |
148 } | |
149 | |
150 long Mem_File_Reader::tell() const { return pos; } | |
151 | |
152 error_t Mem_File_Reader::seek( long n ) | |
153 { | |
154 if ( n > size_ ) | |
155 return eof_error; | |
156 pos = n; | |
157 return 0; | |
158 } | |
159 | |
160 // Std_File_Reader | |
161 | |
162 Std_File_Reader::Std_File_Reader() : file_( 0 ) { } | |
163 | |
164 Std_File_Reader::~Std_File_Reader() { close(); } | |
165 | |
166 error_t Std_File_Reader::open( const char* path ) | |
167 { | |
168 file_ = fopen( path, "rb" ); | |
169 if ( !file_ ) | |
170 return "Couldn't open file"; | |
171 return 0; | |
172 } | |
173 | |
174 long Std_File_Reader::size() const | |
175 { | |
176 long pos = tell(); | |
177 fseek( (FILE*) file_, 0, SEEK_END ); | |
178 long result = tell(); | |
179 fseek( (FILE*) file_, pos, SEEK_SET ); | |
180 return result; | |
181 } | |
182 | |
183 long Std_File_Reader::read_avail( void* p, long s ) | |
184 { | |
185 return fread( p, 1, s, (FILE*) file_ ); | |
186 } | |
187 | |
188 error_t Std_File_Reader::read( void* p, long s ) | |
189 { | |
190 if ( s == (long) fread( p, 1, s, (FILE*) file_ ) ) | |
191 return 0; | |
192 if ( feof( (FILE*) file_ ) ) | |
193 return eof_error; | |
194 return "Couldn't read from file"; | |
195 } | |
196 | |
197 long Std_File_Reader::tell() const { return ftell( (FILE*) file_ ); } | |
198 | |
199 error_t Std_File_Reader::seek( long n ) | |
200 { | |
201 if ( !fseek( (FILE*) file_, n, SEEK_SET ) ) | |
202 return 0; | |
203 if ( n > size() ) | |
204 return eof_error; | |
205 return "Error seeking in file"; | |
206 } | |
207 | |
208 void Std_File_Reader::close() | |
209 { | |
210 if ( file_ ) | |
211 { | |
212 fclose( (FILE*) file_ ); | |
213 file_ = 0; | |
214 } | |
215 } | |
216 | |
217 // Callback_Reader | |
218 | |
219 Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) : | |
220 callback( c ), | |
221 data( d ) | |
222 { | |
223 remain_ = size; | |
224 } | |
225 | |
226 long Callback_Reader::remain() const { return remain_; } | |
227 | |
228 long Callback_Reader::read_avail( void* out, long count ) | |
229 { | |
230 if ( count > remain_ ) | |
231 count = remain_; | |
232 if ( Callback_Reader::read( out, count ) ) | |
233 count = -1; | |
234 return count; | |
235 } | |
236 | |
237 Callback_Reader::error_t Callback_Reader::read( void* out, long count ) | |
238 { | |
239 if ( count > remain_ ) | |
240 return eof_error; | |
241 return callback( data, out, count ); | |
242 } | |
243 | |
244 // Gzip_File_Reader | |
245 | |
246 #ifdef HAVE_ZLIB_H | |
247 | |
248 #include "zlib.h" | |
249 | |
250 static const char* get_gzip_eof( const char* path, long* eof ) | |
251 { | |
252 FILE* file = fopen( path, "rb" ); | |
253 if ( !file ) | |
254 return "Couldn't open file"; | |
255 | |
256 unsigned char buf [4]; | |
257 if ( fread( buf, 2, 1, file ) == 1 && buf [0] == 0x1F && buf [1] == 0x8B ) | |
258 { | |
259 fseek( file, -4, SEEK_END ); | |
260 fread( buf, 4, 1, file ); | |
261 *eof = buf [3] * 0x1000000L + buf [2] * 0x10000L + buf [1] * 0x100L + buf [0]; | |
262 } | |
263 else | |
264 { | |
265 fseek( file, 0, SEEK_END ); | |
266 *eof = ftell( file ); | |
267 } | |
268 const char* err = (ferror( file ) || feof( file )) ? "Couldn't get file size" : 0; | |
269 fclose( file ); | |
270 return err; | |
271 } | |
272 | |
273 Gzip_File_Reader::Gzip_File_Reader() : file_( 0 ) { } | |
274 | |
275 Gzip_File_Reader::~Gzip_File_Reader() { close(); } | |
276 | |
277 error_t Gzip_File_Reader::open( const char* path ) | |
278 { | |
279 close(); | |
280 | |
281 error_t err = get_gzip_eof( path, &size_ ); | |
282 if ( err ) | |
283 return err; | |
284 | |
285 file_ = gzopen( path, "rb" ); | |
286 if ( !file_ ) | |
287 return "Couldn't open file"; | |
288 | |
289 return 0; | |
290 } | |
291 | |
292 long Gzip_File_Reader::size() const { return size_; } | |
293 | |
294 long Gzip_File_Reader::read_avail( void* p, long s ) { return gzread( file_, p, s ); } | |
295 | |
296 long Gzip_File_Reader::tell() const { return gztell( file_ ); } | |
297 | |
298 error_t Gzip_File_Reader::seek( long n ) | |
299 { | |
300 if ( gzseek( file_, n, SEEK_SET ) >= 0 ) | |
301 return 0; | |
302 if ( n > size_ ) | |
303 return eof_error; | |
304 return "Error seeking in file"; | |
305 } | |
306 | |
307 void Gzip_File_Reader::close() | |
308 { | |
309 if ( file_ ) | |
310 { | |
311 gzclose( file_ ); | |
312 file_ = 0; | |
313 } | |
314 } | |
315 | |
316 #endif |