⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 metadata_iterators.c

📁 wince下著名的视频播放器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001,2002,2003,2004,2005  Josh Coalson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Xiph.org Foundation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "private/metadata.h"#include "FLAC/assert.h"#include "FLAC/file_decoder.h"#ifdef max#undef max#endif#define max(a,b) ((a)>(b)?(a):(b))#ifdef min#undef min#endif#define min(a,b) ((a)<(b)?(a):(b))/**************************************************************************** * * Local function declarations * ***************************************************************************/static void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes);static void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes);static void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes);static FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes);static FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes);static FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes);static FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator);static FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block);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);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);static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block);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);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);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);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);static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment *block);static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track);static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block);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);static FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block);static FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block);static FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block);static FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block);static FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block);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);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);static FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block);static FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block);static FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block);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);static FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block);static FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last);static FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append);static void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator);static FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator);static unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb);static unsigned seek_to_first_metadata_block_(FILE *f);static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append);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);static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status);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);static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status);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);static FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status);static FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status);static void cleanup_tempfile_(FILE **tempfile, char **tempfilename);static FLAC__bool get_file_stats_(const char *filename, struct stat *stats);static void set_file_stats_(const char *filename, struct stat *stats);static int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence);static FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle);static FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status);#ifdef FLAC__VALGRIND_TESTINGstatic size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream){	size_t ret = fwrite(ptr, size, nmemb, stream);	if(!ferror(stream))		fflush(stream);	return ret;}#else#define local__fwrite fwrite#endif/**************************************************************************** * * Level 1 implementation * ***************************************************************************/#define SIMPLE_ITERATOR_MAX_PUSH_DEPTH (1+4)/* 1 for initial offset, +4 for our own personal use */struct FLAC__Metadata_SimpleIterator {	FILE *file;	char *filename, *tempfile_path_prefix;	FLAC__bool is_writable;	FLAC__Metadata_SimpleIteratorStatus status;	/*@@@ 2G limits here because of the offset type: */	long offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH];	long first_offset; /* this is the offset to the STREAMINFO block */	unsigned depth;	/* this is the metadata block header of the current block we are pointing to: */	FLAC__bool is_last;	FLAC__MetadataType type;	unsigned length;};FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[] = {	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR",	"FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR"};FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(){	FLAC__Metadata_SimpleIterator *iterator = (FLAC__Metadata_SimpleIterator*)calloc(1, sizeof(FLAC__Metadata_SimpleIterator));	if(0 != iterator) {		iterator->file = 0;		iterator->filename = 0;		iterator->tempfile_path_prefix = 0;		iterator->is_writable = false;		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;		iterator->first_offset = iterator->offset[0] = -1;		iterator->depth = 0;	}	return iterator;}static void simple_iterator_free_guts_(FLAC__Metadata_SimpleIterator *iterator){	FLAC__ASSERT(0 != iterator);	if(0 != iterator->file) {		fclose(iterator->file);		iterator->file = 0;	}	if(0 != iterator->filename) {		free(iterator->filename);		iterator->filename = 0;	}	if(0 != iterator->tempfile_path_prefix) {		free(iterator->tempfile_path_prefix);		iterator->tempfile_path_prefix = 0;	}}FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator){	FLAC__ASSERT(0 != iterator);	simple_iterator_free_guts_(iterator);	free(iterator);}FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator){	FLAC__Metadata_SimpleIteratorStatus status;	FLAC__ASSERT(0 != iterator);	status = iterator->status;	iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;	return status;}static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool read_only){	unsigned ret;	FLAC__ASSERT(0 != iterator);	if(read_only || 0 == (iterator->file = fopen(iterator->filename, "r+b"))) {		iterator->is_writable = false;		if(read_only) {			if(0 == (iterator->file = fopen(iterator->filename, "rb"))) {				iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;				return false;			}		}		else {			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE;			return false;		}	}	else {		iterator->is_writable = true;	}	ret = seek_to_first_metadata_block_(iterator->file);	switch(ret) {		case 0:			iterator->depth = 0;			iterator->first_offset = iterator->offset[iterator->depth] = ftell(iterator->file);			return read_metadata_block_header_(iterator);		case 1:			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;			return false;		case 2:			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;			return false;		case 3:			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE;			return false;		default:			FLAC__ASSERT(0);			return false;	}}#if 0@@@ If we decide to finish implementing this, put this comment back in metadata.h/* * The 'tempfile_path_prefix' allows you to specify a directory where * tempfiles should go.  Remember that if your metadata edits cause the * FLAC file to grow, the entire file will have to be rewritten.  If * 'tempfile_path_prefix' is NULL, the temp file will be written in the * same directory as the original FLAC file.  This makes replacing the * original with the tempfile fast but requires extra space in the same * partition for the tempfile.  If space is a problem, you can pass a * directory name belonging to a different partition in * 'tempfile_path_prefix'.  Note that you should use the forward slash * '/' as the directory separator.  A trailing slash is not needed; it * will be added automatically. */FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool preserve_file_stats, const char *tempfile_path_prefix);#endifFLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats){	const char *tempfile_path_prefix = 0; /*@@@ search for comments near 'rename(...)' for what it will take to finish implementing this */	FLAC__ASSERT(0 != iterator);	FLAC__ASSERT(0 != filename);	simple_iterator_free_guts_(iterator);	if(0 == (iterator->filename = _strdup(filename))) {		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;		return false;	}	if(0 != tempfile_path_prefix && 0 == (iterator->tempfile_path_prefix = _strdup(tempfile_path_prefix))) {		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;		return false;	}	return simple_iterator_prime_input_(iterator, read_only);}FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator){	FLAC__ASSERT(0 != iterator);	FLAC__ASSERT(0 != iterator->file);	return iterator->is_writable;}FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator){	FLAC__ASSERT(0 != iterator);	FLAC__ASSERT(0 != iterator->file);	if(iterator->is_last)		return false;	if(0 != fseek(iterator->file, iterator->length, SEEK_CUR)) {		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;		return false;	}	iterator->offset[iterator->depth] = ftell(iterator->file);	return read_metadata_block_header_(iterator);}FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator){	long this_offset;	FLAC__ASSERT(0 != iterator);	FLAC__ASSERT(0 != iterator->file);	if(iterator->offset[iterator->depth] == iterator->first_offset)		return false;	if(0 != fseek(iterator->file, iterator->first_offset, SEEK_SET)) {		iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;		return false;	}	this_offset = iterator->first_offset;	if(!read_metadata_block_header_(iterator))		return false;	/* we ignore any error from ftell() and catch it in fseek() */	while(ftell(iterator->file) + (long)iterator->length < iterator->offset[iterator->depth]) {		if(0 != fseek(iterator->file, iterator->length, SEEK_CUR)) {			iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;			return false;		}		this_offset = ftell(iterator->file);		if(!read_metadata_block_header_(iterator))			return false;	}	iterator->offset[iterator->depth] = this_offset;	return true;}FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator){	FLAC__ASSERT(0 != iterator);	FLAC__ASSERT(0 != iterator->file);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -