augment unit tests to test for correctness with unknown metadata blocks
[flac.git] / src / test_libFLAC++ / decoders.cpp
1 /* test_libFLAC++ - Unit tester for libFLAC++
2  * Copyright (C) 2002,2003  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 #include "decoders.h"
20 extern "C" {
21 #include "file_utils.h"
22 #include "metadata_utils.h"
23 }
24 #include "FLAC/assert.h"
25 #include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal()
26 #include "FLAC++/decoder.h"
27 #include "share/grabbag.h"
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, unknown_;
34 static ::FLAC__StreamMetadata *expected_metadata_sequence_[8];
35 static unsigned num_expected_;
36 static const char *flacfilename_ = "metadata.flac";
37 static unsigned flacfilesize_;
38
39 static bool die_(const char *msg)
40 {
41         printf("ERROR: %s\n", msg);
42         return false;
43 }
44
45 static void init_metadata_blocks_()
46 {
47         mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
48 }
49
50 static void free_metadata_blocks_()
51 {
52         mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
53 }
54
55 static bool generate_file_()
56 {
57         printf("\n\ngenerating FLAC file for decoder tests...\n");
58
59         num_expected_ = 0;
60         expected_metadata_sequence_[num_expected_++] = &padding_;
61         expected_metadata_sequence_[num_expected_++] = &seektable_;
62         expected_metadata_sequence_[num_expected_++] = &application1_;
63         expected_metadata_sequence_[num_expected_++] = &application2_;
64         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
65         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
66         expected_metadata_sequence_[num_expected_++] = &unknown_;
67
68         if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
69                 return die_("creating the encoded file");
70
71         return true;
72 }
73
74
75 class DecoderCommon {
76 public:
77         FILE *file_;
78         unsigned current_metadata_number_;
79         bool ignore_errors_;
80         bool error_occurred_;
81
82         DecoderCommon(): file_(0), current_metadata_number_(0), ignore_errors_(false), error_occurred_(false) { }
83         ::FLAC__StreamDecoderReadStatus common_read_callback_(FLAC__byte buffer[], unsigned *bytes);
84         ::FLAC__StreamDecoderWriteStatus common_write_callback_(const ::FLAC__Frame *frame);
85         void common_metadata_callback_(const ::FLAC__StreamMetadata *metadata);
86         void common_error_callback_(::FLAC__StreamDecoderErrorStatus status);
87 };
88
89 ::FLAC__StreamDecoderReadStatus DecoderCommon::common_read_callback_(FLAC__byte buffer[], unsigned *bytes)
90 {
91         if(error_occurred_)
92                 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT;
93
94         if(feof(file_))
95                 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
96         else if(*bytes > 0) {
97                 unsigned bytes_read = ::fread(buffer, 1, *bytes, file_);
98                 if(bytes_read == 0) {
99                         if(feof(file_))
100                                 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
101                         else
102                                 return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
103                 }
104                 else {
105                         *bytes = bytes_read;
106                         return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
107                 }
108         }
109         else
110                 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
111 }
112
113 ::FLAC__StreamDecoderWriteStatus DecoderCommon::common_write_callback_(const ::FLAC__Frame *frame)
114 {
115         if(error_occurred_)
116                 return ::FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
117
118         if(
119                 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
120                 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
121         ) {
122                 printf("content... ");
123                 fflush(stdout);
124         }
125
126         return ::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
127 }
128
129 void DecoderCommon::common_metadata_callback_(const ::FLAC__StreamMetadata *metadata)
130 {
131         if(error_occurred_)
132                 return;
133
134         printf("%d... ", current_metadata_number_);
135         fflush(stdout);
136
137         if(current_metadata_number_ >= num_expected_) {
138                 (void)die_("got more metadata blocks than expected");
139                 error_occurred_ = true;
140         }
141         else {
142                 if(!::FLAC__metadata_object_is_equal(expected_metadata_sequence_[current_metadata_number_], metadata)) {
143                         (void)die_("metadata block mismatch");
144                         error_occurred_ = true;
145                 }
146         }
147         current_metadata_number_++;
148 }
149
150 void DecoderCommon::common_error_callback_(::FLAC__StreamDecoderErrorStatus status)
151 {
152         if(!ignore_errors_) {
153                 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, ::FLAC__StreamDecoderErrorStatusString[status]);
154                 error_occurred_ = true;
155         }
156 }
157
158 class StreamDecoder : public FLAC::Decoder::Stream, public DecoderCommon {
159 public:
160         StreamDecoder(): FLAC::Decoder::Stream(), DecoderCommon() { }
161         ~StreamDecoder() { }
162
163         // from FLAC::Decoder::Stream
164         ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
165         ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
166         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
167         void error_callback(::FLAC__StreamDecoderErrorStatus status);
168
169         bool die(const char *msg = 0) const;
170
171         bool test_respond();
172 };
173
174 ::FLAC__StreamDecoderReadStatus StreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
175 {
176         return common_read_callback_(buffer, bytes);
177 }
178
179 ::FLAC__StreamDecoderWriteStatus StreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
180 {
181         (void)buffer;
182
183         return common_write_callback_(frame);
184 }
185
186 void StreamDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
187 {
188         common_metadata_callback_(metadata);
189 }
190
191 void StreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
192 {
193         common_error_callback_(status);
194 }
195
196 bool StreamDecoder::die(const char *msg) const
197 {
198         State state = get_state();
199
200         if(msg)
201                 printf("FAILED, %s", msg);
202         else
203                 printf("FAILED");
204
205         printf(", state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
206
207         return false;
208 }
209
210 bool StreamDecoder::test_respond()
211 {
212         printf("testing init()... ");
213         if(init() != ::FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
214                 return die();
215         printf("OK\n");
216
217         current_metadata_number_ = 0;
218
219         if(::fseek(file_, 0, SEEK_SET) < 0) {
220                 printf("FAILED rewinding input, errno = %d\n", errno);
221                 return false;
222         }
223
224         printf("testing process_until_end_of_stream()... ");
225         if(!process_until_end_of_stream()) {
226                 State state = get_state();
227                 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
228                 return false;
229         }
230         printf("OK\n");
231
232         printf("testing finish()... ");
233         finish();
234         printf("OK\n");
235
236         return true;
237 }
238
239 static bool test_stream_decoder()
240 {
241         StreamDecoder *decoder;
242
243         printf("\n+++ libFLAC++ unit test: FLAC::Decoder::Stream\n\n");
244
245         //
246         // test new -> delete
247         //
248         printf("allocating decoder instance... ");
249         decoder = new StreamDecoder();
250         if(0 == decoder) {
251                 printf("FAILED, new returned NULL\n");
252                 return false;
253         }
254         printf("OK\n");
255
256         printf("testing is_valid()... ");
257         if(!decoder->is_valid()) {
258                 printf("FAILED, returned false\n");
259                 return false;
260         }
261         printf("OK\n");
262
263         printf("freeing decoder instance... ");
264         delete decoder;
265         printf("OK\n");
266
267         //
268         // test new -> init -> delete
269         //
270         printf("allocating decoder instance... ");
271         decoder = new StreamDecoder();
272         if(0 == decoder) {
273                 printf("FAILED, new returned NULL\n");
274                 return false;
275         }
276         printf("OK\n");
277
278         printf("testing is_valid()... ");
279         if(!decoder->is_valid()) {
280                 printf("FAILED, returned false\n");
281                 return false;
282         }
283         printf("OK\n");
284
285         printf("testing init()... ");
286         if(decoder->init() != ::FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
287                 return decoder->die();
288         printf("OK\n");
289
290         printf("freeing decoder instance... ");
291         delete decoder;
292         printf("OK\n");
293
294         //
295         // test normal usage
296         //
297         num_expected_ = 0;
298         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
299
300         printf("allocating decoder instance... ");
301         decoder = new StreamDecoder();
302         if(0 == decoder) {
303                 printf("FAILED, new returned NULL\n");
304                 return false;
305         }
306         printf("OK\n");
307
308         printf("testing is_valid()... ");
309         if(!decoder->is_valid()) {
310                 printf("FAILED, returned false\n");
311                 return false;
312         }
313         printf("OK\n");
314
315         printf("testing init()... ");
316         if(decoder->init() != ::FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
317                 return decoder->die();
318         printf("OK\n");
319
320         printf("testing get_state()... ");
321         FLAC::Decoder::Stream::State state = decoder->get_state();
322         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
323
324         decoder->current_metadata_number_ = 0;
325         decoder->ignore_errors_ = false;
326         decoder->error_occurred_ = false;
327
328         printf("opening FLAC file... ");
329         decoder->file_ = ::fopen(flacfilename_, "rb");
330         if(0 == decoder->file_) {
331                 printf("ERROR\n");
332                 return false;
333         }
334         printf("OK\n");
335
336         printf("testing process_until_end_of_metadata()... ");
337         if(!decoder->process_until_end_of_metadata())
338                 return decoder->die("returned false");
339         printf("OK\n");
340
341         printf("testing process_single()... ");
342         if(!decoder->process_single())
343                 return decoder->die("returned false");
344         printf("OK\n");
345
346         printf("testing flush()... ");
347         if(!decoder->flush())
348                 return decoder->die("returned false");
349         printf("OK\n");
350
351         decoder->ignore_errors_ = true;
352         printf("testing process_single()... ");
353         if(!decoder->process_single())
354                 return decoder->die("returned false");
355         printf("OK\n");
356         decoder->ignore_errors_ = false;
357
358         printf("testing process_until_end_of_stream()... ");
359         if(!decoder->process_until_end_of_stream())
360                 return decoder->die("returned false");
361         printf("OK\n");
362
363         printf("testing get_channels()... ");
364         {
365                 unsigned channels = decoder->get_channels();
366                 if(channels != streaminfo_.data.stream_info.channels) {
367                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
368                         return false;
369                 }
370         }
371         printf("OK\n");
372
373         printf("testing get_bits_per_sample()... ");
374         {
375                 unsigned bits_per_sample = decoder->get_bits_per_sample();
376                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
377                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
378                         return false;
379                 }
380         }
381         printf("OK\n");
382
383         printf("testing get_sample_rate()... ");
384         {
385                 unsigned sample_rate = decoder->get_sample_rate();
386                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
387                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
388                         return false;
389                 }
390         }
391         printf("OK\n");
392
393         printf("testing get_blocksize()... ");
394         {
395                 unsigned blocksize = decoder->get_blocksize();
396                 /* value could be anything since we're at the last block, so accept any answer */
397                 printf("returned %u... OK\n", blocksize);
398         }
399
400         printf("testing get_channel_assignment()... ");
401         {
402                 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment();
403                 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]);
404         }
405
406         printf("testing reset()... ");
407         if(!decoder->reset())
408                 return decoder->die("returned false");
409         printf("OK\n");
410
411         decoder->current_metadata_number_ = 0;
412
413         printf("rewinding input... ");
414         if(::fseek(decoder->file_, 0, SEEK_SET) < 0) {
415                 printf("FAILED, errno = %d\n", errno);
416                 return false;
417         }
418         printf("OK\n");
419
420         printf("testing process_until_end_of_stream()... ");
421         if(!decoder->process_until_end_of_stream())
422                 return decoder->die("returned false");
423         printf("OK\n");
424
425         printf("testing finish()... ");
426         decoder->finish();
427         printf("OK\n");
428
429         /*
430          * respond all
431          */
432
433         printf("testing set_metadata_respond_all()... ");
434         if(!decoder->set_metadata_respond_all()) {
435                 printf("FAILED, returned false\n");
436                 return false;
437         }
438         printf("OK\n");
439
440         num_expected_ = 0;
441         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
442         expected_metadata_sequence_[num_expected_++] = &padding_;
443         expected_metadata_sequence_[num_expected_++] = &seektable_;
444         expected_metadata_sequence_[num_expected_++] = &application1_;
445         expected_metadata_sequence_[num_expected_++] = &application2_;
446         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
447         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
448         expected_metadata_sequence_[num_expected_++] = &unknown_;
449
450         if(!decoder->test_respond())
451                 return false;
452
453         /*
454          * ignore all
455          */
456
457         printf("testing set_metadata_ignore_all()... ");
458         if(!decoder->set_metadata_ignore_all()) {
459                 printf("FAILED, returned false\n");
460                 return false;
461         }
462         printf("OK\n");
463
464         num_expected_ = 0;
465
466         if(!decoder->test_respond())
467                 return false;
468
469         /*
470          * respond all, ignore VORBIS_COMMENT
471          */
472
473         printf("testing set_metadata_respond_all()... ");
474         if(!decoder->set_metadata_respond_all()) {
475                 printf("FAILED, returned false\n");
476                 return false;
477         }
478         printf("OK\n");
479
480         printf("testing set_metadata_ignore(VORBIS_COMMENT)... ");
481         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
482                 printf("FAILED, returned false\n");
483                 return false;
484         }
485         printf("OK\n");
486
487         num_expected_ = 0;
488         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
489         expected_metadata_sequence_[num_expected_++] = &padding_;
490         expected_metadata_sequence_[num_expected_++] = &seektable_;
491         expected_metadata_sequence_[num_expected_++] = &application1_;
492         expected_metadata_sequence_[num_expected_++] = &application2_;
493         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
494         expected_metadata_sequence_[num_expected_++] = &unknown_;
495
496         if(!decoder->test_respond())
497                 return false;
498
499         /*
500          * respond all, ignore APPLICATION
501          */
502
503         printf("testing set_metadata_respond_all()... ");
504         if(!decoder->set_metadata_respond_all()) {
505                 printf("FAILED, returned false\n");
506                 return false;
507         }
508         printf("OK\n");
509
510         printf("testing set_metadata_ignore(APPLICATION)... ");
511         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
512                 printf("FAILED, returned false\n");
513                 return false;
514         }
515         printf("OK\n");
516
517         num_expected_ = 0;
518         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
519         expected_metadata_sequence_[num_expected_++] = &padding_;
520         expected_metadata_sequence_[num_expected_++] = &seektable_;
521         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
522         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
523         expected_metadata_sequence_[num_expected_++] = &unknown_;
524
525         if(!decoder->test_respond())
526                 return false;
527
528         /*
529          * respond all, ignore APPLICATION id of app#1
530          */
531
532         printf("testing set_metadata_respond_all()... ");
533         if(!decoder->set_metadata_respond_all()) {
534                 printf("FAILED, returned false\n");
535                 return false;
536         }
537         printf("OK\n");
538
539         printf("testing set_metadata_ignore_application(of app block #1)... ");
540         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
541                 printf("FAILED, returned false\n");
542                 return false;
543         }
544         printf("OK\n");
545
546         num_expected_ = 0;
547         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
548         expected_metadata_sequence_[num_expected_++] = &padding_;
549         expected_metadata_sequence_[num_expected_++] = &seektable_;
550         expected_metadata_sequence_[num_expected_++] = &application2_;
551         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
552         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
553         expected_metadata_sequence_[num_expected_++] = &unknown_;
554
555         if(!decoder->test_respond())
556                 return false;
557
558         /*
559          * respond all, ignore APPLICATION id of app#1 & app#2
560          */
561
562         printf("testing set_metadata_respond_all()... ");
563         if(!decoder->set_metadata_respond_all()) {
564                 printf("FAILED, returned false\n");
565                 return false;
566         }
567         printf("OK\n");
568
569         printf("testing set_metadata_ignore_application(of app block #1)... ");
570         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
571                 printf("FAILED, returned false\n");
572                 return false;
573         }
574         printf("OK\n");
575
576         printf("testing set_metadata_ignore_application(of app block #2)... ");
577         if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) {
578                 printf("FAILED, returned false\n");
579                 return false;
580         }
581         printf("OK\n");
582
583         num_expected_ = 0;
584         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
585         expected_metadata_sequence_[num_expected_++] = &padding_;
586         expected_metadata_sequence_[num_expected_++] = &seektable_;
587         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
588         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
589         expected_metadata_sequence_[num_expected_++] = &unknown_;
590
591         if(!decoder->test_respond())
592                 return false;
593
594         /*
595          * ignore all, respond VORBIS_COMMENT
596          */
597
598         printf("testing set_metadata_ignore_all()... ");
599         if(!decoder->set_metadata_ignore_all()) {
600                 printf("FAILED, returned false\n");
601                 return false;
602         }
603         printf("OK\n");
604
605         printf("testing set_metadata_respond(VORBIS_COMMENT)... ");
606         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
607                 printf("FAILED, returned false\n");
608                 return false;
609         }
610         printf("OK\n");
611
612         num_expected_ = 0;
613         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
614
615         if(!decoder->test_respond())
616                 return false;
617
618         /*
619          * ignore all, respond APPLICATION
620          */
621
622         printf("testing set_metadata_ignore_all()... ");
623         if(!decoder->set_metadata_ignore_all()) {
624                 printf("FAILED, returned false\n");
625                 return false;
626         }
627         printf("OK\n");
628
629         printf("testing set_metadata_respond(APPLICATION)... ");
630         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
631                 printf("FAILED, returned false\n");
632                 return false;
633         }
634         printf("OK\n");
635
636         num_expected_ = 0;
637         expected_metadata_sequence_[num_expected_++] = &application1_;
638         expected_metadata_sequence_[num_expected_++] = &application2_;
639
640         if(!decoder->test_respond())
641                 return false;
642
643         /*
644          * ignore all, respond APPLICATION id of app#1
645          */
646
647         printf("testing set_metadata_ignore_all()... ");
648         if(!decoder->set_metadata_ignore_all()) {
649                 printf("FAILED, returned false\n");
650                 return false;
651         }
652         printf("OK\n");
653
654         printf("testing set_metadata_respond_application(of app block #1)... ");
655         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
656                 printf("FAILED, returned false\n");
657                 return false;
658         }
659         printf("OK\n");
660
661         num_expected_ = 0;
662         expected_metadata_sequence_[num_expected_++] = &application1_;
663
664         if(!decoder->test_respond())
665                 return false;
666
667         /*
668          * ignore all, respond APPLICATION id of app#1 & app#2
669          */
670
671         printf("testing set_metadata_ignore_all()... ");
672         if(!decoder->set_metadata_ignore_all()) {
673                 printf("FAILED, returned false\n");
674                 return false;
675         }
676         printf("OK\n");
677
678         printf("testing set_metadata_respond_application(of app block #1)... ");
679         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
680                 printf("FAILED, returned false\n");
681                 return false;
682         }
683         printf("OK\n");
684
685         printf("testing set_metadata_respond_application(of app block #2)... ");
686         if(!decoder->set_metadata_respond_application(application2_.data.application.id)) {
687                 printf("FAILED, returned false\n");
688                 return false;
689         }
690         printf("OK\n");
691
692         num_expected_ = 0;
693         expected_metadata_sequence_[num_expected_++] = &application1_;
694         expected_metadata_sequence_[num_expected_++] = &application2_;
695
696         if(!decoder->test_respond())
697                 return false;
698
699         /*
700          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
701          */
702
703         printf("testing set_metadata_respond_all()... ");
704         if(!decoder->set_metadata_respond_all()) {
705                 printf("FAILED, returned false\n");
706                 return false;
707         }
708         printf("OK\n");
709
710         printf("testing set_metadata_ignore(APPLICATION)... ");
711         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
712                 printf("FAILED, returned false\n");
713                 return false;
714         }
715         printf("OK\n");
716
717         printf("testing set_metadata_respond_application(of app block #1)... ");
718         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
719                 printf("FAILED, returned false\n");
720                 return false;
721         }
722         printf("OK\n");
723
724         num_expected_ = 0;
725         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
726         expected_metadata_sequence_[num_expected_++] = &padding_;
727         expected_metadata_sequence_[num_expected_++] = &seektable_;
728         expected_metadata_sequence_[num_expected_++] = &application1_;
729         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
730         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
731         expected_metadata_sequence_[num_expected_++] = &unknown_;
732
733         if(!decoder->test_respond())
734                 return false;
735
736         /*
737          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
738          */
739
740         printf("testing set_metadata_ignore_all()... ");
741         if(!decoder->set_metadata_ignore_all()) {
742                 printf("FAILED, returned false\n");
743                 return false;
744         }
745         printf("OK\n");
746
747         printf("testing set_metadata_respond(APPLICATION)... ");
748         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
749                 printf("FAILED, returned false\n");
750                 return false;
751         }
752         printf("OK\n");
753
754         printf("testing set_metadata_ignore_application(of app block #1)... ");
755         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
756                 printf("FAILED, returned false\n");
757                 return false;
758         }
759         printf("OK\n");
760
761         num_expected_ = 0;
762         expected_metadata_sequence_[num_expected_++] = &application2_;
763
764         if(!decoder->test_respond())
765                 return false;
766
767         /* done, now leave the sequence the way we found it... */
768         num_expected_ = 0;
769         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
770         expected_metadata_sequence_[num_expected_++] = &padding_;
771         expected_metadata_sequence_[num_expected_++] = &seektable_;
772         expected_metadata_sequence_[num_expected_++] = &application1_;
773         expected_metadata_sequence_[num_expected_++] = &application2_;
774         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
775         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
776         expected_metadata_sequence_[num_expected_++] = &unknown_;
777
778         ::fclose(decoder->file_);
779
780         printf("freeing decoder instance... ");
781         delete decoder;
782         printf("OK\n");
783
784         printf("\nPASSED!\n");
785
786         return true;
787 }
788
789 class SeekableStreamDecoder : public FLAC::Decoder::SeekableStream, public DecoderCommon {
790 public:
791         SeekableStreamDecoder(): FLAC::Decoder::SeekableStream(), DecoderCommon() { }
792         ~SeekableStreamDecoder() { }
793
794         // from FLAC::Decoder::SeekableStream
795         ::FLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
796         ::FLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset);
797         ::FLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset);
798         ::FLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length);
799         bool eof_callback();
800         ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
801         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
802         void error_callback(::FLAC__StreamDecoderErrorStatus status);
803
804         bool die(const char *msg = 0) const;
805
806         bool test_respond();
807 };
808
809 ::FLAC__SeekableStreamDecoderReadStatus SeekableStreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
810 {
811         switch(common_read_callback_(buffer, bytes)) {
812                 case ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
813                         return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
814                 case ::FLAC__STREAM_DECODER_READ_STATUS_ABORT:
815                 case ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
816                         return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
817                 default:
818                         FLAC__ASSERT(0);
819                         return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
820         }
821 }
822
823 ::FLAC__SeekableStreamDecoderSeekStatus SeekableStreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset)
824 {
825         if(error_occurred_)
826                 return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
827
828         if(::fseek(file_, (long)absolute_byte_offset, SEEK_SET) < 0) {
829                 error_occurred_ = true;
830                 return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
831         }
832
833         return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
834 }
835
836 ::FLAC__SeekableStreamDecoderTellStatus SeekableStreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset)
837 {
838         if(error_occurred_)
839                 return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
840
841         long offset = ::ftell(file_);
842         *absolute_byte_offset = (FLAC__uint64)offset;
843
844         if(offset < 0) {
845                 error_occurred_ = true;
846                 return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
847         }
848
849         return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
850 }
851
852 ::FLAC__SeekableStreamDecoderLengthStatus SeekableStreamDecoder::length_callback(FLAC__uint64 *stream_length)
853 {
854         if(error_occurred_)
855                 return ::FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
856
857         *stream_length = (FLAC__uint64)flacfilesize_;
858         return ::FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
859 }
860
861 bool SeekableStreamDecoder::eof_callback()
862 {
863         if(error_occurred_)
864                 return true;
865
866         return (bool)feof(file_);
867 }
868
869 ::FLAC__StreamDecoderWriteStatus SeekableStreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
870 {
871         (void)buffer;
872
873         return common_write_callback_(frame);
874 }
875
876 void SeekableStreamDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
877 {
878         common_metadata_callback_(metadata);
879 }
880
881 void SeekableStreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
882 {
883         common_error_callback_(status);
884 }
885
886 bool SeekableStreamDecoder::die(const char *msg) const
887 {
888         State state = get_state();
889
890         if(msg)
891                 printf("FAILED, %s", msg);
892         else
893                 printf("FAILED");
894
895         printf(", state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state), state.as_cstring());
896         if(state == ::FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
897                 FLAC::Decoder::Stream::State state_ = get_stream_decoder_state();
898                 printf("      stream decoder state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state_), state_.as_cstring());
899         }
900
901         return false;
902 }
903
904 bool SeekableStreamDecoder::test_respond()
905 {
906         if(!set_md5_checking(true)) {
907                 printf("FAILED at set_md5_checking(), returned false\n");
908                 return false;
909         }
910
911         printf("testing init()... ");
912         if(init() != ::FLAC__SEEKABLE_STREAM_DECODER_OK)
913                 return die();
914         printf("OK\n");
915
916         current_metadata_number_ = 0;
917
918         if(::fseek(file_, 0, SEEK_SET) < 0) {
919                 printf("FAILED rewinding input, errno = %d\n", errno);
920                 return false;
921         }
922
923         printf("testing process_until_end_of_stream()... ");
924         if(!process_until_end_of_stream()) {
925                 State state = get_state();
926                 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state), state.as_cstring());
927                 return false;
928         }
929         printf("OK\n");
930
931         printf("testing finish()... ");
932         finish();
933         printf("OK\n");
934
935         return true;
936 }
937
938 static bool test_seekable_stream_decoder()
939 {
940         SeekableStreamDecoder *decoder;
941
942         printf("\n+++ libFLAC++ unit test: FLAC::Decoder::SeekableStream\n\n");
943
944         //
945         // test new -> delete
946         //
947         printf("allocating decoder instance... ");
948         decoder = new SeekableStreamDecoder();
949         if(0 == decoder) {
950                 printf("FAILED, new returned NULL\n");
951                 return false;
952         }
953         printf("OK\n");
954
955         printf("testing is_valid()... ");
956         if(!decoder->is_valid()) {
957                 printf("FAILED, returned false\n");
958                 return false;
959         }
960         printf("OK\n");
961
962         printf("freeing decoder instance... ");
963         delete decoder;
964         printf("OK\n");
965
966         //
967         // test new -> init -> delete
968         //
969         printf("allocating decoder instance... ");
970         decoder = new SeekableStreamDecoder();
971         if(0 == decoder) {
972                 printf("FAILED, new returned NULL\n");
973                 return false;
974         }
975         printf("OK\n");
976
977         printf("testing is_valid()... ");
978         if(!decoder->is_valid()) {
979                 printf("FAILED, returned false\n");
980                 return false;
981         }
982         printf("OK\n");
983
984         printf("testing init()... ");
985         if(decoder->init() != ::FLAC__SEEKABLE_STREAM_DECODER_OK)
986                 return decoder->die();
987         printf("OK\n");
988
989         printf("freeing decoder instance... ");
990         delete decoder;
991         printf("OK\n");
992
993         //
994         // test normal usage
995         //
996         num_expected_ = 0;
997         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
998
999         printf("allocating decoder instance... ");
1000         decoder = new SeekableStreamDecoder();
1001         if(0 == decoder) {
1002                 printf("FAILED, new returned NULL\n");
1003                 return false;
1004         }
1005         printf("OK\n");
1006
1007         printf("testing is_valid()... ");
1008         if(!decoder->is_valid()) {
1009                 printf("FAILED, returned false\n");
1010                 return false;
1011         }
1012         printf("OK\n");
1013
1014         printf("testing set_md5_checking()... ");
1015         if(!decoder->set_md5_checking(true)) {
1016                 printf("FAILED, returned false\n");
1017                 return false;
1018         }
1019         printf("OK\n");
1020
1021         printf("testing init()... ");
1022         if(decoder->init() != ::FLAC__SEEKABLE_STREAM_DECODER_OK)
1023                 return decoder->die();
1024         printf("OK\n");
1025
1026         printf("testing get_state()... ");
1027         FLAC::Decoder::SeekableStream::State state = decoder->get_state();
1028         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state), state.as_cstring());
1029
1030         printf("testing get_stream_decoder_state()... ");
1031         FLAC::Decoder::Stream::State state_ = decoder->get_stream_decoder_state();
1032         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state_), state_.as_cstring());
1033
1034         decoder->current_metadata_number_ = 0;
1035         decoder->ignore_errors_ = false;
1036         decoder->error_occurred_ = false;
1037
1038         printf("opening FLAC file... ");
1039         decoder->file_ = ::fopen(flacfilename_, "rb");
1040         if(0 == decoder->file_) {
1041                 printf("ERROR\n");
1042                 return false;
1043         }
1044         printf("OK\n");
1045
1046         printf("testing get_md5_checking()... ");
1047         if(!decoder->get_md5_checking()) {
1048                 printf("FAILED, returned false, expected true\n");
1049                 return false;
1050         }
1051         printf("OK\n");
1052
1053         printf("testing process_until_end_of_metadata()... ");
1054         if(!decoder->process_until_end_of_metadata())
1055                 return decoder->die("returned false");
1056         printf("OK\n");
1057
1058         printf("testing process_single()... ");
1059         if(!decoder->process_single())
1060                 return decoder->die("returned false");
1061         printf("OK\n");
1062
1063         printf("testing flush()... ");
1064         if(!decoder->flush())
1065                 return decoder->die("returned false");
1066         printf("OK\n");
1067
1068         decoder->ignore_errors_ = true;
1069         printf("testing process_single()... ");
1070         if(!decoder->process_single())
1071                 return decoder->die("returned false");
1072         printf("OK\n");
1073         decoder->ignore_errors_ = false;
1074
1075         printf("testing seek_absolute()... ");
1076         if(!decoder->seek_absolute(0))
1077                 return decoder->die("returned false");
1078         printf("OK\n");
1079
1080         printf("testing process_until_end_of_stream()... ");
1081         if(!decoder->process_until_end_of_stream())
1082                 return decoder->die("returned false");
1083         printf("OK\n");
1084
1085         printf("testing get_channels()... ");
1086         {
1087                 unsigned channels = decoder->get_channels();
1088                 if(channels != streaminfo_.data.stream_info.channels) {
1089                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
1090                         return false;
1091                 }
1092         }
1093         printf("OK\n");
1094
1095         printf("testing get_bits_per_sample()... ");
1096         {
1097                 unsigned bits_per_sample = decoder->get_bits_per_sample();
1098                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
1099                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
1100                         return false;
1101                 }
1102         }
1103         printf("OK\n");
1104
1105         printf("testing get_sample_rate()... ");
1106         {
1107                 unsigned sample_rate = decoder->get_sample_rate();
1108                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
1109                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
1110                         return false;
1111                 }
1112         }
1113         printf("OK\n");
1114
1115         printf("testing get_blocksize()... ");
1116         {
1117                 unsigned blocksize = decoder->get_blocksize();
1118                 /* value could be anything since we're at the last block, so accept any answer */
1119                 printf("returned %u... OK\n", blocksize);
1120         }
1121
1122         printf("testing get_channel_assignment()... ");
1123         {
1124                 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment();
1125                 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]);
1126         }
1127
1128         printf("testing reset()... ");
1129         if(!decoder->reset())
1130                 return decoder->die("returned false");
1131         printf("OK\n");
1132
1133         decoder->current_metadata_number_ = 0;
1134
1135         printf("rewinding input... ");
1136         if(::fseek(decoder->file_, 0, SEEK_SET) < 0) {
1137                 printf("FAILED, errno = %d\n", errno);
1138                 return false;
1139         }
1140         printf("OK\n");
1141
1142         printf("testing process_until_end_of_stream()... ");
1143         if(!decoder->process_until_end_of_stream())
1144                 return decoder->die("returned false");
1145         printf("OK\n");
1146
1147         printf("testing finish()... ");
1148         decoder->finish();
1149         printf("OK\n");
1150
1151         /*
1152          * respond all
1153          */
1154
1155         printf("testing set_metadata_respond_all()... ");
1156         if(!decoder->set_metadata_respond_all()) {
1157                 printf("FAILED, returned false\n");
1158                 return false;
1159         }
1160         printf("OK\n");
1161
1162         num_expected_ = 0;
1163         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1164         expected_metadata_sequence_[num_expected_++] = &padding_;
1165         expected_metadata_sequence_[num_expected_++] = &seektable_;
1166         expected_metadata_sequence_[num_expected_++] = &application1_;
1167         expected_metadata_sequence_[num_expected_++] = &application2_;
1168         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1169         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1170         expected_metadata_sequence_[num_expected_++] = &unknown_;
1171
1172         if(!decoder->test_respond())
1173                 return false;
1174
1175         /*
1176          * ignore all
1177          */
1178
1179         printf("testing set_metadata_ignore_all()... ");
1180         if(!decoder->set_metadata_ignore_all()) {
1181                 printf("FAILED, returned false\n");
1182                 return false;
1183         }
1184         printf("OK\n");
1185
1186         num_expected_ = 0;
1187
1188         if(!decoder->test_respond())
1189                 return false;
1190
1191         /*
1192          * respond all, ignore VORBIS_COMMENT
1193          */
1194
1195         printf("testing set_metadata_respond_all()... ");
1196         if(!decoder->set_metadata_respond_all()) {
1197                 printf("FAILED, returned false\n");
1198                 return false;
1199         }
1200         printf("OK\n");
1201
1202         printf("testing set_metadata_ignore(VORBIS_COMMENT)... ");
1203         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
1204                 printf("FAILED, returned false\n");
1205                 return false;
1206         }
1207         printf("OK\n");
1208
1209         num_expected_ = 0;
1210         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1211         expected_metadata_sequence_[num_expected_++] = &padding_;
1212         expected_metadata_sequence_[num_expected_++] = &seektable_;
1213         expected_metadata_sequence_[num_expected_++] = &application1_;
1214         expected_metadata_sequence_[num_expected_++] = &application2_;
1215         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1216         expected_metadata_sequence_[num_expected_++] = &unknown_;
1217
1218         if(!decoder->test_respond())
1219                 return false;
1220
1221         /*
1222          * respond all, ignore APPLICATION
1223          */
1224
1225         printf("testing set_metadata_respond_all()... ");
1226         if(!decoder->set_metadata_respond_all()) {
1227                 printf("FAILED, returned false\n");
1228                 return false;
1229         }
1230         printf("OK\n");
1231
1232         printf("testing set_metadata_ignore(APPLICATION)... ");
1233         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
1234                 printf("FAILED, returned false\n");
1235                 return false;
1236         }
1237         printf("OK\n");
1238
1239         num_expected_ = 0;
1240         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1241         expected_metadata_sequence_[num_expected_++] = &padding_;
1242         expected_metadata_sequence_[num_expected_++] = &seektable_;
1243         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1244         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1245         expected_metadata_sequence_[num_expected_++] = &unknown_;
1246
1247         if(!decoder->test_respond())
1248                 return false;
1249
1250         /*
1251          * respond all, ignore APPLICATION id of app#1
1252          */
1253
1254         printf("testing set_metadata_respond_all()... ");
1255         if(!decoder->set_metadata_respond_all()) {
1256                 printf("FAILED, returned false\n");
1257                 return false;
1258         }
1259         printf("OK\n");
1260
1261         printf("testing set_metadata_ignore_application(of app block #1)... ");
1262         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
1263                 printf("FAILED, returned false\n");
1264                 return false;
1265         }
1266         printf("OK\n");
1267
1268         num_expected_ = 0;
1269         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1270         expected_metadata_sequence_[num_expected_++] = &padding_;
1271         expected_metadata_sequence_[num_expected_++] = &seektable_;
1272         expected_metadata_sequence_[num_expected_++] = &application2_;
1273         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1274         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1275         expected_metadata_sequence_[num_expected_++] = &unknown_;
1276
1277         if(!decoder->test_respond())
1278                 return false;
1279
1280         /*
1281          * respond all, ignore APPLICATION id of app#1 & app#2
1282          */
1283
1284         printf("testing set_metadata_respond_all()... ");
1285         if(!decoder->set_metadata_respond_all()) {
1286                 printf("FAILED, returned false\n");
1287                 return false;
1288         }
1289         printf("OK\n");
1290
1291         printf("testing set_metadata_ignore_application(of app block #1)... ");
1292         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
1293                 printf("FAILED, returned false\n");
1294                 return false;
1295         }
1296         printf("OK\n");
1297
1298         printf("testing set_metadata_ignore_application(of app block #2)... ");
1299         if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) {
1300                 printf("FAILED, returned false\n");
1301                 return false;
1302         }
1303         printf("OK\n");
1304
1305         num_expected_ = 0;
1306         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1307         expected_metadata_sequence_[num_expected_++] = &padding_;
1308         expected_metadata_sequence_[num_expected_++] = &seektable_;
1309         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1310         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1311         expected_metadata_sequence_[num_expected_++] = &unknown_;
1312
1313         if(!decoder->test_respond())
1314                 return false;
1315
1316         /*
1317          * ignore all, respond VORBIS_COMMENT
1318          */
1319
1320         printf("testing set_metadata_ignore_all()... ");
1321         if(!decoder->set_metadata_ignore_all()) {
1322                 printf("FAILED, returned false\n");
1323                 return false;
1324         }
1325         printf("OK\n");
1326
1327         printf("testing set_metadata_respond(VORBIS_COMMENT)... ");
1328         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
1329                 printf("FAILED, returned false\n");
1330                 return false;
1331         }
1332         printf("OK\n");
1333
1334         num_expected_ = 0;
1335         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1336
1337         if(!decoder->test_respond())
1338                 return false;
1339
1340         /*
1341          * ignore all, respond APPLICATION
1342          */
1343
1344         printf("testing set_metadata_ignore_all()... ");
1345         if(!decoder->set_metadata_ignore_all()) {
1346                 printf("FAILED, returned false\n");
1347                 return false;
1348         }
1349         printf("OK\n");
1350
1351         printf("testing set_metadata_respond(APPLICATION)... ");
1352         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
1353                 printf("FAILED, returned false\n");
1354                 return false;
1355         }
1356         printf("OK\n");
1357
1358         num_expected_ = 0;
1359         expected_metadata_sequence_[num_expected_++] = &application1_;
1360         expected_metadata_sequence_[num_expected_++] = &application2_;
1361
1362         if(!decoder->test_respond())
1363                 return false;
1364
1365         /*
1366          * ignore all, respond APPLICATION id of app#1
1367          */
1368
1369         printf("testing set_metadata_ignore_all()... ");
1370         if(!decoder->set_metadata_ignore_all()) {
1371                 printf("FAILED, returned false\n");
1372                 return false;
1373         }
1374         printf("OK\n");
1375
1376         printf("testing set_metadata_respond_application(of app block #1)... ");
1377         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
1378                 printf("FAILED, returned false\n");
1379                 return false;
1380         }
1381         printf("OK\n");
1382
1383         num_expected_ = 0;
1384         expected_metadata_sequence_[num_expected_++] = &application1_;
1385
1386         if(!decoder->test_respond())
1387                 return false;
1388
1389         /*
1390          * ignore all, respond APPLICATION id of app#1 & app#2
1391          */
1392
1393         printf("testing set_metadata_ignore_all()... ");
1394         if(!decoder->set_metadata_ignore_all()) {
1395                 printf("FAILED, returned false\n");
1396                 return false;
1397         }
1398         printf("OK\n");
1399
1400         printf("testing set_metadata_respond_application(of app block #1)... ");
1401         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
1402                 printf("FAILED, returned false\n");
1403                 return false;
1404         }
1405         printf("OK\n");
1406
1407         printf("testing set_metadata_respond_application(of app block #2)... ");
1408         if(!decoder->set_metadata_respond_application(application2_.data.application.id)) {
1409                 printf("FAILED, returned false\n");
1410                 return false;
1411         }
1412         printf("OK\n");
1413
1414         num_expected_ = 0;
1415         expected_metadata_sequence_[num_expected_++] = &application1_;
1416         expected_metadata_sequence_[num_expected_++] = &application2_;
1417
1418         if(!decoder->test_respond())
1419                 return false;
1420
1421         /*
1422          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
1423          */
1424
1425         printf("testing set_metadata_respond_all()... ");
1426         if(!decoder->set_metadata_respond_all()) {
1427                 printf("FAILED, returned false\n");
1428                 return false;
1429         }
1430         printf("OK\n");
1431
1432         printf("testing set_metadata_ignore(APPLICATION)... ");
1433         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
1434                 printf("FAILED, returned false\n");
1435                 return false;
1436         }
1437         printf("OK\n");
1438
1439         printf("testing set_metadata_respond_application(of app block #1)... ");
1440         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
1441                 printf("FAILED, returned false\n");
1442                 return false;
1443         }
1444         printf("OK\n");
1445
1446         num_expected_ = 0;
1447         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1448         expected_metadata_sequence_[num_expected_++] = &padding_;
1449         expected_metadata_sequence_[num_expected_++] = &seektable_;
1450         expected_metadata_sequence_[num_expected_++] = &application1_;
1451         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1452         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1453         expected_metadata_sequence_[num_expected_++] = &unknown_;
1454
1455         if(!decoder->test_respond())
1456                 return false;
1457
1458         /*
1459          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
1460          */
1461
1462         printf("testing set_metadata_ignore_all()... ");
1463         if(!decoder->set_metadata_ignore_all()) {
1464                 printf("FAILED, returned false\n");
1465                 return false;
1466         }
1467         printf("OK\n");
1468
1469         printf("testing set_metadata_respond(APPLICATION)... ");
1470         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
1471                 printf("FAILED, returned false\n");
1472                 return false;
1473         }
1474         printf("OK\n");
1475
1476         printf("testing set_metadata_ignore_application(of app block #1)... ");
1477         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
1478                 printf("FAILED, returned false\n");
1479                 return false;
1480         }
1481         printf("OK\n");
1482
1483         num_expected_ = 0;
1484         expected_metadata_sequence_[num_expected_++] = &application2_;
1485
1486         if(!decoder->test_respond())
1487                 return false;
1488
1489         /* done, now leave the sequence the way we found it... */
1490         num_expected_ = 0;
1491         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1492         expected_metadata_sequence_[num_expected_++] = &padding_;
1493         expected_metadata_sequence_[num_expected_++] = &seektable_;
1494         expected_metadata_sequence_[num_expected_++] = &application1_;
1495         expected_metadata_sequence_[num_expected_++] = &application2_;
1496         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1497         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1498         expected_metadata_sequence_[num_expected_++] = &unknown_;
1499
1500         ::fclose(decoder->file_);
1501
1502         printf("freeing decoder instance... ");
1503         delete decoder;
1504         printf("OK\n");
1505
1506         printf("\nPASSED!\n");
1507
1508         return true;
1509 }
1510
1511 class FileDecoder : public FLAC::Decoder::File, public DecoderCommon {
1512 public:
1513         FileDecoder(): FLAC::Decoder::File(), DecoderCommon() { }
1514         ~FileDecoder() { }
1515
1516         // from FLAC::Decoder::File
1517         ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
1518         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
1519         void error_callback(::FLAC__StreamDecoderErrorStatus status);
1520
1521         bool die(const char *msg = 0) const;
1522
1523         bool test_respond();
1524 };
1525
1526 ::FLAC__StreamDecoderWriteStatus FileDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
1527 {
1528         (void)buffer;
1529         return common_write_callback_(frame);
1530 }
1531
1532 void FileDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
1533 {
1534         common_metadata_callback_(metadata);
1535 }
1536
1537 void FileDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
1538 {
1539         common_error_callback_(status);
1540 }
1541
1542 bool FileDecoder::die(const char *msg) const
1543 {
1544         State state = get_state();
1545
1546         if(msg)
1547                 printf("FAILED, %s", msg);
1548         else
1549                 printf("FAILED");
1550
1551         printf(", state = %u (%s)\n", (unsigned)((::FLAC__FileDecoderState)state), state.as_cstring());
1552         if(state == ::FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
1553                 FLAC::Decoder::SeekableStream::State state_ = get_seekable_stream_decoder_state();
1554                 printf("      seekable stream decoder state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
1555                 if(state_ == ::FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
1556                         FLAC::Decoder::Stream::State state__ = get_stream_decoder_state();
1557                         printf("      stream decoder state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state__), state__.as_cstring());
1558                 }
1559         }
1560
1561         return false;
1562 }
1563
1564 bool FileDecoder::test_respond()
1565 {
1566         if(!set_filename(flacfilename_)) {
1567                 printf("FAILED at set_filename(), returned false\n");
1568                 return false;
1569         }
1570
1571         if(!set_md5_checking(true)) {
1572                 printf("FAILED at set_md5_checking(), returned false\n");
1573                 return false;
1574         }
1575
1576         printf("testing init()... ");
1577         if(init() != ::FLAC__FILE_DECODER_OK)
1578                 return die();
1579         printf("OK\n");
1580
1581         current_metadata_number_ = 0;
1582
1583         printf("testing process_until_end_of_file()... ");
1584         if(!process_until_end_of_file()) {
1585                 State state = get_state();
1586                 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__FileDecoderState)state), state.as_cstring());
1587                 return false;
1588         }
1589         printf("OK\n");
1590
1591         printf("testing finish()... ");
1592         finish();
1593         printf("OK\n");
1594
1595         return true;
1596 }
1597
1598 static bool test_file_decoder()
1599 {
1600         FileDecoder *decoder;
1601
1602         printf("\n+++ libFLAC++ unit test: FLAC::Decoder::File\n\n");
1603
1604         //
1605         // test new -> delete
1606         //
1607         printf("allocating decoder instance... ");
1608         decoder = new FileDecoder();
1609         if(0 == decoder) {
1610                 printf("FAILED, new returned NULL\n");
1611                 return false;
1612         }
1613         printf("OK\n");
1614
1615         printf("testing is_valid()... ");
1616         if(!decoder->is_valid()) {
1617                 printf("FAILED, returned false\n");
1618                 return false;
1619         }
1620         printf("OK\n");
1621
1622         printf("freeing decoder instance... ");
1623         delete decoder;
1624         printf("OK\n");
1625
1626         //
1627         // test new -> init -> delete
1628         //
1629         printf("allocating decoder instance... ");
1630         decoder = new FileDecoder();
1631         if(0 == decoder) {
1632                 printf("FAILED, new returned NULL\n");
1633                 return false;
1634         }
1635         printf("OK\n");
1636
1637         printf("testing is_valid()... ");
1638         if(!decoder->is_valid()) {
1639                 printf("FAILED, returned false\n");
1640                 return false;
1641         }
1642         printf("OK\n");
1643
1644         printf("testing init()... ");
1645         if(decoder->init() != ::FLAC__SEEKABLE_STREAM_DECODER_OK)
1646                 return decoder->die();
1647         printf("OK\n");
1648
1649         printf("freeing decoder instance... ");
1650         delete decoder;
1651         printf("OK\n");
1652
1653         //
1654         // test normal usage
1655         //
1656         num_expected_ = 0;
1657         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1658
1659         printf("allocating decoder instance... ");
1660         decoder = new FileDecoder();
1661         if(0 == decoder) {
1662                 printf("FAILED, new returned NULL\n");
1663                 return false;
1664         }
1665         printf("OK\n");
1666
1667         printf("testing is_valid()... ");
1668         if(!decoder->is_valid()) {
1669                 printf("FAILED, returned false\n");
1670                 return false;
1671         }
1672         printf("OK\n");
1673
1674         printf("testing set_filename()... ");
1675         if(!decoder->set_filename(flacfilename_)) {
1676                 printf("FAILED, returned false\n");
1677                 return false;
1678         }
1679         printf("OK\n");
1680
1681         printf("testing set_md5_checking()... ");
1682         if(!decoder->set_md5_checking(true)) {
1683                 printf("FAILED, returned false\n");
1684                 return false;
1685         }
1686         printf("OK\n");
1687
1688         printf("testing init()... ");
1689         if(decoder->init() != ::FLAC__FILE_DECODER_OK)
1690                 return decoder->die();
1691         printf("OK\n");
1692
1693         printf("testing get_state()... ");
1694         FLAC::Decoder::File::State state = decoder->get_state();
1695         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__FileDecoderState)state), state.as_cstring());
1696
1697         printf("testing get_seekable_stream_decoder_state()... ");
1698         FLAC::Decoder::SeekableStream::State state_ = decoder->get_seekable_stream_decoder_state();
1699         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
1700
1701         printf("testing get_stream_decoder_state()... ");
1702         FLAC::Decoder::Stream::State state__ = decoder->get_stream_decoder_state();
1703         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state__), state__.as_cstring());
1704
1705         decoder->current_metadata_number_ = 0;
1706         decoder->ignore_errors_ = false;
1707         decoder->error_occurred_ = false;
1708
1709         printf("testing get_md5_checking()... ");
1710         if(!decoder->get_md5_checking()) {
1711                 printf("FAILED, returned false, expected true\n");
1712                 return false;
1713         }
1714         printf("OK\n");
1715
1716         printf("testing process_until_end_of_metadata()... ");
1717         if(!decoder->process_until_end_of_metadata())
1718                 return decoder->die("returned false");
1719         printf("OK\n");
1720
1721         printf("testing process_single()... ");
1722         if(!decoder->process_single())
1723                 return decoder->die("returned false");
1724         printf("OK\n");
1725
1726         printf("testing seek_absolute()... ");
1727         if(!decoder->seek_absolute(0))
1728                 return decoder->die("returned false");
1729         printf("OK\n");
1730
1731         printf("testing process_until_end_of_file()... ");
1732         if(!decoder->process_until_end_of_file())
1733                 return decoder->die("returned false");
1734         printf("OK\n");
1735
1736         printf("testing get_channels()... ");
1737         {
1738                 unsigned channels = decoder->get_channels();
1739                 if(channels != streaminfo_.data.stream_info.channels) {
1740                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
1741                         return false;
1742                 }
1743         }
1744         printf("OK\n");
1745
1746         printf("testing get_bits_per_sample()... ");
1747         {
1748                 unsigned bits_per_sample = decoder->get_bits_per_sample();
1749                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
1750                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
1751                         return false;
1752                 }
1753         }
1754         printf("OK\n");
1755
1756         printf("testing get_sample_rate()... ");
1757         {
1758                 unsigned sample_rate = decoder->get_sample_rate();
1759                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
1760                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
1761                         return false;
1762                 }
1763         }
1764         printf("OK\n");
1765
1766         printf("testing get_blocksize()... ");
1767         {
1768                 unsigned blocksize = decoder->get_blocksize();
1769                 /* value could be anything since we're at the last block, so accept any answer */
1770                 printf("returned %u... OK\n", blocksize);
1771         }
1772
1773         printf("testing get_channel_assignment()... ");
1774         {
1775                 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment();
1776                 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]);
1777         }
1778
1779         printf("testing finish()... ");
1780         decoder->finish();
1781         printf("OK\n");
1782
1783         /*
1784          * respond all
1785          */
1786
1787         printf("testing set_metadata_respond_all()... ");
1788         if(!decoder->set_metadata_respond_all()) {
1789                 printf("FAILED, returned false\n");
1790                 return false;
1791         }
1792         printf("OK\n");
1793
1794         num_expected_ = 0;
1795         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1796         expected_metadata_sequence_[num_expected_++] = &padding_;
1797         expected_metadata_sequence_[num_expected_++] = &seektable_;
1798         expected_metadata_sequence_[num_expected_++] = &application1_;
1799         expected_metadata_sequence_[num_expected_++] = &application2_;
1800         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1801         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1802         expected_metadata_sequence_[num_expected_++] = &unknown_;
1803
1804         if(!decoder->test_respond())
1805                 return false;
1806
1807         /*
1808          * ignore all
1809          */
1810
1811         printf("testing set_metadata_ignore_all()... ");
1812         if(!decoder->set_metadata_ignore_all()) {
1813                 printf("FAILED, returned false\n");
1814                 return false;
1815         }
1816         printf("OK\n");
1817
1818         num_expected_ = 0;
1819
1820         if(!decoder->test_respond())
1821                 return false;
1822
1823         /*
1824          * respond all, ignore VORBIS_COMMENT
1825          */
1826
1827         printf("testing set_metadata_respond_all()... ");
1828         if(!decoder->set_metadata_respond_all()) {
1829                 printf("FAILED, returned false\n");
1830                 return false;
1831         }
1832         printf("OK\n");
1833
1834         printf("testing set_metadata_ignore(VORBIS_COMMENT)... ");
1835         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
1836                 printf("FAILED, returned false\n");
1837                 return false;
1838         }
1839         printf("OK\n");
1840
1841         num_expected_ = 0;
1842         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1843         expected_metadata_sequence_[num_expected_++] = &padding_;
1844         expected_metadata_sequence_[num_expected_++] = &seektable_;
1845         expected_metadata_sequence_[num_expected_++] = &application1_;
1846         expected_metadata_sequence_[num_expected_++] = &application2_;
1847         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1848         expected_metadata_sequence_[num_expected_++] = &unknown_;
1849
1850         if(!decoder->test_respond())
1851                 return false;
1852
1853         /*
1854          * respond all, ignore APPLICATION
1855          */
1856
1857         printf("testing set_metadata_respond_all()... ");
1858         if(!decoder->set_metadata_respond_all()) {
1859                 printf("FAILED, returned false\n");
1860                 return false;
1861         }
1862         printf("OK\n");
1863
1864         printf("testing set_metadata_ignore(APPLICATION)... ");
1865         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
1866                 printf("FAILED, returned false\n");
1867                 return false;
1868         }
1869         printf("OK\n");
1870
1871         num_expected_ = 0;
1872         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1873         expected_metadata_sequence_[num_expected_++] = &padding_;
1874         expected_metadata_sequence_[num_expected_++] = &seektable_;
1875         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1876         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1877         expected_metadata_sequence_[num_expected_++] = &unknown_;
1878
1879         if(!decoder->test_respond())
1880                 return false;
1881
1882         /*
1883          * respond all, ignore APPLICATION id of app#1
1884          */
1885
1886         printf("testing set_metadata_respond_all()... ");
1887         if(!decoder->set_metadata_respond_all()) {
1888                 printf("FAILED, returned false\n");
1889                 return false;
1890         }
1891         printf("OK\n");
1892
1893         printf("testing set_metadata_ignore_application(of app block #1)... ");
1894         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
1895                 printf("FAILED, returned false\n");
1896                 return false;
1897         }
1898         printf("OK\n");
1899
1900         num_expected_ = 0;
1901         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1902         expected_metadata_sequence_[num_expected_++] = &padding_;
1903         expected_metadata_sequence_[num_expected_++] = &seektable_;
1904         expected_metadata_sequence_[num_expected_++] = &application2_;
1905         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1906         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1907         expected_metadata_sequence_[num_expected_++] = &unknown_;
1908
1909         if(!decoder->test_respond())
1910                 return false;
1911
1912         /*
1913          * respond all, ignore APPLICATION id of app#1 & app#2
1914          */
1915
1916         printf("testing set_metadata_respond_all()... ");
1917         if(!decoder->set_metadata_respond_all()) {
1918                 printf("FAILED, returned false\n");
1919                 return false;
1920         }
1921         printf("OK\n");
1922
1923         printf("testing set_metadata_ignore_application(of app block #1)... ");
1924         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
1925                 printf("FAILED, returned false\n");
1926                 return false;
1927         }
1928         printf("OK\n");
1929
1930         printf("testing set_metadata_ignore_application(of app block #2)... ");
1931         if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) {
1932                 printf("FAILED, returned false\n");
1933                 return false;
1934         }
1935         printf("OK\n");
1936
1937         num_expected_ = 0;
1938         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1939         expected_metadata_sequence_[num_expected_++] = &padding_;
1940         expected_metadata_sequence_[num_expected_++] = &seektable_;
1941         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1942         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1943         expected_metadata_sequence_[num_expected_++] = &unknown_;
1944
1945         if(!decoder->test_respond())
1946                 return false;
1947
1948         /*
1949          * ignore all, respond VORBIS_COMMENT
1950          */
1951
1952         printf("testing set_metadata_ignore_all()... ");
1953         if(!decoder->set_metadata_ignore_all()) {
1954                 printf("FAILED, returned false\n");
1955                 return false;
1956         }
1957         printf("OK\n");
1958
1959         printf("testing set_metadata_respond(VORBIS_COMMENT)... ");
1960         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
1961                 printf("FAILED, returned false\n");
1962                 return false;
1963         }
1964         printf("OK\n");
1965
1966         num_expected_ = 0;
1967         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1968
1969         if(!decoder->test_respond())
1970                 return false;
1971
1972         /*
1973          * ignore all, respond APPLICATION
1974          */
1975
1976         printf("testing set_metadata_ignore_all()... ");
1977         if(!decoder->set_metadata_ignore_all()) {
1978                 printf("FAILED, returned false\n");
1979                 return false;
1980         }
1981         printf("OK\n");
1982
1983         printf("testing set_metadata_respond(APPLICATION)... ");
1984         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
1985                 printf("FAILED, returned false\n");
1986                 return false;
1987         }
1988         printf("OK\n");
1989
1990         num_expected_ = 0;
1991         expected_metadata_sequence_[num_expected_++] = &application1_;
1992         expected_metadata_sequence_[num_expected_++] = &application2_;
1993
1994         if(!decoder->test_respond())
1995                 return false;
1996
1997         /*
1998          * ignore all, respond APPLICATION id of app#1
1999          */
2000
2001         printf("testing set_metadata_ignore_all()... ");
2002         if(!decoder->set_metadata_ignore_all()) {
2003                 printf("FAILED, returned false\n");
2004                 return false;
2005         }
2006         printf("OK\n");
2007
2008         printf("testing set_metadata_respond_application(of app block #1)... ");
2009         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
2010                 printf("FAILED, returned false\n");
2011                 return false;
2012         }
2013         printf("OK\n");
2014
2015         num_expected_ = 0;
2016         expected_metadata_sequence_[num_expected_++] = &application1_;
2017
2018         if(!decoder->test_respond())
2019                 return false;
2020
2021         /*
2022          * ignore all, respond APPLICATION id of app#1 & app#2
2023          */
2024
2025         printf("testing set_metadata_ignore_all()... ");
2026         if(!decoder->set_metadata_ignore_all()) {
2027                 printf("FAILED, returned false\n");
2028                 return false;
2029         }
2030         printf("OK\n");
2031
2032         printf("testing set_metadata_respond_application(of app block #1)... ");
2033         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
2034                 printf("FAILED, returned false\n");
2035                 return false;
2036         }
2037         printf("OK\n");
2038
2039         printf("testing set_metadata_respond_application(of app block #2)... ");
2040         if(!decoder->set_metadata_respond_application(application2_.data.application.id)) {
2041                 printf("FAILED, returned false\n");
2042                 return false;
2043         }
2044         printf("OK\n");
2045
2046         num_expected_ = 0;
2047         expected_metadata_sequence_[num_expected_++] = &application1_;
2048         expected_metadata_sequence_[num_expected_++] = &application2_;
2049
2050         if(!decoder->test_respond())
2051                 return false;
2052
2053         /*
2054          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
2055          */
2056
2057         printf("testing set_metadata_respond_all()... ");
2058         if(!decoder->set_metadata_respond_all()) {
2059                 printf("FAILED, returned false\n");
2060                 return false;
2061         }
2062         printf("OK\n");
2063
2064         printf("testing set_metadata_ignore(APPLICATION)... ");
2065         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
2066                 printf("FAILED, returned false\n");
2067                 return false;
2068         }
2069         printf("OK\n");
2070
2071         printf("testing set_metadata_respond_application(of app block #1)... ");
2072         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
2073                 printf("FAILED, returned false\n");
2074                 return false;
2075         }
2076         printf("OK\n");
2077
2078         num_expected_ = 0;
2079         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
2080         expected_metadata_sequence_[num_expected_++] = &padding_;
2081         expected_metadata_sequence_[num_expected_++] = &seektable_;
2082         expected_metadata_sequence_[num_expected_++] = &application1_;
2083         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
2084         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
2085         expected_metadata_sequence_[num_expected_++] = &unknown_;
2086
2087         if(!decoder->test_respond())
2088                 return false;
2089
2090         /*
2091          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
2092          */
2093
2094         printf("testing set_metadata_ignore_all()... ");
2095         if(!decoder->set_metadata_ignore_all()) {
2096                 printf("FAILED, returned false\n");
2097                 return false;
2098         }
2099         printf("OK\n");
2100
2101         printf("testing set_metadata_respond(APPLICATION)... ");
2102         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
2103                 printf("FAILED, returned false\n");
2104                 return false;
2105         }
2106         printf("OK\n");
2107
2108         printf("testing set_metadata_ignore_application(of app block #1)... ");
2109         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
2110                 printf("FAILED, returned false\n");
2111                 return false;
2112         }
2113         printf("OK\n");
2114
2115         num_expected_ = 0;
2116         expected_metadata_sequence_[num_expected_++] = &application2_;
2117
2118         if(!decoder->test_respond())
2119                 return false;
2120
2121         /* done, now leave the sequence the way we found it... */
2122         num_expected_ = 0;
2123         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
2124         expected_metadata_sequence_[num_expected_++] = &padding_;
2125         expected_metadata_sequence_[num_expected_++] = &seektable_;
2126         expected_metadata_sequence_[num_expected_++] = &application1_;
2127         expected_metadata_sequence_[num_expected_++] = &application2_;
2128         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
2129         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
2130         expected_metadata_sequence_[num_expected_++] = &unknown_;
2131
2132         printf("freeing decoder instance... ");
2133         delete decoder;
2134         printf("OK\n");
2135
2136         printf("\nPASSED!\n");
2137
2138         return true;
2139 }
2140
2141 bool test_decoders()
2142 {
2143         init_metadata_blocks_();
2144
2145         if(!generate_file_())
2146                 return false;
2147
2148         if(!test_stream_decoder())
2149                 return false;
2150
2151         if(!test_seekable_stream_decoder())
2152                 return false;
2153
2154         if(!test_file_decoder())
2155                 return false;
2156
2157         (void) grabbag__file_remove_file(flacfilename_);
2158
2159         free_metadata_blocks_();
2160
2161         return true;
2162 }