Add --append option to metaflac

This commit is contained in:
Martijn van Beurden 2023-02-14 20:31:39 +01:00
parent b11677e052
commit 8e563a697d
2 changed files with 69 additions and 9 deletions

View File

@ -213,9 +213,71 @@ FLAC__bool do_major_operation__list(const char *filename, FLAC__Metadata_Chain *
FLAC__bool do_major_operation__append(FLAC__Metadata_Chain *chain, const CommandLineOptions *options)
{
(void) chain, (void) options;
flac_fprintf(stderr, "ERROR: --append not implemented yet\n");
return false;
FLAC__byte header[FLAC__STREAM_METADATA_HEADER_LENGTH];
FLAC__byte *buffer;
FLAC__uint32 buffer_size, num_objects = 0, i, append_after = UINT32_MAX;
FLAC__StreamMetadata *object;
FLAC__Metadata_Iterator *iterator;
/* First, find out after which block appending should take place */
for(i = 0; i < options->args.num_arguments; i++) {
if(options->args.arguments[i].type == ARG__BLOCK_NUMBER) {
if(append_after != UINT32_MAX || options->args.arguments[i].value.block_number.num_entries > 1) {
flac_fprintf(stderr, "ERROR: more than one block number specified with --append\n");
return false;
}
append_after = options->args.arguments[i].value.block_number.entries[0];
}
}
iterator = FLAC__metadata_iterator_new();
if(0 == iterator)
die("out of memory allocating iterator");
FLAC__metadata_iterator_init(iterator, chain);
/* Go to requested block */
for(i = 0; i < append_after; i++) {
if(!FLAC__metadata_iterator_next(iterator))
break;
}
/* Read header from stdin */
while(fread(header, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, stdin) == FLAC__STREAM_METADATA_HEADER_LENGTH) {
buffer_size = ((FLAC__uint32)(header[1]) << 16) + ((FLAC__uint32)(header[2]) << 8) + header[3];
buffer = safe_malloc_(buffer_size + FLAC__STREAM_METADATA_HEADER_LENGTH);
memcpy(buffer, header, FLAC__STREAM_METADATA_HEADER_LENGTH);
if(fread(buffer+FLAC__STREAM_METADATA_HEADER_LENGTH, 1, buffer_size, stdin) < buffer_size) {
flac_fprintf(stderr, "ERROR: couldn't read metadata block #%u from stdin\n",(num_objects+1));
free(buffer);
break;
}
if((object = FLAC__metadata_object_set_raw(buffer, buffer_size + FLAC__STREAM_METADATA_HEADER_LENGTH)) == NULL) {
flac_fprintf(stderr, "ERROR: couldn't parse supplied metadata block #%u\n",(num_objects+1));
free(buffer);
break;
}
free(buffer);
if(!FLAC__metadata_iterator_insert_block_after(iterator, object)) {
flac_fprintf(stderr, "ERROR: couldn't add supplied metadata block #%u to file\n",(num_objects+1));
FLAC__metadata_object_delete(object);
FLAC__metadata_iterator_delete(iterator);
break;
}
num_objects++;
}
if(num_objects == 0)
flac_fprintf(stderr, "ERROR: unable to find a metadata block in the supplied input\n");
FLAC__metadata_iterator_delete(iterator);
return true;
}
FLAC__bool do_major_operation__remove(FLAC__Metadata_Chain *chain, const CommandLineOptions *options)

View File

@ -280,18 +280,14 @@ int long_usage(const char *message, ...)
fprintf(out, " You may specify --data-format=binary to dump the raw binary form of each\n");
fprintf(out, " metadata block. Specify --data-format=binary-headerless to omit output of\n");
fprintf(out, " metadata block headers, including the id of APPLICATION metadata blocks.\n");
#if 0
fprintf(out, " The output can be read in using a subsequent call\n");
fprintf(out, " to \"metaflac --append --from-file=...\"\n");
#endif
fprintf(out, " The output can be read in using a subsequent call to\n");
fprintf(out, " \"metaflac --append\"\n");
fprintf(out, "\n");
fprintf(out, " --application-data-format=hexdump|text\n");
fprintf(out, " If the application block you are displaying contains binary data but your\n");
fprintf(out, " --data-format=text, you can display a hex dump of the application data\n");
fprintf(out, " contents instead using --application-data-format=hexdump\n");
fprintf(out, "\n");
#if 0
/*@@@ not implemented yet */
fprintf(out, "--append\n");
fprintf(out, " Insert a metadata block from a file. The input file must be in the same\n");
fprintf(out, " format as generated with --list.\n");
@ -302,6 +298,8 @@ int long_usage(const char *message, ...)
fprintf(out, " of a block before the first STREAMINFO block. You may not --append another\n");
fprintf(out, " STREAMINFO block.\n");
fprintf(out, "\n");
#if 0
/*@@@ not implemented yet */
fprintf(out, " --from-file=filename\n");
fprintf(out, " Mandatory 'option' to specify the input file containing the block contents.\n");
fprintf(out, "\n");