#include fcntl.h in cygwin builds
[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 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__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*)malloc(sizeof(FLAC__FileDecoder));
100         if(decoder == 0) {
101                 return 0;
102         }
103         memset(decoder, 0, sizeof(FLAC__FileDecoder));
104
105         decoder->protected_ = (FLAC__FileDecoderProtected*)malloc(sizeof(FLAC__FileDecoderProtected));
106         if(decoder->protected_ == 0) {
107                 free(decoder);
108                 return 0;
109         }
110         memset(decoder->protected_, 0, sizeof(FLAC__FileDecoderProtected));
111
112         decoder->private_ = (FLAC__FileDecoderPrivate*)malloc(sizeof(FLAC__FileDecoderPrivate));
113         if(decoder->private_ == 0) {
114                 free(decoder->protected_);
115                 free(decoder);
116                 return 0;
117         }
118         memset(decoder->private_, 0, sizeof(FLAC__FileDecoderPrivate));
119
120         decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
121         if(0 == decoder->private_->seekable_stream_decoder) {
122                 free(decoder->private_);
123                 free(decoder->protected_);
124                 free(decoder);
125                 return 0;
126         }
127
128         decoder->private_->file = 0;
129
130         set_defaults_(decoder);
131
132         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
133
134         return decoder;
135 }
136
137 void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder)
138 {
139         FLAC__ASSERT(0 != decoder);
140         FLAC__ASSERT(0 != decoder->protected_);
141         FLAC__ASSERT(0 != decoder->private_);
142         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
143
144         (void)FLAC__file_decoder_finish(decoder);
145
146         FLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
147
148         free(decoder->private_);
149         free(decoder->protected_);
150         free(decoder);
151 }
152
153 /***********************************************************************
154  *
155  * Public class methods
156  *
157  ***********************************************************************/
158
159 FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
160 {
161         FLAC__ASSERT(0 != decoder);
162
163         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
164                 return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;
165
166         if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
167                 return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;
168
169         if(0 == decoder->private_->filename)
170                 decoder->private_->file = get_binary_stdin_();
171         else
172                 decoder->private_->file = fopen(decoder->private_->filename, "rb");
173
174         if(decoder->private_->file == 0)
175                 return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
176
177         FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
178         FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
179         FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
180         FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
181         FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
182         FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
183         FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
184         FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
185         FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
186
187         if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
188                 return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
189
190         return decoder->protected_->state = FLAC__FILE_DECODER_OK;
191 }
192
193 FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
194 {
195         FLAC__ASSERT(0 != decoder);
196
197         if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED)
198                 return true;
199
200         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
201
202         if(0 != decoder->private_->file && decoder->private_->file != stdin) {
203                 fclose(decoder->private_->file);
204                 decoder->private_->file = 0;
205         }
206
207         if(0 != decoder->private_->filename) {
208                 free(decoder->private_->filename);
209                 decoder->private_->filename = 0;
210         }
211
212         set_defaults_(decoder);
213
214         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
215
216         return FLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
217 }
218
219 FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value)
220 {
221         FLAC__ASSERT(0 != decoder);
222         FLAC__ASSERT(0 != decoder->private_);
223         FLAC__ASSERT(0 != decoder->protected_);
224         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
225         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
226                 return false;
227         return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
228 }
229
230 FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value)
231 {
232         FLAC__ASSERT(0 != decoder);
233         FLAC__ASSERT(0 != decoder->private_);
234         FLAC__ASSERT(0 != decoder->protected_);
235         FLAC__ASSERT(0 != value);
236         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
237                 return false;
238         if(0 != decoder->private_->filename) {
239                 free(decoder->private_->filename);
240                 decoder->private_->filename = 0;
241         }
242         if(0 != strcmp(value, "-")) {
243                 if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
244                         decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
245                         return false;
246                 }
247                 strcpy(decoder->private_->filename, value);
248         }
249         return true;
250 }
251
252 FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderWriteCallback value)
253 {
254         FLAC__ASSERT(0 != decoder);
255         FLAC__ASSERT(0 != decoder->private_);
256         FLAC__ASSERT(0 != decoder->protected_);
257         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
258                 return false;
259         decoder->private_->write_callback = value;
260         return true;
261 }
262
263 FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderMetadataCallback value)
264 {
265         FLAC__ASSERT(0 != decoder);
266         FLAC__ASSERT(0 != decoder->private_);
267         FLAC__ASSERT(0 != decoder->protected_);
268         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
269                 return false;
270         decoder->private_->metadata_callback = value;
271         return true;
272 }
273
274 FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderErrorCallback value)
275 {
276         FLAC__ASSERT(0 != decoder);
277         FLAC__ASSERT(0 != decoder->private_);
278         FLAC__ASSERT(0 != decoder->protected_);
279         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
280                 return false;
281         decoder->private_->error_callback = value;
282         return true;
283 }
284
285 FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value)
286 {
287         FLAC__ASSERT(0 != decoder);
288         FLAC__ASSERT(0 != decoder->private_);
289         FLAC__ASSERT(0 != decoder->protected_);
290         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
291                 return false;
292         decoder->private_->client_data = value;
293         return true;
294 }
295
296 FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
297 {
298         FLAC__ASSERT(0 != decoder);
299         FLAC__ASSERT(0 != decoder->private_);
300         FLAC__ASSERT(0 != decoder->protected_);
301         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
302         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
303                 return false;
304         return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type);
305 }
306
307 FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
308 {
309         FLAC__ASSERT(0 != decoder);
310         FLAC__ASSERT(0 != decoder->private_);
311         FLAC__ASSERT(0 != decoder->protected_);
312         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
313         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
314                 return false;
315         return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id);
316 }
317
318 FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder)
319 {
320         FLAC__ASSERT(0 != decoder);
321         FLAC__ASSERT(0 != decoder->private_);
322         FLAC__ASSERT(0 != decoder->protected_);
323         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
324         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
325                 return false;
326         return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder);
327 }
328
329 FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
330 {
331         FLAC__ASSERT(0 != decoder);
332         FLAC__ASSERT(0 != decoder->private_);
333         FLAC__ASSERT(0 != decoder->protected_);
334         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
335         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
336                 return false;
337         return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type);
338 }
339
340 FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
341 {
342         FLAC__ASSERT(0 != decoder);
343         FLAC__ASSERT(0 != decoder->private_);
344         FLAC__ASSERT(0 != decoder->protected_);
345         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
346         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
347                 return false;
348         return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id);
349 }
350
351 FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder)
352 {
353         FLAC__ASSERT(0 != decoder);
354         FLAC__ASSERT(0 != decoder->private_);
355         FLAC__ASSERT(0 != decoder->protected_);
356         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
357         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
358                 return false;
359         return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
360 }
361
362
363 FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder)
364 {
365         FLAC__ASSERT(0 != decoder);
366         FLAC__ASSERT(0 != decoder->protected_);
367         return decoder->protected_->state;
368 }
369
370 FLAC__SeekableStreamDecoderState FLAC__file_decoder_get_seekable_stream_decoder_state(const FLAC__FileDecoder *decoder)
371 {
372         FLAC__ASSERT(0 != decoder);
373         FLAC__ASSERT(0 != decoder->private_);
374         return FLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
375 }
376
377 FLAC__StreamDecoderState FLAC__file_decoder_get_stream_decoder_state(const FLAC__FileDecoder *decoder)
378 {
379         FLAC__ASSERT(0 != decoder);
380         FLAC__ASSERT(0 != decoder->private_);
381         return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
382 }
383
384 FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder)
385 {
386         FLAC__ASSERT(0 != decoder);
387         FLAC__ASSERT(0 != decoder->private_);
388         return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
389 }
390
391 unsigned FLAC__file_decoder_get_channels(const FLAC__FileDecoder *decoder)
392 {
393         FLAC__ASSERT(0 != decoder);
394         FLAC__ASSERT(0 != decoder->private_);
395         return FLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
396 }
397
398 FLAC__ChannelAssignment FLAC__file_decoder_get_channel_assignment(const FLAC__FileDecoder *decoder)
399 {
400         FLAC__ASSERT(0 != decoder);
401         FLAC__ASSERT(0 != decoder->private_);
402         return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
403 }
404
405 unsigned FLAC__file_decoder_get_bits_per_sample(const FLAC__FileDecoder *decoder)
406 {
407         FLAC__ASSERT(0 != decoder);
408         FLAC__ASSERT(0 != decoder->private_);
409         return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
410 }
411
412 unsigned FLAC__file_decoder_get_sample_rate(const FLAC__FileDecoder *decoder)
413 {
414         FLAC__ASSERT(0 != decoder);
415         FLAC__ASSERT(0 != decoder->private_);
416         return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
417 }
418
419 unsigned FLAC__file_decoder_get_blocksize(const FLAC__FileDecoder *decoder)
420 {
421         FLAC__ASSERT(0 != decoder);
422         FLAC__ASSERT(0 != decoder->private_);
423         return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
424 }
425
426 FLAC__bool FLAC__file_decoder_process_single(FLAC__FileDecoder *decoder)
427 {
428         FLAC__bool ret;
429         FLAC__ASSERT(0 != decoder);
430
431         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
432                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
433
434         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
435                 return true;
436
437         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
438
439         ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
440         if(!ret)
441                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
442
443         return ret;
444 }
445
446 FLAC__bool FLAC__file_decoder_process_until_end_of_metadata(FLAC__FileDecoder *decoder)
447 {
448         FLAC__bool ret;
449         FLAC__ASSERT(0 != decoder);
450
451         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
452                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
453
454         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
455                 return true;
456
457         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
458
459         ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
460         if(!ret)
461                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
462
463         return ret;
464 }
465
466 FLAC__bool FLAC__file_decoder_process_until_end_of_file(FLAC__FileDecoder *decoder)
467 {
468         FLAC__bool ret;
469         FLAC__ASSERT(0 != decoder);
470
471         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
472                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
473
474         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
475                 return true;
476
477         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
478
479         ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
480         if(!ret)
481                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
482
483         return ret;
484 }
485
486 FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample)
487 {
488         FLAC__ASSERT(0 != decoder);
489         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK || decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE);
490
491         if(decoder->private_->filename == 0) { /* means the file is stdin... */
492                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
493                 return false;
494         }
495
496         if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
497                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
498                 return false;
499         }
500         else {
501                 decoder->protected_->state = FLAC__FILE_DECODER_OK;
502                 return true;
503         }
504 }
505
506
507 /***********************************************************************
508  *
509  * Private class methods
510  *
511  ***********************************************************************/
512
513 void set_defaults_(FLAC__FileDecoder *decoder)
514 {
515         FLAC__ASSERT(0 != decoder);
516         FLAC__ASSERT(0 != decoder->private_);
517
518         decoder->private_->filename = 0;
519         decoder->private_->write_callback = 0;
520         decoder->private_->metadata_callback = 0;
521         decoder->private_->error_callback = 0;
522         decoder->private_->client_data = 0;
523 }
524
525 /*
526  * This will forcibly set stdin to binary mode (for OSes that require it)
527  */
528 FILE *get_binary_stdin_()
529 {
530         /* if something breaks here it is probably due to the presence or
531          * absence of an underscore before the identifiers 'setmode',
532          * 'fileno', and/or 'O_BINARY'; check your system header files.
533          */
534 #if defined _MSC_VER || defined __MINGW32__
535         _setmode(_fileno(stdin), _O_BINARY);
536 #elif defined __CYGWIN__
537         /* almost certainly not needed for any modern Cygwin, but let's be safe... */
538         setmode(_fileno(stdin), _O_BINARY);
539 #endif
540
541         return stdin;
542 }
543
544 FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
545 {
546         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
547         (void)decoder;
548
549         if(*bytes > 0) {
550                 size_t bytes_read = fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
551                 if(bytes_read == 0 && !feof(file_decoder->private_->file)) {
552                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
553                 }
554                 else {
555                         *bytes = (unsigned)bytes_read;
556                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
557                 }
558         }
559         else
560                 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
561 }
562
563 FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
564 {
565         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
566         (void)decoder;
567
568         if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
569                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
570         else
571                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
572 }
573
574 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
575 {
576         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
577         long pos;
578         (void)decoder;
579
580         if((pos = ftell(file_decoder->private_->file)) < 0)
581                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
582         else {
583                 *absolute_byte_offset = (FLAC__uint64)pos;
584                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
585         }
586 }
587
588 FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
589 {
590         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
591         struct stat filestats;
592         (void)decoder;
593
594         if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
595                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
596         else {
597                 *stream_length = (FLAC__uint64)filestats.st_size;
598                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
599         }
600 }
601
602 FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)
603 {
604         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
605         (void)decoder;
606
607         return feof(file_decoder->private_->file);
608 }
609
610 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
611 {
612         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
613         (void)decoder;
614
615         return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
616 }
617
618 void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
619 {
620         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
621         (void)decoder;
622
623         file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
624 }
625
626 void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
627 {
628         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
629         (void)decoder;
630
631         file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
632 }