~ubuntu-branches/ubuntu/karmic/flac/karmic

« back to all changes in this revision

Viewing changes to src/test_libFLAC/metadata_manip.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2005-01-08 15:08:22 UTC
  • mto: (8.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20050108150822-yvinilrafylazcyv
Tags: upstream-1.1.1
ImportĀ upstreamĀ versionĀ 1.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* test_libFLAC - Unit tester for libFLAC
2
 
 * Copyright (C) 2002,2003  Josh Coalson
 
2
 * Copyright (C) 2002,2003,2004  Josh Coalson
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or
5
5
 * modify it under the terms of the GNU General Public License
25
25
#include <stdio.h>
26
26
#include <stdlib.h> /* for malloc() */
27
27
 
 
28
#if defined _MSC_VER || defined __MINGW32__
 
29
#include <sys/utime.h> /* for utime() */
 
30
#include <io.h> /* for chmod() */
 
31
#else
 
32
#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
 
33
#include <utime.h> /* for utime() */
 
34
#include <unistd.h> /* for chown(), unlink() */
 
35
#endif
 
36
#include <sys/stat.h> /* for stat(), maybe chmod() */
 
37
 
 
38
 
28
39
/******************************************************************************
29
40
        The general strategy of these tests (for interface levels 1 and 2) is
30
41
        to create a dummy FLAC file with a known set of initial metadata
148
159
        }
149
160
}
150
161
 
 
162
/*
 
163
 * This wad of functions supports filename- and callback-based chain reading/writing.
 
164
 * Everything up to set_file_stats_() is copied from libFLAC/metadata_iterators.c
 
165
 */
 
166
FLAC__bool open_tempfile_(const char *filename, FILE **tempfile, char **tempfilename)
 
167
{
 
168
        static const char *tempfile_suffix = ".metadata_edit";
 
169
 
 
170
        if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1)))
 
171
                return false;
 
172
        strcpy(*tempfilename, filename);
 
173
        strcat(*tempfilename, tempfile_suffix);
 
174
 
 
175
        if(0 == (*tempfile = fopen(*tempfilename, "wb")))
 
176
                return false;
 
177
 
 
178
        return true;
 
179
}
 
180
 
 
181
void cleanup_tempfile_(FILE **tempfile, char **tempfilename)
 
182
{
 
183
        if(0 != *tempfile) {
 
184
                (void)fclose(*tempfile);
 
185
                *tempfile = 0;
 
186
        }
 
187
 
 
188
        if(0 != *tempfilename) {
 
189
                (void)unlink(*tempfilename);
 
190
                free(*tempfilename);
 
191
                *tempfilename = 0;
 
192
        }
 
193
}
 
194
 
 
195
FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename)
 
196
{
 
197
        FLAC__ASSERT(0 != filename);
 
198
        FLAC__ASSERT(0 != tempfile);
 
199
        FLAC__ASSERT(0 != tempfilename);
 
200
        FLAC__ASSERT(0 != *tempfilename);
 
201
 
 
202
        if(0 != *tempfile) {
 
203
                (void)fclose(*tempfile);
 
204
                *tempfile = 0;
 
205
        }
 
206
 
 
207
#if defined _MSC_VER || defined __MINGW32__
 
208
        if(unlink(filename) < 0) {
 
209
                cleanup_tempfile_(tempfile, tempfilename);
 
210
                return false;
 
211
        }
 
212
#endif
 
213
 
 
214
        if(0 != rename(*tempfilename, filename)) {
 
215
                cleanup_tempfile_(tempfile, tempfilename);
 
216
                return false;
 
217
        }
 
218
 
 
219
        cleanup_tempfile_(tempfile, tempfilename);
 
220
 
 
221
        return true;
 
222
}
 
223
 
 
224
FLAC__bool get_file_stats_(const char *filename, struct stat *stats)
 
225
{
 
226
        FLAC__ASSERT(0 != filename);
 
227
        FLAC__ASSERT(0 != stats);
 
228
        return (0 == stat(filename, stats));
 
229
}
 
230
 
 
231
void set_file_stats_(const char *filename, struct stat *stats)
 
