try to limit the #defines (of fseeko to fseek and ftello to ftell) to just the versio...
[flac.git] / src / test_libFLAC++ / decoders.cpp
1 /* test_libFLAC++ - Unit tester for libFLAC++
2  * Copyright (C) 2002,2003,2004,2005,2006  Josh Coalson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program 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
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18
19 #if HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #if defined _MSC_VER || defined __MINGW32__
28 #if _MSC_VER <= 1200 /* @@@ [2G limit] */
29 #define fseeko fseek
30 #define ftello ftell
31 #endif
32 #endif
33 #include "decoders.h"
34 #include "FLAC/assert.h"
35 #include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal()
36 #include "FLAC++/decoder.h"
37 #include "share/grabbag.h"
38 extern "C" {
39 #include "test_libs_common/file_utils_flac.h"
40 #include "test_libs_common/metadata_utils.h"
41 }
42
43 #ifdef _MSC_VER
44 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
45 #pragma warning ( disable : 4800 )
46 #endif
47
48 typedef enum {
49         LAYER_STREAM = 0, /* FLAC__stream_decoder_init_stream() without seeking */
50         LAYER_SEEKABLE_STREAM, /* FLAC__stream_decoder_init_stream() with seeking */
51         LAYER_FILE, /* FLAC__stream_decoder_init_FILE() */
52         LAYER_FILENAME /* FLAC__stream_decoder_init_file() */
53 } Layer;
54
55 static const char * const LayerString[] = {
56         "Stream",
57         "Seekable Stream",
58         "FILE*",
59         "Filename"
60 };
61
62 static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, picture_, unknown_;
63 static ::FLAC__StreamMetadata *expected_metadata_sequence_[9];
64 static unsigned num_expected_;
65 static const char *flacfilename_ = "metadata.flac";
66 static off_t flacfilesize_;
67
68 static bool die_(const char *msg)
69 {
70         printf("ERROR: %s\n", msg);
71         return false;
72 }
73
74 static FLAC__bool die_s_(const char *msg, const FLAC::Decoder::Stream *decoder)
75 {
76         FLAC::Decoder::Stream::State state = decoder->get_state();
77
78         if(msg)
79                 printf("FAILED, %s", msg);
80         else
81                 printf("FAILED");
82
83         printf(", state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
84
85         return false;
86 }
87
88 static void init_metadata_blocks_()
89 {
90         mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
91 }
92
93 static void free_metadata_blocks_()
94 {
95         mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
96 }
97
98 static bool generate_file_()
99 {
100         printf("\n\ngenerating FLAC file for decoder tests...\n");
101
102         num_expected_ = 0;
103         expected_metadata_sequence_[num_expected_++] = &padding_;
104         expected_metadata_sequence_[num_expected_++] = &seektable_;
105         expected_metadata_sequence_[num_expected_++] = &application1_;
106         expected_metadata_sequence_[num_expected_++] = &application2_;
107         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
108         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
109         expected_metadata_sequence_[num_expected_++] = &picture_;
110         expected_metadata_sequence_[num_expected_++] = &unknown_;
111
112         if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
113                 return die_("creating the encoded file");
114
115         return true;
116 }
117
118
119 class DecoderCommon {
120 public:
121         Layer layer_;
122         unsigned current_metadata_number_;
123         bool ignore_errors_;
124         bool error_occurred_;
125
126         DecoderCommon(Layer layer): layer_(layer), current_metadata_number_(0), ignore_errors_(false), error_occurred_(false) { }
127         ::FLAC__StreamDecoderWriteStatus common_write_callback_(const ::FLAC__Frame *frame);
128         void common_metadata_callback_(const ::FLAC__StreamMetadata *metadata);
129         void common_error_callback_(::FLAC__StreamDecoderErrorStatus status);
130 };
131
132 ::FLAC__StreamDecoderWriteStatus DecoderCommon::common_write_callback_(const ::FLAC__Frame *frame)
133 {
134         if(error_occurred_)
135                 return ::FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
136
137         if(
138                 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
139                 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
140         ) {
141                 printf("content... ");
142                 fflush(stdout);
143         }
144
145         return ::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
146 }
147
148 void DecoderCommon::common_metadata_callback_(const ::FLAC__StreamMetadata *metadata)
149 {
150         if(error_occurred_)
151                 return;
152
153         printf("%d... ", current_metadata_number_);
154         fflush(stdout);
155
156         if(current_metadata_number_ >= num_expected_) {
157                 (void)die_("got more metadata blocks than expected");
158                 error_occurred_ = true;
159         }
160         else {
161                 if(!::FLAC__metadata_object_is_equal(expected_metadata_sequence_[current_metadata_number_], metadata)) {
162                         (void)die_("metadata block mismatch");
163                         error_occurred_ = true;
164                 }
165         }
166         current_metadata_number_++;
167 }
168
169 void DecoderCommon::common_error_callback_(::FLAC__StreamDecoderErrorStatus status)
170 {
171         if(!ignore_errors_) {
172                 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, ::FLAC__StreamDecoderErrorStatusString[status]);
173                 error_occurred_ = true;
174         }
175 }
176
177 class StreamDecoder : public FLAC::Decoder::Stream, public DecoderCommon {
178 public:
179         FILE *file_;
180
181         StreamDecoder(Layer layer): FLAC::Decoder::Stream(), DecoderCommon(layer), file_(0) { }
182         ~StreamDecoder() { }
183
184         // from FLAC::Decoder::Stream
185         ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
186         ::FLAC__StreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset);
187         ::FLAC__StreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset);
188         ::FLAC__StreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length);
189         bool eof_callback();
190         ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
191         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
192         void error_callback(::FLAC__StreamDecoderErrorStatus status);
193
194         bool test_respond();
195 };
196
197 ::FLAC__StreamDecoderReadStatus StreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
198 {
199         const unsigned requested_bytes = *bytes;
200
201         if(error_occurred_)
202                 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT;
203
204         if(feof(file_)) {
205                 *bytes = 0;
206                 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
207         }
208         else if(requested_bytes > 0) {
209                 *bytes = ::fread(buffer, 1, requested_bytes, file_);
210                 if(*bytes == 0) {
211                         if(feof(file_))
212                                 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
213                         else
214                                 return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
215                 }
216                 else {
217                         return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
218                 }
219         }
220         else
221                 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
222 }
223
224 ::FLAC__StreamDecoderSeekStatus StreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset)
225 {
226         if(layer_ == LAYER_STREAM)
227                 return ::FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
228
229         if(error_occurred_)
230                 return ::FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
231
232         if(fseeko(file_, (off_t)absolute_byte_offset, SEEK_SET) < 0) {
233                 error_occurred_ = true;
234                 return ::FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
235         }
236
237         return ::FLAC__STREAM_DECODER_SEEK_STATUS_OK;
238 }
239
240 ::FLAC__StreamDecoderTellStatus StreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset)
241 {
242         if(layer_ == LAYER_STREAM)
243                 return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
244
245         if(error_occurred_)
246                 return ::FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
247
248         off_t offset = ftello(file_);
249         *absolute_byte_offset = (FLAC__uint64)offset;
250
251         if(offset < 0) {
252                 error_occurred_ = true;
253                 return ::FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
254         }
255
256         return ::FLAC__STREAM_DECODER_TELL_STATUS_OK;
257 }
258
259 ::FLAC__StreamDecoderLengthStatus StreamDecoder::length_callback(FLAC__uint64 *stream_length)
260 {
261         if(layer_ == LAYER_STREAM)
262                 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
263
264         if(error_occurred_)
265                 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
266
267         *stream_length = (FLAC__uint64)flacfilesize_;
268         return ::FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
269 }
270
271 bool StreamDecoder::eof_callback()
272 {
273         if(layer_ == LAYER_STREAM)
274                 return false;
275
276         if(error_occurred_)
277                 return true;
278
279         return (bool)feof(file_);
280 }
281
282 ::FLAC__StreamDecoderWriteStatus StreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
283 {
284         (void)buffer;
285
286         return common_write_callback_(frame);
287 }
288
289 void StreamDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
290 {
291         common_metadata_callback_(metadata);
292 }
293
294 void StreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
295 {
296         common_error_callback_(status);
297 }
298
299 bool StreamDecoder::test_respond()
300 {
301         if(!set_md5_checking(true)) {
302                 printf("FAILED at set_md5_checking(), returned false\n");
303                 return false;
304         }
305
306         printf("testing init()... ");
307         if(init() != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
308                 return die_s_(0, this);
309         printf("OK\n");
310
311         current_metadata_number_ = 0;
312
313         if(fseeko(file_, 0, SEEK_SET) < 0) {
314                 printf("FAILED rewinding input, errno = %d\n", errno);
315                 return false;
316         }
317
318         printf("testing process_until_end_of_stream()... ");
319         if(!process_until_end_of_stream()) {
320                 State state = get_state();
321                 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
322                 return false;
323         }
324         printf("OK\n");
325
326         printf("testing finish()... ");
327         finish();
328         printf("OK\n");
329
330         return true;
331 }
332
333 class FileDecoder : public FLAC::Decoder::File, public DecoderCommon {
334 public:
335         FileDecoder(Layer layer): FLAC::Decoder::File(), DecoderCommon(layer) { }
336         ~FileDecoder() { }
337
338         // from FLAC::Decoder::Stream
339         ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
340         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
341         void error_callback(::FLAC__StreamDecoderErrorStatus status);
342
343         bool test_respond();
344 };
345
346 ::FLAC__StreamDecoderWriteStatus FileDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
347 {
348         (void)buffer;
349         return common_write_callback_(frame);
350 }
351
352 void FileDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
353 {
354         common_metadata_callback_(metadata);
355 }
356
357 void FileDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
358 {
359         common_error_callback_(status);
360 }
361
362 bool FileDecoder::test_respond()
363 {
364         if(!set_md5_checking(true)) {
365                 printf("FAILED at set_md5_checking(), returned false\n");
366                 return false;
367         }
368
369         switch(layer_) {
370                 case LAYER_FILE:
371                         {
372                                 printf("opening FLAC file... ");
373                                 FILE *file = ::fopen(flacfilename_, "rb");
374                                 if(0 == file) {
375                                         printf("ERROR (%s)\n", strerror(errno));
376                                         return false;
377                                 }
378                                 printf("OK\n");
379
380                                 printf("testing init()... ");
381                                 if(init(file) != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
382                                         return die_s_(0, this);
383                         }
384                         break;
385                 case LAYER_FILENAME:
386                         printf("testing init()... ");
387                         if(init(flacfilename_) != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
388                                 return die_s_(0, this);
389                         break;
390                 default:
391                         die_("internal error 001");
392                         return false;
393         }
394         printf("OK\n");
395
396         current_metadata_number_ = 0;
397
398         printf("testing process_until_end_of_stream()... ");
399         if(!process_until_end_of_stream()) {
400                 State state = get_state();
401                 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
402                 return false;
403         }
404         printf("OK\n");
405
406         printf("testing finish()... ");
407         finish();
408         printf("OK\n");
409
410         return true;
411 }
412
413
414 static FLAC::Decoder::Stream *new_by_layer(Layer layer)
415 {
416         if(layer < LAYER_FILE)
417                 return new StreamDecoder(layer);
418         else
419                 return new FileDecoder(layer);
420 }
421
422 static bool test_stream_decoder(Layer layer)
423 {
424         FLAC::Decoder::Stream *decoder;
425         bool expect;
426
427         printf("\n+++ libFLAC++ unit test: FLAC::Decoder::%s (layer: %s)\n\n", layer<LAYER_FILE? "Stream":"File", LayerString[layer]);
428
429         //
430         // test new -> delete
431         //
432         printf("allocating decoder instance... ");
433         decoder = new_by_layer(layer);
434         if(0 == decoder) {
435                 printf("FAILED, new returned NULL\n");
436                 return false;
437         }
438         printf("OK\n");
439
440         printf("testing is_valid()... ");
441         if(!decoder->is_valid()) {
442                 printf("FAILED, returned false\n");
443                 return false;
444         }
445         printf("OK\n");
446
447         printf("freeing decoder instance... ");
448         delete decoder;
449         printf("OK\n");
450
451         //
452         // test new -> init -> delete
453         //
454         printf("allocating decoder instance... ");
455         decoder = new_by_layer(layer);
456         if(0 == decoder) {
457                 printf("FAILED, new returned NULL\n");
458                 return false;
459         }
460         printf("OK\n");
461
462         printf("testing is_valid()... ");
463         if(!decoder->is_valid()) {
464                 printf("FAILED, returned false\n");
465                 return false;
466         }
467         printf("OK\n");
468
469         printf("testing init()... ");
470         switch(layer) {
471                 case LAYER_STREAM:
472                 case LAYER_SEEKABLE_STREAM:
473                         dynamic_cast<StreamDecoder*>(decoder)->file_ = stdin;
474                         if(decoder->init() != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
475                                 return die_s_(0, decoder);
476                         break;
477                 case LAYER_FILE:
478                         if(dynamic_cast<FLAC::Decoder::File*>(decoder)->init(stdin) != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
479                                 return die_s_(0, decoder);
480                         break;
481                 case LAYER_FILENAME:
482                         if(dynamic_cast<FLAC::Decoder::File*>(decoder)->init(flacfilename_) != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
483                                 return die_s_(0, decoder);
484                         break;
485                 default:
486                         die_("internal error 006");
487                         return false;
488         }
489         printf("OK\n");
490
491         printf("freeing decoder instance... ");
492         delete decoder;
493         printf("OK\n");
494
495         //
496         // test normal usage
497         //
498         num_expected_ = 0;
499         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
500
501         printf("allocating decoder instance... ");
502         decoder = new_by_layer(layer);
503         if(0 == decoder) {
504                 printf("FAILED, new returned NULL\n");
505                 return false;
506         }
507         printf("OK\n");
508
509         printf("testing is_valid()... ");
510         if(!decoder->is_valid()) {
511                 printf("FAILED, returned false\n");
512                 return false;
513         }
514         printf("OK\n");
515
516         if(!decoder->set_md5_checking(true)) {
517                 printf("FAILED at set_md5_checking(), returned false\n");
518                 return false;
519         }
520
521         switch(layer) {
522                 case LAYER_STREAM:
523                 case LAYER_SEEKABLE_STREAM:
524                         printf("opening FLAC file... ");
525                         dynamic_cast<StreamDecoder*>(decoder)->file_ = ::fopen(flacfilename_, "rb");
526                         if(0 == dynamic_cast<StreamDecoder*>(decoder)->file_) {
527                                 printf("ERROR (%s)\n", strerror(errno));
528                                 return false;
529                         }
530                         printf("OK\n");
531
532                         printf("testing init()... ");
533                         if(decoder->init() != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
534                                 return die_s_(0, decoder);
535                         break;
536                 case LAYER_FILE:
537                         {
538                                 printf("opening FLAC file... ");
539                                 FILE *file = ::fopen(flacfilename_, "rb");
540                                 if(0 == file) {
541                                         printf("ERROR (%s)\n", strerror(errno));
542                                         return false;
543                                 }
544                                 printf("OK\n");
545
546                                 printf("testing init()... ");
547                                 if(dynamic_cast<FLAC::Decoder::File*>(decoder)->init(file) != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
548                                         return die_s_(0, decoder);
549                         }
550                         break;
551                 case LAYER_FILENAME:
552                         printf("testing init()... ");
553                         if(dynamic_cast<FLAC::Decoder::File*>(decoder)->init(flacfilename_) != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
554                                 return die_s_(0, decoder);
555                         break;
556                 default:
557                         die_("internal error 009");
558                         return false;
559         }
560         printf("OK\n");
561
562         printf("testing get_state()... ");
563         FLAC::Decoder::Stream::State state = decoder->get_state();
564         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
565
566         dynamic_cast<DecoderCommon*>(decoder)->current_metadata_number_ = 0;
567         dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = false;
568         dynamic_cast<DecoderCommon*>(decoder)->error_occurred_ = false;
569
570         printf("testing get_md5_checking()... ");
571         if(!decoder->get_md5_checking()) {
572                 printf("FAILED, returned false, expected true\n");
573                 return false;
574         }
575         printf("OK\n");
576
577         printf("testing process_until_end_of_metadata()... ");
578         if(!decoder->process_until_end_of_metadata())
579                 return die_s_("returned false", decoder);
580         printf("OK\n");
581
582         printf("testing process_single()... ");
583         if(!decoder->process_single())
584                 return die_s_("returned false", decoder);
585         printf("OK\n");
586
587         printf("testing skip_single_frame()... ");
588         if(!decoder->skip_single_frame())
589                 return die_s_("returned false", decoder);
590         printf("OK\n");
591
592         if(layer < LAYER_FILE) {
593                 printf("testing flush()... ");
594                 if(!decoder->flush())
595                         return die_s_("returned false", decoder);
596                 printf("OK\n");
597
598                 dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = true;
599                 printf("testing process_single()... ");
600                 if(!decoder->process_single())
601                         return die_s_("returned false", decoder);
602                 printf("OK\n");
603                 dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = false;
604         }
605
606         expect = (layer != LAYER_STREAM);
607         printf("testing seek_absolute()... ");
608         if(decoder->seek_absolute(0) != expect)
609                 return die_s_(expect? "returned false" : "returned true", decoder);
610         printf("OK\n");
611
612         printf("testing process_until_end_of_stream()... ");
613         if(!decoder->process_until_end_of_stream())
614                 return die_s_("returned false", decoder);
615         printf("OK\n");
616
617         expect = (layer != LAYER_STREAM);
618         printf("testing seek_absolute()... ");
619         if(decoder->seek_absolute(0) != expect)
620                 return die_s_(expect? "returned false" : "returned true", decoder);
621         printf("OK\n");
622
623         printf("testing get_channels()... ");
624         {
625                 unsigned channels = decoder->get_channels();
626                 if(channels != streaminfo_.data.stream_info.channels) {
627                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
628                         return false;
629                 }
630         }
631         printf("OK\n");
632
633         printf("testing get_bits_per_sample()... ");
634         {
635                 unsigned bits_per_sample = decoder->get_bits_per_sample();
636                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
637                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
638                         return false;
639                 }
640         }
641         printf("OK\n");
642
643         printf("testing get_sample_rate()... ");
644         {
645                 unsigned sample_rate = decoder->get_sample_rate();
646                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
647                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
648                         return false;
649                 }
650         }
651         printf("OK\n");
652
653         printf("testing get_blocksize()... ");
654         {
655                 unsigned blocksize = decoder->get_blocksize();
656                 /* value could be anything since we're at the last block, so accept any reasonable answer */
657                 printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED");
658                 if(blocksize == 0)
659                         return false;
660         }
661
662         printf("testing get_channel_assignment()... ");
663         {
664                 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment();
665                 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]);
666         }
667
668         if(layer < LAYER_FILE) {
669                 printf("testing reset()... ");
670                 if(!decoder->reset())
671                         return die_s_("returned false", decoder);
672                 printf("OK\n");
673
674                 if(layer == LAYER_STREAM) {
675                         /* after a reset() we have to rewind the input ourselves */
676                         printf("rewinding input... ");
677                         if(fseeko(dynamic_cast<StreamDecoder*>(decoder)->file_, 0, SEEK_SET) < 0) {
678                                 printf("FAILED, errno = %d\n", errno);
679                                 return false;
680                         }
681                         printf("OK\n");
682                 }
683
684                 dynamic_cast<DecoderCommon*>(decoder)->current_metadata_number_ = 0;
685
686                 printf("testing process_until_end_of_stream()... ");
687                 if(!decoder->process_until_end_of_stream())
688                         return die_s_("returned false", decoder);
689                 printf("OK\n");
690         }
691
692         printf("testing finish()... ");
693         decoder->finish();
694         printf("OK\n");
695
696         /*
697          * respond all
698          */
699
700         printf("testing set_metadata_respond_all()... ");
701         if(!decoder->set_metadata_respond_all()) {
702                 printf("FAILED, returned false\n");
703                 return false;
704         }
705         printf("OK\n");
706
707         num_expected_ = 0;
708         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
709         expected_metadata_sequence_[num_expected_++] = &padding_;
710         expected_metadata_sequence_[num_expected_++] = &seektable_;
711         expected_metadata_sequence_[num_expected_++] = &application1_;
712         expected_metadata_sequence_[num_expected_++] = &application2_;
713         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
714         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
715         expected_metadata_sequence_[num_expected_++] = &picture_;
716         expected_metadata_sequence_[num_expected_++] = &unknown_;
717
718         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
719                 return false;
720
721         /*
722          * ignore all
723          */
724
725         printf("testing set_metadata_ignore_all()... ");
726         if(!decoder->set_metadata_ignore_all()) {
727                 printf("FAILED, returned false\n");
728                 return false;
729         }
730         printf("OK\n");
731
732         num_expected_ = 0;
733
734         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
735                 return false;
736
737         /*
738          * respond all, ignore VORBIS_COMMENT
739          */
740
741         printf("testing set_metadata_respond_all()... ");
742         if(!decoder->set_metadata_respond_all()) {
743                 printf("FAILED, returned false\n");
744                 return false;
745         }
746         printf("OK\n");
747
748         printf("testing set_metadata_ignore(VORBIS_COMMENT)... ");
749         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
750                 printf("FAILED, returned false\n");
751                 return false;
752         }
753         printf("OK\n");
754
755         num_expected_ = 0;
756         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
757         expected_metadata_sequence_[num_expected_++] = &padding_;
758         expected_metadata_sequence_[num_expected_++] = &seektable_;
759         expected_metadata_sequence_[num_expected_++] = &application1_;
760         expected_metadata_sequence_[num_expected_++] = &application2_;
761         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
762         expected_metadata_sequence_[num_expected_++] = &picture_;
763         expected_metadata_sequence_[num_expected_++] = &unknown_;
764
765         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
766                 return false;
767
768         /*
769          * respond all, ignore APPLICATION
770          */
771
772         printf("testing set_metadata_respond_all()... ");
773         if(!decoder->set_metadata_respond_all()) {
774                 printf("FAILED, returned false\n");
775                 return false;
776         }
777         printf("OK\n");
778
779         printf("testing set_metadata_ignore(APPLICATION)... ");
780         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
781                 printf("FAILED, returned false\n");
782                 return false;
783         }
784         printf("OK\n");
785
786         num_expected_ = 0;
787         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
788         expected_metadata_sequence_[num_expected_++] = &padding_;
789         expected_metadata_sequence_[num_expected_++] = &seektable_;
790         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
791         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
792         expected_metadata_sequence_[num_expected_++] = &picture_;
793         expected_metadata_sequence_[num_expected_++] = &unknown_;
794
795         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
796                 return false;
797
798         /*
799          * respond all, ignore APPLICATION id of app#1
800          */
801
802         printf("testing set_metadata_respond_all()... ");
803         if(!decoder->set_metadata_respond_all()) {
804                 printf("FAILED, returned false\n");
805                 return false;
806         }
807         printf("OK\n");
808
809         printf("testing set_metadata_ignore_application(of app block #1)... ");
810         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
811                 printf("FAILED, returned false\n");
812                 return false;
813         }
814         printf("OK\n");
815
816         num_expected_ = 0;
817         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
818         expected_metadata_sequence_[num_expected_++] = &padding_;
819         expected_metadata_sequence_[num_expected_++] = &seektable_;
820         expected_metadata_sequence_[num_expected_++] = &application2_;
821         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
822         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
823         expected_metadata_sequence_[num_expected_++] = &picture_;
824         expected_metadata_sequence_[num_expected_++] = &unknown_;
825
826         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
827                 return false;
828
829         /*
830          * respond all, ignore APPLICATION id of app#1 & app#2
831          */
832
833         printf("testing set_metadata_respond_all()... ");
834         if(!decoder->set_metadata_respond_all()) {
835                 printf("FAILED, returned false\n");
836                 return false;
837         }
838         printf("OK\n");
839
840         printf("testing set_metadata_ignore_application(of app block #1)... ");
841         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
842                 printf("FAILED, returned false\n");
843                 return false;
844         }
845         printf("OK\n");
846
847         printf("testing set_metadata_ignore_application(of app block #2)... ");
848         if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) {
849                 printf("FAILED, returned false\n");
850                 return false;
851         }
852         printf("OK\n");
853
854         num_expected_ = 0;
855         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
856         expected_metadata_sequence_[num_expected_++] = &padding_;
857         expected_metadata_sequence_[num_expected_++] = &seektable_;
858         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
859         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
860         expected_metadata_sequence_[num_expected_++] = &picture_;
861         expected_metadata_sequence_[num_expected_++] = &unknown_;
862
863         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
864                 return false;
865
866         /*
867          * ignore all, respond VORBIS_COMMENT
868          */
869
870         printf("testing set_metadata_ignore_all()... ");
871         if(!decoder->set_metadata_ignore_all()) {
872                 printf("FAILED, returned false\n");
873                 return false;
874         }
875         printf("OK\n");
876
877         printf("testing set_metadata_respond(VORBIS_COMMENT)... ");
878         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
879                 printf("FAILED, returned false\n");
880                 return false;
881         }
882         printf("OK\n");
883
884         num_expected_ = 0;
885         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
886
887         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
888                 return false;
889
890         /*
891          * ignore all, respond APPLICATION
892          */
893
894         printf("testing set_metadata_ignore_all()... ");
895         if(!decoder->set_metadata_ignore_all()) {
896                 printf("FAILED, returned false\n");
897                 return false;
898         }
899         printf("OK\n");
900
901         printf("testing set_metadata_respond(APPLICATION)... ");
902         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
903                 printf("FAILED, returned false\n");
904                 return false;
905         }
906         printf("OK\n");
907
908         num_expected_ = 0;
909         expected_metadata_sequence_[num_expected_++] = &application1_;
910         expected_metadata_sequence_[num_expected_++] = &application2_;
911
912         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
913                 return false;
914
915         /*
916          * ignore all, respond APPLICATION id of app#1
917          */
918
919         printf("testing set_metadata_ignore_all()... ");
920         if(!decoder->set_metadata_ignore_all()) {
921                 printf("FAILED, returned false\n");
922                 return false;
923         }
924         printf("OK\n");
925
926         printf("testing set_metadata_respond_application(of app block #1)... ");
927         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
928                 printf("FAILED, returned false\n");
929                 return false;
930         }
931         printf("OK\n");
932
933         num_expected_ = 0;
934         expected_metadata_sequence_[num_expected_++] = &application1_;
935
936         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
937                 return false;
938
939         /*
940          * ignore all, respond APPLICATION id of app#1 & app#2
941          */
942
943         printf("testing set_metadata_ignore_all()... ");
944         if(!decoder->set_metadata_ignore_all()) {
945                 printf("FAILED, returned false\n");
946                 return false;
947         }
948         printf("OK\n");
949
950         printf("testing set_metadata_respond_application(of app block #1)... ");
951         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
952                 printf("FAILED, returned false\n");
953                 return false;
954         }
955         printf("OK\n");
956
957         printf("testing set_metadata_respond_application(of app block #2)... ");
958         if(!decoder->set_metadata_respond_application(application2_.data.application.id)) {
959                 printf("FAILED, returned false\n");
960                 return false;
961         }
962         printf("OK\n");
963
964         num_expected_ = 0;
965         expected_metadata_sequence_[num_expected_++] = &application1_;
966         expected_metadata_sequence_[num_expected_++] = &application2_;
967
968         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
969                 return false;
970
971         /*
972          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
973          */
974
975         printf("testing set_metadata_respond_all()... ");
976         if(!decoder->set_metadata_respond_all()) {
977                 printf("FAILED, returned false\n");
978                 return false;
979         }
980         printf("OK\n");
981
982         printf("testing set_metadata_ignore(APPLICATION)... ");
983         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
984                 printf("FAILED, returned false\n");
985                 return false;
986         }
987         printf("OK\n");
988
989         printf("testing set_metadata_respond_application(of app block #1)... ");
990         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
991                 printf("FAILED, returned false\n");
992                 return false;
993         }
994         printf("OK\n");
995
996         num_expected_ = 0;
997         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
998         expected_metadata_sequence_[num_expected_++] = &padding_;
999         expected_metadata_sequence_[num_expected_++] = &seektable_;
1000         expected_metadata_sequence_[num_expected_++] = &application1_;
1001         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1002         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1003         expected_metadata_sequence_[num_expected_++] = &picture_;
1004         expected_metadata_sequence_[num_expected_++] = &unknown_;
1005
1006         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
1007                 return false;
1008
1009         /*
1010          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
1011          */
1012
1013         printf("testing set_metadata_ignore_all()... ");
1014         if(!decoder->set_metadata_ignore_all()) {
1015                 printf("FAILED, returned false\n");
1016                 return false;
1017         }
1018         printf("OK\n");
1019
1020         printf("testing set_metadata_respond(APPLICATION)... ");
1021         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
1022                 printf("FAILED, returned false\n");
1023                 return false;
1024         }
1025         printf("OK\n");
1026
1027         printf("testing set_metadata_ignore_application(of app block #1)... ");
1028         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
1029                 printf("FAILED, returned false\n");
1030                 return false;
1031         }
1032         printf("OK\n");
1033
1034         num_expected_ = 0;
1035         expected_metadata_sequence_[num_expected_++] = &application2_;
1036
1037         if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond() : dynamic_cast<FileDecoder*>(decoder)->test_respond()))
1038                 return false;
1039
1040         if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
1041                 ::fclose(dynamic_cast<StreamDecoder*>(decoder)->file_);
1042
1043         printf("freeing decoder instance... ");
1044         delete decoder;
1045         printf("OK\n");
1046
1047         printf("\nPASSED!\n");
1048
1049         return true;
1050 }
1051
1052 bool test_decoders()
1053 {
1054         init_metadata_blocks_();
1055
1056         if(!generate_file_())
1057                 return false;
1058
1059         if(!test_stream_decoder(LAYER_STREAM))
1060                 return false;
1061
1062         if(!test_stream_decoder(LAYER_SEEKABLE_STREAM))
1063                 return false;
1064
1065         if(!test_stream_decoder(LAYER_FILE))
1066                 return false;
1067
1068         if(!test_stream_decoder(LAYER_FILENAME))
1069                 return false;
1070
1071         (void) grabbag__file_remove_file(flacfilename_);
1072
1073         free_metadata_blocks_();
1074
1075         return true;
1076 }