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