switch malloc+memset(0) to calloc()
[flac.git] / src / libFLAC / file_decoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2000,2001,2002  Josh Coalson
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA  02111-1307, USA.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h> /* for malloc() */
22 #include <string.h> /* for strcmp() */
23 #include <sys/stat.h> /* for stat() */
24 #if defined _MSC_VER || defined __MINGW32__
25 #include <io.h> /* for _setmode() */
26 #include <fcntl.h> /* for _O_BINARY */
27 #elif defined __CYGWIN__
28 #include <io.h> /* for setmode(), O_BINARY */
29 #include <fcntl.h> /* for _O_BINARY */
30 #endif
31 #include "FLAC/assert.h"
32 #include "protected/file_decoder.h"
33 #include "protected/seekable_stream_decoder.h"
34 #include "private/md5.h"
35
36 /***********************************************************************
37  *
38  * Private class method prototypes
39  *
40  ***********************************************************************/
41
42 static void set_defaults_(FLAC__FileDecoder *decoder);
43 static FILE *get_binary_stdin_();
44 static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
45 static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
46 static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
47 static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
48 static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
49 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
50 static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
51 static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
52
53 /***********************************************************************
54  *
55  * Private class data
56  *
57  ***********************************************************************/
58
59 typedef struct FLAC__FileDecoderPrivate {
60         FLAC__FileDecoderWriteCallback write_callback;
61         FLAC__FileDecoderMetadataCallback metadata_callback;
62         FLAC__FileDecoderErrorCallback error_callback;
63         void *client_data;
64         FILE *file;
65         char *filename; /* == NULL if stdin */
66         FLAC__SeekableStreamDecoder *seekable_stream_decoder;
67 } FLAC__FileDecoderPrivate;
68
69 /***********************************************************************
70  *
71  * Public static class data
72  *
73  ***********************************************************************/
74
75 FLAC_API const char * const FLAC__FileDecoderStateString[] = {
76         "FLAC__FILE_DECODER_OK",
77         "FLAC__FILE_DECODER_END_OF_FILE",
78         "FLAC__FILE_DECODER_ERROR_OPENING_FILE",
79         "FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
80         "FLAC__FILE_DECODER_SEEK_ERROR",
81         "FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR",
82         "FLAC__FILE_DECODER_ALREADY_INITIALIZED",
83         "FLAC__FILE_DECODER_INVALID_CALLBACK",
84         "FLAC__FILE_DECODER_UNINITIALIZED"
85 };
86
87 /***********************************************************************
88  *
89  * Class constructor/destructor
90  *
91  ***********************************************************************/
92
93 FLAC_API FLAC__FileDecoder *FLAC__file_decoder_new()
94 {
95         FLAC__FileDecoder *decoder;
96
97         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
98
99         decoder = (FLAC__FileDecoder*)calloc(1, sizeof(FLAC__FileDecoder));
100         if(decoder == 0) {
101                 return 0;
102         }
103
104         decoder->protected_ = (FLAC__FileDecoderProtected*)calloc(1, sizeof(FLAC__FileDecoderProtected));
105         if(decoder->protected_ == 0) {
106                 free(decoder);
107                 return 0;
108         }
109
110         decoder->private_ = (FLAC__FileDecoderPrivate*)calloc(1, sizeof(FLAC__FileDecoderPrivate));
111         if(decoder->private_ == 0) {
112                 free(decoder->protected_);
113                 free(decoder);
114                 return 0;
115         }
116
117         decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
118         if(0 == decoder->private_->seekable_stream_decoder) {
119                 free(decoder->private_);
120                 free(decoder->protected_);
121                 free(decoder);
122                 return 0;
123         }
124
125         decoder->private_->file = 0;
126
127         set_defaults_(decoder);
128
129         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
130
131         return decoder;
132 }
133
134 FLAC_API void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder)
135 {
136         FLAC__ASSERT(0 != decoder);
137         FLAC__ASSERT(0 != decoder->protected_);
138         FLAC__ASSERT(0 != decoder->private_);
139         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
140
141         (void)FLAC__file_decoder_finish(decoder);
142
143         FLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
144
145         free(decoder->private_);
146         free(decoder->protected_);
147         free(decoder);
148 }
149
150 /***********************************************************************
151  *
152  * Public class methods
153  *
154  ***********************************************************************/
155
156 FLAC_API FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
157 {
158         FLAC__ASSERT(0 != decoder);
159
160         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
161                 return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;
162
163         if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
164                 return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;
165
166         if(0 == decoder->private_->filename)
167                 decoder->private_->file = get_binary_stdin_();
168         else
169                 decoder->private_->file = fopen(decoder->private_->filename, "rb");
170
171         if(decoder->private_->file == 0)
172                 return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
173
174         FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
175         FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
176         FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
177         FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
178         FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
179         FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
180         FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
181         FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
182         FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
183
184         if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
185                 return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
186
187         return decoder->protected_->state = FLAC__FILE_DECODER_OK;
188 }
189
190 FLAC_API FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
191 {
192         FLAC__ASSERT(0 != decoder);
193
194         if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED)
195                 return true;
196
197         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
198
199         if(0 != decoder->private_->file && decoder->private_->file != stdin) {
200                 fclose(decoder->private_->file);
201                 decoder->private_->file = 0;
202         }
203
204         if(0 != decoder->private_->filename) {
205                 free(decoder->private_->filename);
206                 decoder->private_->filename = 0;
207         }
208
209         set_defaults_(decoder);
210
211         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
212
213         return FLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
214 }
215
216 FLAC_API FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value)
217 {
218         FLAC__ASSERT(0 != decoder);
219         FLAC__ASSERT(0 != decoder->private_);
220         FLAC__ASSERT(0 != decoder->protected_);
221         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
222         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
223                 return false;
224         return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
225 }
226
227 FLAC_API FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value)
228 {
229         FLAC__ASSERT(0 != decoder);
230         FLAC__ASSERT(0 != decoder->private_);
231         FLAC__ASSERT(0 != decoder->protected_);
232         FLAC__ASSERT(0 != value);
233         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
234                 return false;
235         if(0 != decoder->private_->filename) {
236                 free(decoder->private_->filename);
237                 decoder->private_->filename = 0;
238         }
239         if(0 != strcmp(value, "-")) {
240                 if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
241                         decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
242                         return false;
243                 }
244                 strcpy(decoder->private_->filename, value);
245         }
246         return true;
247 }
248
249 FLAC_API FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderWriteCallback value)
250 {
251         FLAC__ASSERT(0 != decoder);
252         FLAC__ASSERT(0 != decoder->private_);
253         FLAC__ASSERT(0 != decoder->protected_);
254         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
255                 return false;
256         decoder->private_->write_callback = value;
257         return true;
258 }
259
260 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderMetadataCallback value)
261 {
262         FLAC__ASSERT(0 != decoder);
263         FLAC__ASSERT(0 != decoder->private_);
264         FLAC__ASSERT(0 != decoder->protected_);
265         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
266                 return false;
267         decoder->private_->metadata_callback = value;
268         return true;
269 }
270
271 FLAC_API FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderErrorCallback value)
272 {
273         FLAC__ASSERT(0 != decoder);
274         FLAC__ASSERT(0 != decoder->private_);
275         FLAC__ASSERT(0 != decoder->protected_);
276         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
277                 return false;
278         decoder->private_->error_callback = value;
279         return true;
280 }
281
282 FLAC_API FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value)
283 {
284         FLAC__ASSERT(0 != decoder);
285         FLAC__ASSERT(0 != decoder->private_);
286         FLAC__ASSERT(0 != decoder->protected_);
287         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
288                 return false;
289         decoder->private_->client_data = value;
290         return true;
291 }
292
293 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
294 {
295         FLAC__ASSERT(0 != decoder);
296         FLAC__ASSERT(0 != decoder->private_);
297         FLAC__ASSERT(0 != decoder->protected_);
298         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
299         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
300                 return false;
301         return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type);
302 }
303
304 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
305 {
306         FLAC__ASSERT(0 != decoder);
307         FLAC__ASSERT(0 != decoder->private_);
308         FLAC__ASSERT(0 != decoder->protected_);
309         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
310         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
311                 return false;
312         return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id);
313 }
314
315 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder)
316 {
317         FLAC__ASSERT(0 != decoder);
318         FLAC__ASSERT(0 != decoder->private_);
319         FLAC__ASSERT(0 != decoder->protected_);
320         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
321         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
322                 return false;
323         return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder);
324 }
325
326 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
327 {
328         FLAC__ASSERT(0 != decoder);
329         FLAC__ASSERT(0 != decoder->private_);
330         FLAC__ASSERT(0 != decoder->protected_);
331         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
332         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
333                 return false;
334         return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type);
335 }
336
337 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
338 {
339         FLAC__ASSERT(0 != decoder);
340         FLAC__ASSERT(0 != decoder->private_);
341         FLAC__ASSERT(0 != decoder->protected_);
342         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
343         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
344                 return false;
345         return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id);
346 }
347
348 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder)
349 {
350         FLAC__ASSERT(0 != decoder);
351         FLAC__ASSERT(0 != decoder->private_);
352         FLAC__ASSERT(0 != decoder->protected_);
353         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
354         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
355                 return false;
356         return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
357 }
358
359 FLAC_API FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder)
360 {
361         FLAC__ASSERT(0 != decoder);
362         FLAC__ASSERT(0 != decoder->protected_);
363         return decoder->protected_->state;
364 }
365
366 FLAC_API FLAC__SeekableStreamDecoderState FLAC__file_decoder_get_seekable_stream_decoder_state(const FLAC__FileDecoder *decoder)
367 {
368         FLAC__ASSERT(0 != decoder);
369         FLAC__ASSERT(0 != decoder->private_);
370         return FLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
371 }
372
373 FLAC_API FLAC__StreamDecoderState FLAC__file_decoder_get_stream_decoder_state(const FLAC__FileDecoder *decoder)
374 {
375         FLAC__ASSERT(0 != decoder);
376         FLAC__ASSERT(0 != decoder->private_);
377         return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
378 }
379
380 FLAC_API FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder)
381 {
382         FLAC__ASSERT(0 != decoder);
383         FLAC__ASSERT(0 != decoder->private_);
384         return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
385 }
386
387 FLAC_API unsigned FLAC__file_decoder_get_channels(const FLAC__FileDecoder *decoder)
388 {
389         FLAC__ASSERT(0 != decoder);
390         FLAC__ASSERT(0 != decoder->private_);
391         return FLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
392 }
393
394 FLAC_API FLAC__ChannelAssignment FLAC__file_decoder_get_channel_assignment(const FLAC__FileDecoder *decoder)
395 {
396         FLAC__ASSERT(0 != decoder);
397         FLAC__ASSERT(0 != decoder->private_);
398         return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
399 }
400
401 FLAC_API unsigned FLAC__file_decoder_get_bits_per_sample(const FLAC__FileDecoder *decoder)
402 {
403         FLAC__ASSERT(0 != decoder);
404         FLAC__ASSERT(0 != decoder->private_);
405         return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
406 }
407
408 FLAC_API unsigned FLAC__file_decoder_get_sample_rate(const FLAC__FileDecoder *decoder)
409 {
410         FLAC__ASSERT(0 != decoder);
411         FLAC__ASSERT(0 != decoder->private_);
412         return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
413 }
414
415 FLAC_API unsigned FLAC__file_decoder_get_blocksize(const FLAC__FileDecoder *decoder)
416 {
417         FLAC__ASSERT(0 != decoder);
418         FLAC__ASSERT(0 != decoder->private_);
419         return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
420 }
421
422 FLAC_API FLAC__bool FLAC__file_decoder_process_single(FLAC__FileDecoder *decoder)
423 {
424         FLAC__bool ret;
425         FLAC__ASSERT(0 != decoder);
426
427         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
428                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
429
430         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
431                 return true;
432
433         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
434
435         ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
436         if(!ret)
437                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
438
439         return ret;
440 }
441
442 FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_metadata(FLAC__FileDecoder *decoder)
443 {
444         FLAC__bool ret;
445         FLAC__ASSERT(0 != decoder);
446
447         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
448                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
449
450         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
451                 return true;
452
453         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
454
455         ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
456         if(!ret)
457                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
458
459         return ret;
460 }
461
462 FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_file(FLAC__FileDecoder *decoder)
463 {
464         FLAC__bool ret;
465         FLAC__ASSERT(0 != decoder);
466
467         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
468                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
469
470         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
471                 return true;
472
473         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
474
475         ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
476         if(!ret)
477                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
478
479         return ret;
480 }
481
482 FLAC_API FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample)
483 {
484         FLAC__ASSERT(0 != decoder);
485         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK || decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE);
486
487         if(decoder->private_->filename == 0) { /* means the file is stdin... */
488                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
489                 return false;
490         }
491
492         if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
493                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
494                 return false;
495         }
496         else {
497                 decoder->protected_->state = FLAC__FILE_DECODER_OK;
498                 return true;
499         }
500 }
501
502
503 /***********************************************************************
504  *
505  * Private class methods
506  *
507  ***********************************************************************/
508
509 void set_defaults_(FLAC__FileDecoder *decoder)
510 {
511         FLAC__ASSERT(0 != decoder);
512         FLAC__ASSERT(0 != decoder->private_);
513
514         decoder->private_->filename = 0;
515         decoder->private_->write_callback = 0;
516         decoder->private_->metadata_callback = 0;
517         decoder->private_->error_callback = 0;
518         decoder->private_->client_data = 0;
519 }
520
521 /*
522  * This will forcibly set stdin to binary mode (for OSes that require it)
523  */
524 FILE *get_binary_stdin_()
525 {
526         /* if something breaks here it is probably due to the presence or
527          * absence of an underscore before the identifiers 'setmode',
528          * 'fileno', and/or 'O_BINARY'; check your system header files.
529          */
530 #if defined _MSC_VER || defined __MINGW32__
531         _setmode(_fileno(stdin), _O_BINARY);
532 #elif defined __CYGWIN__
533         /* almost certainly not needed for any modern Cygwin, but let's be safe... */
534         setmode(_fileno(stdin), _O_BINARY);
535 #endif
536
537         return stdin;
538 }
539
540 FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
541 {
542         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
543         (void)decoder;
544
545         if(*bytes > 0) {
546                 size_t bytes_read = fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
547                 if(bytes_read == 0 && !feof(file_decoder->private_->file)) {
548                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
549                 }
550                 else {
551                         *bytes = (unsigned)bytes_read;
552                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
553                 }
554         }
555         else
556                 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
557 }
558
559 FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
560 {
561         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
562         (void)decoder;
563
564         if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
565                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
566         else
567                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
568 }
569
570 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
571 {
572         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
573         long pos;
574         (void)decoder;
575
576         if((pos = ftell(file_decoder->private_->file)) < 0)
577                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
578         else {
579                 *absolute_byte_offset = (FLAC__uint64)pos;
580                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
581         }
582 }
583
584 FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
585 {
586         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
587         struct stat filestats;
588         (void)decoder;
589
590         if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
591                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
592         else {
593                 *stream_length = (FLAC__uint64)filestats.st_size;
594                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
595         }
596 }
597
598 FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)
599 {
600         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
601         (void)decoder;
602
603         return feof(file_decoder->private_->file);
604 }
605
606 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
607 {
608         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
609         (void)decoder;
610
611         return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
612 }
613
614 void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
615 {
616         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
617         (void)decoder;
618
619         file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
620 }
621
622 void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
623 {
624         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
625         (void)decoder;
626
627         file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
628 }