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