fix bug in stats reporting
[flac.git] / src / test_libFLAC / metadata_object.c
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 "metadata_utils.h"
22 #include <stdio.h>
23 #include <stdlib.h> /* for malloc() */
24 #include <string.h> /* for memcmp() */
25
26 static FLAC__byte *make_dummydata_(FLAC__byte *dummydata, unsigned len)
27 {
28         FLAC__byte *ret;
29
30         if(0 == (ret = (FLAC__byte*)malloc(len))) {
31                 printf("FAILED, malloc error\n");
32                 exit(1);
33         }
34         else
35                 memcpy(ret, dummydata, len);
36
37         return ret;
38 }
39
40 static FLAC__bool compare_seekpoint_array_(const FLAC__StreamMetadata_SeekPoint *from, const FLAC__StreamMetadata_SeekPoint *to, unsigned n)
41 {
42         unsigned i;
43
44         FLAC__ASSERT(0 != from);
45         FLAC__ASSERT(0 != to);
46
47         for(i = 0; i < n; i++) {
48                 if(from[i].sample_number != to[i].sample_number) {
49                         printf("FAILED, point[%u].sample_number mismatch, expected %llu, got %llu\n", i, to[i].sample_number, from[i].sample_number);
50                         return false;
51                 }
52                 if(from[i].stream_offset != to[i].stream_offset) {
53                         printf("FAILED, point[%u].stream_offset mismatch, expected %llu, got %llu\n", i, to[i].stream_offset, from[i].stream_offset);
54                         return false;
55                 }
56                 if(from[i].frame_samples != to[i].frame_samples) {
57                         printf("FAILED, point[%u].frame_samples mismatch, expected %u, got %u\n", i, to[i].frame_samples, from[i].frame_samples);
58                         return false;
59                 }
60         }
61
62         return true;
63 }
64
65 static FLAC__bool check_seektable_(const FLAC__StreamMetadata *block, unsigned num_points, const FLAC__StreamMetadata_SeekPoint *array)
66 {
67         const unsigned expected_length = num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
68
69         if(block->length != expected_length) {
70                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length);
71                 return false;
72     }
73         if(block->data.seek_table.num_points != num_points) {
74                 printf("FAILED, expected %u point, got %u\n", num_points, block->data.seek_table.num_points);
75                 return false;
76         }
77         if(0 == array) {
78                 if(0 != block->data.seek_table.points) {
79                         printf("FAILED, 'points' pointer is not null\n");
80                         return false;
81                 }
82         }
83         else {
84                 if(!compare_seekpoint_array_(block->data.seek_table.points, array, num_points))
85                         return false;
86         }
87         printf("OK\n");
88
89         return true;
90 }
91
92 static void entry_new_(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field)
93 {
94         entry->length = strlen(field);
95         entry->entry = (FLAC__byte*)malloc(entry->length);
96         FLAC__ASSERT(0 != entry->entry);        
97         memcpy(entry->entry, field, entry->length);
98 }
99
100 static void entry_clone_(FLAC__StreamMetadata_VorbisComment_Entry *entry)
101 {
102         FLAC__byte *x = (FLAC__byte*)malloc(entry->length);
103         FLAC__ASSERT(0 != x);   
104         memcpy(x, entry->entry, entry->length);
105         entry->entry = x;
106 }
107
108 static void vc_calc_len_(FLAC__StreamMetadata *block)
109 {
110         const FLAC__StreamMetadata_VorbisComment *vc = &block->data.vorbis_comment;
111         unsigned i;
112
113         block->length = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8;
114         block->length += vc->vendor_string.length;
115         block->length += FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8;
116         for(i = 0; i < vc->num_comments; i++) {
117                 block->length += FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8;
118                 block->length += vc->comments[i].length;
119         }
120 }
121
122 static void vc_resize_(FLAC__StreamMetadata *block, unsigned num)
123 {
124         FLAC__StreamMetadata_VorbisComment *vc = &block->data.vorbis_comment;
125
126         if(vc->num_comments != 0) {
127                 FLAC__ASSERT(0 != vc->comments);
128                 if(num < vc->num_comments) {
129                         unsigned i;
130                         for(i = num; i < vc->num_comments; i++) {
131                                 if(0 != vc->comments[i].entry)
132                                         free(vc->comments[i].entry);
133                         }
134                 }
135         }
136         if(num == 0) {
137                 if(0 != vc->comments) {
138                         free(vc->comments);
139                         vc->comments = 0;
140                 }
141         }
142         else {
143                 vc->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)realloc(vc->comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*num);
144                 FLAC__ASSERT(0 != vc->comments);
145                 if(num > vc->num_comments)
146                         memset(vc->comments+vc->num_comments, 0, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*(num-vc->num_comments));
147         }
148
149         vc->num_comments = num;
150         vc_calc_len_(block);
151 }
152
153 static void vc_set_vs_new_(FLAC__StreamMetadata_VorbisComment_Entry *entry, FLAC__StreamMetadata *block, const char *field)
154 {
155         entry_new_(entry, field);
156         block->data.vorbis_comment.vendor_string = *entry;
157         vc_calc_len_(block);
158 }
159
160 static void vc_set_new_(FLAC__StreamMetadata_VorbisComment_Entry *entry, FLAC__StreamMetadata *block, unsigned pos, const char *field)
161 {
162         entry_new_(entry, field);
163         block->data.vorbis_comment.comments[pos] = *entry;
164         vc_calc_len_(block);
165 }
166
167 static void vc_insert_new_(FLAC__StreamMetadata_VorbisComment_Entry *entry, FLAC__StreamMetadata *block, unsigned pos, const char *field)
168 {
169         vc_resize_(block, block->data.vorbis_comment.num_comments+1);
170         memmove(&block->data.vorbis_comment.comments[pos+1], &block->data.vorbis_comment.comments[pos], sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*(block->data.vorbis_comment.num_comments-1-pos));
171         vc_set_new_(entry, block, pos, field);
172         vc_calc_len_(block);
173 }
174
175 static void vc_delete_(FLAC__StreamMetadata *block, unsigned pos)
176 {
177         if(0 != block->data.vorbis_comment.comments[pos].entry)
178                 free(block->data.vorbis_comment.comments[pos].entry);
179         memmove(&block->data.vorbis_comment.comments[pos], &block->data.vorbis_comment.comments[pos+1], sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*(block->data.vorbis_comment.num_comments-pos-1));
180         block->data.vorbis_comment.comments[block->data.vorbis_comment.num_comments-1].entry = 0;
181         block->data.vorbis_comment.comments[block->data.vorbis_comment.num_comments-1].length = 0;
182         vc_resize_(block, block->data.vorbis_comment.num_comments-1);
183         vc_calc_len_(block);
184 }
185
186 FLAC__bool test_metadata_object()
187 {
188         FLAC__StreamMetadata *block, *blockcopy, *vorbiscomment;
189         FLAC__StreamMetadata_SeekPoint seekpoint_array[8];
190         FLAC__StreamMetadata_VorbisComment_Entry entry;
191         unsigned i, expected_length, seekpoints;
192         static FLAC__byte dummydata[4] = { 'a', 'b', 'c', 'd' };
193
194         printf("\n+++ libFLAC unit test: metadata objects\n\n");
195
196
197         printf("testing STREAMINFO\n");
198
199         printf("testing FLAC__metadata_object_new()... ");
200         block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO);
201         if(0 == block) {
202                 printf("FAILED, returned NULL\n");
203                 return false;
204         }
205         expected_length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
206         if(block->length != expected_length) {
207                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length);
208                 return false;
209     }
210         printf("OK\n");
211
212         printf("testing FLAC__metadata_object_clone()... ");
213         blockcopy = FLAC__metadata_object_clone(block);
214         if(0 == blockcopy) {
215                 printf("FAILED, returned NULL\n");
216                 return false;
217         }
218         if(!compare_block_(block, blockcopy))
219                 return false;
220         printf("OK\n");
221
222         printf("testing FLAC__metadata_object_delete()... ");
223         FLAC__metadata_object_delete(blockcopy);
224         FLAC__metadata_object_delete(block);
225         printf("OK\n");
226
227
228         printf("testing PADDING\n");
229
230         printf("testing FLAC__metadata_object_new()... ");
231         block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
232         if(0 == block) {
233                 printf("FAILED, returned NULL\n");
234                 return false;
235         }
236         expected_length = 0;
237         if(block->length != expected_length) {
238                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length);
239                 return false;
240     }
241         printf("OK\n");
242
243         printf("testing FLAC__metadata_object_clone()... ");
244         blockcopy = FLAC__metadata_object_clone(block);
245         if(0 == blockcopy) {
246                 printf("FAILED, returned NULL\n");
247                 return false;
248         }
249         if(!compare_block_(block, blockcopy))
250                 return false;
251         printf("OK\n");
252
253         printf("testing FLAC__metadata_object_delete()... ");
254         FLAC__metadata_object_delete(blockcopy);
255         FLAC__metadata_object_delete(block);
256         printf("OK\n");
257
258
259         printf("testing APPLICATION\n");
260
261         printf("testing FLAC__metadata_object_new()... ");
262         block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION);
263         if(0 == block) {
264                 printf("FAILED, returned NULL\n");
265                 return false;
266         }
267         expected_length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
268         if(block->length != expected_length) {
269                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length);
270                 return false;
271     }
272         printf("OK\n");
273
274         printf("testing FLAC__metadata_object_clone()... ");
275         blockcopy = FLAC__metadata_object_clone(block);
276         if(0 == blockcopy) {
277                 printf("FAILED, returned NULL\n");
278                 return false;
279         }
280         if(!compare_block_(block, blockcopy))
281                 return false;
282         printf("OK\n");
283
284         printf("testing FLAC__metadata_object_delete()... ");
285         FLAC__metadata_object_delete(blockcopy);
286         printf("OK\n");
287
288         printf("testing FLAC__metadata_object_application_set_data(copy)... ");
289         if(!FLAC__metadata_object_application_set_data(block, dummydata, sizeof(dummydata), true/*copy*/)) {
290                 printf("FAILED, returned false\n");
291                 return false;
292         }
293         expected_length = (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) + sizeof(dummydata);
294         if(block->length != expected_length) {
295                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length);
296                 return false;
297         }
298         if(0 != memcmp(block->data.application.data, dummydata, sizeof(dummydata))) {
299                 printf("FAILED, data mismatch\n");
300                 return false;
301         }
302         printf("OK\n");
303
304         printf("testing FLAC__metadata_object_clone()... ");
305         blockcopy = FLAC__metadata_object_clone(block);
306         if(0 == blockcopy) {
307                 printf("FAILED, returned NULL\n");
308                 return false;
309         }
310         if(!compare_block_(block, blockcopy))
311                 return false;
312         printf("OK\n");
313
314         printf("testing FLAC__metadata_object_delete()... ");
315         FLAC__metadata_object_delete(blockcopy);
316         printf("OK\n");
317
318         printf("testing FLAC__metadata_object_application_set_data(own)... ");
319         if(!FLAC__metadata_object_application_set_data(block, make_dummydata_(dummydata, sizeof(dummydata)), sizeof(dummydata), false/*own*/)) {
320                 printf("FAILED, returned false\n");
321                 return false;
322         }
323         expected_length = (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) + sizeof(dummydata);
324         if(block->length != expected_length) {
325                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length);
326                 return false;
327         }
328         if(0 != memcmp(block->data.application.data, dummydata, sizeof(dummydata))) {
329                 printf("FAILED, data mismatch\n");
330                 return false;
331         }
332         printf("OK\n");
333
334         printf("testing FLAC__metadata_object_clone()... ");
335         blockcopy = FLAC__metadata_object_clone(block);
336         if(0 == blockcopy) {
337                 printf("FAILED, returned NULL\n");
338                 return false;
339         }
340         if(!compare_block_(block, blockcopy))
341                 return false;
342         printf("OK\n");
343
344         printf("testing FLAC__metadata_object_delete()... ");
345         FLAC__metadata_object_delete(blockcopy);
346         FLAC__metadata_object_delete(block);
347         printf("OK\n");
348
349
350         printf("testing SEEKTABLE\n");
351
352         for(i = 0; i < sizeof(seekpoint_array) / sizeof(FLAC__StreamMetadata_SeekPoint); i++) {
353                 seekpoint_array[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
354                 seekpoint_array[i].stream_offset = 0;
355                 seekpoint_array[i].frame_samples = 0;
356         }
357
358         seekpoints = 0;
359         printf("testing FLAC__metadata_object_new()... ");
360         block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE);
361         if(0 == block) {
362                 printf("FAILED, returned NULL\n");
363                 return false;
364         }
365         if(!check_seektable_(block, seekpoints, 0))
366                 return false;
367
368         printf("testing FLAC__metadata_object_clone()... ");
369         blockcopy = FLAC__metadata_object_clone(block);
370         if(0 == blockcopy) {
371                 printf("FAILED, returned NULL\n");
372                 return false;
373         }
374         if(!compare_block_(block, blockcopy))
375                 return false;
376         printf("OK\n");
377
378         printf("testing FLAC__metadata_object_delete()... ");
379         FLAC__metadata_object_delete(blockcopy);
380         printf("OK\n");
381
382         seekpoints = 2;
383         printf("testing FLAC__metadata_object_seektable_resize_points(grow to %u)...", seekpoints);
384         if(!FLAC__metadata_object_seektable_resize_points(block, seekpoints)) {
385                 printf("FAILED, returned false\n");
386                 return false;
387         }
388         if(!check_seektable_(block, seekpoints, seekpoint_array))
389                 return false;
390
391         seekpoints = 1;
392         printf("testing FLAC__metadata_object_seektable_resize_points(shrink to %u)...", seekpoints);
393         if(!FLAC__metadata_object_seektable_resize_points(block, seekpoints)) {
394                 printf("FAILED, returned false\n");
395                 return false;
396         }
397         if(!check_seektable_(block, seekpoints, seekpoint_array))
398                 return false;
399
400         printf("testing FLAC__metadata_object_seektable_is_legal()...");
401         if(!FLAC__metadata_object_seektable_is_legal(block)) {
402                 printf("FAILED, returned false\n");
403                 return false;
404         }
405         printf("OK\n");
406
407         seekpoints = 0;
408         printf("testing FLAC__metadata_object_seektable_resize_points(shrink to %u)...", seekpoints);
409         if(!FLAC__metadata_object_seektable_resize_points(block, seekpoints)) {
410                 printf("FAILED, returned false\n");
411                 return false;
412         }
413         if(!check_seektable_(block, seekpoints, 0))
414                 return false;
415
416         seekpoints++;
417         printf("testing FLAC__metadata_object_seektable_insert_point() on empty array...");
418         if(!FLAC__metadata_object_seektable_insert_point(block, 0, seekpoint_array[0])) {
419                 printf("FAILED, returned false\n");
420                 return false;
421         }
422         if(!check_seektable_(block, seekpoints, seekpoint_array))
423                 return false;
424
425         seekpoint_array[0].sample_number = 1;
426         seekpoints++;
427         printf("testing FLAC__metadata_object_seektable_insert_point() on beginning of non-empty array...");
428         if(!FLAC__metadata_object_seektable_insert_point(block, 0, seekpoint_array[0])) {
429                 printf("FAILED, returned false\n");
430                 return false;
431         }
432         if(!check_seektable_(block, seekpoints, seekpoint_array))
433                 return false;
434
435         seekpoint_array[1].sample_number = 2;
436         seekpoints++;
437         printf("testing FLAC__metadata_object_seektable_insert_point() on middle of non-empty array...");
438         if(!FLAC__metadata_object_seektable_insert_point(block, 1, seekpoint_array[1])) {
439                 printf("FAILED, returned false\n");
440                 return false;
441         }
442         if(!check_seektable_(block, seekpoints, seekpoint_array))
443                 return false;
444
445         seekpoint_array[3].sample_number = 3;
446         seekpoints++;
447         printf("testing FLAC__metadata_object_seektable_insert_point() on end of non-empty array...");
448         if(!FLAC__metadata_object_seektable_insert_point(block, 3, seekpoint_array[3])) {
449                 printf("FAILED, returned false\n");
450                 return false;
451         }
452         if(!check_seektable_(block, seekpoints, seekpoint_array))
453                 return false;
454
455         printf("testing FLAC__metadata_object_clone()... ");
456         blockcopy = FLAC__metadata_object_clone(block);
457         if(0 == blockcopy) {
458                 printf("FAILED, returned NULL\n");
459                 return false;
460         }
461         if(!compare_block_(block, blockcopy))
462                 return false;
463         printf("OK\n");
464
465         printf("testing FLAC__metadata_object_delete()... ");
466         FLAC__metadata_object_delete(blockcopy);
467         printf("OK\n");
468
469         seekpoint_array[2].sample_number = seekpoint_array[3].sample_number;
470         seekpoints--;
471         printf("testing FLAC__metadata_object_seektable_delete_point() on middle of array...");
472         if(!FLAC__metadata_object_seektable_delete_point(block, 2)) {
473                 printf("FAILED, returned false\n");
474                 return false;
475         }
476         if(!check_seektable_(block, seekpoints, seekpoint_array))
477                 return false;
478
479         seekpoints--;
480         printf("testing FLAC__metadata_object_seektable_delete_point() on end of array...");
481         if(!FLAC__metadata_object_seektable_delete_point(block, 2)) {
482                 printf("FAILED, returned false\n");
483                 return false;
484         }
485         if(!check_seektable_(block, seekpoints, seekpoint_array))
486                 return false;
487
488         seekpoints--;
489         printf("testing FLAC__metadata_object_seektable_delete_point() on beginning of array...");
490         if(!FLAC__metadata_object_seektable_delete_point(block, 0)) {
491                 printf("FAILED, returned false\n");
492                 return false;
493         }
494         if(!check_seektable_(block, seekpoints, seekpoint_array+1))
495                 return false;
496
497         printf("testing FLAC__metadata_object_seektable_set_point()...");
498         FLAC__metadata_object_seektable_set_point(block, 0, seekpoint_array[0]);
499         if(!check_seektable_(block, seekpoints, seekpoint_array))
500                 return false;
501
502         printf("testing FLAC__metadata_object_delete()... ");
503         FLAC__metadata_object_delete(block);
504         printf("OK\n");
505
506         /* seektable template functions */
507
508         for(i = 0; i < sizeof(seekpoint_array) / sizeof(FLAC__StreamMetadata_SeekPoint); i++) {
509                 seekpoint_array[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
510                 seekpoint_array[i].stream_offset = 0;
511                 seekpoint_array[i].frame_samples = 0;
512         }
513
514         seekpoints = 0;
515         printf("testing FLAC__metadata_object_new()... ");
516         block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE);
517         if(0 == block) {
518                 printf("FAILED, returned NULL\n");
519                 return false;
520         }
521         if(!check_seektable_(block, seekpoints, 0))
522                 return false;
523
524         seekpoints += 2;
525         printf("testing FLAC__metadata_object_seekpoint_template_append_placeholders()... ");
526         if(!FLAC__metadata_object_seektable_template_append_placeholders(block, 2)) {
527                 printf("FAILED, returned false\n");
528                 return false;
529         }
530         if(!check_seektable_(block, seekpoints, seekpoint_array))
531                 return false;
532
533         seekpoint_array[seekpoints++].sample_number = 7;
534         printf("testing FLAC__metadata_object_seekpoint_template_append_point()... ");
535         if(!FLAC__metadata_object_seektable_template_append_point(block, 7)) {
536                 printf("FAILED, returned false\n");
537                 return false;
538         }
539         if(!check_seektable_(block, seekpoints, seekpoint_array))
540                 return false;
541
542     {
543                 FLAC__uint64 nums[2] = { 3, 7 };
544                 seekpoint_array[seekpoints++].sample_number = nums[0];
545                 seekpoint_array[seekpoints++].sample_number = nums[1];
546                 printf("testing FLAC__metadata_object_seekpoint_template_append_points()... ");
547                 if(!FLAC__metadata_object_seektable_template_append_points(block, nums, sizeof(nums)/sizeof(FLAC__uint64))) {
548                         printf("FAILED, returned false\n");
549                         return false;
550                 }
551                 if(!check_seektable_(block, seekpoints, seekpoint_array))
552                         return false;
553         }
554
555         seekpoint_array[seekpoints++].sample_number = 0;
556         seekpoint_array[seekpoints++].sample_number = 10;
557         seekpoint_array[seekpoints++].sample_number = 20;
558         printf("testing FLAC__metadata_object_seekpoint_template_append_spaced_points()... ");
559         if(!FLAC__metadata_object_seektable_template_append_spaced_points(block, 3, 30)) {
560                 printf("FAILED, returned false\n");
561                 return false;
562         }
563         if(!check_seektable_(block, seekpoints, seekpoint_array))
564                 return false;
565
566         seekpoints--;
567         seekpoint_array[0].sample_number = 0;
568         seekpoint_array[1].sample_number = 3;
569         seekpoint_array[2].sample_number = 7;
570         seekpoint_array[3].sample_number = 10;
571         seekpoint_array[4].sample_number = 20;
572         seekpoint_array[5].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
573         seekpoint_array[6].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
574         printf("testing FLAC__metadata_object_seekpoint_template_sort(compact=true)... ");
575         if(!FLAC__metadata_object_seektable_template_sort(block, /*compact=*/true)) {
576                 printf("FAILED, returned false\n");
577                 return false;
578         }
579         if(!FLAC__metadata_object_seektable_is_legal(block)) {
580                 printf("FAILED, seek table is illegal\n");
581                 return false;
582         }
583         if(!check_seektable_(block, seekpoints, seekpoint_array))
584                 return false;
585
586         printf("testing FLAC__metadata_object_seekpoint_template_sort(compact=false)... ");
587         if(!FLAC__metadata_object_seektable_template_sort(block, /*compact=*/false)) {
588                 printf("FAILED, returned false\n");
589                 return false;
590         }
591         if(!FLAC__metadata_object_seektable_is_legal(block)) {
592                 printf("FAILED, seek table is illegal\n");
593                 return false;
594         }
595         if(!check_seektable_(block, seekpoints, seekpoint_array))
596                 return false;
597
598         printf("testing FLAC__metadata_object_delete()... ");
599         FLAC__metadata_object_delete(block);
600         printf("OK\n");
601
602
603         printf("testing VORBIS_COMMENT\n");
604
605         printf("testing FLAC__metadata_object_new()... ");
606         block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
607         if(0 == block) {
608                 printf("FAILED, returned NULL\n");
609                 return false;
610         }
611         expected_length = (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN + FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8;
612         if(block->length != expected_length) {
613                 printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length);
614                 return false;
615     }
616         printf("OK\n");
617
618         printf("testing FLAC__metadata_object_clone()... ");
619         vorbiscomment = FLAC__metadata_object_clone(block);
620         if(0 == vorbiscomment) {
621                 printf("FAILED, returned NULL\n");
622                 return false;
623         }
624         if(!compare_block_(vorbiscomment, block))
625                 return false;
626         printf("OK\n");
627
628         vc_resize_(vorbiscomment, 2);
629         printf("testing FLAC__metadata_object_vorbiscomment_resize_comments(grow to %u)...", vorbiscomment->data.vorbis_comment.num_comments);
630         if(!FLAC__metadata_object_vorbiscomment_resize_comments(block, vorbiscomment->data.vorbis_comment.num_comments)) {
631                 printf("FAILED, returned false\n");
632                 return false;
633         }
634         if(!compare_block_(vorbiscomment, block))
635                 return false;
636         printf("OK\n");
637
638         vc_resize_(vorbiscomment, 1);
639         printf("testing FLAC__metadata_object_vorbiscomment_resize_comments(shrink to %u)...", vorbiscomment->data.vorbis_comment.num_comments);
640         if(!FLAC__metadata_object_vorbiscomment_resize_comments(block, vorbiscomment->data.vorbis_comment.num_comments)) {
641                 printf("FAILED, returned false\n");
642                 return false;
643         }
644         if(!compare_block_(vorbiscomment, block))
645                 return false;
646         printf("OK\n");
647
648         vc_resize_(vorbiscomment, 0);
649         printf("testing FLAC__metadata_object_vorbiscomment_resize_comments(shrink to %u)...", vorbiscomment->data.vorbis_comment.num_comments);
650         if(!FLAC__metadata_object_vorbiscomment_resize_comments(block, vorbiscomment->data.vorbis_comment.num_comments)) {
651                 printf("FAILED, returned false\n");
652                 return false;
653         }
654         if(!compare_block_(vorbiscomment, block))
655                 return false;
656         printf("OK\n");
657
658         printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(copy) on empty array...");
659         vc_insert_new_(&entry, vorbiscomment, 0, "name1=field1");
660         if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 0, entry, /*copy=*/true)) {
661                 printf("FAILED, returned false\n");
662                 return false;
663         }
664         if(!compare_block_(vorbiscomment, block))
665                 return false;
666         printf("OK\n");
667
668         printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(copy) on beginning of non-empty array...");
669         vc_insert_new_(&entry, vorbiscomment, 0, "name2=field2");
670         if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 0, entry, /*copy=*/true)) {
671                 printf("FAILED, returned false\n");
672                 return false;
673         }
674         if(!compare_block_(vorbiscomment, block))
675                 return false;
676         printf("OK\n");
677
678         printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(copy) on middle of non-empty array...");
679         vc_insert_new_(&entry, vorbiscomment, 1, "name3=field3");
680         if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 1, entry, /*copy=*/true)) {
681                 printf("FAILED, returned false\n");
682                 return false;
683         }
684         if(!compare_block_(vorbiscomment, block))
685                 return false;
686         printf("OK\n");
687
688         printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(copy) on end of non-empty array...");
689         vc_insert_new_(&entry, vorbiscomment, 3, "name4=field4");
690         if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 3, entry, /*copy=*/true)) {
691                 printf("FAILED, returned false\n");
692                 return false;
693         }
694         if(!compare_block_(vorbiscomment, block))
695                 return false;
696         printf("OK\n");
697
698         printf("testing FLAC__metadata_object_clone()... ");
699         blockcopy = FLAC__metadata_object_clone(block);
700         if(0 == blockcopy) {
701                 printf("FAILED, returned NULL\n");
702                 return false;
703         }
704         if(!compare_block_(block, blockcopy))
705                 return false;
706         printf("OK\n");
707
708         printf("testing FLAC__metadata_object_delete()... ");
709         FLAC__metadata_object_delete(blockcopy);
710         printf("OK\n");
711
712         printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on middle of array...");
713         vc_delete_(vorbiscomment, 2);
714         if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 2)) {
715                 printf("FAILED, returned false\n");
716                 return false;
717         }
718         if(!compare_block_(vorbiscomment, block))
719                 return false;
720         printf("OK\n");
721
722         printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on end of array...");
723         vc_delete_(vorbiscomment, 2);
724         if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 2)) {
725                 printf("FAILED, returned false\n");
726                 return false;
727         }
728         if(!compare_block_(vorbiscomment, block))
729                 return false;
730         printf("OK\n");
731
732         printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on beginning of array...");
733         vc_delete_(vorbiscomment, 0);
734         if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 0)) {
735                 printf("FAILED, returned false\n");
736                 return false;
737         }
738         if(!compare_block_(vorbiscomment, block))
739                 return false;
740         printf("OK\n");
741
742         printf("testing FLAC__metadata_object_vorbiscomment_set_comment(copy)...");
743         vc_set_new_(&entry, vorbiscomment, 0, "name5=field5");
744         FLAC__metadata_object_vorbiscomment_set_comment(block, 0, entry, /*copy=*/true);
745         if(!compare_block_(vorbiscomment, block))
746                 return false;
747         printf("OK\n");
748
749         printf("testing FLAC__metadata_object_vorbiscomment_set_vendor_string(copy)...");
750         vc_set_vs_new_(&entry, vorbiscomment, "name6=field6");
751         FLAC__metadata_object_vorbiscomment_set_vendor_string(block, entry, /*copy=*/true);
752         if(!compare_block_(vorbiscomment, block))
753                 return false;
754         printf("OK\n");
755
756         printf("testing FLAC__metadata_object_delete()... ");
757         FLAC__metadata_object_delete(vorbiscomment);
758         FLAC__metadata_object_delete(block);
759         printf("OK\n");
760
761
762         printf("testing FLAC__metadata_object_new()... ");
763         block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
764         if(0 == block) {
765                 printf("FAILED, returned NULL\n");
766                 return false;
767         }
768         printf("OK\n");
769
770         printf("testing FLAC__metadata_object_clone()... ");
771         vorbiscomment = FLAC__metadata_object_clone(block);
772         if(0 == vorbiscomment) {
773                 printf("FAILED, returned NULL\n");
774                 return false;
775         }
776         if(!compare_block_(vorbiscomment, block))
777                 return false;
778         printf("OK\n");
779
780         printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(own) on empty array...");
781         vc_insert_new_(&entry, vorbiscomment, 0, "name1=field1");
782         entry_clone_(&entry);
783         if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 0, entry, /*copy=*/false)) {
784                 printf("FAILED, returned false\n");
785                 return false;
786         }
787         if(!compare_block_(vorbiscomment, block))
788                 return false;
789         printf("OK\n");
790
791         printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(own) on beginning of non-empty array...");
792         vc_insert_new_(&entry, vorbiscomment, 0, "name2=field2");
793         entry_clone_(&entry);
794         if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 0, entry, /*copy=*/false)) {
795                 printf("FAILED, returned false\n");
796                 return false;
797         }
798         if(!compare_block_(vorbiscomment, block))
799                 return false;
800         printf("OK\n");
801
802         printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(own) on middle of non-empty array...");
803         vc_insert_new_(&entry, vorbiscomment, 1, "name3=field3");
804         entry_clone_(&entry);
805         if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 1, entry, /*copy=*/false)) {
806                 printf("FAILED, returned false\n");
807                 return false;
808         }
809         if(!compare_block_(vorbiscomment, block))
810                 return false;
811         printf("OK\n");
812
813         printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(own) on end of non-empty array...");
814         vc_insert_new_(&entry, vorbiscomment, 3, "name4=field4");
815         entry_clone_(&entry);
816         if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 3, entry, /*copy=*/false)) {
817                 printf("FAILED, returned false\n");
818                 return false;
819         }
820         if(!compare_block_(vorbiscomment, block))
821                 return false;
822         printf("OK\n");
823
824         printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on middle of array...");
825         vc_delete_(vorbiscomment, 2);
826         if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 2)) {
827                 printf("FAILED, returned false\n");
828                 return false;
829         }
830         if(!compare_block_(vorbiscomment, block))
831                 return false;
832         printf("OK\n");
833
834         printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on end of array...");
835         vc_delete_(vorbiscomment, 2);
836         if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 2)) {
837                 printf("FAILED, returned false\n");
838                 return false;
839         }
840         if(!compare_block_(vorbiscomment, block))
841                 return false;
842         printf("OK\n");
843
844         printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on beginning of array...");
845         vc_delete_(vorbiscomment, 0);
846         if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 0)) {
847                 printf("FAILED, returned false\n");
848                 return false;
849         }
850         if(!compare_block_(vorbiscomment, block))
851                 return false;
852         printf("OK\n");
853
854         printf("testing FLAC__metadata_object_vorbiscomment_set_comment(own)...");
855         vc_set_new_(&entry, vorbiscomment, 0, "name5=field5");
856         entry_clone_(&entry);
857         FLAC__metadata_object_vorbiscomment_set_comment(block, 0, entry, /*copy=*/false);
858         if(!compare_block_(vorbiscomment, block))
859                 return false;
860         printf("OK\n");
861
862         printf("testing FLAC__metadata_object_vorbiscomment_set_vendor_string(own)...");
863         vc_set_vs_new_(&entry, vorbiscomment, "name6=field6");
864         entry_clone_(&entry);
865         FLAC__metadata_object_vorbiscomment_set_vendor_string(block, entry, /*copy=*/false);
866         if(!compare_block_(vorbiscomment, block))
867                 return false;
868         printf("OK\n");
869
870         printf("testing FLAC__metadata_object_delete()... ");
871         FLAC__metadata_object_delete(vorbiscomment);
872         FLAC__metadata_object_delete(block);
873         printf("OK\n");
874
875
876         return true;
877 }