From b59ef460cc1fa273bd53e8f1cb7607672dab3c9a Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 30 Sep 2013 19:04:36 -0400 Subject: [PATCH] update submodules --- example-clients | 2 +- jack | 2 +- libjack/Makefile.am | 3 +- libjack/metadata.c | 477 ++++++++++++++++++++++++++++++++++++++++++++ tools | 2 +- 5 files changed, 482 insertions(+), 4 deletions(-) create mode 100644 libjack/metadata.c diff --git a/example-clients b/example-clients index b952e1e..d53945f 160000 --- a/example-clients +++ b/example-clients @@ -1 +1 @@ -Subproject commit b952e1e5f1e280ed45094273a12e996fc26081c7 +Subproject commit d53945f7ed7285db9b0626ff12535291528f7680 diff --git a/jack b/jack index 2d8115f..94dd1e8 160000 --- a/jack +++ b/jack @@ -1 +1 @@ -Subproject commit 2d8115ffacbfbcfb303f4c8e437eeb84346cb80b +Subproject commit 94dd1e8751371761b60d511171d89fd149b417be diff --git a/libjack/Makefile.am b/libjack/Makefile.am index b976fe7..8d248e6 100644 --- a/libjack/Makefile.am +++ b/libjack/Makefile.am @@ -15,6 +15,7 @@ SOURCE_FILES = \ messagebuffer.c \ pool.c \ port.c \ + metadata.c \ midiport.c \ ringbuffer.c \ shm.c \ @@ -37,6 +38,6 @@ AM_CXXFLAGS = $(JACK_CFLAGS) libjack_la_CFLAGS = $(AM_CFLAGS) libjack_la_SOURCES = $(SOURCE_FILES) -libjack_la_LIBADD = simd.lo @OS_LDFLAGS@ +libjack_la_LIBADD = simd.lo -ldb @OS_LDFLAGS@ libjack_la_LDFLAGS = -export-dynamic -version-info @JACK_SO_VERSION@ diff --git a/libjack/metadata.c b/libjack/metadata.c new file mode 100644 index 0000000..290ae83 --- /dev/null +++ b/libjack/metadata.c @@ -0,0 +1,477 @@ +/* + Copyright (C) 2013 Paul Davis + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at + your option) any later version. + + This program 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include +#include + +#include "internal.h" + +static DB* db = NULL; + +static int +jack_property_init (const char* server_name) +{ + int ret; + char dbpath[PATH_MAX+1]; + char server_dir[PATH_MAX+1]; + + /* idempotent */ + + if (db) { + return 0; + } + + if ((ret = db_create (&db, NULL, 0)) != 0) { + jack_error ("Cannot initialize metadata DB (%s)", db_strerror (ret)); + return -1; + } + + snprintf (dbpath, sizeof (dbpath), "%s/%s", jack_server_dir (server_name, server_dir), "metadata.db"); + + if ((ret = db->open (db, NULL, dbpath, NULL, DB_HASH, DB_CREATE|DB_THREAD, 0666)) != 0) { + jack_error ("Cannot open metadata DB at %s: %s", dbpath, db_strerror (ret)); + db->close (db, 0); + db = NULL; + return -1; + } + + return 0; +} + +static void jack_properties_uninit () __attribute__ ((destructor)); + +void +jack_properties_uninit () +{ + if (db) { + db->close (db, 0); + db = NULL; + } +} + +void +jack_free_description(jack_description_t* desc) +{ + return; +} + +static void +make_key_dbt (DBT* dbt, jack_uuid_t subject, const char* key) +{ + char ustr[JACK_UUID_STRING_SIZE]; + size_t len1, len2; + + memset(dbt, 0, sizeof(DBT)); + jack_uuid_unparse (subject, ustr); + len1 = JACK_UUID_STRING_SIZE; + len2 = strlen (key) + 1; + dbt->size = len1 + len2; + dbt->data = malloc (dbt->size); + memcpy (dbt->data, ustr, len1); // copy subject+null + memcpy (dbt->data + len1, key, len2); // copy key+null +} + + +int +jack_set_property (jack_uuid_t subject, + const char* key, + const char* value, + const char* type) +{ + DBT d_key; + DBT data; + int ret; + size_t len1, len2; + + if (jack_property_init (NULL)) { + return -1; + } + + /* build a key */ + + make_key_dbt (&d_key, subject, key); + + /* build data */ + + memset(&data, 0, sizeof(data)); + + len1 = strlen(value) + 1; + if (type && type[0] != '\0') { + len2 = strlen(type) + 1; + } else { + len2 = 0; + } + + data.size = len1 + len2; + data.data = malloc (data.size); + memcpy (data.data, value, len1); + + if (len2) { + memcpy (data.data + len1, type, len2); + } + + if ((ret = db->put (db, NULL, &d_key, &data, 0)) != 0) { + char ustr[JACK_UUID_STRING_SIZE]; + jack_uuid_unparse (subject, ustr); + jack_error ("Cannot store metadata for %s/%s (%s)", ustr, key, db_strerror (ret)); + return -1; + } + + return 0; +} + +int +jack_get_property (jack_uuid_t subject, + const char* key, + char** value, + char** type) +{ + DBT d_key; + DBT data; + int ret; + size_t len1, len2; + + if (key == NULL || key[0] == '\0') { + return -1; + } + + if (jack_property_init (NULL)) { + return -1; + } + + /* build a key */ + + make_key_dbt (&d_key, subject, key); + + /* setup data DBT */ + + memset(&data, 0, sizeof(data)); + data.flags = DB_DBT_MALLOC; + + if ((ret = db->get (db, NULL, &d_key, &data, 0)) != 0) { + if (ret != DB_NOTFOUND) { + char ustr[JACK_UUID_STRING_SIZE]; + jack_uuid_unparse (subject, ustr); + jack_error ("Cannot metadata for %s/%s (%s)", ustr, key, db_strerror (ret)); + } + return -1; + } + + /* result must have at least 2 chars plus 2 nulls to be valid + */ + + if (data.size < 4) { + if (data.size > 0) { + free (data.data); + } + return -1; + } + + len1 = strlen (data.data) + 1; + (*value) = (char *) malloc (len1); + memcpy (*value, data.data, len1); + + if (len1 < data.size) { + len2 = strlen (data.data+len1) + 1; + + (*type) = (char *) malloc (len2); + memcpy (*type, data.data+len1, len2); + } else { + /* no type specified, assume default */ + *type = NULL; + } + + if (data.size) { + free (data.data); + } + + return 0; +} + +int +jack_get_properties (jack_uuid_t subject, + jack_description_t* desc) +{ + DBT key; + DBT data; + DBC* cursor; + int ret; + size_t len1, len2; + size_t cnt = 0; + char ustr[JACK_UUID_STRING_SIZE]; + size_t props_size = 0; + jack_property_t* prop; + + desc->properties = NULL; + + jack_uuid_unparse (subject, ustr); + + if (jack_property_init (NULL)) { + return -1; + } + + + if ((ret = db->cursor (db, NULL, &cursor, 0)) != 0) { + jack_error ("Cannot create cursor for metadata search (%s)", db_strerror (ret)); + return -1; + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + data.flags = DB_DBT_MALLOC; + + while ((ret = cursor->get(cursor, &key, &data, DB_NEXT)) == 0) { + + /* require 2 extra chars (data+null) for key, + which is composed of UUID str plus a key name + */ + + if (key.size < JACK_UUID_STRING_SIZE + 2) { + if (data.size > 0) { + free (data.data); + } + continue; + } + + if (memcmp (ustr, key.data, JACK_UUID_STRING_SIZE) != 0) { + /* not relevant */ + if (data.size > 0) { + free (data.data); + } + continue; + } + + /* result must have at least 2 chars plus 2 nulls to be valid + */ + + if (data.size < 4) { + if (data.size > 0) { + free (data.data); + } + continue; + } + + /* realloc array if necessary */ + + if (cnt == props_size) { + if (props_size == 0) { + props_size = 8; + } else { + props_size *= 2; + } + + desc->properties = (jack_property_t*) realloc (desc->properties, sizeof (jack_property_t) * props_size); + } + + prop = &desc->properties[cnt]; + + /* store UUID/subject */ + + jack_uuid_copy (desc->subject, subject); + + /* copy key (without leading UUID as subject */ + + len1 = key.size - JACK_UUID_STRING_SIZE; + prop->key = malloc (key.size); + memcpy ((char*) prop->key, key.data + JACK_UUID_STRING_SIZE, len1); + + /* copy data */ + + len1 = strlen (data.data) + 1; + prop->data = (char *) malloc (len1); + memcpy ((char*) prop->data, data.data, len1); + + if (len1 < data.size) { + len2 = strlen (data.data+len1) + 1; + + prop->type= (char *) malloc (len2); + memcpy ((char*) prop->type, data.data+len1, len2); + } else { + /* no type specified, assume default */ + prop->type = NULL; + } + + if (data.size) { + free (data.data); + } + + ++cnt; + } + + cursor->close (cursor); + + return cnt; +} + +int +jack_get_all_properties (jack_description_t** desc) +{ + DBT key; + DBT data; + DBC* cursor; + int ret; + size_t cnt = 0; + + if (jack_property_init (NULL)) { + return -1; + } + + + if ((ret = db->cursor (db, NULL, &cursor, 0)) != 0) { + jack_error ("Cannot create cursor for metadata search (%s)", db_strerror (ret)); + return -1; + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + data.flags = DB_DBT_MALLOC; + + while ((ret = cursor->get(cursor, &key, &data, DB_NEXT)) == 0) { + + if (data.size) { + free (data.data); + } + + ++cnt; + } + + cursor->close (cursor); + + return cnt; +} + + +int +jack_get_description (jack_uuid_t subject, + jack_description_t* desc) +{ + return 0; +} + +int +jack_get_all_descriptions (jack_description_t** descs) +{ + return 0; +} + +int jack_set_property_change_callback (jack_client_t* client, + JackPropertyChangeCallback callback, + void *arg) +{ + return 0; +} + +int +jack_remove_property (jack_uuid_t subject, const char* key) +{ + DBT d_key; + int ret; + + if (jack_property_init (NULL)) { + return -1; + } + + make_key_dbt (&d_key, subject, key); + if ((ret = db->del (db, NULL, &d_key, 0)) != 0) { + jack_error ("Cannot delete key %s (%s)", key, db_strerror (ret)); + return -1; + } + return 0; +} + +int +jack_remove_properties (jack_uuid_t subject) +{ + DBT key; + DBT data; + DBC* cursor; + int ret; + char ustr[JACK_UUID_STRING_SIZE]; + int retval = 0; + + jack_uuid_unparse (subject, ustr); + + if (jack_property_init (NULL)) { + return -1; + } + + + if ((ret = db->cursor (db, NULL, &cursor, 0)) != 0) { + jack_error ("Cannot create cursor for metadata search (%s)", db_strerror (ret)); + return -1; + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + data.flags = DB_DBT_MALLOC; + + while ((ret = cursor->get(cursor, &key, &data, DB_NEXT)) == 0) { + + /* require 2 extra chars (data+null) for key, + which is composed of UUID str plus a key name + */ + + if (key.size < JACK_UUID_STRING_SIZE + 2) { + if (data.size > 0) { + free (data.data); + } + continue; + } + + if (memcmp (ustr, key.data, JACK_UUID_STRING_SIZE) != 0) { + /* not relevant */ + if (data.size > 0) { + free (data.data); + } + continue; + } + + if ((ret = cursor->del (cursor, 0)) != 0) { + jack_error ("cannot delete property (%s)", db_strerror (ret)); + /* don't return -1 here since this would leave things + even more inconsistent. wait till the cursor is finished + */ + retval = -1; + } + } + + cursor->close (cursor); + + return retval; +} + +int +jack_remove_all_properties () +{ + int ret; + + if (jack_property_init (NULL)) { + return -1; + } + + if ((ret = db->truncate (db, NULL, NULL, 0)) != 0) { + jack_error ("Cannot clear properties (%s)", db_strerror (ret)); + return -1; + } + + return 0; +} diff --git a/tools b/tools index 177e915..3150f17 160000 --- a/tools +++ b/tools @@ -1 +1 @@ -Subproject commit 177e91545dda9a1ebc81a511e787a6ef1ccbb525 +Subproject commit 3150f173da1ca48b08c0669186bb6986ab4ab71e