232
{
 
233
        struct utimbuf srctime;
 
234
 
 
235
        FLAC__ASSERT(0 != filename);
 
236
        FLAC__ASSERT(0 != stats);
 
237
 
 
238
        srctime.actime = stats->st_atime;
 
239
        srctime.modtime = stats->st_mtime;
 
240
        (void)chmod(filename, stats->st_mode);
 
241
        (void)utime(filename, &srctime);
 
242
#if !defined _MSC_VER && !defined __MINGW32__
 
243
        (void)chown(filename, stats->st_uid, -1);
 
244
        (void)chown(filename, -1, stats->st_gid);
 
245
#endif
 
246
}
 
247
 
 
248
#ifdef FLAC__VALGRIND_TESTING
 
249
static size_t chain_write_cb_(const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
 
250
{
 
251
        FILE *stream = (FILE*)handle;
 
252
        size_t ret = fwrite(ptr, size, nmemb, stream);
 
253
        if(!ferror(stream))
 
254
                fflush(stream);
 
255
        return ret;
 
256
}
 
257
#endif
 
258
 
 
259
static int chain_seek_cb_(FLAC__IOHandle handle, FLAC__int64 offset, int whence)
 
260
{
 
261
        long o = (long)offset;
 
262
        FLAC__ASSERT(offset == o);
 
263
        return fseek((FILE*)handle, o, whence);
 
264
}
 
265
 
 
266
static FLAC__int64 chain_tell_cb_(FLAC__IOHandle handle)
 
267
{
 
268
        return ftell((FILE*)handle);
 
269
}
 
270
 
 
271
static int chain_eof_cb_(FLAC__IOHandle handle)
 
272
{
 
273
        return feof((FILE*)handle);
 
274
}
 
275
 
 
276
static FLAC__bool write_chain_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats, FLAC__bool filename_based, const char *filename)
 
277
{
 
278
        if(filename_based)
 
279
                return FLAC__metadata_chain_write(chain, use_padding, preserve_file_stats);
 
280
        else {
 
281
                FLAC__IOCallbacks callbacks;
 
282
 
 
283
                memset(&callbacks, 0, sizeof(callbacks));
 
284
                callbacks.read = (FLAC__IOCallback_Read)fread;
 
285
#ifdef FLAC__VALGRIND_TESTING
 
286
                callbacks.write = chain_write_cb_;
 
287
#else
 
288
                callbacks.write = (FLAC__IOCallback_Write)fwrite;
 
289
#endif
 
290
                callbacks.seek = chain_seek_cb_;
 
291
                callbacks.eof = chain_eof_cb_;
 
292
 
 
293
                if(FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
 
294
                        struct stat stats;
 
295
                        FILE *file, *tempfile;
 
296
                        char *tempfilename;
 
297
                        if(preserve_file_stats) {
 
298
                                if(!get_file_stats_(filename, &stats))
 
299
                                        return false;
 
300
                        }
 
301
                        if(0 == (file = fopen(filename, "rb")))
 
302
                                return false; /*@@@ chain status still says OK though */
 
303
                        if(!open_tempfile_(filename, &tempfile, &tempfilename)) {
 
304
                                fclose(file);
 
305
                                cleanup_tempfile_(&tempfile, &tempfilename);
 
306
                                return false; /*@@@ chain status still says OK though */
 
307
                        }
 
308
                        if(!FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, use_padding, (FLAC__IOHandle)file, callbacks, (FLAC__IOHandle)tempfile, callbacks)) {
 
309
                                fclose(file);
 
310
                                fclose(tempfile);
 
311
                                return false;
 
312
                        }
 
313
                        fclose(file);
 
314
                        fclose(tempfile);
 
315
                        file = tempfile = 0;
 
316
                        if(!transport_tempfile_(filename, &tempfile, &tempfilename))
 
317
                                return false;
 
318
                        if(preserve_file_stats)
 
319
                                set_file_stats_(filename, &stats);
 
320
                }
 
321
                else {
 
322
                        FILE *file = fopen(filename, "r+b");
 
323
                        if(0 == file)
 
324
                                return false; /*@@@ chain status still says OK though */
 
325
                        if(!FLAC__metadata_chain_write_with_callbacks(chain, use_padding, (FLAC__IOHandle)file, callbacks))
 
326
                                return false;
 
327
                        fclose(file);
 
328
                }
 
329
        }
 
