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; }
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; }
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; }
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; }