change .cc suffix to .cpp
[flac.git] / src / test_libFLAC++ / metadata_object.cpp
1 /* test_libFLAC++ - Unit tester for libFLAC++
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 "FLAC/assert.h"
20 #include "FLAC++/metadata.h"
21 #include <stdio.h>
22 #include <stdlib.h> /* for malloc() */
23 #include <string.h> /* for memcmp() */
24
25 static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application_, vorbiscomment_;
26
27 static bool die_(const char *msg)
28 {
29         printf("FAILED, %s\n", msg);
30         return false;
31 }
32
33 static void *malloc_or_die_(size_t size)
34 {
35         void *x = malloc(size);
36         if(0 == x) {
37                 fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
38                 exit(1);
39         }
40         return x;
41 }
42
43 static void init_metadata_blocks_()
44 {
45         streaminfo_.is_last = false;
46         streaminfo_.type = ::FLAC__METADATA_TYPE_STREAMINFO;
47         streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
48         streaminfo_.data.stream_info.min_blocksize = 576;
49         streaminfo_.data.stream_info.max_blocksize = 576;
50         streaminfo_.data.stream_info.min_framesize = 0;
51         streaminfo_.data.stream_info.max_framesize = 0;
52         streaminfo_.data.stream_info.sample_rate = 44100;
53         streaminfo_.data.stream_info.channels = 1;
54         streaminfo_.data.stream_info.bits_per_sample = 8;
55         streaminfo_.data.stream_info.total_samples = 0;
56         memset(streaminfo_.data.stream_info.md5sum, 0, 16);
57
58         padding_.is_last = false;
59         padding_.type = ::FLAC__METADATA_TYPE_PADDING;
60         padding_.length = 1234;
61
62         seektable_.is_last = false;
63         seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE;
64         seektable_.data.seek_table.num_points = 2;
65         seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
66         seektable_.data.seek_table.points = (::FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetadata_SeekPoint));
67         seektable_.data.seek_table.points[0].sample_number = 0;
68         seektable_.data.seek_table.points[0].stream_offset = 0;
69         seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
70         seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
71         seektable_.data.seek_table.points[1].stream_offset = 1000;
72         seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
73
74         application_.is_last = false;
75         application_.type = ::FLAC__METADATA_TYPE_APPLICATION;
76         application_.length = 8;
77         memcpy(application_.data.application.id, "\xfe\xdc\xba\x98", 4);
78         application_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
79         memcpy(application_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
80
81         vorbiscomment_.is_last = true;
82         vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT;
83         vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0);
84         vorbiscomment_.data.vorbis_comment.vendor_string.length = 5;
85         vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(5);
86         memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "name0", 8);
87         vorbiscomment_.data.vorbis_comment.num_comments = 2;
88         vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetadata_VorbisComment_Entry));
89         vorbiscomment_.data.vorbis_comment.comments[0].length = 12;
90         vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(12);
91         memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "name2=value2", 12);
92         vorbiscomment_.data.vorbis_comment.comments[1].length = 12;
93         vorbiscomment_.data.vorbis_comment.comments[1].entry = (FLAC__byte*)malloc_or_die_(12);
94         memcpy(vorbiscomment_.data.vorbis_comment.comments[1].entry, "name3=value3", 12);
95 }
96
97 static void free_metadata_blocks_()
98 {
99         free(seektable_.data.seek_table.points);
100         free(application_.data.application.data);
101         free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
102         free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
103         free(vorbiscomment_.data.vorbis_comment.comments);
104 }
105
106 bool test_metadata_object_streaminfo()
107 {
108         unsigned expected_length;
109
110         printf("testing class FLAC::Metadata::StreamInfo\n");
111
112         printf("testing StreamInfo::StreamInfo()... ");
113         FLAC::Metadata::StreamInfo block;
114         if(!block.is_valid())
115                 return die_("!block.is_valid()");
116         expected_length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
117         if(block.get_length() != expected_length) {
118                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
119                 return false;
120         }
121         printf("OK\n");
122
123         printf("testing StreamInfo::StreamInfo(const StreamInfo &)... +\n");
124         printf("        StreamInfo::operator!=(const StreamInfo &)... ");
125         {
126                 FLAC::Metadata::StreamInfo blockcopy(block);
127                 if(!blockcopy.is_valid())
128                         return die_("!block.is_valid()");
129                 if(blockcopy != block)
130                         return die_("copy is not identical to original");
131                 printf("OK\n");
132
133                 printf("testing StreamInfo::~StreamInfo()... ");
134         }
135         printf("OK\n");
136
137         printf("testing StreamInfo::StreamInfo(const ::FLAC__StreamMetadata &)... +\n");
138         printf("        StreamInfo::operator!=(const ::FLAC__StreamMetadata &)... ");
139         {
140                 FLAC::Metadata::StreamInfo blockcopy(streaminfo_);
141                 if(!blockcopy.is_valid())
142                         return die_("!block.is_valid()");
143                 if(blockcopy != streaminfo_)
144                         return die_("copy is not identical to original");
145                 printf("OK\n");
146         }
147
148         printf("testing StreamInfo::StreamInfo(const ::FLAC__StreamMetadata *)... +\n");
149         printf("        StreamInfo::operator!=(const ::FLAC__StreamMetadata *)... ");
150         {
151                 FLAC::Metadata::StreamInfo blockcopy(&streaminfo_);
152                 if(!blockcopy.is_valid())
153                         return die_("!block.is_valid()");
154                 if(blockcopy != streaminfo_)
155                         return die_("copy is not identical to original");
156                 printf("OK\n");
157         }
158
159         printf("testing StreamInfo::operator=(const StreamInfo &)... +\n");
160         printf("        StreamInfo::operator==(const StreamInfo &)... ");
161         {
162                 FLAC::Metadata::StreamInfo blockcopy = block;
163                 if(!blockcopy.is_valid())
164                         return die_("!block.is_valid()");
165                 if(!(blockcopy == block))
166                         return die_("copy is not identical to original");
167                 printf("OK\n");
168         }
169
170         printf("testing StreamInfo::operator=(const ::FLAC__StreamMetadata &)... +\n");
171         printf("        StreamInfo::operator==(const ::FLAC__StreamMetadata &)... ");
172         {
173                 FLAC::Metadata::StreamInfo blockcopy = streaminfo_;
174                 if(!blockcopy.is_valid())
175                         return die_("!block.is_valid()");
176                 if(!(blockcopy == streaminfo_))
177                         return die_("copy is not identical to original");
178                 printf("OK\n");
179         }
180
181         printf("testing StreamInfo::operator=(const ::FLAC__StreamMetadata *)... +\n");
182         printf("        StreamInfo::operator==(const ::FLAC__StreamMetadata *)... ");
183         {
184                 FLAC::Metadata::StreamInfo blockcopy = &streaminfo_;
185                 if(!blockcopy.is_valid())
186                         return die_("!block.is_valid()");
187                 if(!(blockcopy == streaminfo_))
188                         return die_("copy is not identical to original");
189                 printf("OK\n");
190         }
191
192         printf("testing StreamInfo::set_min_blocksize()... ");
193         block.set_min_blocksize(streaminfo_.data.stream_info.min_blocksize);
194         printf("OK\n");
195
196         printf("testing StreamInfo::set_max_blocksize()... ");
197         block.set_max_blocksize(streaminfo_.data.stream_info.max_blocksize);
198         printf("OK\n");
199
200         printf("testing StreamInfo::set_min_framesize()... ");
201         block.set_min_framesize(streaminfo_.data.stream_info.min_framesize);
202         printf("OK\n");
203
204         printf("testing StreamInfo::set_max_framesize()... ");
205         block.set_max_framesize(streaminfo_.data.stream_info.max_framesize);
206         printf("OK\n");
207
208         printf("testing StreamInfo::set_sample_rate()... ");
209         block.set_sample_rate(streaminfo_.data.stream_info.sample_rate);
210         printf("OK\n");
211
212         printf("testing StreamInfo::set_channels()... ");
213         block.set_channels(streaminfo_.data.stream_info.channels);
214         printf("OK\n");
215
216         printf("testing StreamInfo::set_bits_per_sample()... ");
217         block.set_bits_per_sample(streaminfo_.data.stream_info.bits_per_sample);
218         printf("OK\n");
219
220         printf("testing StreamInfo::set_total_samples()... ");
221         block.set_total_samples(streaminfo_.data.stream_info.total_samples);
222         printf("OK\n");
223
224         printf("testing StreamInfo::set_md5sum()... ");
225         block.set_md5sum(streaminfo_.data.stream_info.md5sum);
226         printf("OK\n");
227
228         printf("testing StreamInfo::get_min_blocksize()... ");
229         if(block.get_min_blocksize() != streaminfo_.data.stream_info.min_blocksize)
230                 return die_("value mismatch, doesn't match previously set value");
231         printf("OK\n");
232
233         printf("testing StreamInfo::get_max_blocksize()... ");
234         if(block.get_max_blocksize() != streaminfo_.data.stream_info.max_blocksize)
235                 return die_("value mismatch, doesn't match previously set value");
236         printf("OK\n");
237
238         printf("testing StreamInfo::get_min_framesize()... ");
239         if(block.get_min_framesize() != streaminfo_.data.stream_info.min_framesize)
240                 return die_("value mismatch, doesn't match previously set value");
241         printf("OK\n");
242
243         printf("testing StreamInfo::get_max_framesize()... ");
244         if(block.get_max_framesize() != streaminfo_.data.stream_info.max_framesize)
245                 return die_("value mismatch, doesn't match previously set value");
246         printf("OK\n");
247
248         printf("testing StreamInfo::get_sample_rate()... ");
249         if(block.get_sample_rate() != streaminfo_.data.stream_info.sample_rate)
250                 return die_("value mismatch, doesn't match previously set value");
251         printf("OK\n");
252
253         printf("testing StreamInfo::get_channels()... ");
254         if(block.get_channels() != streaminfo_.data.stream_info.channels)
255                 return die_("value mismatch, doesn't match previously set value");
256         printf("OK\n");
257
258         printf("testing StreamInfo::get_bits_per_sample()... ");
259         if(block.get_bits_per_sample() != streaminfo_.data.stream_info.bits_per_sample)
260                 return die_("value mismatch, doesn't match previously set value");
261         printf("OK\n");
262
263         printf("testing StreamInfo::get_total_samples()... ");
264         if(block.get_total_samples() != streaminfo_.data.stream_info.total_samples)
265                 return die_("value mismatch, doesn't match previously set value");
266         printf("OK\n");
267
268         printf("testing StreamInfo::get_md5sum()... ");
269         if(0 != memcmp(block.get_md5sum(), streaminfo_.data.stream_info.md5sum, 16))
270                 return die_("value mismatch, doesn't match previously set value");
271         printf("OK\n");
272
273         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
274         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
275         if(0 == clone_)
276                 return die_("returned NULL");
277         if(0 == dynamic_cast<FLAC::Metadata::StreamInfo *>(clone_))
278                 return die_("downcast is NULL");
279         if(*dynamic_cast<FLAC::Metadata::StreamInfo *>(clone_) != block)
280                 return die_("clone is not identical");
281         printf("OK\n");
282
283
284         printf("PASSED\n\n");
285         return true;
286 }
287
288 bool test_metadata_object_padding()
289 {
290         unsigned expected_length;
291
292         printf("testing class FLAC::Metadata::Padding\n");
293
294         printf("testing Padding::Padding()... ");
295         FLAC::Metadata::Padding block;
296         if(!block.is_valid())
297                 return die_("!block.is_valid()");
298         expected_length = 0;
299         if(block.get_length() != expected_length) {
300                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
301                 return false;
302         }
303         printf("OK\n");
304
305         printf("testing Padding::Padding(const Padding &)... +\n");
306         printf("        Padding::operator!=(const Padding &)... ");
307         {
308                 FLAC::Metadata::Padding blockcopy(block);
309                 if(!blockcopy.is_valid())
310                         return die_("!block.is_valid()");
311                 if(blockcopy != block)
312                         return die_("copy is not identical to original");
313                 printf("OK\n");
314
315                 printf("testing Padding::~Padding()... ");
316         }
317         printf("OK\n");
318
319         printf("testing Padding::Padding(const ::FLAC__StreamMetadata &)... +\n");
320         printf("        Padding::operator!=(const ::FLAC__StreamMetadata &)... ");
321         {
322                 FLAC::Metadata::Padding blockcopy(padding_);
323                 if(!blockcopy.is_valid())
324                         return die_("!block.is_valid()");
325                 if(blockcopy != padding_)
326                         return die_("copy is not identical to original");
327                 printf("OK\n");
328         }
329
330         printf("testing Padding::Padding(const ::FLAC__StreamMetadata *)... +\n");
331         printf("        Padding::operator!=(const ::FLAC__StreamMetadata *)... ");
332         {
333                 FLAC::Metadata::Padding blockcopy(&padding_);
334                 if(!blockcopy.is_valid())
335                         return die_("!block.is_valid()");
336                 if(blockcopy != padding_)
337                         return die_("copy is not identical to original");
338                 printf("OK\n");
339         }
340
341         printf("testing Padding::operator=(const Padding &)... +\n");
342         printf("        Padding::operator==(const Padding &)... ");
343         {
344                 FLAC::Metadata::Padding blockcopy = block;
345                 if(!blockcopy.is_valid())
346                         return die_("!block.is_valid()");
347                 if(!(blockcopy == block))
348                         return die_("copy is not identical to original");
349                 printf("OK\n");
350         }
351
352         printf("testing Padding::operator=(const ::FLAC__StreamMetadata &)... +\n");
353         printf("        Padding::operator==(const ::FLAC__StreamMetadata &)... ");
354         {
355                 FLAC::Metadata::Padding blockcopy = padding_;
356                 if(!blockcopy.is_valid())
357                         return die_("!block.is_valid()");
358                 if(!(blockcopy == padding_))
359                         return die_("copy is not identical to original");
360                 printf("OK\n");
361         }
362
363         printf("testing Padding::operator=(const ::FLAC__StreamMetadata *)... +\n");
364         printf("        Padding::operator==(const ::FLAC__StreamMetadata *)... ");
365         {
366                 FLAC::Metadata::Padding blockcopy = &padding_;
367                 if(!blockcopy.is_valid())
368                         return die_("!block.is_valid()");
369                 if(!(blockcopy == padding_))
370                         return die_("copy is not identical to original");
371                 printf("OK\n");
372         }
373
374         printf("testing Padding::set_length()... ");
375         block.set_length(padding_.length);
376         printf("OK\n");
377
378         printf("testing Prototype::get_length()... ");
379         if(block.get_length() != padding_.length)
380                 return die_("value mismatch, doesn't match previously set value");
381         printf("OK\n");
382
383         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
384         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
385         if(0 == clone_)
386                 return die_("returned NULL");
387         if(0 == dynamic_cast<FLAC::Metadata::Padding *>(clone_))
388                 return die_("downcast is NULL");
389         if(*dynamic_cast<FLAC::Metadata::Padding *>(clone_) != block)
390                 return die_("clone is not identical");
391         printf("OK\n");
392
393
394         printf("PASSED\n\n");
395         return true;
396 }
397
398 bool test_metadata_object_application()
399 {
400         unsigned expected_length;
401
402         printf("testing class FLAC::Metadata::Application\n");
403
404         printf("testing Application::Application()... ");
405         FLAC::Metadata::Application block;
406         if(!block.is_valid())
407                 return die_("!block.is_valid()");
408         expected_length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
409         if(block.get_length() != expected_length) {
410                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
411                 return false;
412         }
413         printf("OK\n");
414
415         printf("testing Application::Application(const Application &)... +\n");
416         printf("        Application::operator!=(const Application &)... ");
417         {
418                 FLAC::Metadata::Application blockcopy(block);
419                 if(!blockcopy.is_valid())
420                         return die_("!block.is_valid()");
421                 if(blockcopy != block)
422                         return die_("copy is not identical to original");
423                 printf("OK\n");
424
425                 printf("testing Application::~Application()... ");
426         }
427         printf("OK\n");
428
429         printf("testing Application::Application(const ::FLAC__StreamMetadata &)... +\n");
430         printf("        Application::operator!=(const ::FLAC__StreamMetadata &)... ");
431         {
432                 FLAC::Metadata::Application blockcopy(application_);
433                 if(!blockcopy.is_valid())
434                         return die_("!block.is_valid()");
435                 if(blockcopy != application_)
436                         return die_("copy is not identical to original");
437                 printf("OK\n");
438         }
439
440         printf("testing Application::Application(const ::FLAC__StreamMetadata *)... +\n");
441         printf("        Application::operator!=(const ::FLAC__StreamMetadata *)... ");
442         {
443                 FLAC::Metadata::Application blockcopy(&application_);
444                 if(!blockcopy.is_valid())
445                         return die_("!block.is_valid()");
446                 if(blockcopy != application_)
447                         return die_("copy is not identical to original");
448                 printf("OK\n");
449         }
450
451         printf("testing Application::operator=(const Application &)... +\n");
452         printf("        Application::operator==(const Application &)... ");
453         {
454                 FLAC::Metadata::Application blockcopy = block;
455                 if(!blockcopy.is_valid())
456                         return die_("!block.is_valid()");
457                 if(!(blockcopy == block))
458                         return die_("copy is not identical to original");
459                 printf("OK\n");
460         }
461
462         printf("testing Application::operator=(const ::FLAC__StreamMetadata &)... +\n");
463         printf("        Application::operator==(const ::FLAC__StreamMetadata &)... ");
464         {
465                 FLAC::Metadata::Application blockcopy = application_;
466                 if(!blockcopy.is_valid())
467                         return die_("!block.is_valid()");
468                 if(!(blockcopy == application_))
469                         return die_("copy is not identical to original");
470                 printf("OK\n");
471         }
472
473         printf("testing Application::operator=(const ::FLAC__StreamMetadata *)... +\n");
474         printf("        Application::operator==(const ::FLAC__StreamMetadata *)... ");
475         {
476                 FLAC::Metadata::Application blockcopy = &application_;
477                 if(!blockcopy.is_valid())
478                         return die_("!block.is_valid()");
479                 if(!(blockcopy == application_))
480                         return die_("copy is not identical to original");
481                 printf("OK\n");
482         }
483
484         printf("testing Application::set_id()... ");
485         block.set_id(application_.data.application.id);
486         printf("OK\n");
487
488         printf("testing Application::set_data()... ");
489         block.set_data(application_.data.application.data, application_.length - sizeof(application_.data.application.id), /*copy=*/true);
490         printf("OK\n");
491
492         printf("testing Application::get_id()... ");
493         if(0 != memcmp(block.get_id(), application_.data.application.id, sizeof(application_.data.application.id)))
494                 return die_("value mismatch, doesn't match previously set value");
495         printf("OK\n");
496
497         printf("testing Application::get_data()... ");
498         if(0 != memcmp(block.get_data(), application_.data.application.data, application_.length - sizeof(application_.data.application.id)))
499                 return die_("value mismatch, doesn't match previously set value");
500         printf("OK\n");
501
502         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
503         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
504         if(0 == clone_)
505                 return die_("returned NULL");
506         if(0 == dynamic_cast<FLAC::Metadata::Application *>(clone_))
507                 return die_("downcast is NULL");
508         if(*dynamic_cast<FLAC::Metadata::Application *>(clone_) != block)
509                 return die_("clone is not identical");
510         printf("OK\n");
511
512
513         printf("PASSED\n\n");
514         return true;
515 }
516
517 bool test_metadata_object_seektable()
518 {
519         unsigned expected_length;
520
521         printf("testing class FLAC::Metadata::SeekTable\n");
522
523         printf("testing SeekTable::SeekTable()... ");
524         FLAC::Metadata::SeekTable block;
525         if(!block.is_valid())
526                 return die_("!block.is_valid()");
527         expected_length = 0;
528         if(block.get_length() != expected_length) {
529                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
530                 return false;
531         }
532         printf("OK\n");
533
534         printf("testing SeekTable::SeekTable(const SeekTable &)... +\n");
535         printf("        SeekTable::operator!=(const SeekTable &)... ");
536         {
537                 FLAC::Metadata::SeekTable blockcopy(block);
538                 if(!blockcopy.is_valid())
539                         return die_("!block.is_valid()");
540                 if(blockcopy != block)
541                         return die_("copy is not identical to original");
542                 printf("OK\n");
543
544                 printf("testing SeekTable::~SeekTable()... ");
545         }
546         printf("OK\n");
547
548         printf("testing SeekTable::SeekTable(const ::FLAC__StreamMetadata &)... +\n");
549         printf("        SeekTable::operator!=(const ::FLAC__StreamMetadata &)... ");
550         {
551                 FLAC::Metadata::SeekTable blockcopy(seektable_);
552                 if(!blockcopy.is_valid())
553                         return die_("!block.is_valid()");
554                 if(blockcopy != seektable_)
555                         return die_("copy is not identical to original");
556                 printf("OK\n");
557         }
558
559         printf("testing SeekTable::SeekTable(const ::FLAC__StreamMetadata *)... +\n");
560         printf("        SeekTable::operator!=(const ::FLAC__StreamMetadata *)... ");
561         {
562                 FLAC::Metadata::SeekTable blockcopy(&seektable_);
563                 if(!blockcopy.is_valid())
564                         return die_("!block.is_valid()");
565                 if(blockcopy != seektable_)
566                         return die_("copy is not identical to original");
567                 printf("OK\n");
568         }
569
570         printf("testing SeekTable::operator=(const SeekTable &)... +\n");
571         printf("        SeekTable::operator==(const SeekTable &)... ");
572         {
573                 FLAC::Metadata::SeekTable blockcopy = block;
574                 if(!blockcopy.is_valid())
575                         return die_("!block.is_valid()");
576                 if(!(blockcopy == block))
577                         return die_("copy is not identical to original");
578                 printf("OK\n");
579         }
580
581         printf("testing SeekTable::operator=(const ::FLAC__StreamMetadata &)... +\n");
582         printf("        SeekTable::operator==(const ::FLAC__StreamMetadata &)... ");
583         {
584                 FLAC::Metadata::SeekTable blockcopy = seektable_;
585                 if(!blockcopy.is_valid())
586                         return die_("!block.is_valid()");
587                 if(!(blockcopy == seektable_))
588                         return die_("copy is not identical to original");
589                 printf("OK\n");
590         }
591
592         printf("testing SeekTable::operator=(const ::FLAC__StreamMetadata *)... +\n");
593         printf("        SeekTable::operator==(const ::FLAC__StreamMetadata *)... ");
594         {
595                 FLAC::Metadata::SeekTable blockcopy = &seektable_;
596                 if(!blockcopy.is_valid())
597                         return die_("!block.is_valid()");
598                 if(!(blockcopy == seektable_))
599                         return die_("copy is not identical to original");
600                 printf("OK\n");
601         }
602
603         printf("testing SeekTable::insert_point() x 3... ");
604         if(!block.insert_point(0, seektable_.data.seek_table.points[1]))
605                 return die_("returned false");
606         if(!block.insert_point(0, seektable_.data.seek_table.points[1]))
607                 return die_("returned false");
608         if(!block.insert_point(1, seektable_.data.seek_table.points[0]))
609                 return die_("returned false");
610         printf("OK\n");
611
612         printf("testing SeekTable::is_legal()... ");
613         if(block.is_legal())
614                 return die_("returned true");
615         printf("OK\n");
616
617         printf("testing SeekTable::set_point()... ");
618         block.set_point(0, seektable_.data.seek_table.points[0]);
619         printf("OK\n");
620
621         printf("testing SeekTable::delete_point()... ");
622         if(!block.delete_point(0))
623                 return die_("returned false");
624         printf("OK\n");
625
626         printf("testing SeekTable::is_legal()... ");
627         if(!block.is_legal())
628                 return die_("returned false");
629         printf("OK\n");
630
631         printf("testing SeekTable::get_num_points()... ");
632         if(block.get_num_points() != seektable_.data.seek_table.num_points)
633                 return die_("number mismatch");
634         printf("OK\n");
635
636         printf("testing SeekTable::operator!=(const ::FLAC__StreamMetadata &)... ");
637         if(block != seektable_)
638                 return die_("data mismatch");
639         printf("OK\n");
640
641         printf("testing SeekTable::get_point()... ");
642         if(
643                 block.get_point(1).sample_number != seektable_.data.seek_table.points[1].sample_number ||
644                 block.get_point(1).stream_offset != seektable_.data.seek_table.points[1].stream_offset ||
645                 block.get_point(1).frame_samples != seektable_.data.seek_table.points[1].frame_samples
646         )
647                 return die_("point mismatch");
648         printf("OK\n");
649
650         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
651         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
652         if(0 == clone_)
653                 return die_("returned NULL");
654         if(0 == dynamic_cast<FLAC::Metadata::SeekTable *>(clone_))
655                 return die_("downcast is NULL");
656         if(*dynamic_cast<FLAC::Metadata::SeekTable *>(clone_) != block)
657                 return die_("clone is not identical");
658         printf("OK\n");
659
660
661         printf("PASSED\n\n");
662         return true;
663 }
664
665 bool test_metadata_object_vorbiscomment()
666 {
667         unsigned expected_length;
668
669         printf("testing class FLAC::Metadata::VorbisComment::Entry\n");
670
671         printf("testing Entry::Entry()... ");
672         {
673                 FLAC::Metadata::VorbisComment::Entry entry1;
674                 if(!entry1.is_valid())
675                         return die_("!is_valid()");
676                 printf("OK\n");
677
678                 printf("testing Entry::~Entry()... ");
679         }
680         printf("OK\n");
681
682         printf("testing Entry::Entry(const char *field, unsigned field_length)... ");
683         FLAC::Metadata::VorbisComment::Entry entry2("name2=value2", strlen("name2=value2"));
684         if(!entry2.is_valid())
685                 return die_("!is_valid()");
686         printf("OK\n");
687
688         printf("testing Entry::Entry(const char *field_name, const char *field_value, unsigned field_value_length)... ");
689         FLAC::Metadata::VorbisComment::Entry entry3("name3", "value3", strlen("value3"));
690         if(!entry3.is_valid())
691                 return die_("!is_valid()");
692         printf("OK\n");
693
694         printf("testing Entry::Entry(const Entry &entry)... ");
695         {
696                 FLAC::Metadata::VorbisComment::Entry entry2copy(entry2);
697                 if(!entry2copy.is_valid())
698                         return die_("!is_valid()");
699                 printf("OK\n");
700
701                 printf("testing Entry::~Entry()... ");
702         }
703         printf("OK\n");
704
705         printf("testing Entry::operator=(const Entry &entry)... ");
706         FLAC::Metadata::VorbisComment::Entry entry1 = entry2;
707         if(!entry2.is_valid())
708                 return die_("!is_valid()");
709         printf("OK\n");
710
711         printf("testing Entry::get_field_length()... ");
712         if(entry1.get_field_length() != strlen("name2=value2"))
713                 return die_("value mismatch");
714         printf("OK\n");
715
716         printf("testing Entry::get_field_name_length()... ");
717         if(entry1.get_field_name_length() != strlen("name2"))
718                 return die_("value mismatch");
719         printf("OK\n");
720
721         printf("testing Entry::get_field_value_length()... ");
722         if(entry1.get_field_value_length() != strlen("value2"))
723                 return die_("value mismatch");
724         printf("OK\n");
725
726         printf("testing Entry::get_entry()... ");
727         {
728                 ::FLAC__StreamMetadata_VorbisComment_Entry entry = entry1.get_entry();
729                 if(entry.length != strlen("name2=value2"))
730                         return die_("entry length mismatch");
731                 if(0 != memcmp(entry.entry, "name2=value2", entry.length))
732                         return die_("entry value mismatch");
733         }
734         printf("OK\n");
735
736         printf("testing Entry::get_field()... ");
737         if(0 != memcmp(entry1.get_field(), "name2=value2", strlen("name2=value2")))
738                 return die_("value mismatch");
739         printf("OK\n");
740
741         printf("testing Entry::get_field_name()... ");
742         if(0 != memcmp(entry1.get_field_name(), "name2", strlen("name2")))
743                 return die_("value mismatch");
744         printf("OK\n");
745
746         printf("testing Entry::get_field_value()... ");
747         if(0 != memcmp(entry1.get_field_value(), "value2", strlen("value2")))
748                 return die_("value mismatch");
749         printf("OK\n");
750
751         printf("testing Entry::set_field_name()... ");
752         if(!entry1.set_field_name("name1"))
753                 return die_("returned false");
754         if(0 != memcmp(entry1.get_field_name(), "name1", strlen("name1")))
755                 return die_("value mismatch");
756         if(0 != memcmp(entry1.get_field(), "name1=value2", strlen("name1=value2")))
757                 return die_("entry mismatch");
758         printf("OK\n");
759
760         printf("testing Entry::set_field_value()... ");
761         if(!entry1.set_field_value("value1", strlen("value1")))
762                 return die_("returned false");
763         if(0 != memcmp(entry1.get_field_value(), "value1", strlen("value1")))
764                 return die_("value mismatch");
765         if(0 != memcmp(entry1.get_field(), "name1=value1", strlen("name1=value1")))
766                 return die_("entry mismatch");
767         printf("OK\n");
768
769         printf("testing Entry::set_field()... ");
770         if(!entry1.set_field("name0=value0", strlen("name0=value0")))
771                 return die_("returned false");
772         if(0 != memcmp(entry1.get_field_name(), "name0", strlen("name0")))
773                 return die_("value mismatch");
774         if(0 != memcmp(entry1.get_field_value(), "value0", strlen("value0")))
775                 return die_("value mismatch");
776         if(0 != memcmp(entry1.get_field(), "name0=value0", strlen("name0=value0")))
777                 return die_("entry mismatch");
778         printf("OK\n");
779
780         printf("PASSED\n\n");
781
782
783         printf("testing class FLAC::Metadata::VorbisComment\n");
784
785         printf("testing VorbisComment::VorbisComment()... ");
786         FLAC::Metadata::VorbisComment block;
787         if(!block.is_valid())
788                 return die_("!block.is_valid()");
789         expected_length = (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN + FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8;
790         if(block.get_length() != expected_length) {
791                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
792                 return false;
793         }
794         printf("OK\n");
795
796         printf("testing VorbisComment::VorbisComment(const VorbisComment &)... +\n");
797         printf("        VorbisComment::operator!=(const VorbisComment &)... ");
798         {
799                 FLAC::Metadata::VorbisComment blockcopy(block);
800                 if(!blockcopy.is_valid())
801                         return die_("!block.is_valid()");
802                 if(blockcopy != block)
803                         return die_("copy is not identical to original");
804                 printf("OK\n");
805
806                 printf("testing VorbisComment::~VorbisComment()... ");
807         }
808         printf("OK\n");
809
810         printf("testing VorbisComment::VorbisComment(const ::FLAC__StreamMetadata &)... +\n");
811         printf("        VorbisComment::operator!=(const ::FLAC__StreamMetadata &)... ");
812         {
813                 FLAC::Metadata::VorbisComment blockcopy(vorbiscomment_);
814                 if(!blockcopy.is_valid())
815                         return die_("!block.is_valid()");
816                 if(blockcopy != vorbiscomment_)
817                         return die_("copy is not identical to original");
818                 printf("OK\n");
819         }
820
821         printf("testing VorbisComment::VorbisComment(const ::FLAC__StreamMetadata *)... +\n");
822         printf("        VorbisComment::operator!=(const ::FLAC__StreamMetadata *)... ");
823         {
824                 FLAC::Metadata::VorbisComment blockcopy(&vorbiscomment_);
825                 if(!blockcopy.is_valid())
826                         return die_("!block.is_valid()");
827                 if(blockcopy != vorbiscomment_)
828                         return die_("copy is not identical to original");
829                 printf("OK\n");
830         }
831
832         printf("testing VorbisComment::operator=(const VorbisComment &)... +\n");
833         printf("        VorbisComment::operator==(const VorbisComment &)... ");
834         {
835                 FLAC::Metadata::VorbisComment blockcopy = block;
836                 if(!blockcopy.is_valid())
837                         return die_("!block.is_valid()");
838                 if(!(blockcopy == block))
839                         return die_("copy is not identical to original");
840                 printf("OK\n");
841         }
842
843         printf("testing VorbisComment::operator=(const ::FLAC__StreamMetadata &)... +\n");
844         printf("        VorbisComment::operator==(const ::FLAC__StreamMetadata &)... ");
845         {
846                 FLAC::Metadata::VorbisComment blockcopy = vorbiscomment_;
847                 if(!blockcopy.is_valid())
848                         return die_("!block.is_valid()");
849                 if(!(blockcopy == vorbiscomment_))
850                         return die_("copy is not identical to original");
851                 printf("OK\n");
852         }
853
854         printf("testing VorbisComment::operator=(const ::FLAC__StreamMetadata *)... +\n");
855         printf("        VorbisComment::operator==(const ::FLAC__StreamMetadata *)... ");
856         {
857                 FLAC::Metadata::VorbisComment blockcopy = &vorbiscomment_;
858                 if(!blockcopy.is_valid())
859                         return die_("!block.is_valid()");
860                 if(!(blockcopy == vorbiscomment_))
861                         return die_("copy is not identical to original");
862                 printf("OK\n");
863         }
864
865         printf("testing VorbisComment::get_num_comments()... ");
866         if(block.get_num_comments() != 0)
867                 return die_("value mismatch, expected 0");
868         printf("OK\n");
869
870         printf("testing VorbisComment::set_vendor_string()... ");
871         if(!block.set_vendor_string(entry1))
872                 return die_("returned false");
873         printf("OK\n");
874
875         printf("testing VorbisComment::get_vendor_string()... ");
876         if(block.get_vendor_string().get_field_name_length() != vorbiscomment_.data.vorbis_comment.vendor_string.length)
877                 return die_("length mismatch");
878         if(0 != memcmp(block.get_vendor_string().get_field_name(), vorbiscomment_.data.vorbis_comment.vendor_string.entry, vorbiscomment_.data.vorbis_comment.vendor_string.length))
879                 return die_("value mismatch");
880         printf("OK\n");
881
882         printf("testing VorbisComment::insert_comment()... +\n");
883         printf("        VorbisComment::get_comment()... ");
884         if(!block.insert_comment(0, entry3))
885                 return die_("returned false");
886         if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[1].length)
887                 return die_("length mismatch");
888         if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[1].entry, vorbiscomment_.data.vorbis_comment.comments[1].length))
889                 return die_("value mismatch");
890         printf("OK\n");
891
892         printf("testing VorbisComment::insert_comment()... +\n");
893         printf("        VorbisComment::get_comment()... ");
894         if(!block.insert_comment(0, entry3))
895                 return die_("returned false");
896         if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[1].length)
897                 return die_("length mismatch");
898         if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[1].entry, vorbiscomment_.data.vorbis_comment.comments[1].length))
899                 return die_("value mismatch");
900         printf("OK\n");
901
902         printf("testing VorbisComment::insert_comment()... +\n");
903         printf("        VorbisComment::get_comment()... ");
904         if(!block.insert_comment(1, entry2))
905                 return die_("returned false");
906         if(block.get_comment(1).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[0].length)
907                 return die_("length mismatch");
908         if(0 != memcmp(block.get_comment(1).get_field(), vorbiscomment_.data.vorbis_comment.comments[0].entry, vorbiscomment_.data.vorbis_comment.comments[0].length))
909                 return die_("value mismatch");
910         printf("OK\n");
911
912         printf("testing VorbisComment::set_comment()... +\n");
913         printf("        VorbisComment::get_comment()... ");
914         if(!block.set_comment(0, entry2))
915                 return die_("returned false");
916         if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[0].length)
917                 return die_("length mismatch");
918         if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[0].entry, vorbiscomment_.data.vorbis_comment.comments[0].length))
919                 return die_("value mismatch");
920         printf("OK\n");
921
922         printf("testing VorbisComment::delete_comment()... +\n");
923         printf("        VorbisComment::get_comment()... ");
924         if(!block.delete_comment(0))
925                 return die_("returned false");
926         if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[0].length)
927                 return die_("length[0] mismatch");
928         if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[0].entry, vorbiscomment_.data.vorbis_comment.comments[0].length))
929                 return die_("value[0] mismatch");
930         if(block.get_comment(1).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[1].length)
931                 return die_("length[1] mismatch");
932         if(0 != memcmp(block.get_comment(1).get_field(), vorbiscomment_.data.vorbis_comment.comments[1].entry, vorbiscomment_.data.vorbis_comment.comments[1].length))
933                 return die_("value[0] mismatch");
934         printf("OK\n");
935
936         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
937         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
938         if(0 == clone_)
939                 return die_("returned NULL");
940         if(0 == dynamic_cast<FLAC::Metadata::VorbisComment *>(clone_))
941                 return die_("downcast is NULL");
942         if(*dynamic_cast<FLAC::Metadata::VorbisComment *>(clone_) != block)
943                 return die_("clone is not identical");
944         printf("OK\n");
945
946
947         printf("PASSED\n\n");
948         return true;
949 }
950
951 bool test_metadata_object()
952 {
953         printf("\n+++ libFLAC++ unit test: metadata objects\n\n");
954
955         init_metadata_blocks_();
956
957         if(!test_metadata_object_streaminfo())
958                 return false;
959
960         if(!test_metadata_object_padding())
961                 return false;
962
963         if(!test_metadata_object_application())
964                 return false;
965
966         if(!test_metadata_object_seektable())
967                 return false;
968
969         if(!test_metadata_object_vorbiscomment())
970                 return false;
971
972         free_metadata_blocks_();
973
974         return true;
975 }