complete largefile support
[platform/upstream/flac.git] / src / libFLAC / metadata_iterators.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2001,2002,2003,2004,2005,2006  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
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.
30  */
31
32 #if HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35
36 #include <errno.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #if defined _MSC_VER || defined __MINGW32__
42 #include <sys/utime.h> /* for utime() */
43 #include <io.h> /* for chmod() */
44 #include <sys/types.h> /* for off_t */
45 //@@@ [2G limit] hacks for MSVC6
46 #define fseeko fseek
47 #define ftello ftell
48 #else
49 #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
50 #include <utime.h> /* for utime() */
51 #include <unistd.h> /* for chown(), unlink() */
52 #endif
53 #include <sys/stat.h> /* for stat(), maybe chmod() */
54
55 #include "private/metadata.h"
56
57 #include "FLAC/assert.h"
58 #include "FLAC/file_decoder.h"
59
60 #ifdef max
61 #undef max
62 #endif
63 #define max(a,b) ((a)>(b)?(a):(b))
64 #ifdef min
65 #undef min
66 #endif
67 #define min(a,b) ((a)<(b)?(a):(b))
68
69
70 /****************************************************************************
71  *
72  * Local function declarations
73  *
74  ***************************************************************************/
75
76 static void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes);
77 static void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes);
78 static void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes);
79 static FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes);
80 static FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes);
81 static FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes);
82
83 static FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator);
84 static FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block);
85 static FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length);
86 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata *block);
87 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block);
88 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_Padding *block, unsigned block_length);
89 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Application *block, unsigned block_length);
90 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_SeekTable *block, unsigned block_length);
91 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entry_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment_Entry *entry);
92 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment *block);
93 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track);
94 static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block);
95 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);
96
97 static FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block);
98 static FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block);
99 static FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block);
100 static FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block);
101 static FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block);
102 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);
103 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);
104 static FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block);
105 static FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block);
106 static FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block);
107 static FLAC__bool write_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Unknown *block, unsigned block_length);
108
109 static FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block);
110 static FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last);
111 static FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append);
112
113 static void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator);
114 static FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator);
115
116 static unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb);
117 static unsigned seek_to_first_metadata_block_(FILE *f);
118
119 static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append);
120 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);
121
122 static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status);
123 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);
124 static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status);
125 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);
126
127 static FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status);
128 static FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status);
129 static void cleanup_tempfile_(FILE **tempfile, char **tempfilename);
130
131 static FLAC__bool get_file_stats_(const char *filename, struct stat *stats);
132 static void set_file_stats_(const char *filename, struct stat *stats);
133
134 static int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence);
135 static FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle);
136
137 static FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status);
138
139
140 #ifdef FLAC__VALGRIND_TESTING
141 static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
142 {
143         size_t ret = fwrite(ptr, size, nmemb, stream);
144         if(!ferror(stream))
145                 fflush(stream);
146         return ret;
147 }
148 #else
149 #define local__fwrite fwrite
150 #endif
151
152 /****************************************************************************
153  *
154  * Level 0 implementation
155  *
156  ***************************************************************************/
157
158 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
159 static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
160 static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
161
162 typedef struct {
163         FLAC__bool got_error;
164         FLAC__StreamMetadata *object;
165 } level0_client_data;
166
167 static FLAC__StreamMetadata *get_one_metadata_block_(const char *filename, FLAC__MetadataType type)
168 {
169         level0_client_data cd;
170         FLAC__FileDecoder *decoder;
171
172         FLAC__ASSERT(0 != filename);
173
174         cd.got_error = false;
175         cd.object = 0;
176
177         decoder = FLAC__file_decoder_new();
178
179         if(0 == decoder)
180                 return 0;
181
182         FLAC__file_decoder_set_md5_checking(decoder, false);
183         FLAC__file_decoder_set_filename(decoder, filename);
184         FLAC__file_decoder_set_metadata_ignore_all(decoder);
185         FLAC__file_decoder_set_metadata_respond(decoder, type);
186         FLAC__file_decoder_set_write_callback(decoder, write_callback_);
187         FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_);
188         FLAC__file_decoder_set_error_callback(decoder, error_callback_);
189         FLAC__file_decoder_set_client_data(decoder, &cd);
190
191         if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK || cd.got_error) {
192                 FLAC__file_decoder_finish(decoder);
193                 FLAC__file_decoder_delete(decoder);
194                 return 0;
195         }
196
197         if(!FLAC__file_decoder_process_until_end_of_metadata(decoder) || cd.got_error) {
198                 FLAC__file_decoder_finish(decoder);
199                 FLAC__file_decoder_delete(decoder);
200                 if(0 != cd.object)
201                         FLAC__metadata_object_delete(cd.object);
202                 return 0;
203         }
204
205         FLAC__file_decoder_finish(decoder);
206         FLAC__file_decoder_delete(decoder);
207
208         return cd.object;
209 }
210
211 FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo)
212 {
213         FLAC__StreamMetadata *object;
214
215         FLAC__ASSERT(0 != filename);
216         FLAC__ASSERT(0 != streaminfo);
217
218         object = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_STREAMINFO);
219
220         if (object) {
221                 /* can just copy the contents since STREAMINFO has no internal structure */
222                 *streaminfo = *object;
223                 FLAC__metadata_object_delete(object);
224                 return true;
225         }
226         else {
227                 return false;
228         }
229 }
230
231 FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags)
232 {
233         FLAC__ASSERT(0 != filename);
234         FLAC__ASSERT(0 != tags);
235
236         *tags = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_VORBIS_COMMENT);
237
238         return 0 != *tags;
239 }
240
241 FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet)
242 {
243         FLAC__ASSERT(0 != filename);
244         FLAC__ASSERT(0 != cuesheet);
245
246         *cuesheet = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_CUESHEET);
247
248         return 0 != *cuesheet;
249 }
250
251 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
252 {
253         (void)decoder, (void)frame, (void)buffer, (void)client_data;
254
255         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
256 }
257
258 void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
259 {
260         level0_client_data *cd = (level0_client_data *)client_data;
261         (void)decoder;
262
263         /*
264          * we assume we only get here when the one metadata block we were
265          * looking for was passed to us
266          */
267         if(!cd->got_error && 0 == cd->object) {
268                 if(0 == (cd->object = FLAC__metadata_object_clone(metadata)))
269                         cd->got_error = true;
270         }
271 }
272
273 void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
274 {
275         level0_client_data *cd = (level0_client_data *)client_data;
276         (void)decoder;
277
278         if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
279                 cd->got_error = true;
280 }
281
282
283 /****************************************************************************
284  *
285  * Level 1 implementation
286  *
287  ***************************************************************************/
288
289 #define SIMPLE_ITERATOR_MAX_PUSH_DEPTH (1+4)
290 /* 1 for initial offset, +4 for our own personal use */
291
292 struct FLAC__Metadata_SimpleIterator {
293         FILE *file;
294         char *filename, *tempfile_path_prefix;
295         struct stat stats;
296         FLAC__bool has_stats;
297         FLAC__bool is_writable;
298         FLAC__Metadata_SimpleIteratorStatus status;
299         off_t offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH];
300         off_t first_offset; /* this is the offset to the STREAMINFO block */
301         unsigned depth;
302         /* this is the metadata block header of the current block we are pointing to: */
303         FLAC__bool is_last;
304         FLAC__MetadataType type;
305         unsigned length;
306 };
307
308 FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[] = {
309         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK",
310         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT",
311         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE",
312         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE",
313         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE",
314         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA",
315         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR",
316         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR",
317         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR",
318         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR",
319         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR",
320         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR",
321         "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR"
322 };
323
324
325 FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new()
326 {
327         FLAC__Metadata_SimpleIterator *iterator = (FLAC__Metadata_SimpleIterator*)calloc(1, sizeof(FLAC__Metadata_SimpleIterator));
328
329         if(0 != iterator) {
330                 iterator->file = 0;
331                 iterator->filename = 0;
332                 iterator->tempfile_path_prefix = 0;
333                 iterator->has_stats = false;
334                 iterator->is_writable = false;
335                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
336                 iterator->first_offset = iterator->offset[0] = -1;
337                 iterator->depth = 0;
338         }
339
340         return iterator;
341 }
342
343 static void simple_iterator_free_guts_(FLAC__Metadata_SimpleIterator *iterator)
344 {
345         FLAC__ASSERT(0 != iterator);
346
347         if(0 != iterator->file) {
348                 fclose(iterator->file);
349                 iterator->file = 0;
350                 if(iterator->has_stats)
351                         set_file_stats_(iterator->filename, &iterator->stats);
352         }
353         if(0 != iterator->filename) {
354                 free(iterator->filename);
355                 iterator->filename = 0;
356         }
357         if(0 != iterator->tempfile_path_prefix) {
358                 free(iterator->tempfile_path_prefix);
359                 iterator->tempfile_path_prefix = 0;
360         }
361 }
362
363 FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator)
364 {
365         FLAC__ASSERT(0 != iterator);
366
367         simple_iterator_free_guts_(iterator);
368         free(iterator);
369 }
370
371 FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator)
372 {
373         FLAC__Metadata_SimpleIteratorStatus status;
374
375         FLAC__ASSERT(0 != iterator);
376
377         status = iterator->status;
378         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
379         return status;
380 }
381
382 static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool read_only)
383 {
384         unsigned ret;
385
386         FLAC__ASSERT(0 != iterator);
387
388         if(read_only || 0 == (iterator->file = fopen(iterator->filename, "r+b"))) {
389                 iterator->is_writable = false;
390                 if(read_only || errno == EACCES) {
391                         if(0 == (iterator->file = fopen(iterator->filename, "rb"))) {
392                                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;
393                                 return false;
394                         }
395                 }
396                 else {
397                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;
398                         return false;
399                 }
400         }
401         else {
402                 iterator->is_writable = true;
403         }
404
405         ret = seek_to_first_metadata_block_(iterator->file);
406         switch(ret) {
407                 case 0:
408                         iterator->depth = 0;
409                         iterator->first_offset = iterator->offset[iterator->depth] = ftello(iterator->file);
410                         return read_metadata_block_header_(iterator);
411                 case 1:
412                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
413                         return false;
414                 case 2:
415                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
416                         return false;
417                 case 3:
418                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE;
419                         return false;
420                 default:
421                         FLAC__ASSERT(0);
422                         return false;
423         }
424 }
425
426 #if 0
427 @@@ If we decide to finish implementing this, put this comment back in metadata.h
428 /*
429  * The 'tempfile_path_prefix' allows you to specify a directory where
430  * tempfiles should go.  Remember that if your metadata edits cause the
431  * FLAC file to grow, the entire file will have to be rewritten.  If
432  * 'tempfile_path_prefix' is NULL, the temp file will be written in the
433  * same directory as the original FLAC file.  This makes replacing the
434  * original with the tempfile fast but requires extra space in the same
435  * partition for the tempfile.  If space is a problem, you can pass a
436  * directory name belonging to a different partition in
437  * 'tempfile_path_prefix'.  Note that you should use the forward slash
438  * '/' as the directory separator.  A trailing slash is not needed; it
439  * will be added automatically.
440  */
441 FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool preserve_file_stats, const char *tempfile_path_prefix);
442 #endif
443
444 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats)
445 {
446         const char *tempfile_path_prefix = 0; /*@@@ search for comments near 'rename(...)' for what it will take to finish implementing this */
447
448         FLAC__ASSERT(0 != iterator);
449         FLAC__ASSERT(0 != filename);
450
451         simple_iterator_free_guts_(iterator);
452
453         if(!read_only && preserve_file_stats)
454                 iterator->has_stats = get_file_stats_(filename, &iterator->stats);
455
456         if(0 == (iterator->filename = strdup(filename))) {
457                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
458                 return false;
459         }
460         if(0 != tempfile_path_prefix && 0 == (iterator->tempfile_path_prefix = strdup(tempfile_path_prefix))) {
461                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
462                 return false;
463         }
464
465         return simple_iterator_prime_input_(iterator, read_only);
466 }
467
468 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator)
469 {
470         FLAC__ASSERT(0 != iterator);
471         FLAC__ASSERT(0 != iterator->file);
472
473         return iterator->is_writable;
474 }
475
476 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator)
477 {
478         FLAC__ASSERT(0 != iterator);
479         FLAC__ASSERT(0 != iterator->file);
480
481         if(iterator->is_last)
482                 return false;
483
484         if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) {
485                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
486                 return false;
487         }
488
489         iterator->offset[iterator->depth] = ftello(iterator->file);
490
491         return read_metadata_block_header_(iterator);
492 }
493
494 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator)
495 {
496         off_t this_offset;
497
498         FLAC__ASSERT(0 != iterator);
499         FLAC__ASSERT(0 != iterator->file);
500
501         if(iterator->offset[iterator->depth] == iterator->first_offset)
502                 return false;
503
504         if(0 != fseeko(iterator->file, iterator->first_offset, SEEK_SET)) {
505                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
506                 return false;
507         }
508         this_offset = iterator->first_offset;
509         if(!read_metadata_block_header_(iterator))
510                 return false;
511
512         /* we ignore any error from ftello() and catch it in fseeko() */
513         while(ftello(iterator->file) + (off_t)iterator->length < iterator->offset[iterator->depth]) {
514                 if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) {
515                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
516                         return false;
517                 }
518                 this_offset = ftello(iterator->file);
519                 if(!read_metadata_block_header_(iterator))
520                         return false;
521         }
522
523         iterator->offset[iterator->depth] = this_offset;
524
525         return true;
526 }
527
528 FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator)
529 {
530         FLAC__ASSERT(0 != iterator);
531         FLAC__ASSERT(0 != iterator->file);
532
533         return iterator->type;
534 }
535
536 FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator)
537 {
538         FLAC__StreamMetadata *block = FLAC__metadata_object_new(iterator->type);
539
540         FLAC__ASSERT(0 != iterator);
541         FLAC__ASSERT(0 != iterator->file);
542
543         if(0 != block) {
544                 block->is_last = iterator->is_last;
545                 block->length = iterator->length;
546
547                 if(!read_metadata_block_data_(iterator, block)) {
548                         FLAC__metadata_object_delete(block);
549                         return 0;
550                 }
551
552                 /* back up to the beginning of the block data to stay consistent */
553                 if(0 != fseeko(iterator->file, iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH, SEEK_SET)) {
554                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
555                         FLAC__metadata_object_delete(block);
556                         return 0;
557                 }
558         }
559         else
560                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
561
562         return block;
563 }
564
565 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding)
566 {
567         FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth];)
568         FLAC__bool ret;
569
570         FLAC__ASSERT(0 != iterator);
571         FLAC__ASSERT(0 != iterator->file);
572         FLAC__ASSERT(0 != block);
573
574         if(!iterator->is_writable) {
575                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE;
576                 return false;
577         }
578
579         if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO || block->type == FLAC__METADATA_TYPE_STREAMINFO) {
580                 if(iterator->type != block->type) {
581                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT;
582                         return false;
583                 }
584         }
585
586         block->is_last = iterator->is_last;
587
588         if(iterator->length == block->length)
589                 return write_metadata_block_stationary_(iterator, block);
590         else if(iterator->length > block->length) {
591                 if(use_padding && iterator->length >= FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) {
592                         ret = write_metadata_block_stationary_with_padding_(iterator, block, iterator->length - FLAC__STREAM_METADATA_HEADER_LENGTH - block->length, block->is_last);
593                         FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
594                         FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
595                         return ret;
596                 }
597                 else {
598                         ret = rewrite_whole_file_(iterator, block, /*append=*/false);
599                         FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
600                         FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
601                         return ret;
602                 }
603         }
604         else /* iterator->length < block->length */ {
605                 unsigned padding_leftover = 0;
606                 FLAC__bool padding_is_last = false;
607                 if(use_padding) {
608                         /* first see if we can even use padding */
609                         if(iterator->is_last) {
610                                 use_padding = false;
611                         }
612                         else {
613                                 const unsigned extra_padding_bytes_required = block->length - iterator->length;
614                                 simple_iterator_push_(iterator);
615                                 if(!FLAC__metadata_simple_iterator_next(iterator)) {
616                                         (void)simple_iterator_pop_(iterator);
617                                         return false;
618                                 }
619                                 if(iterator->type != FLAC__METADATA_TYPE_PADDING) {
620                                         use_padding = false;
621                                 }
622                                 else {
623                                         if(FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length == extra_padding_bytes_required) {
624                                                 padding_leftover = 0;
625                                                 block->is_last = iterator->is_last;
626                                         }
627                                         else if(iterator->length < extra_padding_bytes_required)
628                                                 use_padding = false;
629                                         else {
630                                                 padding_leftover = FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length - extra_padding_bytes_required;
631                                                 padding_is_last = iterator->is_last;
632                                                 block->is_last = false;
633                                         }
634                                 }
635                                 if(!simple_iterator_pop_(iterator))
636                                         return false;
637                         }
638                 }
639                 if(use_padding) {
640                         if(padding_leftover == 0) {
641                                 ret = write_metadata_block_stationary_(iterator, block);
642                                 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
643                                 FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
644                                 return ret;
645                         }
646                         else {
647                                 FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH);
648                                 ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last);
649                                 FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
650                                 FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
651                                 return ret;
652                         }
653                 }
654                 else {
655                         ret = rewrite_whole_file_(iterator, block, /*append=*/false);
656                         FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
657                         FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
658                         return ret;
659                 }
660         }
661 }
662
663 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding)
664 {
665         unsigned padding_leftover = 0;
666         FLAC__bool padding_is_last = false;
667
668         FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length;)
669         FLAC__bool ret;
670
671         FLAC__ASSERT(0 != iterator);
672         FLAC__ASSERT(0 != iterator->file);
673         FLAC__ASSERT(0 != block);
674
675         if(!iterator->is_writable)
676                 return false;
677
678         if(block->type == FLAC__METADATA_TYPE_STREAMINFO) {
679                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT;
680                 return false;
681         }
682
683         block->is_last = iterator->is_last;
684
685         if(use_padding) {
686                 /* first see if we can even use padding */
687                 if(iterator->is_last) {
688                         use_padding = false;
689                 }
690                 else {
691                         simple_iterator_push_(iterator);
692                         if(!FLAC__metadata_simple_iterator_next(iterator)) {
693                                 (void)simple_iterator_pop_(iterator);
694                                 return false;
695                         }
696                         if(iterator->type != FLAC__METADATA_TYPE_PADDING) {
697                                 use_padding = false;
698                         }
699                         else {
700                                 if(iterator->length == block->length) {
701                                         padding_leftover = 0;
702                                         block->is_last = iterator->is_last;
703                                 }
704                                 else if(iterator->length < FLAC__STREAM_METADATA_HEADER_LENGTH + block->length)
705                                         use_padding = false;
706                                 else {
707                                         padding_leftover = iterator->length - block->length;
708                                         padding_is_last = iterator->is_last;
709                                         block->is_last = false;
710                                 }
711                         }
712                         if(!simple_iterator_pop_(iterator))
713                                 return false;
714                 }
715         }
716         if(use_padding) {
717                 /* move to the next block, which is suitable padding */
718                 if(!FLAC__metadata_simple_iterator_next(iterator))
719                         return false;
720                 if(padding_leftover == 0) {
721                         ret = write_metadata_block_stationary_(iterator, block);
722                         FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
723                         FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
724                         return ret;
725                 }
726                 else {
727                         FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH);
728                         ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last);
729                         FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
730                         FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
731                         return ret;
732                 }
733         }
734         else {
735                 ret = rewrite_whole_file_(iterator, block, /*append=*/true);
736                 FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
737                 FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH);
738                 return ret;
739         }
740 }
741
742 FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding)
743 {
744         FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth];)
745         FLAC__bool ret;
746
747         if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO) {
748                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT;
749                 return false;
750         }
751
752         if(use_padding) {
753                 FLAC__StreamMetadata *padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
754                 if(0 == padding) {
755                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
756                         return false;
757                 }
758                 padding->length = iterator->length;
759                 if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false)) {
760                         FLAC__metadata_object_delete(padding);
761                         return false;
762                 }
763                 FLAC__metadata_object_delete(padding);
764                 if(!FLAC__metadata_simple_iterator_prev(iterator))
765                         return false;
766                 FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset);
767                 FLAC__ASSERT(ftello(iterator->file) + (off_t)iterator->length == debug_target_offset);
768                 return true;
769         }
770         else {
771                 ret = rewrite_whole_file_(iterator, 0, /*append=*/false);
772                 FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset);
773                 FLAC__ASSERT(ftello(iterator->file) + (off_t)iterator->length == debug_target_offset);
774                 return ret;
775         }
776 }
777
778
779
780 /****************************************************************************
781  *
782  * Level 2 implementation
783  *
784  ***************************************************************************/
785
786
787 typedef struct FLAC__Metadata_Node {
788         FLAC__StreamMetadata *data;
789         struct FLAC__Metadata_Node *prev, *next;
790 } FLAC__Metadata_Node;
791
792 struct FLAC__Metadata_Chain {
793         char *filename; /* will be NULL if using callbacks */
794         FLAC__Metadata_Node *head;
795         FLAC__Metadata_Node *tail;
796         unsigned nodes;
797         FLAC__Metadata_ChainStatus status;
798         off_t first_offset, last_offset;
799         /*
800          * This is the length of the chain initially read from the FLAC file.
801          * it is used to compare against the current length to decide whether
802          * or not the whole file has to be rewritten.
803          */
804         off_t initial_length;
805 };
806
807 struct FLAC__Metadata_Iterator {
808         FLAC__Metadata_Chain *chain;
809         FLAC__Metadata_Node *current;
810 };
811
812 FLAC_API const char * const FLAC__Metadata_ChainStatusString[] = {
813         "FLAC__METADATA_CHAIN_STATUS_OK",
814         "FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT",
815         "FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE",
816         "FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE",
817         "FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE",
818         "FLAC__METADATA_CHAIN_STATUS_BAD_METADATA",
819         "FLAC__METADATA_CHAIN_STATUS_READ_ERROR",
820         "FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR",
821         "FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR",
822         "FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR",
823         "FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR",
824         "FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR",
825         "FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR",
826         "FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS",
827         "FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH",
828         "FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL"
829 };
830
831
832 static FLAC__Metadata_Node *node_new_()
833 {
834         return (FLAC__Metadata_Node*)calloc(1, sizeof(FLAC__Metadata_Node));
835 }
836
837 static void node_delete_(FLAC__Metadata_Node *node)
838 {
839         FLAC__ASSERT(0 != node);
840         if(0 != node->data)
841                 FLAC__metadata_object_delete(node->data);
842         free(node);
843 }
844
845 static void chain_init_(FLAC__Metadata_Chain *chain)
846 {
847         FLAC__ASSERT(0 != chain);
848
849         chain->filename = 0;
850         chain->head = chain->tail = 0;
851         chain->nodes = 0;
852         chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
853         chain->initial_length = 0;
854 }
855
856 static void chain_clear_(FLAC__Metadata_Chain *chain)
857 {
858         FLAC__Metadata_Node *node, *next;
859
860         FLAC__ASSERT(0 != chain);
861
862         for(node = chain->head; node; ) {
863                 next = node->next;
864                 node_delete_(node);
865                 node = next;
866         }
867
868         if(0 != chain->filename)
869                 free(chain->filename);
870
871         chain_init_(chain);
872 }
873
874 static void chain_append_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
875 {
876         FLAC__ASSERT(0 != chain);
877         FLAC__ASSERT(0 != node);
878         FLAC__ASSERT(0 != node->data);
879
880         node->next = node->prev = 0;
881         node->data->is_last = true;
882         if(0 != chain->tail)
883                 chain->tail->data->is_last = false;
884
885         if(0 == chain->head)
886                 chain->head = node;
887         else {
888                 FLAC__ASSERT(0 != chain->tail);
889                 chain->tail->next = node;
890                 node->prev = chain->tail;
891         }
892         chain->tail = node;
893         chain->nodes++;
894 }
895
896 static void chain_remove_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
897 {
898         FLAC__ASSERT(0 != chain);
899         FLAC__ASSERT(0 != node);
900
901         if(node == chain->head)
902                 chain->head = node->next;
903         else
904                 node->prev->next = node->next;
905
906         if(node == chain->tail)
907                 chain->tail = node->prev;
908         else
909                 node->next->prev = node->prev;
910
911         if(0 != chain->tail)
912                 chain->tail->data->is_last = true;
913
914         chain->nodes--;
915 }
916
917 static void chain_delete_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
918 {
919         chain_remove_node_(chain, node);
920         node_delete_(node);
921 }
922
923 static off_t chain_calculate_length_(FLAC__Metadata_Chain *chain)
924 {
925         const FLAC__Metadata_Node *node;
926         off_t length = 0;
927         for(node = chain->head; node; node = node->next)
928                 length += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);
929         return length;
930 }
931
932 static void iterator_insert_node_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node)
933 {
934         FLAC__ASSERT(0 != node);
935         FLAC__ASSERT(0 != node->data);
936         FLAC__ASSERT(0 != iterator);
937         FLAC__ASSERT(0 != iterator->current);
938         FLAC__ASSERT(0 != iterator->chain);
939         FLAC__ASSERT(0 != iterator->chain->head);
940         FLAC__ASSERT(0 != iterator->chain->tail);
941
942         node->data->is_last = false;
943
944         node->prev = iterator->current->prev;
945         node->next = iterator->current;
946
947         if(0 == node->prev)
948                 iterator->chain->head = node;
949         else
950                 node->prev->next = node;
951
952         iterator->current->prev = node;
953
954         iterator->chain->nodes++;
955 }
956
957 static void iterator_insert_node_after_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node)
958 {
959         FLAC__ASSERT(0 != node);
960         FLAC__ASSERT(0 != node->data);
961         FLAC__ASSERT(0 != iterator);
962         FLAC__ASSERT(0 != iterator->current);
963         FLAC__ASSERT(0 != iterator->chain);
964         FLAC__ASSERT(0 != iterator->chain->head);
965         FLAC__ASSERT(0 != iterator->chain->tail);
966
967         iterator->current->data->is_last = false;
968
969         node->prev = iterator->current;
970         node->next = iterator->current->next;
971
972         if(0 == node->next)
973                 iterator->chain->tail = node;
974         else
975                 node->next->prev = node;
976
977         node->prev->next = node;
978
979         iterator->chain->tail->data->is_last = true;
980
981         iterator->chain->nodes++;
982 }
983
984 /* return true iff node and node->next are both padding */
985 static FLAC__bool chain_merge_adjacent_padding_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
986 {
987         if(node->data->type == FLAC__METADATA_TYPE_PADDING && 0 != node->next && node->next->data->type == FLAC__METADATA_TYPE_PADDING) {
988                 const unsigned growth = FLAC__STREAM_METADATA_HEADER_LENGTH + node->next->data->length;
989                 node->data->length += growth;
990
991                 chain_delete_node_(chain, node->next);
992                 return true;
993         }
994         else
995                 return false;
996 }
997
998 /* Returns the new length of the chain, or 0 if there was an error. */
999 /* WATCHOUT: This can get called multiple times before a write, so
1000  * it should still work when this happens.
1001  */
1002 /* WATCHOUT: Make sure to also update the logic in
1003  * FLAC__metadata_chain_check_if_tempfile_needed() if the logic here changes.
1004  */
1005 static off_t chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding)
1006 {
1007         off_t current_length = chain_calculate_length_(chain);
1008
1009         if(use_padding) {
1010                 /* if the metadata shrank and the last block is padding, we just extend the last padding block */
1011                 if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
1012                         const off_t delta = chain->initial_length - current_length;
1013                         chain->tail->data->length += delta;
1014                         current_length += delta;
1015                         FLAC__ASSERT(current_length == chain->initial_length);
1016                 }
1017                 /* if the metadata shrank more than 4 bytes then there's room to add another padding block */
1018                 else if(current_length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) {
1019                         FLAC__StreamMetadata *padding;
1020                         FLAC__Metadata_Node *node;
1021                         if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) {
1022                                 chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
1023                                 return 0;
1024                         }
1025                         padding->length = chain->initial_length - (FLAC__STREAM_METADATA_HEADER_LENGTH + current_length);
1026                         if(0 == (node = node_new_())) {
1027                                 FLAC__metadata_object_delete(padding);
1028                                 chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
1029                                 return 0;
1030                         }
1031                         node->data = padding;
1032                         chain_append_node_(chain, node);
1033                         current_length = chain_calculate_length_(chain);
1034                         FLAC__ASSERT(current_length == chain->initial_length);
1035                 }
1036                 /* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */
1037                 else if(current_length > chain->initial_length) {
1038                         const off_t delta = current_length - chain->initial_length;
1039                         if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
1040                                 /* if the delta is exactly the size of the last padding block, remove the padding block */
1041                                 if((off_t)chain->tail->data->length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta) {
1042                                         chain_delete_node_(chain, chain->tail);
1043                                         current_length = chain_calculate_length_(chain);
1044                                         FLAC__ASSERT(current_length == chain->initial_length);
1045                                 }
1046                                 /* if there is at least 'delta' bytes of padding, trim the padding down */
1047                                 else if((off_t)chain->tail->data->length >= delta) {
1048                                         chain->tail->data->length -= delta;
1049                                         current_length -= delta;
1050                                         FLAC__ASSERT(current_length == chain->initial_length);
1051                                 }
1052                         }
1053                 }
1054         }
1055
1056         return current_length;
1057 }
1058
1059 static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__IOCallback_Tell tell_cb)
1060 {
1061         FLAC__Metadata_Node *node;
1062
1063         FLAC__ASSERT(0 != chain);
1064
1065         /* we assume we're already at the beginning of the file */
1066
1067         switch(seek_to_first_metadata_block_cb_(handle, read_cb, seek_cb)) {
1068                 case 0:
1069                         break;
1070                 case 1:
1071                         chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
1072                         return false;
1073                 case 2:
1074                         chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
1075                         return false;
1076                 case 3:
1077                         chain->status = FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE;
1078                         return false;
1079                 default:
1080                         FLAC__ASSERT(0);
1081                         return false;
1082         }
1083
1084         {
1085                 FLAC__int64 pos = tell_cb(handle);
1086                 if(pos < 0) {
1087                         chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
1088                         return false;
1089                 }
1090                 chain->first_offset = (off_t)pos;
1091         }
1092
1093         {
1094                 FLAC__bool is_last;
1095                 FLAC__MetadataType type;
1096                 unsigned length;
1097
1098                 do {
1099                         node = node_new_();
1100                         if(0 == node) {
1101                                 chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
1102                                 return false;
1103                         }
1104
1105                         if(!read_metadata_block_header_cb_(handle, read_cb, &is_last, &type, &length)) {
1106                                 chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
1107                                 return false;
1108                         }
1109
1110                         node->data = FLAC__metadata_object_new(type);
1111                         if(0 == node->data) {
1112                                 node_delete_(node);
1113                                 chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
1114                                 return false;
1115                         }
1116
1117                         node->data->is_last = is_last;
1118                         node->data->length = length;
1119
1120                         chain->status = get_equivalent_status_(read_metadata_block_data_cb_(handle, read_cb, seek_cb, node->data));
1121                         if(chain->status != FLAC__METADATA_CHAIN_STATUS_OK) {
1122                                 node_delete_(node);
1123                                 return false;
1124                         }
1125                         chain_append_node_(chain, node);
1126                 } while(!is_last);
1127         }
1128
1129         {
1130                 FLAC__int64 pos = tell_cb(handle);
1131                 if(pos < 0) {
1132                         chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
1133                         return false;
1134                 }
1135                 chain->last_offset = (off_t)pos;
1136         }
1137
1138         chain->initial_length = chain_calculate_length_(chain);
1139
1140         return true;
1141 }
1142
1143 static FLAC__bool chain_rewrite_metadata_in_place_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, FLAC__IOCallback_Seek seek_cb)
1144 {
1145         FLAC__Metadata_Node *node;
1146
1147         FLAC__ASSERT(0 != chain);
1148         FLAC__ASSERT(0 != chain->head);
1149
1150         if(0 != seek_cb(handle, chain->first_offset, SEEK_SET)) {
1151                 chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
1152                 return false;
1153         }
1154
1155         for(node = chain->head; node; node = node->next) {
1156                 if(!write_metadata_block_header_cb_(handle, write_cb, node->data)) {
1157                         chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
1158                         return false;
1159                 }
1160                 if(!write_metadata_block_data_cb_(handle, write_cb, node->data)) {
1161                         chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
1162                         return false;
1163                 }
1164         }
1165
1166         /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/
1167
1168         chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
1169         return true;
1170 }
1171
1172 static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain)
1173 {
1174         FILE *file;
1175         FLAC__bool ret;
1176
1177         FLAC__ASSERT(0 != chain->filename);
1178
1179         if(0 == (file = fopen(chain->filename, "r+b"))) {
1180                 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
1181                 return false;
1182         }
1183
1184         /* chain_rewrite_metadata_in_place_cb_() sets chain->status for us */
1185         ret = chain_rewrite_metadata_in_place_cb_(chain, (FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, fseek_wrapper_);
1186
1187         fclose(file);
1188
1189         return ret;
1190 }
1191
1192 static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix)
1193 {
1194         FILE *f, *tempfile;
1195         char *tempfilename;
1196         FLAC__Metadata_SimpleIteratorStatus status;
1197         const FLAC__Metadata_Node *node;
1198
1199         FLAC__ASSERT(0 != chain);
1200         FLAC__ASSERT(0 != chain->filename);
1201         FLAC__ASSERT(0 != chain->head);
1202
1203         /* copy the file prefix (data up to first metadata block */
1204         if(0 == (f = fopen(chain->filename, "rb"))) {
1205                 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
1206                 return false;
1207         }
1208         if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) {
1209                 chain->status = get_equivalent_status_(status);
1210                 cleanup_tempfile_(&tempfile, &tempfilename);
1211                 return false;
1212         }
1213         if(!copy_n_bytes_from_file_(f, tempfile, chain->first_offset, &status)) {
1214                 chain->status = get_equivalent_status_(status);
1215                 cleanup_tempfile_(&tempfile, &tempfilename);
1216                 return false;
1217         }
1218
1219         /* write the metadata */
1220         for(node = chain->head; node; node = node->next) {
1221                 if(!write_metadata_block_header_(tempfile, &status, node->data)) {
1222                         chain->status = get_equivalent_status_(status);
1223                         return false;
1224                 }
1225                 if(!write_metadata_block_data_(tempfile, &status, node->data)) {
1226                         chain->status = get_equivalent_status_(status);
1227                         return false;
1228                 }
1229         }
1230         /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/
1231
1232         /* copy the file postfix (everything after the metadata) */
1233         if(0 != fseeko(f, chain->last_offset, SEEK_SET)) {
1234                 cleanup_tempfile_(&tempfile, &tempfilename);
1235                 chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
1236                 return false;
1237         }
1238         if(!copy_remaining_bytes_from_file_(f, tempfile, &status)) {
1239                 cleanup_tempfile_(&tempfile, &tempfilename);
1240                 chain->status = get_equivalent_status_(status);
1241                 return false;
1242         }
1243
1244         /* move the tempfile on top of the original */
1245         (void)fclose(f);
1246         if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status))
1247                 return false;
1248
1249         return true;
1250 }
1251
1252 /* assumes 'handle' is already at beginning of file */
1253 static FLAC__bool chain_rewrite_file_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb)
1254 {
1255         FLAC__Metadata_SimpleIteratorStatus status;
1256         const FLAC__Metadata_Node *node;
1257
1258         FLAC__ASSERT(0 != chain);
1259         FLAC__ASSERT(0 == chain->filename);
1260         FLAC__ASSERT(0 != chain->head);
1261
1262         /* copy the file prefix (data up to first metadata block */
1263         if(!copy_n_bytes_from_file_cb_(handle, read_cb, temp_handle, temp_write_cb, chain->first_offset, &status)) {
1264                 chain->status = get_equivalent_status_(status);
1265                 return false;
1266         }
1267
1268         /* write the metadata */
1269         for(node = chain->head; node; node = node->next) {
1270                 if(!write_metadata_block_header_cb_(temp_handle, temp_write_cb, node->data)) {
1271                         chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
1272                         return false;
1273                 }
1274                 if(!write_metadata_block_data_cb_(temp_handle, temp_write_cb, node->data)) {
1275                         chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
1276                         return false;
1277                 }
1278         }
1279         /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/
1280
1281         /* copy the file postfix (everything after the metadata) */
1282         if(0 != seek_cb(handle, chain->last_offset, SEEK_SET)) {
1283                 chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
1284                 return false;
1285         }
1286         if(!copy_remaining_bytes_from_file_cb_(handle, read_cb, eof_cb, temp_handle, temp_write_cb, &status)) {
1287                 chain->status = get_equivalent_status_(status);
1288                 return false;
1289         }
1290
1291         return true;
1292 }
1293
1294 FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new()
1295 {
1296         FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)calloc(1, sizeof(FLAC__Metadata_Chain));
1297
1298         if(0 != chain)
1299                 chain_init_(chain);
1300
1301         return chain;
1302 }
1303
1304 FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain)
1305 {
1306         FLAC__ASSERT(0 != chain);
1307
1308         chain_clear_(chain);
1309
1310         free(chain);
1311 }
1312
1313 FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain)
1314 {
1315         FLAC__Metadata_ChainStatus status;
1316
1317         FLAC__ASSERT(0 != chain);
1318
1319         status = chain->status;
1320         chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
1321         return status;
1322 }
1323
1324 FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename)
1325 {
1326         FILE *file;
1327         FLAC__bool ret;
1328
1329         FLAC__ASSERT(0 != chain);
1330         FLAC__ASSERT(0 != filename);
1331
1332         chain_clear_(chain);
1333
1334         if(0 == (chain->filename = strdup(filename))) {
1335                 chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
1336                 return false;
1337         }
1338
1339         if(0 == (file = fopen(filename, "rb"))) {
1340                 chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
1341                 return false;
1342         }
1343
1344         /* chain_read_cb_() sets chain->status for us */
1345         ret = chain_read_cb_(chain, file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, ftell_wrapper_);
1346
1347         fclose(file);
1348
1349         return ret;
1350 }
1351
1352 FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks)
1353 {
1354         FLAC__ASSERT(0 != chain);
1355
1356         chain_clear_(chain);
1357
1358         if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.tell) {
1359                 chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
1360                 return false;
1361         }
1362
1363         /* rewind */
1364         if(0 != callbacks.seek(handle, 0, SEEK_SET)) {
1365                 chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
1366                 return false;
1367         }
1368
1369         if(!chain_read_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.tell))
1370                 return false; /* chain->status is already set by chain_read_cb_ */
1371
1372         return true;
1373 }
1374
1375 FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding)
1376 {
1377         /* This does all the same checks that are in chain_prepare_for_write_()
1378          * but doesn't actually alter the chain.  Make sure to update the logic
1379          * here if chain_prepare_for_write_() changes.
1380          */
1381         const off_t current_length = chain_calculate_length_(chain);
1382
1383         FLAC__ASSERT(0 != chain);
1384
1385         if(use_padding) {
1386                 /* if the metadata shrank and the last block is padding, we just extend the last padding block */
1387                 if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING)
1388                         return false;
1389                 /* if the metadata shrank more than 4 bytes then there's room to add another padding block */
1390                 else if(current_length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length)
1391                         return false;
1392                 /* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */
1393                 else if(current_length > chain->initial_length) {
1394                         const off_t delta = current_length - chain->initial_length;
1395                         if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
1396                                 /* if the delta is exactly the size of the last padding block, remove the padding block */
1397                                 if((off_t)chain->tail->data->length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta)
1398                                         return false;
1399                                 /* if there is at least 'delta' bytes of padding, trim the padding down */
1400                                 else if((off_t)chain->tail->data->length >= delta)
1401                                         return false;
1402                         }
1403                 }
1404         }
1405
1406         return (current_length != chain->initial_length);
1407 }
1408
1409 FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats)
1410 {
1411         struct stat stats;
1412         const char *tempfile_path_prefix = 0;
1413         off_t current_length;
1414
1415         FLAC__ASSERT(0 != chain);
1416
1417         if (0 == chain->filename) {
1418                 chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH;
1419                 return false;
1420         }
1421
1422         current_length = chain_prepare_for_write_(chain, use_padding);
1423
1424         /* a return value of 0 means there was an error; chain->status is already set */
1425         if (0 == current_length)
1426                 return false;
1427
1428         if(preserve_file_stats)
1429                 get_file_stats_(chain->filename, &stats);
1430
1431         if(current_length == chain->initial_length) {
1432                 if(!chain_rewrite_metadata_in_place_(chain))
1433                         return false;
1434         }
1435         else {
1436                 if(!chain_rewrite_file_(chain, tempfile_path_prefix))
1437                         return false;
1438
1439                 /* recompute lengths and offsets */
1440                 {
1441                         const FLAC__Metadata_Node *node;
1442                         chain->initial_length = current_length;
1443                         chain->last_offset = chain->first_offset;
1444                         for(node = chain->head; node; node = node->next)
1445                                 chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);
1446                 }
1447         }
1448
1449         if(preserve_file_stats)
1450                 set_file_stats_(chain->filename, &stats);
1451
1452         return true;
1453 }
1454
1455 FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks)
1456 {
1457         off_t current_length;
1458
1459         FLAC__ASSERT(0 != chain);
1460
1461         if (0 != chain->filename) {
1462                 chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH;
1463                 return false;
1464         }
1465
1466         if (0 == callbacks.write || 0 == callbacks.seek) {
1467                 chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
1468                 return false;
1469         }
1470
1471         if (FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
1472                 chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL;
1473                 return false;
1474         }
1475
1476         current_length = chain_prepare_for_write_(chain, use_padding);
1477
1478         /* a return value of 0 means there was an error; chain->status is already set */
1479         if (0 == current_length)
1480                 return false;
1481
1482         FLAC__ASSERT(current_length == chain->initial_length);
1483
1484         return chain_rewrite_metadata_in_place_cb_(chain, handle, callbacks.write, callbacks.seek);
1485 }
1486
1487 FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks)
1488 {
1489         off_t current_length;
1490
1491         FLAC__ASSERT(0 != chain);
1492
1493         if (0 != chain->filename) {
1494                 chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH;
1495                 return false;
1496         }
1497
1498         if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.eof) {
1499                 chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
1500                 return false;
1501         }
1502         if (0 == temp_callbacks.write) {
1503                 chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
1504                 return false;
1505         }
1506
1507         if (!FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
1508                 chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL;
1509                 return false;
1510         }
1511
1512         current_length = chain_prepare_for_write_(chain, use_padding);
1513
1514         /* a return value of 0 means there was an error; chain->status is already set */
1515         if (0 == current_length)
1516                 return false;
1517
1518         FLAC__ASSERT(current_length != chain->initial_length);
1519
1520         /* rewind */
1521         if(0 != callbacks.seek(handle, 0, SEEK_SET)) {
1522                 chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
1523                 return false;
1524         }
1525
1526         if(!chain_rewrite_file_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.eof, temp_handle, temp_callbacks.write))
1527                 return false;
1528
1529         /* recompute lengths and offsets */
1530         {
1531                 const FLAC__Metadata_Node *node;
1532                 chain->initial_length = current_length;
1533                 chain->last_offset = chain->first_offset;
1534                 for(node = chain->head; node; node = node->next)
1535                         chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);
1536         }
1537
1538         return true;
1539 }
1540
1541 FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain)
1542 {
1543         FLAC__Metadata_Node *node;
1544
1545         FLAC__ASSERT(0 != chain);
1546
1547         for(node = chain->head; node; ) {
1548                 if(!chain_merge_adjacent_padding_(chain, node))
1549                         node = node->next;
1550         }
1551 }
1552
1553 FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain)
1554 {
1555         FLAC__Metadata_Node *node, *save;
1556         unsigned i;
1557
1558         FLAC__ASSERT(0 != chain);
1559
1560         /*
1561          * Don't try and be too smart... this simple algo is good enough for
1562          * the small number of nodes that we deal with.
1563          */
1564         for(i = 0, node = chain->head; i < chain->nodes; i++) {
1565                 if(node->data->type == FLAC__METADATA_TYPE_PADDING) {
1566                         save = node->next;
1567                         chain_remove_node_(chain, node);
1568                         chain_append_node_(chain, node);
1569                         node = save;
1570                 }
1571                 else {
1572                         node = node->next;
1573                 }
1574         }
1575
1576         FLAC__metadata_chain_merge_padding(chain);
1577 }
1578
1579
1580 FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new()
1581 {
1582         FLAC__Metadata_Iterator *iterator = (FLAC__Metadata_Iterator*)calloc(1, sizeof(FLAC__Metadata_Iterator));
1583
1584         /* calloc() implies:
1585                 iterator->current = 0;
1586                 iterator->chain = 0;
1587         */
1588
1589         return iterator;
1590 }
1591
1592 FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator)
1593 {
1594         FLAC__ASSERT(0 != iterator);
1595
1596         free(iterator);
1597 }
1598
1599 FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain)
1600 {
1601         FLAC__ASSERT(0 != iterator);
1602         FLAC__ASSERT(0 != chain);
1603         FLAC__ASSERT(0 != chain->head);
1604
1605         iterator->chain = chain;
1606         iterator->current = chain->head;
1607 }
1608
1609 FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator)
1610 {
1611         FLAC__ASSERT(0 != iterator);
1612
1613         if(0 == iterator->current || 0 == iterator->current->next)
1614                 return false;
1615
1616         iterator->current = iterator->current->next;
1617         return true;
1618 }
1619
1620 FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator)
1621 {
1622         FLAC__ASSERT(0 != iterator);
1623
1624         if(0 == iterator->current || 0 == iterator->current->prev)
1625                 return false;
1626
1627         iterator->current = iterator->current->prev;
1628         return true;
1629 }
1630
1631 FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator)
1632 {
1633         FLAC__ASSERT(0 != iterator);
1634         FLAC__ASSERT(0 != iterator->current);
1635         FLAC__ASSERT(0 != iterator->current->data);
1636
1637         return iterator->current->data->type;
1638 }
1639
1640 FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator)
1641 {
1642         FLAC__ASSERT(0 != iterator);
1643         FLAC__ASSERT(0 != iterator->current);
1644
1645         return iterator->current->data;
1646 }
1647
1648 FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block)
1649 {
1650         FLAC__ASSERT(0 != iterator);
1651         FLAC__ASSERT(0 != block);
1652         return FLAC__metadata_iterator_delete_block(iterator, false) && FLAC__metadata_iterator_insert_block_after(iterator, block);
1653 }
1654
1655 FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding)
1656 {
1657         FLAC__Metadata_Node *save;
1658
1659         FLAC__ASSERT(0 != iterator);
1660         FLAC__ASSERT(0 != iterator->current);
1661
1662         if(0 == iterator->current->prev) {
1663                 FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO);
1664                 return false;
1665         }
1666
1667         save = iterator->current->prev;
1668
1669         if(replace_with_padding) {
1670                 FLAC__metadata_object_delete_data(iterator->current->data);
1671                 iterator->current->data->type = FLAC__METADATA_TYPE_PADDING;
1672         }
1673         else {
1674                 chain_delete_node_(iterator->chain, iterator->current);
1675         }
1676
1677         iterator->current = save;
1678         return true;
1679 }
1680
1681 FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block)
1682 {
1683         FLAC__Metadata_Node *node;
1684
1685         FLAC__ASSERT(0 != iterator);
1686         FLAC__ASSERT(0 != iterator->current);
1687         FLAC__ASSERT(0 != block);
1688
1689         if(block->type == FLAC__METADATA_TYPE_STREAMINFO)
1690                 return false;
1691
1692         if(0 == iterator->current->prev) {
1693                 FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO);
1694                 return false;
1695         }
1696
1697         if(0 == (node = node_new_()))
1698                 return false;
1699
1700         node->data = block;
1701         iterator_insert_node_(iterator, node);
1702         iterator->current = node;
1703         return true;
1704 }
1705
1706 FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block)
1707 {
1708         FLAC__Metadata_Node *node;
1709
1710         FLAC__ASSERT(0 != iterator);
1711         FLAC__ASSERT(0 != iterator->current);
1712         FLAC__ASSERT(0 != block);
1713
1714         if(block->type == FLAC__METADATA_TYPE_STREAMINFO)
1715                 return false;
1716
1717         if(0 == (node = node_new_()))
1718                 return false;
1719
1720         node->data = block;
1721         iterator_insert_node_after_(iterator, node);
1722         iterator->current = node;
1723         return true;
1724 }
1725
1726
1727 /****************************************************************************
1728  *
1729  * Local function definitions
1730  *
1731  ***************************************************************************/
1732
1733 void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes)
1734 {
1735         unsigned i;
1736
1737         b += bytes;
1738
1739         for(i = 0; i < bytes; i++) {
1740                 *(--b) = (FLAC__byte)(val & 0xff);
1741                 val >>= 8;
1742         }
1743 }
1744
1745 void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes)
1746 {
1747         unsigned i;
1748
1749         for(i = 0; i < bytes; i++) {
1750                 *(b++) = (FLAC__byte)(val & 0xff);
1751                 val >>= 8;
1752         }
1753 }
1754
1755 void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes)
1756 {
1757         unsigned i;
1758
1759         b += bytes;
1760
1761         for(i = 0; i < bytes; i++) {
1762                 *(--b) = (FLAC__byte)(val & 0xff);
1763                 val >>= 8;
1764         }
1765 }
1766
1767 FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes)
1768 {
1769         FLAC__uint32 ret = 0;
1770         unsigned i;
1771
1772         for(i = 0; i < bytes; i++)
1773                 ret = (ret << 8) | (FLAC__uint32)(*b++);
1774
1775         return ret;
1776 }
1777
1778 FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes)
1779 {
1780         FLAC__uint32 ret = 0;
1781         unsigned i;
1782
1783         b += bytes;
1784
1785         for(i = 0; i < bytes; i++)
1786                 ret = (ret << 8) | (FLAC__uint32)(*--b);
1787
1788         return ret;
1789 }
1790
1791 FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes)
1792 {
1793         FLAC__uint64 ret = 0;
1794         unsigned i;
1795
1796         for(i = 0; i < bytes; i++)
1797                 ret = (ret << 8) | (FLAC__uint64)(*b++);
1798
1799         return ret;
1800 }
1801
1802 FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator)
1803 {
1804         FLAC__ASSERT(0 != iterator);
1805         FLAC__ASSERT(0 != iterator->file);
1806
1807         if(!read_metadata_block_header_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, &iterator->is_last, &iterator->type, &iterator->length)) {
1808                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
1809                 return false;
1810         }
1811
1812         return true;
1813 }
1814
1815 FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block)
1816 {
1817         FLAC__ASSERT(0 != iterator);
1818         FLAC__ASSERT(0 != iterator->file);
1819
1820         iterator->status = read_metadata_block_data_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, block);
1821
1822         return (iterator->status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK);
1823 }
1824
1825 FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length)
1826 {
1827         FLAC__byte raw_header[FLAC__STREAM_METADATA_HEADER_LENGTH];
1828
1829         if(read_cb(raw_header, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH)
1830                 return false;
1831
1832         *is_last = raw_header[0] & 0x80? true : false;
1833         *type = (FLAC__MetadataType)(raw_header[0] & 0x7f);
1834         *length = unpack_uint32_(raw_header + 1, 3);
1835
1836         /* Note that we don't check:
1837          *    if(iterator->type >= FLAC__METADATA_TYPE_UNDEFINED)
1838          * we just will read in an opaque block
1839          */
1840
1841         return true;
1842 }
1843
1844 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata *block)
1845 {
1846         switch(block->type) {
1847                 case FLAC__METADATA_TYPE_STREAMINFO:
1848                         return read_metadata_block_data_streaminfo_cb_(handle, read_cb, &block->data.stream_info);
1849                 case FLAC__METADATA_TYPE_PADDING:
1850                         return read_metadata_block_data_padding_cb_(handle, seek_cb, &block->data.padding, block->length);
1851                 case FLAC__METADATA_TYPE_APPLICATION:
1852                         return read_metadata_block_data_application_cb_(handle, read_cb, &block->data.application, block->length);
1853                 case FLAC__METADATA_TYPE_SEEKTABLE:
1854                         return read_metadata_block_data_seektable_cb_(handle, read_cb, &block->data.seek_table, block->length);
1855                 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
1856                         return read_metadata_block_data_vorbis_comment_cb_(handle, read_cb, &block->data.vorbis_comment);
1857                 case FLAC__METADATA_TYPE_CUESHEET:
1858                         return read_metadata_block_data_cuesheet_cb_(handle, read_cb, &block->data.cue_sheet);
1859                 default:
1860                         return read_metadata_block_data_unknown_cb_(handle, read_cb, &block->data.unknown, block->length);
1861         }
1862 }
1863
1864 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block)
1865 {
1866         FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH], *b;
1867
1868         if(read_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH)
1869                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
1870
1871         b = buffer;
1872
1873         /* we are using hardcoded numbers for simplicity but we should
1874          * probably eventually write a bit-level unpacker and use the
1875          * _STREAMINFO_ constants.
1876          */
1877         block->min_blocksize = unpack_uint32_(b, 2); b += 2;
1878         block->max_blocksize = unpack_uint32_(b, 2); b += 2;
1879         block->min_framesize = unpack_uint32_(b, 3); b += 3;
1880         block->max_framesize = unpack_uint32_(b, 3); b += 3;
1881         block->sample_rate = (unpack_uint32_(b, 2) << 4) | ((unsigned)(b[2] & 0xf0) >> 4);
1882         block->channels = (unsigned)((b[2] & 0x0e) >> 1) + 1;
1883         block->bits_per_sample = ((((unsigned)(b[2] & 0x01)) << 4) | (((unsigned)(b[3] & 0xf0)) >> 4)) + 1;
1884         block->total_samples = (((FLAC__uint64)(b[3] & 0x0f)) << 32) | unpack_uint64_(b+4, 4);
1885         memcpy(block->md5sum, b+8, 16);
1886
1887         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
1888 }
1889
1890
1891 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_Padding *block, unsigned block_length)
1892 {
1893         (void)block; /* nothing to do; we don't care about reading the padding bytes */
1894
1895         if(0 != seek_cb(handle, block_length, SEEK_CUR))
1896                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
1897
1898         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
1899 }
1900
1901 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Application *block, unsigned block_length)
1902 {
1903         const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
1904
1905         if(read_cb(block->id, 1, id_bytes, handle) != id_bytes)
1906                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
1907
1908         block_length -= id_bytes;
1909
1910         if(block_length == 0) {
1911                 block->data = 0;
1912         }
1913         else {
1914                 if(0 == (block->data = (FLAC__byte*)malloc(block_length)))
1915                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
1916
1917                 if(read_cb(block->data, 1, block_length, handle) != block_length)
1918                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
1919         }
1920
1921         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
1922 }
1923
1924 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_SeekTable *block, unsigned block_length)
1925 {
1926         unsigned i;
1927         FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH];
1928
1929         FLAC__ASSERT(block_length % FLAC__STREAM_METADATA_SEEKPOINT_LENGTH == 0);
1930
1931         block->num_points = block_length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
1932
1933         if(block->num_points == 0)
1934                 block->points = 0;
1935         else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)malloc(block->num_points * sizeof(FLAC__StreamMetadata_SeekPoint))))
1936                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
1937
1938         for(i = 0; i < block->num_points; i++) {
1939                 if(read_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)
1940                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
1941                 /* some MAGIC NUMBERs here */
1942                 block->points[i].sample_number = unpack_uint64_(buffer, 8);
1943                 block->points[i].stream_offset = unpack_uint64_(buffer+8, 8);
1944                 block->points[i].frame_samples = unpack_uint32_(buffer+16, 2);
1945         }
1946
1947         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
1948 }
1949
1950 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entry_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment_Entry *entry)
1951 {
1952         const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8;
1953         FLAC__byte buffer[4]; /* magic number is asserted below */
1954
1955         FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8 == 4);
1956
1957         if(read_cb(buffer, 1, entry_length_len, handle) != entry_length_len)
1958                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
1959         entry->length = unpack_uint32_little_endian_(buffer, entry_length_len);
1960
1961         if(0 != entry->entry)
1962                 free(entry->entry);
1963
1964         if(entry->length == 0) {
1965                 entry->entry = 0;
1966         }
1967         else {
1968                 if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1)))
1969                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
1970
1971                 if(read_cb(entry->entry, 1, entry->length, handle) != entry->length)
1972                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
1973
1974                 entry->entry[entry->length] = '\0';
1975         }
1976
1977         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
1978 }
1979
1980 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment *block)
1981 {
1982         unsigned i;
1983         FLAC__Metadata_SimpleIteratorStatus status;
1984         const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8;
1985         FLAC__byte buffer[4]; /* magic number is asserted below */
1986
1987         FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8 == 4);
1988
1989         if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, &(block->vendor_string))))
1990                 return status;
1991
1992         if(read_cb(buffer, 1, num_comments_len, handle) != num_comments_len)
1993                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
1994         block->num_comments = unpack_uint32_little_endian_(buffer, num_comments_len);
1995
1996         if(block->num_comments == 0) {
1997                 block->comments = 0;
1998         }
1999         else if(0 == (block->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry))))
2000                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
2001
2002         for(i = 0; i < block->num_comments; i++) {
2003                 if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, block->comments + i)))
2004                         return status;
2005         }
2006
2007         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
2008 }
2009
2010 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track)
2011 {
2012         unsigned i, len;
2013         FLAC__byte buffer[32]; /* asserted below that this is big enough */
2014
2015         FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64));
2016         FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8);
2017         FLAC__ASSERT(sizeof(buffer) >= (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8);
2018
2019         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0);
2020         len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8;
2021         if(read_cb(buffer, 1, len, handle) != len)
2022                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2023         track->offset = unpack_uint64_(buffer, len);
2024
2025         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0);
2026         len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8;
2027         if(read_cb(buffer, 1, len, handle) != len)
2028                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2029         track->number = (FLAC__byte)unpack_uint32_(buffer, len);
2030
2031         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0);
2032         len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8;
2033         if(read_cb(track->isrc, 1, len, handle) != len)
2034                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2035
2036         FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) % 8 == 0);
2037         len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8;
2038         if(read_cb(buffer, 1, len, handle) != len)
2039                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2040         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN == 1);
2041         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN == 1);
2042         track->type = buffer[0] >> 7;
2043         track->pre_emphasis = (buffer[0] >> 6) & 1;
2044
2045         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN % 8 == 0);
2046         len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN / 8;
2047         if(read_cb(buffer, 1, len, handle) != len)
2048                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2049         track->num_indices = (FLAC__byte)unpack_uint32_(buffer, len);
2050
2051         if(track->num_indices == 0) {
2052                 track->indices = 0;
2053         }
2054         else if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index))))
2055                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
2056
2057         for(i = 0; i < track->num_indices; i++) {
2058                 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN % 8 == 0);
2059                 len = FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN / 8;
2060                 if(read_cb(buffer, 1, len, handle) != len)
2061                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2062                 track->indices[i].offset = unpack_uint64_(buffer, len);
2063
2064                 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN % 8 == 0);
2065                 len = FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN / 8;
2066                 if(read_cb(buffer, 1, len, handle) != len)
2067                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2068                 track->indices[i].number = (FLAC__byte)unpack_uint32_(buffer, len);
2069
2070                 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN % 8 == 0);
2071                 len = FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN / 8;
2072                 if(read_cb(buffer, 1, len, handle) != len)
2073                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2074         }
2075
2076         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
2077 }
2078
2079 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block)
2080 {
2081         unsigned i, len;
2082         FLAC__Metadata_SimpleIteratorStatus status;
2083         FLAC__byte buffer[1024]; /* MSVC needs a constant expression so we put a magic number and assert */
2084
2085         FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)/8 <= sizeof(buffer));
2086         FLAC__ASSERT(sizeof(FLAC__uint64) <= sizeof(buffer));
2087
2088         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0);
2089         len = FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8;
2090         if(read_cb(block->media_catalog_number, 1, len, handle) != len)
2091                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2092
2093         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN % 8 == 0);
2094         len = FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN / 8;
2095         if(read_cb(buffer, 1, len, handle) != len)
2096                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2097         block->lead_in = unpack_uint64_(buffer, len);
2098
2099         FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) % 8 == 0);
2100         len = (FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) / 8;
2101         if(read_cb(buffer, 1, len, handle) != len)
2102                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2103         block->is_cd = buffer[0]&0x80? true : false;
2104
2105         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN % 8 == 0);
2106         len = FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN / 8;
2107         if(read_cb(buffer, 1, len, handle) != len)
2108                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2109         block->num_tracks = unpack_uint32_(buffer, len);
2110
2111         if(block->num_tracks == 0) {
2112                 block->tracks = 0;
2113         }
2114         else if(0 == (block->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(block->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track))))
2115                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
2116
2117         for(i = 0; i < block->num_tracks; i++) {
2118                 if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_cuesheet_track_cb_(handle, read_cb, block->tracks + i)))
2119                         return status;
2120         }
2121
2122         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
2123 }
2124
2125 FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Unknown *block, unsigned block_length)
2126 {
2127         if(block_length == 0) {
2128                 block->data = 0;
2129         }
2130         else {
2131                 if(0 == (block->data = (FLAC__byte*)malloc(block_length)))
2132                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
2133
2134                 if(read_cb(block->data, 1, block_length, handle) != block_length)
2135                         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2136         }
2137
2138         return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
2139 }
2140
2141 FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block)
2142 {
2143         FLAC__ASSERT(0 != file);
2144         FLAC__ASSERT(0 != status);
2145
2146         if(!write_metadata_block_header_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) {
2147                 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2148                 return false;
2149         }
2150
2151         return true;
2152 }
2153
2154 FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block)
2155 {
2156         FLAC__ASSERT(0 != file);
2157         FLAC__ASSERT(0 != status);
2158
2159         if (write_metadata_block_data_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) {
2160                 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
2161                 return true;
2162         }
2163         else {
2164                 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2165                 return false;
2166         }
2167 }
2168
2169 FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block)
2170 {
2171         FLAC__byte buffer[FLAC__STREAM_METADATA_HEADER_LENGTH];
2172
2173         FLAC__ASSERT(block->length < (1u << FLAC__STREAM_METADATA_LENGTH_LEN));
2174
2175         buffer[0] = (block->is_last? 0x80 : 0) | (FLAC__byte)block->type;
2176         pack_uint32_(block->length, buffer + 1, 3);
2177
2178         if(write_cb(buffer, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH)
2179                 return false;
2180
2181         return true;
2182 }
2183
2184 FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block)
2185 {
2186         FLAC__ASSERT(0 != block);
2187
2188         switch(block->type) {
2189                 case FLAC__METADATA_TYPE_STREAMINFO:
2190                         return write_metadata_block_data_streaminfo_cb_(handle, write_cb, &block->data.stream_info);
2191                 case FLAC__METADATA_TYPE_PADDING:
2192                         return write_metadata_block_data_padding_cb_(handle, write_cb, &block->data.padding, block->length);
2193                 case FLAC__METADATA_TYPE_APPLICATION:
2194                         return write_metadata_block_data_application_cb_(handle, write_cb, &block->data.application, block->length);
2195                 case FLAC__METADATA_TYPE_SEEKTABLE:
2196                         return write_metadata_block_data_seektable_cb_(handle, write_cb, &block->data.seek_table);
2197                 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
2198                         return write_metadata_block_data_vorbis_comment_cb_(handle, write_cb, &block->data.vorbis_comment);
2199                 case FLAC__METADATA_TYPE_CUESHEET:
2200                         return write_metadata_block_data_cuesheet_cb_(handle, write_cb, &block->data.cue_sheet);
2201                 default:
2202                         return write_metadata_block_data_unknown_cb_(handle, write_cb, &block->data.unknown, block->length);
2203         }
2204 }
2205
2206 FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block)
2207 {
2208         FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH];
2209         const unsigned channels1 = block->channels - 1;
2210         const unsigned bps1 = block->bits_per_sample - 1;
2211
2212         /* we are using hardcoded numbers for simplicity but we should
2213          * probably eventually write a bit-level packer and use the
2214          * _STREAMINFO_ constants.
2215          */
2216         pack_uint32_(block->min_blocksize, buffer, 2);
2217         pack_uint32_(block->max_blocksize, buffer+2, 2);
2218         pack_uint32_(block->min_framesize, buffer+4, 3);
2219         pack_uint32_(block->max_framesize, buffer+7, 3);
2220         buffer[10] = (block->sample_rate >> 12) & 0xff;
2221         buffer[11] = (block->sample_rate >> 4) & 0xff;
2222         buffer[12] = ((block->sample_rate & 0x0f) << 4) | (channels1 << 1) | (bps1 >> 4);
2223         buffer[13] = (FLAC__byte)(((bps1 & 0x0f) << 4) | ((block->total_samples >> 32) & 0x0f));
2224         pack_uint32_((FLAC__uint32)block->total_samples, buffer+14, 4);
2225         memcpy(buffer+18, block->md5sum, 16);
2226
2227         if(write_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH)
2228                 return false;
2229
2230         return true;
2231 }
2232
2233 FLAC__bool write_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Padding *block, unsigned block_length)
2234 {
2235         unsigned i, n = block_length;
2236         FLAC__byte buffer[1024];
2237
2238         (void)block;
2239
2240         memset(buffer, 0, 1024);
2241
2242         for(i = 0; i < n/1024; i++)
2243                 if(write_cb(buffer, 1, 1024, handle) != 1024)
2244                         return false;
2245
2246         n %= 1024;
2247
2248         if(write_cb(buffer, 1, n, handle) != n)
2249                 return false;
2250
2251         return true;
2252 }
2253
2254 FLAC__bool write_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Application *block, unsigned block_length)
2255 {
2256         const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
2257
2258         if(write_cb(block->id, 1, id_bytes, handle) != id_bytes)
2259                 return false;
2260
2261         block_length -= id_bytes;
2262
2263         if(write_cb(block->data, 1, block_length, handle) != block_length)
2264                 return false;
2265
2266         return true;
2267 }
2268
2269 FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block)
2270 {
2271         unsigned i;
2272         FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH];
2273
2274         for(i = 0; i < block->num_points; i++) {
2275                 /* some MAGIC NUMBERs here */
2276                 pack_uint64_(block->points[i].sample_number, buffer, 8);
2277                 pack_uint64_(block->points[i].stream_offset, buffer+8, 8);
2278                 pack_uint32_(block->points[i].frame_samples, buffer+16, 2);
2279                 if(write_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)
2280                         return false;
2281         }
2282
2283         return true;
2284 }
2285
2286 FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block)
2287 {
2288         unsigned i;
2289         const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8;
2290         const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8;
2291         FLAC__byte buffer[4]; /* magic number is asserted below */
2292
2293         FLAC__ASSERT(max(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN, FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8 == 4);
2294
2295         pack_uint32_little_endian_(block->vendor_string.length, buffer, entry_length_len);
2296         if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len)
2297                 return false;
2298         if(write_cb(block->vendor_string.entry, 1, block->vendor_string.length, handle) != block->vendor_string.length)
2299                 return false;
2300
2301         pack_uint32_little_endian_(block->num_comments, buffer, num_comments_len);
2302         if(write_cb(buffer, 1, num_comments_len, handle) != num_comments_len)
2303                 return false;
2304
2305         for(i = 0; i < block->num_comments; i++) {
2306                 pack_uint32_little_endian_(block->comments[i].length, buffer, entry_length_len);
2307                 if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len)
2308                         return false;
2309                 if(write_cb(block->comments[i].entry, 1, block->comments[i].length, handle) != block->comments[i].length)
2310                         return false;
2311         }
2312
2313         return true;
2314 }
2315
2316 FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block)
2317 {
2318         unsigned i, j, len;
2319         FLAC__byte buffer[1024]; /* asserted below that this is big enough */
2320
2321         FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64));
2322         FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN/8);
2323         FLAC__ASSERT(sizeof(buffer) >= (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)/8);
2324         FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8);
2325
2326         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0);
2327         len = FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8;
2328         if(write_cb(block->media_catalog_number, 1, len, handle) != len)
2329                 return false;
2330
2331         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN % 8 == 0);
2332         len = FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN / 8;
2333         pack_uint64_(block->lead_in, buffer, len);
2334         if(write_cb(buffer, 1, len, handle) != len)
2335                 return false;
2336
2337         FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) % 8 == 0);
2338         len = (FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) / 8;
2339         memset(buffer, 0, len);
2340         if(block->is_cd)
2341                 buffer[0] |= 0x80;
2342         if(write_cb(buffer, 1, len, handle) != len)
2343                 return false;
2344
2345         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN % 8 == 0);
2346         len = FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN / 8;
2347         pack_uint32_(block->num_tracks, buffer, len);
2348         if(write_cb(buffer, 1, len, handle) != len)
2349                 return false;
2350
2351         for(i = 0; i < block->num_tracks; i++) {
2352                 FLAC__StreamMetadata_CueSheet_Track *track = block->tracks + i;
2353
2354                 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0);
2355                 len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8;
2356                 pack_uint64_(track->offset, buffer, len);
2357                 if(write_cb(buffer, 1, len, handle) != len)
2358                         return false;
2359
2360                 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0);
2361                 len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8;
2362                 pack_uint32_(track->number, buffer, len);
2363                 if(write_cb(buffer, 1, len, handle) != len)
2364                         return false;
2365
2366                 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0);
2367                 len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8;
2368                 if(write_cb(track->isrc, 1, len, handle) != len)
2369                         return false;
2370
2371                 FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) % 8 == 0);
2372                 len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8;
2373                 memset(buffer, 0, len);
2374                 buffer[0] = (track->type << 7) | (track->pre_emphasis << 6);
2375                 if(write_cb(buffer, 1, len, handle) != len)
2376                         return false;
2377
2378                 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN % 8 == 0);
2379                 len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN / 8;
2380                 pack_uint32_(track->num_indices, buffer, len);
2381                 if(write_cb(buffer, 1, len, handle) != len)
2382                         return false;
2383
2384                 for(j = 0; j < track->num_indices; j++) {
2385                         FLAC__StreamMetadata_CueSheet_Index *index = track->indices + j;
2386
2387                         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN % 8 == 0);
2388                         len = FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN / 8;
2389                         pack_uint64_(index->offset, buffer, len);
2390                         if(write_cb(buffer, 1, len, handle) != len)
2391                                 return false;
2392
2393                         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN % 8 == 0);
2394                         len = FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN / 8;
2395                         pack_uint32_(index->number, buffer, len);
2396                         if(write_cb(buffer, 1, len, handle) != len)
2397                                 return false;
2398
2399                         FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN % 8 == 0);
2400                         len = FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN / 8;
2401                         memset(buffer, 0, len);
2402                         if(write_cb(buffer, 1, len, handle) != len)
2403                                 return false;
2404                 }
2405         }
2406
2407         return true;
2408 }
2409
2410 FLAC__bool write_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Unknown *block, unsigned block_length)
2411 {
2412         if(write_cb(block->data, 1, block_length, handle) != block_length)
2413                 return false;
2414
2415         return true;
2416 }
2417
2418 FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block)
2419 {
2420         if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2421                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2422                 return false;
2423         }
2424
2425         if(!write_metadata_block_header_(iterator->file, &iterator->status, block))
2426                 return false;
2427
2428         if(!write_metadata_block_data_(iterator->file, &iterator->status, block))
2429                 return false;
2430
2431         if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2432                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2433                 return false;
2434         }
2435
2436         return read_metadata_block_header_(iterator);
2437 }
2438
2439 FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last)
2440 {
2441         FLAC__StreamMetadata *padding;
2442
2443         if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2444                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2445                 return false;
2446         }
2447
2448         block->is_last = false;
2449
2450         if(!write_metadata_block_header_(iterator->file, &iterator->status, block))
2451                 return false;
2452
2453         if(!write_metadata_block_data_(iterator->file, &iterator->status, block))
2454                 return false;
2455
2456         if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
2457                 return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
2458
2459         padding->is_last = padding_is_last;
2460         padding->length = padding_length;
2461
2462         if(!write_metadata_block_header_(iterator->file, &iterator->status, padding)) {
2463                 FLAC__metadata_object_delete(padding);
2464                 return false;
2465         }
2466
2467         if(!write_metadata_block_data_(iterator->file, &iterator->status, padding)) {
2468                 FLAC__metadata_object_delete(padding);
2469                 return false;
2470         }
2471
2472         FLAC__metadata_object_delete(padding);
2473
2474         if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2475                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2476                 return false;
2477         }
2478
2479         return read_metadata_block_header_(iterator);
2480 }
2481
2482 FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append)
2483 {
2484         FILE *tempfile;
2485         char *tempfilename;
2486         int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */
2487         off_t fixup_is_last_flag_offset = -1;
2488
2489         FLAC__ASSERT(0 != block || append == false);
2490
2491         if(iterator->is_last) {
2492                 if(append) {
2493                         fixup_is_last_code = 1; /* 1 => clear the is_last flag at the following offset */
2494                         fixup_is_last_flag_offset = iterator->offset[iterator->depth];
2495                 }
2496                 else if(0 == block) {
2497                         simple_iterator_push_(iterator);
2498                         if(!FLAC__metadata_simple_iterator_prev(iterator)) {
2499                                 (void)simple_iterator_pop_(iterator);
2500                                 return false;
2501                         }
2502                         fixup_is_last_code = -1; /* -1 => set the is_last the flag at the following offset */
2503                         fixup_is_last_flag_offset = iterator->offset[iterator->depth];
2504                         if(!simple_iterator_pop_(iterator))
2505                                 return false;
2506                 }
2507         }
2508
2509         if(!simple_iterator_copy_file_prefix_(iterator, &tempfile, &tempfilename, append))
2510                 return false;
2511
2512         if(0 != block) {
2513                 if(!write_metadata_block_header_(tempfile, &iterator->status, block)) {
2514                         cleanup_tempfile_(&tempfile, &tempfilename);
2515                         return false;
2516                 }
2517
2518                 if(!write_metadata_block_data_(tempfile, &iterator->status, block)) {
2519                         cleanup_tempfile_(&tempfile, &tempfilename);
2520                         return false;
2521                 }
2522         }
2523
2524         if(!simple_iterator_copy_file_postfix_(iterator, &tempfile, &tempfilename, fixup_is_last_code, fixup_is_last_flag_offset, block==0))
2525                 return false;
2526
2527         if(append)
2528                 return FLAC__metadata_simple_iterator_next(iterator);
2529
2530         return true;
2531 }
2532
2533 void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator)
2534 {
2535         FLAC__ASSERT(iterator->depth+1 < SIMPLE_ITERATOR_MAX_PUSH_DEPTH);
2536         iterator->offset[iterator->depth+1] = iterator->offset[iterator->depth];
2537         iterator->depth++;
2538 }
2539
2540 FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator)
2541 {
2542         FLAC__ASSERT(iterator->depth > 0);
2543         iterator->depth--;
2544         if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
2545                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2546                 return false;
2547         }
2548
2549         return read_metadata_block_header_(iterator);
2550 }
2551
2552 /* return meanings:
2553  * 0: ok
2554  * 1: read error
2555  * 2: seek error
2556  * 3: not a FLAC file
2557  */
2558 unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb)
2559 {
2560         FLAC__byte buffer[4];
2561         size_t n;
2562         unsigned i;
2563
2564         FLAC__ASSERT(FLAC__STREAM_SYNC_LENGTH == 4);
2565
2566         /* skip any id3v2 tag */
2567         errno = 0;
2568         n = read_cb(buffer, 1, 4, handle);
2569         if(errno)
2570                 return 1;
2571         else if(n != 4)
2572                 return 3;
2573         else if(0 == memcmp(buffer, "ID3", 3)) {
2574                 unsigned tag_length = 0;
2575
2576                 /* skip to the tag length */
2577                 if(seek_cb(handle, 2, SEEK_CUR) < 0)
2578                         return 2;
2579
2580                 /* read the length */
2581                 for(i = 0; i < 4; i++) {
2582                         if(read_cb(buffer, 1, 1, handle) < 1 || buffer[0] & 0x80)
2583                                 return 1;
2584                         tag_length <<= 7;
2585                         tag_length |= (buffer[0] & 0x7f);
2586                 }
2587
2588                 /* skip the rest of the tag */
2589                 if(seek_cb(handle, tag_length, SEEK_CUR) < 0)
2590                         return 2;
2591
2592                 /* read the stream sync code */
2593                 errno = 0;
2594                 n = read_cb(buffer, 1, 4, handle);
2595                 if(errno)
2596                         return 1;
2597                 else if(n != 4)
2598                         return 3;
2599         }
2600
2601         /* check for the fLaC signature */
2602         if(0 == memcmp(FLAC__STREAM_SYNC_STRING, buffer, FLAC__STREAM_SYNC_LENGTH))
2603                 return 0;
2604         else
2605                 return 3;
2606 }
2607
2608 unsigned seek_to_first_metadata_block_(FILE *f)
2609 {
2610         return seek_to_first_metadata_block_cb_((FLAC__IOHandle)f, (FLAC__IOCallback_Read)fread, fseek_wrapper_);
2611 }
2612
2613 FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append)
2614 {
2615         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];
2616
2617         if(0 != fseeko(iterator->file, 0, SEEK_SET)) {
2618                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2619                 return false;
2620         }
2621         if(!open_tempfile_(iterator->filename, iterator->tempfile_path_prefix, tempfile, tempfilename, &iterator->status)) {
2622                 cleanup_tempfile_(tempfile, tempfilename);
2623                 return false;
2624         }
2625         if(!copy_n_bytes_from_file_(iterator->file, *tempfile, offset_end, &iterator->status)) {
2626                 cleanup_tempfile_(tempfile, tempfilename);
2627                 return false;
2628         }
2629
2630         return true;
2631 }
2632
2633 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)
2634 {
2635         off_t save_offset = iterator->offset[iterator->depth];
2636         FLAC__ASSERT(0 != *tempfile);
2637
2638         if(0 != fseeko(iterator->file, save_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length, SEEK_SET)) {
2639                 cleanup_tempfile_(tempfile, tempfilename);
2640                 iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2641                 return false;
2642         }
2643         if(!copy_remaining_bytes_from_file_(iterator->file, *tempfile, &iterator->status)) {
2644                 cleanup_tempfile_(tempfile, tempfilename);
2645                 return false;
2646         }
2647
2648         if(fixup_is_last_code != 0) {
2649                 /*
2650                  * if code == 1, it means a block was appended to the end so
2651                  *   we have to clear the is_last flag of the previous block
2652                  * if code == -1, it means the last block was deleted so
2653                  *   we have to set the is_last flag of the previous block
2654                  */
2655                 /* MAGIC NUMBERs here; we know the is_last flag is the high bit of the byte at this location */
2656                 FLAC__byte x;
2657                 if(0 != fseeko(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
2658                         cleanup_tempfile_(tempfile, tempfilename);
2659                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2660                         return false;
2661                 }
2662                 if(fread(&x, 1, 1, *tempfile) != 1) {
2663                         cleanup_tempfile_(tempfile, tempfilename);
2664                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2665                         return false;
2666                 }
2667                 if(fixup_is_last_code > 0) {
2668                         FLAC__ASSERT(x & 0x80);
2669                         x &= 0x7f;
2670                 }
2671                 else {
2672                         FLAC__ASSERT(!(x & 0x80));
2673                         x |= 0x80;
2674                 }
2675                 if(0 != fseeko(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
2676                         cleanup_tempfile_(tempfile, tempfilename);
2677                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
2678                         return false;
2679                 }
2680                 if(local__fwrite(&x, 1, 1, *tempfile) != 1) {
2681                         cleanup_tempfile_(tempfile, tempfilename);
2682                         iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2683                         return false;
2684                 }
2685         }
2686
2687         (void)fclose(iterator->file);
2688
2689         if(!transport_tempfile_(iterator->filename, tempfile, tempfilename, &iterator->status))
2690                 return false;
2691
2692         if(iterator->has_stats)
2693                 set_file_stats_(iterator->filename, &iterator->stats);
2694
2695         if(!simple_iterator_prime_input_(iterator, !iterator->is_writable))
2696                 return false;
2697         if(backup) {
2698                 while(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length < save_offset)
2699                         if(!FLAC__metadata_simple_iterator_next(iterator))
2700                                 return false;
2701                 return true;
2702         }
2703         else {
2704                 /* move the iterator to it's original block faster by faking a push, then doing a pop_ */
2705                 FLAC__ASSERT(iterator->depth == 0);
2706                 iterator->offset[0] = save_offset;
2707                 iterator->depth++;
2708                 return simple_iterator_pop_(iterator);
2709         }
2710 }
2711
2712 FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status)
2713 {
2714         FLAC__byte buffer[8192];
2715         size_t n;
2716
2717         while(bytes > 0) {
2718                 n = min(sizeof(buffer), bytes);
2719                 if(fread(buffer, 1, n, file) != n) {
2720                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2721                         return false;
2722                 }
2723                 if(local__fwrite(buffer, 1, n, tempfile) != n) {
2724                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2725                         return false;
2726                 }
2727                 bytes -= n;
2728         }
2729
2730         return true;
2731 }
2732
2733 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)
2734 {
2735         FLAC__byte buffer[8192];
2736         size_t n;
2737
2738         while(bytes > 0) {
2739                 n = min(sizeof(buffer), bytes);
2740                 if(read_cb(buffer, 1, n, handle) != n) {
2741                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2742                         return false;
2743                 }
2744                 if(temp_write_cb(buffer, 1, n, temp_handle) != n) {
2745                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2746                         return false;
2747                 }
2748                 bytes -= n;
2749         }
2750
2751         return true;
2752 }
2753
2754 FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status)
2755 {
2756         FLAC__byte buffer[8192];
2757         size_t n;
2758
2759         while(!feof(file)) {
2760                 n = fread(buffer, 1, sizeof(buffer), file);
2761                 if(n == 0 && !feof(file)) {
2762                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2763                         return false;
2764                 }
2765                 if(n > 0 && local__fwrite(buffer, 1, n, tempfile) != n) {
2766                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2767                         return false;
2768                 }
2769         }
2770
2771         return true;
2772 }
2773
2774 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)
2775 {
2776         FLAC__byte buffer[8192];
2777         size_t n;
2778
2779         while(!eof_cb(handle)) {
2780                 n = read_cb(buffer, 1, sizeof(buffer), handle);
2781                 if(n == 0 && !eof_cb(handle)) {
2782                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
2783                         return false;
2784                 }
2785                 if(n > 0 && temp_write_cb(buffer, 1, n, temp_handle) != n) {
2786                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
2787                         return false;
2788                 }
2789         }
2790
2791         return true;
2792 }
2793
2794 FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status)
2795 {
2796         static const char *tempfile_suffix = ".metadata_edit";
2797         if(0 == tempfile_path_prefix) {
2798                 if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) {
2799                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
2800                         return false;
2801                 }
2802                 strcpy(*tempfilename, filename);
2803                 strcat(*tempfilename, tempfile_suffix);
2804         }
2805         else {
2806                 const char *p = strrchr(filename, '/');
2807                 if(0 == p)
2808                         p = filename;
2809                 else
2810                         p++;
2811
2812                 if(0 == (*tempfilename = (char*)malloc(strlen(tempfile_path_prefix) + 1 + strlen(p) + strlen(tempfile_suffix) + 1))) {
2813                         *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
2814                         return false;
2815                 }
2816                 strcpy(*tempfilename, tempfile_path_prefix);
2817                 strcat(*tempfilename, "/");
2818                 strcat(*tempfilename, p);
2819                 strcat(*tempfilename, tempfile_suffix);
2820         }
2821
2822         if(0 == (*tempfile = fopen(*tempfilename, "w+b"))) {
2823                 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;
2824                 return false;
2825         }
2826
2827         return true;
2828 }
2829
2830 FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status)
2831 {
2832         FLAC__ASSERT(0 != filename);
2833         FLAC__ASSERT(0 != tempfile);
2834         FLAC__ASSERT(0 != *tempfile);
2835         FLAC__ASSERT(0 != tempfilename);
2836         FLAC__ASSERT(0 != *tempfilename);
2837         FLAC__ASSERT(0 != status);
2838
2839         (void)fclose(*tempfile);
2840         *tempfile = 0;
2841
2842 #if defined _MSC_VER || defined __MINGW32__ || defined __EMX__
2843         if(unlink(filename) < 0) {
2844                 cleanup_tempfile_(tempfile, tempfilename);
2845                 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR;
2846                 return false;
2847         }
2848 #endif
2849
2850         /*@@@ to fully support the tempfile_path_prefix we need to update this piece to actually copy across filesystems instead of just rename(): */
2851         if(0 != rename(*tempfilename, filename)) {
2852                 cleanup_tempfile_(tempfile, tempfilename);
2853                 *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR;
2854                 return false;
2855         }
2856
2857         cleanup_tempfile_(tempfile, tempfilename);
2858
2859         return true;
2860 }
2861
2862 void cleanup_tempfile_(FILE **tempfile, char **tempfilename)
2863 {
2864         if(0 != *tempfile) {
2865                 (void)fclose(*tempfile);
2866                 *tempfile = 0;
2867         }
2868
2869         if(0 != *tempfilename) {
2870                 (void)unlink(*tempfilename);
2871                 free(*tempfilename);
2872                 *tempfilename = 0;
2873         }
2874 }
2875
2876 FLAC__bool get_file_stats_(const char *filename, struct stat *stats)
2877 {
2878         FLAC__ASSERT(0 != filename);
2879         FLAC__ASSERT(0 != stats);
2880         return (0 == stat(filename, stats));
2881 }
2882
2883 void set_file_stats_(const char *filename, struct stat *stats)
2884 {
2885         struct utimbuf srctime;
2886
2887         FLAC__ASSERT(0 != filename);
2888         FLAC__ASSERT(0 != stats);
2889
2890         srctime.actime = stats->st_atime;
2891         srctime.modtime = stats->st_mtime;
2892         (void)chmod(filename, stats->st_mode);
2893         (void)utime(filename, &srctime);
2894 #if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
2895         (void)chown(filename, stats->st_uid, -1);
2896         (void)chown(filename, -1, stats->st_gid);
2897 #endif
2898 }
2899
2900 int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence)
2901 {
2902         return fseeko((FILE*)handle, (off_t)offset, whence);
2903 }
2904
2905 FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle)
2906 {
2907         return ftello((FILE*)handle);
2908 }
2909
2910 FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status)
2911 {
2912         switch(status) {
2913                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK:
2914                         return FLAC__METADATA_CHAIN_STATUS_OK;
2915                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT:
2916                         return FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT;
2917                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE:
2918                         return FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
2919                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE:
2920                         return FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE;
2921                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE:
2922                         return FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE;
2923                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA:
2924                         return FLAC__METADATA_CHAIN_STATUS_BAD_METADATA;
2925                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR:
2926                         return FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
2927                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR:
2928                         return FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
2929                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR:
2930                         return FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
2931                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR:
2932                         return FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR;
2933                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR:
2934                         return FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR;
2935                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR:
2936                         return FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
2937                 case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR:
2938                 default:
2939                         return FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR;
2940         }
2941 }