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