330
 
 
331
        return true;
 
332
}
 
333
 
 
334
static FLAC__bool read_chain_(FLAC__Metadata_Chain *chain, const char *filename, FLAC__bool filename_based)
 
335
{
 
336
        if(filename_based)
 
337
                return FLAC__metadata_chain_read(chain, flacfile_);
 
338
        else {
 
339
                FLAC__IOCallbacks callbacks;
 
340
 
 
341
                memset(&callbacks, 0, sizeof(callbacks));
 
342
                callbacks.read = (FLAC__IOCallback_Read)fread;
 
343
                callbacks.seek = chain_seek_cb_;
 
344
                callbacks.tell = chain_tell_cb_;
 
345
 
 
346
                {
 
347
                        FLAC__bool ret;
 
348
                        FILE *file = fopen(filename, "rb");
 
349
                        if(0 == file)
 
350
                                return false; /*@@@ chain status still says OK though */
 
351
                        ret = FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks);
 
352
                        fclose(file);
 
353
                        return ret;
 
354
                }
 
355
        }
 
356
}
 
357
 
151
358
/* function for comparing our metadata to a FLAC__Metadata_Chain */
152
359
 
153
360
static FLAC__bool compare_chain_(FLAC__Metadata_Chain *chain, unsigned current_position, FLAC__StreamMetadata *current_block)
327
534
        return true;
328
535
}
329
536
 
330
 
static FLAC__bool test_file_(const char *filename, void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data))
 
537
static FLAC__bool test_file_(const char *filename, FLAC__FileDecoderMetadataCallback metadata_callback)
331
538
{
332
539
        FLAC__FileDecoder *decoder;
333
540
        decoder_client_struct decoder_client_data;
397
604
static FLAC__bool test_level_0_()
398
605
{
399
606
        FLAC__StreamMetadata streaminfo;
 
607
        FLAC__StreamMetadata *tags = 0;
400
608
 
401
609
        printf("\n\n++++++ testing level 0 interface\n");
402
610
 
406
614
        if(!test_file_(flacfile_, decoder_metadata_callback_null_))
407
615
                return false;
408
616
 
 
617
        printf("testing FLAC__metadata_get_streaminfo()... ");
 
618
 
409
619
        if(!FLAC__metadata_get_streaminfo(flacfile_, &streaminfo))
410
620
                return die_("during FLAC__metadata_get_streaminfo()");
411
621
 
421
631
        if(streaminfo.data.stream_info.max_blocksize != 576)
422
632
                return die_("mismatch in streaminfo.data.stream_info.max_blocksize");
423
633
 
 
634
        printf("OK\n");
 
635
 
 
636
        printf("testing FLAC__metadata_get_tags()... ");
 
637
 
 
638
        if(!FLAC__metadata_get_tags(flacfile_, &tags))
 
639
                return die_("during FLAC__metadata_get_tags()");
 
640
 
 
641
        /* check to see if some basic data matches (c.f. generate_file_()) */
 
642
        if(tags->data.vorbis_comment.num_comments != 0)
 
643
                return die_("mismatch in tags->data.vorbis_comment.num_comments");
 
644
 
 
645
        printf("OK\n");
 
646
 
 
647
        FLAC__metadata_object_delete(tags);
 
648
 
424
649
        if(!remove_file_(flacfile_))
425
650
                return false;
426
651
 
1087
1312
        return true;
1088
1313
}
1089
1314
 
1090
 
static FLAC__bool test_level_2_()
 
1315
static FLAC__bool test_level_2_(FLAC__bool filename_based)
1091
1316
{
1092
1317
        FLAC__Metadata_Iterator *iterator;
1093
1318
        FLAC__Metadata_Chain *chain;
1098
1323
        /* initialize 'data' to avoid Valgrind errors */
1099
1324
        memset(data, 0, sizeof(data));
1100
1325
 
1101
 
        printf("\n\n++++++ testing level 2 interface\n");
 
1326
        printf("\n\n++++++ testing level 2 interface (%s-based)\n", filename_based? "filename":"callback");
1102
1327
 
1103
1328
        printf("generate read-only file\n");
1104
1329
 
1115
1340
 
1116
1341
        printf("read chain\n");
1117
1342
 
1118
 
        if(!FLAC__metadata_chain_read(chain, flacfile_))
 
1343
        if(!read_chain_(chain, flacfile_, filename_based))
1119
1344
                return die_c_("reading chain", FLAC__metadata_chain_status(chain));
1120
1345
 
1121
1346
        printf("[S]VP\ttest initial metadata\n");
1149
1374
        if(!replace_in_our_metadata_(block, our_current_position, /*copy=*/true))
1150
1375
                return die_("copying object");
1151
1376
 
1152
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/true))
 
1377
        if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/true, filename_based, flacfile_))
1153
1378
                return die_c_("during FLAC__metadata_chain_write(chain, false, true)", FLAC__metadata_chain_status(chain));
1154
1379
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1155
1380
                return false;
1179
1404
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1180
1405
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1181
1406
 
1182
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
 
1407
        if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1183
1408
                return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1184
1409
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1185
1410
                return false;
1196
1421
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1197
1422
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1198
1423
 
1199
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
 
1424
        if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1200
1425
                return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1201
1426
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1202
1427
                return false;
1213
1438
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1214
1439
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1215
1440
 
1216
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
 
1441
        if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1217
1442
                return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1218
1443
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1219
1444
                return false;
1230
1455
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1231
1456
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1232
1457
 
1233
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
 
1458
        if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1234
1459
                return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1235
1460
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1236
1461
                return false;
1247
1472
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1248
1473
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1249
1474
 
1250
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
 
1475
        if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1251
1476
                return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1252
1477
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1253
1478
                return false;
1269
1494
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1270
1495
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1271
1496
 
1272
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
 
1497
        if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1273
1498
                return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1274
1499
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1275
1500
                return false;
1287
1512
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1288
1513
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1289
1514
 
1290
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
 
1515
        if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1291
1516
                return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1292
1517
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1293
1518
                return false;
1304
1529
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1305
1530
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1306
1531
 
1307
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
 
1532
        if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1308
1533
                return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1309
1534
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1310
1535
                return false;
1322
1547
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1323
1548
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1324
1549
 
1325
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
 
1550
        if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1326
1551
                return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1327
1552
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1328
1553
                return false;
1340
1565
        if(!FLAC__metadata_iterator_set_block(iterator, app))
1341
1566
                return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
1342
1567
 
1343
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
 
1568
        if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1344
1569
                return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1345
1570
        if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
1346
1571
                return false;
1456
1681
        delete_from_our_metadata_(4);
1457
1682
        delete_from_our_metadata_(3);
1458
1683
 
1459
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
 
1684
        if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1460
1685
                return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1461
1686
        if(!compare_chain_(chain, 0, 0))
1462
1687
                return false;
1468
1693
        our_metadata_.blocks[4]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[2]->length);
1469
1694
        delete_from_our_metadata_(2);
1470
1695
 
1471
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false))
 
1696
        if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1472
1697
                return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
1473
1698
        if(!compare_chain_(chain, 0, 0))
1474
1699
                return false;
1567
1792
        printf("SV\tmerge padding\n");
1568
1793
        FLAC__metadata_chain_merge_padding(chain);
1569
1794
 
1570
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
 
1795
        if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1571
1796
                return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1572
1797
        if(!compare_chain_(chain, 0, 0))
1573
1798
                return false;
1577
1802
        printf("SV\tsort padding\n");
1578
1803
        FLAC__metadata_chain_sort_padding(chain);
1579
1804
 
1580
 
        if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
 
1805
        if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1581
1806
                return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
1582
1807
        if(!compare_chain_(chain, 0, 0))
1583
1808
                return false;
1594
1819
        return true;
1595
1820
}
1596
1821
 
 
1822
static FLAC__bool test_level_2_misc_()
 
1823
{
 
1824
        FLAC__Metadata_Iterator *iterator;
 
1825
        FLAC__Metadata_Chain *chain;
 
1826
        FLAC__IOCallbacks callbacks;
 
1827
 
 
1828
        memset(&callbacks, 0, sizeof(callbacks));
 
1829
        callbacks.read = (FLAC__IOCallback_Read)fread;
 
1830
#ifdef FLAC__VALGRIND_TESTING
 
1831
        callbacks.write = chain_write_cb_;
 
1832
#else
 
1833
        callbacks.write = (FLAC__IOCallback_Write)fwrite;
 
1834
#endif
 
1835
        callbacks.seek = chain_seek_cb_;
 
1836
        callbacks.tell = chain_tell_cb_;
 
1837
        callbacks.eof = chain_eof_cb_;
 
1838
 
 
1839
        printf("\n\n++++++ testing level 2 interface (mismatched read/write protections)\n");
 
1840
 
 
1841
        printf("generate file\n");
 
1842
 
 
1843
        if(!generate_file_())
 
1844
                return false;
 
1845
 
 
1846
        printf("create chain\n");
 
1847
 
 
1848
        if(0 == (chain = FLAC__metadata_chain_new()))
 
1849
                return die_("allocating chain");
 
1850
 
 
1851
        printf("read chain (filename-based)\n");
 
1852
 
 
1853
        if(!FLAC__metadata_chain_read(chain, flacfile_))
 
1854
                return die_c_("reading chain", FLAC__metadata_chain_status(chain));
 
1855
 
 
1856
        printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks()\n");
 
1857
        {
 
1858
                if(FLAC__metadata_chain_write_with_callbacks(chain, /*use_padding=*/false, 0, callbacks))
 
1859
                        return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
 
1860
                if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH)
 
1861
                        return die_c_("expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", FLAC__metadata_chain_status(chain));
 
1862
                printf("  OK: FLAC__metadata_chain_write_with_callbacks() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
 
1863
        }
 
1864
 
 
1865
        printf("read chain (filename-based)\n");
 
1866
 
 
1867
        if(!FLAC__metadata_chain_read(chain, flacfile_))
 
1868
                return die_c_("reading chain", FLAC__metadata_chain_status(chain));
 
1869
 
 
1870
        printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks_and_tempfile()\n");
 
1871
        {
 
1872
                if(FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, /*use_padding=*/false, 0, callbacks, 0, callbacks))
 
1873
                        return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
 
1874
                if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH)
 
1875
                        return die_c_("expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", FLAC__metadata_chain_status(chain));
 
1876
                printf("  OK: FLAC__metadata_chain_write_with_callbacks_and_tempfile() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
 
1877
        }
 
1878
 
 
1879
        printf("read chain (callback-based)\n");
 
1880
        {
 
1881
                FILE *file = fopen(flacfile_, "rb");
 
1882
                if(0 == file)
 
1883
                        return die_("opening file");
 
1884
                if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
 
1885
                        fclose(file);
 
1886
                        return die_c_("reading chain", FLAC__metadata_chain_status(chain));
 
1887
                }
 
1888
                fclose(file);
 
1889
        }
 
1890
 
 
1891
        printf("write chain with wrong method FLAC__metadata_chain_write()\n");
 
1892
        {
 
1893
                if(FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
 
1894
                        return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
 
1895
                if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH)
 
1896
                        return die_c_("expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", FLAC__metadata_chain_status(chain));
 
1897
                printf("  OK: FLAC__metadata_chain_write() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
 
1898
        }
 
1899
 
 
1900
        printf("read chain (callback-based)\n");
 
1901
        {
 
1902
                FILE *file = fopen(flacfile_, "rb");
 
1903
                if(0 == file)
 
1904
                        return die_("opening file");
 
1905
                if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
 
1906
                        fclose(file);
 
1907
                        return die_c_("reading chain", FLAC__metadata_chain_status(chain));
 
1908
                }
 
1909
                fclose(file);
 
1910
        }
 
1911
 
 
1912
        printf("testing FLAC__metadata_chain_check_if_tempfile_needed()... ");
 
