comparison src/flac113/libflac/metadata_iterators.c @ 720:0357863b3631 trunk

[svn] * Link libogg and static libflac * First steps towards using VFS
author js
date Sat, 24 Feb 2007 11:04:38 -0800
parents a9b178bc4ae4
children
comparison
equal deleted inserted replaced
719:be03e09c7c20 720:0357863b3631
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32 #include <audacious/vfs.h>
33
32 #if HAVE_CONFIG_H 34 #if HAVE_CONFIG_H
33 # include <config.h> 35 # include <config.h>
34 #endif 36 #endif
35 37
36 #include <errno.h> 38 #include <errno.h>
44 #else 46 #else
45 #include <sys/utime.h> /* for utime() */ 47 #include <sys/utime.h> /* for utime() */
46 #endif 48 #endif
47 #include <io.h> /* for chmod() */ 49 #include <io.h> /* for chmod() */
48 #include <sys/types.h> /* for off_t */ 50 #include <sys/types.h> /* for off_t */
49 #if _MSC_VER <= 1600 || defined __BORLANDC__ /* @@@ [2G limit] */
50 #define fseeko fseek
51 #define ftello ftell
52 #endif
53 #else 51 #else
54 #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */ 52 #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
55 #include <utime.h> /* for utime() */ 53 #include <utime.h> /* for utime() */
56 #include <unistd.h> /* for chown(), unlink() */ 54 #include <unistd.h> /* for chown(), unlink() */
57 #endif 55 #endif
98 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track); 96 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track);
99 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block); 97 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block);
100 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Picture *block); 98 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Picture *block);
101 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Unknown *block, unsigned block_length); 99 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Unknown *block, unsigned block_length);
102 100
103 static FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block); 101 static FLAC__bool write_metadata_block_header_(VFSFile *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block);
104 static FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block); 102 static FLAC__bool write_metadata_block_data_(VFSFile *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block);
105 static FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block); 103 static FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block);
106 static FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block); 104 static FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block);
107 static FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block); 105 static FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block);
108 static FLAC__bool write_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Padding *block, unsigned block_length); 106 static FLAC__bool write_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Padding *block, unsigned block_length);
109 static FLAC__bool write_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Application *block, unsigned block_length); 107 static FLAC__bool write_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Application *block, unsigned block_length);
119 117
120 static void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator); 118 static void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator);
121 static FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator); 119 static FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator);
122 120
123 static unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb); 121 static unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb);
124 static unsigned seek_to_first_metadata_block_(FILE *f); 122 static unsigned seek_to_first_metadata_block_(VFSFile *f);
125 123
126 static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append); 124 static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, VFSFile **tempfile, char **tempfilename, FLAC__bool append);
127 static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, off_t fixup_is_last_flag_offset, FLAC__bool backup); 125 static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, VFSFile **tempfile, char **tempfilename, int fixup_is_last_code, off_t fixup_is_last_flag_offset, FLAC__bool backup);
128 126
129 static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status); 127 static FLAC__bool copy_n_bytes_from_file_(VFSFile *file, VFSFile *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status);
130 static FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status); 128 static FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status);
131 static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status); 129 static FLAC__bool copy_remaining_bytes_from_file_(VFSFile *file, VFSFile *tempfile, FLAC__Metadata_SimpleIteratorStatus *status);
132 static FLAC__bool copy_remaining_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__Metadata_SimpleIteratorStatus *status); 130 static FLAC__bool copy_remaining_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__Metadata_SimpleIteratorStatus *status);
133 131
134 static FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status); 132 static FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, VFSFile **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status);
135 static FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status); 133 static FLAC__bool transport_tempfile_(const char *filename, VFSFile **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status);
136 static void cleanup_tempfile_(FILE **tempfile, char **tempfilename); 134 static void cleanup_tempfile_(VFSFile **tempfile, char **tempfilename);
137 135
138 static FLAC__bool get_file_stats_(const char *filename, struct stat *stats); 136 static FLAC__bool get_file_stats_(const char *filename, struct stat *stats);
139 static void set_file_stats_(const char *filename, struct stat *stats); 137 static void set_file_stats_(const char *filename, struct stat *stats);
140 138
141 static int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence); 139 static int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence);
143 141
144 static FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status); 142 static FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status);
145 143
146 144
147 #ifdef FLAC__VALGRIND_TESTING 145 #ifdef FLAC__VALGRIND_TESTING
148 static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 146 static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, VFSFile *stream)
149 { 147 {
150 size_t ret = fwrite(ptr, size, nmemb, stream); 148 size_t ret = vfs_fwrite(ptr, size, nmemb, stream);
151 if(!ferror(stream)) 149 if(!ferror(stream))
152 fflush(stream); 150 fflush(stream);
153 return ret; 151 return ret;
154 } 152 }
155 #else 153 #else
156 #define local__fwrite fwrite 154 #define local__fwrite vfs_fwrite
157 #endif 155 #endif
158 156
159 /**************************************************************************** 157 /****************************************************************************
160 * 158 *
161 * Level 0 implementation 159 * Level 0 implementation
340 338
341 #define SIMPLE_ITERATOR_MAX_PUSH_DEPTH (1+4) 339 #define SIMPLE_ITERATOR_MAX_PUSH_DEPTH (1+4)
342 /* 1 for initial offset, +4 for our own personal use */ 340 /* 1 for initial offset, +4 for our own personal use */
343 341
344 struct FLAC__Metadata_SimpleIterator { 342 struct FLAC__Metadata_SimpleIterator {
345 FILE *file; 343 VFSFile *file;
346 char *filename, *tempfile_path_prefix; 344 char *filename, *tempfile_path_prefix;
347 struct stat stats; 345 struct stat stats;
348 FLAC__bool has_stats; 346 FLAC__bool has_stats;
349 FLAC__bool is_writable; 347 FLAC__bool is_writable;
350 FLAC__Metadata_SimpleIteratorStatus status; 348 FLAC__Metadata_SimpleIteratorStatus status;
395 static void simple_iterator_free_guts_(FLAC__Metadata_SimpleIterator *iterator) 393 static void simple_iterator_free_guts_(FLAC__Metadata_SimpleIterator *iterator)
396 { 394 {
397 FLAC__ASSERT(0 != iterator); 395 FLAC__ASSERT(0 != iterator);
398 396
399 if(0 != iterator->file) { 397 if(0 != iterator->file) {
400 fclose(iterator->file); 398 vfs_fclose(iterator->file);
401 iterator->file = 0; 399 iterator->file = 0;
402 if(iterator->has_stats) 400 if(iterator->has_stats)
403 set_file_stats_(iterator->filename, &iterator->stats); 401 set_file_stats_(iterator->filename, &iterator->stats);
404 } 402 }
405 if(0 != iterator->filename) { 403 if(0 != iterator->filename) {
435 { 433 {
436 unsigned ret; 434 unsigned ret;
437 435
438 FLAC__ASSERT(0 != iterator); 436 FLAC__ASSERT(0 != iterator);
439 437
440 if(read_only || 0 == (iterator->file = fopen(iterator->filename, "r+b"))) { 438 if(read_only || 0 == (iterator->file = vfs_fopen(iterator->filename, "r+b"))) {
441 iterator->is_writable = false; 439 iterator->is_writable = false;
442 if(read_only || errno == EACCES) { 440 if(read_only || errno == EACCES) {
443 if(0 == (iterator->file = fopen(iterator->filename, "rb"))) { 441 if(0 == (iterator->file = vfs_fopen(iterator->filename, "rb"))) {
444 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; 442 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;
445 return false; 443 return false;
446 } 444 }
447 } 445 }
448 else { 446 else {
456 454
457 ret = seek_to_first_metadata_block_(iterator->file); 455 ret = seek_to_first_metadata_block_(iterator->file);
458 switch(ret) { 456 switch(ret) {
459 case 0: 457 case 0:
460 iterator->depth = 0; 458 iterator->depth = 0;
461 iterator->first_offset = iterator->offset[iterator->depth] = ftello(iterator->file); 459 iterator->first_offset = iterator->offset[iterator->depth] = vfs_ftell(iterator->file);
462 return read_metadata_block_header_(iterator); 460 return read_metadata_block_header_(iterator);
463 case 1: 461 case 1:
464 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; 462 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
465 return false; 463 return false;
466 case 2: 464 case 2:
531 FLAC__ASSERT(0 != iterator->file); 529 FLAC__ASSERT(0 != iterator->file);
532 530
533 if(iterator->is_last) 531 if(iterator->is_last)
534 return false; 532 return false;
535 533
536 if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) { 534 if(0 != vfs_fseek(iterator->file, iterator->length, SEEK_CUR)) {
537 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 535 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
538 return false; 536 return false;
539 } 537 }
540 538
541 iterator->offset[iterator->depth] = ftello(iterator->file); 539 iterator->offset[iterator->depth] = vfs_ftell(iterator->file);
542 540
543 return read_metadata_block_header_(iterator); 541 return read_metadata_block_header_(iterator);
544 } 542 }
545 543
546 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator) 544 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator)
551 FLAC__ASSERT(0 != iterator->file); 549 FLAC__ASSERT(0 != iterator->file);
552 550
553 if(iterator->offset[iterator->depth] == iterator->first_offset) 551 if(iterator->offset[iterator->depth] == iterator->first_offset)
554 return false; 552 return false;
555 553
556 if(0 != fseeko(iterator->file, iterator->first_offset, SEEK_SET)) { 554 if(0 != vfs_fseek(iterator->file, iterator->first_offset, SEEK_SET)) {
557 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 555 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
558 return false; 556 return false;
559 } 557 }
560 this_offset = iterator->first_offset; 558 this_offset = iterator->first_offset;
561 if(!read_metadata_block_header_(iterator)) 559 if(!read_metadata_block_header_(iterator))
562 return false; 560 return false;
563 561
564 /* we ignore any error from ftello() and catch it in fseeko() */ 562 /* we ignore any error from ftello() and catch it in fseeko() */
565 while(ftello(iterator->file) + (off_t)iterator->length < iterator->offset[iterator->depth]) { 563 while(vfs_ftell(iterator->file) + (off_t)iterator->length < iterator->offset[iterator->depth]) {
566 if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) { 564 if(0 != vfs_fseek(iterator->file, iterator->length, SEEK_CUR)) {
567 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 565 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
568 return false; 566 return false;
569 } 567 }
570 this_offset = ftello(iterator->file); 568 this_offset = vfs_ftell(iterator->file);
571 if(!read_metadata_block_header_(iterator)) 569 if(!read_metadata_block_header_(iterator))
572 return false; 570 return false;
573 } 571 }
574 572
575 iterator->offset[iterator->depth] = this_offset; 573 iterator->offset[iterator->depth] = this_offset;
600 FLAC__metadata_object_delete(block); 598 FLAC__metadata_object_delete(block);
601 return 0; 599 return 0;
602 } 600 }
603 601
604 /* back up to the beginning of the block data to stay consistent */ 602 /* back up to the beginning of the block data to stay consistent */
605 if(0 != fseeko(iterator->file, iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH, SEEK_SET)) { 603 if(0 != vfs_fseek(iterator->file, iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH, SEEK_SET)) {
606 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 604 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
607 FLAC__metadata_object_delete(block); 605 FLAC__metadata_object_delete(block);
608 return 0; 606 return 0;
609 } 607 }
610 } 608 }
641 return write_metadata_block_stationary_(iterator, block); 639 return write_metadata_block_stationary_(iterator, block);
642 else if(iterator->length > block->length) { 640 else if(iterator->length > block->length) {
643 if(use_padding && iterator->length >= FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) { 641 if(use_padding && iterator->length >= FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) {
644 ret = write_metadata_block_stationary_with_padding_(iterator, block, iterator->length - FLAC__STREAM_METADATA_HEADER_LENGTH - block->length, block->is_last); 642 ret = write_metadata_block_stationary_with_padding_(iterator, block, iterator->length - FLAC__STREAM_METADATA_HEADER_LENGTH - block->length, block->is_last);
645 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); 643 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
646 FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); 644 FLAC__ASSERT(!ret || vfs_ftell(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
647 return ret; 645 return ret;
648 } 646 }
649 else { 647 else {
650 ret = rewrite_whole_file_(iterator, block, /*append=*/false); 648 ret = rewrite_whole_file_(iterator, block, /*append=*/false);
651 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); 649 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
652 FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); 650 FLAC__ASSERT(!ret || vfs_ftell(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
653 return ret; 651 return ret;
654 } 652 }
655 } 653 }
656 else /* iterator->length < block->length */ { 654 else /* iterator->length < block->length */ {
657 unsigned padding_leftover = 0; 655 unsigned padding_leftover = 0;
690 } 688 }
691 if(use_padding) { 689 if(use_padding) {
692 if(padding_leftover == 0) { 690 if(padding_leftover == 0) {
693 ret = write_metadata_block_stationary_(iterator, block); 691 ret = write_metadata_block_stationary_(iterator, block);
694 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); 692 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
695 FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); 693 FLAC__ASSERT(!ret || vfs_ftell(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
696 return ret; 694 return ret;
697 } 695 }
698 else { 696 else {
699 FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH); 697 FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH);
700 ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last); 698 ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last);
701 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); 699 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
702 FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); 700 FLAC__ASSERT(!ret || vfs_ftell(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
703 return ret; 701 return ret;
704 } 702 }
705 } 703 }
706 else { 704 else {
707 ret = rewrite_whole_file_(iterator, block, /*append=*/false); 705 ret = rewrite_whole_file_(iterator, block, /*append=*/false);
708 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); 706 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
709 FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); 707 FLAC__ASSERT(!ret || vfs_ftell(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
710 return ret; 708 return ret;
711 } 709 }
712 } 710 }
713 } 711 }
714 712
770 if(!FLAC__metadata_simple_iterator_next(iterator)) 768 if(!FLAC__metadata_simple_iterator_next(iterator))
771 return false; 769 return false;
772 if(padding_leftover == 0) { 770 if(padding_leftover == 0) {
773 ret = write_metadata_block_stationary_(iterator, block); 771 ret = write_metadata_block_stationary_(iterator, block);
774 FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); 772 FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
775 FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); 773 FLAC__ASSERT(vfs_ftell(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
776 return ret; 774 return ret;
777 } 775 }
778 else { 776 else {
779 FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH); 777 FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH);
780 ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last); 778 ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last);
781 FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); 779 FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
782 FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); 780 FLAC__ASSERT(vfs_ftell(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
783 return ret; 781 return ret;
784 } 782 }
785 } 783 }
786 else { 784 else {
787 ret = rewrite_whole_file_(iterator, block, /*append=*/true); 785 ret = rewrite_whole_file_(iterator, block, /*append=*/true);
788 FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); 786 FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
789 FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); 787 FLAC__ASSERT(vfs_ftell(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
790 return ret; 788 return ret;
791 } 789 }
792 } 790 }
793 791
794 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding) 792 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding)
814 } 812 }
815 FLAC__metadata_object_delete(padding); 813 FLAC__metadata_object_delete(padding);
816 if(!FLAC__metadata_simple_iterator_prev(iterator)) 814 if(!FLAC__metadata_simple_iterator_prev(iterator))
817 return false; 815 return false;
818 FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset); 816 FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset);
819 FLAC__ASSERT(ftello(iterator->file) + (off_t)iterator->length == debug_target_offset); 817 FLAC__ASSERT(vfs_ftell(iterator->file) + (off_t)iterator->length == debug_target_offset);
820 return true; 818 return true;
821 } 819 }
822 else { 820 else {
823 ret = rewrite_whole_file_(iterator, 0, /*append=*/false); 821 ret = rewrite_whole_file_(iterator, 0, /*append=*/false);
824 FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset); 822 FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset);
825 FLAC__ASSERT(ftello(iterator->file) + (off_t)iterator->length == debug_target_offset); 823 FLAC__ASSERT(vfs_ftell(iterator->file) + (off_t)iterator->length == debug_target_offset);
826 return ret; 824 return ret;
827 } 825 }
828 } 826 }
829 827
830 828
1317 return true; 1315 return true;
1318 } 1316 }
1319 1317
1320 static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain) 1318 static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain)
1321 { 1319 {
1322 FILE *file; 1320 VFSFile *file;
1323 FLAC__bool ret; 1321 FLAC__bool ret;
1324 1322
1325 FLAC__ASSERT(0 != chain->filename); 1323 FLAC__ASSERT(0 != chain->filename);
1326 1324
1327 if(0 == (file = fopen(chain->filename, "r+b"))) { 1325 if(0 == (file = vfs_fopen(chain->filename, "r+b"))) {
1328 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; 1326 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
1329 return false; 1327 return false;
1330 } 1328 }
1331 1329
1332 /* chain_rewrite_metadata_in_place_cb_() sets chain->status for us */ 1330 /* chain_rewrite_metadata_in_place_cb_() sets chain->status for us */
1333 ret = chain_rewrite_metadata_in_place_cb_(chain, (FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, fseek_wrapper_); 1331 ret = chain_rewrite_metadata_in_place_cb_(chain, (FLAC__IOHandle)file, (FLAC__IOCallback_Write)vfs_fwrite, fseek_wrapper_);
1334 1332
1335 fclose(file); 1333 vfs_fclose(file);
1336 1334
1337 return ret; 1335 return ret;
1338 } 1336 }
1339 1337
1340 static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix) 1338 static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix)
1341 { 1339 {
1342 FILE *f, *tempfile; 1340 VFSFile *f, *tempfile;
1343 char *tempfilename; 1341 char *tempfilename;
1344 FLAC__Metadata_SimpleIteratorStatus status; 1342 FLAC__Metadata_SimpleIteratorStatus status;
1345 const FLAC__Metadata_Node *node; 1343 const FLAC__Metadata_Node *node;
1346 1344
1347 FLAC__ASSERT(0 != chain); 1345 FLAC__ASSERT(0 != chain);
1348 FLAC__ASSERT(0 != chain->filename); 1346 FLAC__ASSERT(0 != chain->filename);
1349 FLAC__ASSERT(0 != chain->head); 1347 FLAC__ASSERT(0 != chain->head);
1350 1348
1351 /* copy the file prefix (data up to first metadata block */ 1349 /* copy the file prefix (data up to first metadata block */
1352 if(0 == (f = fopen(chain->filename, "rb"))) { 1350 if(0 == (f = vfs_fopen(chain->filename, "rb"))) {
1353 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; 1351 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
1354 return false; 1352 return false;
1355 } 1353 }
1356 if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) { 1354 if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) {
1357 chain->status = get_equivalent_status_(status); 1355 chain->status = get_equivalent_status_(status);
1376 } 1374 }
1377 } 1375 }
1378 /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/ 1376 /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/
1379 1377
1380 /* copy the file postfix (everything after the metadata) */ 1378 /* copy the file postfix (everything after the metadata) */
1381 if(0 != fseeko(f, chain->last_offset, SEEK_SET)) { 1379 if(0 != vfs_fseek(f, chain->last_offset, SEEK_SET)) {
1382 cleanup_tempfile_(&tempfile, &tempfilename); 1380 cleanup_tempfile_(&tempfile, &tempfilename);
1383 chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; 1381 chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
1384 return false; 1382 return false;
1385 } 1383 }
1386 if(!copy_remaining_bytes_from_file_(f, tempfile, &status)) { 1384 if(!copy_remaining_bytes_from_file_(f, tempfile, &status)) {
1388 chain->status = get_equivalent_status_(status); 1386 chain->status = get_equivalent_status_(status);
1389 return false; 1387 return false;
1390 } 1388 }
1391 1389
1392 /* move the tempfile on top of the original */ 1390 /* move the tempfile on top of the original */
1393 (void)fclose(f); 1391 (void)vfs_fclose(f);
1394 if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status)) 1392 if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status))
1395 return false; 1393 return false;
1396 1394
1397 return true; 1395 return true;
1398 } 1396 }
1469 return status; 1467 return status;
1470 } 1468 }
1471 1469
1472 static FLAC__bool chain_read_(FLAC__Metadata_Chain *chain, const char *filename, FLAC__bool is_ogg) 1470 static FLAC__bool chain_read_(FLAC__Metadata_Chain *chain, const char *filename, FLAC__bool is_ogg)
1473 { 1471 {
1474 FILE *file; 1472 VFSFile *file;
1475 FLAC__bool ret; 1473 FLAC__bool ret;
1476 1474
1477 FLAC__ASSERT(0 != chain); 1475 FLAC__ASSERT(0 != chain);
1478 FLAC__ASSERT(0 != filename); 1476 FLAC__ASSERT(0 != filename);
1479 1477
1484 return false; 1482 return false;
1485 } 1483 }
1486 1484
1487 chain->is_ogg = is_ogg; 1485 chain->is_ogg = is_ogg;
1488 1486
1489 if(0 == (file = fopen(filename, "rb"))) { 1487 if(0 == (file = vfs_fopen(filename, "rb"))) {
1490 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; 1488 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
1491 return false; 1489 return false;
1492 } 1490 }
1493 1491
1494 /* the function also sets chain->status for us */ 1492 /* the function also sets chain->status for us */
1495 ret = is_ogg? 1493 ret = is_ogg?
1496 chain_read_ogg_cb_(chain, file, (FLAC__IOCallback_Read)fread) : 1494 chain_read_ogg_cb_(chain, file, (FLAC__IOCallback_Read)vfs_fread) :
1497 chain_read_cb_(chain, file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, ftell_wrapper_) 1495 chain_read_cb_(chain, file, (FLAC__IOCallback_Read)vfs_fread, fseek_wrapper_, ftell_wrapper_)
1498 ; 1496 ;
1499 1497
1500 fclose(file); 1498 vfs_fclose(file);
1501 1499
1502 return ret; 1500 return ret;
1503 } 1501 }
1504 1502
1505 FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename) 1503 FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename)
1997 FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator) 1995 FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator)
1998 { 1996 {
1999 FLAC__ASSERT(0 != iterator); 1997 FLAC__ASSERT(0 != iterator);
2000 FLAC__ASSERT(0 != iterator->file); 1998 FLAC__ASSERT(0 != iterator->file);
2001 1999
2002 if(!read_metadata_block_header_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, &iterator->is_last, &iterator->type, &iterator->length)) { 2000 if(!read_metadata_block_header_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)vfs_fread, &iterator->is_last, &iterator->type, &iterator->length)) {
2003 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; 2001 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2004 return false; 2002 return false;
2005 } 2003 }
2006 2004
2007 return true; 2005 return true;
2010 FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block) 2008 FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block)
2011 { 2009 {
2012 FLAC__ASSERT(0 != iterator); 2010 FLAC__ASSERT(0 != iterator);
2013 FLAC__ASSERT(0 != iterator->file); 2011 FLAC__ASSERT(0 != iterator->file);
2014 2012
2015 iterator->status = read_metadata_block_data_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, block); 2013 iterator->status = read_metadata_block_data_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)vfs_fread, fseek_wrapper_, block);
2016 2014
2017 return (iterator->status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK); 2015 return (iterator->status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK);
2018 } 2016 }
2019 2017
2020 FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length) 2018 FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length)
2418 } 2416 }
2419 2417
2420 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; 2418 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
2421 } 2419 }
2422 2420
2423 FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block) 2421 FLAC__bool write_metadata_block_header_(VFSFile *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block)
2424 { 2422 {
2425 FLAC__ASSERT(0 != file); 2423 FLAC__ASSERT(0 != file);
2426 FLAC__ASSERT(0 != status); 2424 FLAC__ASSERT(0 != status);
2427 2425
2428 if(!write_metadata_block_header_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) { 2426 if(!write_metadata_block_header_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)vfs_fwrite, block)) {
2429 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; 2427 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2430 return false; 2428 return false;
2431 } 2429 }
2432 2430
2433 return true; 2431 return true;
2434 } 2432 }
2435 2433
2436 FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block) 2434 FLAC__bool write_metadata_block_data_(VFSFile *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block)
2437 { 2435 {
2438 FLAC__ASSERT(0 != file); 2436 FLAC__ASSERT(0 != file);
2439 FLAC__ASSERT(0 != status); 2437 FLAC__ASSERT(0 != status);
2440 2438
2441 if (write_metadata_block_data_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) { 2439 if (write_metadata_block_data_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)vfs_fwrite, block)) {
2442 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; 2440 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
2443 return true; 2441 return true;
2444 } 2442 }
2445 else { 2443 else {
2446 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; 2444 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2773 return true; 2771 return true;
2774 } 2772 }
2775 2773
2776 FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block) 2774 FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block)
2777 { 2775 {
2778 if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { 2776 if(0 != vfs_fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2779 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 2777 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2780 return false; 2778 return false;
2781 } 2779 }
2782 2780
2783 if(!write_metadata_block_header_(iterator->file, &iterator->status, block)) 2781 if(!write_metadata_block_header_(iterator->file, &iterator->status, block))
2784 return false; 2782 return false;
2785 2783
2786 if(!write_metadata_block_data_(iterator->file, &iterator->status, block)) 2784 if(!write_metadata_block_data_(iterator->file, &iterator->status, block))
2787 return false; 2785 return false;
2788 2786
2789 if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { 2787 if(0 != vfs_fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2790 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 2788 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2791 return false; 2789 return false;
2792 } 2790 }
2793 2791
2794 return read_metadata_block_header_(iterator); 2792 return read_metadata_block_header_(iterator);
2796 2794
2797 FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last) 2795 FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last)
2798 { 2796 {
2799 FLAC__StreamMetadata *padding; 2797 FLAC__StreamMetadata *padding;
2800 2798
2801 if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { 2799 if(0 != vfs_fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2802 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 2800 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2803 return false; 2801 return false;
2804 } 2802 }
2805 2803
2806 block->is_last = false; 2804 block->is_last = false;
2827 return false; 2825 return false;
2828 } 2826 }
2829 2827
2830 FLAC__metadata_object_delete(padding); 2828 FLAC__metadata_object_delete(padding);
2831 2829
2832 if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { 2830 if(0 != vfs_fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2833 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 2831 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2834 return false; 2832 return false;
2835 } 2833 }
2836 2834
2837 return read_metadata_block_header_(iterator); 2835 return read_metadata_block_header_(iterator);
2838 } 2836 }
2839 2837
2840 FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append) 2838 FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append)
2841 { 2839 {
2842 FILE *tempfile; 2840 VFSFile *tempfile;
2843 char *tempfilename; 2841 char *tempfilename;
2844 int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */ 2842 int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */
2845 off_t fixup_is_last_flag_offset = -1; 2843 off_t fixup_is_last_flag_offset = -1;
2846 2844
2847 FLAC__ASSERT(0 != block || append == false); 2845 FLAC__ASSERT(0 != block || append == false);
2897 2895
2898 FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator) 2896 FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator)
2899 { 2897 {
2900 FLAC__ASSERT(iterator->depth > 0); 2898 FLAC__ASSERT(iterator->depth > 0);
2901 iterator->depth--; 2899 iterator->depth--;
2902 if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { 2900 if(0 != vfs_fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2903 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 2901 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2904 return false; 2902 return false;
2905 } 2903 }
2906 2904
2907 return read_metadata_block_header_(iterator); 2905 return read_metadata_block_header_(iterator);
2961 return 0; 2959 return 0;
2962 else 2960 else
2963 return 3; 2961 return 3;
2964 } 2962 }
2965 2963
2966 unsigned seek_to_first_metadata_block_(FILE *f) 2964 unsigned seek_to_first_metadata_block_(VFSFile *f)
2967 { 2965 {
2968 return seek_to_first_metadata_block_cb_((FLAC__IOHandle)f, (FLAC__IOCallback_Read)fread, fseek_wrapper_); 2966 return seek_to_first_metadata_block_cb_((FLAC__IOHandle)f, (FLAC__IOCallback_Read)vfs_fread, fseek_wrapper_);
2969 } 2967 }
2970 2968
2971 FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append) 2969 FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, VFSFile **tempfile, char **tempfilename, FLAC__bool append)
2972 { 2970 {
2973 const off_t offset_end = append? iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length : iterator->offset[iterator->depth]; 2971 const off_t offset_end = append? iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length : iterator->offset[iterator->depth];
2974 2972
2975 if(0 != fseeko(iterator->file, 0, SEEK_SET)) { 2973 if(0 != vfs_fseek(iterator->file, 0, SEEK_SET)) {
2976 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 2974 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2977 return false; 2975 return false;
2978 } 2976 }
2979 if(!open_tempfile_(iterator->filename, iterator->tempfile_path_prefix, tempfile, tempfilename, &iterator->status)) { 2977 if(!open_tempfile_(iterator->filename, iterator->tempfile_path_prefix, tempfile, tempfilename, &iterator->status)) {
2980 cleanup_tempfile_(tempfile, tempfilename); 2978 cleanup_tempfile_(tempfile, tempfilename);
2986 } 2984 }
2987 2985
2988 return true; 2986 return true;
2989 } 2987 }
2990 2988
2991 FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, off_t fixup_is_last_flag_offset, FLAC__bool backup) 2989 FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, VFSFile **tempfile, char **tempfilename, int fixup_is_last_code, off_t fixup_is_last_flag_offset, FLAC__bool backup)
2992 { 2990 {
2993 off_t save_offset = iterator->offset[iterator->depth]; 2991 off_t save_offset = iterator->offset[iterator->depth];
2994 FLAC__ASSERT(0 != *tempfile); 2992 FLAC__ASSERT(0 != *tempfile);
2995 2993
2996 if(0 != fseeko(iterator->file, save_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length, SEEK_SET)) { 2994 if(0 != vfs_fseek(iterator->file, save_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length, SEEK_SET)) {
2997 cleanup_tempfile_(tempfile, tempfilename); 2995 cleanup_tempfile_(tempfile, tempfilename);
2998 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 2996 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2999 return false; 2997 return false;
3000 } 2998 }
3001 if(!copy_remaining_bytes_from_file_(iterator->file, *tempfile, &iterator->status)) { 2999 if(!copy_remaining_bytes_from_file_(iterator->file, *tempfile, &iterator->status)) {
3010 * if code == -1, it means the last block was deleted so 3008 * if code == -1, it means the last block was deleted so
3011 * we have to set the is_last flag of the previous block 3009 * we have to set the is_last flag of the previous block
3012 */ 3010 */
3013 /* MAGIC NUMBERs here; we know the is_last flag is the high bit of the byte at this location */ 3011 /* MAGIC NUMBERs here; we know the is_last flag is the high bit of the byte at this location */
3014 FLAC__byte x; 3012 FLAC__byte x;
3015 if(0 != fseeko(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) { 3013 if(0 != vfs_fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
3016 cleanup_tempfile_(tempfile, tempfilename); 3014 cleanup_tempfile_(tempfile, tempfilename);
3017 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 3015 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
3018 return false; 3016 return false;
3019 } 3017 }
3020 if(fread(&x, 1, 1, *tempfile) != 1) { 3018 if(vfs_fread(&x, 1, 1, *tempfile) != 1) {
3021 cleanup_tempfile_(tempfile, tempfilename); 3019 cleanup_tempfile_(tempfile, tempfilename);
3022 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; 3020 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
3023 return false; 3021 return false;
3024 } 3022 }
3025 if(fixup_is_last_code > 0) { 3023 if(fixup_is_last_code > 0) {
3028 } 3026 }
3029 else { 3027 else {
3030 FLAC__ASSERT(!(x & 0x80)); 3028 FLAC__ASSERT(!(x & 0x80));
3031 x |= 0x80; 3029 x |= 0x80;
3032 } 3030 }
3033 if(0 != fseeko(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) { 3031 if(0 != vfs_fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
3034 cleanup_tempfile_(tempfile, tempfilename); 3032 cleanup_tempfile_(tempfile, tempfilename);
3035 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; 3033 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
3036 return false; 3034 return false;
3037 } 3035 }
3038 if(local__fwrite(&x, 1, 1, *tempfile) != 1) { 3036 if(local__fwrite(&x, 1, 1, *tempfile) != 1) {
3040 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; 3038 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
3041 return false; 3039 return false;
3042 } 3040 }
3043 } 3041 }
3044 3042
3045 (void)fclose(iterator->file); 3043 (void)vfs_fclose(iterator->file);
3046 3044
3047 if(!transport_tempfile_(iterator->filename, tempfile, tempfilename, &iterator->status)) 3045 if(!transport_tempfile_(iterator->filename, tempfile, tempfilename, &iterator->status))
3048 return false; 3046 return false;
3049 3047
3050 if(iterator->has_stats) 3048 if(iterator->has_stats)
3065 iterator->depth++; 3063 iterator->depth++;
3066 return simple_iterator_pop_(iterator); 3064 return simple_iterator_pop_(iterator);
3067 } 3065 }
3068 } 3066 }
3069 3067
3070 FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status) 3068 FLAC__bool copy_n_bytes_from_file_(VFSFile *file, VFSFile *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status)
3071 { 3069 {
3072 FLAC__byte buffer[8192]; 3070 FLAC__byte buffer[8192];
3073 size_t n; 3071 size_t n;
3074 3072
3075 FLAC__ASSERT(bytes >= 0); 3073 FLAC__ASSERT(bytes >= 0);
3076 while(bytes > 0) { 3074 while(bytes > 0) {
3077 n = min(sizeof(buffer), (size_t)bytes); 3075 n = min(sizeof(buffer), (size_t)bytes);
3078 if(fread(buffer, 1, n, file) != n) { 3076 if(vfs_fread(buffer, 1, n, file) != n) {
3079 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; 3077 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
3080 return false; 3078 return false;
3081 } 3079 }
3082 if(local__fwrite(buffer, 1, n, tempfile) != n) { 3080 if(local__fwrite(buffer, 1, n, tempfile) != n) {
3083 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; 3081 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
3109 } 3107 }
3110 3108
3111 return true; 3109 return true;
3112 } 3110 }
3113 3111
3114 FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status) 3112 FLAC__bool copy_remaining_bytes_from_file_(VFSFile *file, VFSFile *tempfile, FLAC__Metadata_SimpleIteratorStatus *status)
3115 { 3113 {
3116 FLAC__byte buffer[8192]; 3114 FLAC__byte buffer[8192];
3117 size_t n; 3115 size_t n;
3118 3116
3119 while(!feof(file)) { 3117 while(!vfs_feof(file)) {
3120 n = fread(buffer, 1, sizeof(buffer), file); 3118 n = vfs_fread(buffer, 1, sizeof(buffer), file);
3121 if(n == 0 && !feof(file)) { 3119 if(n == 0 && !vfs_feof(file)) {
3122 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; 3120 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
3123 return false; 3121 return false;
3124 } 3122 }
3125 if(n > 0 && local__fwrite(buffer, 1, n, tempfile) != n) { 3123 if(n > 0 && local__fwrite(buffer, 1, n, tempfile) != n) {
3126 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; 3124 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
3149 } 3147 }
3150 3148
3151 return true; 3149 return true;
3152 } 3150 }
3153 3151
3154 FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status) 3152 FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, VFSFile **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status)
3155 { 3153 {
3156 static const char *tempfile_suffix = ".metadata_edit"; 3154 static const char *tempfile_suffix = ".metadata_edit";
3157 if(0 == tempfile_path_prefix) { 3155 if(0 == tempfile_path_prefix) {
3158 if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) { 3156 if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) {
3159 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; 3157 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
3177 strcat(*tempfilename, "/"); 3175 strcat(*tempfilename, "/");
3178 strcat(*tempfilename, p); 3176 strcat(*tempfilename, p);
3179 strcat(*tempfilename, tempfile_suffix); 3177 strcat(*tempfilename, tempfile_suffix);
3180 } 3178 }
3181 3179
3182 if(0 == (*tempfile = fopen(*tempfilename, "w+b"))) { 3180 if(0 == (*tempfile = vfs_fopen(*tempfilename, "w+b"))) {
3183 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; 3181 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;
3184 return false; 3182 return false;
3185 } 3183 }
3186 3184
3187 return true; 3185 return true;
3188 } 3186 }
3189 3187
3190 FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status) 3188 FLAC__bool transport_tempfile_(const char *filename, VFSFile **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status)
3191 { 3189 {
3192 FLAC__ASSERT(0 != filename); 3190 FLAC__ASSERT(0 != filename);
3193 FLAC__ASSERT(0 != tempfile); 3191 FLAC__ASSERT(0 != tempfile);
3194 FLAC__ASSERT(0 != *tempfile); 3192 FLAC__ASSERT(0 != *tempfile);
3195 FLAC__ASSERT(0 != tempfilename); 3193 FLAC__ASSERT(0 != tempfilename);
3196 FLAC__ASSERT(0 != *tempfilename); 3194 FLAC__ASSERT(0 != *tempfilename);
3197 FLAC__ASSERT(0 != status); 3195 FLAC__ASSERT(0 != status);
3198 3196
3199 (void)fclose(*tempfile); 3197 (void)vfs_fclose(*tempfile);
3200 *tempfile = 0; 3198 *tempfile = 0;
3201 3199
3202 #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ || defined __EMX__ 3200 #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ || defined __EMX__
3203 /* on some flavors of windows, rename() will fail if the destination already exists */ 3201 /* on some flavors of windows, rename() will fail if the destination already exists */
3204 if(unlink(filename) < 0) { 3202 if(unlink(filename) < 0) {
3218 cleanup_tempfile_(tempfile, tempfilename); 3216 cleanup_tempfile_(tempfile, tempfilename);
3219 3217
3220 return true; 3218 return true;
3221 } 3219 }
3222 3220
3223 void cleanup_tempfile_(FILE **tempfile, char **tempfilename) 3221 void cleanup_tempfile_(VFSFile **tempfile, char **tempfilename)
3224 { 3222 {
3225 if(0 != *tempfile) { 3223 if(0 != *tempfile) {
3226 (void)fclose(*tempfile); 3224 (void)vfs_fclose(*tempfile);
3227 *tempfile = 0; 3225 *tempfile = 0;
3228 } 3226 }
3229 3227
3230 if(0 != *tempfilename) { 3228 if(0 != *tempfilename) {
3231 (void)unlink(*tempfilename); 3229 (void)unlink(*tempfilename);
3258 #endif 3256 #endif
3259 } 3257 }
3260 3258
3261 int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence) 3259 int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence)
3262 { 3260 {
3263 return fseeko((FILE*)handle, (off_t)offset, whence); 3261 return vfs_fseek((VFSFile*)handle, (off_t)offset, whence);
3264 } 3262 }
3265 3263
3266 FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle) 3264 FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle)
3267 { 3265 {
3268 return ftello((FILE*)handle); 3266 return vfs_ftell((VFSFile*)handle);
3269 } 3267 }
3270 3268
3271 FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status) 3269 FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status)
3272 { 3270 {
3273 switch(status) { 3271 switch(status) {