Enable libFLAC to write to new file on changing metadata

Previously, altering metadata could only be done rewriting the
file (or with a tempfile with the assumption the tempfile would
replace the existing file). However, there are good reasons to
write a new file instead. One API call is added for that, and
one is changed to enable this.
This commit is contained in:
Martijn van Beurden 2024-10-24 13:52:59 +02:00
parent 3725add64a
commit 73b55024d0
6 changed files with 417 additions and 276 deletions

View File

@ -1177,6 +1177,7 @@ namespace FLAC {
bool check_if_tempfile_needed(bool use_padding); ///< See FLAC__metadata_chain_check_if_tempfile_needed().
bool write(bool use_padding = true, bool preserve_file_stats = false); ///< See FLAC__metadata_chain_write().
bool write(const char *filename, bool use_padding = false); ///< See FLAC__metadata_chain_write_new_file().
bool write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks); ///< See FLAC__metadata_chain_write_with_callbacks().
bool write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks, ::FLAC__IOHandle temp_handle, ::FLAC__IOCallbacks temp_callbacks); ///< See FLAC__metadata_chain_write_with_callbacks_and_tempfile().

View File

@ -788,9 +788,6 @@ typedef enum {
/**< FLAC__metadata_chain_write_with_callbacks() was called when the
* chain write requires a tempfile; use
* FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead.
* Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was
* called when the chain write does not require a tempfile; use
* FLAC__metadata_chain_write_with_callbacks() instead.
* Always check FLAC__metadata_chain_check_if_tempfile_needed()
* before writing via callbacks. */
@ -927,11 +924,11 @@ FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_
* edited metadata back to the FLAC file does not require rewriting the
* entire file. If rewriting is required, then a temporary workfile is
* required. When writing metadata using callbacks, you must check
* this function to know whether to call
* FLAC__metadata_chain_write_with_callbacks() or
* FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When
* writing with FLAC__metadata_chain_write(), the temporary file is
* handled internally.
* this function to know whether
* FLAC__metadata_chain_write_with_callbacks() can be used or
* FLAC__metadata_chain_write_with_callbacks_and_tempfile() is
* necessary. When writing with FLAC__metadata_chain_write(), the
* temporary file is handled internally.
*
* \param chain A pointer to an existing chain.
* \param use_padding
@ -994,6 +991,28 @@ FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata
*/
FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats);
/** Write all metadata out to a new FLAC file.
*
* This function works similar to FLAC__metadata_chain_write(), but is
* useful if writing to a new file is desired. This is more efficient
* than copying the file before changing it.
*
* For this write function to be used, the chain must have been read with
* FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not
* FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks().
* See also FLAC__metadata_chain_write_with_callbacks_and_tempfile()
*
* \param chain A pointer to an existing chain.
* \param use_padding See FLAC__metadata_chain_write()
* \param filename The filename of the new file.
* \assert
* \code chain != NULL \endcode
* \retval FLAC__bool
* \c true if the write succeeded, else \c false. On failure,
* check the status with FLAC__metadata_chain_status().
*/
FLAC_API FLAC__bool FLAC__metadata_chain_write_new_file(FLAC__Metadata_Chain *chain, const char *filename, FLAC__bool use_padding);
/** Write all metadata out to a FLAC stream via callbacks.
*
* (See FLAC__metadata_chain_write() for the details on how padding is
@ -1035,7 +1054,8 @@ FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Cha
* FLAC file to edit, and a temporary handle to which the new FLAC
* file will be written. It is the caller's job to move this temporary
* FLAC file on top of the original FLAC file to complete the metadata
* edit.
* edit. This version of the write-with-callbacks function can also be
* used if writing to a new file is desired anyway.
*
* The \a handle must be open for reading and be seekable. The
* equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb"
@ -1050,8 +1070,6 @@ FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Cha
* For this write function to be used, the chain must have been read with
* FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(),
* not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg().
* Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned
* \c true.
*
* \param chain A pointer to an existing chain.
* \param use_padding See FLAC__metadata_chain_write()

View File

@ -1619,6 +1619,12 @@ namespace FLAC {
return static_cast<bool>(::FLAC__metadata_chain_write(chain_, use_padding, preserve_file_stats));
}
bool Chain::write(const char* filename, bool use_padding)
{
FLAC__ASSERT(is_valid());
return static_cast<bool>(::FLAC__metadata_chain_write_new_file(chain_, filename, use_padding));
}
bool Chain::write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks)
{
FLAC__ASSERT(is_valid());

View File

@ -1475,7 +1475,7 @@ static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain)
return ret;
}
static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix)
static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix, const char *filename)
{
FILE *f, *tempfile = NULL;
char *tempfilename;
@ -1491,9 +1491,19 @@ static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *t
chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
return false;
}
if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) {
chain->status = get_equivalent_status_(status);
goto err;
if(filename == NULL) {
if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) {
chain->status = get_equivalent_status_(status);
goto err;
}
}
else {
if(0 == (tempfile = flac_fopen(filename, "wb"))) {
(void)fclose(f);
chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
return false;
}
}
if(!copy_n_bytes_from_file_(f, tempfile, chain->first_offset, &status)) {
chain->status = get_equivalent_status_(status);
@ -1525,16 +1535,23 @@ static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *t
/* move the tempfile on top of the original */
(void)fclose(f);
if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status)) {
chain->status = get_equivalent_status_(status);
return false;
if(filename == NULL) {
if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status)) {
chain->status = get_equivalent_status_(status);
return false;
}
}
else
(void)fclose(tempfile);
return true;
err:
(void)fclose(f);
cleanup_tempfile_(&tempfile, &tempfilename);
if(filename == NULL)
cleanup_tempfile_(&tempfile, &tempfilename);
else
(void)fclose(tempfile);
return false;
}
@ -1820,7 +1837,7 @@ FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC
return false;
}
else {
if(!chain_rewrite_file_(chain, tempfile_path_prefix))
if(!chain_rewrite_file_(chain, tempfile_path_prefix, NULL))
return false;
/* recompute lengths and offsets */
@ -1839,6 +1856,48 @@ FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC
return true;
}
FLAC_API FLAC__bool FLAC__metadata_chain_write_new_file(FLAC__Metadata_Chain *chain, const char *filename, FLAC__bool use_padding)
{
FLAC__off_t current_length;
FLAC__ASSERT(0 != chain);
if (chain->is_ogg) { /* cannot write back to Ogg FLAC yet */
chain->status = FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR;
return false;
}
if (0 == chain->filename) {
chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH;
return false;
}
if (0 == filename) {
chain->status = FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT;
return false;
}
current_length = chain_prepare_for_write_(chain, use_padding);
/* a return value of 0 means there was an error; chain->status is already set */
if (0 == current_length)
return false;
if(!chain_rewrite_file_(chain, NULL, filename))
return false;
/* recompute lengths and offsets */
{
const FLAC__Metadata_Node *node;
chain->initial_length = current_length;
chain->last_offset = chain->first_offset;
for(node = chain->head; node; node = node->next)
chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);
}
return true;
}
FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks)
{
FLAC__off_t current_length;
@ -1901,19 +1960,12 @@ FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC_
return false;
}
if (!FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL;
return false;
}
current_length = chain_prepare_for_write_(chain, use_padding);
/* a return value of 0 means there was an error; chain->status is already set */
if (0 == current_length)
return false;
FLAC__ASSERT(current_length != chain->initial_length);
/* rewind */
if(0 != callbacks.seek(handle, 0, SEEK_SET)) {
chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;

View File

@ -77,9 +77,12 @@ static OurMetadata our_metadata_;
/* the current block number that corresponds to the position of the iterator we are testing */
static uint32_t mc_our_block_number_ = 0;
static const char *flacfilename(bool is_ogg)
static const char *flacfilename(bool is_ogg, bool to_different_file)
{
return is_ogg? "metadata.oga" : "metadata.flac";
if(to_different_file)
return is_ogg? "metadata_secondary.oga" : "metadata_secondary.flac";
else
return is_ogg? "metadata.oga" : "metadata.flac";
}
static bool die_(const char *msg)
@ -317,10 +320,13 @@ static int chain_eof_cb_(::FLAC__IOHandle handle)
return feof((FILE*)handle);
}
static bool write_chain_(FLAC::Metadata::Chain &chain, bool use_padding, bool preserve_file_stats, bool filename_based, const char *filename)
static bool write_chain_(FLAC::Metadata::Chain &chain, bool use_padding, bool preserve_file_stats, bool filename_based, const char *filename, FLAC__bool to_different_file)
{
if(filename_based)
return chain.write(use_padding, preserve_file_stats);
if(!to_different_file)
return chain.write(use_padding, preserve_file_stats);
else
return chain.write(flacfilename(false, true), use_padding);
else {
::FLAC__IOCallbacks callbacks;
@ -334,7 +340,7 @@ static bool write_chain_(FLAC::Metadata::Chain &chain, bool use_padding, bool pr
callbacks.seek = chain_seek_cb_;
callbacks.eof = chain_eof_cb_;
if(chain.check_if_tempfile_needed(use_padding)) {
if(to_different_file || chain.check_if_tempfile_needed(use_padding)) {
struct flac_stat_s stats;
FILE *file, *tempfile;
char *tempfilename;
@ -344,10 +350,18 @@ static bool write_chain_(FLAC::Metadata::Chain &chain, bool use_padding, bool pr
}
if(0 == (file = flac_fopen(filename, "rb")))
return false; /*@@@@ chain status still says OK though */
if(!open_tempfile_(filename, &tempfile, &tempfilename)) {
fclose(file);
cleanup_tempfile_(&tempfile, &tempfilename);
return false; /*@@@@ chain status still says OK though */
if(!to_different_file) {
if(!open_tempfile_(filename, &tempfile, &tempfilename)) {
fclose(file);
cleanup_tempfile_(&tempfile, &tempfilename);
return false; /*@@@@ chain status still says OK though */
}
}
else {
if(0 == (tempfile = flac_fopen(flacfilename(false, true), "wb"))) {
fclose(file);
return false; /*@@@@ chain status still says OK though */
}
}
if(!chain.write(use_padding, (::FLAC__IOHandle)file, callbacks, (::FLAC__IOHandle)tempfile, callbacks)) {
fclose(file);
@ -357,10 +371,16 @@ static bool write_chain_(FLAC::Metadata::Chain &chain, bool use_padding, bool pr
fclose(file);
fclose(tempfile);
file = tempfile = 0;
if(!transport_tempfile_(filename, &tempfile, &tempfilename))
return false;
if(preserve_file_stats)
set_file_stats_(filename, &stats);
if(!to_different_file) {
if(!transport_tempfile_(filename, &tempfile, &tempfilename))
return false;
if(preserve_file_stats)
set_file_stats_(filename, &stats);
}
else {
if(preserve_file_stats)
set_file_stats_(flacfilename(false, true), &stats);
}
}
else {
FILE *file = flac_fopen(filename, "r+b");
@ -604,7 +624,7 @@ static bool generate_file_(bool include_extras, bool is_ogg)
)
return die_("priming our metadata");
if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg), 0, 512 * 1024, &streaminfo, metadata, n))
if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg, false), 0, 512 * 1024, &streaminfo, metadata, n))
return die_("creating the encoded file");
free(vorbiscomment.data.vorbis_comment.vendor_string.entry);
@ -615,11 +635,15 @@ static bool generate_file_(bool include_extras, bool is_ogg)
return true;
}
static bool test_file_(bool is_ogg, bool ignore_metadata)
static bool test_file_(bool is_ogg, bool ignore_metadata, bool to_different_file)
{
const char *filename = flacfilename(is_ogg);
const char *filename = flacfilename(is_ogg, false);
OurFileDecoder decoder(ignore_metadata);
if(to_different_file)
if(flac_unlink(filename) || flac_rename(flacfilename(is_ogg, true), filename))
return die_("renaming file");
mc_our_block_number_ = 0;
decoder.error_occurred_ = false;
@ -680,12 +704,12 @@ static bool test_level_0_()
if(!generate_file_(/*include_extras=*/true, /*is_ogg=*/false))
return false;
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/true))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/true, false))
return false;
printf("testing FLAC::Metadata::get_streaminfo()... ");
if(!FLAC::Metadata::get_streaminfo(flacfilename(/*is_ogg=*/false), streaminfo))
if(!FLAC::Metadata::get_streaminfo(flacfilename(/*is_ogg=*/false, false), streaminfo))
return die_("during FLAC::Metadata::get_streaminfo()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -707,7 +731,7 @@ static bool test_level_0_()
FLAC::Metadata::VorbisComment *tags = 0;
if(!FLAC::Metadata::get_tags(flacfilename(/*is_ogg=*/false), tags))
if(!FLAC::Metadata::get_tags(flacfilename(/*is_ogg=*/false, false), tags))
return die_("during FLAC::Metadata::get_tags()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -724,7 +748,7 @@ static bool test_level_0_()
FLAC::Metadata::VorbisComment tags;
if(!FLAC::Metadata::get_tags(flacfilename(/*is_ogg=*/false), tags))
if(!FLAC::Metadata::get_tags(flacfilename(/*is_ogg=*/false, false), tags))
return die_("during FLAC::Metadata::get_tags()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -739,7 +763,7 @@ static bool test_level_0_()
FLAC::Metadata::CueSheet *cuesheet = 0;
if(!FLAC::Metadata::get_cuesheet(flacfilename(/*is_ogg=*/false), cuesheet))
if(!FLAC::Metadata::get_cuesheet(flacfilename(/*is_ogg=*/false, false), cuesheet))
return die_("during FLAC::Metadata::get_cuesheet()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -756,7 +780,7 @@ static bool test_level_0_()
FLAC::Metadata::CueSheet cuesheet;
if(!FLAC::Metadata::get_cuesheet(flacfilename(/*is_ogg=*/false), cuesheet))
if(!FLAC::Metadata::get_cuesheet(flacfilename(/*is_ogg=*/false, false), cuesheet))
return die_("during FLAC::Metadata::get_cuesheet()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -771,7 +795,7 @@ static bool test_level_0_()
FLAC::Metadata::Picture *picture = 0;
if(!FLAC::Metadata::get_picture(flacfilename(/*is_ogg=*/false), picture, /*type=*/(::FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(uint32_t)(-1), /*max_height=*/(uint32_t)(-1), /*max_depth=*/(uint32_t)(-1), /*max_colors=*/(uint32_t)(-1)))
if(!FLAC::Metadata::get_picture(flacfilename(/*is_ogg=*/false, false), picture, /*type=*/(::FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(uint32_t)(-1), /*max_height=*/(uint32_t)(-1), /*max_depth=*/(uint32_t)(-1), /*max_colors=*/(uint32_t)(-1)))
return die_("during FLAC::Metadata::get_picture()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -788,7 +812,7 @@ static bool test_level_0_()
FLAC::Metadata::Picture picture;
if(!FLAC::Metadata::get_picture(flacfilename(/*is_ogg=*/false), picture, /*type=*/(::FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(uint32_t)(-1), /*max_height=*/(uint32_t)(-1), /*max_depth=*/(uint32_t)(-1), /*max_colors=*/(uint32_t)(-1)))
if(!FLAC::Metadata::get_picture(flacfilename(/*is_ogg=*/false, false), picture, /*type=*/(::FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(uint32_t)(-1), /*max_height=*/(uint32_t)(-1), /*max_depth=*/(uint32_t)(-1), /*max_colors=*/(uint32_t)(-1)))
return die_("during FLAC::Metadata::get_picture()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -798,7 +822,7 @@ static bool test_level_0_()
printf("OK\n");
}
if(!remove_file_(flacfilename(/*is_ogg=*/false)))
if(!remove_file_(flacfilename(/*is_ogg=*/false, false)))
return false;
return true;
@ -825,10 +849,10 @@ static bool test_level_1_()
if(!generate_file_(/*include_extras=*/false, /*is_ogg=*/false))
return false;
if(!change_stats_(flacfilename(/*is_ogg=*/false), /*read_only=*/true))
if(!change_stats_(flacfilename(/*is_ogg=*/false, false), /*read_only=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/true))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/true, false))
return false;
FLAC::Metadata::SimpleIterator iterator;
@ -836,7 +860,7 @@ static bool test_level_1_()
if(!iterator.is_valid())
return die_("iterator.is_valid() returned false");
if(!iterator.init(flacfilename(/*is_ogg=*/false), /*read_only=*/false, /*preserve_file_stats=*/false))
if(!iterator.init(flacfilename(/*is_ogg=*/false, false), /*read_only=*/false, /*preserve_file_stats=*/false))
return die_("iterator.init() returned false");
printf("is writable = %u\n", (uint32_t)iterator.is_writable());
@ -915,7 +939,7 @@ static bool test_level_1_()
{
printf("simple iterator on writable file\n");
if(!change_stats_(flacfilename(/*is_ogg=*/false), /*read-only=*/false))
if(!change_stats_(flacfilename(/*is_ogg=*/false, false), /*read-only=*/false))
return false;
printf("creating APPLICATION block\n");
@ -940,7 +964,7 @@ static bool test_level_1_()
return die_("iterator.is_valid() returned false");
}
if(!iterator.init(flacfilename(/*is_ogg=*/false), /*read_only=*/false, /*preserve_file_stats=*/false)) {
if(!iterator.init(flacfilename(/*is_ogg=*/false, false), /*read_only=*/false, /*preserve_file_stats=*/false)) {
delete app;
delete padding;
return die_("iterator.init() returned false");
@ -1001,7 +1025,7 @@ static bool test_level_1_()
if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[P]PP\tprev\n");
@ -1021,7 +1045,7 @@ static bool test_level_1_()
if(iterator.status() != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT)
return die_("iterator.status() should have been FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT");
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("[S]VPPP\tnext\n");
@ -1049,7 +1073,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("S[V]PP\tnext\n");
@ -1067,7 +1091,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
our_current_position--;
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[P]P\tnext\n");
@ -1080,7 +1104,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[P]\tprev\n");
@ -1105,7 +1129,7 @@ static bool test_level_1_()
return die_ss_("iterator.set_block(block, false)", iterator);
delete block;
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("[S]VP\tnext\n");
@ -1121,7 +1145,7 @@ static bool test_level_1_()
return false;
add_to_padding_length_(our_current_position+1, -((int)(FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + (int)app->get_length()));
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]P\tnext\n");
@ -1137,7 +1161,7 @@ static bool test_level_1_()
return false;
add_to_padding_length_(our_current_position+1, -((int)(FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + (int)app->get_length()));
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVA[A]P\tset APPLICATION (grow), don't expand into padding\n");
@ -1149,7 +1173,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, false))
return die_ss_("iterator.set_block(app, false)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVA[A]P\tset APPLICATION (shrink), don't fill in with padding\n");
@ -1161,7 +1185,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, false))
return die_ss_("iterator.set_block(app, false)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVA[A]P\tset APPLICATION (grow), expand into padding of exceeding size\n");
@ -1174,7 +1198,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, true))
return die_ss_("iterator.set_block(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVA[A]P\tset APPLICATION (shrink), fill in with padding\n");
@ -1189,7 +1213,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, true))
return die_ss_("iterator.set_block(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVA[A]PP\tnext\n");
@ -1209,7 +1233,7 @@ static bool test_level_1_()
if(!iterator.set_block(padding, false))
return die_ss_("iterator.set_block(padding, false)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVAAP[P]\tset APPLICATION (grow)\n");
@ -1219,7 +1243,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, false))
return die_ss_("iterator.set_block(app, false)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVAAP[A]\tset PADDING (equal)\n");
@ -1229,7 +1253,7 @@ static bool test_level_1_()
if(!iterator.set_block(padding, false))
return die_ss_("iterator.set_block(padding, false)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVAAP[P]\tprev\n");
@ -1242,7 +1266,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVA[A]P\tdelete (middle block), don't replace with padding\n");
@ -1250,7 +1274,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]P\tnext\n");
@ -1265,7 +1289,7 @@ static bool test_level_1_()
if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVAP[P]\tprev\n");
@ -1286,7 +1310,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, true))
return die_ss_("iterator.set_block(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]PP\tset APPLICATION (grow), try to expand into padding which is 'close' but still too small\n");
@ -1297,7 +1321,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, true))
return die_ss_("iterator.set_block(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]PP\tset APPLICATION (grow), expand into padding which will leave 0-length pad\n");
@ -1309,7 +1333,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, true))
return die_ss_("iterator.set_block(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]PP\tset APPLICATION (grow), expand into padding which is exactly consumed\n");
@ -1321,7 +1345,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, true))
return die_ss_("iterator.set_block(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]P\tset APPLICATION (grow), expand into padding which is exactly consumed\n");
@ -1334,7 +1358,7 @@ static bool test_level_1_()
if(!iterator.set_block(app, true))
return die_ss_("iterator.set_block(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]\tset PADDING (equal size)\n");
@ -1344,7 +1368,7 @@ static bool test_level_1_()
if(!iterator.set_block(padding, true))
return die_ss_("iterator.set_block(padding, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[P]\tinsert PADDING after\n");
@ -1353,7 +1377,7 @@ static bool test_level_1_()
if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVP[P]\tinsert PADDING after\n");
@ -1363,7 +1387,7 @@ static bool test_level_1_()
if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SVPP[P]\tprev\n");
@ -1389,7 +1413,7 @@ static bool test_level_1_()
if(!iterator.insert_block_after(app, true))
return die_ss_("iterator.insert_block_after(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]PPP\tdelete (middle block), don't replace with padding\n");
@ -1397,7 +1421,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("S[V]PPP\tinsert APPLICATION after, try to expand into padding which is 'close' but still too small\n");
@ -1408,7 +1432,7 @@ static bool test_level_1_()
if(!iterator.insert_block_after(app, true))
return die_ss_("iterator.insert_block_after(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]PPP\tdelete (middle block), don't replace with padding\n");
@ -1416,7 +1440,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("S[V]PPP\tinsert APPLICATION after, expand into padding which is exactly consumed\n");
@ -1428,7 +1452,7 @@ static bool test_level_1_()
if(!iterator.insert_block_after(app, true))
return die_ss_("iterator.insert_block_after(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]PP\tdelete (middle block), don't replace with padding\n");
@ -1436,7 +1460,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("S[V]PP\tinsert APPLICATION after, expand into padding which will leave 0-length pad\n");
@ -1448,7 +1472,7 @@ static bool test_level_1_()
if(!iterator.insert_block_after(app, true))
return die_ss_("iterator.insert_block_after(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("SV[A]PP\tdelete (middle block), don't replace with padding\n");
@ -1456,7 +1480,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("S[V]PP\tnext\n");
@ -1469,7 +1493,7 @@ static bool test_level_1_()
return die_ss_("iterator.delete_block(false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
printf("S[V]P\tinsert APPLICATION after, expand into padding which is exactly consumed\n");
@ -1481,20 +1505,20 @@ static bool test_level_1_()
if(!iterator.insert_block_after(app, true))
return die_ss_("iterator.insert_block_after(app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false))
if(!test_file_(/*is_ogg=*/false, /*ignore_metadata=*/false, false))
return false;
}
delete app;
delete padding;
if(!remove_file_(flacfilename(/*is_ogg=*/false)))
if(!remove_file_(flacfilename(/*is_ogg=*/false, false)))
return false;
return true;
}
static bool test_level_2_(bool filename_based, bool is_ogg)
static bool test_level_2_(bool filename_based, bool is_ogg, bool to_different_file)
{
FLAC::Metadata::Prototype *block;
FLAC::Metadata::StreamInfo *streaminfo;
@ -1506,14 +1530,14 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
// initialize 'data' to avoid Valgrind errors
memset(data, 0, sizeof(data));
printf("\n\n++++++ testing level 2 interface (%s-based, %s FLAC)\n", filename_based? "filename":"callback", is_ogg? "Ogg":"native");
printf("\n\n++++++ testing level 2 interface (%s-based, %s FLAC, %s)\n", filename_based? "filename":"callback", is_ogg? "Ogg":"native", to_different_file? "Different file":"Same file");
printf("generate read-only file\n");
if(!generate_file_(/*include_extras=*/false, is_ogg))
return false;
if(!change_stats_(flacfilename(is_ogg), /*read_only=*/true))
if(!change_stats_(flacfilename(is_ogg, false), /*read_only=*/true))
return false;
printf("create chain\n");
@ -1523,14 +1547,14 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
printf("read chain\n");
if(!read_chain_(chain, flacfilename(is_ogg), filename_based, is_ogg))
if(!read_chain_(chain, flacfilename(is_ogg, false), filename_based, is_ogg))
return die_c_("reading chain", chain.status());
printf("[S]VP\ttest initial metadata\n");
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, false))
return false;
if(is_ogg)
@ -1538,7 +1562,7 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
printf("switch file to read-write\n");
if(!change_stats_(flacfilename(is_ogg), /*read-only=*/false))
if(!change_stats_(flacfilename(is_ogg, false), /*read-only=*/false))
return false;
printf("create iterator\n");
@ -1565,13 +1589,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
return die_("copying object");
delete block;
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/true, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/true, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(false, true)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("[S]VP\tnext\n");
@ -1598,13 +1622,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(false, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]\tshrink APPLICATION, don't use padding\n");
@ -1617,13 +1641,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(false, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]\tgrow APPLICATION, don't use padding\n");
@ -1636,13 +1660,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(false, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]\tgrow APPLICATION, use padding, but last block is not padding\n");
@ -1655,13 +1679,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(false, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]\tshrink APPLICATION, use padding, last block is not padding, but delta is too small for new PADDING block\n");
@ -1674,13 +1698,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(true, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]\tshrink APPLICATION, use padding, last block is not padding, delta is enough for new PADDING block\n");
@ -1698,13 +1722,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(true, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]P\tshrink APPLICATION, use padding, last block is padding\n");
@ -1718,13 +1742,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(true, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding, but delta is too small\n");
@ -1737,13 +1761,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(true, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding of exceeding size\n");
@ -1757,13 +1781,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(true, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding of exact size\n");
@ -1777,13 +1801,13 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
if(!iterator.set_block(app))
return die_c_("iterator.set_block(app)", chain.status());
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(true, false)", chain.status());
block = iterator.get_block();
if(!compare_chain_(chain, our_current_position, block))
return false;
delete block;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV[A]\tprev\n");
@ -1904,11 +1928,11 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
delete_from_our_metadata_(4);
delete_from_our_metadata_(3);
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(true, false)", chain.status());
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SVPAP\tsort padding\n");
@ -1916,11 +1940,11 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
add_to_padding_length_(4, FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[2]->get_length());
delete_from_our_metadata_(2);
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(true, false)", chain.status());
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("create iterator\n");
@ -2026,25 +2050,25 @@ static bool test_level_2_(bool filename_based, bool is_ogg)
printf("SV\tmerge padding\n");
chain.merge_padding();
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(false, false)", chain.status());
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
printf("SV\tsort padding\n");
chain.sort_padding();
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during chain.write(false, false)", chain.status());
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
if(!test_file_(is_ogg, /*ignore_metadata=*/false, to_different_file))
return false;
end:
if(!remove_file_(flacfilename(is_ogg)))
if(!remove_file_(flacfilename(is_ogg, false)))
return false;
return true;
@ -2079,7 +2103,7 @@ static bool test_level_2_misc_(bool is_ogg)
printf("read chain (filename-based)\n");
if(!chain.read(flacfilename(is_ogg)))
if(!chain.read(flacfilename(is_ogg, false)))
return die_c_("reading chain", chain.status());
printf("write chain with wrong method Chain::write(with callbacks)\n");
@ -2093,7 +2117,7 @@ static bool test_level_2_misc_(bool is_ogg)
printf("read chain (filename-based)\n");
if(!chain.read(flacfilename(is_ogg)))
if(!chain.read(flacfilename(is_ogg, false)))
return die_c_("reading chain", chain.status());
printf("write chain with wrong method Chain::write(with callbacks and tempfile)\n");
@ -2107,7 +2131,7 @@ static bool test_level_2_misc_(bool is_ogg)
printf("read chain (callback-based)\n");
{
FILE *file = flac_fopen(flacfilename(is_ogg), "rb");
FILE *file = flac_fopen(flacfilename(is_ogg, false), "rb");
if(0 == file)
return die_("opening file");
if(!chain.read((::FLAC__IOHandle)file, callbacks)) {
@ -2126,9 +2150,31 @@ static bool test_level_2_misc_(bool is_ogg)
printf(" OK: write() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
}
printf("read chain (callback-based)\n");
{
FILE *file = flac_fopen(flacfilename(is_ogg), "rb");
FILE *file = flac_fopen(flacfilename(is_ogg, false), "rb");
if(0 == file)
return die_("opening file");
if(!chain.read((::FLAC__IOHandle)file, callbacks)) {
fclose(file);
return die_c_("reading chain", chain.status());
}
fclose(file);
}
printf("write chain with wrong method write()\n");
{
if(chain.write(flacfilename(is_ogg, true),/*use_padding=*/false))
return die_c_("mismatched write should have failed", chain.status());
if(chain.status() != ::FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH)
return die_c_("expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", chain.status());
printf(" OK: write() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
}
printf("read chain (callback-based)\n");
{
FILE *file = flac_fopen(flacfilename(is_ogg, false), "rb");
if(0 == file)
return die_("opening file");
if(!chain.read((::FLAC__IOHandle)file, callbacks)) {
@ -2145,18 +2191,9 @@ static bool test_level_2_misc_(bool is_ogg)
else
return die_("Chain::check_if_tempfile_needed() returned true but shouldn't have");
printf("write chain with wrong method Chain::write(with callbacks and tempfile)\n");
{
if(chain.write(/*use_padding=*/false, 0, callbacks, 0, callbacks))
return die_c_("mismatched write should have failed", chain.status());
if(chain.status() != ::FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL)
return die_c_("expected FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL", chain.status());
printf(" OK: Chain::write(with callbacks and tempfile) returned false,FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL like it should\n");
}
printf("read chain (callback-based)\n");
{
FILE *file = flac_fopen(flacfilename(is_ogg), "rb");
FILE *file = flac_fopen(flacfilename(is_ogg, false), "rb");
if(0 == file)
return die_("opening file");
if(!chain.read((::FLAC__IOHandle)file, callbacks)) {
@ -2200,7 +2237,7 @@ static bool test_level_2_misc_(bool is_ogg)
} // delete iterator
if(!remove_file_(flacfilename(is_ogg)))
if(!remove_file_(flacfilename(is_ogg, false)))
return false;
return true;
@ -2218,17 +2255,21 @@ bool test_metadata_file_manipulation()
if(!test_level_1_())
return false;
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/false)) /* filename-based */
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/false, /*to_different_file=*/false)) /* filename-based */
return false;
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/false)) /* callback-based */
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/false, /*to_different_file=*/false)) /* callback-based */
return false;
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/false, /*to_different_file=*/true)) /* filename-based */
return false;
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/false, /*to_different_file=*/true)) /* callback-based */
return false;
if(!test_level_2_misc_(/*is_ogg=*/false))
return false;
if(FLAC_API_SUPPORTS_OGG_FLAC) {
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/true)) /* filename-based */
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/true, /*to_different_file=*/false)) /* filename-based */
return false;
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/true)) /* callback-based */
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/true, /*to_different_file=*/false)) /* callback-based */
return false;
#if 0
/* when ogg flac write is supported, will have to add this: */

