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