fix bug: source file needs to be explicitly rewound before reading/writing in callbac...
[flac.git] / src / test_libFLAC++ / metadata_object.cpp
1 /* test_libFLAC++ - Unit tester for libFLAC++
2  * Copyright (C) 2002,2003,2004  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_, cuesheet_;
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 bool index_is_equal_(const ::FLAC__StreamMetadata_CueSheet_Index &index, const ::FLAC__StreamMetadata_CueSheet_Index &indexcopy)
44 {
45         if(indexcopy.offset != index.offset)
46                 return false;
47         if(indexcopy.number != index.number)
48                 return false;
49         return true;
50 }
51
52 static bool track_is_equal_(const ::FLAC__StreamMetadata_CueSheet_Track *track, const ::FLAC__StreamMetadata_CueSheet_Track *trackcopy)
53 {
54         unsigned i;
55
56         if(trackcopy->offset != track->offset)
57                 return false;
58         if(trackcopy->number != track->number)
59                 return false;
60         if(0 != strcmp(trackcopy->isrc, track->isrc))
61                 return false;
62         if(trackcopy->type != track->type)
63                 return false;
64         if(trackcopy->pre_emphasis != track->pre_emphasis)
65                 return false;
66         if(trackcopy->num_indices != track->num_indices)
67                 return false;
68         if(0 == track->indices || 0 == trackcopy->indices) {
69                 if(track->indices != trackcopy->indices)
70                         return false;
71         }
72         else {
73                 for(i = 0; i < track->num_indices; i++) {
74                         if(!index_is_equal_(trackcopy->indices[i], track->indices[i]))
75                                 return false;
76                 }
77         }
78         return true;
79 }
80
81 static void init_metadata_blocks_()
82 {
83         streaminfo_.is_last = false;
84         streaminfo_.type = ::FLAC__METADATA_TYPE_STREAMINFO;
85         streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
86         streaminfo_.data.stream_info.min_blocksize = 576;
87         streaminfo_.data.stream_info.max_blocksize = 576;
88         streaminfo_.data.stream_info.min_framesize = 0;
89         streaminfo_.data.stream_info.max_framesize = 0;
90         streaminfo_.data.stream_info.sample_rate = 44100;
91         streaminfo_.data.stream_info.channels = 1;
92         streaminfo_.data.stream_info.bits_per_sample = 8;
93         streaminfo_.data.stream_info.total_samples = 0;
94         memset(streaminfo_.data.stream_info.md5sum, 0, 16);
95
96         padding_.is_last = false;
97         padding_.type = ::FLAC__METADATA_TYPE_PADDING;
98         padding_.length = 1234;
99
100         seektable_.is_last = false;
101         seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE;
102         seektable_.data.seek_table.num_points = 2;
103         seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
104         seektable_.data.seek_table.points = (::FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetadata_SeekPoint));
105         seektable_.data.seek_table.points[0].sample_number = 0;
106         seektable_.data.seek_table.points[0].stream_offset = 0;
107         seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
108         seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
109         seektable_.data.seek_table.points[1].stream_offset = 1000;
110         seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
111
112         application_.is_last = false;
113         application_.type = ::FLAC__METADATA_TYPE_APPLICATION;
114         application_.length = 8;
115         memcpy(application_.data.application.id, "\xfe\xdc\xba\x98", 4);
116         application_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
117         memcpy(application_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
118
119         vorbiscomment_.is_last = false;
120         vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT;
121         vorbiscomment_.length = (4 + 5) + 4 + (4 + 12) + (4 + 12);
122         vorbiscomment_.data.vorbis_comment.vendor_string.length = 5;
123         vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(5);
124         memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "name0", 5);
125         vorbiscomment_.data.vorbis_comment.num_comments = 2;
126         vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetadata_VorbisComment_Entry));
127         vorbiscomment_.data.vorbis_comment.comments[0].length = 12;
128         vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(12);
129         memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "name2=value2", 12);
130         vorbiscomment_.data.vorbis_comment.comments[1].length = 12;
131         vorbiscomment_.data.vorbis_comment.comments[1].entry = (FLAC__byte*)malloc_or_die_(12);
132         memcpy(vorbiscomment_.data.vorbis_comment.comments[1].entry, "name3=value3", 12);
133
134         cuesheet_.is_last = true;
135         cuesheet_.type = ::FLAC__METADATA_TYPE_CUESHEET;
136         cuesheet_.length =
137                 /* cuesheet guts */
138                 (
139                         FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN +
140                         FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN +
141                         FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN +
142                         FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN +
143                         FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN
144                 ) / 8 +
145                 /* 2 tracks */
146                 2 * (
147                         FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN +
148                         FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN +
149                         FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN +
150                         FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN +
151                         FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN +
152                         FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN +
153                         FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN
154                 ) / 8 +
155                 /* 3 index points */
156                 3 * (
157                         FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN +
158                         FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN +
159                         FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN
160                 ) / 8
161         ;
162         memset(cuesheet_.data.cue_sheet.media_catalog_number, 0, sizeof(cuesheet_.data.cue_sheet.media_catalog_number));
163         cuesheet_.data.cue_sheet.media_catalog_number[0] = 'j';
164         cuesheet_.data.cue_sheet.media_catalog_number[1] = 'C';
165         cuesheet_.data.cue_sheet.lead_in = 159;
166         cuesheet_.data.cue_sheet.is_cd = true;
167         cuesheet_.data.cue_sheet.num_tracks = 2;
168         cuesheet_.data.cue_sheet.tracks = (FLAC__StreamMetadata_CueSheet_Track*)malloc_or_die_(cuesheet_.data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track));
169         cuesheet_.data.cue_sheet.tracks[0].offset = 1;
170         cuesheet_.data.cue_sheet.tracks[0].number = 1;
171         memcpy(cuesheet_.data.cue_sheet.tracks[0].isrc, "ACBDE1234567", sizeof(cuesheet_.data.cue_sheet.tracks[0].isrc));
172         cuesheet_.data.cue_sheet.tracks[0].type = 0;
173         cuesheet_.data.cue_sheet.tracks[0].pre_emphasis = 1;
174         cuesheet_.data.cue_sheet.tracks[0].num_indices = 2;
175         cuesheet_.data.cue_sheet.tracks[0].indices = (FLAC__StreamMetadata_CueSheet_Index*)malloc_or_die_(cuesheet_.data.cue_sheet.tracks[0].num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
176         cuesheet_.data.cue_sheet.tracks[0].indices[0].offset = 0;
177         cuesheet_.data.cue_sheet.tracks[0].indices[0].number = 0;
178         cuesheet_.data.cue_sheet.tracks[0].indices[1].offset = 1234567890;
179         cuesheet_.data.cue_sheet.tracks[0].indices[1].number = 1;
180         cuesheet_.data.cue_sheet.tracks[1].offset = 2345678901u;
181         cuesheet_.data.cue_sheet.tracks[1].number = 2;
182         memcpy(cuesheet_.data.cue_sheet.tracks[1].isrc, "ACBDE7654321", sizeof(cuesheet_.data.cue_sheet.tracks[1].isrc));
183         cuesheet_.data.cue_sheet.tracks[1].type = 1;
184         cuesheet_.data.cue_sheet.tracks[1].pre_emphasis = 0;
185         cuesheet_.data.cue_sheet.tracks[1].num_indices = 1;
186         cuesheet_.data.cue_sheet.tracks[1].indices = (FLAC__StreamMetadata_CueSheet_Index*)malloc_or_die_(cuesheet_.data.cue_sheet.tracks[1].num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
187         cuesheet_.data.cue_sheet.tracks[1].indices[0].offset = 0;
188         cuesheet_.data.cue_sheet.tracks[1].indices[0].number = 1;
189 }
190
191 static void free_metadata_blocks_()
192 {
193         free(seektable_.data.seek_table.points);
194         free(application_.data.application.data);
195         free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
196         free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
197         free(vorbiscomment_.data.vorbis_comment.comments[1].entry);
198         free(vorbiscomment_.data.vorbis_comment.comments);
199         free(cuesheet_.data.cue_sheet.tracks[0].indices);
200         free(cuesheet_.data.cue_sheet.tracks[1].indices);
201         free(cuesheet_.data.cue_sheet.tracks);
202 }
203
204 bool test_metadata_object_streaminfo()
205 {
206         unsigned expected_length;
207
208         printf("testing class FLAC::Metadata::StreamInfo\n");
209
210         printf("testing StreamInfo::StreamInfo()... ");
211         FLAC::Metadata::StreamInfo block;
212         if(!block.is_valid())
213                 return die_("!block.is_valid()");
214         expected_length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
215         if(block.get_length() != expected_length) {
216                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
217                 return false;
218         }
219         printf("OK\n");
220
221         printf("testing StreamInfo::StreamInfo(const StreamInfo &)... +\n");
222         printf("        StreamInfo::operator!=(const StreamInfo &)... ");
223         {
224                 FLAC::Metadata::StreamInfo blockcopy(block);
225                 if(!blockcopy.is_valid())
226                         return die_("!block.is_valid()");
227                 if(blockcopy != block)
228                         return die_("copy is not identical to original");
229                 printf("OK\n");
230
231                 printf("testing StreamInfo::~StreamInfo()... ");
232         }
233         printf("OK\n");
234
235         printf("testing StreamInfo::StreamInfo(const ::FLAC__StreamMetadata &)... +\n");
236         printf("        StreamInfo::operator!=(const ::FLAC__StreamMetadata &)... ");
237         {
238                 FLAC::Metadata::StreamInfo blockcopy(streaminfo_);
239                 if(!blockcopy.is_valid())
240                         return die_("!block.is_valid()");
241                 if(blockcopy != streaminfo_)
242                         return die_("copy is not identical to original");
243                 printf("OK\n");
244         }
245
246         printf("testing StreamInfo::StreamInfo(const ::FLAC__StreamMetadata *)... +\n");
247         printf("        StreamInfo::operator!=(const ::FLAC__StreamMetadata *)... ");
248         {
249                 FLAC::Metadata::StreamInfo blockcopy(&streaminfo_);
250                 if(!blockcopy.is_valid())
251                         return die_("!block.is_valid()");
252                 if(blockcopy != streaminfo_)
253                         return die_("copy is not identical to original");
254                 printf("OK\n");
255         }
256
257         printf("testing StreamInfo::operator=(const StreamInfo &)... +\n");
258         printf("        StreamInfo::operator==(const StreamInfo &)... ");
259         {
260                 FLAC::Metadata::StreamInfo blockcopy = block;
261                 if(!blockcopy.is_valid())
262                         return die_("!block.is_valid()");
263                 if(!(blockcopy == block))
264                         return die_("copy is not identical to original");
265                 printf("OK\n");
266         }
267
268         printf("testing StreamInfo::operator=(const ::FLAC__StreamMetadata &)... +\n");
269         printf("        StreamInfo::operator==(const ::FLAC__StreamMetadata &)... ");
270         {
271                 FLAC::Metadata::StreamInfo blockcopy = streaminfo_;
272                 if(!blockcopy.is_valid())
273                         return die_("!block.is_valid()");
274                 if(!(blockcopy == streaminfo_))
275                         return die_("copy is not identical to original");
276                 printf("OK\n");
277         }
278
279         printf("testing StreamInfo::operator=(const ::FLAC__StreamMetadata *)... +\n");
280         printf("        StreamInfo::operator==(const ::FLAC__StreamMetadata *)... ");
281         {
282                 FLAC::Metadata::StreamInfo blockcopy = &streaminfo_;
283                 if(!blockcopy.is_valid())
284                         return die_("!block.is_valid()");
285                 if(!(blockcopy == streaminfo_))
286                         return die_("copy is not identical to original");
287                 printf("OK\n");
288         }
289
290         printf("testing StreamInfo::set_min_blocksize()... ");
291         block.set_min_blocksize(streaminfo_.data.stream_info.min_blocksize);
292         printf("OK\n");
293
294         printf("testing StreamInfo::set_max_blocksize()... ");
295         block.set_max_blocksize(streaminfo_.data.stream_info.max_blocksize);
296         printf("OK\n");
297
298         printf("testing StreamInfo::set_min_framesize()... ");
299         block.set_min_framesize(streaminfo_.data.stream_info.min_framesize);
300         printf("OK\n");
301
302         printf("testing StreamInfo::set_max_framesize()... ");
303         block.set_max_framesize(streaminfo_.data.stream_info.max_framesize);
304         printf("OK\n");
305
306         printf("testing StreamInfo::set_sample_rate()... ");
307         block.set_sample_rate(streaminfo_.data.stream_info.sample_rate);
308         printf("OK\n");
309
310         printf("testing StreamInfo::set_channels()... ");
311         block.set_channels(streaminfo_.data.stream_info.channels);
312         printf("OK\n");
313
314         printf("testing StreamInfo::set_bits_per_sample()... ");
315         block.set_bits_per_sample(streaminfo_.data.stream_info.bits_per_sample);
316         printf("OK\n");
317
318         printf("testing StreamInfo::set_total_samples()... ");
319         block.set_total_samples(streaminfo_.data.stream_info.total_samples);
320         printf("OK\n");
321
322         printf("testing StreamInfo::set_md5sum()... ");
323         block.set_md5sum(streaminfo_.data.stream_info.md5sum);
324         printf("OK\n");
325
326         printf("testing StreamInfo::get_min_blocksize()... ");
327         if(block.get_min_blocksize() != streaminfo_.data.stream_info.min_blocksize)
328                 return die_("value mismatch, doesn't match previously set value");
329         printf("OK\n");
330
331         printf("testing StreamInfo::get_max_blocksize()... ");
332         if(block.get_max_blocksize() != streaminfo_.data.stream_info.max_blocksize)
333                 return die_("value mismatch, doesn't match previously set value");
334         printf("OK\n");
335
336         printf("testing StreamInfo::get_min_framesize()... ");
337         if(block.get_min_framesize() != streaminfo_.data.stream_info.min_framesize)
338                 return die_("value mismatch, doesn't match previously set value");
339         printf("OK\n");
340
341         printf("testing StreamInfo::get_max_framesize()... ");
342         if(block.get_max_framesize() != streaminfo_.data.stream_info.max_framesize)
343                 return die_("value mismatch, doesn't match previously set value");
344         printf("OK\n");
345
346         printf("testing StreamInfo::get_sample_rate()... ");
347         if(block.get_sample_rate() != streaminfo_.data.stream_info.sample_rate)
348                 return die_("value mismatch, doesn't match previously set value");
349         printf("OK\n");
350
351         printf("testing StreamInfo::get_channels()... ");
352         if(block.get_channels() != streaminfo_.data.stream_info.channels)
353                 return die_("value mismatch, doesn't match previously set value");
354         printf("OK\n");
355
356         printf("testing StreamInfo::get_bits_per_sample()... ");
357         if(block.get_bits_per_sample() != streaminfo_.data.stream_info.bits_per_sample)
358                 return die_("value mismatch, doesn't match previously set value");
359         printf("OK\n");
360
361         printf("testing StreamInfo::get_total_samples()... ");
362         if(block.get_total_samples() != streaminfo_.data.stream_info.total_samples)
363                 return die_("value mismatch, doesn't match previously set value");
364         printf("OK\n");
365
366         printf("testing StreamInfo::get_md5sum()... ");
367         if(0 != memcmp(block.get_md5sum(), streaminfo_.data.stream_info.md5sum, 16))
368                 return die_("value mismatch, doesn't match previously set value");
369         printf("OK\n");
370
371         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
372         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
373         if(0 == clone_)
374                 return die_("returned NULL");
375         if(0 == dynamic_cast<FLAC::Metadata::StreamInfo *>(clone_))
376                 return die_("downcast is NULL");
377         if(*dynamic_cast<FLAC::Metadata::StreamInfo *>(clone_) != block)
378                 return die_("clone is not identical");
379         printf("OK\n");
380         printf("testing StreamInfo::~StreamInfo()... ");
381         delete clone_;
382         printf("OK\n");
383
384
385         printf("PASSED\n\n");
386         return true;
387 }
388
389 bool test_metadata_object_padding()
390 {
391         unsigned expected_length;
392
393         printf("testing class FLAC::Metadata::Padding\n");
394
395         printf("testing Padding::Padding()... ");
396         FLAC::Metadata::Padding block;
397         if(!block.is_valid())
398                 return die_("!block.is_valid()");
399         expected_length = 0;
400         if(block.get_length() != expected_length) {
401                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
402                 return false;
403         }
404         printf("OK\n");
405
406         printf("testing Padding::Padding(const Padding &)... +\n");
407         printf("        Padding::operator!=(const Padding &)... ");
408         {
409                 FLAC::Metadata::Padding blockcopy(block);
410                 if(!blockcopy.is_valid())
411                         return die_("!block.is_valid()");
412                 if(blockcopy != block)
413                         return die_("copy is not identical to original");
414                 printf("OK\n");
415
416                 printf("testing Padding::~Padding()... ");
417         }
418         printf("OK\n");
419
420         printf("testing Padding::Padding(const ::FLAC__StreamMetadata &)... +\n");
421         printf("        Padding::operator!=(const ::FLAC__StreamMetadata &)... ");
422         {
423                 FLAC::Metadata::Padding blockcopy(padding_);
424                 if(!blockcopy.is_valid())
425                         return die_("!block.is_valid()");
426                 if(blockcopy != padding_)
427                         return die_("copy is not identical to original");
428                 printf("OK\n");
429         }
430
431         printf("testing Padding::Padding(const ::FLAC__StreamMetadata *)... +\n");
432         printf("        Padding::operator!=(const ::FLAC__StreamMetadata *)... ");
433         {
434                 FLAC::Metadata::Padding blockcopy(&padding_);
435                 if(!blockcopy.is_valid())
436                         return die_("!block.is_valid()");
437                 if(blockcopy != padding_)
438                         return die_("copy is not identical to original");
439                 printf("OK\n");
440         }
441
442         printf("testing Padding::operator=(const Padding &)... +\n");
443         printf("        Padding::operator==(const Padding &)... ");
444         {
445                 FLAC::Metadata::Padding blockcopy = block;
446                 if(!blockcopy.is_valid())
447                         return die_("!block.is_valid()");
448                 if(!(blockcopy == block))
449                         return die_("copy is not identical to original");
450                 printf("OK\n");
451         }
452
453         printf("testing Padding::operator=(const ::FLAC__StreamMetadata &)... +\n");
454         printf("        Padding::operator==(const ::FLAC__StreamMetadata &)... ");
455         {
456                 FLAC::Metadata::Padding blockcopy = padding_;
457                 if(!blockcopy.is_valid())
458                         return die_("!block.is_valid()");
459                 if(!(blockcopy == padding_))
460                         return die_("copy is not identical to original");
461                 printf("OK\n");
462         }
463
464         printf("testing Padding::operator=(const ::FLAC__StreamMetadata *)... +\n");
465         printf("        Padding::operator==(const ::FLAC__StreamMetadata *)... ");
466         {
467                 FLAC::Metadata::Padding blockcopy = &padding_;
468                 if(!blockcopy.is_valid())
469                         return die_("!block.is_valid()");
470                 if(!(blockcopy == padding_))
471                         return die_("copy is not identical to original");
472                 printf("OK\n");
473         }
474
475         printf("testing Padding::set_length()... ");
476         block.set_length(padding_.length);
477         printf("OK\n");
478
479         printf("testing Prototype::get_length()... ");
480         if(block.get_length() != padding_.length)
481                 return die_("value mismatch, doesn't match previously set value");
482         printf("OK\n");
483
484         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
485         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
486         if(0 == clone_)
487                 return die_("returned NULL");
488         if(0 == dynamic_cast<FLAC::Metadata::Padding *>(clone_))
489                 return die_("downcast is NULL");
490         if(*dynamic_cast<FLAC::Metadata::Padding *>(clone_) != block)
491                 return die_("clone is not identical");
492         printf("OK\n");
493         printf("testing Padding::~Padding()... ");
494         delete clone_;
495         printf("OK\n");
496
497
498         printf("PASSED\n\n");
499         return true;
500 }
501
502 bool test_metadata_object_application()
503 {
504         unsigned expected_length;
505
506         printf("testing class FLAC::Metadata::Application\n");
507
508         printf("testing Application::Application()... ");
509         FLAC::Metadata::Application block;
510         if(!block.is_valid())
511                 return die_("!block.is_valid()");
512         expected_length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
513         if(block.get_length() != expected_length) {
514                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
515                 return false;
516         }
517         printf("OK\n");
518
519         printf("testing Application::Application(const Application &)... +\n");
520         printf("        Application::operator!=(const Application &)... ");
521         {
522                 FLAC::Metadata::Application blockcopy(block);
523                 if(!blockcopy.is_valid())
524                         return die_("!block.is_valid()");
525                 if(blockcopy != block)
526                         return die_("copy is not identical to original");
527                 printf("OK\n");
528
529                 printf("testing Application::~Application()... ");
530         }
531         printf("OK\n");
532
533         printf("testing Application::Application(const ::FLAC__StreamMetadata &)... +\n");
534         printf("        Application::operator!=(const ::FLAC__StreamMetadata &)... ");
535         {
536                 FLAC::Metadata::Application blockcopy(application_);
537                 if(!blockcopy.is_valid())
538                         return die_("!block.is_valid()");
539                 if(blockcopy != application_)
540                         return die_("copy is not identical to original");
541                 printf("OK\n");
542         }
543
544         printf("testing Application::Application(const ::FLAC__StreamMetadata *)... +\n");
545         printf("        Application::operator!=(const ::FLAC__StreamMetadata *)... ");
546         {
547                 FLAC::Metadata::Application blockcopy(&application_);
548                 if(!blockcopy.is_valid())
549                         return die_("!block.is_valid()");
550                 if(blockcopy != application_)
551                         return die_("copy is not identical to original");
552                 printf("OK\n");
553         }
554
555         printf("testing Application::operator=(const Application &)... +\n");
556         printf("        Application::operator==(const Application &)... ");
557         {
558                 FLAC::Metadata::Application blockcopy = block;
559                 if(!blockcopy.is_valid())
560                         return die_("!block.is_valid()");
561                 if(!(blockcopy == block))
562                         return die_("copy is not identical to original");
563                 printf("OK\n");
564         }
565
566         printf("testing Application::operator=(const ::FLAC__StreamMetadata &)... +\n");
567         printf("        Application::operator==(const ::FLAC__StreamMetadata &)... ");
568         {
569                 FLAC::Metadata::Application blockcopy = application_;
570                 if(!blockcopy.is_valid())
571                         return die_("!block.is_valid()");
572                 if(!(blockcopy == application_))
573                         return die_("copy is not identical to original");
574                 printf("OK\n");
575         }
576
577         printf("testing Application::operator=(const ::FLAC__StreamMetadata *)... +\n");
578         printf("        Application::operator==(const ::FLAC__StreamMetadata *)... ");
579         {
580                 FLAC::Metadata::Application blockcopy = &application_;
581                 if(!blockcopy.is_valid())
582                         return die_("!block.is_valid()");
583                 if(!(blockcopy == application_))
584                         return die_("copy is not identical to original");
585                 printf("OK\n");
586         }
587
588         printf("testing Application::set_id()... ");
589         block.set_id(application_.data.application.id);
590         printf("OK\n");
591
592         printf("testing Application::set_data()... ");
593         block.set_data(application_.data.application.data, application_.length - sizeof(application_.data.application.id), /*copy=*/true);
594         printf("OK\n");
595
596         printf("testing Application::get_id()... ");
597         if(0 != memcmp(block.get_id(), application_.data.application.id, sizeof(application_.data.application.id)))
598                 return die_("value mismatch, doesn't match previously set value");
599         printf("OK\n");
600
601         printf("testing Application::get_data()... ");
602         if(0 != memcmp(block.get_data(), application_.data.application.data, application_.length - sizeof(application_.data.application.id)))
603                 return die_("value mismatch, doesn't match previously set value");
604         printf("OK\n");
605
606         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
607         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
608         if(0 == clone_)
609                 return die_("returned NULL");
610         if(0 == dynamic_cast<FLAC::Metadata::Application *>(clone_))
611                 return die_("downcast is NULL");
612         if(*dynamic_cast<FLAC::Metadata::Application *>(clone_) != block)
613                 return die_("clone is not identical");
614         printf("OK\n");
615         printf("testing Application::~Application()... ");
616         delete clone_;
617         printf("OK\n");
618
619
620         printf("PASSED\n\n");
621         return true;
622 }
623
624 bool test_metadata_object_seektable()
625 {
626         unsigned expected_length;
627
628         printf("testing class FLAC::Metadata::SeekTable\n");
629
630         printf("testing SeekTable::SeekTable()... ");
631         FLAC::Metadata::SeekTable block;
632         if(!block.is_valid())
633                 return die_("!block.is_valid()");
634         expected_length = 0;
635         if(block.get_length() != expected_length) {
636                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
637                 return false;
638         }
639         printf("OK\n");
640
641         printf("testing SeekTable::SeekTable(const SeekTable &)... +\n");
642         printf("        SeekTable::operator!=(const SeekTable &)... ");
643         {
644                 FLAC::Metadata::SeekTable blockcopy(block);
645                 if(!blockcopy.is_valid())
646                         return die_("!block.is_valid()");
647                 if(blockcopy != block)
648                         return die_("copy is not identical to original");
649                 printf("OK\n");
650
651                 printf("testing SeekTable::~SeekTable()... ");
652         }
653         printf("OK\n");
654
655         printf("testing SeekTable::SeekTable(const ::FLAC__StreamMetadata &)... +\n");
656         printf("        SeekTable::operator!=(const ::FLAC__StreamMetadata &)... ");
657         {
658                 FLAC::Metadata::SeekTable blockcopy(seektable_);
659                 if(!blockcopy.is_valid())
660                         return die_("!block.is_valid()");
661                 if(blockcopy != seektable_)
662                         return die_("copy is not identical to original");
663                 printf("OK\n");
664         }
665
666         printf("testing SeekTable::SeekTable(const ::FLAC__StreamMetadata *)... +\n");
667         printf("        SeekTable::operator!=(const ::FLAC__StreamMetadata *)... ");
668         {
669                 FLAC::Metadata::SeekTable blockcopy(&seektable_);
670                 if(!blockcopy.is_valid())
671                         return die_("!block.is_valid()");
672                 if(blockcopy != seektable_)
673                         return die_("copy is not identical to original");
674                 printf("OK\n");
675         }
676
677         printf("testing SeekTable::operator=(const SeekTable &)... +\n");
678         printf("        SeekTable::operator==(const SeekTable &)... ");
679         {
680                 FLAC::Metadata::SeekTable blockcopy = block;
681                 if(!blockcopy.is_valid())
682                         return die_("!block.is_valid()");
683                 if(!(blockcopy == block))
684                         return die_("copy is not identical to original");
685                 printf("OK\n");
686         }
687
688         printf("testing SeekTable::operator=(const ::FLAC__StreamMetadata &)... +\n");
689         printf("        SeekTable::operator==(const ::FLAC__StreamMetadata &)... ");
690         {
691                 FLAC::Metadata::SeekTable blockcopy = seektable_;
692                 if(!blockcopy.is_valid())
693                         return die_("!block.is_valid()");
694                 if(!(blockcopy == seektable_))
695                         return die_("copy is not identical to original");
696                 printf("OK\n");
697         }
698
699         printf("testing SeekTable::operator=(const ::FLAC__StreamMetadata *)... +\n");
700         printf("        SeekTable::operator==(const ::FLAC__StreamMetadata *)... ");
701         {
702                 FLAC::Metadata::SeekTable blockcopy = &seektable_;
703                 if(!blockcopy.is_valid())
704                         return die_("!block.is_valid()");
705                 if(!(blockcopy == seektable_))
706                         return die_("copy is not identical to original");
707                 printf("OK\n");
708         }
709
710         printf("testing SeekTable::insert_point() x 3... ");
711         if(!block.insert_point(0, seektable_.data.seek_table.points[1]))
712                 return die_("returned false");
713         if(!block.insert_point(0, seektable_.data.seek_table.points[1]))
714                 return die_("returned false");
715         if(!block.insert_point(1, seektable_.data.seek_table.points[0]))
716                 return die_("returned false");
717         printf("OK\n");
718
719         printf("testing SeekTable::is_legal()... ");
720         if(block.is_legal())
721                 return die_("returned true");
722         printf("OK\n");
723
724         printf("testing SeekTable::set_point()... ");
725         block.set_point(0, seektable_.data.seek_table.points[0]);
726         printf("OK\n");
727
728         printf("testing SeekTable::delete_point()... ");
729         if(!block.delete_point(0))
730                 return die_("returned false");
731         printf("OK\n");
732
733         printf("testing SeekTable::is_legal()... ");
734         if(!block.is_legal())
735                 return die_("returned false");
736         printf("OK\n");
737
738         printf("testing SeekTable::get_num_points()... ");
739         if(block.get_num_points() != seektable_.data.seek_table.num_points)
740                 return die_("number mismatch");
741         printf("OK\n");
742
743         printf("testing SeekTable::operator!=(const ::FLAC__StreamMetadata &)... ");
744         if(block != seektable_)
745                 return die_("data mismatch");
746         printf("OK\n");
747
748         printf("testing SeekTable::get_point()... ");
749         if(
750                 block.get_point(1).sample_number != seektable_.data.seek_table.points[1].sample_number ||
751                 block.get_point(1).stream_offset != seektable_.data.seek_table.points[1].stream_offset ||
752                 block.get_point(1).frame_samples != seektable_.data.seek_table.points[1].frame_samples
753         )
754                 return die_("point mismatch");
755         printf("OK\n");
756
757         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
758         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
759         if(0 == clone_)
760                 return die_("returned NULL");
761         if(0 == dynamic_cast<FLAC::Metadata::SeekTable *>(clone_))
762                 return die_("downcast is NULL");
763         if(*dynamic_cast<FLAC::Metadata::SeekTable *>(clone_) != block)
764                 return die_("clone is not identical");
765         printf("OK\n");
766         printf("testing SeekTable::~SeekTable()... ");
767         delete clone_;
768         printf("OK\n");
769
770
771         printf("PASSED\n\n");
772         return true;
773 }
774
775 bool test_metadata_object_vorbiscomment()
776 {
777         unsigned expected_length;
778
779         printf("testing class FLAC::Metadata::VorbisComment::Entry\n");
780
781         printf("testing Entry::Entry()... ");
782         {
783                 FLAC::Metadata::VorbisComment::Entry entry1;
784                 if(!entry1.is_valid())
785                         return die_("!is_valid()");
786                 printf("OK\n");
787
788                 printf("testing Entry::~Entry()... ");
789         }
790         printf("OK\n");
791
792         printf("testing Entry::Entry(const char *field, unsigned field_length)... ");
793         FLAC::Metadata::VorbisComment::Entry entry2("name2=value2", strlen("name2=value2"));
794         if(!entry2.is_valid())
795                 return die_("!is_valid()");
796         printf("OK\n");
797
798         printf("testing Entry::Entry(const char *field_name, const char *field_value, unsigned field_value_length)... ");
799         FLAC::Metadata::VorbisComment::Entry entry3("name3", "value3", strlen("value3"));
800         if(!entry3.is_valid())
801                 return die_("!is_valid()");
802         printf("OK\n");
803
804         printf("testing Entry::Entry(const Entry &entry)... ");
805         {
806                 FLAC::Metadata::VorbisComment::Entry entry2copy(entry2);
807                 if(!entry2copy.is_valid())
808                         return die_("!is_valid()");
809                 printf("OK\n");
810
811                 printf("testing Entry::~Entry()... ");
812         }
813         printf("OK\n");
814
815         printf("testing Entry::operator=(const Entry &entry)... ");
816         FLAC::Metadata::VorbisComment::Entry entry1 = entry2;
817         if(!entry2.is_valid())
818                 return die_("!is_valid()");
819         printf("OK\n");
820
821         printf("testing Entry::get_field_length()... ");
822         if(entry1.get_field_length() != strlen("name2=value2"))
823                 return die_("value mismatch");
824         printf("OK\n");
825
826         printf("testing Entry::get_field_name_length()... ");
827         if(entry1.get_field_name_length() != strlen("name2"))
828                 return die_("value mismatch");
829         printf("OK\n");
830
831         printf("testing Entry::get_field_value_length()... ");
832         if(entry1.get_field_value_length() != strlen("value2"))
833                 return die_("value mismatch");
834         printf("OK\n");
835
836         printf("testing Entry::get_entry()... ");
837         {
838                 ::FLAC__StreamMetadata_VorbisComment_Entry entry = entry1.get_entry();
839                 if(entry.length != strlen("name2=value2"))
840                         return die_("entry length mismatch");
841                 if(0 != memcmp(entry.entry, "name2=value2", entry.length))
842                         return die_("entry value mismatch");
843         }
844         printf("OK\n");
845
846         printf("testing Entry::get_field()... ");
847         if(0 != memcmp(entry1.get_field(), "name2=value2", strlen("name2=value2")))
848                 return die_("value mismatch");
849         printf("OK\n");
850
851         printf("testing Entry::get_field_name()... ");
852         if(0 != memcmp(entry1.get_field_name(), "name2", strlen("name2")))
853                 return die_("value mismatch");
854         printf("OK\n");
855
856         printf("testing Entry::get_field_value()... ");
857         if(0 != memcmp(entry1.get_field_value(), "value2", strlen("value2")))
858                 return die_("value mismatch");
859         printf("OK\n");
860
861         printf("testing Entry::set_field_name()... ");
862         if(!entry1.set_field_name("name1"))
863                 return die_("returned false");
864         if(0 != memcmp(entry1.get_field_name(), "name1", strlen("name1")))
865                 return die_("value mismatch");
866         if(0 != memcmp(entry1.get_field(), "name1=value2", strlen("name1=value2")))
867                 return die_("entry mismatch");
868         printf("OK\n");
869
870         printf("testing Entry::set_field_value()... ");
871         if(!entry1.set_field_value("value1", strlen("value1")))
872                 return die_("returned false");
873         if(0 != memcmp(entry1.get_field_value(), "value1", strlen("value1")))
874                 return die_("value mismatch");
875         if(0 != memcmp(entry1.get_field(), "name1=value1", strlen("name1=value1")))
876                 return die_("entry mismatch");
877         printf("OK\n");
878
879         printf("testing Entry::set_field()... ");
880         if(!entry1.set_field("name0=value0", strlen("name0=value0")))
881                 return die_("returned false");
882         if(0 != memcmp(entry1.get_field_name(), "name0", strlen("name0")))
883                 return die_("value mismatch");
884         if(0 != memcmp(entry1.get_field_value(), "value0", strlen("value0")))
885                 return die_("value mismatch");
886         if(0 != memcmp(entry1.get_field(), "name0=value0", strlen("name0=value0")))
887                 return die_("entry mismatch");
888         printf("OK\n");
889
890         printf("PASSED\n\n");
891
892
893         printf("testing class FLAC::Metadata::VorbisComment\n");
894
895         printf("testing VorbisComment::VorbisComment()... ");
896         FLAC::Metadata::VorbisComment block;
897         if(!block.is_valid())
898                 return die_("!block.is_valid()");
899         expected_length = (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + strlen(::FLAC__VENDOR_STRING) + FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN/8);
900         if(block.get_length() != expected_length) {
901                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
902                 return false;
903         }
904         printf("OK\n");
905
906         printf("testing VorbisComment::VorbisComment(const VorbisComment &)... +\n");
907         printf("        VorbisComment::operator!=(const VorbisComment &)... ");
908         {
909                 FLAC::Metadata::VorbisComment blockcopy(block);
910                 if(!blockcopy.is_valid())
911                         return die_("!block.is_valid()");
912                 if(blockcopy != block)
913                         return die_("copy is not identical to original");
914                 printf("OK\n");
915
916                 printf("testing VorbisComment::~VorbisComment()... ");
917         }
918         printf("OK\n");
919
920         printf("testing VorbisComment::VorbisComment(const ::FLAC__StreamMetadata &)... +\n");
921         printf("        VorbisComment::operator!=(const ::FLAC__StreamMetadata &)... ");
922         {
923                 FLAC::Metadata::VorbisComment blockcopy(vorbiscomment_);
924                 if(!blockcopy.is_valid())
925                         return die_("!block.is_valid()");
926                 if(blockcopy != vorbiscomment_)
927                         return die_("copy is not identical to original");
928                 printf("OK\n");
929         }
930
931         printf("testing VorbisComment::VorbisComment(const ::FLAC__StreamMetadata *)... +\n");
932         printf("        VorbisComment::operator!=(const ::FLAC__StreamMetadata *)... ");
933         {
934                 FLAC::Metadata::VorbisComment blockcopy(&vorbiscomment_);
935                 if(!blockcopy.is_valid())
936                         return die_("!block.is_valid()");
937                 if(blockcopy != vorbiscomment_)
938                         return die_("copy is not identical to original");
939                 printf("OK\n");
940         }
941
942         printf("testing VorbisComment::operator=(const VorbisComment &)... +\n");
943         printf("        VorbisComment::operator==(const VorbisComment &)... ");
944         {
945                 FLAC::Metadata::VorbisComment blockcopy = block;
946                 if(!blockcopy.is_valid())
947                         return die_("!block.is_valid()");
948                 if(!(blockcopy == block))
949                         return die_("copy is not identical to original");
950                 printf("OK\n");
951         }
952
953         printf("testing VorbisComment::operator=(const ::FLAC__StreamMetadata &)... +\n");
954         printf("        VorbisComment::operator==(const ::FLAC__StreamMetadata &)... ");
955         {
956                 FLAC::Metadata::VorbisComment blockcopy = vorbiscomment_;
957                 if(!blockcopy.is_valid())
958                         return die_("!block.is_valid()");
959                 if(!(blockcopy == vorbiscomment_))
960                         return die_("copy is not identical to original");
961                 printf("OK\n");
962         }
963
964         printf("testing VorbisComment::operator=(const ::FLAC__StreamMetadata *)... +\n");
965         printf("        VorbisComment::operator==(const ::FLAC__StreamMetadata *)... ");
966         {
967                 FLAC::Metadata::VorbisComment blockcopy = &vorbiscomment_;
968                 if(!blockcopy.is_valid())
969                         return die_("!block.is_valid()");
970                 if(!(blockcopy == vorbiscomment_))
971                         return die_("copy is not identical to original");
972                 printf("OK\n");
973         }
974
975         printf("testing VorbisComment::get_num_comments()... ");
976         if(block.get_num_comments() != 0)
977                 return die_("value mismatch, expected 0");
978         printf("OK\n");
979
980         printf("testing VorbisComment::set_vendor_string()... ");
981         if(!block.set_vendor_string(entry1))
982                 return die_("returned false");
983         printf("OK\n");
984
985         printf("testing VorbisComment::get_vendor_string()... ");
986         if(block.get_vendor_string().get_field_name_length() != vorbiscomment_.data.vorbis_comment.vendor_string.length)
987                 return die_("length mismatch");
988         if(0 != memcmp(block.get_vendor_string().get_field_name(), vorbiscomment_.data.vorbis_comment.vendor_string.entry, vorbiscomment_.data.vorbis_comment.vendor_string.length))
989                 return die_("value mismatch");
990         printf("OK\n");
991
992         printf("testing VorbisComment::insert_comment()... +\n");
993         printf("        VorbisComment::get_comment()... ");
994         if(!block.insert_comment(0, entry3))
995                 return die_("returned false");
996         if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[1].length)
997                 return die_("length mismatch");
998         if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[1].entry, vorbiscomment_.data.vorbis_comment.comments[1].length))
999                 return die_("value mismatch");
1000         printf("OK\n");
1001
1002         printf("testing VorbisComment::insert_comment()... +\n");
1003         printf("        VorbisComment::get_comment()... ");
1004         if(!block.insert_comment(0, entry3))
1005                 return die_("returned false");
1006         if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[1].length)
1007                 return die_("length mismatch");
1008         if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[1].entry, vorbiscomment_.data.vorbis_comment.comments[1].length))
1009                 return die_("value mismatch");
1010         printf("OK\n");
1011
1012         printf("testing VorbisComment::insert_comment()... +\n");
1013         printf("        VorbisComment::get_comment()... ");
1014         if(!block.insert_comment(1, entry2))
1015                 return die_("returned false");
1016         if(block.get_comment(1).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[0].length)
1017                 return die_("length mismatch");
1018         if(0 != memcmp(block.get_comment(1).get_field(), vorbiscomment_.data.vorbis_comment.comments[0].entry, vorbiscomment_.data.vorbis_comment.comments[0].length))
1019                 return die_("value mismatch");
1020         printf("OK\n");
1021
1022         printf("testing VorbisComment::set_comment()... +\n");
1023         printf("        VorbisComment::get_comment()... ");
1024         if(!block.set_comment(0, entry2))
1025                 return die_("returned false");
1026         if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[0].length)
1027                 return die_("length mismatch");
1028         if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[0].entry, vorbiscomment_.data.vorbis_comment.comments[0].length))
1029                 return die_("value mismatch");
1030         printf("OK\n");
1031
1032         printf("testing VorbisComment::delete_comment()... +\n");
1033         printf("        VorbisComment::get_comment()... ");
1034         if(!block.delete_comment(0))
1035                 return die_("returned false");
1036         if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[0].length)
1037                 return die_("length[0] mismatch");
1038         if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[0].entry, vorbiscomment_.data.vorbis_comment.comments[0].length))
1039                 return die_("value[0] mismatch");
1040         if(block.get_comment(1).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[1].length)
1041                 return die_("length[1] mismatch");
1042         if(0 != memcmp(block.get_comment(1).get_field(), vorbiscomment_.data.vorbis_comment.comments[1].entry, vorbiscomment_.data.vorbis_comment.comments[1].length))
1043                 return die_("value[0] mismatch");
1044         printf("OK\n");
1045
1046         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
1047         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
1048         if(0 == clone_)
1049                 return die_("returned NULL");
1050         if(0 == dynamic_cast<FLAC::Metadata::VorbisComment *>(clone_))
1051                 return die_("downcast is NULL");
1052         if(*dynamic_cast<FLAC::Metadata::VorbisComment *>(clone_) != block)
1053                 return die_("clone is not identical");
1054         printf("OK\n");
1055         printf("testing VorbisComment::~VorbisComment()... ");
1056         delete clone_;
1057         printf("OK\n");
1058
1059
1060         printf("PASSED\n\n");
1061         return true;
1062 }
1063
1064 bool test_metadata_object_cuesheet()
1065 {
1066         unsigned expected_length;
1067
1068         printf("testing class FLAC::Metadata::CueSheet::Track\n");
1069
1070         printf("testing Track::Track()... ");
1071         FLAC::Metadata::CueSheet::Track track0;
1072         if(!track0.is_valid())
1073                 return die_("!is_valid()");
1074         printf("OK\n");
1075
1076         {
1077                 printf("testing Track::get_track()... ");
1078                 const ::FLAC__StreamMetadata_CueSheet_Track *trackp = track0.get_track();
1079                 if(0 == trackp)
1080                         return die_("returned pointer is NULL");
1081                 printf("OK\n");
1082
1083                 printf("testing Track::Track(const ::FLAC__StreamMetadata_CueSheet_Track*)... ");
1084                 FLAC::Metadata::CueSheet::Track track2(trackp);
1085                 if(!track2.is_valid())
1086                         return die_("!is_valid()");
1087                 if(!track_is_equal_(track2.get_track(), trackp))
1088                         return die_("copy is not equal");
1089                 printf("OK\n");
1090
1091                 printf("testing Track::~Track()... ");
1092         }
1093         printf("OK\n");
1094
1095         printf("testing Track::Track(const Track &track)... ");
1096         {
1097                 FLAC::Metadata::CueSheet::Track track0copy(track0);
1098                 if(!track0copy.is_valid())
1099                         return die_("!is_valid()");
1100                 if(!track_is_equal_(track0copy.get_track(), track0.get_track()))
1101                         return die_("copy is not equal");
1102                 printf("OK\n");
1103
1104                 printf("testing Track::~Track()... ");
1105         }
1106         printf("OK\n");
1107
1108         printf("testing Track::operator=(const Track &track)... ");
1109         FLAC::Metadata::CueSheet::Track track1 = track0;
1110         if(!track0.is_valid())
1111                 return die_("!is_valid()");
1112         if(!track_is_equal_(track1.get_track(), track0.get_track()))
1113                 return die_("copy is not equal");
1114         printf("OK\n");
1115
1116         printf("testing Track::get_offset()... ");
1117         if(track1.get_offset() != 0)
1118                 return die_("value mismatch");
1119         printf("OK\n");
1120
1121         printf("testing Track::get_number()... ");
1122         if(track1.get_number() != 0)
1123                 return die_("value mismatch");
1124         printf("OK\n");
1125
1126         printf("testing Track::get_isrc()... ");
1127         if(0 != memcmp(track1.get_isrc(), "\0\0\0\0\0\0\0\0\0\0\0\0\0", 13))
1128                 return die_("value mismatch");
1129         printf("OK\n");
1130
1131         printf("testing Track::get_type()... ");
1132         if(track1.get_type() != 0)
1133                 return die_("value mismatch");
1134         printf("OK\n");
1135
1136         printf("testing Track::get_pre_emphasis()... ");
1137         if(track1.get_pre_emphasis() != 0)
1138                 return die_("value mismatch");
1139         printf("OK\n");
1140
1141         printf("testing Track::get_num_indices()... ");
1142         if(track1.get_num_indices() != 0)
1143                 return die_("value mismatch");
1144         printf("OK\n");
1145
1146         printf("testing Track::set_offset()... ");
1147         track1.set_offset(588);
1148         if(track1.get_offset() != 588)
1149                 return die_("value mismatch");
1150         printf("OK\n");
1151
1152         printf("testing Track::set_number()... ");
1153         track1.set_number(1);
1154         if(track1.get_number() != 1)
1155                 return die_("value mismatch");
1156         printf("OK\n");
1157
1158         printf("testing Track::set_isrc()... ");
1159         track1.set_isrc("ABCDE1234567");
1160         if(0 != memcmp(track1.get_isrc(), "ABCDE1234567", 13))
1161                 return die_("value mismatch");
1162         printf("OK\n");
1163
1164         printf("testing Track::set_type()... ");
1165         track1.set_type(1);
1166         if(track1.get_type() != 1)
1167                 return die_("value mismatch");
1168         printf("OK\n");
1169
1170         printf("testing Track::set_pre_emphasis()... ");
1171         track1.set_pre_emphasis(1);
1172         if(track1.get_pre_emphasis() != 1)
1173                 return die_("value mismatch");
1174         printf("OK\n");
1175
1176         printf("PASSED\n\n");
1177
1178         printf("testing class FLAC::Metadata::CueSheet\n");
1179
1180         printf("testing CueSheet::CueSheet()... ");
1181         FLAC::Metadata::CueSheet block;
1182         if(!block.is_valid())
1183                 return die_("!block.is_valid()");
1184         expected_length = (
1185                 FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN +
1186                 FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN +
1187                 FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN +
1188                 FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN +
1189                 FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN
1190         ) / 8;
1191         if(block.get_length() != expected_length) {
1192                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
1193                 return false;
1194         }
1195         printf("OK\n");
1196
1197         printf("testing CueSheet::CueSheet(const CueSheet &)... +\n");
1198         printf("        CueSheet::operator!=(const CueSheet &)... ");
1199         {
1200                 FLAC::Metadata::CueSheet blockcopy(block);
1201                 if(!blockcopy.is_valid())
1202                         return die_("!block.is_valid()");
1203                 if(blockcopy != block)
1204                         return die_("copy is not identical to original");
1205                 printf("OK\n");
1206
1207                 printf("testing CueSheet::~CueSheet()... ");
1208         }
1209         printf("OK\n");
1210
1211         printf("testing CueSheet::CueSheet(const ::FLAC__StreamMetadata &)... +\n");
1212         printf("        CueSheet::operator!=(const ::FLAC__StreamMetadata &)... ");
1213         {
1214                 FLAC::Metadata::CueSheet blockcopy(cuesheet_);
1215                 if(!blockcopy.is_valid())
1216                         return die_("!block.is_valid()");
1217                 if(blockcopy != cuesheet_)
1218                         return die_("copy is not identical to original");
1219                 printf("OK\n");
1220         }
1221
1222         printf("testing CueSheet::CueSheet(const ::FLAC__StreamMetadata *)... +\n");
1223         printf("        CueSheet::operator!=(const ::FLAC__StreamMetadata *)... ");
1224         {
1225                 FLAC::Metadata::CueSheet blockcopy(&cuesheet_);
1226                 if(!blockcopy.is_valid())
1227                         return die_("!block.is_valid()");
1228                 if(blockcopy != cuesheet_)
1229                         return die_("copy is not identical to original");
1230                 printf("OK\n");
1231         }
1232
1233         printf("testing CueSheet::operator=(const CueSheet &)... +\n");
1234         printf("        CueSheet::operator==(const CueSheet &)... ");
1235         {
1236                 FLAC::Metadata::CueSheet blockcopy = block;
1237                 if(!blockcopy.is_valid())
1238                         return die_("!block.is_valid()");
1239                 if(!(blockcopy == block))
1240                         return die_("copy is not identical to original");
1241                 printf("OK\n");
1242         }
1243
1244         printf("testing CueSheet::operator=(const ::FLAC__StreamMetadata &)... +\n");
1245         printf("        CueSheet::operator==(const ::FLAC__StreamMetadata &)... ");
1246         {
1247                 FLAC::Metadata::CueSheet blockcopy = cuesheet_;
1248                 if(!blockcopy.is_valid())
1249                         return die_("!block.is_valid()");
1250                 if(!(blockcopy == cuesheet_))
1251                         return die_("copy is not identical to original");
1252                 printf("OK\n");
1253         }
1254
1255         printf("testing CueSheet::operator=(const ::FLAC__StreamMetadata *)... +\n");
1256         printf("        CueSheet::operator==(const ::FLAC__StreamMetadata *)... ");
1257         {
1258                 FLAC::Metadata::CueSheet blockcopy = &cuesheet_;
1259                 if(!blockcopy.is_valid())
1260                         return die_("!block.is_valid()");
1261                 if(!(blockcopy == cuesheet_))
1262                         return die_("copy is not identical to original");
1263                 printf("OK\n");
1264         }
1265
1266         printf("testing CueSheet::get_media_catalog_number()... ");
1267         if(0 != strcmp(block.get_media_catalog_number(), ""))
1268                 return die_("value mismatch");
1269         printf("OK\n");
1270
1271         printf("testing CueSheet::get_lead_in()... ");
1272         if(block.get_lead_in() != 0)
1273                 return die_("value mismatch, expected 0");
1274         printf("OK\n");
1275
1276         printf("testing CueSheet::get_is_cd()... ");
1277         if(block.get_is_cd())
1278                 return die_("value mismatch, expected false");
1279         printf("OK\n");
1280
1281         printf("testing CueSheet::get_num_tracks()... ");
1282         if(block.get_num_tracks() != 0)
1283                 return die_("value mismatch, expected 0");
1284         printf("OK\n");
1285
1286         printf("testing CueSheet::set_media_catalog_number()... ");
1287         {
1288                 char mcn[129];
1289                 memset(mcn, 0, sizeof(mcn));
1290                 strcpy(mcn, "1234567890123");
1291                 block.set_media_catalog_number(mcn);
1292                 if(0 != memcmp(block.get_media_catalog_number(), mcn, sizeof(mcn)))
1293                         return die_("value mismatch");
1294         }
1295         printf("OK\n");
1296
1297         printf("testing CueSheet::set_lead_in()... ");
1298         block.set_lead_in(588);
1299         if(block.get_lead_in() != 588)
1300                 return die_("value mismatch");
1301         printf("OK\n");
1302
1303         printf("testing CueSheet::set_is_cd()... ");
1304         block.set_is_cd(true);
1305         if(!block.get_is_cd())
1306                 return die_("value mismatch");
1307         printf("OK\n");
1308
1309         printf("testing CueSheet::insert_track()... +\n");
1310         printf("        CueSheet::get_track()... ");
1311         if(!block.insert_track(0, track0))
1312                 return die_("returned false");
1313         if(!track_is_equal_(block.get_track(0).get_track(), track0.get_track()))
1314                 return die_("value mismatch");
1315         printf("OK\n");
1316
1317         printf("testing CueSheet::insert_track()... +\n");
1318         printf("        CueSheet::get_track()... ");
1319         if(!block.insert_track(1, track1))
1320                 return die_("returned false");
1321         if(!track_is_equal_(block.get_track(1).get_track(), track1.get_track()))
1322                 return die_("value mismatch");
1323         printf("OK\n");
1324
1325         ::FLAC__StreamMetadata_CueSheet_Index index0;
1326         index0.offset = 588*4;
1327         index0.number = 1;
1328
1329         printf("testing CueSheet::insert_index(0)... +\n");
1330         printf("        CueSheet::get_track()... +\n");
1331         printf("        CueSheet::Track::get_index()... ");
1332         if(!block.insert_index(0, 0, index0))
1333                 return die_("returned false");
1334         if(!index_is_equal_(block.get_track(0).get_index(0), index0))
1335                 return die_("value mismatch");
1336         printf("OK\n");
1337
1338         index0.offset = 588*5;
1339         printf("testing CueSheet::Track::set_index()... ");
1340         {
1341                 FLAC::Metadata::CueSheet::Track track_ = block.get_track(0);
1342                 track_.set_index(0, index0);
1343                 if(!index_is_equal_(track_.get_index(0), index0))
1344                         return die_("value mismatch");
1345         }
1346         printf("OK\n");
1347
1348         index0.offset = 588*6;
1349         printf("testing CueSheet::set_index()... ");
1350         block.set_index(0, 0, index0);
1351         if(!index_is_equal_(block.get_track(0).get_index(0), index0))
1352                 return die_("value mismatch");
1353         printf("OK\n");
1354
1355         printf("testing CueSheet::delete_index()... ");
1356         if(!block.delete_index(0, 0))
1357                 return die_("returned false");
1358         if(block.get_track(0).get_num_indices() != 0)
1359                 return die_("num_indices mismatch");
1360         printf("OK\n");
1361
1362
1363         printf("testing CueSheet::set_track()... +\n");
1364         printf("        CueSheet::get_track()... ");
1365         if(!block.set_track(0, track1))
1366                 return die_("returned false");
1367         if(!track_is_equal_(block.get_track(0).get_track(), track1.get_track()))
1368                 return die_("value mismatch");
1369         printf("OK\n");
1370
1371         printf("testing CueSheet::delete_track()... ");
1372         if(!block.delete_track(0))
1373                 return die_("returned false");
1374         if(block.get_num_tracks() != 1)
1375                 return die_("num_tracks mismatch");
1376         printf("OK\n");
1377
1378         printf("testing FLAC::Metadata::clone(const FLAC::Metadata::Prototype *)... ");
1379         FLAC::Metadata::Prototype *clone_ = FLAC::Metadata::clone(&block);
1380         if(0 == clone_)
1381                 return die_("returned NULL");
1382         if(0 == dynamic_cast<FLAC::Metadata::CueSheet *>(clone_))
1383                 return die_("downcast is NULL");
1384         if(*dynamic_cast<FLAC::Metadata::CueSheet *>(clone_) != block)
1385                 return die_("clone is not identical");
1386         printf("OK\n");
1387         printf("testing CueSheet::~CueSheet()... ");
1388         delete clone_;
1389         printf("OK\n");
1390
1391         printf("PASSED\n\n");
1392         return true;
1393 }
1394
1395 bool test_metadata_object()
1396 {
1397         printf("\n+++ libFLAC++ unit test: metadata objects\n\n");
1398
1399         init_metadata_blocks_();
1400
1401         if(!test_metadata_object_streaminfo())
1402                 return false;
1403
1404         if(!test_metadata_object_padding())
1405                 return false;
1406
1407         if(!test_metadata_object_application())
1408                 return false;
1409
1410         if(!test_metadata_object_seektable())
1411                 return false;
1412
1413         if(!test_metadata_object_vorbiscomment())
1414                 return false;
1415
1416         if(!test_metadata_object_cuesheet())
1417                 return false;
1418
1419         free_metadata_blocks_();
1420
1421         return true;
1422 }