View File

@ -70,9 +70,12 @@ static our_metadata_struct our_metadata_;
/* the current block number that corresponds to the position of the iterator we are testing */
static uint32_t mc_our_block_number_ = 0;
static const char *flacfilename(FLAC__bool is_ogg)
static const char *flacfilename(FLAC__bool is_ogg, FLAC__bool to_different_file)
{
return is_ogg? "metadata.oga" : "metadata.flac";
if(to_different_file)
return is_ogg? "metadata_secondary.oga" : "metadata_secondary.flac";
else
return is_ogg? "metadata.oga" : "metadata.flac";
}
static FLAC__bool die_(const char *msg)
@ -303,10 +306,13 @@ static int chain_eof_cb_(FLAC__IOHandle handle)
return feof((FILE*)handle);
}
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)
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, FLAC__bool to_different_file)
{
if(filename_based)
return FLAC__metadata_chain_write(chain, use_padding, preserve_file_stats);
if(!to_different_file)
return FLAC__metadata_chain_write(chain, use_padding, preserve_file_stats);
else
return FLAC__metadata_chain_write_new_file(chain, flacfilename(false, true), use_padding);
else {
FLAC__IOCallbacks callbacks;
@ -320,7 +326,7 @@ static FLAC__bool write_chain_(FLAC__Metadata_Chain *chain, FLAC__bool use_paddi
callbacks.seek = chain_seek_cb_;
callbacks.eof = chain_eof_cb_;
if(FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
if(to_different_file || FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
struct flac_stat_s stats;
FILE *file, *tempfile = 0;
char *tempfilename;
@ -330,10 +336,18 @@ static FLAC__bool write_chain_(FLAC__Metadata_Chain *chain, FLAC__bool use_paddi
}
if(0 == (file = flac_fopen(filename, "rb")))
return false; /*@@@@ chain status still says OK though */
if(!open_tempfile_(filename, &tempfile, &tempfilename)) {
fclose(file);
cleanup_tempfile_(&tempfile, &tempfilename);
return false; /*@@@@ chain status still says OK though */
if(!to_different_file) {
if(!open_tempfile_(filename, &tempfile, &tempfilename)) {
fclose(file);
cleanup_tempfile_(&tempfile, &tempfilename);
return false; /*@@@@ chain status still says OK though */
}
}
else {
if(0 == (tempfile = flac_fopen(flacfilename(false, true), "wb"))) {
fclose(file);
return false; /*@@@@ chain status still says OK though */
}
}
if(!FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, use_padding, (FLAC__IOHandle)file, callbacks, (FLAC__IOHandle)tempfile, callbacks)) {
fclose(file);
@ -343,10 +357,16 @@ static FLAC__bool write_chain_(FLAC__Metadata_Chain *chain, FLAC__bool use_paddi
fclose(file);
fclose(tempfile);
file = tempfile = 0;
if(!transport_tempfile_(filename, &tempfile, &tempfilename))
return false;
if(preserve_file_stats)
set_file_stats_(filename, &stats);
if(!to_different_file) {
if(!transport_tempfile_(filename, &tempfile, &tempfilename))
return false;
if(preserve_file_stats)
set_file_stats_(filename, &stats);
}
else
if(preserve_file_stats)
set_file_stats_(flacfilename(false, true), &stats);
}
else {
FILE *file = flac_fopen(filename, "r+b");
@ -365,8 +385,8 @@ static FLAC__bool read_chain_(FLAC__Metadata_Chain *chain, const char *filename,
{
if(filename_based)
return is_ogg?
FLAC__metadata_chain_read_ogg(chain, flacfilename(is_ogg)) :
FLAC__metadata_chain_read(chain, flacfilename(is_ogg))
FLAC__metadata_chain_read_ogg(chain, flacfilename(is_ogg, false)) :
FLAC__metadata_chain_read(chain, flacfilename(is_ogg, false))
;
else {
FLAC__IOCallbacks callbacks;
@ -613,7 +633,7 @@ static FLAC__bool generate_file_(FLAC__bool include_extras, FLAC__bool is_ogg)
)
return die_("priming our metadata");
if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg), 0, 512 * 1024, &streaminfo, metadata, n))
if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg, false), 0, 512 * 1024, &streaminfo, metadata, n))
return die_("creating the encoded file");
free(vorbiscomment.data.vorbis_comment.vendor_string.entry);
@ -626,14 +646,19 @@ static FLAC__bool generate_file_(FLAC__bool include_extras, FLAC__bool is_ogg)
return true;
}
static FLAC__bool test_file_(FLAC__bool is_ogg, FLAC__StreamDecoderMetadataCallback metadata_callback)
static FLAC__bool test_file_(FLAC__bool is_ogg, FLAC__StreamDecoderMetadataCallback metadata_callback, FLAC__bool to_different_file)
{
const char *filename = flacfilename(is_ogg);
const char *filename = flacfilename(is_ogg, false);
FLAC__StreamDecoder *decoder;
decoder_client_struct decoder_client_data;
FLAC__ASSERT(0 != metadata_callback);
if(to_different_file) {
if(flac_unlink(filename) || flac_rename(flacfilename(is_ogg, true), filename))
return die_("renaming file");
}
mc_our_block_number_ = 0;
decoder_client_data.error_occurred = false;
@ -705,12 +730,12 @@ static FLAC__bool test_level_0_(FLAC__bool is_ogg)
if(!generate_file_(/*include_extras=*/true, is_ogg))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_null_))
if(!test_file_(is_ogg, decoder_metadata_callback_null_, false))
return false;
printf("testing FLAC__metadata_get_streaminfo()... ");
if(!FLAC__metadata_get_streaminfo(flacfilename(is_ogg), &streaminfo))
if(!FLAC__metadata_get_streaminfo(flacfilename(is_ogg, false), &streaminfo))
return die_("during FLAC__metadata_get_streaminfo()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -729,7 +754,7 @@ static FLAC__bool test_level_0_(FLAC__bool is_ogg)
printf("testing FLAC__metadata_get_tags()... ");
if(!FLAC__metadata_get_tags(flacfilename(is_ogg), &tags))
if(!FLAC__metadata_get_tags(flacfilename(is_ogg, false), &tags))
return die_("during FLAC__metadata_get_tags()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -742,7 +767,7 @@ static FLAC__bool test_level_0_(FLAC__bool is_ogg)
printf("testing FLAC__metadata_get_cuesheet()... ");
if(!FLAC__metadata_get_cuesheet(flacfilename(is_ogg), &cuesheet))
if(!FLAC__metadata_get_cuesheet(flacfilename(is_ogg, false), &cuesheet))
return die_("during FLAC__metadata_get_cuesheet()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -756,7 +781,7 @@ static FLAC__bool test_level_0_(FLAC__bool is_ogg)
/* FLAC__metadata_get_picture uses layer 1, which isn't ogg-capable yet */
printf("testing FLAC__metadata_get_picture()... ");
if(!FLAC__metadata_get_picture(flacfilename(is_ogg), &picture, /*type=*/(FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(uint32_t)(-1), /*max_height=*/(uint32_t)(-1), /*max_depth=*/(uint32_t)(-1), /*max_colors=*/(uint32_t)(-1)))
if(!FLAC__metadata_get_picture(flacfilename(is_ogg, false), &picture, /*type=*/(FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(uint32_t)(-1), /*max_height=*/(uint32_t)(-1), /*max_depth=*/(uint32_t)(-1), /*max_colors=*/(uint32_t)(-1)))
return die_("during FLAC__metadata_get_picture()");
/* check to see if some basic data matches (c.f. generate_file_()) */
@ -768,7 +793,7 @@ static FLAC__bool test_level_0_(FLAC__bool is_ogg)
FLAC__metadata_object_delete(picture);
}
if(!remove_file_(flacfilename(is_ogg)))
if(!remove_file_(flacfilename(is_ogg, false)))
return false;
return true;
@ -793,16 +818,16 @@ static FLAC__bool test_level_1_(void)
if(!generate_file_(/*include_extras=*/false, /*is_ogg=*/false))
return false;
if(!change_stats_(flacfilename(/*is_ogg=*/false), /*read_only=*/true))
if(!change_stats_(flacfilename(/*is_ogg=*/false, false), /*read_only=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_null_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_null_, false))
return false;
if(0 == (iterator = FLAC__metadata_simple_iterator_new()))
return die_("FLAC__metadata_simple_iterator_new()");
if(!FLAC__metadata_simple_iterator_init(iterator, flacfilename(/*is_ogg=*/false), /*read_only=*/false, /*preserve_file_stats=*/false))
if(!FLAC__metadata_simple_iterator_init(iterator, flacfilename(/*is_ogg=*/false, false), /*read_only=*/false, /*preserve_file_stats=*/false))
return die_("FLAC__metadata_simple_iterator_init() returned false");
printf("is writable = %u\n", (uint32_t)FLAC__metadata_simple_iterator_is_writable(iterator));
@ -879,7 +904,7 @@ static FLAC__bool test_level_1_(void)
printf("simple iterator on writable file\n");
if(!change_stats_(flacfilename(/*is_ogg=*/false), /*read-only=*/false))
if(!change_stats_(flacfilename(/*is_ogg=*/false, false), /*read-only=*/false))
return false;
printf("creating APPLICATION block\n");
@ -897,7 +922,7 @@ static FLAC__bool test_level_1_(void)
if(0 == (iterator = FLAC__metadata_simple_iterator_new()))
return die_("FLAC__metadata_simple_iterator_new()");
if(!FLAC__metadata_simple_iterator_init(iterator, flacfilename(/*is_ogg=*/false), /*read_only=*/false, /*preserve_file_stats=*/false))
if(!FLAC__metadata_simple_iterator_init(iterator, flacfilename(/*is_ogg=*/false, false), /*read_only=*/false, /*preserve_file_stats=*/false))
return die_("FLAC__metadata_simple_iterator_init() returned false");
our_current_position = 0;
@ -946,7 +971,7 @@ static FLAC__bool test_level_1_(void)
if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[P]PP\tprev\n");
@ -966,7 +991,7 @@ static FLAC__bool test_level_1_(void)
if(FLAC__metadata_simple_iterator_status(iterator) != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT)
return die_("FLAC__metadata_simple_iterator_status() should have been FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT");
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("[S]VPPP\tnext\n");
@ -994,7 +1019,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("S[V]PP\tnext\n");
@ -1012,7 +1037,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
our_current_position--;
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[P]P\tnext\n");
@ -1025,7 +1050,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[P]\tprev\n");
@ -1048,7 +1073,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, block, false)", iterator);
FLAC__metadata_object_delete(block);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("[S]VP\tnext\n");
@ -1064,7 +1089,7 @@ static FLAC__bool test_level_1_(void)
return false;
our_metadata_.blocks[our_current_position+1]->length -= (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + app->length;
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]P\tnext\n");
@ -1080,7 +1105,7 @@ static FLAC__bool test_level_1_(void)
return false;
our_metadata_.blocks[our_current_position+1]->length -= (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + app->length;
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVA[A]P\tset APPLICATION (grow), don't expand into padding\n");
@ -1092,7 +1117,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVA[A]P\tset APPLICATION (shrink), don't fill in with padding\n");
@ -1104,7 +1129,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVA[A]P\tset APPLICATION (grow), expand into padding of exceeding size\n");
@ -1117,7 +1142,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVA[A]P\tset APPLICATION (shrink), fill in with padding\n");
@ -1132,7 +1157,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVA[A]PP\tnext\n");
@ -1152,7 +1177,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, false)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVAAP[P]\tset APPLICATION (grow)\n");
@ -1162,7 +1187,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVAAP[A]\tset PADDING (equal)\n");
@ -1172,7 +1197,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, false)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVAAP[P]\tprev\n");
@ -1185,7 +1210,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVA[A]P\tdelete (middle block), don't replace with padding\n");
@ -1193,7 +1218,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]P\tnext\n");
@ -1208,7 +1233,7 @@ static FLAC__bool test_level_1_(void)
if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVAP[P]\tprev\n");
@ -1229,7 +1254,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]PP\tset APPLICATION (grow), try to expand into padding which is 'close' but still too small\n");
@ -1240,7 +1265,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]PP\tset APPLICATION (grow), expand into padding which will leave 0-length pad\n");
@ -1252,7 +1277,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]PP\tset APPLICATION (grow), expand into padding which is exactly consumed\n");
@ -1264,7 +1289,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]P\tset APPLICATION (grow), expand into padding which is exactly consumed\n");
@ -1277,7 +1302,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]\tset PADDING (equal size)\n");
@ -1287,7 +1312,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, true))
return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[P]\tinsert PADDING after\n");
@ -1296,7 +1321,7 @@ static FLAC__bool test_level_1_(void)
if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVP[P]\tinsert PADDING after\n");
@ -1306,7 +1331,7 @@ static FLAC__bool test_level_1_(void)
if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
return false;
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SVPP[P]\tprev\n");
@ -1332,7 +1357,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]PPP\tdelete (middle block), don't replace with padding\n");
@ -1340,7 +1365,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("S[V]PPP\tinsert APPLICATION after, try to expand into padding which is 'close' but still too small\n");
@ -1351,7 +1376,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]PPP\tdelete (middle block), don't replace with padding\n");
@ -1359,7 +1384,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("S[V]PPP\tinsert APPLICATION after, expand into padding which is exactly consumed\n");
@ -1371,7 +1396,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]PP\tdelete (middle block), don't replace with padding\n");
@ -1379,7 +1404,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("S[V]PP\tinsert APPLICATION after, expand into padding which will leave 0-length pad\n");
@ -1391,7 +1416,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("SV[A]PP\tdelete (middle block), don't replace with padding\n");
@ -1399,7 +1424,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("S[V]PP\tnext\n");
@ -1412,7 +1437,7 @@ static FLAC__bool test_level_1_(void)
return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
delete_from_our_metadata_(our_current_position--);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("S[V]P\tinsert APPLICATION after, expand into padding which is exactly consumed\n");
@ -1424,7 +1449,7 @@ static FLAC__bool test_level_1_(void)
if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_, false))
return false;
printf("delete simple iterator\n");
@ -1434,31 +1459,31 @@ static FLAC__bool test_level_1_(void)
FLAC__metadata_object_delete(app);
FLAC__metadata_object_delete(padding);
if(!remove_file_(flacfilename(/*is_ogg=*/false)))
if(!remove_file_(flacfilename(/*is_ogg=*/false, false)))
return false;
return true;
}
static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg, FLAC__bool to_different_file)
{
FLAC__Metadata_Iterator *iterator;
FLAC__Metadata_Chain *chain;
FLAC__StreamMetadata *block, *app, *padding;
FLAC__StreamMetadata *block, *app, *padding = 0;
FLAC__byte data[2000];
uint32_t our_current_position;
/* initialize 'data' to avoid Valgrind errors */
memset(data, 0, sizeof(data));
printf("\n\n++++++ testing level 2 interface (%s-based, %s FLAC)\n", filename_based? "filename":"callback", is_ogg? "Ogg":"native");
printf("\n\n++++++ testing level 2 interface (%s-based, %s FLAC, %s)\n", filename_based? "filename":"callback", is_ogg? "Ogg":"native", to_different_file? "Different file":"Same file");
printf("generate read-only file\n");
if(!generate_file_(/*include_extras=*/false, is_ogg))
return false;
if(!change_stats_(flacfilename(is_ogg), /*read_only=*/true))
if(!change_stats_(flacfilename(is_ogg, false), /*read_only=*/true))
return false;
printf("create chain\n");
@ -1468,14 +1493,14 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
printf("read chain\n");
if(!read_chain_(chain, flacfilename(is_ogg), filename_based, is_ogg))
if(!read_chain_(chain, flacfilename(is_ogg, false), filename_based, is_ogg))
return die_c_("reading chain", FLAC__metadata_chain_status(chain));
printf("[S]VP\ttest initial metadata\n");
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, false))
return false;
if(is_ogg)
@ -1483,7 +1508,7 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
printf("switch file to read-write\n");
if(!change_stats_(flacfilename(is_ogg), /*read-only=*/false))
if(!change_stats_(flacfilename(is_ogg, false), /*read-only=*/false))
return false;
printf("create iterator\n");
@ -1505,11 +1530,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!replace_in_our_metadata_(block, our_current_position, /*copy=*/true))
return die_("copying object");
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/true, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/true, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, false, true)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("[S]VP\tnext\n");
@ -1535,11 +1560,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]\tshrink APPLICATION, don't use padding\n");
@ -1552,11 +1577,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]\tgrow APPLICATION, don't use padding\n");
@ -1569,11 +1594,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]\tgrow APPLICATION, use padding, but last block is not padding\n");
@ -1586,11 +1611,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]\tshrink APPLICATION, use padding, last block is not padding, but delta is too small for new PADDING block\n");
@ -1603,11 +1628,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]\tshrink APPLICATION, use padding, last block is not padding, delta is enough for new PADDING block\n");
@ -1625,11 +1650,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]P\tshrink APPLICATION, use padding, last block is padding\n");
@ -1643,11 +1668,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding, but delta is too small\n");
@ -1660,11 +1685,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding of exceeding size\n");
@ -1678,11 +1703,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding of exact size\n");
@ -1696,11 +1721,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
if(!FLAC__metadata_iterator_set_block(iterator, app))
return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV[A]\tprev\n");
@ -1812,11 +1837,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
delete_from_our_metadata_(4);
delete_from_our_metadata_(3);
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SVPAP\tsort padding\n");
@ -1824,11 +1849,11 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
our_metadata_.blocks[4]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[2]->length);
delete_from_our_metadata_(2);
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("create iterator\n");
@ -1923,21 +1948,21 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
printf("SV\tmerge padding\n");
FLAC__metadata_chain_merge_padding(chain);
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
printf("SV\tsort padding\n");
FLAC__metadata_chain_sort_padding(chain);
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg, false), to_different_file))
return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
if(!compare_chain_(chain, 0, 0))
return false;
if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
if(!test_file_(is_ogg, decoder_metadata_callback_compare_, to_different_file))
return false;
end:
@ -1945,7 +1970,7 @@ end:
FLAC__metadata_chain_delete(chain);
if(!remove_file_(flacfilename(is_ogg)))
if(!remove_file_(flacfilename(is_ogg, false)))
return false;
return true;
@ -1982,7 +2007,7 @@ static FLAC__bool test_level_2_misc_(FLAC__bool is_ogg)
printf("read chain (filename-based)\n");
if(!FLAC__metadata_chain_read(chain, flacfilename(is_ogg)))
if(!FLAC__metadata_chain_read(chain, flacfilename(is_ogg, false)))
return die_c_("reading chain", FLAC__metadata_chain_status(chain));
printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks()\n");
@ -1996,7 +2021,7 @@ static FLAC__bool test_level_2_misc_(FLAC__bool is_ogg)
printf("read chain (filename-based)\n");
if(!FLAC__metadata_chain_read(chain, flacfilename(is_ogg)))
if(!FLAC__metadata_chain_read(chain, flacfilename(is_ogg, false)))
return die_c_("reading chain", FLAC__metadata_chain_status(chain));
printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks_and_tempfile()\n");
@ -2010,7 +2035,7 @@ static FLAC__bool test_level_2_misc_(FLAC__bool is_ogg)
printf("read chain (callback-based)\n");
{
FILE *file = flac_fopen(flacfilename(is_ogg), "rb");
FILE *file = flac_fopen(flacfilename(is_ogg, false), "rb");
if(0 == file)
return die_("opening file");
if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
@ -2029,9 +2054,10 @@ static FLAC__bool test_level_2_misc_(FLAC__bool is_ogg)
printf(" OK: FLAC__metadata_chain_write() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
}
printf("read chain (callback-based)\n");
{
FILE *file = flac_fopen(flacfilename(is_ogg), "rb");
FILE *file = flac_fopen(flacfilename(is_ogg, false), "rb");
if(0 == file)
return die_("opening file");
if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
@ -2041,25 +2067,18 @@ static FLAC__bool test_level_2_misc_(FLAC__bool is_ogg)
fclose(file);
}
printf("testing FLAC__metadata_chain_check_if_tempfile_needed()... ");
if(!FLAC__metadata_chain_check_if_tempfile_needed(chain, /*use_padding=*/false))
printf("OK: FLAC__metadata_chain_check_if_tempfile_needed() returned false like it should\n");
else
return die_("FLAC__metadata_chain_check_if_tempfile_needed() returned true but shouldn't have");
printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks_and_tempfile()\n");
printf("write chain with wrong method FLAC__metadata_chain_write_new_file()\n");
{
if(FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, /*use_padding=*/false, 0, callbacks, 0, callbacks))
if(FLAC__metadata_chain_write_new_file(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL)
return die_c_("expected FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL", FLAC__metadata_chain_status(chain));
printf(" OK: FLAC__metadata_chain_write_with_callbacks_and_tempfile() returned false,FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL like it should\n");
if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH)
return die_c_("expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", FLAC__metadata_chain_status(chain));
printf(" OK: FLAC__metadata_chain_write_new_file() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
}
printf("read chain (callback-based)\n");
{
FILE *file = flac_fopen(flacfilename(is_ogg), "rb");
FILE *file = flac_fopen(flacfilename(is_ogg, false), "rb");
if(0 == file)
return die_("opening file");
if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
@ -2107,7 +2126,7 @@ static FLAC__bool test_level_2_misc_(FLAC__bool is_ogg)
FLAC__metadata_chain_delete(chain);
if(!remove_file_(flacfilename(is_ogg)))
if(!remove_file_(flacfilename(is_ogg, false)))
return false;
return true;
@ -2131,17 +2150,21 @@ FLAC__bool test_metadata_file_manipulation(void)
if(!test_level_1_())
return false;
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/false)) /* filename-based */
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/false, /*to_different_file=*/false)) /* filename-based */
return false;
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/false)) /* callback-based */
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/false, /*to_different_file=*/false)) /* callback-based */
return false;
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/false, /*to_different_file=*/true)) /* filename-based */
return false;
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/false, /*to_different_file=*/true)) /* callback-based */
return false;
if(!test_level_2_misc_(/*is_ogg=*/false))
return false;
if(FLAC_API_SUPPORTS_OGG_FLAC) {
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/true)) /* filename-based */
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/true, /*to_different_file=*/false)) /* filename-based */
return false;
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/true)) /* callback-based */
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/true, /*to_different_file=*/false)) /* callback-based */
return false;
#if 0
/* when ogg flac write is supported, will have to add this: */