add FLAC__metadata_chain_read_with_callbacks()
diff --git a/src/libFLAC/metadata_iterators.c b/src/libFLAC/metadata_iterators.c
index f00af24..19bf015 100644
--- a/src/libFLAC/metadata_iterators.c
+++ b/src/libFLAC/metadata_iterators.c
@@ -740,7 +740,7 @@
} 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__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 @@
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__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__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 @@
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;
}