[asterisk-commits] file: branch file/bucket r396743 - in /team/file/bucket: ./ build_tools/ incl...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Aug 15 10:25:08 CDT 2013
Author: file
Date: Thu Aug 15 10:25:04 2013
New Revision: 396743
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=396743
Log:
Incorporate review feedback.
Still need to document stuff some more and take care of temporary file stuff.
Modified:
team/file/bucket/build_tools/menuselect-deps.in
team/file/bucket/configure
team/file/bucket/configure.ac
team/file/bucket/include/asterisk/autoconfig.h.in
team/file/bucket/include/asterisk/bucket.h
team/file/bucket/include/asterisk/config_options.h
team/file/bucket/main/Makefile
team/file/bucket/main/bucket.c
team/file/bucket/main/config_options.c
team/file/bucket/makeopts.in
team/file/bucket/tests/test_bucket.c
Modified: team/file/bucket/build_tools/menuselect-deps.in
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/build_tools/menuselect-deps.in?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/build_tools/menuselect-deps.in (original)
+++ team/file/bucket/build_tools/menuselect-deps.in Thu Aug 15 10:25:04 2013
@@ -26,6 +26,7 @@
IXJUSER=@PBX_IXJUSER@
JACK=@PBX_JACK@
JANSSON=@PBX_JANSSON@
+URIPARSER=@PBX_URIPARSER@
KQUEUE=@PBX_KQUEUE@
LDAP=@PBX_LDAP@
LIBEDIT=@PBX_LIBEDIT@
Modified: team/file/bucket/configure.ac
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/configure.ac?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/configure.ac (original)
+++ team/file/bucket/configure.ac Thu Aug 15 10:25:04 2013
@@ -408,6 +408,7 @@
AST_EXT_LIB_SETUP([ISDNNET], [ISDN4Linux], [isdnnet])
AST_EXT_LIB_SETUP([JACK], [Jack Audio Connection Kit], [jack])
AST_EXT_LIB_SETUP([JANSSON], [Jansson JSON library], [jansson])
+AST_EXT_LIB_SETUP([URIPARSER], [uriparser library], [uriparser])
AST_EXT_LIB_SETUP([KQUEUE], [kqueue support], [kqueue])
AST_EXT_LIB_SETUP([LDAP], [OpenLDAP], [ldap])
AST_LIBCURL_CHECK_CONFIG([], [7.10.1])
@@ -541,6 +542,13 @@
if test "x$JANSSON_LIB" == "x"; then
AC_MSG_ERROR([*** JSON support not found (this typically means the libjansson development package is missing)])
+fi
+
+# Find required uriparser support.
+AST_EXT_LIB_CHECK([URIPARSER], [uriparser], [uriParseUriA], [uriparser/Uri.h])
+
+if test "x$URIPARSER_LIB" == "x"; then
+ AC_MSG_ERROR([*** uriparser support not found (this typically means the liburiparser development package is missing)])
fi
# Another mandatory item (unless it's explicitly disabled)
Modified: team/file/bucket/include/asterisk/autoconfig.h.in
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/include/asterisk/autoconfig.h.in?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/include/asterisk/autoconfig.h.in (original)
+++ team/file/bucket/include/asterisk/autoconfig.h.in Thu Aug 15 10:25:04 2013
@@ -1018,6 +1018,9 @@
/* Define to 1 if you have the `unsetenv' function. */
#undef HAVE_UNSETENV
+
+/* Define to 1 if you have the uriparser library library. */
+#undef HAVE_URIPARSER
/* Define to 1 if you have the `utime' function. */
#undef HAVE_UTIME
Modified: team/file/bucket/include/asterisk/bucket.h
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/include/asterisk/bucket.h?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/include/asterisk/bucket.h (original)
+++ team/file/bucket/include/asterisk/bucket.h Thu Aug 15 10:25:04 2013
@@ -28,7 +28,8 @@
* Bucket is an API which provides directory and file access in a generic fashion. It is
* implemented as a thin wrapper over the sorcery data access layer API and is written in
* a pluggable fashion to allow different backend storage mechanisms.
- */
+ *
+ */
#ifndef _ASTERISK_BUCKET_H
#define _ASTERISK_BUCKET_H
Modified: team/file/bucket/include/asterisk/config_options.h
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/include/asterisk/config_options.h?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/include/asterisk/config_options.h (original)
+++ team/file/bucket/include/asterisk/config_options.h Thu Aug 15 10:25:04 2013
@@ -53,17 +53,6 @@
ACO_EXACT = 1,
ACO_REGEX,
};
-
-
-/*! \brief A callback function for handling a particular option
- * \param opt The option being configured
- * \param var The config variable to use to configure \a obj
- * \param obj The object to be configured
- *
- * \retval 0 Parsing and recording the config value succeeded
- * \retval non-zero Failure. Parsing should stop and no reload applied
- */
-typedef int (*aco_option_handler)(const struct aco_option *opt, struct ast_variable *var, void *obj);
/*! Callback functions for option parsing via aco_process_config() */
@@ -448,21 +437,15 @@
OPT_UINT_T,
};
-/*! \brief Configuration option structure */
-struct aco_option {
- const char *name;
- const char *aliased_to;
- const char *default_val;
- enum aco_matchtype match_type;
- regex_t *name_regex;
- struct aco_type **obj;
- enum aco_option_type type;
- aco_option_handler handler;
- unsigned int flags;
- unsigned char deprecated:1;
- size_t argc;
- intptr_t args[0];
-};
+/*! \brief A callback function for handling a particular option
+ * \param opt The option being configured
+ * \param var The config variable to use to configure \a obj
+ * \param obj The object to be configured
+ *
+ * \retval 0 Parsing and recording the config value succeeded
+ * \retval non-zero Failure. Parsing should stop and no reload applied
+ */
+typedef int (*aco_option_handler)(const struct aco_option *opt, struct ast_variable *var, void *obj);
/*! \brief Allocate a container to hold config options */
struct ao2_container *aco_option_container_alloc(void);
@@ -605,6 +588,16 @@
* \retval value of the flags on the config option
*/
unsigned int aco_option_get_flags(const struct aco_option *option);
+
+/*!
+ * \brief Get the offset position for an argument within a config option
+ *
+ * \param option Pointer to the aco_option struct
+ * \param arg Argument number
+ *
+ * \retval position of the argument
+ */
+intptr_t aco_option_get_argument(const struct aco_option *option, unsigned int position);
/*! \note Everything below this point is to handle converting varargs
* containing field names, to varargs containing a count of args, followed
Modified: team/file/bucket/main/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/main/Makefile?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/main/Makefile (original)
+++ team/file/bucket/main/Makefile Thu Aug 15 10:25:04 2013
@@ -36,6 +36,7 @@
AST_LIBS+=$(SQLITE3_LIB)
AST_LIBS+=$(ASTSSL_LIBS)
AST_LIBS+=$(JANSSON_LIB)
+AST_LIBS+=$(URIPARSER_LIB)
AST_LIBS+=$(UUID_LIB)
AST_LIBS+=$(CRYPT_LIB)
@@ -154,6 +155,7 @@
asterisk.o: _ASTCFLAGS+=$(LIBEDIT_INCLUDE)
cli.o: _ASTCFLAGS+=$(LIBEDIT_INCLUDE)
json.o: _ASTCFLAGS+=$(JANSSON_INCLUDE)
+bucket.o: _ASTCFLAGS+=$(URIPARSER_INCLUDE)
crypt.o: _ASTCFLAGS+=$(CRYPT_INCLUDE)
uuid.o: _ASTCFLAGS+=$(UUID_INCLUDE)
Modified: team/file/bucket/main/bucket.c
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/main/bucket.c?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/main/bucket.c (original)
+++ team/file/bucket/main/bucket.c Thu Aug 15 10:25:04 2013
@@ -24,12 +24,15 @@
*/
/*** MODULEINFO
+ <depend>uriparser</depend>
<support_level>core</support_level>
***/
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include <uriparser/Uri.h>
#include "asterisk/logger.h"
#include "asterisk/sorcery.h"
@@ -72,48 +75,6 @@
char name[0];
};
-/*!
- * \brief Simple URI parser
- *
- * \param uri Full URI
- * \param scheme The scheme in the URI
- * \param name The name of the object in the URI
- *
- * \retval 0 success
- * \retval -1 failure
- *
- * \note The URI passed in will be modified
- */
-static int bucket_uri_parse(char *uri, char **scheme, char **name)
-{
- char *tmp;
-
- /* If no URI has been specified this is invalid */
- if (ast_strlen_zero(uri)) {
- return -1;
- }
-
- *scheme = DEFAULT_UNSPECIFIED_SCHEME;
- *name = NULL;
-
- /* Assume the naming starts at the front until proven otherwise */
- *name = uri;
-
- /* Determine the scheme from the provided URI */
- if ((tmp = strstr(uri, "://"))) {
- *scheme = uri;
- *tmp++ = '\0';
- *name = tmp;
- }
-
- /* Determine the name */
- if ((tmp = strrchr(*name, '/'))) {
- *name = tmp + 1;
- }
-
- return 0;
-}
-
/*! \brief Callback function for creating a bucket */
static int bucket_wizard_create(const struct ast_sorcery *sorcery, void *data, void *object)
{
@@ -132,20 +93,28 @@
static void *bucket_wizard_retrieve(const struct ast_sorcery *sorcery, void *data, const char *type,
const char *id)
{
- char *uri, *uri_scheme, *uri_name;
+ UriParserStateA state;
+ UriUriA uri;
SCOPED_AO2RDLOCK(lock, schemes);
+ size_t len;
+ char *uri_scheme;
RAII_VAR(struct bucket_scheme *, scheme, NULL, ao2_cleanup);
- if (!(uri = ast_strdupa(id))) {
- return NULL;
- }
-
- if (bucket_uri_parse(uri, &uri_scheme, &uri_name) ||
- ast_strlen_zero(uri_scheme) || ast_strlen_zero(uri_name)) {
- return NULL;
- }
+ state.uri = &uri;
+ if (uriParseUriA(&state, id) != URI_SUCCESS ||
+ !uri.scheme.first || !uri.scheme.afterLast) {
+ uriFreeUriMembersA(&uri);
+ return NULL;
+ }
+
+ len = (uri.scheme.afterLast - uri.scheme.first) + 1;
+ uri_scheme = ast_alloca(len);
+ ast_copy_string(uri_scheme, uri.scheme.first, len);
scheme = ao2_find(schemes, uri_scheme, OBJ_KEY | OBJ_NOLOCK);
+
+ uriFreeUriMembersA(&uri);
+
if (!scheme) {
return NULL;
}
@@ -193,20 +162,28 @@
static void *bucket_file_wizard_retrieve(const struct ast_sorcery *sorcery, void *data, const char *type,
const char *id)
{
- char *uri, *uri_scheme, *uri_name;
+ UriParserStateA state;
+ UriUriA uri;
+ size_t len;
+ char *uri_scheme;
SCOPED_AO2RDLOCK(lock, schemes);
RAII_VAR(struct bucket_scheme *, scheme, NULL, ao2_cleanup);
- if (!(uri = ast_strdupa(id))) {
- return NULL;
- }
-
- if (bucket_uri_parse(uri, &uri_scheme, &uri_name) ||
- ast_strlen_zero(uri_scheme) || ast_strlen_zero(uri_name)) {
- return NULL;
- }
+ state.uri = &uri;
+ if (uriParseUriA(&state, id) != URI_SUCCESS ||
+ !uri.scheme.first || !uri.scheme.afterLast) {
+ uriFreeUriMembersA(&uri);
+ return NULL;
+ }
+
+ len = (uri.scheme.afterLast - uri.scheme.first) + 1;
+ uri_scheme = ast_alloca(len);
+ ast_copy_string(uri_scheme, uri.scheme.first, len);
scheme = ao2_find(schemes, uri_scheme, OBJ_KEY | OBJ_NOLOCK);
+
+ uriFreeUriMembersA(&uri);
+
if (!scheme) {
return NULL;
}
@@ -344,6 +321,26 @@
ao2_cleanup(bucket->files);
}
+/*! \brief Sorting function for red black tree string container */
+static int bucket_rbtree_str_sort_cmp(const void *obj_left, const void *obj_right, int flags)
+{
+ const char *str_left = obj_left;
+ const char *str_right = obj_right;
+ int cmp = 0;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ case OBJ_KEY:
+ cmp = strcmp(str_left, str_right);
+ break;
+ case OBJ_PARTIAL_KEY:
+ cmp = strncmp(str_left, str_right, strlen(str_right));
+ break;
+ }
+ return cmp;
+}
+
/*! \brief Allocator for buckets */
static void *bucket_alloc(const char *name)
{
@@ -358,12 +355,14 @@
return NULL;
}
- bucket->buckets = ast_str_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, BUCKET_BUCKETS);
+ bucket->buckets = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
+ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, bucket_rbtree_str_sort_cmp, NULL);
if (!bucket->buckets) {
return NULL;
}
- bucket->files = ast_str_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, FILE_BUCKETS);
+ bucket->files = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
+ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, bucket_rbtree_str_sort_cmp, NULL);
if (!bucket->files) {
return NULL;
}
@@ -374,17 +373,29 @@
struct ast_bucket *ast_bucket_alloc(const char *uri)
{
- char *full_uri, *uri_scheme, *uri_name;
+ UriParserStateA state;
+ UriUriA full_uri;
+ size_t len;
+ char *uri_scheme, *uri_name;
struct ast_bucket *bucket;
- if (!(full_uri = ast_strdupa(uri))) {
- return NULL;
- }
-
- if (bucket_uri_parse(full_uri, &uri_scheme, &uri_name) ||
- ast_strlen_zero(uri_scheme) || ast_strlen_zero(uri_name)) {
- return NULL;
- }
+ state.uri = &full_uri;
+ if (uriParseUriA(&state, uri) != URI_SUCCESS ||
+ !full_uri.scheme.first || !full_uri.scheme.afterLast ||
+ !full_uri.pathTail) {
+ uriFreeUriMembersA(&full_uri);
+ return NULL;
+ }
+
+ len = (full_uri.scheme.afterLast - full_uri.scheme.first) + 1;
+ uri_scheme = ast_alloca(len);
+ ast_copy_string(uri_scheme, full_uri.scheme.first, len);
+
+ len = (full_uri.pathTail->text.afterLast - full_uri.pathTail->text.first) + 1;
+ uri_name = ast_alloca(len);
+ ast_copy_string(uri_name, full_uri.pathTail->text.first, len);
+
+ uriFreeUriMembersA(&full_uri);
if (!(bucket = ast_sorcery_alloc(bucket_sorcery, "bucket", uri))) {
return NULL;
@@ -444,12 +455,15 @@
}
if (ast_json_object_set(json, "id", id)) {
- ast_json_unref(id);
return NULL;
}
buckets = ast_json_array_create();
if (!buckets) {
+ return NULL;
+ }
+
+ if (ast_json_object_set(json, "buckets", buckets)) {
return NULL;
}
@@ -457,24 +471,23 @@
for (; (uri = ao2_iterator_next(&i)); ao2_ref(uri, -1)) {
struct ast_json *bucket_uri = ast_json_string_create(uri);
- if (!bucket_uri) {
+ if (!bucket_uri || ast_json_array_append(buckets, bucket_uri)) {
res = -1;
break;
}
-
- ast_json_array_append(buckets, bucket_uri);
}
ao2_iterator_destroy(&i);
if (res) {
- ast_json_unref(buckets);
- return NULL;
- }
-
- ast_json_object_set(json, "buckets", buckets);
+ return NULL;
+ }
files = ast_json_array_create();
if (!files) {
+ return NULL;
+ }
+
+ if (ast_json_object_set(json, "files", files)) {
return NULL;
}
@@ -482,21 +495,16 @@
for (; (uri = ao2_iterator_next(&i)); ao2_ref(uri, -1)) {
struct ast_json *file_uri = ast_json_string_create(uri);
- if (!file_uri) {
+ if (!file_uri || ast_json_array_append(files, file_uri)) {
res = -1;
break;
}
-
- ast_json_array_append(files, file_uri);
}
ao2_iterator_destroy(&i);
if (res) {
- ast_json_unref(files);
- return NULL;
- }
-
- ast_json_object_set(json, "files", files);
+ return NULL;
+ }
ast_json_ref(json);
return json;
@@ -505,10 +513,21 @@
/*! \brief Hashing function for file metadata */
static int bucket_file_metadata_hash(const void *obj, const int flags)
{
- const struct ast_bucket_metadata *metadata = obj;
- const char *name = obj;
-
- return ast_str_hash(flags & OBJ_KEY ? name : metadata->name);
+ const struct ast_bucket_metadata *object;
+ const char *key;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_KEY:
+ key = obj;
+ return ast_str_hash(key);
+ case OBJ_POINTER:
+ object = obj;
+ return ast_str_hash(object->name);
+ default:
+ /* Hash can only work on something with a full key */
+ ast_assert(0);
+ return 0;
+ }
}
/*! \brief Comparison function for file metadata */
@@ -558,18 +577,30 @@
struct ast_bucket_file *ast_bucket_file_alloc(const char *uri)
{
- char *full_uri, *uri_scheme, *uri_name;
+ UriParserStateA state;
+ UriUriA full_uri;
+ size_t len;
+ char *uri_scheme, *uri_name;
struct ast_bucket_file *file;
int fd;
- if (!(full_uri = ast_strdupa(uri))) {
- return NULL;
- }
-
- if (bucket_uri_parse(full_uri, &uri_scheme, &uri_name) ||
- ast_strlen_zero(uri_scheme) || ast_strlen_zero(uri_name)) {
- return NULL;
- }
+ state.uri = &full_uri;
+ if (uriParseUriA(&state, uri) != URI_SUCCESS ||
+ !full_uri.scheme.first || !full_uri.scheme.afterLast ||
+ !full_uri.pathTail) {
+ uriFreeUriMembersA(&full_uri);
+ return NULL;
+ }
+
+ len = (full_uri.scheme.afterLast - full_uri.scheme.first) + 1;
+ uri_scheme = ast_alloca(len);
+ ast_copy_string(uri_scheme, full_uri.scheme.first, len);
+
+ len = (full_uri.pathTail->text.afterLast - full_uri.pathTail->text.first) + 1;
+ uri_name = ast_alloca(len);
+ ast_copy_string(uri_name, full_uri.pathTail->text.first, len);
+
+ uriFreeUriMembersA(&full_uri);
if (!(file = ast_sorcery_alloc(bucket_sorcery, "file", uri))) {
return NULL;
@@ -601,11 +632,11 @@
char buf[4096]; /* XXX make it lerger. */
if ((ifd = open(infile, O_RDONLY)) < 0) {
- ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
+ ast_log(LOG_WARNING, "Unable to open %s in read-only mode, error: %s\n", infile, strerror(errno));
return -1;
}
if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) {
- ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
+ ast_log(LOG_WARNING, "Unable to open %s in write-only mode, error: %s\n", outfile, strerror(errno));
close(ifd);
return -1;
}
@@ -634,25 +665,20 @@
struct ast_bucket_file *ast_bucket_file_copy(struct ast_bucket_file *file, const char *uri)
{
- struct ast_bucket_file *copy;
-
- copy = ast_bucket_file_alloc(uri);
+ RAII_VAR(struct ast_bucket_file *, copy, ast_bucket_file_alloc(uri), ao2_cleanup);
+
if (!copy) {
return NULL;
}
ao2_cleanup(copy->metadata);
copy->metadata = ao2_container_clone(file->metadata, 0);
- if (!copy->metadata) {
- ao2_ref(copy, -1);
- return NULL;
- }
-
- if (bucket_copy(file->path, copy->path)) {
- ao2_ref(copy, -1);
- return NULL;
- }
-
+ if (!copy->metadata ||
+ bucket_copy(file->path, copy->path)) {
+ return NULL;
+ }
+
+ ao2_ref(copy, +1);
return copy;
}
@@ -704,12 +730,15 @@
}
if (ast_json_object_set(json, "id", id)) {
- ast_json_unref(id);
return NULL;
}
metadata = ast_json_object_create();
if (!metadata) {
+ return NULL;
+ }
+
+ if (ast_json_object_set(json, "metadata", metadata)) {
return NULL;
}
@@ -717,21 +746,16 @@
for (; (attribute = ao2_iterator_next(&i)); ao2_ref(attribute, -1)) {
struct ast_json *value = ast_json_string_create(attribute->value);
- if (!value) {
+ if (!value || ast_json_object_set(metadata, attribute->name, value)) {
res = -1;
break;
}
-
- ast_json_object_set(metadata, attribute->name, value);
}
ao2_iterator_destroy(&i);
if (res) {
- ast_json_unref(metadata);
- return NULL;
- }
-
- ast_json_object_set(json, "metadata", metadata);
+ return NULL;
+ }
ast_json_ref(json);
return json;
@@ -740,10 +764,21 @@
/*! \brief Hashing function for scheme container */
static int bucket_scheme_hash(const void *obj, const int flags)
{
- const struct bucket_scheme *scheme = obj;
- const char *name = obj;
-
- return ast_str_hash(flags & OBJ_KEY ? name : scheme->name);
+ const struct bucket_scheme *object;
+ const char *key;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_KEY:
+ key = obj;
+ return ast_str_hash(key);
+ case OBJ_POINTER:
+ object = obj;
+ return ast_str_hash(object->name);
+ default:
+ /* Hash can only work on something with a full key */
+ ast_assert(0);
+ return 0;
+ }
}
/*! \brief Comparison function for scheme container */
@@ -771,7 +806,7 @@
/*! \brief Custom handler for translating from a string timeval to actual structure */
static int timeval_str2struct(const struct aco_option *opt, struct ast_variable *var, void *obj)
{
- struct timeval *field = (struct timeval *)(obj + opt->args[0]);
+ struct timeval *field = (struct timeval *)(obj + aco_option_get_argument(opt, 0));
return ast_get_timeval(var->value, field, ast_tv(0, 0), NULL);
}
@@ -785,36 +820,38 @@
/*! \brief Initialize bucket support */
int ast_bucket_init(void)
{
+ ast_register_cleanup(&bucket_cleanup);
+
schemes = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, SCHEME_BUCKETS, bucket_scheme_hash,
bucket_scheme_cmp);
if (!schemes) {
ast_log(LOG_ERROR, "Failed to create container for Bucket schemes\n");
- goto failure;
+ return -1;
}
if (__ast_sorcery_wizard_register(&bucket_wizard, NULL)) {
ast_log(LOG_ERROR, "Failed to register sorcery wizard for 'bucket' intermediary\n");
- goto failure;
+ return -1;
}
if (__ast_sorcery_wizard_register(&bucket_file_wizard, NULL)) {
ast_log(LOG_ERROR, "Failed to register sorcery wizard for 'file' intermediary\n");
- goto failure;
+ return -1;
}
if (!(bucket_sorcery = ast_sorcery_open())) {
ast_log(LOG_ERROR, "Failed to create sorcery instance for Bucket support\n");
- goto failure;
+ return -1;
}
if (ast_sorcery_apply_default(bucket_sorcery, "bucket", "bucket", NULL)) {
ast_log(LOG_ERROR, "Failed to apply intermediary for 'bucket' object type in Bucket sorcery\n");
- goto failure;
+ return -1;
}
if (ast_sorcery_object_register(bucket_sorcery, "bucket", bucket_alloc, NULL, NULL)) {
ast_log(LOG_ERROR, "Failed to register 'bucket' object type in Bucket sorcery\n");
- goto failure;
+ return -1;
}
ast_sorcery_object_field_register(bucket_sorcery, "bucket", "name", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket, name));
@@ -824,12 +861,12 @@
if (ast_sorcery_apply_default(bucket_sorcery, "file", "bucket_file", NULL)) {
ast_log(LOG_ERROR, "Failed to apply intermediary for 'file' object type in Bucket sorcery\n");
- goto failure;
+ return -1;
}
if (ast_sorcery_object_register(bucket_sorcery, "file", bucket_file_alloc, NULL, NULL)) {
ast_log(LOG_ERROR, "Failed to register 'file' object type in Bucket sorcery\n");
- goto failure;
+ return -1;
}
ast_sorcery_object_field_register(bucket_sorcery, "file", "name", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket_file, name));
@@ -837,11 +874,5 @@
ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "created", "", timeval_str2struct, timeval_struct2str, 0, FLDSET(struct ast_bucket_file, created));
ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "modified", "", timeval_str2struct, timeval_struct2str, 0, FLDSET(struct ast_bucket_file, modified));
- ast_register_cleanup(bucket_cleanup);
-
return 0;
-
-failure:
- bucket_cleanup();
- return -1;
-}
+}
Modified: team/file/bucket/main/config_options.c
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/main/config_options.c?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/main/config_options.c (original)
+++ team/file/bucket/main/config_options.c Thu Aug 15 10:25:04 2013
@@ -59,6 +59,21 @@
struct ao2_container *opts; /*!< The container of options registered to the aco_info */
};
+struct aco_option {
+ const char *name;
+ const char *aliased_to;
+ const char *default_val;
+ enum aco_matchtype match_type;
+ regex_t *name_regex;
+ struct aco_type **obj;
+ enum aco_option_type type;
+ aco_option_handler handler;
+ unsigned int flags;
+ unsigned char deprecated:1;
+ size_t argc;
+ intptr_t args[0];
+};
+
#ifdef AST_XML_DOCS
static struct ao2_container *xmldocs;
#endif /* AST_XML_DOCS */
@@ -211,6 +226,11 @@
unsigned int aco_option_get_flags(const struct aco_option *option)
{
return option->flags;
+}
+
+intptr_t aco_option_get_argument(const struct aco_option *option, unsigned int position)
+{
+ return option->args[position];
}
#ifdef AST_XML_DOCS
Modified: team/file/bucket/makeopts.in
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/makeopts.in?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/makeopts.in (original)
+++ team/file/bucket/makeopts.in Thu Aug 15 10:25:04 2013
@@ -173,6 +173,9 @@
JANSSON_INCLUDE=@JANSSON_INCLUDE@
JANSSON_LIB=@JANSSON_LIB@
+URIPARSER_INCLUDE=@URIPARSER_INCLUDE@
+URIPARSER_LIB=@URIPARSER_LIB@
+
LDAP_INCLUDE=@LDAP_INCLUDE@
LDAP_LIB=@LDAP_LIB@
Modified: team/file/bucket/tests/test_bucket.c
URL: http://svnview.digium.com/svn/asterisk/team/file/bucket/tests/test_bucket.c?view=diff&rev=396743&r1=396742&r2=396743
==============================================================================
--- team/file/bucket/tests/test_bucket.c (original)
+++ team/file/bucket/tests/test_bucket.c Thu Aug 15 10:25:04 2013
@@ -290,8 +290,8 @@
AST_TEST_DEFINE(bucket_json)
{
RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
- struct ast_json_iter *field;
switch (cmd) {
case TEST_INIT:
@@ -312,6 +312,17 @@
ast_str_container_add(bucket->buckets, "test:///tmp/bob/joe");
ast_str_container_add(bucket->files, "test:///tmp/bob/recording.wav");
+
+ expected = ast_json_pack("{s: s, s: s, s: [s], s: s, s: s, s: [s], s: s}",
+ "modified", "0.000000", "created", "0.000000",
+ "buckets", "test:///tmp/bob/joe",
+ "name", "bob", "scheme", "test",
+ "files", "test:///tmp/bob/recording.wav",
+ "id", "test:///tmp/bob");
+ if (!expected) {
+ ast_test_status_update(test, "Could not produce JSON for expected bucket value\n");
+ return AST_TEST_FAIL;
+ }
json = ast_bucket_json(bucket);
if (!json) {
@@ -319,72 +330,9 @@
return AST_TEST_FAIL;
}
- for (field = ast_json_object_iter(json); field; field = ast_json_object_iter_next(json, field)) {
- struct ast_json *value = ast_json_object_iter_value(field);
-
- if (!strcmp(ast_json_object_iter_key(field), "id")) {
- if (strcmp(ast_json_string_get(value), "bob")) {
- ast_test_status_update(test, "Expected id of 'bob' in bucket JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "modified")) {
- if (strcmp(ast_json_string_get(value), "0")) {
- ast_test_status_update(test, "Expected modified time of '0' in bucket JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "created")) {
- if (strcmp(ast_json_string_get(value), "0")) {
- ast_test_status_update(test, "Expected created time of '0' in bucket JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "scheme")) {
- if (strcmp(ast_json_string_get(value), "test")) {
- ast_test_status_update(test, "Expected scheme of 'test' in bucket JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "uri")) {
- if (strcmp(ast_json_string_get(value), "test:///tmp/bob")) {
- ast_test_status_update(test, "Expected URI of 'test:///tmp/bob' in bucket JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "buckets")) {
- struct ast_json *uri;
-
- if (ast_json_array_size(value) != 1) {
- ast_test_status_update(test, "Expected buckets array size of '1' in bucket JSON but got '%zd'\n",
- ast_json_array_size(value));
- return AST_TEST_FAIL;
- }
-
- uri = ast_json_array_get(value, 0);
-
- if (strcmp(ast_json_string_get(uri), "test:///tmp/bob/joe")) {
- ast_test_status_update(test, "Expected URI of 'test:///tmp/bob/joe' in buckets array but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "files")) {
- struct ast_json *uri;
-
- if (ast_json_array_size(value) != 1) {
- ast_test_status_update(test, "Expected files array size of '1' in bucket JSON but got '%zd'\n",
- ast_json_array_size(value));
- return AST_TEST_FAIL;
- }
-
- uri = ast_json_array_get(value, 0);
-
- if (strcmp(ast_json_string_get(uri), "test:///tmp/bob/recording.wav")) {
- ast_test_status_update(test, "Expected URI of 'test:///tmp/bob/recording.wav' in buckets array but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- }
+ if (!ast_json_equal(json, expected)) {
+ ast_test_status_update(test, "Bucket JSON does not match expected output\n");
+ return AST_TEST_FAIL;
}
return AST_TEST_PASS;
@@ -495,12 +443,6 @@
return AST_TEST_FAIL;
}
- if (!stat(file->path, &st)) {
- ast_test_status_update(test, "Temporary file '%s' existed before creating it\n",
- file->path);
- return AST_TEST_FAIL;
- }
-
if (!(temporary = fopen(file->path, "w"))) {
ast_test_status_update(test, "Failed to open temporary file '%s'\n",
file->path);
@@ -579,6 +521,7 @@
RAII_VAR(struct ast_bucket_file *, copy, NULL, ao2_cleanup);
FILE *temporary;
struct stat old, new;
+ RAII_VAR(struct ast_bucket_metadata *, metadata, NULL, ao2_cleanup);
switch (cmd) {
case TEST_INIT:
@@ -633,6 +576,17 @@
return AST_TEST_FAIL;
}
+ metadata = ast_bucket_file_metadata_get(copy, "bob");
+ if (!metadata) {
+ ast_test_status_update(test, "Copy of file does not have expected metadata\n");
+ return AST_TEST_FAIL;
+ }
+
+ if (strcmp(metadata->value, "joe")) {
+ ast_test_status_update(test, "Copy of file contains metadata for 'bob' but value is not what it should be\n");
+ return AST_TEST_FAIL;
+ }
+
return AST_TEST_PASS;
}
@@ -884,14 +838,20 @@
return AST_TEST_FAIL;
}
+ if (strcmp(metadata->value, "joe")) {
+ ast_test_status_update(test, "Retrieved metadata value is '%s' while it should be 'joe'\n",
+ metadata->value);
+ return AST_TEST_FAIL;
+ }
+
return AST_TEST_PASS;
}
AST_TEST_DEFINE(bucket_file_json)
{
RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
- struct ast_json_iter *field;
switch (cmd) {
case TEST_INIT:
@@ -912,6 +872,14 @@
if (ast_bucket_file_metadata_set(file, "bob", "joe")) {
ast_test_status_update(test, "Failed to set metadata 'bob' to 'joe' on newly allocated file\n");
+ return AST_TEST_FAIL;
+ }
+
+ expected = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: {s :s}}",
+ "modified", "0.000000", "created", "0.000000", "name", "bob", "scheme", "test",
+ "id", "test:///tmp/bob", "metadata", "bob", "joe");
+ if (!expected) {
+ ast_test_status_update(test, "Could not produce JSON for expected bucket file value\n");
return AST_TEST_FAIL;
}
@@ -921,53 +889,9 @@
return AST_TEST_FAIL;
}
- for (field = ast_json_object_iter(json); field; field = ast_json_object_iter_next(json, field)) {
- struct ast_json *value = ast_json_object_iter_value(field);
-
- if (!strcmp(ast_json_object_iter_key(field), "id")) {
- if (strcmp(ast_json_string_get(value), "bob")) {
- ast_test_status_update(test, "Expected id of 'bob' in file JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "modified")) {
- if (strcmp(ast_json_string_get(value), "0")) {
- ast_test_status_update(test, "Expected modified time of '0' in file JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "created")) {
- if (strcmp(ast_json_string_get(value), "0")) {
- ast_test_status_update(test, "Expected created time of '0' in file JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "scheme")) {
- if (strcmp(ast_json_string_get(value), "test")) {
- ast_test_status_update(test, "Expected scheme of 'test' in file JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "uri")) {
- if (strcmp(ast_json_string_get(value), "test:///tmp/bob")) {
- ast_test_status_update(test, "Expected URI of 'test:///tmp/bob' in file JSON but got '%s'\n",
- ast_json_string_get(value));
- return AST_TEST_FAIL;
- }
- } else if (!strcmp(ast_json_object_iter_key(field), "metadata")) {
- struct ast_json *bob = ast_json_object_get(value, "bob");
-
- if (!bob) {
- ast_test_status_update(test, "Failed to get 'bob' metadata in JSON\n");
- return AST_TEST_FAIL;
- }
-
- if (strcmp(ast_json_string_get(bob), "joe")) {
- ast_test_status_update(test, "Retrieved 'bob' metadata has value '%s' instead of 'joe'\n",
- ast_json_string_get(bob));
- return AST_TEST_FAIL;
- }
- }
+ if (!ast_json_equal(json, expected)) {
+ ast_test_status_update(test, "Bucket file JSON does not match expected output\n");
+ return AST_TEST_FAIL;
}
return AST_TEST_PASS;
More information about the asterisk-commits
mailing list