Use binary search for functions

This commit is contained in:
Benedikt Heine 2018-12-07 23:29:51 +01:00
parent c35801b3ab
commit ae58207f9b
2 changed files with 46 additions and 10 deletions

View File

@ -71,20 +71,42 @@ static const char *stack_tag_hints[] = {
"x-canonical-private-synchronous", "x-canonical-private-synchronous",
"x-dunst-stack-tag" "x-dunst-stack-tag"
}; };
struct dbus_method {
const char *method_name;
void (*method) (GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation);
};
#define DBUS_METHOD(name) static void dbus_cb_##name( \ #define DBUS_METHOD(name) static void dbus_cb_##name( \
GDBusConnection *connection, \ GDBusConnection *connection, \
const gchar *sender, \ const gchar *sender, \
GVariant *parameters, \ GVariant *parameters, \
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
#define CALL_METHOD(name) dbus_cb_##name(connection, sender, parameters, invocation) static struct raw_image *get_raw_image_from_data_hint(GVariant *icon_data);
int cmp_methods(const void *vkey, const void *velem)
{
const char *key = (const char*)vkey;
const struct dbus_method *m = (const struct dbus_method*)velem;
return strcmp(key, m->method_name);
}
DBUS_METHOD(Notify); DBUS_METHOD(Notify);
DBUS_METHOD(CloseNotification); DBUS_METHOD(CloseNotification);
DBUS_METHOD(GetCapabilities); DBUS_METHOD(GetCapabilities);
DBUS_METHOD(GetServerInformation); DBUS_METHOD(GetServerInformation);
static struct raw_image *get_raw_image_from_data_hint(GVariant *icon_data); static struct dbus_method methods_fdn[] = {
{"CloseNotification", dbus_cb_CloseNotification},
{"GetCapabilities", dbus_cb_GetCapabilities},
{"GetServerInformation", dbus_cb_GetServerInformation},
{"Notify", dbus_cb_Notify},
};
void handle_method_call(GDBusConnection *connection, void handle_method_call(GDBusConnection *connection,
const gchar *sender, const gchar *sender,
@ -95,14 +117,15 @@ void handle_method_call(GDBusConnection *connection,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
gpointer user_data) gpointer user_data)
{ {
if (STR_EQ(method_name, "GetCapabilities")) { struct dbus_method *m = bsearch(
CALL_METHOD(GetCapabilities); method_name,
} else if (STR_EQ(method_name, "Notify")) { &methods_fdn,
CALL_METHOD(Notify); G_N_ELEMENTS(methods_fdn),
} else if (STR_EQ(method_name, "CloseNotification")) { sizeof(struct dbus_method),
CALL_METHOD(CloseNotification); cmp_methods);
} else if (STR_EQ(method_name, "GetServerInformation")) {
CALL_METHOD(GetServerInformation); if (m) {
m->method(connection, sender, parameters, invocation);
} else { } else {
LOG_M("Unknown method name: '%s' (sender: '%s').", LOG_M("Unknown method name: '%s' (sender: '%s').",
method_name, method_name,

View File

@ -268,6 +268,17 @@ TEST test_server_caps(enum markup_mode markup)
PASS(); PASS();
} }
TEST assert_methodlists_sorted(void)
{
for (size_t i = 0; i+1 < G_N_ELEMENTS(methods_fdn); i++) {
ASSERT(0 > strcmp(
methods_fdn[i].method_name,
methods_fdn[i+1].method_name));
}
PASS();
}
// TESTS END // TESTS END
@ -286,6 +297,8 @@ gpointer run_threaded_tests(gpointer data)
RUN_TESTp(test_server_caps, MARKUP_STRIP); RUN_TESTp(test_server_caps, MARKUP_STRIP);
RUN_TESTp(test_server_caps, MARKUP_NO); RUN_TESTp(test_server_caps, MARKUP_NO);
RUN_TEST(assert_methodlists_sorted);
RUN_TEST(test_dbus_teardown); RUN_TEST(test_dbus_teardown);
g_main_loop_quit(loop); g_main_loop_quit(loop);
return NULL; return NULL;