diff options
-rw-r--r-- | libs/ardour/lv2_pfile.h | 121 | ||||
-rw-r--r-- | libs/ardour/lv2_plugin.cc | 23 | ||||
-rw-r--r-- | libs/ardour/rdff.c (renamed from libs/ardour/lv2_pfile.c) | 88 | ||||
-rw-r--r-- | libs/ardour/rdff.h | 121 | ||||
-rw-r--r-- | libs/ardour/wscript | 2 |
5 files changed, 176 insertions, 179 deletions
diff --git a/libs/ardour/lv2_pfile.h b/libs/ardour/lv2_pfile.h deleted file mode 100644 index 8cc97875db..0000000000 --- a/libs/ardour/lv2_pfile.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - Portable file-based LV2 Persist implementation. - See <http://lv2plug.in/ns/ext/persist> for details. - - Copyright 2011 David Robillard <http://drobilla.net> - - This is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This software is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this sofware; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ - -#ifndef LV2PFILE_H -#define LV2PFILE_H - -#include <stdbool.h> -#include <stdint.h> - -#ifdef __GNUC__ -# define PACKED __attribute__((__packed__)) -#else -# define PACKED -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _LV2PFile* LV2PFile; -typedef struct _LV2PFile_Iterator* LV2PFile_Iterator; - -typedef enum { - LV2_PFILE_OK = 0, - LV2_PFILE_UNKNOWN_ERROR = 1, - LV2_PFILE_EOF = 2, - LV2_PFILE_CORRUPT = 3 -} LV2PFileStatus; - -typedef struct { - char type[4]; - uint32_t size; - char data[]; -} PACKED LV2PFileChunkHeader; - -typedef struct { - uint32_t id; - char uri[]; -} PACKED LV2PFileURIChunk; - -typedef struct { - uint32_t key; - uint32_t type; - uint32_t size; - char value[]; -} PACKED LV2PFileValueChunk; - -/** - Open/Create a new persist file. -*/ -LV2PFile -lv2_pfile_open(const char* path, bool write); - -/** - Write a URI ID to @a file. -*/ -LV2PFileStatus -lv2_pfile_write_uri(LV2PFile file, - uint32_t id, - const char* uri, - uint32_t size); - -/** - Write a key/value record to @a file. -*/ -LV2PFileStatus -lv2_pfile_write_value(LV2PFile file, - uint32_t key, - const void* value, - uint32_t size, - uint32_t type); -LV2PFileStatus -lv2_pfile_read_chunk(LV2PFile file, - LV2PFileChunkHeader** buf); - -/** - Read a record from a persist file. - @a key and @a value are allocated with malloc and must be freed by caller. -*/ -#if 0 -LV2PFileStatus -lv2_pfile_read(LV2PFile file, - char** key, - uint32_t* key_len, - char** type, - uint32_t* type_len, - void** value, - uint64_t* size); -#endif - -/** - Close @a file. - After this call, @a file is invalid. -*/ -void -lv2_pfile_close(LV2PFile file); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LV2PFILE_H */ diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index f2016e6340..3832a899e7 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -46,7 +46,7 @@ #include <locale.h> #include "lv2ext/lv2_persist.h" -#include "lv2_pfile.h" +#include "rdff.h" #define NS_DC "http://dublincore.org/documents/dcmi-namespace/" #define NS_LV2 "http://lv2plug.in/ns/lv2core#" @@ -442,12 +442,12 @@ LV2Plugin::add_state(XMLNode* root) const &state); // Open state file - LV2PFile file = lv2_pfile_open(state_path.c_str(), true); + RDFF file = rdff_open(state_path.c_str(), true); // Write all referenced URIs to state file for (PersistState::URIs::const_iterator i = state.uris.begin(); i != state.uris.end(); ++i) { - lv2_pfile_write_uri(file, i->first, + rdff_write_uri(file, i->first, i->second.c_str(), i->second.length() + 1); } @@ -456,7 +456,7 @@ LV2Plugin::add_state(XMLNode* root) const i != state.values.end(); ++i) { const uint32_t key = i->first; const PersistValue& val = i->second; - lv2_pfile_write_value(file, + rdff_write_value(file, key, val.value, val.size, @@ -464,7 +464,7 @@ LV2Plugin::add_state(XMLNode* root) const } // Close state file - lv2_pfile_close(file); + rdff_close(file); root->add_property("state-file", state_filename); } @@ -631,21 +631,20 @@ LV2Plugin::set_state(const XMLNode& node, int version) _instance, "http://lv2plug.in/ns/ext/persist"); if (persist) { cout << "Loading LV2 state from " << state_path << endl; - LV2PFile file = lv2_pfile_open(state_path.c_str(), false); + RDFF file = rdff_open(state_path.c_str(), false); PersistState state(_uri_map); // Load file into state object - LV2PFileChunkHeader* chunk = (LV2PFileChunkHeader*)malloc( - sizeof(LV2PFileChunkHeader)); + RDFFChunk* chunk = (RDFFChunk*)malloc(sizeof(RDFFChunk)); chunk->size = 0; - while (!lv2_pfile_read_chunk(file, &chunk)) { + while (!rdff_read_chunk(file, &chunk)) { if (!strncmp(chunk->type, "URID", 4)) { - LV2PFileURIChunk* body = (LV2PFileURIChunk*)chunk->data; + RDFFURIChunk* body = (RDFFURIChunk*)chunk->data; printf("READ URI %u: %s\n", body->id, body->uri); state.add_uri(body->id, body->uri); } else if (!strncmp(chunk->type, "KVAL", 4)) { - LV2PFileValueChunk* body = (LV2PFileValueChunk*)chunk->data; + RDFFValueChunk* body = (RDFFValueChunk*)chunk->data; printf("READ VAL %u = %s (size: %u type: %u)\n", body->key, body->value, body->size, body->type); state.add_value(body->key, @@ -660,7 +659,7 @@ LV2Plugin::set_state(const XMLNode& node, int version) persist->restore(_instance->lv2_handle, &LV2Plugin::lv2_persist_retrieve_callback, &state); - lv2_pfile_close(file); + rdff_close(file); } else { warning << string_compose( _("Plugin \"%1\% failed to return LV2 persist data"), diff --git a/libs/ardour/lv2_pfile.c b/libs/ardour/rdff.c index cdf14b2ed2..28fd63c4c4 100644 --- a/libs/ardour/lv2_pfile.c +++ b/libs/ardour/rdff.c @@ -1,7 +1,5 @@ /* - Portable file-based LV2 Persist implementation. - See <http://lv2plug.in/ns/ext/persist> for details. - + RDFF - RDF in RIFF Copyright 2011 David Robillard <http://drobilla.net> This is free software; you can redistribute it and/or modify it @@ -26,22 +24,22 @@ #include <stdlib.h> #include <string.h> -#include "lv2_pfile.h" +#include "rdff.h" #define CHUNK_ID_LEN 4 -static const char FILE_TYPE[CHUNK_ID_LEN] = "LV2F"; /* LV2 RIFF File */ -static const char CHUNK_KVAL[CHUNK_ID_LEN] = "KVAL"; /* Key/Value Chunk */ -static const char CHUNK_URID[CHUNK_ID_LEN] = "URID"; /* URI ID Chunk */ +static const char FILE_TYPE[CHUNK_ID_LEN] = "RDFF"; /* RDFF File ID */ +static const char CHUNK_KVAL[CHUNK_ID_LEN] = "KVAL"; /* Key/Value Chunk ID */ +static const char CHUNK_URID[CHUNK_ID_LEN] = "URID"; /* URI-ID Chunk ID*/ -struct _LV2PFile { +struct _RDFF { FILE* fd; uint32_t size; bool write; }; -LV2PFile -lv2_pfile_open(const char* path, bool write) +RDFF +rdff_open(const char* path, bool write) { FILE* fd = fopen(path, (write ? "w" : "r")); if (!fd) { @@ -78,7 +76,7 @@ lv2_pfile_open(const char* path, bool write) } } - LV2PFile ret = (LV2PFile)malloc(sizeof(struct _LV2PFile)); + RDFF ret = (RDFF)malloc(sizeof(struct _RDFF)); ret->fd = fd; ret->size = size; ret->write = write; @@ -87,14 +85,14 @@ lv2_pfile_open(const char* path, bool write) #define WRITE(ptr, size, nmemb, stream) \ if (fwrite(ptr, size, nmemb, stream) != nmemb) { \ - return LV2_PFILE_UNKNOWN_ERROR; \ + return RDFF_STATUS_UNKNOWN_ERROR; \ } -LV2PFileStatus -lv2_pfile_write_uri(LV2PFile file, - uint32_t id, - const char* uri, - uint32_t len) +RDFFStatus +rdff_write_uri(RDFF file, + uint32_t id, + const char* uri, + uint32_t len) { const uint32_t chunk_size = sizeof(id) + len + 1; WRITE(CHUNK_URID, CHUNK_ID_LEN, 1, file->fd); @@ -105,15 +103,15 @@ lv2_pfile_write_uri(LV2PFile file, WRITE("", 1, 1, file->fd); /* pad */ } file->size += 8 + chunk_size; - return LV2_PFILE_OK; + return RDFF_STATUS_OK; } -LV2PFileStatus -lv2_pfile_write_value(LV2PFile file, - uint32_t key, - const void* value, - uint32_t size, - uint32_t type) +RDFFStatus +rdff_write_value(RDFF file, + uint32_t key, + const void* value, + uint32_t size, + uint32_t type) { const uint32_t chunk_size = sizeof(key) + sizeof(type) + sizeof(size) + size; WRITE(CHUNK_KVAL, CHUNK_ID_LEN, 1, file->fd); @@ -126,19 +124,19 @@ lv2_pfile_write_value(LV2PFile file, WRITE("", 1, 1, file->fd); /* write pad */ } file->size += 8 + chunk_size; - return LV2_PFILE_OK; + return RDFF_STATUS_OK; } -LV2PFileStatus -lv2_pfile_read_chunk(LV2PFile file, - LV2PFileChunkHeader** buf) +RDFFStatus +rdff_read_chunk(RDFF file, + RDFFChunk** buf) { if (feof(file->fd)) - return LV2_PFILE_EOF; + return RDFF_STATUS_EOF; #define READ(ptr, size, nmemb, stream) \ if (fread(ptr, size, nmemb, stream) != nmemb) { \ - return LV2_PFILE_CORRUPT; \ + return RDFF_STATUS_CORRUPT; \ } const uint32_t alloc_size = (*buf)->size; @@ -146,18 +144,18 @@ lv2_pfile_read_chunk(LV2PFile file, READ((*buf)->type, sizeof((*buf)->type), 1, file->fd); READ(&(*buf)->size, sizeof((*buf)->size), 1, file->fd); if ((*buf)->size > alloc_size) { - *buf = realloc(*buf, sizeof(LV2PFileChunkHeader) + (*buf)->size); + *buf = realloc(*buf, sizeof(RDFFChunk) + (*buf)->size); } READ((*buf)->data, (*buf)->size, 1, file->fd); if (((*buf)->size % 2)) { char pad; READ(&pad, 1, 1, file->fd); /* skip pad */ } - return LV2_PFILE_OK; + return RDFF_STATUS_OK; } void -lv2_pfile_close(LV2PFile file) +rdff_close(RDFF file) { if (file) { if (file->write) { @@ -184,7 +182,7 @@ main(int argc, char** argv) const char* const filename = argv[1]; - LV2PFile file = lv2_pfile_open(filename, true); + RDFF file = rdff_open(filename, true); if (!file) goto fail; @@ -194,54 +192,54 @@ main(int argc, char** argv) char uri[64]; for (int i = 0; i < N_URIS; ++i) { snprintf(uri, sizeof(uri), "http://example.org/uri%02d", i + 1); - lv2_pfile_write_uri(file, i + 1, uri, strlen(uri) + 1); + rdff_write_uri(file, i + 1, uri, strlen(uri) + 1); } char val[6]; for (int i = 0; i < N_RECORDS; ++i) { snprintf(val, sizeof(val), "VAL%02d", i); - lv2_pfile_write_value(file, + rdff_write_value(file, rand() % N_URIS, val, sizeof(val), 0); } - lv2_pfile_close(file); + rdff_close(file); - file = lv2_pfile_open(filename, false); + file = rdff_open(filename, false); if (!file) goto fail; - LV2PFileChunkHeader* chunk = malloc(sizeof(LV2PFileChunkHeader)); + RDFFChunk* chunk = malloc(sizeof(RDFFChunk)); chunk->size = 0; for (int i = 0; i < N_URIS; ++i) { - if (lv2_pfile_read_chunk(file, &chunk) + if (rdff_read_chunk(file, &chunk) || strncmp(chunk->type, "URID", 4)) { fprintf(stderr, "error: expected URID chunk\n"); goto fail; } - LV2PFileURIChunk* body = (LV2PFileURIChunk*)chunk->data; + RDFFURIChunk* body = (RDFFURIChunk*)chunk->data; printf("URI: %s\n", body->uri); } for (int i = 0; i < N_RECORDS; ++i) { - if (lv2_pfile_read_chunk(file, &chunk) + if (rdff_read_chunk(file, &chunk) || strncmp(chunk->type, "KVAL", 4)) { fprintf(stderr, "error: expected KVAL chunk\n"); goto fail; } - LV2PFileValueChunk* body = (LV2PFileValueChunk*)chunk->data; + RDFFValueChunk* body = (RDFFValueChunk*)chunk->data; printf("KEY %d = %s\n", body->key, body->value); } free(chunk); - lv2_pfile_close(file); + rdff_close(file); return 0; fail: - lv2_pfile_close(file); + rdff_close(file); fprintf(stderr, "Test failed\n"); return 1; } diff --git a/libs/ardour/rdff.h b/libs/ardour/rdff.h new file mode 100644 index 0000000000..6e9d197536 --- /dev/null +++ b/libs/ardour/rdff.h @@ -0,0 +1,121 @@ +/* + RDFF - RDF in RIFF + Copyright 2011 David Robillard <http://drobilla.net> + + This is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This software is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this sofware; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA. +*/ + +#ifndef RDFF_RDFF_H +#define RDFF_RDFF_H + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __GNUC__ +# define PACKED __attribute__((__packed__)) +#else +# define PACKED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _RDFF* RDFF; + +typedef enum { + RDFF_STATUS_OK = 0, + RDFF_STATUS_UNKNOWN_ERROR = 1, + RDFF_STATUS_EOF = 2, + RDFF_STATUS_CORRUPT = 3 +} RDFFStatus; + +/** + Generic RIFF chunk header. +*/ +typedef struct { + char type[4]; + uint32_t size; + char data[]; +} PACKED RDFFChunk; + +/** + Body of a URID chunk. +*/ +typedef struct { + uint32_t id; + char uri[]; +} PACKED RDFFURIChunk; + +/** + Body of a KVAL chunk. +*/ +typedef struct { + uint32_t key; + uint32_t type; + uint32_t size; + char value[]; +} PACKED RDFFValueChunk; + +/** + Open/Create a new RDFF file. +*/ +RDFF +rdff_open(const char* path, bool write); + +/** + Write a URI ID to @a file. +*/ +RDFFStatus +rdff_write_uri(RDFF file, + uint32_t id, + const char* uri, + uint32_t len); + +/** + Write a key/value record to @a file. +*/ +RDFFStatus +rdff_write_value(RDFF file, + uint32_t key, + const void* value, + uint32_t size, + uint32_t type); + +/** + Read a chunk from @a file. + + @param buf MUST point to an RDFFChunk dynamically allocated with malloc. + The @a size field (i.e. (*buf)->size) MUST be set to the amount of available + memory in the chunk (not including the header). If this is insufficient, + *buf will be resized using realloc. +*/ +RDFFStatus +rdff_read_chunk(RDFF file, + RDFFChunk** buf); + +/** + Close @a file. + After this call, @a file is invalid. +*/ +void +rdff_close(RDFF file); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* RDFF_RDFF_H */ diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 0532619c81..4b2fd546bb 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -327,7 +327,7 @@ def build(bld): #obj.add_objects = 'default/libs/surfaces/control_protocol/smpte_1.o' if bld.env['HAVE_SLV2']: - obj.source += [ 'lv2_plugin.cc', 'lv2_event_buffer.cc', 'uri_map.cc', 'lv2_pfile.c' ] + obj.source += [ 'lv2_plugin.cc', 'lv2_event_buffer.cc', 'uri_map.cc', 'rdff.c' ] obj.uselib += ' SLV2 ' + ' RASQAL ' if bld.env['VST_SUPPORT']: |