diff --git a/include/FLAC++/metadata.h b/include/FLAC++/metadata.h index 6b34e2d7..c55d8c48 100644 --- a/include/FLAC++/metadata.h +++ b/include/FLAC++/metadata.h @@ -641,7 +641,7 @@ namespace FLAC { SimpleIterator(); virtual ~SimpleIterator(); - bool init(const char *filename, bool preserve_file_stats = false); + bool init(const char *filename, bool read_only, bool preserve_file_stats); bool is_valid() const; Status status(); diff --git a/include/FLAC/metadata.h b/include/FLAC/metadata.h index 2c9fe843..fcf1482b 100644 --- a/include/FLAC/metadata.h +++ b/include/FLAC/metadata.h @@ -276,12 +276,17 @@ void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterat FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator); /** Initialize the iterator to point to the first metadata block in the - * given FLAC file. If \a preserve_file_stats is \c true, the owner and - * modification time will be preserved even if the FLAC file is written. + * given FLAC file. * * \param iterator A pointer to an existing iterator. * \param filename The path to the FLAC file. - * \param preserve_file_stats See above. + * \param read_only If \c true, the FLAC file will be opened + * in read-only mode; if \c false, the FLAC + * file will be opened for edit even if no + * edits are performed. + * \param preserve_file_stats If \c true, the owner and modification + * time will be preserved even if the FLAC + * file is written to. * \assert * \code iterator != NULL \endcode * \code filename != NULL \endcode @@ -289,7 +294,7 @@ FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__ * \c false if a memory allocation error occurs, the file can't be * opened, or another error occurs, else \c true. */ -FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool preserve_file_stats); +FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats); /** Returns \c true if the FLAC file is writable. If \c false, calls to * FLAC__metadata_simple_iterator_set_block() and diff --git a/src/libFLAC++/metadata.cc b/src/libFLAC++/metadata.cc index e2abf818..a5023a5c 100644 --- a/src/libFLAC++/metadata.cc +++ b/src/libFLAC++/metadata.cc @@ -782,11 +782,11 @@ namespace FLAC { iterator_ = 0; } - bool SimpleIterator::init(const char *filename, bool preserve_file_stats) + bool SimpleIterator::init(const char *filename, bool read_only, bool preserve_file_stats) { FLAC__ASSERT(0 != filename); FLAC__ASSERT(is_valid()); - return (bool)::FLAC__metadata_simple_iterator_init(iterator_, filename, preserve_file_stats); + return (bool)::FLAC__metadata_simple_iterator_init(iterator_, filename, read_only, preserve_file_stats); } bool SimpleIterator::is_valid() const diff --git a/src/libFLAC/metadata_iterators.c b/src/libFLAC/metadata_iterators.c index 70d78b31..95cea1ca 100644 --- a/src/libFLAC/metadata_iterators.c +++ b/src/libFLAC/metadata_iterators.c @@ -297,18 +297,17 @@ FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__ return status; } -static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *iterator) +static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool read_only) { unsigned ret; FLAC__ASSERT(0 != iterator); - iterator->is_writable = false; - - if(0 == (iterator->file = fopen(iterator->filename, "r+b"))) { + if(read_only || 0 == (iterator->file = fopen(iterator->filename, "r+b"))) { + iterator->is_writable = false; #if !defined _MSC_VER && !defined __MINGW32__ /*@@@ don't know how to resolve errno without using LIBC.LIB; must use MSVCRT.LIB only for plugins */ - if(errno == EACCES) { + if(read_only || errno == EACCES) { #endif if(0 == (iterator->file = fopen(iterator->filename, "rb"))) { iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; @@ -362,7 +361,7 @@ static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *it FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool preserve_file_stats, const char *tempfile_path_prefix); #endif -FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool preserve_file_stats) +FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats) { const char *tempfile_path_prefix = 0; /*@@@ search for comments near 'rename(...)' for what it will take to finish implementing this */ @@ -371,7 +370,7 @@ FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *it simple_iterator_free_guts_(iterator); - if(preserve_file_stats) + if(!read_only && preserve_file_stats) iterator->has_stats = get_file_stats_(filename, &iterator->stats); if(0 == (iterator->filename = strdup(filename))) { @@ -383,7 +382,7 @@ FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *it return false; } - return simple_iterator_prime_input_(iterator); + return simple_iterator_prime_input_(iterator, read_only); } FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator) @@ -949,7 +948,7 @@ FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *fi return false; } - if(!FLAC__metadata_simple_iterator_init(iterator, filename, /*preserve_file_stats=*/false)) { + if(!FLAC__metadata_simple_iterator_init(iterator, filename, /*read_only=*/true, /*preserve_file_stats=*/false)) { chain->status = get_equivalent_status_(iterator->status); return false; } @@ -2071,7 +2070,7 @@ FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *ite if(iterator->has_stats) set_file_stats_(iterator->filename, &iterator->stats); - if(!simple_iterator_prime_input_(iterator)) + if(!simple_iterator_prime_input_(iterator, !iterator->is_writable)) return false; if(backup) { while(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length < save_offset) diff --git a/src/test_libFLAC++/metadata_manip.cc b/src/test_libFLAC++/metadata_manip.cc index 2a0812bd..47fb1b9f 100644 --- a/src/test_libFLAC++/metadata_manip.cc +++ b/src/test_libFLAC++/metadata_manip.cc @@ -441,7 +441,7 @@ static bool test_level_1_() if(!iterator.is_valid()) return die_("iterator.is_valid() returned false"); - if(!iterator.init(flacfile_, false)) + if(!iterator.init(flacfile_, /*read_only=*/false, /*preserve_file_stats=*/false)) return die_("iterator.init() returned false"); printf("is writable = %u\n", (unsigned)iterator.is_writable()); @@ -537,7 +537,7 @@ static bool test_level_1_() if(!iterator.is_valid()) return die_("iterator.is_valid() returned false"); - if(!iterator.init(flacfile_, /*preserve_file_stats=*/false)) + if(!iterator.init(flacfile_, /*read_only=*/false, /*preserve_file_stats=*/false)) return die_("iterator.init() returned false"); our_current_position = 0; diff --git a/src/test_libFLAC/metadata_manip.c b/src/test_libFLAC/metadata_manip.c index b9988223..152f8734 100644 --- a/src/test_libFLAC/metadata_manip.c +++ b/src/test_libFLAC/metadata_manip.c @@ -451,7 +451,7 @@ static FLAC__bool test_level_1_() if(0 == (iterator = FLAC__metadata_simple_iterator_new())) return die_("FLAC__metadata_simple_iterator_new()"); - if(!FLAC__metadata_simple_iterator_init(iterator, flacfile_, false)) + if(!FLAC__metadata_simple_iterator_init(iterator, flacfile_, /*read_only=*/false, /*preserve_file_stats=*/false)) return die_("FLAC__metadata_simple_iterator_init() returned false"); printf("is writable = %u\n", (unsigned)FLAC__metadata_simple_iterator_is_writable(iterator)); @@ -544,7 +544,7 @@ static FLAC__bool test_level_1_() if(0 == (iterator = FLAC__metadata_simple_iterator_new())) return die_("FLAC__metadata_simple_iterator_new()"); - if(!FLAC__metadata_simple_iterator_init(iterator, flacfile_, /*preserve_file_stats=*/false)) + if(!FLAC__metadata_simple_iterator_init(iterator, flacfile_, /*read_only=*/false, /*preserve_file_stats=*/false)) return die_("FLAC__metadata_simple_iterator_init() returned false"); our_current_position = 0;