Example #1
0
static FLAC__bool vorbiscomment_set_entry_(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry *dest, const FLAC__StreamMetadata_VorbisComment_Entry *src, FLAC__bool copy)
{
	FLAC__byte *save;

	FLAC__ASSERT(0 != object);
	FLAC__ASSERT(0 != dest);
	FLAC__ASSERT(0 != src);
	FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
	FLAC__ASSERT((0 != src->entry && src->length > 0) || (0 == src->entry && src->length == 0));

	save = dest->entry;

	/* do the copy first so that if we fail we leave the object untouched */
	if(copy && (0 != src->entry && src->length > 0)) {
		if(!copy_vcentry_(dest, src))
			return false;
	}
	else {
		/* either we're not copying or the src is null */
		*dest = *src;
	}

	if(0 != save)
		free(save);

	vorbiscomment_calculate_length_(object);
	return true;
}
Example #2
0
static FLAC__bool vorbiscomment_set_entry_(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry *dest, const FLAC__StreamMetadata_VorbisComment_Entry *src, FLAC__bool copy)
{
	FLAC__byte *save;

	FLAC__ASSERT(0 != object);
	FLAC__ASSERT(0 != dest);
	FLAC__ASSERT(0 != src);
	FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
	FLAC__ASSERT((0 != src->entry && src->length > 0) || (0 == src->entry && src->length == 0));

	save = dest->entry;

	if(0 != src->entry && src->length > 0) {
		if(copy) {
			/* do the copy first so that if we fail we leave the dest object untouched */
			if(!copy_vcentry_(dest, src))
				return false;
		}
		else {
			/* we have to make sure that the string we're taking over is null-terminated */

			/*
			 * Stripping the const from src->entry is OK since we're taking
			 * ownership of the pointer.  This is a hack around a deficiency
			 * in the API where the same function is used for 'copy' and
			 * 'own', but the source entry is a const pointer.  If we were
			 * precise, the 'own' flavor would be a separate function with a
			 * non-const source pointer.  But it's not, so we hack away.
			 */
			if(!ensure_null_terminated_((FLAC__byte**)(&src->entry), src->length))
				return false;
			*dest = *src;
		}
	}
	else {
		/* the src is null */
		*dest = *src;
	}

	if(0 != save)
		free(save);

	vorbiscomment_calculate_length_(object);
	return true;
}
Example #3
0
static FLAC__StreamMetadata_VorbisComment_Entry *vorbiscomment_entry_array_copy_(const FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments)
{
	FLAC__StreamMetadata_VorbisComment_Entry *return_array;

	FLAC__ASSERT(0 != object_array);
	FLAC__ASSERT(num_comments > 0);

	return_array = vorbiscomment_entry_array_new_(num_comments);

	if(0 != return_array) {
		unsigned i;

		for(i = 0; i < num_comments; i++) {
			if(!copy_vcentry_(return_array+i, object_array+i)) {
				vorbiscomment_entry_array_delete_(return_array, num_comments);
				return 0;
			}
		}
	}

	return return_array;
}
Example #4
0
FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object)
{
	FLAC__StreamMetadata *to;

	FLAC__ASSERT(0 != object);

	if(0 != (to = FLAC__metadata_object_new(object->type))) {
		to->is_last = object->is_last;
		to->type = object->type;
		to->length = object->length;
		switch(to->type) {
			case FLAC__METADATA_TYPE_STREAMINFO:
				memcpy(&to->data.stream_info, &object->data.stream_info, sizeof(FLAC__StreamMetadata_StreamInfo));
				break;
			case FLAC__METADATA_TYPE_PADDING:
				break;
			case FLAC__METADATA_TYPE_APPLICATION:
				memcpy(&to->data.application.id, &object->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8);
				if(!copy_bytes_(&to->data.application.data, object->data.application.data, object->length - FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) {
					FLAC__metadata_object_delete(to);
					return 0;
				}
				break;
			case FLAC__METADATA_TYPE_SEEKTABLE:
				to->data.seek_table.num_points = object->data.seek_table.num_points;
				if(!copy_bytes_((FLAC__byte**)&to->data.seek_table.points, (FLAC__byte*)object->data.seek_table.points, object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint))) {
					FLAC__metadata_object_delete(to);
					return 0;
				}
				break;
			case FLAC__METADATA_TYPE_VORBIS_COMMENT:
				if(0 != to->data.vorbis_comment.vendor_string.entry) {
					free(to->data.vorbis_comment.vendor_string.entry);
					to->data.vorbis_comment.vendor_string.entry = 0;
				}
				if(!copy_vcentry_(&to->data.vorbis_comment.vendor_string, &object->data.vorbis_comment.vendor_string)) {
					FLAC__metadata_object_delete(to);
					return 0;
				}
				if(object->data.vorbis_comment.num_comments == 0) {
					FLAC__ASSERT(0 == object->data.vorbis_comment.comments);
					to->data.vorbis_comment.comments = 0;
				}
				else {
					FLAC__ASSERT(0 != object->data.vorbis_comment.comments);
					to->data.vorbis_comment.comments = vorbiscomment_entry_array_copy_(object->data.vorbis_comment.comments, object->data.vorbis_comment.num_comments);
					if(0 == to->data.vorbis_comment.comments) {
						FLAC__metadata_object_delete(to);
						return 0;
					}
				}
				to->data.vorbis_comment.num_comments = object->data.vorbis_comment.num_comments;
				break;
			case FLAC__METADATA_TYPE_CUESHEET:
				memcpy(&to->data.cue_sheet, &object->data.cue_sheet, sizeof(FLAC__StreamMetadata_CueSheet));
				if(object->data.cue_sheet.num_tracks == 0) {
					FLAC__ASSERT(0 == object->data.cue_sheet.tracks);
				}
				else {
					FLAC__ASSERT(0 != object->data.cue_sheet.tracks);
					to->data.cue_sheet.tracks = cuesheet_track_array_copy_(object->data.cue_sheet.tracks, object->data.cue_sheet.num_tracks);
					if(0 == to->data.cue_sheet.tracks) {
						FLAC__metadata_object_delete(to);
						return 0;
					}
				}
				break;
			default:
				if(!copy_bytes_(&to->data.unknown.data, object->data.unknown.data, object->length)) {
					FLAC__metadata_object_delete(to);
					return 0;
				}
				break;
		}
	}

	return to;
}