add FLAC__metadata_chain_read_with_callbacks()
This commit is contained in:
parent
ea25cb3615
commit
91748beb86
@ -585,9 +585,12 @@ typedef enum {
|
||||
FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR,
|
||||
/**< Memory allocation failed */
|
||||
|
||||
FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR
|
||||
FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR,
|
||||
/**< The caller violated an assertion or an unexpected error occurred */
|
||||
|
||||
FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS
|
||||
/**< One or more of the required callbacks was NULL */
|
||||
|
||||
} FLAC__Metadata_ChainStatus;
|
||||
|
||||
/** Maps a FLAC__Metadata_ChainStatus to a C string.
|
||||
@ -640,6 +643,24 @@ FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_C
|
||||
*/
|
||||
FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename);
|
||||
|
||||
/** Read all metadata from a FLAC stream into the chain via I/O callbacks.
|
||||
*
|
||||
* \param chain A pointer to an existing chain.
|
||||
* \param handle The I/O handle of the FLAC stream to read. The
|
||||
* handle will be closed after the metadata is read.
|
||||
* \param callbacks
|
||||
* A set of callbacks to use for I/O. The mandatory
|
||||
* callbacks are \a read, \a seek, \a tell, and
|
||||
* \a close.
|
||||
* \assert
|
||||
* \code chain != NULL \endcode
|
||||
* \retval FLAC__bool
|
||||
* \c true if a valid list of metadata blocks was read from
|
||||
* \a handle, else \c false. On failure, check the status with
|
||||
* FLAC__metadata_chain_status().
|
||||
*/
|
||||
FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks);
|
||||
|
||||
/** Write all metadata out to the FLAC file. This function tries to be as
|
||||
* efficient as possible; how the metadata is actually written is shown by
|
||||
* the following:
|
||||
|
@ -740,7 +740,7 @@ typedef struct FLAC__Metadata_Node {
|
||||
} FLAC__Metadata_Node;
|
||||
|
||||
struct FLAC__Metadata_Chain {
|
||||
char *filename;
|
||||
char *filename; /* will be NULL if using callbacks */
|
||||
FLAC__Metadata_Node *head;
|
||||
FLAC__Metadata_Node *tail;
|
||||
unsigned nodes;
|
||||
@ -772,7 +772,8 @@ FLAC_API const char * const FLAC__Metadata_ChainStatusString[] = {
|
||||
"FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR",
|
||||
"FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR",
|
||||
"FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR",
|
||||
"FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR"
|
||||
"FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR",
|
||||
"FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS"
|
||||
};
|
||||
|
||||
|
||||
@ -789,6 +790,35 @@ static void node_delete_(FLAC__Metadata_Node *node)
|
||||
free(node);
|
||||
}
|
||||
|
||||
static void chain_init_(FLAC__Metadata_Chain *chain)
|
||||
{
|
||||
FLAC__ASSERT(0 != chain);
|
||||
|
||||
chain->filename = 0;
|
||||
chain->head = chain->tail = 0;
|
||||
chain->nodes = 0;
|
||||
chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
|
||||
chain->initial_length = 0;
|
||||
}
|
||||
|
||||
static void chain_clear_(FLAC__Metadata_Chain *chain)
|
||||
{
|
||||
FLAC__Metadata_Node *node, *next;
|
||||
|
||||
FLAC__ASSERT(0 != chain);
|
||||
|
||||
for(node = chain->head; node; ) {
|
||||
next = node->next;
|
||||
node_delete_(node);
|
||||
node = next;
|
||||
}
|
||||
|
||||
if(0 != chain->filename)
|
||||
free(chain->filename);
|
||||
|
||||
chain_init_(chain);
|
||||
}
|
||||
|
||||
static void chain_append_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node)
|
||||
{
|
||||
FLAC__ASSERT(0 != chain);
|
||||
@ -1003,31 +1033,17 @@ FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new()
|
||||
{
|
||||
FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)calloc(1, sizeof(FLAC__Metadata_Chain));
|
||||
|
||||
if(0 != chain) {
|
||||
chain->filename = 0;
|
||||
chain->head = chain->tail = 0;
|
||||
chain->nodes = 0;
|
||||
chain->status = FLAC__METADATA_CHAIN_STATUS_OK;
|
||||
chain->initial_length = 0;
|
||||
}
|
||||
if(0 != chain)
|
||||
chain_init_(chain);
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain)
|
||||
{
|
||||
FLAC__Metadata_Node *node, *next;
|
||||
|
||||
FLAC__ASSERT(0 != chain);
|
||||
|
||||
for(node = chain->head; node; ) {
|
||||
next = node->next;
|
||||
node_delete_(node);
|
||||
node = next;
|
||||
}
|
||||
|
||||
if(0 != chain->filename)
|
||||
free(chain->filename);
|
||||
chain_clear_(chain);
|
||||
|
||||
free(chain);
|
||||
}
|
||||
@ -1050,6 +1066,8 @@ FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const
|
||||
FLAC__ASSERT(0 != chain);
|
||||
FLAC__ASSERT(0 != filename);
|
||||
|
||||
chain_clear_(chain);
|
||||
|
||||
if(0 == (chain->filename = strdup(filename))) {
|
||||
chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
@ -1063,6 +1081,27 @@ FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const
|
||||
if(!chain_read_cb_(chain, file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, ftell_wrapper_, (FLAC__IOCallback_Close)fclose))
|
||||
return false; /* chain->status is already set by chain_read_cb_ */
|
||||
|
||||
/* chain_read_cb_() closes the file handle */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
FLAC__ASSERT(0 != chain);
|
||||
|
||||
chain_clear_(chain);
|
||||
|
||||
if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.tell || 0 == callbacks.close) {
|
||||
chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!chain_read_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.tell, callbacks.close))
|
||||
return false; /* chain->status is already set by chain_read_cb_ */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user