Commit 91748beb authored by Josh Coalson's avatar Josh Coalson
Browse files

add FLAC__metadata_chain_read_with_callbacks()

parent ea25cb36
......@@ -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;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment