minor syntax
[flac.git] / src / test_libOggFLAC++ / decoders.cpp
1 /* test_libOggFLAC++ - Unit tester for libOggFLAC++
2  * Copyright (C) 2002  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 }
23 #include "FLAC/assert.h"
24 #include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal()
25 #include "OggFLAC++/decoder.h"
26 #include "share/grabbag.h"
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_;
33 static ::FLAC__StreamMetadata *expected_metadata_sequence_[6];
34 static unsigned num_expected_;
35 static const char *oggflacfilename_ = "metadata.ogg";
36 static unsigned oggflacfilesize_;
37
38 static bool die_(const char *msg)
39 {
40         printf("ERROR: %s\n", msg);
41         return false;
42 }
43
44 static void *malloc_or_die_(size_t size)
45 {
46         void *x = malloc(size);
47         if(0 == x) {
48                 fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
49                 exit(1);
50         }
51         return x;
52 }
53
54 static void init_metadata_blocks_()
55 {
56         /*
57                 most of the actual numbers and data in the blocks don't matter,
58                 we just want to make sure the decoder parses them correctly
59
60                 remember, the metadata interface gets tested after the decoders,
61                 so we do all the metadata manipulation here without it.
62         */
63
64         /* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
65         streaminfo_.is_last = false;
66         streaminfo_.type = ::FLAC__METADATA_TYPE_STREAMINFO;
67         streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
68         streaminfo_.data.stream_info.min_blocksize = 576;
69         streaminfo_.data.stream_info.max_blocksize = 576;
70         streaminfo_.data.stream_info.min_framesize = 0;
71         streaminfo_.data.stream_info.max_framesize = 0;
72         streaminfo_.data.stream_info.sample_rate = 44100;
73         streaminfo_.data.stream_info.channels = 1;
74         streaminfo_.data.stream_info.bits_per_sample = 8;
75         streaminfo_.data.stream_info.total_samples = 0;
76         memset(streaminfo_.data.stream_info.md5sum, 0, 16);
77
78         padding_.is_last = false;
79         padding_.type = ::FLAC__METADATA_TYPE_PADDING;
80         padding_.length = 1234;
81
82         seektable_.is_last = false;
83         seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE;
84         seektable_.data.seek_table.num_points = 2;
85         seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
86         seektable_.data.seek_table.points = (::FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetadata_SeekPoint));
87         seektable_.data.seek_table.points[0].sample_number = 0;
88         seektable_.data.seek_table.points[0].stream_offset = 0;
89         seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
90         seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
91         seektable_.data.seek_table.points[1].stream_offset = 1000;
92         seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
93
94         application1_.is_last = false;
95         application1_.type = ::FLAC__METADATA_TYPE_APPLICATION;
96         application1_.length = 8;
97         memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
98         application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
99         memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
100
101         application2_.is_last = false;
102         application2_.type = ::FLAC__METADATA_TYPE_APPLICATION;
103         application2_.length = 4;
104         memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
105         application2_.data.application.data = 0;
106
107         {
108                 const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
109                 vorbiscomment_.is_last = true;
110                 vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
111                 vorbiscomment_.length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
112                 vorbiscomment_.data.vorbis_comment.vendor_string.length = vendor_string_length;
113                 vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length);
114                 memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
115                 vorbiscomment_.data.vorbis_comment.num_comments = 2;
116                 vorbiscomment_.data.vorbis_comment.comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
117                 vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
118                 vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
119                 memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
120                 vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
121                 vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
122         }
123 }
124
125 static void free_metadata_blocks_()
126 {
127         free(seektable_.data.seek_table.points);
128         free(application1_.data.application.data);
129         free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
130         free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
131         free(vorbiscomment_.data.vorbis_comment.comments);
132 }
133
134 static bool generate_file_()
135 {
136         printf("\n\ngenerating Ogg FLAC file for decoder tests...\n");
137
138         expected_metadata_sequence_[0] = &padding_;
139         expected_metadata_sequence_[1] = &seektable_;
140         expected_metadata_sequence_[2] = &application1_;
141         expected_metadata_sequence_[3] = &application2_;
142         expected_metadata_sequence_[4] = &vorbiscomment_;
143         num_expected_ = 5;
144
145         if(!file_utils__generate_oggflacfile(oggflacfilename_, &oggflacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
146                 return die_("creating the encoded file");
147
148         return true;
149 }
150
151
152 class DecoderCommon {
153 public:
154         FILE *file_;
155         unsigned current_metadata_number_;
156         bool ignore_errors_;
157         bool error_occurred_;
158
159         DecoderCommon(): file_(0), current_metadata_number_(0), ignore_errors_(false), error_occurred_(false) { }
160         ::FLAC__StreamDecoderReadStatus common_read_callback_(FLAC__byte buffer[], unsigned *bytes);
161         ::FLAC__StreamDecoderWriteStatus common_write_callback_(const ::FLAC__Frame *frame);
162         void common_metadata_callback_(const ::FLAC__StreamMetadata *metadata);
163         void common_error_callback_(::FLAC__StreamDecoderErrorStatus status);
164 };
165
166 ::FLAC__StreamDecoderReadStatus DecoderCommon::common_read_callback_(FLAC__byte buffer[], unsigned *bytes)
167 {
168         if(error_occurred_)
169                 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT;
170
171         if(feof(file_))
172                 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
173         else if(*bytes > 0) {
174                 unsigned bytes_read = ::fread(buffer, 1, *bytes, file_);
175                 if(bytes_read == 0) {
176                         if(feof(file_))
177                                 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
178                         else
179                                 return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
180                 }
181                 else {
182                         *bytes = bytes_read;
183                         return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
184                 }
185         }
186         else
187                 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
188 }
189
190 ::FLAC__StreamDecoderWriteStatus DecoderCommon::common_write_callback_(const ::FLAC__Frame *frame)
191 {
192         if(error_occurred_)
193                 return ::FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
194
195         if(
196                 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
197                 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
198         ) {
199                 printf("content... ");
200                 fflush(stdout);
201         }
202
203         return ::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
204 }
205
206 void DecoderCommon::common_metadata_callback_(const ::FLAC__StreamMetadata *metadata)
207 {
208         if(error_occurred_)
209                 return;
210
211         printf("%d... ", current_metadata_number_);
212         fflush(stdout);
213
214         if(current_metadata_number_ >= num_expected_) {
215                 (void)die_("got more metadata blocks than expected");
216                 error_occurred_ = true;
217         }
218         else {
219                 if(!::FLAC__metadata_object_is_equal(expected_metadata_sequence_[current_metadata_number_], metadata)) {
220                         (void)die_("metadata block mismatch");
221                         error_occurred_ = true;
222                 }
223         }
224         current_metadata_number_++;
225 }
226
227 void DecoderCommon::common_error_callback_(::FLAC__StreamDecoderErrorStatus status)
228 {
229         if(!ignore_errors_) {
230                 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, ::FLAC__StreamDecoderErrorStatusString[status]);
231                 error_occurred_ = true;
232         }
233 }
234
235 class StreamDecoder : public OggFLAC::Decoder::Stream, public DecoderCommon {
236 public:
237         StreamDecoder(): OggFLAC::Decoder::Stream(), DecoderCommon() { }
238         ~StreamDecoder() { }
239
240         // from OggFLAC::Decoder::Stream
241         ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
242         ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
243         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
244         void error_callback(::FLAC__StreamDecoderErrorStatus status);
245
246         bool die(const char *msg = 0) const;
247
248         bool test_respond();
249 };
250
251 ::FLAC__StreamDecoderReadStatus StreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
252 {
253         return common_read_callback_(buffer, bytes);
254 }
255
256 ::FLAC__StreamDecoderWriteStatus StreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
257 {
258         (void)buffer;
259
260         return common_write_callback_(frame);
261 }
262
263 void StreamDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
264 {
265         common_metadata_callback_(metadata);
266 }
267
268 void StreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
269 {
270         common_error_callback_(status);
271 }
272
273 bool StreamDecoder::die(const char *msg) const
274 {
275         State state = get_state();
276
277         if(msg)
278                 printf("FAILED, %s", msg);
279         else
280                 printf("FAILED");
281
282         printf(", state = %u (%s)\n", (unsigned)((::OggFLAC__StreamDecoderState)state), state.as_cstring());
283
284         return false;
285 }
286
287 bool StreamDecoder::test_respond()
288 {
289         printf("testing init()... ");
290         if(init() != ::OggFLAC__STREAM_DECODER_OK)
291                 return die();
292         printf("OK\n");
293
294         current_metadata_number_ = 0;
295
296         if(::fseek(file_, 0, SEEK_SET) < 0) {
297                 printf("FAILED rewinding input, errno = %d\n", errno);
298                 return false;
299         }
300
301         printf("testing process_until_end_of_stream()... ");
302         if(!process_until_end_of_stream()) {
303                 State state = get_state();
304                 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::OggFLAC__StreamDecoderState)state), state.as_cstring());
305                 return false;
306         }
307         printf("OK\n");
308
309         printf("testing finish()... ");
310         finish();
311         printf("OK\n");
312
313         return true;
314 }
315
316 static bool test_stream_decoder()
317 {
318         StreamDecoder *decoder;
319
320         printf("\n+++ libOggFLAC++ unit test: OggFLAC::Decoder::Stream\n\n");
321
322         //
323         // test new -> delete
324         //
325         printf("allocating decoder instance... ");
326         decoder = new StreamDecoder();
327         if(0 == decoder) {
328                 printf("FAILED, new returned NULL\n");
329                 return false;
330         }
331         printf("OK\n");
332
333         printf("testing is_valid()... ");
334         if(!decoder->is_valid()) {
335                 printf("FAILED, returned false\n");
336                 return false;
337         }
338         printf("OK\n");
339
340         printf("freeing decoder instance... ");
341         delete decoder;
342         printf("OK\n");
343
344         //
345         // test new -> init -> delete
346         //
347         printf("allocating decoder instance... ");
348         decoder = new StreamDecoder();
349         if(0 == decoder) {
350                 printf("FAILED, new returned NULL\n");
351                 return false;
352         }
353         printf("OK\n");
354
355         printf("testing is_valid()... ");
356         if(!decoder->is_valid()) {
357                 printf("FAILED, returned false\n");
358                 return false;
359         }
360         printf("OK\n");
361
362         printf("testing init()... ");
363         if(decoder->init() != ::OggFLAC__STREAM_DECODER_OK)
364                 return decoder->die();
365         printf("OK\n");
366
367         printf("freeing decoder instance... ");
368         delete decoder;
369         printf("OK\n");
370
371         //
372         // test normal usage
373         //
374         num_expected_ = 0;
375         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
376
377         printf("allocating decoder instance... ");
378         decoder = new StreamDecoder();
379         if(0 == decoder) {
380                 printf("FAILED, new returned NULL\n");
381                 return false;
382         }
383         printf("OK\n");
384
385         printf("testing is_valid()... ");
386         if(!decoder->is_valid()) {
387                 printf("FAILED, returned false\n");
388                 return false;
389         }
390         printf("OK\n");
391
392         printf("testing set_serial_number()... ");
393         if(!decoder->set_serial_number(file_utils__serial_number))
394                 return decoder->die("returned false");
395         printf("OK\n");
396
397         printf("testing init()... ");
398         if(decoder->init() != ::OggFLAC__STREAM_DECODER_OK)
399                 return decoder->die();
400         printf("OK\n");
401
402         printf("testing get_state()... ");
403         OggFLAC::Decoder::Stream::State state = decoder->get_state();
404         printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__StreamDecoderState)state), state.as_cstring());
405
406         printf("testing get_FLAC_stream_decoder_state()... ");
407         FLAC::Decoder::Stream::State state_ = decoder->get_FLAC_stream_decoder_state();
408         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state_), state_.as_cstring());
409
410         decoder->current_metadata_number_ = 0;
411         decoder->ignore_errors_ = false;
412         decoder->error_occurred_ = false;
413
414         printf("opening Ogg FLAC file... ");
415         decoder->file_ = ::fopen(oggflacfilename_, "rb");
416         if(0 == decoder->file_) {
417                 printf("ERROR\n");
418                 return false;
419         }
420         printf("OK\n");
421
422         printf("testing process_until_end_of_metadata()... ");
423         if(!decoder->process_until_end_of_metadata())
424                 return decoder->die("returned false");
425         printf("OK\n");
426
427         printf("testing process_single()... ");
428         if(!decoder->process_single())
429                 return decoder->die("returned false");
430         printf("OK\n");
431
432         printf("testing flush()... ");
433         if(!decoder->flush())
434                 return decoder->die("returned false");
435         printf("OK\n");
436
437         decoder->ignore_errors_ = true;
438         printf("testing process_single()... ");
439         if(!decoder->process_single())
440                 return decoder->die("returned false");
441         printf("OK\n");
442         decoder->ignore_errors_ = false;
443
444         printf("testing process_until_end_of_stream()... ");
445         if(!decoder->process_until_end_of_stream())
446                 return decoder->die("returned false");
447         printf("OK\n");
448
449         printf("testing get_channels()... ");
450         {
451                 unsigned channels = decoder->get_channels();
452                 if(channels != streaminfo_.data.stream_info.channels) {
453                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
454                         return false;
455                 }
456         }
457         printf("OK\n");
458
459         printf("testing get_bits_per_sample()... ");
460         {
461                 unsigned bits_per_sample = decoder->get_bits_per_sample();
462                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
463                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
464                         return false;
465                 }
466         }
467         printf("OK\n");
468
469         printf("testing get_sample_rate()... ");
470         {
471                 unsigned sample_rate = decoder->get_sample_rate();
472                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
473                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
474                         return false;
475                 }
476         }
477         printf("OK\n");
478
479         printf("testing get_blocksize()... ");
480         {
481                 unsigned blocksize = decoder->get_blocksize();
482                 /* value could be anything since we're at the last block, so accept any answer */
483                 printf("returned %u... OK\n", blocksize);
484         }
485
486         printf("testing get_channel_assignment()... ");
487         {
488                 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment();
489                 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]);
490         }
491
492         printf("testing reset()... ");
493         if(!decoder->reset())
494                 return decoder->die("returned false");
495         printf("OK\n");
496
497         decoder->current_metadata_number_ = 0;
498
499         printf("rewinding input... ");
500         if(::fseek(decoder->file_, 0, SEEK_SET) < 0) {
501                 printf("FAILED, errno = %d\n", errno);
502                 return false;
503         }
504         printf("OK\n");
505
506         printf("testing process_until_end_of_stream()... ");
507         if(!decoder->process_until_end_of_stream())
508                 return decoder->die("returned false");
509         printf("OK\n");
510
511         printf("testing finish()... ");
512         decoder->finish();
513         printf("OK\n");
514
515         /*
516          * respond all
517          */
518
519         printf("testing set_metadata_respond_all()... ");
520         if(!decoder->set_metadata_respond_all()) {
521                 printf("FAILED, returned false\n");
522                 return false;
523         }
524         printf("OK\n");
525
526         num_expected_ = 0;
527         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
528         expected_metadata_sequence_[num_expected_++] = &padding_;
529         expected_metadata_sequence_[num_expected_++] = &seektable_;
530         expected_metadata_sequence_[num_expected_++] = &application1_;
531         expected_metadata_sequence_[num_expected_++] = &application2_;
532         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
533
534         if(!decoder->test_respond())
535                 return false;
536
537         /*
538          * ignore all
539          */
540
541         printf("testing set_metadata_ignore_all()... ");
542         if(!decoder->set_metadata_ignore_all()) {
543                 printf("FAILED, returned false\n");
544                 return false;
545         }
546         printf("OK\n");
547
548         num_expected_ = 0;
549
550         if(!decoder->test_respond())
551                 return false;
552
553         /*
554          * respond all, ignore VORBIS_COMMENT
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(VORBIS_COMMENT)... ");
565         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
566                 printf("FAILED, returned false\n");
567                 return false;
568         }
569         printf("OK\n");
570
571         num_expected_ = 0;
572         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
573         expected_metadata_sequence_[num_expected_++] = &padding_;
574         expected_metadata_sequence_[num_expected_++] = &seektable_;
575         expected_metadata_sequence_[num_expected_++] = &application1_;
576         expected_metadata_sequence_[num_expected_++] = &application2_;
577
578         if(!decoder->test_respond())
579                 return false;
580
581         /*
582          * respond all, ignore APPLICATION
583          */
584
585         printf("testing set_metadata_respond_all()... ");
586         if(!decoder->set_metadata_respond_all()) {
587                 printf("FAILED, returned false\n");
588                 return false;
589         }
590         printf("OK\n");
591
592         printf("testing set_metadata_ignore(APPLICATION)... ");
593         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
594                 printf("FAILED, returned false\n");
595                 return false;
596         }
597         printf("OK\n");
598
599         num_expected_ = 0;
600         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
601         expected_metadata_sequence_[num_expected_++] = &padding_;
602         expected_metadata_sequence_[num_expected_++] = &seektable_;
603         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
604
605         if(!decoder->test_respond())
606                 return false;
607
608         /*
609          * respond all, ignore APPLICATION id of app#1
610          */
611
612         printf("testing set_metadata_respond_all()... ");
613         if(!decoder->set_metadata_respond_all()) {
614                 printf("FAILED, returned false\n");
615                 return false;
616         }
617         printf("OK\n");
618
619         printf("testing set_metadata_ignore_application(of app block #1)... ");
620         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
621                 printf("FAILED, returned false\n");
622                 return false;
623         }
624         printf("OK\n");
625
626         num_expected_ = 0;
627         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
628         expected_metadata_sequence_[num_expected_++] = &padding_;
629         expected_metadata_sequence_[num_expected_++] = &seektable_;
630         expected_metadata_sequence_[num_expected_++] = &application2_;
631         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
632
633         if(!decoder->test_respond())
634                 return false;
635
636         /*
637          * respond all, ignore APPLICATION id of app#1 & app#2
638          */
639
640         printf("testing set_metadata_respond_all()... ");
641         if(!decoder->set_metadata_respond_all()) {
642                 printf("FAILED, returned false\n");
643                 return false;
644         }
645         printf("OK\n");
646
647         printf("testing set_metadata_ignore_application(of app block #1)... ");
648         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
649                 printf("FAILED, returned false\n");
650                 return false;
651         }
652         printf("OK\n");
653
654         printf("testing set_metadata_ignore_application(of app block #2)... ");
655         if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) {
656                 printf("FAILED, returned false\n");
657                 return false;
658         }
659         printf("OK\n");
660
661         num_expected_ = 0;
662         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
663         expected_metadata_sequence_[num_expected_++] = &padding_;
664         expected_metadata_sequence_[num_expected_++] = &seektable_;
665         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
666
667         if(!decoder->test_respond())
668                 return false;
669
670         /*
671          * ignore all, respond VORBIS_COMMENT
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(VORBIS_COMMENT)... ");
682         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
683                 printf("FAILED, returned false\n");
684                 return false;
685         }
686         printf("OK\n");
687
688         num_expected_ = 0;
689         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
690
691         if(!decoder->test_respond())
692                 return false;
693
694         /*
695          * ignore all, respond APPLICATION
696          */
697
698         printf("testing set_metadata_ignore_all()... ");
699         if(!decoder->set_metadata_ignore_all()) {
700                 printf("FAILED, returned false\n");
701                 return false;
702         }
703         printf("OK\n");
704
705         printf("testing set_metadata_respond(APPLICATION)... ");
706         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
707                 printf("FAILED, returned false\n");
708                 return false;
709         }
710         printf("OK\n");
711
712         num_expected_ = 0;
713         expected_metadata_sequence_[num_expected_++] = &application1_;
714         expected_metadata_sequence_[num_expected_++] = &application2_;
715
716         if(!decoder->test_respond())
717                 return false;
718
719         /*
720          * ignore all, respond APPLICATION id of app#1
721          */
722
723         printf("testing set_metadata_ignore_all()... ");
724         if(!decoder->set_metadata_ignore_all()) {
725                 printf("FAILED, returned false\n");
726                 return false;
727         }
728         printf("OK\n");
729
730         printf("testing set_metadata_respond_application(of app block #1)... ");
731         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
732                 printf("FAILED, returned false\n");
733                 return false;
734         }
735         printf("OK\n");
736
737         num_expected_ = 0;
738         expected_metadata_sequence_[num_expected_++] = &application1_;
739
740         if(!decoder->test_respond())
741                 return false;
742
743         /*
744          * ignore all, respond APPLICATION id of app#1 & app#2
745          */
746
747         printf("testing set_metadata_ignore_all()... ");
748         if(!decoder->set_metadata_ignore_all()) {
749                 printf("FAILED, returned false\n");
750                 return false;
751         }
752         printf("OK\n");
753
754         printf("testing set_metadata_respond_application(of app block #1)... ");
755         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
756                 printf("FAILED, returned false\n");
757                 return false;
758         }
759         printf("OK\n");
760
761         printf("testing set_metadata_respond_application(of app block #2)... ");
762         if(!decoder->set_metadata_respond_application(application2_.data.application.id)) {
763                 printf("FAILED, returned false\n");
764                 return false;
765         }
766         printf("OK\n");
767
768         num_expected_ = 0;
769         expected_metadata_sequence_[num_expected_++] = &application1_;
770         expected_metadata_sequence_[num_expected_++] = &application2_;
771
772         if(!decoder->test_respond())
773                 return false;
774
775         /*
776          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
777          */
778
779         printf("testing set_metadata_respond_all()... ");
780         if(!decoder->set_metadata_respond_all()) {
781                 printf("FAILED, returned false\n");
782                 return false;
783         }
784         printf("OK\n");
785
786         printf("testing set_metadata_ignore(APPLICATION)... ");
787         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
788                 printf("FAILED, returned false\n");
789                 return false;
790         }
791         printf("OK\n");
792
793         printf("testing set_metadata_respond_application(of app block #1)... ");
794         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
795                 printf("FAILED, returned false\n");
796                 return false;
797         }
798         printf("OK\n");
799
800         num_expected_ = 0;
801         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
802         expected_metadata_sequence_[num_expected_++] = &padding_;
803         expected_metadata_sequence_[num_expected_++] = &seektable_;
804         expected_metadata_sequence_[num_expected_++] = &application1_;
805         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
806
807         if(!decoder->test_respond())
808                 return false;
809
810         /*
811          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
812          */
813
814         printf("testing set_metadata_ignore_all()... ");
815         if(!decoder->set_metadata_ignore_all()) {
816                 printf("FAILED, returned false\n");
817                 return false;
818         }
819         printf("OK\n");
820
821         printf("testing set_metadata_respond(APPLICATION)... ");
822         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
823                 printf("FAILED, returned false\n");
824                 return false;
825         }
826         printf("OK\n");
827
828         printf("testing set_metadata_ignore_application(of app block #1)... ");
829         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
830                 printf("FAILED, returned false\n");
831                 return false;
832         }
833         printf("OK\n");
834
835         num_expected_ = 0;
836         expected_metadata_sequence_[num_expected_++] = &application2_;
837
838         if(!decoder->test_respond())
839                 return false;
840
841         /* done, now leave the sequence the way we found it... */
842         num_expected_ = 0;
843         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
844         expected_metadata_sequence_[num_expected_++] = &padding_;
845         expected_metadata_sequence_[num_expected_++] = &seektable_;
846         expected_metadata_sequence_[num_expected_++] = &application1_;
847         expected_metadata_sequence_[num_expected_++] = &application2_;
848         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
849
850         ::fclose(decoder->file_);
851
852         printf("freeing decoder instance... ");
853         delete decoder;
854         printf("OK\n");
855
856         printf("\nPASSED!\n");
857
858         return true;
859 }
860
861 bool test_decoders()
862 {
863         init_metadata_blocks_();
864         if(!generate_file_())
865                 return false;
866
867         if(!test_stream_decoder())
868                 return false;
869
870         (void) grabbag__file_remove_file(oggflacfilename_);
871         free_metadata_blocks_();
872
873         return true;
874 }