[asterisk-commits] file: branch file/sorceryx4 r389050 - in /team/file/sorceryx4: include/asteri...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat May 18 12:27:34 CDT 2013


Author: file
Date: Sat May 18 12:27:30 2013
New Revision: 389050

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389050
Log:
Add the ability to extend objects by explicitly specifying a field is an extension by prefixing it with '@'.

Extended fields do not have any type safety restrictions. Any consumer of an extended field must confirm
it is valid for its use at use time.

Modified:
    team/file/sorceryx4/include/asterisk/sorcery.h
    team/file/sorceryx4/main/sorcery.c
    team/file/sorceryx4/tests/test_sorcery.c

Modified: team/file/sorceryx4/include/asterisk/sorcery.h
URL: http://svnview.digium.com/svn/asterisk/team/file/sorceryx4/include/asterisk/sorcery.h?view=diff&rev=389050&r1=389049&r2=389050
==============================================================================
--- team/file/sorceryx4/include/asterisk/sorcery.h (original)
+++ team/file/sorceryx4/include/asterisk/sorcery.h Sat May 18 12:27:30 2013
@@ -706,6 +706,19 @@
  */
 const char *ast_sorcery_object_get_type(const void *object);
 
+/*!
+ * \brief Get an extended field value from a sorcery object
+ *
+ * \param object Pointer to a sorcery object
+ * \param name Name of the extended field value
+ *
+ * \retval non-NULL if found
+ * \retval NULL if not found
+ *
+ * \note The returned string does NOT need to be freed and is guaranteed to remain valid for the lifetime of the object
+ */
+const char *ast_sorcery_object_get_extended(const void *object, const char *name);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: team/file/sorceryx4/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorceryx4/main/sorcery.c?view=diff&rev=389050&r1=389049&r2=389050
==============================================================================
--- team/file/sorceryx4/main/sorcery.c (original)
+++ team/file/sorceryx4/main/sorcery.c Sat May 18 12:27:30 2013
@@ -68,6 +68,9 @@
 
 	/*! \brief Optional object destructor */
 	ao2_destructor_fn destructor;
+
+	/*! \brief Extended object fields */
+	struct ast_variable *extended;
 };
 
 /*! \brief Structure for registered object type */
@@ -537,6 +540,22 @@
 	return sorcery_apply_wizard_mapping(sorcery, type, module, name, data, 0);
 }
 
+static int sorcery_extended_config_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	/* The + 1 below is to strip the @ from the beginning of the name */
+	struct ast_variable *extended = ast_variable_new(var->name + 1, var->value, "");
+	const struct ast_sorcery_object_details *details = obj;
+
+	if (!extended) {
+		return -1;
+	}
+
+	extended->next = details->object->extended;
+	details->object->extended = extended;
+
+	return 0;
+}
+
 int ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply)
 {
 	RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
@@ -556,6 +575,10 @@
 	object_type->file->types[1] = NULL;
 
 	if (aco_info_init(object_type->info)) {
+		return -1;
+	}
+
+	if (ast_sorcery_object_fields_register(sorcery, type, "^@", sorcery_extended_config_handler, NULL)) {
 		return -1;
 	}
 
@@ -996,6 +1019,8 @@
 	if (details->object->destructor) {
 		details->object->destructor(object);
 	}
+
+	ast_variables_destroy(details->object->extended);
 }
 
 void *ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
@@ -1416,6 +1441,20 @@
 	return details->object->type;
 }
 
+const char *ast_sorcery_object_get_extended(const void *object, const char *name)
+{
+	const struct ast_sorcery_object_details *details = object;
+	struct ast_variable *field;
+
+	for (field = details->object->extended; field; field = field->next) {
+		if (!strcmp(field->name, name)) {
+			return field->value;
+		}
+	}
+
+	return NULL;
+}
+
 int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
 {
 	RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);

Modified: team/file/sorceryx4/tests/test_sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorceryx4/tests/test_sorcery.c?view=diff&rev=389050&r1=389049&r2=389050
==============================================================================
--- team/file/sorceryx4/tests/test_sorcery.c (original)
+++ team/file/sorceryx4/tests/test_sorcery.c Sat May 18 12:27:30 2013
@@ -1294,6 +1294,53 @@
 		res = AST_TEST_FAIL;
 	} else if (obj->bob != 256) {
 		ast_test_status_update(test, "Regex field handler was not called when it should have been\n");
+		res = AST_TEST_FAIL;
+	}
+
+	return res;
+}
+
+AST_TEST_DEFINE(extended_fields)
+{
+	int res = AST_TEST_PASS;
+	RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
+	RAII_VAR(struct test_sorcery_object *, obj, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
+	const char *value;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "extended_fields";
+		info->category = "/main/sorcery/";
+		info->summary = "sorcery object extended fields unit test";
+		info->description =
+			"Test extended fields support in sorcery";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	if (!(sorcery = alloc_and_initialize_sorcery())) {
+		ast_test_status_update(test, "Failed to open sorcery structure\n");
+		return AST_TEST_FAIL;
+	}
+
+	if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
+		ast_test_status_update(test, "Failed to allocate a known object type\n");
+		return AST_TEST_FAIL;
+	}
+
+	if (!(objset = ast_variable_new("@testing", "toast", ""))) {
+		ast_test_status_update(test, "Failed to create an object set, test could not occur\n");
+		res = AST_TEST_FAIL;
+	} else if (ast_sorcery_objectset_apply(sorcery, obj, objset)) {
+		ast_test_status_update(test, "Failed to apply valid object set to object\n");
+		res = AST_TEST_FAIL;
+	} else if (!(value = ast_sorcery_object_get_extended(obj, "testing"))) {
+		ast_test_status_update(test, "Extended field, which was set using object set, could not be found\n");
+		res = AST_TEST_FAIL;
+	} else if (strcmp(value, "toast")) {
+		ast_test_status_update(test, "Extended field does not contain expected value\n");
 		res = AST_TEST_FAIL;
 	}
 
@@ -2604,6 +2651,7 @@
 	AST_TEST_UNREGISTER(objectset_apply_invalid);
 	AST_TEST_UNREGISTER(objectset_transform);
 	AST_TEST_UNREGISTER(objectset_apply_fields);
+	AST_TEST_UNREGISTER(extended_fields);
 	AST_TEST_UNREGISTER(changeset_create);
 	AST_TEST_UNREGISTER(changeset_create_unchanged);
 	AST_TEST_UNREGISTER(object_create);
@@ -2651,6 +2699,7 @@
 	AST_TEST_REGISTER(objectset_apply_invalid);
 	AST_TEST_REGISTER(objectset_transform);
 	AST_TEST_REGISTER(objectset_apply_fields);
+	AST_TEST_REGISTER(extended_fields);
 	AST_TEST_REGISTER(changeset_create);
 	AST_TEST_REGISTER(changeset_create_unchanged);
 	AST_TEST_REGISTER(object_create);




More information about the asterisk-commits mailing list