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

📄 metadata_iterators.c

📁 wince下著名的视频播放器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	else		node->next->prev = node->prev;	if(0 != chain->tail)		chain->tail->data->is_last = true;	chain->nodes--;}static void chain_delete_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node){	chain_remove_node_(chain, node);	node_delete_(node);}static unsigned chain_calculate_length_(FLAC__Metadata_Chain *chain){	const FLAC__Metadata_Node *node;	unsigned length = 0;	for(node = chain->head; node; node = node->next)		length += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length);	return length;}static void iterator_insert_node_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node){	FLAC__ASSERT(0 != node);	FLAC__ASSERT(0 != node->data);	FLAC__ASSERT(0 != iterator);	FLAC__ASSERT(0 != iterator->current);	FLAC__ASSERT(0 != iterator->chain);	FLAC__ASSERT(0 != iterator->chain->head);	FLAC__ASSERT(0 != iterator->chain->tail);	node->data->is_last = false;	node->prev = iterator->current->prev;	node->next = iterator->current;	if(0 == node->prev)		iterator->chain->head = node;	else		node->prev->next = node;	iterator->current->prev = node;	iterator->chain->nodes++;}static void iterator_insert_node_after_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node){	FLAC__ASSERT(0 != node);	FLAC__ASSERT(0 != node->data);	FLAC__ASSERT(0 != iterator);	FLAC__ASSERT(0 != iterator->current);	FLAC__ASSERT(0 != iterator->chain);	FLAC__ASSERT(0 != iterator->chain->head);	FLAC__ASSERT(0 != iterator->chain->tail);	iterator->current->data->is_last = false;	node->prev = iterator->current;	node->next = iterator->current->next;	if(0 == node->next)		iterator->chain->tail = node;	else		node->next->prev = node;	node->prev->next = node;	iterator->chain->tail->data->is_last = true;	iterator->chain->nodes++;}/* return true iff node and node->next are both padding */static FLAC__bool chain_merge_adjacent_padding_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node){	if(node->data->type == FLAC__METADATA_TYPE_PADDING && 0 != node->next && node->next->data->type == FLAC__METADATA_TYPE_PADDING) {		const unsigned growth = FLAC__STREAM_METADATA_HEADER_LENGTH + node->next->data->length;		node->data->length += growth;		chain_delete_node_(chain, node->next);		return true;	}	else		return false;}/* Returns the new length of the chain, or 0 if there was an error. *//* WATCHOUT: This can get called multiple times before a write, so * it should still work when this happens. *//* WATCHOUT: Make sure to also update the logic in * FLAC__metadata_chain_check_if_tempfile_needed() if the logic here changes. */static unsigned chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding){	unsigned current_length = chain_calculate_length_(chain);	if(use_padding) {		/* if the metadata shrank and the last block is padding, we just extend the last padding block */		if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {			const unsigned delta = chain->initial_length - current_length;			chain->tail->data->length += delta;			current_length += delta;			FLAC__ASSERT(current_length == chain->initial_length);		}		/* if the metadata shrank more than 4 bytes then there's room to add another padding block */		else if(current_length + FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) {			FLAC__StreamMetadata *padding;			FLAC__Metadata_Node *node;			if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) {				chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;				return 0;			}			padding->length = chain->initial_length - (FLAC__STREAM_METADATA_HEADER_LENGTH + current_length);			if(0 == (node = node_new_())) {				FLAC__metadata_object_delete(padding);				chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;				return 0;			}			node->data = padding;			chain_append_node_(chain, node);			current_length = chain_calculate_length_(chain);			FLAC__ASSERT(current_length == chain->initial_length);		}		/* 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 */		else if(current_length > chain->initial_length) {			const unsigned delta = current_length - chain->initial_length;			if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) {				/* if the delta is exactly the size of the last padding block, remove the padding block */				if(chain->tail->data->length + FLAC__STREAM_METADATA_HEADER_LENGTH == delta) {					chain_delete_node_(chain, chain->tail);					current_length = chain_calculate_length_(chain);					FLAC__ASSERT(current_length == chain->initial_length);				}				/* if there is at least 'delta' bytes of padding, trim the padding down */				else if(chain->tail->data->length >= delta) {					chain->tail->data->length -= delta;					current_length -= delta;					FLAC__ASSERT(current_length == chain->initial_length);				}			}		}	}	return current_length;}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){	FLAC__Metadata_Node *node;	FLAC__ASSERT(0 != chain);	/* we assume we're already at the beginning of the file */	switch(seek_to_first_metadata_block_cb_(handle, read_cb, seek_cb)) {		case 0:			break;		case 1:			chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;			return false;		case 2:			chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;			return false;		case 3:			chain->status = FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE;			return false;		default:			FLAC__ASSERT(0);			return false;	}	{		FLAC__int64 pos = tell_cb(handle);		if(pos < 0) {			chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;			return false;		}		chain->first_offset = (long)pos;	}	{		FLAC__bool is_last;		FLAC__MetadataType type;		unsigned length;		do {			node = node_new_();			if(0 == node) {				chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;				return false;			}			if(!read_metadata_block_header_cb_(handle, read_cb, &is_last, &type, &length)) {				chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;				return false;			}			node->data = FLAC__metadata_object_new(type);			if(0 == node->data) {				node_delete_(node);				chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;				return false;			}			node->data->is_last = is_last;			node->data->length = length;			chain->status = get_equivalent_status_(read_metadata_block_data_cb_(handle, read_cb, seek_cb, node->data));			if(chain->status != FLAC__METADATA_CHAIN_STATUS_OK) {				node_delete_(node);				return false;			}			chain_append_node_(chain, node);		} while(!is_last);	}	{		FLAC__int64 pos = tell_cb(handle);		if(pos < 0) {			chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;			return false;		}		chain->last_offset = (long)pos;	}	chain->initial_length = chain_calculate_length_(chain);	return true;}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){	FLAC__Metadata_Node *node;	FLAC__ASSERT(0 != chain);	FLAC__ASSERT(0 != chain->head);	if(0 != seek_cb(handle, chain->first_offset, SEEK_SET)) {		chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;		return false;	}	for(node = chain->head; node; node = node->next) {		if(!write_metadata_block_header_cb_(handle, write_cb, node->data)) {			chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;			return false;		}		if(!write_metadata_block_data_cb_(handle, write_cb, node->data)) {			chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;			return false;		}	}	/*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/	chain->status = FLAC__METADATA_CHAIN_STATUS_OK;	return true;}static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain){	FILE *file;	FLAC__bool ret;	FLAC__ASSERT(0 != chain->filename);	if(0 == (file = fopen(chain->filename, "r+b"))) {		chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;		return false;	}	/* chain_rewrite_metadata_in_place_cb_() sets chain->status for us */	ret = chain_rewrite_metadata_in_place_cb_(chain, (FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, fseek_wrapper_);	fclose(file);	return ret;}static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix){	FILE *f, *tempfile;	char *tempfilename;	FLAC__Metadata_SimpleIteratorStatus status;	const FLAC__Metadata_Node *node;	FLAC__ASSERT(0 != chain);	FLAC__ASSERT(0 != chain->filename);	FLAC__ASSERT(0 != chain->head);	/* copy the file prefix (data up to first metadata block */	if(0 == (f = fopen(chain->filename, "rb"))) {		chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE;		return false;	}	if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) {		chain->status = get_equivalent_status_(status);		cleanup_tempfile_(&tempfile, &tempfilename);		return false;	}	if(!copy_n_bytes_from_file_(f, tempfile, chain->first_offset, &status)) {		chain->status = get_equivalent_status_(status);		cleanup_tempfile_(&tempfile, &tempfilename);		return false;	}	/* write the metadata */	for(node = chain->head; node; node = node->next) {		if(!write_metadata_block_header_(tempfile, &status, node->data)) {			chain->status = get_equivalent_status_(status);			return false;		}		if(!write_metadata_block_data_(tempfile, &status, node->data)) {			chain->status = get_equivalent_status_(status);			return false;		}	}	/*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/	/* copy the file postfix (everything after the metadata) */	if(0 != fseek(f, chain->last_offset, SEEK_SET)) {		cleanup_tempfile_(&tempfile, &tempfilename);		chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR;		return false;	}	if(!copy_remaining_bytes_from_file_(f, tempfile, &status)) {		cleanup_tempfile_(&tempfile, &tempfilename);		chain->status = get_equivalent_status_(status);		return false;	}	/* move the tempfile on top of the original */	(void)fclose(f);	if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status))		return false;	return true;}/* assumes 'handle' is already at beginning of file */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){	FLAC__Metadata_SimpleIteratorStatus status;	const FLAC__Metadata_Node *node;	FLAC__ASSERT(0 != chain);	FLAC__ASSERT(0 == chain->filename);	FLAC__ASSERT(0 != chain->head);	/* copy the file prefix (data up to first metadata block */	if(!copy_n_bytes_from_file_cb_(handle, read_cb, temp_handle, temp_write_cb, chain->first_offset, &status)) {		chain->status = get_equivalent_status_(status);		return false;	}	/* write the metadata */	for(node = chain->head; node; node = node->next) {		if(!write_metadata_block_header_cb_(temp_handle, temp_write_cb, node->data)) {			chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;			return false;		}		if(!write_metadata_block_data_cb_(temp_handle, temp_write_cb, node->data)) {			chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR;			return false;		}	}	/*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/	/* copy the file postfix (everything after the metadata) */	if(0 != seek_cb(handle, chain->last_offset, SEEK_SET)) {

⌨️ 快捷键说明

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