revamp decoder process calls
[flac.git] / src / test_libFLAC / metadata_manip.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 "file_utils.h"
20 #include "metadata_utils.h"
21 #include "FLAC/assert.h"
22 #include "FLAC/file_decoder.h"
23 #include "FLAC/metadata.h"
24 #include <stdio.h>
25 #include <stdlib.h> /* for malloc() */
26
27 /******************************************************************************
28         The general strategy of these tests (for interface levels 1 and 2) is
29         to create a dummy FLAC file with a known set of initial metadata
30         blocks, then keep a mirror locally of what we expect the metadata to be
31         after each operation.  Then testing becomes a simple matter of running
32         a FLAC__FileDecoder over the dummy file after each operation, comparing
33         the decoded metadata to what's in our local copy.  If there are any
34         differences in the metadata, or the actual audio data is corrupted, we
35         will catch it while decoding.
36 ******************************************************************************/
37
38 typedef struct {
39         FLAC__bool error_occurred;
40 } decoder_client_struct;
41
42 typedef struct {
43         FLAC__StreamMetadata *blocks[64];
44         unsigned num_blocks;
45 } our_metadata_struct;
46
47 static const char *flacfile_ = "metadata.flac";
48
49 /* our copy of the metadata in flacfile_ */
50 static our_metadata_struct our_metadata_;
51
52 /* the current block number that corresponds to the position of the iterator we are testing */
53 static unsigned mc_our_block_number_ = 0;
54
55 static FLAC__bool die_(const char *msg)
56 {
57         printf("ERROR: %s\n", msg);
58         return false;
59 }
60
61 static FLAC__bool die_c_(const char *msg, FLAC__Metadata_ChainStatus status)
62 {
63         printf("ERROR: %s\n", msg);
64         printf("       status=%s\n", FLAC__Metadata_ChainStatusString[status]);
65         return false;
66 }
67
68 static FLAC__bool die_ss_(const char *msg, FLAC__Metadata_SimpleIterator *iterator)
69 {
70         printf("ERROR: %s\n", msg);
71         printf("       status=%s\n", FLAC__Metadata_SimpleIteratorStatusString[FLAC__metadata_simple_iterator_status(iterator)]);
72         return false;
73 }
74
75 /* functions for working with our metadata copy */
76
77 static FLAC__bool replace_in_our_metadata_(FLAC__StreamMetadata *block, unsigned position, FLAC__bool copy)
78 {
79         unsigned i;
80         FLAC__StreamMetadata *obj = block;
81         FLAC__ASSERT(position < our_metadata_.num_blocks);
82         if(copy) {
83                 if(0 == (obj = FLAC__metadata_object_clone(block)))
84                         return die_("during FLAC__metadata_object_clone()");
85         }
86         FLAC__metadata_object_delete(our_metadata_.blocks[position]);
87         our_metadata_.blocks[position] = obj;
88
89         /* set the is_last flags */
90         for(i = 0; i < our_metadata_.num_blocks - 1; i++)
91                 our_metadata_.blocks[i]->is_last = false;
92         our_metadata_.blocks[i]->is_last = true;
93
94         return true;
95 }
96
97 static FLAC__bool insert_to_our_metadata_(FLAC__StreamMetadata *block, unsigned position, FLAC__bool copy)
98 {
99         unsigned i;
100         FLAC__StreamMetadata *obj = block;
101         if(copy) {
102                 if(0 == (obj = FLAC__metadata_object_clone(block)))
103                         return die_("during FLAC__metadata_object_clone()");
104         }
105         if(position > our_metadata_.num_blocks) {
106                 position = our_metadata_.num_blocks;
107         }
108         else {
109                 for(i = our_metadata_.num_blocks; i > position; i--)
110                         our_metadata_.blocks[i] = our_metadata_.blocks[i-1];
111         }
112         our_metadata_.blocks[position] = obj;
113         our_metadata_.num_blocks++;
114
115         /* set the is_last flags */
116         for(i = 0; i < our_metadata_.num_blocks - 1; i++)
117                 our_metadata_.blocks[i]->is_last = false;
118         our_metadata_.blocks[i]->is_last = true;
119
120         return true;
121 }
122
123 static void delete_from_our_metadata_(unsigned position)
124 {
125         unsigned i;
126         FLAC__ASSERT(position < our_metadata_.num_blocks);
127         FLAC__metadata_object_delete(our_metadata_.blocks[position]);
128         for(i = position; i < our_metadata_.num_blocks - 1; i++)
129                 our_metadata_.blocks[i] = our_metadata_.blocks[i+1];
130         our_metadata_.num_blocks--;
131
132         /* set the is_last flags */
133         if(our_metadata_.num_blocks > 0) {
134                 for(i = 0; i < our_metadata_.num_blocks - 1; i++)
135                         our_metadata_.blocks[i]->is_last = false;
136                 our_metadata_.blocks[i]->is_last = true;
137         }
138 }
139
140 /* function for comparing our metadata to a FLAC__Metadata_Chain */
141
142 static FLAC__bool compare_chain_(FLAC__Metadata_Chain *chain, unsigned current_position, FLAC__StreamMetadata *current_block)
143 {
144         unsigned i;
145         FLAC__Metadata_Iterator *iterator;
146         FLAC__StreamMetadata *block;
147         FLAC__bool next_ok = true;
148
149         FLAC__ASSERT(0 != chain);
150
151         printf("\tcomparing chain... ");
152         fflush(stdout);
153
154         if(0 == (iterator = FLAC__metadata_iterator_new()))
155                 return die_("allocating memory for iterator");
156
157         FLAC__metadata_iterator_init(iterator, chain);
158
159         i = 0;
160         do {
161                 printf("%u... ", i);
162                 fflush(stdout);
163
164                 if(0 == (block = FLAC__metadata_iterator_get_block(iterator))) {
165                         FLAC__metadata_iterator_delete(iterator);
166                         return die_("getting block from iterator");
167                 }
168
169                 if(!compare_block_(our_metadata_.blocks[i], block)) {
170                         FLAC__metadata_iterator_delete(iterator);
171                         return die_("metadata block mismatch");
172                 }
173
174                 i++;
175                 next_ok = FLAC__metadata_iterator_next(iterator);
176         } while(i < our_metadata_.num_blocks && next_ok);
177
178         FLAC__metadata_iterator_delete(iterator);
179
180         if(next_ok)
181                 return die_("chain has more blocks than expected");
182
183         if(i < our_metadata_.num_blocks)
184                 return die_("short block count in chain");
185
186         if(0 != current_block) {
187                 printf("CURRENT_POSITION... ");
188                 fflush(stdout);
189
190                 if(!compare_block_(our_metadata_.blocks[current_position], current_block))
191                         return die_("metadata block mismatch");
192         }
193
194         printf("PASSED\n");
195
196         return true;
197 }
198
199 /* decoder callbacks for checking the file */
200
201 static FLAC__StreamDecoderWriteStatus decoder_write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
202 {
203         (void)decoder, (void)buffer, (void)client_data;
204
205         if(
206                 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
207                 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
208         ) {
209                 printf("content... ");
210                 fflush(stdout);
211         }
212
213         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
214 }
215
216 /* this version pays no attention to the metadata */
217 static void decoder_metadata_callback_null_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
218 {
219         (void)decoder, (void)metadata, (void)client_data;
220
221         printf("%d... ", mc_our_block_number_);
222         fflush(stdout);
223
224         mc_our_block_number_++;
225 }
226
227 /* this version is used when we want to compare to our metadata copy */
228 static void decoder_metadata_callback_compare_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
229 {
230         decoder_client_struct *dcd = (decoder_client_struct*)client_data;
231
232         (void)decoder;
233
234         /* don't bother checking if we've already hit an error */
235         if(dcd->error_occurred)
236                 return;
237
238         printf("%d... ", mc_our_block_number_);
239         fflush(stdout);
240
241         if(mc_our_block_number_ >= our_metadata_.num_blocks) {
242                 (void)die_("got more metadata blocks than expected");
243                 dcd->error_occurred = true;
244         }
245         else {
246                 if(!compare_block_(our_metadata_.blocks[mc_our_block_number_], metadata)) {
247                         (void)die_("metadata block mismatch");
248                         dcd->error_occurred = true;
249                 }
250         }
251         mc_our_block_number_++;
252 }
253
254 static void decoder_error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
255 {
256         decoder_client_struct *dcd = (decoder_client_struct*)client_data;
257         (void)decoder;
258
259         dcd->error_occurred = true;
260         printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);
261 }
262
263 static FLAC__bool generate_file_()
264 {
265         FLAC__StreamMetadata streaminfo, padding;
266         FLAC__StreamMetadata *metadata[1];
267
268         printf("generating FLAC file for test\n");
269
270         while(our_metadata_.num_blocks > 0)
271                 delete_from_our_metadata_(0);
272
273         streaminfo.is_last = false;
274         streaminfo.type = FLAC__METADATA_TYPE_STREAMINFO;
275         streaminfo.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
276         streaminfo.data.stream_info.min_blocksize = 576;
277         streaminfo.data.stream_info.max_blocksize = 576;
278         streaminfo.data.stream_info.min_framesize = 0;
279         streaminfo.data.stream_info.max_framesize = 0;
280         streaminfo.data.stream_info.sample_rate = 44100;
281         streaminfo.data.stream_info.channels = 1;
282         streaminfo.data.stream_info.bits_per_sample = 8;
283         streaminfo.data.stream_info.total_samples = 0;
284         memset(streaminfo.data.stream_info.md5sum, 0, 16);
285
286         padding.is_last = true;
287         padding.type = FLAC__METADATA_TYPE_PADDING;
288         padding.length = 1234;
289
290         metadata[0] = &padding;
291
292         if(!insert_to_our_metadata_(&streaminfo, 0, /*copy=*/true) || !insert_to_our_metadata_(&padding, 1, /*copy=*/true))
293                 return die_("priming our metadata");
294
295         if(!file_utils__generate_flacfile(flacfile_, 0, 512 * 1024, &streaminfo, metadata, 1))
296                 return die_("creating the encoded file"); 
297
298         return true;
299 }
300
301 static FLAC__bool test_file_(const char *filename, void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data))
302 {
303         FLAC__FileDecoder *decoder;
304         decoder_client_struct decoder_client_data;
305
306         FLAC__ASSERT(0 != filename);
307         FLAC__ASSERT(0 != metadata_callback);
308
309         mc_our_block_number_ = 0;
310         decoder_client_data.error_occurred = false;
311
312         printf("\ttesting '%s'... ", filename);
313         fflush(stdout);
314
315         if(0 == (decoder = FLAC__file_decoder_new()))
316                 return die_("couldn't allocate decoder instance");
317
318         FLAC__file_decoder_set_md5_checking(decoder, true);
319         FLAC__file_decoder_set_filename(decoder, filename);
320         FLAC__file_decoder_set_write_callback(decoder, decoder_write_callback_);
321         FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback);
322         FLAC__file_decoder_set_error_callback(decoder, decoder_error_callback_);
323         FLAC__file_decoder_set_client_data(decoder, &decoder_client_data);
324         FLAC__file_decoder_set_metadata_respond_all(decoder);
325         if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK) {
326                 FLAC__file_decoder_finish(decoder);
327                 FLAC__file_decoder_delete(decoder);
328                 return die_("initializing decoder\n");
329         }
330         if(!FLAC__file_decoder_process_until_end_of_file(decoder)) {
331                 FLAC__file_decoder_finish(decoder);
332                 FLAC__file_decoder_delete(decoder);
333                 return die_("decoding file\n");
334         }
335
336         FLAC__file_decoder_finish(decoder);
337         FLAC__file_decoder_delete(decoder);
338
339         if(decoder_client_data.error_occurred)
340                 return false;
341
342         if(mc_our_block_number_ != our_metadata_.num_blocks)
343                 return die_("short metadata block count");
344
345         printf("PASSED\n");
346         return true;
347 }
348
349 static FLAC__bool change_stats_(const char *filename, FLAC__bool read_only)
350 {
351         if(!file_utils__change_stats(filename, read_only))
352         return die_("during file_utils__change_stats()");
353
354         return true;
355 }
356
357 static FLAC__bool remove_file_(const char *filename)
358 {
359         while(our_metadata_.num_blocks > 0)
360                 delete_from_our_metadata_(0);
361
362         if(!file_utils__remove_file(filename))
363                 return die_("removing file");
364
365         return true;
366 }
367
368 static FLAC__bool test_level_0_()
369 {
370         FLAC__StreamMetadata streaminfo;
371
372         printf("\n\n++++++ testing level 0 interface\n");
373
374         if(!generate_file_())
375                 return false;
376
377         if(!test_file_(flacfile_, decoder_metadata_callback_null_))
378                 return false;
379
380         if(!FLAC__metadata_get_streaminfo(flacfile_, &streaminfo))
381                 return die_("during FLAC__metadata_get_streaminfo()");
382
383         /* check to see if some basic data matches (c.f. generate_file_()) */
384         if(streaminfo.data.stream_info.channels != 1)
385                 return die_("mismatch in streaminfo.data.stream_info.channels");
386         if(streaminfo.data.stream_info.bits_per_sample != 8)
387                 return die_("mismatch in streaminfo.data.stream_info.bits_per_sample");
388         if(streaminfo.data.stream_info.sample_rate != 44100)
389                 return die_("mismatch in streaminfo.data.stream_info.sample_rate");
390         if(streaminfo.data.stream_info.min_blocksize != 576)
391                 return die_("mismatch in streaminfo.data.stream_info.min_blocksize");
392         if(streaminfo.data.stream_info.max_blocksize != 576)
393                 return die_("mismatch in streaminfo.data.stream_info.max_blocksize");
394
395         if(!remove_file_(flacfile_))
396                 return false;
397
398         return true;
399 }
400
401 static FLAC__bool test_level_1_()
402 {
403         FLAC__Metadata_SimpleIterator *iterator;
404         FLAC__StreamMetadata *block, *app, *padding;
405         FLAC__byte data[1000];
406         unsigned our_current_position = 0;
407
408         printf("\n\n++++++ testing level 1 interface\n");
409
410         /************************************************************/
411
412         printf("simple iterator on read-only file\n");
413
414         if(!generate_file_())
415                 return false;
416
417         if(!change_stats_(flacfile_, /*read_only=*/true))
418                 return false;
419
420         if(!test_file_(flacfile_, decoder_metadata_callback_null_))
421                 return false;
422
423         if(0 == (iterator = FLAC__metadata_simple_iterator_new()))
424                 return die_("FLAC__metadata_simple_iterator_new()");
425
426         if(!FLAC__metadata_simple_iterator_init(iterator, flacfile_, false))
427                 return die_("FLAC__metadata_simple_iterator_init() returned false");
428
429         printf("is writable = %u\n", (unsigned)FLAC__metadata_simple_iterator_is_writable(iterator));
430         if(FLAC__metadata_simple_iterator_is_writable(iterator))
431                 return die_("iterator claims file is writable when tester thinks it should not be; are you running as root?\n");
432
433         printf("iterate forwards\n");
434
435         if(FLAC__metadata_simple_iterator_get_block_type(iterator) != FLAC__METADATA_TYPE_STREAMINFO)
436                 return die_("expected STREAMINFO type from FLAC__metadata_simple_iterator_get_block_type()");
437         if(0 == (block = FLAC__metadata_simple_iterator_get_block(iterator)))
438                 return die_("getting block 0");
439         if(block->type != FLAC__METADATA_TYPE_STREAMINFO)
440                 return die_("expected STREAMINFO type");
441         if(block->is_last)
442                 return die_("expected is_last to be false");
443         if(block->length != FLAC__STREAM_METADATA_STREAMINFO_LENGTH)
444                 return die_("bad STREAMINFO length");
445         /* check to see if some basic data matches (c.f. generate_file_()) */
446         if(block->data.stream_info.channels != 1)
447                 return die_("mismatch in channels");
448         if(block->data.stream_info.bits_per_sample != 8)
449                 return die_("mismatch in bits_per_sample");
450         if(block->data.stream_info.sample_rate != 44100)
451                 return die_("mismatch in sample_rate");
452         if(block->data.stream_info.min_blocksize != 576)
453                 return die_("mismatch in min_blocksize");
454         if(block->data.stream_info.max_blocksize != 576)
455                 return die_("mismatch in max_blocksize");
456
457         if(!FLAC__metadata_simple_iterator_next(iterator))
458                 return die_("forward iterator ended early");
459         our_current_position++;
460
461         if(FLAC__metadata_simple_iterator_get_block_type(iterator) != FLAC__METADATA_TYPE_PADDING)
462                 return die_("expected PADDING type from FLAC__metadata_simple_iterator_get_block_type()");
463         if(0 == (block = FLAC__metadata_simple_iterator_get_block(iterator)))
464                 return die_("getting block 1");
465         if(block->type != FLAC__METADATA_TYPE_PADDING)
466                 return die_("expected PADDING type");
467         if(!block->is_last)
468                 return die_("expected is_last to be true");
469         /* check to see if some basic data matches (c.f. generate_file_()) */
470         if(block->length != 1234)
471                 return die_("bad PADDING length");
472
473         if(FLAC__metadata_simple_iterator_next(iterator))
474                 return die_("forward iterator returned true but should have returned false");
475
476         printf("iterate backwards\n");
477         if(!FLAC__metadata_simple_iterator_prev(iterator))
478                 return die_("reverse iterator ended early");
479         if(FLAC__metadata_simple_iterator_prev(iterator))
480                 return die_("reverse iterator returned true but should have returned false");
481
482         printf("testing FLAC__metadata_simple_iterator_set_block() on read-only file...\n");
483
484         if(!FLAC__metadata_simple_iterator_set_block(iterator, (FLAC__StreamMetadata*)99, false))
485                 printf("PASSED.  FLAC__metadata_simple_iterator_set_block() returned false like it should\n");
486         else
487                 return die_("FLAC__metadata_simple_iterator_set_block() returned true but shouldn't have");
488
489         FLAC__metadata_simple_iterator_delete(iterator);
490
491         /************************************************************/
492
493         printf("simple iterator on writable file\n");
494
495         if(!change_stats_(flacfile_, /*read-only=*/false))
496                 return false;
497
498         printf("creating APPLICATION block\n");
499
500         if(0 == (app = FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)))
501                 return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)");
502         memcpy(app->data.application.id, "duh", (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8));
503
504         printf("creating PADDING block\n");
505
506         if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
507                 return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)");
508         padding->length = 20;
509
510         if(0 == (iterator = FLAC__metadata_simple_iterator_new()))
511                 return die_("FLAC__metadata_simple_iterator_new()");
512
513         if(!FLAC__metadata_simple_iterator_init(iterator, flacfile_, /*preserve_file_stats=*/false))
514                 return die_("FLAC__metadata_simple_iterator_init() returned false");
515         our_current_position = 0;
516
517         printf("is writable = %u\n", (unsigned)FLAC__metadata_simple_iterator_is_writable(iterator));
518
519         printf("[S]P\ttry to write over STREAMINFO block...\n");
520         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
521                 printf("\tFLAC__metadata_simple_iterator_set_block() returned false like it should\n");
522         else
523                 return die_("FLAC__metadata_simple_iterator_set_block() returned true but shouldn't have");
524
525         printf("[S]P\tnext\n");
526         if(!FLAC__metadata_simple_iterator_next(iterator))
527                 return die_("iterator ended early\n");
528         our_current_position++;
529
530         printf("S[P]\tinsert PADDING after, don't expand into padding\n");
531         padding->length = 25;
532         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
533                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
534         if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
535                 return false;
536
537         printf("SP[P]\tprev\n");
538         if(!FLAC__metadata_simple_iterator_prev(iterator))
539                 return die_("iterator ended early\n");
540         our_current_position--;
541
542         printf("S[P]P\tprev\n");
543         if(!FLAC__metadata_simple_iterator_prev(iterator))
544                 return die_("iterator ended early\n");
545         our_current_position--;
546
547         printf("[S]PP\tinsert PADDING after, don't expand into padding\n");
548         padding->length = 30;
549         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
550                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
551         if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
552                 return false;
553
554         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
555                 return false;
556         
557         printf("S[P]PP\tprev\n");
558         if(!FLAC__metadata_simple_iterator_prev(iterator))
559                 return die_("iterator ended early\n");
560         our_current_position--;
561
562         printf("[S]PPP\tdelete (STREAMINFO block), must fail\n");
563         if(FLAC__metadata_simple_iterator_delete_block(iterator, false))
564                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false) should have returned false", iterator);
565
566         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
567                 return false;
568
569         printf("[S]PPP\tnext\n");
570         if(!FLAC__metadata_simple_iterator_next(iterator))
571                 return die_("iterator ended early\n");
572         our_current_position++;
573
574         printf("S[P]PP\tdelete (middle block), replace with padding\n");
575         if(!FLAC__metadata_simple_iterator_delete_block(iterator, true))
576                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, true)", iterator);
577         our_current_position--;
578
579         printf("[S]PPP\tnext\n");
580         if(!FLAC__metadata_simple_iterator_next(iterator))
581                 return die_("iterator ended early\n");
582         our_current_position++;
583
584         printf("S[P]PP\tdelete (middle block), don't replace with padding\n");
585         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
586                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
587         delete_from_our_metadata_(our_current_position--);
588
589         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
590                 return false;
591
592         printf("[S]PP\tnext\n");
593         if(!FLAC__metadata_simple_iterator_next(iterator))
594                 return die_("iterator ended early\n");
595         our_current_position++;
596
597         printf("S[P]P\tnext\n");
598         if(!FLAC__metadata_simple_iterator_next(iterator))
599                 return die_("iterator ended early\n");
600         our_current_position++;
601
602         printf("SP[P]\tdelete (last block), replace with padding\n");
603         if(!FLAC__metadata_simple_iterator_delete_block(iterator, true))
604                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
605         our_current_position--;
606
607         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
608                 return false;
609
610         printf("S[P]P\tnext\n");
611         if(!FLAC__metadata_simple_iterator_next(iterator))
612                 return die_("iterator ended early\n");
613         our_current_position++;
614
615         printf("SP[P]\tdelete (last block), don't replace with padding\n");
616         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
617                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
618         delete_from_our_metadata_(our_current_position--);
619
620         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
621                 return false;
622
623         printf("S[P]\tprev\n");
624         if(!FLAC__metadata_simple_iterator_prev(iterator))
625                 return die_("iterator ended early\n");
626         our_current_position--;
627
628         printf("[S]P\tset STREAMINFO (change sample rate)\n");
629         FLAC__ASSERT(our_current_position == 0);
630         block = FLAC__metadata_simple_iterator_get_block(iterator);
631         block->data.stream_info.sample_rate = 32000;
632         if(!replace_in_our_metadata_(block, our_current_position, /*copy=*/true))
633                 return die_("copying object");
634         if(!FLAC__metadata_simple_iterator_set_block(iterator, block, false))
635                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, block, false)", iterator);
636         FLAC__metadata_object_delete(block);
637
638         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
639                 return false;
640
641         printf("[S]P\tinsert APPLICATION after, expand into padding of exceeding size\n");
642         app->data.application.id[0] = 'e'; /* twiddle the id so that our comparison doesn't miss transposition */
643         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
644                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
645         if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
646                 return false;
647         our_metadata_.blocks[our_current_position+1]->length -= (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + app->length;
648
649         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
650                 return false;
651
652         printf("S[A]P\tnext\n");
653         if(!FLAC__metadata_simple_iterator_next(iterator))
654                 return die_("iterator ended early\n");
655         our_current_position++;
656
657         printf("SA[P]\tset APPLICATION, expand into padding of exceeding size\n");
658         app->data.application.id[0] = 'f'; /* twiddle the id */
659         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
660                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
661         if(!insert_to_our_metadata_(app, our_current_position, /*copy=*/true))
662                 return false;
663         our_metadata_.blocks[our_current_position+1]->length -= (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + app->length;
664
665         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
666                 return false;
667
668         printf("SA[A]P\tset APPLICATION (grow), don't expand into padding\n");
669         app->data.application.id[0] = 'g'; /* twiddle the id */
670         if(!FLAC__metadata_object_application_set_data(app, data, sizeof(data), true))
671                 return die_("setting APPLICATION data");
672         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
673                 return die_("copying object");
674         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
675                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
676
677         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
678                 return false;
679
680         printf("SA[A]P\tset APPLICATION (shrink), don't fill in with padding\n");
681         app->data.application.id[0] = 'h'; /* twiddle the id */
682         if(!FLAC__metadata_object_application_set_data(app, data, 12, true))
683                 return die_("setting APPLICATION data");
684         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
685                 return die_("copying object");
686         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
687                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
688
689         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
690                 return false;
691
692         printf("SA[A]P\tset APPLICATION (grow), expand into padding of exceeding size\n");
693         app->data.application.id[0] = 'i'; /* twiddle the id */
694         if(!FLAC__metadata_object_application_set_data(app, data, sizeof(data), true))
695                 return die_("setting APPLICATION data");
696         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
697                 return die_("copying object");
698         our_metadata_.blocks[our_current_position+1]->length -= (sizeof(data) - 12);
699         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
700                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
701
702         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
703                 return false;
704
705         printf("SA[A]P\tset APPLICATION (shrink), fill in with padding\n");
706         app->data.application.id[0] = 'j'; /* twiddle the id */
707         if(!FLAC__metadata_object_application_set_data(app, data, 23, true))
708                 return die_("setting APPLICATION data");
709         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
710                 return die_("copying object");
711         if(!insert_to_our_metadata_(padding, our_current_position+1, /*copy=*/true))
712                 return die_("copying object");
713         our_metadata_.blocks[our_current_position+1]->length = sizeof(data) - 23 - FLAC__STREAM_METADATA_HEADER_LENGTH;
714         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
715                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
716
717         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
718                 return false;
719
720         printf("SA[A]PP\tnext\n");
721         if(!FLAC__metadata_simple_iterator_next(iterator))
722                 return die_("iterator ended early\n");
723         our_current_position++;
724
725         printf("SAA[P]P\tnext\n");
726         if(!FLAC__metadata_simple_iterator_next(iterator))
727                 return die_("iterator ended early\n");
728         our_current_position++;
729
730         printf("SAAP[P]\tset PADDING (shrink), don't fill in with padding\n");
731         padding->length = 5;
732         if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true))
733                 return die_("copying object");
734         if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false))
735                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, false)", iterator);
736
737         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
738                 return false;
739
740         printf("SAAP[P]\tset APPLICATION (grow)\n");
741         app->data.application.id[0] = 'k'; /* twiddle the id */
742         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
743                 return die_("copying object");
744         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
745                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
746
747         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
748                 return false;
749
750         printf("SAAP[A]\tset PADDING (equal)\n");
751         padding->length = 27;
752         if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true))
753                 return die_("copying object");
754         if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false))
755                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, false)", iterator);
756
757         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
758                 return false;
759
760         printf("SAAP[P]\tprev\n");
761         if(!FLAC__metadata_simple_iterator_prev(iterator))
762                 return die_("iterator ended early\n");
763         our_current_position--;
764
765         printf("SAA[P]P\tdelete (middle block), don't replace with padding\n");
766         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
767                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
768         delete_from_our_metadata_(our_current_position--);
769
770         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
771                 return false;
772
773         printf("SA[A]P\tdelete (middle block), don't replace with padding\n");
774         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
775                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
776         delete_from_our_metadata_(our_current_position--);
777
778         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
779                 return false;
780
781         printf("S[A]P\tnext\n");
782         if(!FLAC__metadata_simple_iterator_next(iterator))
783                 return die_("iterator ended early\n");
784         our_current_position++;
785
786         printf("SA[P]\tinsert PADDING after\n");
787         padding->length = 5;
788         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
789                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
790         if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
791                 return false;
792
793         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
794                 return false;
795
796         printf("SAP[P]\tprev\n");
797         if(!FLAC__metadata_simple_iterator_prev(iterator))
798                 return die_("iterator ended early\n");
799         our_current_position--;
800
801         printf("SA[P]P\tprev\n");
802         if(!FLAC__metadata_simple_iterator_prev(iterator))
803                 return die_("iterator ended early\n");
804         our_current_position--;
805
806         printf("S[A]PP\tset APPLICATION (grow), try to expand into padding which is too small\n");
807         if(!FLAC__metadata_object_application_set_data(app, data, 32, true))
808                 return die_("setting APPLICATION data");
809         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
810                 return die_("copying object");
811         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
812                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
813
814         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
815                 return false;
816
817         printf("S[A]PP\tset APPLICATION (grow), try to expand into padding which is 'close' but still too small\n");
818         if(!FLAC__metadata_object_application_set_data(app, data, 60, true))
819                 return die_("setting APPLICATION data");
820         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
821                 return die_("copying object");
822         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
823                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
824
825         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
826                 return false;
827
828         printf("S[A]PP\tset APPLICATION (grow), expand into padding which will leave 0-length pad\n");
829         if(!FLAC__metadata_object_application_set_data(app, data, 87, true))
830                 return die_("setting APPLICATION data");
831         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
832                 return die_("copying object");
833         our_metadata_.blocks[our_current_position+1]->length = 0;
834         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
835                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
836
837         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
838                 return false;
839
840         printf("S[A]PP\tset APPLICATION (grow), expand into padding which is exactly consumed\n");
841         if(!FLAC__metadata_object_application_set_data(app, data, 91, true))
842                 return die_("setting APPLICATION data");
843         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
844                 return die_("copying object");
845         delete_from_our_metadata_(our_current_position+1);
846         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
847                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
848
849         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
850                 return false;
851
852         printf("S[A]P\tset APPLICATION (grow), expand into padding which is exactly consumed\n");
853         if(!FLAC__metadata_object_application_set_data(app, data, 100, true))
854                 return die_("setting APPLICATION data");
855         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
856                 return die_("copying object");
857         delete_from_our_metadata_(our_current_position+1);
858         our_metadata_.blocks[our_current_position]->is_last = true;
859         if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
860                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
861
862         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
863                 return false;
864
865         printf("S[A]\tset PADDING (equal size)\n");
866         padding->length = app->length;
867         if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true))
868                 return die_("copying object");
869         if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, true))
870                 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, true)", iterator);
871
872         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
873                 return false;
874
875         printf("S[P]\tinsert PADDING after\n");
876         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
877                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
878         if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
879                 return false;
880
881         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
882                 return false;
883
884         printf("SP[P]\tinsert PADDING after\n");
885         padding->length = 5;
886         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
887                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
888         if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
889                 return false;
890
891         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
892                 return false;
893
894         printf("SPP[P]\tprev\n");
895         if(!FLAC__metadata_simple_iterator_prev(iterator))
896                 return die_("iterator ended early\n");
897         our_current_position--;
898
899         printf("SP[P]P\tprev\n");
900         if(!FLAC__metadata_simple_iterator_prev(iterator))
901                 return die_("iterator ended early\n");
902         our_current_position--;
903
904         printf("S[P]PP\tprev\n");
905         if(!FLAC__metadata_simple_iterator_prev(iterator))
906                 return die_("iterator ended early\n");
907         our_current_position--;
908
909         printf("[S]PPP\tinsert APPLICATION after, try to expand into padding which is too small\n");
910         if(!FLAC__metadata_object_application_set_data(app, data, 101, true))
911                 return die_("setting APPLICATION data");
912         if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
913                 return die_("copying object");
914         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
915                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
916
917         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
918                 return false;
919
920         printf("S[A]PPP\tdelete (middle block), don't replace with padding\n");
921         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
922                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
923         delete_from_our_metadata_(our_current_position--);
924
925         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
926                 return false;
927
928         printf("[S]PPP\tinsert APPLICATION after, try to expand into padding which is 'close' but still too small\n");
929         if(!FLAC__metadata_object_application_set_data(app, data, 97, true))
930                 return die_("setting APPLICATION data");
931         if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
932                 return die_("copying object");
933         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
934                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
935
936         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
937                 return false;
938
939         printf("S[A]PPP\tdelete (middle block), don't replace with padding\n");
940         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
941                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
942         delete_from_our_metadata_(our_current_position--);
943
944         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
945                 return false;
946
947         printf("[S]PPP\tinsert APPLICATION after, expand into padding which is exactly consumed\n");
948         if(!FLAC__metadata_object_application_set_data(app, data, 100, true))
949                 return die_("setting APPLICATION data");
950         if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
951                 return die_("copying object");
952         delete_from_our_metadata_(our_current_position+1);
953         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
954                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
955
956         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
957                 return false;
958
959         printf("S[A]PP\tdelete (middle block), don't replace with padding\n");
960         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
961                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
962         delete_from_our_metadata_(our_current_position--);
963
964         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
965                 return false;
966
967         printf("[S]PP\tinsert APPLICATION after, expand into padding which will leave 0-length pad\n");
968         if(!FLAC__metadata_object_application_set_data(app, data, 96, true))
969                 return die_("setting APPLICATION data");
970         if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
971                 return die_("copying object");
972         our_metadata_.blocks[our_current_position+1]->length = 0;
973         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
974                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
975
976         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
977                 return false;
978
979         printf("S[A]PP\tdelete (middle block), don't replace with padding\n");
980         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
981                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
982         delete_from_our_metadata_(our_current_position--);
983
984         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
985                 return false;
986
987         printf("[S]PP\tnext\n");
988         if(!FLAC__metadata_simple_iterator_next(iterator))
989                 return die_("iterator ended early\n");
990         our_current_position++;
991
992         printf("S[P]P\tdelete (middle block), don't replace with padding\n");
993         if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
994                 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
995         delete_from_our_metadata_(our_current_position--);
996
997         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
998                 return false;
999
1000         printf("[S]P\tinsert APPLICATION after, expand into padding which is exactly consumed\n");
1001         if(!FLAC__metadata_object_application_set_data(app, data, 1, true))
1002                 return die_("setting APPLICATION data");
1003         if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
1004                 return die_("copying object");
1005         delete_from_our_metadata_(our_current_position+1);
1006         if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
1007                 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
1008
1009         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1010                 return false;
1011
1012         printf("delete simple iterator\n");
1013
1014         FLAC__metadata_simple_iterator_delete(iterator);
1015
1016         FLAC__metadata_object_delete(app);
1017         FLAC__metadata_object_delete(padding);
1018
1019         if(!remove_file_(flacfile_))
1020                 return false;
1021
1022         return true;
1023 }
1024
1025 static FLAC__bool test_level_2_()
1026 {
1027         FLAC__Metadata_Iterator *iterator;
1028         FLAC__Metadata_Chain *chain;
1029         FLAC__StreamMetadata *block, *app, *padding;
1030         FLAC__byte data[2000];
1031         unsigned our_current_position;
1032
1033         printf("\n\n++++++ testing level 2 interface\n");
1034
1035         printf("generate read-only file\n");
1036
1037         if(!generate_file_())
1038                 return false;
1039
1040         if(!change_stats_(flacfile_, /*read_only=*/true))
1041                 return false;
1042
1043         printf("create chain\n");
1044
1045         if(0 == (chain = FLAC__metadata_chain_new()))
1046                 return die_("allocating chain");
1047
1048         printf("read chain\n");
1049
1050         if(!FLAC__metadata_chain_read(chain, flacfile_))
1051                 return die_c_("reading chain", FLAC__metadata_chain_status(chain));
1052
1053         printf("[S]P\ttest initial metadata\n");
1054
1055         if(!compare_chain_(chain, 0, 0))
1056                 return false;
1057         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1058                 return false;
1059
1060         printf("switch file to read-write\n");
1061
1062         if(!change_stats_(flacfile_, /*read-only=*/false))
1063                 return false;
1064
1065         printf("create iterator\n");
1066         if(0 == (iterator = FLAC__metadata_iterator_new()))
1067                 return die_("allocating memory for iterator");
1068
1069         our_current_position = 0;
1070
1071         FLAC__metadata_iterator_init(iterator, chain);
1072
1073         if(0 == (block = FLAC__metadata_iterator_get_block(iterator)))
1074                 return die_("getting block from iterator");
1075
1076         FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_STREAMINFO);
1077
1078         printf("[S]P\tmodify STREAMINFO, write\n");
1079
1080         block->data.stream_info.sample_rate = 32000;
1081         if(!replace_in_our_metadata_(block, our_current_position, /*copy=*/true))
1082                 return die_("copying object");
1083
1084         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/true))
1085                 return die_c_("during FLAC__metadata_chain_write(chain, false, true)", FLAC__metadata_chain_status(chain));
1086         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1087                 return false;
1088         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1089                 return false;
1090
1091         printf("[S]P\tnext\n");
1092         if(!FLAC__metadata_iterator_next(iterator))
1093                 return die_("iterator ended early\n");
1094         our_current_position++;
1095
1096         printf("S[P]\treplace PADDING with identical-size APPLICATION\n");
1097         if(0 == (block = FLAC__metadata_iterator_get_block(iterator)))
1098                 return die_("getting block from iterator");
1099         if(0 == (app = FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)))
1100                 return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)");
1101         memcpy(app->data.application.id, "duh", (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8));
1102         if(!FLAC__metadata_object_application_set_data(app, data, block->length-(FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), true))
1103                 return die_("setting APPLICATION data");
1104         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1105                 return die_("copying object");
1106         if(!FLAC__metadata_iterator_set_block(iterator, app))
1107                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1108
1109         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
1110                 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1111         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1112                 return false;
1113         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1114                 return false;
1115
1116         printf("S[A]\tshrink APPLICATION, don't use padding\n");
1117         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1118                 return die_("copying object");
1119         if(!FLAC__metadata_object_application_set_data(app, data, 26, true))
1120                 return die_("setting APPLICATION data");
1121         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1122                 return die_("copying object");
1123         if(!FLAC__metadata_iterator_set_block(iterator, app))
1124                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1125
1126         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
1127                 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1128         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1129                 return false;
1130         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1131                 return false;
1132
1133         printf("S[A]\tgrow APPLICATION, don't use padding\n");
1134         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1135                 return die_("copying object");
1136         if(!FLAC__metadata_object_application_set_data(app, data, 28, true))
1137                 return die_("setting APPLICATION data");
1138         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1139                 return die_("copying object");
1140         if(!FLAC__metadata_iterator_set_block(iterator, app))
1141                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1142
1143         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
1144                 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1145         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1146                 return false;
1147         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1148                 return false;
1149
1150         printf("S[A]\tgrow APPLICATION, use padding, but last block is not padding\n");
1151         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1152                 return die_("copying object");
1153         if(!FLAC__metadata_object_application_set_data(app, data, 36, true))
1154                 return die_("setting APPLICATION data");
1155         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1156                 return die_("copying object");
1157         if(!FLAC__metadata_iterator_set_block(iterator, app))
1158                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1159
1160         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
1161                 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1162         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1163                 return false;
1164         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1165                 return false;
1166
1167         printf("S[A]\tshrink APPLICATION, use padding, last block is not padding, but delta is too small for new PADDING block\n");
1168         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1169                 return die_("copying object");
1170         if(!FLAC__metadata_object_application_set_data(app, data, 33, true))
1171                 return die_("setting APPLICATION data");
1172         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1173                 return die_("copying object");
1174         if(!FLAC__metadata_iterator_set_block(iterator, app))
1175                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1176
1177         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
1178                 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1179         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1180                 return false;
1181         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1182                 return false;
1183
1184         printf("S[A]\tshrink APPLICATION, use padding, last block is not padding, delta is enough for new PADDING block\n");
1185         if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
1186                 return die_("creating PADDING block");
1187         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1188                 return die_("copying object");
1189         if(!FLAC__metadata_object_application_set_data(app, data, 29, true))
1190                 return die_("setting APPLICATION data");
1191         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1192                 return die_("copying object");
1193         padding->length = 0;
1194         if(!insert_to_our_metadata_(padding, our_current_position+1, /*copy=*/false))
1195                 return die_("internal error");
1196         if(!FLAC__metadata_iterator_set_block(iterator, app))
1197                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1198
1199         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
1200                 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1201         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1202                 return false;
1203         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1204                 return false;
1205
1206         printf("S[A]P\tshrink APPLICATION, use padding, last block is padding\n");
1207         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1208                 return die_("copying object");
1209         if(!FLAC__metadata_object_application_set_data(app, data, 16, true))
1210                 return die_("setting APPLICATION data");
1211         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1212                 return die_("copying object");
1213         our_metadata_.blocks[our_current_position+1]->length = 13;
1214         if(!FLAC__metadata_iterator_set_block(iterator, app))
1215                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1216
1217         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
1218                 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1219         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1220                 return false;
1221         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1222                 return false;
1223
1224         printf("S[A]P\tgrow APPLICATION, use padding, last block is padding, but delta is too small\n");
1225         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1226                 return die_("copying object");
1227         if(!FLAC__metadata_object_application_set_data(app, data, 50, true))
1228                 return die_("setting APPLICATION data");
1229         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1230                 return die_("copying object");
1231         if(!FLAC__metadata_iterator_set_block(iterator, app))
1232                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1233
1234         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
1235                 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1236         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1237                 return false;
1238         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1239                 return false;
1240
1241         printf("S[A]P\tgrow APPLICATION, use padding, last block is padding of exceeding size\n");
1242         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1243                 return die_("copying object");
1244         if(!FLAC__metadata_object_application_set_data(app, data, 56, true))
1245                 return die_("setting APPLICATION data");
1246         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1247                 return die_("copying object");
1248         our_metadata_.blocks[our_current_position+1]->length -= (56 - 50);
1249         if(!FLAC__metadata_iterator_set_block(iterator, app))
1250                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1251
1252         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
1253                 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1254         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1255                 return false;
1256         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1257                 return false;
1258
1259         printf("S[A]P\tgrow APPLICATION, use padding, last block is padding of exact size\n");
1260         if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1261                 return die_("copying object");
1262         if(!FLAC__metadata_object_application_set_data(app, data, 67, true))
1263                 return die_("setting APPLICATION data");
1264         if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
1265                 return die_("copying object");
1266         delete_from_our_metadata_(our_current_position+1);
1267         if(!FLAC__metadata_iterator_set_block(iterator, app))
1268                 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1269
1270         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
1271                 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1272         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1273                 return false;
1274         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1275                 return false;
1276
1277         printf("S[A]\tprev\n");
1278         if(!FLAC__metadata_iterator_prev(iterator))
1279                 return die_("iterator ended early\n");
1280         our_current_position--;
1281
1282         printf("[S]A\tinsert PADDING before STREAMINFO (should fail)\n");
1283         if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
1284                 return die_("creating PADDING block");
1285         padding->length = 30;
1286         if(!FLAC__metadata_iterator_insert_block_before(iterator, padding))
1287                 printf("\tFLAC__metadata_iterator_insert_block_before() returned false like it should\n");
1288         else
1289                 return die_("FLAC__metadata_iterator_insert_block_before() should have returned false");
1290
1291         printf("[S]A\tinsert PADDING after\n");
1292         if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
1293                 return die_("copying metadata");
1294         if(!FLAC__metadata_iterator_insert_block_after(iterator, padding))
1295                 return die_("FLAC__metadata_iterator_insert_block_after(iterator, padding)");
1296
1297         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1298                 return false;
1299
1300         printf("S[P]A\tinsert PADDING before\n");
1301         if(0 == (padding = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1302                 return die_("creating PADDING block");
1303         padding->length = 17;
1304         if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true))
1305                 return die_("copying metadata");
1306         if(!FLAC__metadata_iterator_insert_block_before(iterator, padding))
1307                 return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)");
1308
1309         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1310                 return false;
1311
1312         printf("S[P]PA\tinsert PADDING before\n");
1313         if(0 == (padding = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
1314                 return die_("creating PADDING block");
1315         padding->length = 0;
1316         if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true))
1317                 return die_("copying metadata");
1318         if(!FLAC__metadata_iterator_insert_block_before(iterator, padding))
1319                 return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)");
1320
1321         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1322                 return false;
1323
1324         printf("S[P]PPA\tnext\n");
1325         if(!FLAC__metadata_iterator_next(iterator))
1326                 return die_("iterator ended early\n");
1327         our_current_position++;
1328
1329         printf("SP[P]PA\tnext\n");
1330         if(!FLAC__metadata_iterator_next(iterator))
1331                 return die_("iterator ended early\n");
1332         our_current_position++;
1333
1334         printf("SPP[P]A\tnext\n");
1335         if(!FLAC__metadata_iterator_next(iterator))
1336                 return die_("iterator ended early\n");
1337         our_current_position++;
1338
1339         printf("SPPP[A]\tinsert PADDING after\n");
1340         if(0 == (padding = FLAC__metadata_object_clone(our_metadata_.blocks[1])))
1341                 return die_("creating PADDING block");
1342         padding->length = 57;
1343         if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
1344                 return die_("copying metadata");
1345         if(!FLAC__metadata_iterator_insert_block_after(iterator, padding))
1346                 return die_("FLAC__metadata_iterator_insert_block_after(iterator, padding)");
1347
1348         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1349                 return false;
1350
1351         printf("SPPPA[P]\tinsert PADDING before\n");
1352         if(0 == (padding = FLAC__metadata_object_clone(our_metadata_.blocks[1])))
1353                 return die_("creating PADDING block");
1354         padding->length = 99;
1355         if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true))
1356                 return die_("copying metadata");
1357         if(!FLAC__metadata_iterator_insert_block_before(iterator, padding))
1358                 return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)");
1359
1360         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1361                 return false;
1362
1363         printf("delete iterator\n");
1364         FLAC__metadata_iterator_delete(iterator);
1365         our_current_position = 0;
1366
1367         printf("SPPPAPP\tmerge padding\n");
1368         FLAC__metadata_chain_merge_padding(chain);
1369         our_metadata_.blocks[1]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[2]->length);
1370         our_metadata_.blocks[1]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[3]->length);
1371         our_metadata_.blocks[5]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[6]->length);
1372         delete_from_our_metadata_(6);
1373         delete_from_our_metadata_(3);
1374         delete_from_our_metadata_(2);
1375
1376         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
1377                 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1378         if(!compare_chain_(chain, 0, 0))
1379                 return false;
1380         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1381                 return false;
1382
1383         printf("SPAP\tsort padding\n");
1384         FLAC__metadata_chain_sort_padding(chain);
1385         our_metadata_.blocks[3]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[1]->length);
1386         delete_from_our_metadata_(1);
1387
1388         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
1389                 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1390         if(!compare_chain_(chain, 0, 0))
1391                 return false;
1392         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1393                 return false;
1394
1395         printf("create iterator\n");
1396         if(0 == (iterator = FLAC__metadata_iterator_new()))
1397                 return die_("allocating memory for iterator");
1398
1399         our_current_position = 0;
1400
1401         FLAC__metadata_iterator_init(iterator, chain);
1402
1403         printf("[S]AP\tnext\n");
1404         if(!FLAC__metadata_iterator_next(iterator))
1405                 return die_("iterator ended early\n");
1406         our_current_position++;
1407
1408         printf("S[A]P\tdelete middle block, replace with padding\n");
1409         if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
1410                 return die_("creating PADDING block");
1411         padding->length = 71;
1412         if(!replace_in_our_metadata_(padding, our_current_position--, /*copy=*/false))
1413                 return die_("copying object");
1414         if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/true))
1415                 return die_c_("FLAC__metadata_iterator_delete_block(iterator, true)", FLAC__metadata_chain_status(chain));
1416
1417         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1418                 return false;
1419
1420         printf("[S]PP\tnext\n");
1421         if(!FLAC__metadata_iterator_next(iterator))
1422                 return die_("iterator ended early\n");
1423         our_current_position++;
1424
1425         printf("S[P]P\tdelete middle block, don't replace with padding\n");
1426         delete_from_our_metadata_(our_current_position--);
1427         if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false))
1428                 return die_c_("FLAC__metadata_iterator_delete_block(iterator, false)", FLAC__metadata_chain_status(chain));
1429
1430         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1431                 return false;
1432
1433         printf("[S]P\tnext\n");
1434         if(!FLAC__metadata_iterator_next(iterator))
1435                 return die_("iterator ended early\n");
1436         our_current_position++;
1437
1438         printf("S[P]\tdelete last block, replace with padding\n");
1439         if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
1440                 return die_("creating PADDING block");
1441         padding->length = 219;
1442         if(!replace_in_our_metadata_(padding, our_current_position--, /*copy=*/false))
1443                 return die_("copying object");
1444         if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/true))
1445                 return die_c_("FLAC__metadata_iterator_delete_block(iterator, true)", FLAC__metadata_chain_status(chain));
1446
1447         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1448                 return false;
1449
1450         printf("[S]P\tnext\n");
1451         if(!FLAC__metadata_iterator_next(iterator))
1452                 return die_("iterator ended early\n");
1453         our_current_position++;
1454
1455         printf("S[P]\tdelete last block, don't replace with padding\n");
1456         delete_from_our_metadata_(our_current_position--);
1457         if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false))
1458                 return die_c_("FLAC__metadata_iterator_delete_block(iterator, false)", FLAC__metadata_chain_status(chain));
1459
1460         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1461                 return false;
1462
1463         printf("[S]\tdelete STREAMINFO block, should fail\n");
1464         if(FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false))
1465                 return die_("FLAC__metadata_iterator_delete_block() on STREAMINFO should have failed but didn't");
1466
1467         if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1468                 return false;
1469
1470         printf("delete iterator\n");
1471         FLAC__metadata_iterator_delete(iterator);
1472         our_current_position = 0;
1473
1474         printf("S\tmerge padding\n");
1475         FLAC__metadata_chain_merge_padding(chain);
1476
1477         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
1478                 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1479         if(!compare_chain_(chain, 0, 0))
1480                 return false;
1481         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1482                 return false;
1483
1484         printf("S\tsort padding\n");
1485         FLAC__metadata_chain_sort_padding(chain);
1486
1487         if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
1488                 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1489         if(!compare_chain_(chain, 0, 0))
1490                 return false;
1491         if(!test_file_(flacfile_, decoder_metadata_callback_compare_))
1492                 return false;
1493
1494         printf("delete chain\n");
1495
1496         FLAC__metadata_chain_delete(chain);
1497
1498         if(!remove_file_(flacfile_))
1499                 return false;
1500
1501         return true;
1502 }
1503
1504 FLAC__bool test_metadata_file_manipulation()
1505 {
1506         printf("\n+++ libFLAC unit test: metadata manipulation\n\n");
1507
1508         our_metadata_.num_blocks = 0;
1509
1510         if(!test_level_0_())
1511                 return false;
1512
1513         if(!test_level_1_())
1514                 return false;
1515
1516         if(!test_level_2_())
1517                 return false;
1518
1519         return true;
1520 }