move common stuff into metadata_utils
[flac.git] / src / test_libOggFLAC++ / decoders.cpp
1 /* test_libOggFLAC++ - Unit tester for libOggFLAC++
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 "OggFLAC++/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 *oggflacfilename_ = "metadata.ogg";
37 static unsigned oggflacfilesize_;
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 Ogg 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_oggflacfile(oggflacfilename_, &oggflacfilesize_, 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 OggFLAC::Decoder::Stream, public DecoderCommon {
158 public:
159         StreamDecoder(): OggFLAC::Decoder::Stream(), DecoderCommon() { }
160         ~StreamDecoder() { }
161
162         // from OggFLAC::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)((::OggFLAC__StreamDecoderState)state), state.as_cstring());
205
206         return false;
207 }
208
209 bool StreamDecoder::test_respond()
210 {
211         printf("testing init()... ");
212         if(init() != ::OggFLAC__STREAM_DECODER_OK)
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)((::OggFLAC__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+++ libOggFLAC++ unit test: OggFLAC::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() != ::OggFLAC__STREAM_DECODER_OK)
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 set_serial_number()... ");
315         if(!decoder->set_serial_number(file_utils__serial_number))
316                 return decoder->die("returned false");
317         printf("OK\n");
318
319         printf("testing init()... ");
320         if(decoder->init() != ::OggFLAC__STREAM_DECODER_OK)
321                 return decoder->die();
322         printf("OK\n");
323
324         printf("testing get_state()... ");
325         OggFLAC::Decoder::Stream::State state = decoder->get_state();
326         printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__StreamDecoderState)state), state.as_cstring());
327
328         printf("testing get_FLAC_stream_decoder_state()... ");
329         FLAC::Decoder::Stream::State state_ = decoder->get_FLAC_stream_decoder_state();
330         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state_), state_.as_cstring());
331
332         decoder->current_metadata_number_ = 0;
333         decoder->ignore_errors_ = false;
334         decoder->error_occurred_ = false;
335
336         printf("opening Ogg FLAC file... ");
337         decoder->file_ = ::fopen(oggflacfilename_, "rb");
338         if(0 == decoder->file_) {
339                 printf("ERROR\n");
340                 return false;
341         }
342         printf("OK\n");
343
344         printf("testing process_until_end_of_metadata()... ");
345         if(!decoder->process_until_end_of_metadata())
346                 return decoder->die("returned false");
347         printf("OK\n");
348
349         printf("testing process_single()... ");
350         if(!decoder->process_single())
351                 return decoder->die("returned false");
352         printf("OK\n");
353
354         printf("testing flush()... ");
355         if(!decoder->flush())
356                 return decoder->die("returned false");
357         printf("OK\n");
358
359         decoder->ignore_errors_ = true;
360         printf("testing process_single()... ");
361         if(!decoder->process_single())
362                 return decoder->die("returned false");
363         printf("OK\n");
364         decoder->ignore_errors_ = false;
365
366         printf("testing process_until_end_of_stream()... ");
367         if(!decoder->process_until_end_of_stream())
368                 return decoder->die("returned false");
369         printf("OK\n");
370
371         printf("testing get_channels()... ");
372         {
373                 unsigned channels = decoder->get_channels();
374                 if(channels != streaminfo_.data.stream_info.channels) {
375                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
376                         return false;
377                 }
378         }
379         printf("OK\n");
380
381         printf("testing get_bits_per_sample()... ");
382         {
383                 unsigned bits_per_sample = decoder->get_bits_per_sample();
384                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
385                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
386                         return false;
387                 }
388         }
389         printf("OK\n");
390
391         printf("testing get_sample_rate()... ");
392         {
393                 unsigned sample_rate = decoder->get_sample_rate();
394                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
395                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
396                         return false;
397                 }
398         }
399         printf("OK\n");
400
401         printf("testing get_blocksize()... ");
402         {
403                 unsigned blocksize = decoder->get_blocksize();
404                 /* value could be anything since we're at the last block, so accept any answer */
405                 printf("returned %u... OK\n", blocksize);
406         }
407
408         printf("testing get_channel_assignment()... ");
409         {
410                 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment();
411                 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]);
412         }
413
414         printf("testing reset()... ");
415         if(!decoder->reset())
416                 return decoder->die("returned false");
417         printf("OK\n");
418
419         decoder->current_metadata_number_ = 0;
420
421         printf("rewinding input... ");
422         if(::fseek(decoder->file_, 0, SEEK_SET) < 0) {
423                 printf("FAILED, errno = %d\n", errno);
424                 return false;
425         }
426         printf("OK\n");
427
428         printf("testing process_until_end_of_stream()... ");
429         if(!decoder->process_until_end_of_stream())
430                 return decoder->die("returned false");
431         printf("OK\n");
432
433         printf("testing finish()... ");
434         decoder->finish();
435         printf("OK\n");
436
437         /*
438          * respond all
439          */
440
441         printf("testing set_metadata_respond_all()... ");
442         if(!decoder->set_metadata_respond_all()) {
443                 printf("FAILED, returned false\n");
444                 return false;
445         }
446         printf("OK\n");
447
448         num_expected_ = 0;
449         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
450         expected_metadata_sequence_[num_expected_++] = &padding_;
451         expected_metadata_sequence_[num_expected_++] = &seektable_;
452         expected_metadata_sequence_[num_expected_++] = &application1_;
453         expected_metadata_sequence_[num_expected_++] = &application2_;
454         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
455         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
456
457         if(!decoder->test_respond())
458                 return false;
459
460         /*
461          * ignore all
462          */
463
464         printf("testing set_metadata_ignore_all()... ");
465         if(!decoder->set_metadata_ignore_all()) {
466                 printf("FAILED, returned false\n");
467                 return false;
468         }
469         printf("OK\n");
470
471         num_expected_ = 0;
472
473         if(!decoder->test_respond())
474                 return false;
475
476         /*
477          * respond all, ignore VORBIS_COMMENT
478          */
479
480         printf("testing set_metadata_respond_all()... ");
481         if(!decoder->set_metadata_respond_all()) {
482                 printf("FAILED, returned false\n");
483                 return false;
484         }
485         printf("OK\n");
486
487         printf("testing set_metadata_ignore(VORBIS_COMMENT)... ");
488         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
489                 printf("FAILED, returned false\n");
490                 return false;
491         }
492         printf("OK\n");
493
494         num_expected_ = 0;
495         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
496         expected_metadata_sequence_[num_expected_++] = &padding_;
497         expected_metadata_sequence_[num_expected_++] = &seektable_;
498         expected_metadata_sequence_[num_expected_++] = &application1_;
499         expected_metadata_sequence_[num_expected_++] = &application2_;
500         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
501
502         if(!decoder->test_respond())
503                 return false;
504
505         /*
506          * respond all, ignore APPLICATION
507          */
508
509         printf("testing set_metadata_respond_all()... ");
510         if(!decoder->set_metadata_respond_all()) {
511                 printf("FAILED, returned false\n");
512                 return false;
513         }
514         printf("OK\n");
515
516         printf("testing set_metadata_ignore(APPLICATION)... ");
517         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
518                 printf("FAILED, returned false\n");
519                 return false;
520         }
521         printf("OK\n");
522
523         num_expected_ = 0;
524         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
525         expected_metadata_sequence_[num_expected_++] = &padding_;
526         expected_metadata_sequence_[num_expected_++] = &seektable_;
527         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
528         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
529
530         if(!decoder->test_respond())
531                 return false;
532
533         /*
534          * respond all, ignore APPLICATION id of app#1
535          */
536
537         printf("testing set_metadata_respond_all()... ");
538         if(!decoder->set_metadata_respond_all()) {
539                 printf("FAILED, returned false\n");
540                 return false;
541         }
542         printf("OK\n");
543
544         printf("testing set_metadata_ignore_application(of app block #1)... ");
545         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
546                 printf("FAILED, returned false\n");
547                 return false;
548         }
549         printf("OK\n");
550
551         num_expected_ = 0;
552         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
553         expected_metadata_sequence_[num_expected_++] = &padding_;
554         expected_metadata_sequence_[num_expected_++] = &seektable_;
555         expected_metadata_sequence_[num_expected_++] = &application2_;
556         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
557         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
558
559         if(!decoder->test_respond())
560                 return false;
561
562         /*
563          * respond all, ignore APPLICATION id of app#1 & app#2
564          */
565
566         printf("testing set_metadata_respond_all()... ");
567         if(!decoder->set_metadata_respond_all()) {
568                 printf("FAILED, returned false\n");
569                 return false;
570         }
571         printf("OK\n");
572
573         printf("testing set_metadata_ignore_application(of app block #1)... ");
574         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
575                 printf("FAILED, returned false\n");
576                 return false;
577         }
578         printf("OK\n");
579
580         printf("testing set_metadata_ignore_application(of app block #2)... ");
581         if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) {
582                 printf("FAILED, returned false\n");
583                 return false;
584         }
585         printf("OK\n");
586
587         num_expected_ = 0;
588         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
589         expected_metadata_sequence_[num_expected_++] = &padding_;
590         expected_metadata_sequence_[num_expected_++] = &seektable_;
591         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
592         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
593
594         if(!decoder->test_respond())
595                 return false;
596
597         /*
598          * ignore all, respond VORBIS_COMMENT
599          */
600
601         printf("testing set_metadata_ignore_all()... ");
602         if(!decoder->set_metadata_ignore_all()) {
603                 printf("FAILED, returned false\n");
604                 return false;
605         }
606         printf("OK\n");
607
608         printf("testing set_metadata_respond(VORBIS_COMMENT)... ");
609         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
610                 printf("FAILED, returned false\n");
611                 return false;
612         }
613         printf("OK\n");
614
615         num_expected_ = 0;
616         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
617
618         if(!decoder->test_respond())
619                 return false;
620
621         /*
622          * ignore all, respond APPLICATION
623          */
624
625         printf("testing set_metadata_ignore_all()... ");
626         if(!decoder->set_metadata_ignore_all()) {
627                 printf("FAILED, returned false\n");
628                 return false;
629         }
630         printf("OK\n");
631
632         printf("testing set_metadata_respond(APPLICATION)... ");
633         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
634                 printf("FAILED, returned false\n");
635                 return false;
636         }
637         printf("OK\n");
638
639         num_expected_ = 0;
640         expected_metadata_sequence_[num_expected_++] = &application1_;
641         expected_metadata_sequence_[num_expected_++] = &application2_;
642
643         if(!decoder->test_respond())
644                 return false;
645
646         /*
647          * ignore all, respond APPLICATION id of app#1
648          */
649
650         printf("testing set_metadata_ignore_all()... ");
651         if(!decoder->set_metadata_ignore_all()) {
652                 printf("FAILED, returned false\n");
653                 return false;
654         }
655         printf("OK\n");
656
657         printf("testing set_metadata_respond_application(of app block #1)... ");
658         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
659                 printf("FAILED, returned false\n");
660                 return false;
661         }
662         printf("OK\n");
663
664         num_expected_ = 0;
665         expected_metadata_sequence_[num_expected_++] = &application1_;
666
667         if(!decoder->test_respond())
668                 return false;
669
670         /*
671          * ignore all, respond APPLICATION id of app#1 & app#2
672          */
673
674         printf("testing set_metadata_ignore_all()... ");
675         if(!decoder->set_metadata_ignore_all()) {
676                 printf("FAILED, returned false\n");
677                 return false;
678         }
679         printf("OK\n");
680
681         printf("testing set_metadata_respond_application(of app block #1)... ");
682         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
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 #2)... ");
689         if(!decoder->set_metadata_respond_application(application2_.data.application.id)) {
690                 printf("FAILED, returned false\n");
691                 return false;
692         }
693         printf("OK\n");
694
695         num_expected_ = 0;
696         expected_metadata_sequence_[num_expected_++] = &application1_;
697         expected_metadata_sequence_[num_expected_++] = &application2_;
698
699         if(!decoder->test_respond())
700                 return false;
701
702         /*
703          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
704          */
705
706         printf("testing set_metadata_respond_all()... ");
707         if(!decoder->set_metadata_respond_all()) {
708                 printf("FAILED, returned false\n");
709                 return false;
710         }
711         printf("OK\n");
712
713         printf("testing set_metadata_ignore(APPLICATION)... ");
714         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
715                 printf("FAILED, returned false\n");
716                 return false;
717         }
718         printf("OK\n");
719
720         printf("testing set_metadata_respond_application(of app block #1)... ");
721         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
722                 printf("FAILED, returned false\n");
723                 return false;
724         }
725         printf("OK\n");
726
727         num_expected_ = 0;
728         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
729         expected_metadata_sequence_[num_expected_++] = &padding_;
730         expected_metadata_sequence_[num_expected_++] = &seektable_;
731         expected_metadata_sequence_[num_expected_++] = &application1_;
732         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
733         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
734
735         if(!decoder->test_respond())
736                 return false;
737
738         /*
739          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
740          */
741
742         printf("testing set_metadata_ignore_all()... ");
743         if(!decoder->set_metadata_ignore_all()) {
744                 printf("FAILED, returned false\n");
745                 return false;
746         }
747         printf("OK\n");
748
749         printf("testing set_metadata_respond(APPLICATION)... ");
750         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
751                 printf("FAILED, returned false\n");
752                 return false;
753         }
754         printf("OK\n");
755
756         printf("testing set_metadata_ignore_application(of app block #1)... ");
757         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
758                 printf("FAILED, returned false\n");
759                 return false;
760         }
761         printf("OK\n");
762
763         num_expected_ = 0;
764         expected_metadata_sequence_[num_expected_++] = &application2_;
765
766         if(!decoder->test_respond())
767                 return false;
768
769         /* done, now leave the sequence the way we found it... */
770         num_expected_ = 0;
771         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
772         expected_metadata_sequence_[num_expected_++] = &padding_;
773         expected_metadata_sequence_[num_expected_++] = &seektable_;
774         expected_metadata_sequence_[num_expected_++] = &application1_;
775         expected_metadata_sequence_[num_expected_++] = &application2_;
776         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
777         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
778
779         ::fclose(decoder->file_);
780
781         printf("freeing decoder instance... ");
782         delete decoder;
783         printf("OK\n");
784
785         printf("\nPASSED!\n");
786
787         return true;
788 }
789
790 bool test_decoders()
791 {
792         init_metadata_blocks_();
793         if(!generate_file_())
794                 return false;
795
796         if(!test_stream_decoder())
797                 return false;
798
799         (void) grabbag__file_remove_file(oggflacfilename_);
800         free_metadata_blocks_();
801
802         return true;
803 }