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