1913
 
 
1914
        if(!FLAC__metadata_chain_check_if_tempfile_needed(chain, /*use_padding=*/false))
 
1915
                printf("OK: FLAC__metadata_chain_check_if_tempfile_needed() returned false like it should\n");
 
1916
        else
 
1917
                return die_("FLAC__metadata_chain_check_if_tempfile_needed() returned true but shouldn't have");
 
1918
 
 
1919
        printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks_and_tempfile()\n");
 
1920
        {
 
1921
                if(FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, /*use_padding=*/false, 0, callbacks, 0, callbacks))
 
1922
                        return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
 
1923
                if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL)
 
1924
                        return die_c_("expected FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL", FLAC__metadata_chain_status(chain));
 
1925
                printf("  OK: FLAC__metadata_chain_write_with_callbacks_and_tempfile() returned false,FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL like it should\n");
 
1926
        }
 
1927
 
 
1928
        printf("read chain (callback-based)\n");
 
1929
        {
 
1930
                FILE *file = fopen(flacfile_, "rb");
 
1931
                if(0 == file)
 
1932
                        return die_("opening file");
 
1933
                if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
 
1934
                        fclose(file);
 
1935
                        return die_c_("reading chain", FLAC__metadata_chain_status(chain));
 
1936
                }
 
1937
                fclose(file);
 
1938
        }
 
1939
 
 
1940
        printf("create iterator\n");
 
1941
        if(0 == (iterator = FLAC__metadata_iterator_new()))
 
1942
                return die_("allocating memory for iterator");
 
1943
 
 
1944
        FLAC__metadata_iterator_init(iterator, chain);
 
1945
 
 
1946
        printf("[S]VP\tnext\n");
 
1947
        if(!FLAC__metadata_iterator_next(iterator))
 
1948
                return die_("iterator ended early\n");
 
1949
 
 
1950
        printf("S[V]P\tdelete VORBIS_COMMENT, write\n");
 
1951
        if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false))
 
1952
                return die_c_("block delete failed\n", FLAC__metadata_chain_status(chain));
 
1953
 
 
1954
        printf("testing FLAC__metadata_chain_check_if_tempfile_needed()... ");
 
1955
 
 
1956
        if(FLAC__metadata_chain_check_if_tempfile_needed(chain, /*use_padding=*/false))
 
1957
                printf("OK: FLAC__metadata_chain_check_if_tempfile_needed() returned true like it should\n");
 
1958
        else
 
1959
                return die_("FLAC__metadata_chain_check_if_tempfile_needed() returned false but shouldn't have");
 
1960
 
 
1961
        printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks()\n");
 
1962
        {
 
1963
                if(FLAC__metadata_chain_write_with_callbacks(chain, /*use_padding=*/false, 0, callbacks))
 
1964
                        return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
 
1965
                if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL)
 
1966
                        return die_c_("expected FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL", FLAC__metadata_chain_status(chain));
 
1967
                printf("  OK: FLAC__metadata_chain_write_with_callbacks() returned false,FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL like it should\n");
 
1968
        }
 
1969
 
 
1970
        printf("delete iterator\n");
 
1971
 
 
1972
        FLAC__metadata_iterator_delete(iterator);
 
1973
 
 
1974
        printf("delete chain\n");
 
1975
 
 
1976
        FLAC__metadata_chain_delete(chain);
 
1977
 
 
1978
        if(!remove_file_(flacfile_))
 
1979
                return false;
 
1980
 
 
1981
        return true;
 
1982
}
 
1983
 
1597
1984
FLAC__bool test_metadata_file_manipulation()
1598
1985
{
1599
1986
        printf("\n+++ libFLAC unit test: metadata manipulation\n\n");
1606
1993
        if(!test_level_1_())
1607
1994
                return false;
1608
1995
 
1609
 
        if(!test_level_2_())
 
1996
        if(!test_level_2_(/*filename_based=*/true)) /* filename-based */
 
1997
                return false;
 
1998
        if(!test_level_2_(/*filename_based=*/false)) /* callback-based */
 
1999
                return false;
 
2000
        if(!test_level_2_misc_())
1610
2001
                return false;
1611
2002
 
1612
2003
        return true;