metadata_iterators.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:95k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* libFLAC - Free Lossless Audio Codec library
  2.  * Copyright (C) 2001,2002,2003,2004,2005  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. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include "private/metadata.h"
  35. #include "FLAC/assert.h"
  36. #include "FLAC/file_decoder.h"
  37. #ifdef max
  38. #undef max
  39. #endif
  40. #define max(a,b) ((a)>(b)?(a):(b))
  41. #ifdef min
  42. #undef min
  43. #endif
  44. #define min(a,b) ((a)<(b)?(a):(b))
  45. /****************************************************************************
  46.  *
  47.  * Local function declarations
  48.  *
  49.  ***************************************************************************/
  50. static void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes);
  51. static void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes);
  52. static void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes);
  53. static FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes);
  54. static FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes);
  55. static FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes);
  56. static FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator);
  57. static FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block);
  58. 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);
  59. 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);
  60. static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block);
  61. 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);
  62. 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);
  63. 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);
  64. 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);
  65. static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment *block);
  66. static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track);
  67. static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block);
  68. 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);
  69. static FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block);
  70. static FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block);
  71. static FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block);
  72. static FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block);
  73. static FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block);
  74. 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);
  75. 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);
  76. static FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block);
  77. static FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block);
  78. static FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block);
  79. 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);
  80. static FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block);
  81. static FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last);
  82. static FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append);
  83. static void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator);
  84. static FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator);
  85. static unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb);
  86. static unsigned seek_to_first_metadata_block_(FILE *f);
  87. static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append);
  88. static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, long fixup_is_last_flag_offset, FLAC__bool backup);
  89. static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status);
  90. 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, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status);
  91. static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status);
  92. 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);
  93. static FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status);
  94. static FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status);
  95. static void cleanup_tempfile_(FILE **tempfile, char **tempfilename);
  96. static FLAC__bool get_file_stats_(const char *filename, struct stat *stats);
  97. static void set_file_stats_(const char *filename, struct stat *stats);
  98. static int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence);
  99. static FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle);
  100. static FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status);
  101. #ifdef FLAC__VALGRIND_TESTING
  102. static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
  103. {
  104. size_t ret = fwrite(ptr, size, nmemb, stream);
  105. if(!ferror(stream))
  106. fflush(stream);
  107. return ret;
  108. }
  109. #else
  110. #define local__fwrite fwrite
  111. #endif
  112. /****************************************************************************
  113.  *
  114.  * Level 1 implementation
  115.  *
  116.  ***************************************************************************/
  117. #define SIMPLE_ITERATOR_MAX_PUSH_DEPTH (1+4)
  118. /* 1 for initial offset, +4 for our own personal use */
  119. struct FLAC__Metadata_SimpleIterator {
  120. FILE *file;
  121. char *filename, *tempfile_path_prefix;
  122. FLAC__bool is_writable;
  123. FLAC__Metadata_SimpleIteratorStatus status;
  124. /*@@@ 2G limits here because of the offset type: */
  125. long offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH];
  126. long first_offset; /* this is the offset to the STREAMINFO block */
  127. unsigned depth;
  128. /* this is the metadata block header of the current block we are pointing to: */
  129. FLAC__bool is_last;
  130. FLAC__MetadataType type;
  131. unsigned length;
  132. };
  133. FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[] = {
  134. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK",
  135. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT",
  136. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE",
  137. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE",
  138. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE",
  139. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA",
  140. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR",
  141. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR",
  142. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR",
  143. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR",
  144. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR",
  145. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR",
  146. "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR"
  147. };
  148. FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new()
  149. {
  150. FLAC__Metadata_SimpleIterator *iterator = (FLAC__Metadata_SimpleIterator*)calloc(1, sizeof(FLAC__Metadata_SimpleIterator));
  151. if(0 != iterator) {
  152. iterator->file = 0;
  153. iterator->filename = 0;
  154. iterator->tempfile_path_prefix = 0;
  155. iterator->is_writable = false;
  156. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  157. iterator->first_offset = iterator->offset[0] = -1;
  158. iterator->depth = 0;
  159. }
  160. return iterator;
  161. }
  162. static void simple_iterator_free_guts_(FLAC__Metadata_SimpleIterator *iterator)
  163. {
  164. FLAC__ASSERT(0 != iterator);
  165. if(0 != iterator->file) {
  166. fclose(iterator->file);
  167. iterator->file = 0;
  168. }
  169. if(0 != iterator->filename) {
  170. free(iterator->filename);
  171. iterator->filename = 0;
  172. }
  173. if(0 != iterator->tempfile_path_prefix) {
  174. free(iterator->tempfile_path_prefix);
  175. iterator->tempfile_path_prefix = 0;
  176. }
  177. }
  178. FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator)
  179. {
  180. FLAC__ASSERT(0 != iterator);
  181. simple_iterator_free_guts_(iterator);
  182. free(iterator);
  183. }
  184. FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator)
  185. {
  186. FLAC__Metadata_SimpleIteratorStatus status;
  187. FLAC__ASSERT(0 != iterator);
  188. status = iterator->status;
  189. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  190. return status;
  191. }
  192. static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool read_only)
  193. {
  194. unsigned ret;
  195. FLAC__ASSERT(0 != iterator);
  196. if(read_only || 0 == (iterator->file = fopen(iterator->filename, "r+b"))) {
  197. iterator->is_writable = false;
  198. if(read_only) {
  199. if(0 == (iterator->file = fopen(iterator->filename, "rb"))) {
  200. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;
  201. return false;
  202. }
  203. }
  204. else {
  205. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;
  206. return false;
  207. }
  208. }
  209. else {
  210. iterator->is_writable = true;
  211. }
  212. ret = seek_to_first_metadata_block_(iterator->file);
  213. switch(ret) {
  214. case 0:
  215. iterator->depth = 0;
  216. iterator->first_offset = iterator->offset[iterator->depth] = ftell(iterator->file);
  217. return read_metadata_block_header_(iterator);
  218. case 1:
  219. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  220. return false;
  221. case 2:
  222. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  223. return false;
  224. case 3:
  225. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE;
  226. return false;
  227. default:
  228. FLAC__ASSERT(0);
  229. return false;
  230. }
  231. }
  232. #if 0
  233. @@@ If we decide to finish implementing this, put this comment back in metadata.h
  234. /*
  235.  * The 'tempfile_path_prefix' allows you to specify a directory where
  236.  * tempfiles should go.  Remember that if your metadata edits cause the
  237.  * FLAC file to grow, the entire file will have to be rewritten.  If
  238.  * 'tempfile_path_prefix' is NULL, the temp file will be written in the
  239.  * same directory as the original FLAC file.  This makes replacing the
  240.  * original with the tempfile fast but requires extra space in the same
  241.  * partition for the tempfile.  If space is a problem, you can pass a
  242.  * directory name belonging to a different partition in
  243.  * 'tempfile_path_prefix'.  Note that you should use the forward slash
  244.  * '/' as the directory separator.  A trailing slash is not needed; it
  245.  * will be added automatically.
  246.  */
  247. FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool preserve_file_stats, const char *tempfile_path_prefix);
  248. #endif
  249. 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)
  250. {
  251. const char *tempfile_path_prefix = 0; /*@@@ search for comments near 'rename(...)' for what it will take to finish implementing this */
  252. FLAC__ASSERT(0 != iterator);
  253. FLAC__ASSERT(0 != filename);
  254. simple_iterator_free_guts_(iterator);
  255. if(0 == (iterator->filename = _strdup(filename))) {
  256. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  257. return false;
  258. }
  259. if(0 != tempfile_path_prefix && 0 == (iterator->tempfile_path_prefix = _strdup(tempfile_path_prefix))) {
  260. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  261. return false;
  262. }
  263. return simple_iterator_prime_input_(iterator, read_only);
  264. }
  265. FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator)
  266. {
  267. FLAC__ASSERT(0 != iterator);
  268. FLAC__ASSERT(0 != iterator->file);
  269. return iterator->is_writable;
  270. }
  271. FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator)
  272. {
  273. FLAC__ASSERT(0 != iterator);
  274. FLAC__ASSERT(0 != iterator->file);
  275. if(iterator->is_last)
  276. return false;
  277. if(0 != fseek(iterator->file, iterator->length, SEEK_CUR)) {
  278. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  279. return false;
  280. }
  281. iterator->offset[iterator->depth] = ftell(iterator->file);
  282. return read_metadata_block_header_(iterator);
  283. }
  284. FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator)
  285. {
  286. long this_offset;
  287. FLAC__ASSERT(0 != iterator);
  288. FLAC__ASSERT(0 != iterator->file);
  289. if(iterator->offset[iterator->depth] == iterator->first_offset)
  290. return false;
  291. if(0 != fseek(iterator->file, iterator->first_offset, SEEK_SET)) {
  292. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  293. return false;
  294. }
  295. this_offset = iterator->first_offset;
  296. if(!read_metadata_block_header_(iterator))
  297. return false;
  298. /* we ignore any error from ftell() and catch it in fseek() */
  299. while(ftell(iterator->file) + (long)iterator->length < iterator->offset[iterator->depth]) {
  300. if(0 != fseek(iterator->file, iterator->length, SEEK_CUR)) {
  301. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  302. return false;
  303. }
  304. this_offset = ftell(iterator->file);
  305. if(!read_metadata_block_header_(iterator))
  306. return false;
  307. }
  308. iterator->offset[iterator->depth] = this_offset;
  309. return true;
  310. }
  311. FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator)
  312. {
  313. FLAC__ASSERT(0 != iterator);
  314. FLAC__ASSERT(0 != iterator->file);
  315. return iterator->type;
  316. }
  317. FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator)
  318. {
  319. FLAC__StreamMetadata *block = FLAC__metadata_object_new(iterator->type);
  320. FLAC__ASSERT(0 != iterator);
  321. FLAC__ASSERT(0 != iterator->file);
  322. if(0 != block) {
  323. block->is_last = iterator->is_last;
  324. block->length = iterator->length;
  325. if(!read_metadata_block_data_(iterator, block)) {
  326. FLAC__metadata_object_delete(block);
  327. return 0;
  328. }
  329. /* back up to the beginning of the block data to stay consistent */
  330. if(0 != fseek(iterator->file, iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH, SEEK_SET)) {
  331. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  332. FLAC__metadata_object_delete(block);
  333. return 0;
  334. }
  335. }
  336. else
  337. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  338. return block;
  339. }
  340. FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding)
  341. {
  342. FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth];)
  343. FLAC__bool ret;
  344. FLAC__ASSERT(0 != iterator);
  345. FLAC__ASSERT(0 != iterator->file);
  346. FLAC__ASSERT(0 != block);
  347. if(!iterator->is_writable) {
  348. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE;
  349. return false;
  350. }
  351. if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO || block->type == FLAC__METADATA_TYPE_STREAMINFO) {
  352. if(iterator->type != block->type) {
  353. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT;
  354. return false;
  355. }
  356. }
  357. block->is_last = iterator->is_last;
  358. if(iterator->length == block->length)
  359. return write_metadata_block_stationary_(iterator, block);
  360. else if(iterator->length > block->length) {
  361. if(use_padding && iterator->length >= FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) {
  362. ret = write_metadata_block_stationary_with_padding_(iterator, block, iterator->length - FLAC__STREAM_METADATA_HEADER_LENGTH - block->length, block->is_last);
  363. FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
  364. FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
  365. return ret;
  366. }
  367. else {
  368. ret = rewrite_whole_file_(iterator, block, /*append=*/false);
  369. FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
  370. FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
  371. return ret;
  372. }
  373. }
  374. else /* iterator->length < block->length */ {
  375. unsigned padding_leftover = 0;
  376. FLAC__bool padding_is_last = false;
  377. if(use_padding) {
  378. /* first see if we can even use padding */
  379. if(iterator->is_last) {
  380. use_padding = false;
  381. }
  382. else {
  383. const unsigned extra_padding_bytes_required = block->length - iterator->length;
  384. simple_iterator_push_(iterator);
  385. if(!FLAC__metadata_simple_iterator_next(iterator)) {
  386. (void)simple_iterator_pop_(iterator);
  387. return false;
  388. }
  389. if(iterator->type != FLAC__METADATA_TYPE_PADDING) {
  390. use_padding = false;
  391. }
  392. else {
  393. if(FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length == extra_padding_bytes_required) {
  394. padding_leftover = 0;
  395. block->is_last = iterator->is_last;
  396. }
  397. else if(iterator->length < extra_padding_bytes_required)
  398. use_padding = false;
  399. else {
  400. padding_leftover = FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length - extra_padding_bytes_required;
  401. padding_is_last = iterator->is_last;
  402. block->is_last = false;
  403. }
  404. }
  405. if(!simple_iterator_pop_(iterator))
  406. return false;
  407. }
  408. }
  409. if(use_padding) {
  410. if(padding_leftover == 0) {
  411. ret = write_metadata_block_stationary_(iterator, block);
  412. FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
  413. FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
  414. return ret;
  415. }
  416. else {
  417. FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH);
  418. ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last);
  419. FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
  420. FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
  421. return ret;
  422. }
  423. }
  424. else {
  425. ret = rewrite_whole_file_(iterator, block, /*append=*/false);
  426. FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset);
  427. FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
  428. return ret;
  429. }
  430. }
  431. }
  432. FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding)
  433. {
  434. unsigned padding_leftover = 0;
  435. FLAC__bool padding_is_last = false;
  436. FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length;)
  437. FLAC__bool ret;
  438. FLAC__ASSERT(0 != iterator);
  439. FLAC__ASSERT(0 != iterator->file);
  440. FLAC__ASSERT(0 != block);
  441. if(!iterator->is_writable)
  442. return false;
  443. if(block->type == FLAC__METADATA_TYPE_STREAMINFO) {
  444. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT;
  445. return false;
  446. }
  447. block->is_last = iterator->is_last;
  448. if(use_padding) {
  449. /* first see if we can even use padding */
  450. if(iterator->is_last) {
  451. use_padding = false;
  452. }
  453. else {
  454. simple_iterator_push_(iterator);
  455. if(!FLAC__metadata_simple_iterator_next(iterator)) {
  456. (void)simple_iterator_pop_(iterator);
  457. return false;
  458. }
  459. if(iterator->type != FLAC__METADATA_TYPE_PADDING) {
  460. use_padding = false;
  461. }
  462. else {
  463. if(iterator->length == block->length) {
  464. padding_leftover = 0;
  465. block->is_last = iterator->is_last;
  466. }
  467. else if(iterator->length < FLAC__STREAM_METADATA_HEADER_LENGTH + block->length)
  468. use_padding = false;
  469. else {
  470. padding_leftover = iterator->length - block->length;
  471. padding_is_last = iterator->is_last;
  472. block->is_last = false;
  473. }
  474. }
  475. if(!simple_iterator_pop_(iterator))
  476. return false;
  477. }
  478. }
  479. if(use_padding) {
  480. /* move to the next block, which is suitable padding */
  481. if(!FLAC__metadata_simple_iterator_next(iterator))
  482. return false;
  483. if(padding_leftover == 0) {
  484. ret = write_metadata_block_stationary_(iterator, block);
  485. FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
  486. FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
  487. return ret;
  488. }
  489. else {
  490. FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH);
  491. ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last);
  492. FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
  493. FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
  494. return ret;
  495. }
  496. }
  497. else {
  498. ret = rewrite_whole_file_(iterator, block, /*append=*/true);
  499. FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
  500. FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH);
  501. return ret;
  502. }
  503. }
  504. FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding)
  505. {
  506. FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth];)
  507. FLAC__bool ret;
  508. if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO) {
  509. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT;
  510. return false;
  511. }
  512. if(use_padding) {
  513. FLAC__StreamMetadata *padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
  514. if(0 == padding) {
  515. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  516. return false;
  517. }
  518. padding->length = iterator->length;
  519. if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false)) {
  520. FLAC__metadata_object_delete(padding);
  521. return false;
  522. }
  523. FLAC__metadata_object_delete(padding);
  524. if(!FLAC__metadata_simple_iterator_prev(iterator))
  525. return false;
  526. FLAC__ASSERT(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length == debug_target_offset);
  527. FLAC__ASSERT(ftell(iterator->file) + (long)iterator->length == debug_target_offset);
  528. return true;
  529. }
  530. else {
  531. ret = rewrite_whole_file_(iterator, 0, /*append=*/false);
  532. FLAC__ASSERT(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length == debug_target_offset);
  533. FLAC__ASSERT(ftell(iterator->file) + (long)iterator->length == debug_target_offset);
  534. return ret;
  535. }
  536. }
  537. /****************************************************************************
  538.  *
  539.  * Level 2 implementation
  540.  *
  541.  ***************************************************************************/
  542. typedef struct FLAC__Metadata_Node {
  543. FLAC__StreamMetadata *data;
  544. struct FLAC__Metadata_Node *prev, *next;
  545. } FLAC__Metadata_Node;
  546. struct FLAC__Metadata_Chain {
  547. char *filename; /* will be NULL if using callbacks */
  548. FLAC__Metadata_Node *head;
  549. FLAC__Metadata_Node *tail;
  550. unsigned nodes;
  551. FLAC__Metadata_ChainStatus status;
  552. long first_offset, last_offset; /*@@@ 2G limit */
  553. /*
  554.  * This is the length of the chain initially read from the FLAC file.
  555.  * it is used to compare against the current length to decide whether
  556.  * or not the whole file has to be rewritten.
  557.  */
  558. unsigned initial_length; /*@@@ 4G limit */
  559. };
  560. struct FLAC__Metadata_Iterator {
  561. FLAC__Metadata_Chain *chain;
  562. FLAC__Metadata_Node *current;
  563. };
  564. FLAC_API const char * const FLAC__Metadata_ChainStatusString[] = {
  565. "FLAC__METADATA_CHAIN_STATUS_OK",
  566. "FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT",
  567. "FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE",
  568. "FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE",
  569. "FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE",
  570. "FLAC__METADATA_CHAIN_STATUS_BAD_METADATA",
  571. "FLAC__METADATA_CHAIN_STATUS_READ_ERROR",
  572. "FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR",
  573. "FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR",
  574. "FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR",
  575. "FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR",
  576. "FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR",
  577. "FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR",
  578. "FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS",
  579. "FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH",
  580. "FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL"
  581. };
  582. static FLAC__Metadata_Node *node_new_()
  583. {
  584. return (FLAC__Metadata_Node*)calloc(1, sizeof(FLAC__Metadata_Node));
  585. }
  586. static void node_delete_(FLAC__Metadata_Node *node)
  587. {
  588. FLAC__ASSERT(0 != node);
  589. if(0 != node->data)
  590. FLAC__metadata_object_delete(node->data);
  591. free(node);
  592. }
  593. static void chain_init_(FLAC__Metadata_Chain *chain)
  594. {
  595. FLAC__ASSERT(0 != chain);
  596. chain->filename = 0;
  597. chain->head = chain->tail = 0;
  598. chain->nodes = 0;
  599. chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
  600. chain->initial_length = 0;
  601. }
  602. static void chain_clear_(FLAC__Metadata_Chain *chain)
  603. {
  604. FLAC__Metadata_Node *node, *next;
  605. FLAC__ASSERT(0 != chain);
  606. for(node = chain->head; node; ) {
  607. next = node->next;
  608. node_delete_(node);
  609. node = next;
  610. }
  611. if(0 != chain->filename)
  612. free(chain->filename);
  613. chain_init_(chain);
  614. }
  615. static void chain_append_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
  616. {
  617. FLAC__ASSERT(0 != chain);
  618. FLAC__ASSERT(0 != node);
  619. FLAC__ASSERT(0 != node->data);
  620. node->next = node->prev = 0;
  621. node->data->is_last = true;
  622. if(0 != chain->tail)
  623. chain->tail->data->is_last = false;
  624. if(0 == chain->head)
  625. chain->head = node;
  626. else {
  627. FLAC__ASSERT(0 != chain->tail);
  628. chain->tail->next = node;
  629. node->prev = chain->tail;
  630. }
  631. chain->tail = node;
  632. chain->nodes++;
  633. }
  634. static void chain_remove_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
  635. {
  636. FLAC__ASSERT(0 != chain);
  637. FLAC__ASSERT(0 != node);
  638. if(node == chain->head)
  639. chain->head = node->next;
  640. else
  641. node->prev->next = node->next;
  642. if(node == chain->tail)
  643. chain->tail = node->prev;
  644. else
  645. node->next->prev = node->prev;
  646. if(0 != chain->tail)
  647. chain->tail->data->is_last = true;
  648. chain->nodes--;
  649. }
  650. static void chain_delete_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
  651. {
  652. chain_remove_node_(chain, node);
  653. node_delete_(node);
  654. }
  655. static unsigned chain_calculate_length_(FLAC__Metadata_Chain *chain)
  656. {
  657. const FLAC__Metadata_Node *node;
  658. unsigned length = 0;
  659. for(node = chain->head; node; node = node->next)
  660. length += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);
  661. return length;
  662. }
  663. static void iterator_insert_node_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node)
  664. {
  665. FLAC__ASSERT(0 != node);
  666. FLAC__ASSERT(0 != node->data);
  667. FLAC__ASSERT(0 != iterator);
  668. FLAC__ASSERT(0 != iterator->current);
  669. FLAC__ASSERT(0 != iterator->chain);
  670. FLAC__ASSERT(0 != iterator->chain->head);
  671. FLAC__ASSERT(0 != iterator->chain->tail);
  672. node->data->is_last = false;
  673. node->prev = iterator->current->prev;
  674. node->next = iterator->current;
  675. if(0 == node->prev)
  676. iterator->chain->head = node;
  677. else
  678. node->prev->next = node;
  679. iterator->current->prev = node;
  680. iterator->chain->nodes++;
  681. }
  682. static void iterator_insert_node_after_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node)
  683. {
  684. FLAC__ASSERT(0 != node);
  685. FLAC__ASSERT(0 != node->data);
  686. FLAC__ASSERT(0 != iterator);
  687. FLAC__ASSERT(0 != iterator->current);
  688. FLAC__ASSERT(0 != iterator->chain);
  689. FLAC__ASSERT(0 != iterator->chain->head);
  690. FLAC__ASSERT(0 != iterator->chain->tail);
  691. iterator->current->data->is_last = false;
  692. node->prev = iterator->current;
  693. node->next = iterator->current->next;
  694. if(0 == node->next)
  695. iterator->chain->tail = node;
  696. else
  697. node->next->prev = node;
  698. node->prev->next = node;
  699. iterator->chain->tail->data->is_last = true;
  700. iterator->chain->nodes++;
  701. }
  702. /* return true iff node and node->next are both padding */
  703. static FLAC__bool chain_merge_adjacent_padding_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
  704. {
  705. if(node->data->type == FLAC__METADATA_TYPE_PADDING && 0 != node->next && node->next->data->type == FLAC__METADATA_TYPE_PADDING) {
  706. const unsigned growth = FLAC__STREAM_METADATA_HEADER_LENGTH + node->next->data->length;
  707. node->data->length += growth;
  708. chain_delete_node_(chain, node->next);
  709. return true;
  710. }
  711. else
  712. return false;
  713. }
  714. /* Returns the new length of the chain, or 0 if there was an error. */
  715. /* WATCHOUT: This can get called multiple times before a write, so
  716.  * it should still work when this happens.
  717.  */
  718. /* WATCHOUT: Make sure to also update the logic in
  719.  * FLAC__metadata_chain_check_if_tempfile_needed() if the logic here changes.
  720.  */
  721. static unsigned chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding)
  722. {
  723. unsigned current_length = chain_calculate_length_(chain);
  724. if(use_padding) {
  725. /* if the metadata shrank and the last block is padding, we just extend the last padding block */
  726. if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
  727. const unsigned delta = chain->initial_length - current_length;
  728. chain->tail->data->length += delta;
  729. current_length += delta;
  730. FLAC__ASSERT(current_length == chain->initial_length);
  731. }
  732. /* if the metadata shrank more than 4 bytes then there's room to add another padding block */
  733. else if(current_length + FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) {
  734. FLAC__StreamMetadata *padding;
  735. FLAC__Metadata_Node *node;
  736. if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) {
  737. chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
  738. return 0;
  739. }
  740. padding->length = chain->initial_length - (FLAC__STREAM_METADATA_HEADER_LENGTH + current_length);
  741. if(0 == (node = node_new_())) {
  742. FLAC__metadata_object_delete(padding);
  743. chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
  744. return 0;
  745. }
  746. node->data = padding;
  747. chain_append_node_(chain, node);
  748. current_length = chain_calculate_length_(chain);
  749. FLAC__ASSERT(current_length == chain->initial_length);
  750. }
  751. /* 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 */
  752. else if(current_length > chain->initial_length) {
  753. const unsigned delta = current_length - chain->initial_length;
  754. if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
  755. /* if the delta is exactly the size of the last padding block, remove the padding block */
  756. if(chain->tail->data->length + FLAC__STREAM_METADATA_HEADER_LENGTH == delta) {
  757. chain_delete_node_(chain, chain->tail);
  758. current_length = chain_calculate_length_(chain);
  759. FLAC__ASSERT(current_length == chain->initial_length);
  760. }
  761. /* if there is at least 'delta' bytes of padding, trim the padding down */
  762. else if(chain->tail->data->length >= delta) {
  763. chain->tail->data->length -= delta;
  764. current_length -= delta;
  765. FLAC__ASSERT(current_length == chain->initial_length);
  766. }
  767. }
  768. }
  769. }
  770. return current_length;
  771. }
  772. 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)
  773. {
  774. FLAC__Metadata_Node *node;
  775. FLAC__ASSERT(0 != chain);
  776. /* we assume we're already at the beginning of the file */
  777. switch(seek_to_first_metadata_block_cb_(handle, read_cb, seek_cb)) {
  778. case 0:
  779. break;
  780. case 1:
  781. chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
  782. return false;
  783. case 2:
  784. chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
  785. return false;
  786. case 3:
  787. chain->status = FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE;
  788. return false;
  789. default:
  790. FLAC__ASSERT(0);
  791. return false;
  792. }
  793. {
  794. FLAC__int64 pos = tell_cb(handle);
  795. if(pos < 0) {
  796. chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
  797. return false;
  798. }
  799. chain->first_offset = (long)pos;
  800. }
  801. {
  802. FLAC__bool is_last;
  803. FLAC__MetadataType type;
  804. unsigned length;
  805. do {
  806. node = node_new_();
  807. if(0 == node) {
  808. chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
  809. return false;
  810. }
  811. if(!read_metadata_block_header_cb_(handle, read_cb, &is_last, &type, &length)) {
  812. chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
  813. return false;
  814. }
  815. node->data = FLAC__metadata_object_new(type);
  816. if(0 == node->data) {
  817. node_delete_(node);
  818. chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
  819. return false;
  820. }
  821. node->data->is_last = is_last;
  822. node->data->length = length;
  823. chain->status = get_equivalent_status_(read_metadata_block_data_cb_(handle, read_cb, seek_cb, node->data));
  824. if(chain->status != FLAC__METADATA_CHAIN_STATUS_OK) {
  825. node_delete_(node);
  826. return false;
  827. }
  828. chain_append_node_(chain, node);
  829. } while(!is_last);
  830. }
  831. {
  832. FLAC__int64 pos = tell_cb(handle);
  833. if(pos < 0) {
  834. chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
  835. return false;
  836. }
  837. chain->last_offset = (long)pos;
  838. }
  839. chain->initial_length = chain_calculate_length_(chain);
  840. return true;
  841. }
  842. 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)
  843. {
  844. FLAC__Metadata_Node *node;
  845. FLAC__ASSERT(0 != chain);
  846. FLAC__ASSERT(0 != chain->head);
  847. if(0 != seek_cb(handle, chain->first_offset, SEEK_SET)) {
  848. chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
  849. return false;
  850. }
  851. for(node = chain->head; node; node = node->next) {
  852. if(!write_metadata_block_header_cb_(handle, write_cb, node->data)) {
  853. chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
  854. return false;
  855. }
  856. if(!write_metadata_block_data_cb_(handle, write_cb, node->data)) {
  857. chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
  858. return false;
  859. }
  860. }
  861. /*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/
  862. chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
  863. return true;
  864. }
  865. static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain)
  866. {
  867. FILE *file;
  868. FLAC__bool ret;
  869. FLAC__ASSERT(0 != chain->filename);
  870. if(0 == (file = fopen(chain->filename, "r+b"))) {
  871. chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
  872. return false;
  873. }
  874. /* chain_rewrite_metadata_in_place_cb_() sets chain->status for us */
  875. ret = chain_rewrite_metadata_in_place_cb_(chain, (FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, fseek_wrapper_);
  876. fclose(file);
  877. return ret;
  878. }
  879. static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix)
  880. {
  881. FILE *f, *tempfile;
  882. char *tempfilename;
  883. FLAC__Metadata_SimpleIteratorStatus status;
  884. const FLAC__Metadata_Node *node;
  885. FLAC__ASSERT(0 != chain);
  886. FLAC__ASSERT(0 != chain->filename);
  887. FLAC__ASSERT(0 != chain->head);
  888. /* copy the file prefix (data up to first metadata block */
  889. if(0 == (f = fopen(chain->filename, "rb"))) {
  890. chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
  891. return false;
  892. }
  893. if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) {
  894. chain->status = get_equivalent_status_(status);
  895. cleanup_tempfile_(&tempfile, &tempfilename);
  896. return false;
  897. }
  898. if(!copy_n_bytes_from_file_(f, tempfile, chain->first_offset, &status)) {
  899. chain->status = get_equivalent_status_(status);
  900. cleanup_tempfile_(&tempfile, &tempfilename);
  901. return false;
  902. }
  903. /* write the metadata */
  904. for(node = chain->head; node; node = node->next) {
  905. if(!write_metadata_block_header_(tempfile, &status, node->data)) {
  906. chain->status = get_equivalent_status_(status);
  907. return false;
  908. }
  909. if(!write_metadata_block_data_(tempfile, &status, node->data)) {
  910. chain->status = get_equivalent_status_(status);
  911. return false;
  912. }
  913. }
  914. /*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/
  915. /* copy the file postfix (everything after the metadata) */
  916. if(0 != fseek(f, chain->last_offset, SEEK_SET)) {
  917. cleanup_tempfile_(&tempfile, &tempfilename);
  918. chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
  919. return false;
  920. }
  921. if(!copy_remaining_bytes_from_file_(f, tempfile, &status)) {
  922. cleanup_tempfile_(&tempfile, &tempfilename);
  923. chain->status = get_equivalent_status_(status);
  924. return false;
  925. }
  926. /* move the tempfile on top of the original */
  927. (void)fclose(f);
  928. if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status))
  929. return false;
  930. return true;
  931. }
  932. /* assumes 'handle' is already at beginning of file */
  933. 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)
  934. {
  935. FLAC__Metadata_SimpleIteratorStatus status;
  936. const FLAC__Metadata_Node *node;
  937. FLAC__ASSERT(0 != chain);
  938. FLAC__ASSERT(0 == chain->filename);
  939. FLAC__ASSERT(0 != chain->head);
  940. /* copy the file prefix (data up to first metadata block */
  941. if(!copy_n_bytes_from_file_cb_(handle, read_cb, temp_handle, temp_write_cb, chain->first_offset, &status)) {
  942. chain->status = get_equivalent_status_(status);
  943. return false;
  944. }
  945. /* write the metadata */
  946. for(node = chain->head; node; node = node->next) {
  947. if(!write_metadata_block_header_cb_(temp_handle, temp_write_cb, node->data)) {
  948. chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
  949. return false;
  950. }
  951. if(!write_metadata_block_data_cb_(temp_handle, temp_write_cb, node->data)) {
  952. chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
  953. return false;
  954. }
  955. }
  956. /*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/
  957. /* copy the file postfix (everything after the metadata) */
  958. if(0 != seek_cb(handle, chain->last_offset, SEEK_SET)) {
  959. chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
  960. return false;
  961. }
  962. if(!copy_remaining_bytes_from_file_cb_(handle, read_cb, eof_cb, temp_handle, temp_write_cb, &status)) {
  963. chain->status = get_equivalent_status_(status);
  964. return false;
  965. }
  966. return true;
  967. }
  968. FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new()
  969. {
  970. FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)calloc(1, sizeof(FLAC__Metadata_Chain));
  971. if(0 != chain)
  972. chain_init_(chain);
  973. return chain;
  974. }
  975. FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain)
  976. {
  977. FLAC__ASSERT(0 != chain);
  978. chain_clear_(chain);
  979. free(chain);
  980. }
  981. FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain)
  982. {
  983. FLAC__Metadata_ChainStatus status;
  984. FLAC__ASSERT(0 != chain);
  985. status = chain->status;
  986. chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
  987. return status;
  988. }
  989. FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename)
  990. {
  991. FILE *file;
  992. FLAC__bool ret;
  993. FLAC__ASSERT(0 != chain);
  994. FLAC__ASSERT(0 != filename);
  995. chain_clear_(chain);
  996. if(0 == (chain->filename = _strdup(filename))) {
  997. chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
  998. return false;
  999. }
  1000. if(0 == (file = fopen(filename, "rb"))) {
  1001. chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
  1002. return false;
  1003. }
  1004. /* chain_read_cb_() sets chain->status for us */
  1005. ret = chain_read_cb_(chain, file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, ftell_wrapper_);
  1006. fclose(file);
  1007. return ret;
  1008. }
  1009. FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks)
  1010. {
  1011. FLAC__ASSERT(0 != chain);
  1012. chain_clear_(chain);
  1013. if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.tell) {
  1014. chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
  1015. return false;
  1016. }
  1017. /* rewind */
  1018. if(0 != callbacks.seek(handle, 0, SEEK_SET)) {
  1019. chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
  1020. return false;
  1021. }
  1022. if(!chain_read_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.tell))
  1023. return false; /* chain->status is already set by chain_read_cb_ */
  1024. return true;
  1025. }
  1026. FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding)
  1027. {
  1028. /* This does all the same checks that are in chain_prepare_for_write_()
  1029.  * but doesn't actually alter the chain.  Make sure to update the logic
  1030.  * here if chain_prepare_for_write_() changes.
  1031.  */
  1032. const unsigned current_length = chain_calculate_length_(chain);
  1033. FLAC__ASSERT(0 != chain);
  1034. if(use_padding) {
  1035. /* if the metadata shrank and the last block is padding, we just extend the last padding block */
  1036. if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING)
  1037. return false;
  1038. /* if the metadata shrank more than 4 bytes then there's room to add another padding block */
  1039. else if(current_length + FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length)
  1040. return false;
  1041. /* 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 */
  1042. else if(current_length > chain->initial_length) {
  1043. const unsigned delta = current_length - chain->initial_length;
  1044. if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {
  1045. /* if the delta is exactly the size of the last padding block, remove the padding block */
  1046. if(chain->tail->data->length + FLAC__STREAM_METADATA_HEADER_LENGTH == delta)
  1047. return false;
  1048. /* if there is at least 'delta' bytes of padding, trim the padding down */
  1049. else if(chain->tail->data->length >= delta)
  1050. return false;
  1051. }
  1052. }
  1053. }
  1054. return (current_length != chain->initial_length);
  1055. }
  1056. FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats)
  1057. {
  1058. const char *tempfile_path_prefix = 0;
  1059. unsigned current_length;
  1060. FLAC__ASSERT(0 != chain);
  1061. if (0 == chain->filename) {
  1062. chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH;
  1063. return false;
  1064. }
  1065. current_length = chain_prepare_for_write_(chain, use_padding);
  1066. /* a return value of 0 means there was an error; chain->status is already set */
  1067. if (0 == current_length)
  1068. return false;
  1069. if(current_length == chain->initial_length) {
  1070. if(!chain_rewrite_metadata_in_place_(chain))
  1071. return false;
  1072. }
  1073. else {
  1074. if(!chain_rewrite_file_(chain, tempfile_path_prefix))
  1075. return false;
  1076. /* recompute lengths and offsets */
  1077. {
  1078. const FLAC__Metadata_Node *node;
  1079. chain->initial_length = current_length;
  1080. chain->last_offset = chain->first_offset;
  1081. for(node = chain->head; node; node = node->next)
  1082. chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);
  1083. }
  1084. }
  1085. return true;
  1086. }
  1087. FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks)
  1088. {
  1089. unsigned current_length;
  1090. FLAC__ASSERT(0 != chain);
  1091. if (0 != chain->filename) {
  1092. chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH;
  1093. return false;
  1094. }
  1095. if (0 == callbacks.write || 0 == callbacks.seek) {
  1096. chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
  1097. return false;
  1098. }
  1099. if (FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
  1100. chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL;
  1101. return false;
  1102. }
  1103. current_length = chain_prepare_for_write_(chain, use_padding);
  1104. /* a return value of 0 means there was an error; chain->status is already set */
  1105. if (0 == current_length)
  1106. return false;
  1107. FLAC__ASSERT(current_length == chain->initial_length);
  1108. return chain_rewrite_metadata_in_place_cb_(chain, handle, callbacks.write, callbacks.seek);
  1109. }
  1110. 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)
  1111. {
  1112. unsigned current_length;
  1113. FLAC__ASSERT(0 != chain);
  1114. if (0 != chain->filename) {
  1115. chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH;
  1116. return false;
  1117. }
  1118. if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.eof) {
  1119. chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
  1120. return false;
  1121. }
  1122. if (0 == temp_callbacks.write) {
  1123. chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
  1124. return false;
  1125. }
  1126. if (!FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
  1127. chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL;
  1128. return false;
  1129. }
  1130. current_length = chain_prepare_for_write_(chain, use_padding);
  1131. /* a return value of 0 means there was an error; chain->status is already set */
  1132. if (0 == current_length)
  1133. return false;
  1134. FLAC__ASSERT(current_length != chain->initial_length);
  1135. /* rewind */
  1136. if(0 != callbacks.seek(handle, 0, SEEK_SET)) {
  1137. chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
  1138. return false;
  1139. }
  1140. if(!chain_rewrite_file_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.eof, temp_handle, temp_callbacks.write))
  1141. return false;
  1142. /* recompute lengths and offsets */
  1143. {
  1144. const FLAC__Metadata_Node *node;
  1145. chain->initial_length = current_length;
  1146. chain->last_offset = chain->first_offset;
  1147. for(node = chain->head; node; node = node->next)
  1148. chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);
  1149. }
  1150. return true;
  1151. }
  1152. FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain)
  1153. {
  1154. FLAC__Metadata_Node *node;
  1155. FLAC__ASSERT(0 != chain);
  1156. for(node = chain->head; node; ) {
  1157. if(!chain_merge_adjacent_padding_(chain, node))
  1158. node = node->next;
  1159. }
  1160. }
  1161. FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain)
  1162. {
  1163. FLAC__Metadata_Node *node, *save;
  1164. unsigned i;
  1165. FLAC__ASSERT(0 != chain);
  1166. /*
  1167.  * Don't try and be too smart... this simple algo is good enough for
  1168.  * the small number of nodes that we deal with.
  1169.  */
  1170. for(i = 0, node = chain->head; i < chain->nodes; i++) {
  1171. if(node->data->type == FLAC__METADATA_TYPE_PADDING) {
  1172. save = node->next;
  1173. chain_remove_node_(chain, node);
  1174. chain_append_node_(chain, node);
  1175. node = save;
  1176. }
  1177. else {
  1178. node = node->next;
  1179. }
  1180. }
  1181. FLAC__metadata_chain_merge_padding(chain);
  1182. }
  1183. FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new()
  1184. {
  1185. FLAC__Metadata_Iterator *iterator = (FLAC__Metadata_Iterator*)calloc(1, sizeof(FLAC__Metadata_Iterator));
  1186. /* calloc() implies:
  1187. iterator->current = 0;
  1188. iterator->chain = 0;
  1189. */
  1190. return iterator;
  1191. }
  1192. FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator)
  1193. {
  1194. FLAC__ASSERT(0 != iterator);
  1195. free(iterator);
  1196. }
  1197. FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain)
  1198. {
  1199. FLAC__ASSERT(0 != iterator);
  1200. FLAC__ASSERT(0 != chain);
  1201. FLAC__ASSERT(0 != chain->head);
  1202. iterator->chain = chain;
  1203. iterator->current = chain->head;
  1204. }
  1205. FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator)
  1206. {
  1207. FLAC__ASSERT(0 != iterator);
  1208. if(0 == iterator->current || 0 == iterator->current->next)
  1209. return false;
  1210. iterator->current = iterator->current->next;
  1211. return true;
  1212. }
  1213. FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator)
  1214. {
  1215. FLAC__ASSERT(0 != iterator);
  1216. if(0 == iterator->current || 0 == iterator->current->prev)
  1217. return false;
  1218. iterator->current = iterator->current->prev;
  1219. return true;
  1220. }
  1221. FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator)
  1222. {
  1223. FLAC__ASSERT(0 != iterator);
  1224. FLAC__ASSERT(0 != iterator->current);
  1225. FLAC__ASSERT(0 != iterator->current->data);
  1226. return iterator->current->data->type;
  1227. }
  1228. FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator)
  1229. {
  1230. FLAC__ASSERT(0 != iterator);
  1231. FLAC__ASSERT(0 != iterator->current);
  1232. return iterator->current->data;
  1233. }
  1234. FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block)
  1235. {
  1236. FLAC__ASSERT(0 != iterator);
  1237. FLAC__ASSERT(0 != block);
  1238. return FLAC__metadata_iterator_delete_block(iterator, false) && FLAC__metadata_iterator_insert_block_after(iterator, block);
  1239. }
  1240. FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding)
  1241. {
  1242. FLAC__Metadata_Node *save;
  1243. FLAC__ASSERT(0 != iterator);
  1244. FLAC__ASSERT(0 != iterator->current);
  1245. if(0 == iterator->current->prev) {
  1246. FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO);
  1247. return false;
  1248. }
  1249. save = iterator->current->prev;
  1250. if(replace_with_padding) {
  1251. FLAC__metadata_object_delete_data(iterator->current->data);
  1252. iterator->current->data->type = FLAC__METADATA_TYPE_PADDING;
  1253. }
  1254. else {
  1255. chain_delete_node_(iterator->chain, iterator->current);
  1256. }
  1257. iterator->current = save;
  1258. return true;
  1259. }
  1260. FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block)
  1261. {
  1262. FLAC__Metadata_Node *node;
  1263. FLAC__ASSERT(0 != iterator);
  1264. FLAC__ASSERT(0 != iterator->current);
  1265. FLAC__ASSERT(0 != block);
  1266. if(block->type == FLAC__METADATA_TYPE_STREAMINFO)
  1267. return false;
  1268. if(0 == iterator->current->prev) {
  1269. FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO);
  1270. return false;
  1271. }
  1272. if(0 == (node = node_new_()))
  1273. return false;
  1274. node->data = block;
  1275. iterator_insert_node_(iterator, node);
  1276. iterator->current = node;
  1277. return true;
  1278. }
  1279. FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block)
  1280. {
  1281. FLAC__Metadata_Node *node;
  1282. FLAC__ASSERT(0 != iterator);
  1283. FLAC__ASSERT(0 != iterator->current);
  1284. FLAC__ASSERT(0 != block);
  1285. if(block->type == FLAC__METADATA_TYPE_STREAMINFO)
  1286. return false;
  1287. if(0 == (node = node_new_()))
  1288. return false;
  1289. node->data = block;
  1290. iterator_insert_node_after_(iterator, node);
  1291. iterator->current = node;
  1292. return true;
  1293. }
  1294. /****************************************************************************
  1295.  *
  1296.  * Local function definitions
  1297.  *
  1298.  ***************************************************************************/
  1299. void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes)
  1300. {
  1301. unsigned i;
  1302. b += bytes;
  1303. for(i = 0; i < bytes; i++) {
  1304. *(--b) = (FLAC__byte)(val & 0xff);
  1305. val >>= 8;
  1306. }
  1307. }
  1308. void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes)
  1309. {
  1310. unsigned i;
  1311. for(i = 0; i < bytes; i++) {
  1312. *(b++) = (FLAC__byte)(val & 0xff);
  1313. val >>= 8;
  1314. }
  1315. }
  1316. void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes)
  1317. {
  1318. unsigned i;
  1319. b += bytes;
  1320. for(i = 0; i < bytes; i++) {
  1321. *(--b) = (FLAC__byte)(val & 0xff);
  1322. val >>= 8;
  1323. }
  1324. }
  1325. FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes)
  1326. {
  1327. FLAC__uint32 ret = 0;
  1328. unsigned i;
  1329. for(i = 0; i < bytes; i++)
  1330. ret = (ret << 8) | (FLAC__uint32)(*b++);
  1331. return ret;
  1332. }
  1333. FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes)
  1334. {
  1335. FLAC__uint32 ret = 0;
  1336. unsigned i;
  1337. b += bytes;
  1338. for(i = 0; i < bytes; i++)
  1339. ret = (ret << 8) | (FLAC__uint32)(*--b);
  1340. return ret;
  1341. }
  1342. FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes)
  1343. {
  1344. FLAC__uint64 ret = 0;
  1345. unsigned i;
  1346. for(i = 0; i < bytes; i++)
  1347. ret = (ret << 8) | (FLAC__uint64)(*b++);
  1348. return ret;
  1349. }
  1350. FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator)
  1351. {
  1352. FLAC__ASSERT(0 != iterator);
  1353. FLAC__ASSERT(0 != iterator->file);
  1354. if(!read_metadata_block_header_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, &iterator->is_last, &iterator->type, &iterator->length)) {
  1355. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1356. return false;
  1357. }
  1358. return true;
  1359. }
  1360. FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block)
  1361. {
  1362. FLAC__ASSERT(0 != iterator);
  1363. FLAC__ASSERT(0 != iterator->file);
  1364. iterator->status = read_metadata_block_data_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, block);
  1365. return (iterator->status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK);
  1366. }
  1367. FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length)
  1368. {
  1369. FLAC__byte raw_header[FLAC__STREAM_METADATA_HEADER_LENGTH];
  1370. if(read_cb(raw_header, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH)
  1371. return false;
  1372. *is_last = raw_header[0] & 0x80? true : false;
  1373. *type = (FLAC__MetadataType)(raw_header[0] & 0x7f);
  1374. *length = unpack_uint32_(raw_header + 1, 3);
  1375. /* Note that we don't check:
  1376.  *    if(iterator->type >= FLAC__METADATA_TYPE_UNDEFINED)
  1377.  * we just will read in an opaque block
  1378.  */
  1379. return true;
  1380. }
  1381. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata *block)
  1382. {
  1383. switch(block->type) {
  1384. case FLAC__METADATA_TYPE_STREAMINFO:
  1385. return read_metadata_block_data_streaminfo_cb_(handle, read_cb, &block->data.stream_info);
  1386. case FLAC__METADATA_TYPE_PADDING:
  1387. return read_metadata_block_data_padding_cb_(handle, seek_cb, &block->data.padding, block->length);
  1388. case FLAC__METADATA_TYPE_APPLICATION:
  1389. return read_metadata_block_data_application_cb_(handle, read_cb, &block->data.application, block->length);
  1390. case FLAC__METADATA_TYPE_SEEKTABLE:
  1391. return read_metadata_block_data_seektable_cb_(handle, read_cb, &block->data.seek_table, block->length);
  1392. case FLAC__METADATA_TYPE_VORBIS_COMMENT:
  1393. return read_metadata_block_data_vorbis_comment_cb_(handle, read_cb, &block->data.vorbis_comment);
  1394. case FLAC__METADATA_TYPE_CUESHEET:
  1395. return read_metadata_block_data_cuesheet_cb_(handle, read_cb, &block->data.cue_sheet);
  1396. default:
  1397. return read_metadata_block_data_unknown_cb_(handle, read_cb, &block->data.unknown, block->length);
  1398. }
  1399. }
  1400. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block)
  1401. {
  1402. FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH], *b;
  1403. if(read_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH)
  1404. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1405. b = buffer;
  1406. /* we are using hardcoded numbers for simplicity but we should
  1407.  * probably eventually write a bit-level unpacker and use the
  1408.  * _STREAMINFO_ constants.
  1409.  */
  1410. block->min_blocksize = unpack_uint32_(b, 2); b += 2;
  1411. block->max_blocksize = unpack_uint32_(b, 2); b += 2;
  1412. block->min_framesize = unpack_uint32_(b, 3); b += 3;
  1413. block->max_framesize = unpack_uint32_(b, 3); b += 3;
  1414. block->sample_rate = (unpack_uint32_(b, 2) << 4) | ((unsigned)(b[2] & 0xf0) >> 4);
  1415. block->channels = (unsigned)((b[2] & 0x0e) >> 1) + 1;
  1416. block->bits_per_sample = ((((unsigned)(b[2] & 0x01)) << 4) | (((unsigned)(b[3] & 0xf0)) >> 4)) + 1;
  1417. block->total_samples = (((FLAC__uint64)(b[3] & 0x0f)) << 32) | unpack_uint64_(b+4, 4);
  1418. memcpy(block->md5sum, b+8, 16);
  1419. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1420. }
  1421. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_Padding *block, unsigned block_length)
  1422. {
  1423. (void)block; /* nothing to do; we don't care about reading the padding bytes */
  1424. if(0 != seek_cb(handle, block_length, SEEK_CUR))
  1425. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  1426. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1427. }
  1428. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Application *block, unsigned block_length)
  1429. {
  1430. const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
  1431. if(read_cb(block->id, 1, id_bytes, handle) != id_bytes)
  1432. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1433. block_length -= id_bytes;
  1434. if(block_length == 0) {
  1435. block->data = 0;
  1436. }
  1437. else {
  1438. if(0 == (block->data = (FLAC__byte*)malloc(block_length)))
  1439. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  1440. if(read_cb(block->data, 1, block_length, handle) != block_length)
  1441. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1442. }
  1443. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1444. }
  1445. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_SeekTable *block, unsigned block_length)
  1446. {
  1447. unsigned i;
  1448. FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH];
  1449. FLAC__ASSERT(block_length % FLAC__STREAM_METADATA_SEEKPOINT_LENGTH == 0);
  1450. block->num_points = block_length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
  1451. if(block->num_points == 0)
  1452. block->points = 0;
  1453. else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)malloc(block->num_points * sizeof(FLAC__StreamMetadata_SeekPoint))))
  1454. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  1455. for(i = 0; i < block->num_points; i++) {
  1456. if(read_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)
  1457. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1458. /* some MAGIC NUMBERs here */
  1459. block->points[i].sample_number = unpack_uint64_(buffer, 8);
  1460. block->points[i].stream_offset = unpack_uint64_(buffer+8, 8);
  1461. block->points[i].frame_samples = unpack_uint32_(buffer+16, 2);
  1462. }
  1463. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1464. }
  1465. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entry_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment_Entry *entry)
  1466. {
  1467. const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8;
  1468. FLAC__byte buffer[4]; /* magic number is asserted below */
  1469. FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8 == 4);
  1470. if(read_cb(buffer, 1, entry_length_len, handle) != entry_length_len)
  1471. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1472. entry->length = unpack_uint32_little_endian_(buffer, entry_length_len);
  1473. if(0 != entry->entry)
  1474. free(entry->entry);
  1475. if(entry->length == 0) {
  1476. entry->entry = 0;
  1477. }
  1478. else {
  1479. if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1)))
  1480. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  1481. if(read_cb(entry->entry, 1, entry->length, handle) != entry->length)
  1482. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1483. entry->entry[entry->length] = '';
  1484. }
  1485. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1486. }
  1487. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment *block)
  1488. {
  1489. unsigned i;
  1490. FLAC__Metadata_SimpleIteratorStatus status;
  1491. const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8;
  1492. FLAC__byte buffer[4]; /* magic number is asserted below */
  1493. FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8 == 4);
  1494. if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, &(block->vendor_string))))
  1495. return status;
  1496. if(read_cb(buffer, 1, num_comments_len, handle) != num_comments_len)
  1497. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1498. block->num_comments = unpack_uint32_little_endian_(buffer, num_comments_len);
  1499. if(block->num_comments == 0) {
  1500. block->comments = 0;
  1501. }
  1502. else if(0 == (block->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry))))
  1503. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  1504. for(i = 0; i < block->num_comments; i++) {
  1505. if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, block->comments + i)))
  1506. return status;
  1507. }
  1508. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1509. }
  1510. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track)
  1511. {
  1512. unsigned i, len;
  1513. FLAC__byte buffer[32]; /* asserted below that this is big enough */
  1514. FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64));
  1515. FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8);
  1516. 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);
  1517. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0);
  1518. len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8;
  1519. if(read_cb(buffer, 1, len, handle) != len)
  1520. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1521. track->offset = unpack_uint64_(buffer, len);
  1522. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0);
  1523. len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8;
  1524. if(read_cb(buffer, 1, len, handle) != len)
  1525. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1526. track->number = (FLAC__byte)unpack_uint32_(buffer, len);
  1527. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0);
  1528. len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8;
  1529. if(read_cb(track->isrc, 1, len, handle) != len)
  1530. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1531. 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);
  1532. len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8;
  1533. if(read_cb(buffer, 1, len, handle) != len)
  1534. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1535. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN == 1);
  1536. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN == 1);
  1537. track->type = buffer[0] >> 7;
  1538. track->pre_emphasis = (buffer[0] >> 6) & 1;
  1539. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN % 8 == 0);
  1540. len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN / 8;
  1541. if(read_cb(buffer, 1, len, handle) != len)
  1542. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1543. track->num_indices = (FLAC__byte)unpack_uint32_(buffer, len);
  1544. if(track->num_indices == 0) {
  1545. track->indices = 0;
  1546. }
  1547. else if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index))))
  1548. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  1549. for(i = 0; i < track->num_indices; i++) {
  1550. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN % 8 == 0);
  1551. len = FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN / 8;
  1552. if(read_cb(buffer, 1, len, handle) != len)
  1553. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1554. track->indices[i].offset = unpack_uint64_(buffer, len);
  1555. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN % 8 == 0);
  1556. len = FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN / 8;
  1557. if(read_cb(buffer, 1, len, handle) != len)
  1558. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1559. track->indices[i].number = (FLAC__byte)unpack_uint32_(buffer, len);
  1560. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN % 8 == 0);
  1561. len = FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN / 8;
  1562. if(read_cb(buffer, 1, len, handle) != len)
  1563. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1564. }
  1565. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1566. }
  1567. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block)
  1568. {
  1569. unsigned i, len;
  1570. FLAC__Metadata_SimpleIteratorStatus status;
  1571. FLAC__byte buffer[1024]; /* MSVC needs a constant expression so we put a magic number and assert */
  1572. FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)/8 <= sizeof(buffer));
  1573. FLAC__ASSERT(sizeof(FLAC__uint64) <= sizeof(buffer));
  1574. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0);
  1575. len = FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8;
  1576. if(read_cb(block->media_catalog_number, 1, len, handle) != len)
  1577. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1578. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN % 8 == 0);
  1579. len = FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN / 8;
  1580. if(read_cb(buffer, 1, len, handle) != len)
  1581. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1582. block->lead_in = unpack_uint64_(buffer, len);
  1583. FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) % 8 == 0);
  1584. len = (FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) / 8;
  1585. if(read_cb(buffer, 1, len, handle) != len)
  1586. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1587. block->is_cd = buffer[0]&0x80? true : false;
  1588. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN % 8 == 0);
  1589. len = FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN / 8;
  1590. if(read_cb(buffer, 1, len, handle) != len)
  1591. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1592. block->num_tracks = unpack_uint32_(buffer, len);
  1593. if(block->num_tracks == 0) {
  1594. block->tracks = 0;
  1595. }
  1596. else if(0 == (block->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(block->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track))))
  1597. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  1598. for(i = 0; i < block->num_tracks; i++) {
  1599. if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_cuesheet_track_cb_(handle, read_cb, block->tracks + i)))
  1600. return status;
  1601. }
  1602. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1603. }
  1604. FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Unknown *block, unsigned block_length)
  1605. {
  1606. if(block_length == 0) {
  1607. block->data = 0;
  1608. }
  1609. else {
  1610. if(0 == (block->data = (FLAC__byte*)malloc(block_length)))
  1611. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  1612. if(read_cb(block->data, 1, block_length, handle) != block_length)
  1613. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  1614. }
  1615. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1616. }
  1617. FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block)
  1618. {
  1619. FLAC__ASSERT(0 != file);
  1620. FLAC__ASSERT(0 != status);
  1621. if(!write_metadata_block_header_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) {
  1622. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
  1623. return false;
  1624. }
  1625. return true;
  1626. }
  1627. FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block)
  1628. {
  1629. FLAC__ASSERT(0 != file);
  1630. FLAC__ASSERT(0 != status);
  1631. if (write_metadata_block_data_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) {
  1632. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
  1633. return true;
  1634. }
  1635. else {
  1636. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
  1637. return false;
  1638. }
  1639. }
  1640. FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block)
  1641. {
  1642. FLAC__byte buffer[FLAC__STREAM_METADATA_HEADER_LENGTH];
  1643. FLAC__ASSERT(block->length < (1u << FLAC__STREAM_METADATA_LENGTH_LEN));
  1644. buffer[0] = (block->is_last? 0x80 : 0) | (FLAC__byte)block->type;
  1645. pack_uint32_(block->length, buffer + 1, 3);
  1646. if(write_cb(buffer, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH)
  1647. return false;
  1648. return true;
  1649. }
  1650. FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block)
  1651. {
  1652. FLAC__ASSERT(0 != block);
  1653. switch(block->type) {
  1654. case FLAC__METADATA_TYPE_STREAMINFO:
  1655. return write_metadata_block_data_streaminfo_cb_(handle, write_cb, &block->data.stream_info);
  1656. case FLAC__METADATA_TYPE_PADDING:
  1657. return write_metadata_block_data_padding_cb_(handle, write_cb, &block->data.padding, block->length);
  1658. case FLAC__METADATA_TYPE_APPLICATION:
  1659. return write_metadata_block_data_application_cb_(handle, write_cb, &block->data.application, block->length);
  1660. case FLAC__METADATA_TYPE_SEEKTABLE:
  1661. return write_metadata_block_data_seektable_cb_(handle, write_cb, &block->data.seek_table);
  1662. case FLAC__METADATA_TYPE_VORBIS_COMMENT:
  1663. return write_metadata_block_data_vorbis_comment_cb_(handle, write_cb, &block->data.vorbis_comment);
  1664. case FLAC__METADATA_TYPE_CUESHEET:
  1665. return write_metadata_block_data_cuesheet_cb_(handle, write_cb, &block->data.cue_sheet);
  1666. default:
  1667. return write_metadata_block_data_unknown_cb_(handle, write_cb, &block->data.unknown, block->length);
  1668. }
  1669. }
  1670. FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block)
  1671. {
  1672. FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH];
  1673. const unsigned channels1 = block->channels - 1;
  1674. const unsigned bps1 = block->bits_per_sample - 1;
  1675. /* we are using hardcoded numbers for simplicity but we should
  1676.  * probably eventually write a bit-level packer and use the
  1677.  * _STREAMINFO_ constants.
  1678.  */
  1679. pack_uint32_(block->min_blocksize, buffer, 2);
  1680. pack_uint32_(block->max_blocksize, buffer+2, 2);
  1681. pack_uint32_(block->min_framesize, buffer+4, 3);
  1682. pack_uint32_(block->max_framesize, buffer+7, 3);
  1683. buffer[10] = (block->sample_rate >> 12) & 0xff;
  1684. buffer[11] = (block->sample_rate >> 4) & 0xff;
  1685. buffer[12] = ((block->sample_rate & 0x0f) << 4) | (channels1 << 1) | (bps1 >> 4);
  1686. buffer[13] = (FLAC__byte)(((bps1 & 0x0f) << 4) | ((block->total_samples >> 32) & 0x0f));
  1687. pack_uint32_((FLAC__uint32)block->total_samples, buffer+14, 4);
  1688. memcpy(buffer+18, block->md5sum, 16);
  1689. if(write_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH)
  1690. return false;
  1691. return true;
  1692. }
  1693. FLAC__bool write_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Padding *block, unsigned block_length)
  1694. {
  1695. unsigned i, n = block_length;
  1696. FLAC__byte buffer[1024];
  1697. (void)block;
  1698. memset(buffer, 0, 1024);
  1699. for(i = 0; i < n/1024; i++)
  1700. if(write_cb(buffer, 1, 1024, handle) != 1024)
  1701. return false;
  1702. n %= 1024;
  1703. if(write_cb(buffer, 1, n, handle) != n)
  1704. return false;
  1705. return true;
  1706. }
  1707. FLAC__bool write_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Application *block, unsigned block_length)
  1708. {
  1709. const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
  1710. if(write_cb(block->id, 1, id_bytes, handle) != id_bytes)
  1711. return false;
  1712. block_length -= id_bytes;
  1713. if(write_cb(block->data, 1, block_length, handle) != block_length)
  1714. return false;
  1715. return true;
  1716. }
  1717. FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block)
  1718. {
  1719. unsigned i;
  1720. FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH];
  1721. for(i = 0; i < block->num_points; i++) {
  1722. /* some MAGIC NUMBERs here */
  1723. pack_uint64_(block->points[i].sample_number, buffer, 8);
  1724. pack_uint64_(block->points[i].stream_offset, buffer+8, 8);
  1725. pack_uint32_(block->points[i].frame_samples, buffer+16, 2);
  1726. if(write_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)
  1727. return false;
  1728. }
  1729. return true;
  1730. }
  1731. FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block)
  1732. {
  1733. unsigned i;
  1734. const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8;
  1735. const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8;
  1736. FLAC__byte buffer[4]; /* magic number is asserted below */
  1737. FLAC__ASSERT(max(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN, FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8 == 4);
  1738. pack_uint32_little_endian_(block->vendor_string.length, buffer, entry_length_len);
  1739. if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len)
  1740. return false;
  1741. if(write_cb(block->vendor_string.entry, 1, block->vendor_string.length, handle) != block->vendor_string.length)
  1742. return false;
  1743. pack_uint32_little_endian_(block->num_comments, buffer, num_comments_len);
  1744. if(write_cb(buffer, 1, num_comments_len, handle) != num_comments_len)
  1745. return false;
  1746. for(i = 0; i < block->num_comments; i++) {
  1747. pack_uint32_little_endian_(block->comments[i].length, buffer, entry_length_len);
  1748. if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len)
  1749. return false;
  1750. if(write_cb(block->comments[i].entry, 1, block->comments[i].length, handle) != block->comments[i].length)
  1751. return false;
  1752. }
  1753. return true;
  1754. }
  1755. FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block)
  1756. {
  1757. unsigned i, j, len;
  1758. FLAC__byte buffer[1024]; /* asserted below that this is big enough */
  1759. FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64));
  1760. FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN/8);
  1761. 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);
  1762. FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8);
  1763. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0);
  1764. len = FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8;
  1765. if(write_cb(block->media_catalog_number, 1, len, handle) != len)
  1766. return false;
  1767. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN % 8 == 0);
  1768. len = FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN / 8;
  1769. pack_uint64_(block->lead_in, buffer, len);
  1770. if(write_cb(buffer, 1, len, handle) != len)
  1771. return false;
  1772. FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) % 8 == 0);
  1773. len = (FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) / 8;
  1774. memset(buffer, 0, len);
  1775. if(block->is_cd)
  1776. buffer[0] |= 0x80;
  1777. if(write_cb(buffer, 1, len, handle) != len)
  1778. return false;
  1779. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN % 8 == 0);
  1780. len = FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN / 8;
  1781. pack_uint32_(block->num_tracks, buffer, len);
  1782. if(write_cb(buffer, 1, len, handle) != len)
  1783. return false;
  1784. for(i = 0; i < block->num_tracks; i++) {
  1785. FLAC__StreamMetadata_CueSheet_Track *track = block->tracks + i;
  1786. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0);
  1787. len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8;
  1788. pack_uint64_(track->offset, buffer, len);
  1789. if(write_cb(buffer, 1, len, handle) != len)
  1790. return false;
  1791. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0);
  1792. len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8;
  1793. pack_uint32_(track->number, buffer, len);
  1794. if(write_cb(buffer, 1, len, handle) != len)
  1795. return false;
  1796. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0);
  1797. len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8;
  1798. if(write_cb(track->isrc, 1, len, handle) != len)
  1799. return false;
  1800. 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);
  1801. len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8;
  1802. memset(buffer, 0, len);
  1803. buffer[0] = (track->type << 7) | (track->pre_emphasis << 6);
  1804. if(write_cb(buffer, 1, len, handle) != len)
  1805. return false;
  1806. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN % 8 == 0);
  1807. len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN / 8;
  1808. pack_uint32_(track->num_indices, buffer, len);
  1809. if(write_cb(buffer, 1, len, handle) != len)
  1810. return false;
  1811. for(j = 0; j < track->num_indices; j++) {
  1812. FLAC__StreamMetadata_CueSheet_Index *index = track->indices + j;
  1813. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN % 8 == 0);
  1814. len = FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN / 8;
  1815. pack_uint64_(index->offset, buffer, len);
  1816. if(write_cb(buffer, 1, len, handle) != len)
  1817. return false;
  1818. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN % 8 == 0);
  1819. len = FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN / 8;
  1820. pack_uint32_(index->number, buffer, len);
  1821. if(write_cb(buffer, 1, len, handle) != len)
  1822. return false;
  1823. FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN % 8 == 0);
  1824. len = FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN / 8;
  1825. memset(buffer, 0, len);
  1826. if(write_cb(buffer, 1, len, handle) != len)
  1827. return false;
  1828. }
  1829. }
  1830. return true;
  1831. }
  1832. FLAC__bool write_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Unknown *block, unsigned block_length)
  1833. {
  1834. if(write_cb(block->data, 1, block_length, handle) != block_length)
  1835. return false;
  1836. return true;
  1837. }
  1838. FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block)
  1839. {
  1840. if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
  1841. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  1842. return false;
  1843. }
  1844. if(!write_metadata_block_header_(iterator->file, &iterator->status, block))
  1845. return false;
  1846. if(!write_metadata_block_data_(iterator->file, &iterator->status, block))
  1847. return false;
  1848. if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
  1849. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  1850. return false;
  1851. }
  1852. return read_metadata_block_header_(iterator);
  1853. }
  1854. FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last)
  1855. {
  1856. FLAC__StreamMetadata *padding;
  1857. if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
  1858. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  1859. return false;
  1860. }
  1861. block->is_last = false;
  1862. if(!write_metadata_block_header_(iterator->file, &iterator->status, block))
  1863. return false;
  1864. if(!write_metadata_block_data_(iterator->file, &iterator->status, block))
  1865. return false;
  1866. if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
  1867. return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  1868. padding->is_last = padding_is_last;
  1869. padding->length = padding_length;
  1870. if(!write_metadata_block_header_(iterator->file, &iterator->status, padding)) {
  1871. FLAC__metadata_object_delete(padding);
  1872. return false;
  1873. }
  1874. if(!write_metadata_block_data_(iterator->file, &iterator->status, padding)) {
  1875. FLAC__metadata_object_delete(padding);
  1876. return false;
  1877. }
  1878. FLAC__metadata_object_delete(padding);
  1879. if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
  1880. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  1881. return false;
  1882. }
  1883. return read_metadata_block_header_(iterator);
  1884. }
  1885. FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append)
  1886. {
  1887. FILE *tempfile;
  1888. char *tempfilename;
  1889. int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */
  1890. long fixup_is_last_flag_offset = -1;
  1891. FLAC__ASSERT(0 != block || append == false);
  1892. if(iterator->is_last) {
  1893. if(append) {
  1894. fixup_is_last_code = 1; /* 1 => clear the is_last flag at the following offset */
  1895. fixup_is_last_flag_offset = iterator->offset[iterator->depth];
  1896. }
  1897. else if(0 == block) {
  1898. simple_iterator_push_(iterator);
  1899. if(!FLAC__metadata_simple_iterator_prev(iterator)) {
  1900. (void)simple_iterator_pop_(iterator);
  1901. return false;
  1902. }
  1903. fixup_is_last_code = -1; /* -1 => set the is_last the flag at the following offset */
  1904. fixup_is_last_flag_offset = iterator->offset[iterator->depth];
  1905. if(!simple_iterator_pop_(iterator))
  1906. return false;
  1907. }
  1908. }
  1909. if(!simple_iterator_copy_file_prefix_(iterator, &tempfile, &tempfilename, append))
  1910. return false;
  1911. if(0 != block) {
  1912. if(!write_metadata_block_header_(tempfile, &iterator->status, block)) {
  1913. cleanup_tempfile_(&tempfile, &tempfilename);
  1914. return false;
  1915. }
  1916. if(!write_metadata_block_data_(tempfile, &iterator->status, block)) {
  1917. cleanup_tempfile_(&tempfile, &tempfilename);
  1918. return false;
  1919. }
  1920. }
  1921. if(!simple_iterator_copy_file_postfix_(iterator, &tempfile, &tempfilename, fixup_is_last_code, fixup_is_last_flag_offset, block==0))
  1922. return false;
  1923. if(append)
  1924. return FLAC__metadata_simple_iterator_next(iterator);
  1925. return true;
  1926. }
  1927. void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator)
  1928. {
  1929. FLAC__ASSERT(iterator->depth+1 < SIMPLE_ITERATOR_MAX_PUSH_DEPTH);
  1930. iterator->offset[iterator->depth+1] = iterator->offset[iterator->depth];
  1931. iterator->depth++;
  1932. }
  1933. FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator)
  1934. {
  1935. FLAC__ASSERT(iterator->depth > 0);
  1936. iterator->depth--;
  1937. if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) {
  1938. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  1939. return false;
  1940. }
  1941. return read_metadata_block_header_(iterator);
  1942. }
  1943. /* return meanings:
  1944.  * 0: ok
  1945.  * 1: read error
  1946.  * 2: seek error
  1947.  * 3: not a FLAC file
  1948.  */
  1949. unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb)
  1950. {
  1951. FLAC__byte buffer[4];
  1952. size_t n;
  1953. unsigned i;
  1954. FLAC__ASSERT(FLAC__STREAM_SYNC_LENGTH == 4);
  1955. /* skip any id3v2 tag */
  1956. n = read_cb(buffer, 1, 4, handle);
  1957.   if(n != 4)
  1958. return 3;
  1959. else if(0 == memcmp(buffer, "ID3", 3)) {
  1960. unsigned tag_length = 0;
  1961. /* skip to the tag length */
  1962. if(seek_cb(handle, 2, SEEK_CUR) < 0)
  1963. return 2;
  1964. /* read the length */
  1965. for(i = 0; i < 4; i++) {
  1966. if(read_cb(buffer, 1, 1, handle) < 1 || buffer[0] & 0x80)
  1967. return 1;
  1968. tag_length <<= 7;
  1969. tag_length |= (buffer[0] & 0x7f);
  1970. }
  1971. /* skip the rest of the tag */
  1972. if(seek_cb(handle, tag_length, SEEK_CUR) < 0)
  1973. return 2;
  1974. /* read the stream sync code */
  1975. n = read_cb(buffer, 1, 4, handle);
  1976.     if(n != 4)
  1977. return 3;
  1978. }
  1979. /* check for the fLaC signature */
  1980. if(0 == memcmp(FLAC__STREAM_SYNC_STRING, buffer, FLAC__STREAM_SYNC_LENGTH))
  1981. return 0;
  1982. else
  1983. return 3;
  1984. }
  1985. unsigned seek_to_first_metadata_block_(FILE *f)
  1986. {
  1987. return seek_to_first_metadata_block_cb_((FLAC__IOHandle)f, (FLAC__IOCallback_Read)fread, fseek_wrapper_);
  1988. }
  1989. FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append)
  1990. {
  1991. const long offset_end = append? iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length : iterator->offset[iterator->depth];
  1992. if(0 != fseek(iterator->file, 0, SEEK_SET)) {
  1993. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  1994. return false;
  1995. }
  1996. if(!open_tempfile_(iterator->filename, iterator->tempfile_path_prefix, tempfile, tempfilename, &iterator->status)) {
  1997. cleanup_tempfile_(tempfile, tempfilename);
  1998. return false;
  1999. }
  2000. if(!copy_n_bytes_from_file_(iterator->file, *tempfile, offset_end, &iterator->status)) {
  2001. cleanup_tempfile_(tempfile, tempfilename);
  2002. return false;
  2003. }
  2004. return true;
  2005. }
  2006. FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, long fixup_is_last_flag_offset, FLAC__bool backup)
  2007. {
  2008. long save_offset = iterator->offset[iterator->depth]; /*@@@ 2G limit */
  2009. FLAC__ASSERT(0 != *tempfile);
  2010. if(0 != fseek(iterator->file, save_offset + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length, SEEK_SET)) {
  2011. cleanup_tempfile_(tempfile, tempfilename);
  2012. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  2013. return false;
  2014. }
  2015. if(!copy_remaining_bytes_from_file_(iterator->file, *tempfile, &iterator->status)) {
  2016. cleanup_tempfile_(tempfile, tempfilename);
  2017. return false;
  2018. }
  2019. if(fixup_is_last_code != 0) {
  2020. /*
  2021.  * if code == 1, it means a block was appended to the end so
  2022.  *   we have to clear the is_last flag of the previous block
  2023.  * if code == -1, it means the last block was deleted so
  2024.  *   we have to set the is_last flag of the previous block
  2025.  */
  2026. /* MAGIC NUMBERs here; we know the is_last flag is the high bit of the byte at this location */
  2027. FLAC__byte x;
  2028. if(0 != fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
  2029. cleanup_tempfile_(tempfile, tempfilename);
  2030. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  2031. return false;
  2032. }
  2033. if(fread(&x, 1, 1, *tempfile) != 1) {
  2034. cleanup_tempfile_(tempfile, tempfilename);
  2035. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  2036. return false;
  2037. }
  2038. if(fixup_is_last_code > 0) {
  2039. FLAC__ASSERT(x & 0x80);
  2040. x &= 0x7f;
  2041. }
  2042. else {
  2043. FLAC__ASSERT(!(x & 0x80));
  2044. x |= 0x80;
  2045. }
  2046. if(0 != fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
  2047. cleanup_tempfile_(tempfile, tempfilename);
  2048. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
  2049. return false;
  2050. }
  2051. if(local__fwrite(&x, 1, 1, *tempfile) != 1) {
  2052. cleanup_tempfile_(tempfile, tempfilename);
  2053. iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
  2054. return false;
  2055. }
  2056. }
  2057. (void)fclose(iterator->file);
  2058. if(!transport_tempfile_(iterator->filename, tempfile, tempfilename, &iterator->status))
  2059. return false;
  2060. if(!simple_iterator_prime_input_(iterator, !iterator->is_writable))
  2061. return false;
  2062. if(backup) {
  2063. while(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length < save_offset)
  2064. if(!FLAC__metadata_simple_iterator_next(iterator))
  2065. return false;
  2066. return true;
  2067. }
  2068. else {
  2069. /* move the iterator to it's original block faster by faking a push, then doing a pop_ */
  2070. FLAC__ASSERT(iterator->depth == 0);
  2071. iterator->offset[0] = save_offset;
  2072. iterator->depth++;
  2073. return simple_iterator_pop_(iterator);
  2074. }
  2075. }
  2076. FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status)
  2077. {
  2078. FLAC__byte buffer[8192];
  2079. unsigned n;
  2080. while(bytes > 0) {
  2081. n = min(sizeof(buffer), bytes);
  2082. if(fread(buffer, 1, n, file) != n) {
  2083. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  2084. return false;
  2085. }
  2086. if(local__fwrite(buffer, 1, n, tempfile) != n) {
  2087. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
  2088. return false;
  2089. }
  2090. bytes -= n;
  2091. }
  2092. return true;
  2093. }
  2094. 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, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status)
  2095. {
  2096. FLAC__byte buffer[8192];
  2097. unsigned n;
  2098. while(bytes > 0) {
  2099. n = min(sizeof(buffer), bytes);
  2100. if(read_cb(buffer, 1, n, handle) != n) {
  2101. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  2102. return false;
  2103. }
  2104. if(temp_write_cb(buffer, 1, n, temp_handle) != n) {
  2105. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
  2106. return false;
  2107. }
  2108. bytes -= n;
  2109. }
  2110. return true;
  2111. }
  2112. FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status)
  2113. {
  2114. FLAC__byte buffer[8192];
  2115. size_t n;
  2116. while(!feof(file)) {
  2117. n = fread(buffer, 1, sizeof(buffer), file);
  2118. if(n == 0 && !feof(file)) {
  2119. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  2120. return false;
  2121. }
  2122. if(n > 0 && local__fwrite(buffer, 1, n, tempfile) != n) {
  2123. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
  2124. return false;
  2125. }
  2126. }
  2127. return true;
  2128. }
  2129. 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)
  2130. {
  2131. FLAC__byte buffer[8192];
  2132. size_t n;
  2133. while(!eof_cb(handle)) {
  2134. n = read_cb(buffer, 1, sizeof(buffer), handle);
  2135. if(n == 0 && !eof_cb(handle)) {
  2136. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
  2137. return false;
  2138. }
  2139. if(n > 0 && temp_write_cb(buffer, 1, n, temp_handle) != n) {
  2140. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR;
  2141. return false;
  2142. }
  2143. }
  2144. return true;
  2145. }
  2146. FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status)
  2147. {
  2148. static const char *tempfile_suffix = ".metadata_edit";
  2149. if(0 == tempfile_path_prefix) {
  2150. if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) {
  2151. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  2152. return false;
  2153. }
  2154. strcpy(*tempfilename, filename);
  2155. strcat(*tempfilename, tempfile_suffix);
  2156. }
  2157. else {
  2158. const char *p = strrchr(filename, '/');
  2159. if(0 == p)
  2160. p = filename;
  2161. else
  2162. p++;
  2163. if(0 == (*tempfilename = (char*)malloc(strlen(tempfile_path_prefix) + 1 + strlen(p) + strlen(tempfile_suffix) + 1))) {
  2164. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
  2165. return false;
  2166. }
  2167. strcpy(*tempfilename, tempfile_path_prefix);
  2168. strcat(*tempfilename, "/");
  2169. strcat(*tempfilename, p);
  2170. strcat(*tempfilename, tempfile_suffix);
  2171. }
  2172. if(0 == (*tempfile = fopen(*tempfilename, "w+b"))) {
  2173. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;
  2174. return false;
  2175. }
  2176. return true;
  2177. }
  2178. FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status)
  2179. {
  2180. FLAC__ASSERT(0 != filename);
  2181. FLAC__ASSERT(0 != tempfile);
  2182. FLAC__ASSERT(0 != *tempfile);
  2183. FLAC__ASSERT(0 != tempfilename);
  2184. FLAC__ASSERT(0 != *tempfilename);
  2185. FLAC__ASSERT(0 != status);
  2186. (void)fclose(*tempfile);
  2187. *tempfile = 0;
  2188. #if defined _MSC_VER || defined __MINGW32__
  2189. if(_unlink(filename) < 0) {
  2190. cleanup_tempfile_(tempfile, tempfilename);
  2191. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR;
  2192. return false;
  2193. }
  2194. #endif
  2195. /*@@@ to fully support the tempfile_path_prefix we need to update this piece to actually copy across filesystems instead of just rename(): */
  2196. if(0 != rename(*tempfilename, filename)) {
  2197. cleanup_tempfile_(tempfile, tempfilename);
  2198. *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR;
  2199. return false;
  2200. }
  2201. cleanup_tempfile_(tempfile, tempfilename);
  2202. return true;
  2203. }
  2204. void cleanup_tempfile_(FILE **tempfile, char **tempfilename)
  2205. {
  2206. if(0 != *tempfile) {
  2207. (void)fclose(*tempfile);
  2208. *tempfile = 0;
  2209. }
  2210. if(0 != *tempfilename) {
  2211. (void)_unlink(*tempfilename);
  2212. free(*tempfilename);
  2213. *tempfilename = 0;
  2214. }
  2215. }
  2216. FLAC__bool get_file_stats_(const char *filename, struct stat *stats)
  2217. {
  2218. FLAC__ASSERT(0 != filename);
  2219. FLAC__ASSERT(0 != stats);
  2220. return (0 == stat(filename, stats));
  2221. }
  2222. /* @@@ WATCHOUT @@@
  2223.  * We cast FLAC__int64 to long and use fseek()/ftell() because
  2224.  * none of our operations on metadata is ever likely to go past
  2225.  * 2 gigabytes.
  2226.  */
  2227. int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence)
  2228. {
  2229. FLAC__ASSERT(offset <= 0x7fffffff);
  2230. return fseek((FILE*)handle, (long)offset, whence);
  2231. }
  2232. FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle)
  2233. {
  2234. return (long)ftell((FILE*)handle);
  2235. }
  2236. FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status)
  2237. {
  2238. switch(status) {
  2239. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK:
  2240. return FLAC__METADATA_CHAIN_STATUS_OK;
  2241. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT:
  2242. return FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT;
  2243. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE:
  2244. return FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;
  2245. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE:
  2246. return FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE;
  2247. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE:
  2248. return FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE;
  2249. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA:
  2250. return FLAC__METADATA_CHAIN_STATUS_BAD_METADATA;
  2251. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR:
  2252. return FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
  2253. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR:
  2254. return FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;
  2255. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR:
  2256. return FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;
  2257. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR:
  2258. return FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR;
  2259. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR:
  2260. return FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR;
  2261. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR:
  2262. return FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
  2263. case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR:
  2264. default:
  2265. return FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR;
  2266. }
  2267. }