The structure for control element ID is hybrid. It has two ways to check equality; e.g. equality of fields except for numid. Just checking equality according to the fields, current alsa-lib take userspace applications to call functions referring to the fields several times. It's better to add optimized version of the equality check. This commit adds API to check the equality of fields for a pair of control element IDs. Signed-off-by: Takashi Sakamoto <o-takashi@xxxxxxxxxxxxx> --- include/control.h | 1 + src/control/control.c | 26 +++++++++++++++++++++++++- test/lsb/ctl-elem-id.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/include/control.h b/include/control.h index 260d7f30..8aca67e6 100644 --- a/include/control.h +++ b/include/control.h @@ -425,6 +425,7 @@ void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj); void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj); void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src); int snd_ctl_elem_id_equal_by_numid(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r); +int snd_ctl_elem_id_equal_by_tuple(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r); int snd_ctl_elem_id_compare(snd_ctl_elem_id_t *id1, const snd_ctl_elem_id_t *id2); unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj); snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj); diff --git a/src/control/control.c b/src/control/control.c index 6d1eda15..93f8f93d 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -84,7 +84,9 @@ rare). The numid can change on each boot. In case of an USB sound card, the numid can also change when it is reconnected. For equality check between a pair of #snd_ctl_elem_id_t according to the numid, -snd_ctl_elem_id_equal_by_numid() is available. +snd_ctl_elem_id_equal_by_numid() is available. For equality check between a pair +of #snd_ctl_elem_id_t according to the tuple, snd_ctl_elem_id_equal_by_tuple() +is available. \section element_lists Element Lists @@ -1837,6 +1839,28 @@ int snd_ctl_elem_id_equal_by_numid(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) return l->numid == r->numid; } +/** + * \brief check equality between two arguments according to iface, device, + * subdevice, name, and index fields. + * \param l opaque pointer to element ID structure. + * \param r opaque pointer to another element ID structure. + * \retval zero if they equal, else zero. + * + * The structure underlying #snd_ctl_elem_id_t is hybrid one. It has two ways to + * check equality. The API implements one of the ways, according to the values + * of iface, device, subdevice, name, and index fields. + */ +int snd_ctl_elem_id_equal_by_tuple(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + assert(l && r); + + return (l->iface == r->iface) && + (l->device == r->device) && + (l->subdevice == r->subdevice) && + !strcmp((const char *)l->name, (const char *)r->name) && + (l->index == r->index); +} + /** * \brief compare one #snd_ctl_elem_id_t to another * \param id1 pointer to first id diff --git a/test/lsb/ctl-elem-id.c b/test/lsb/ctl-elem-id.c index f499b268..39060a8e 100644 --- a/test/lsb/ctl-elem-id.c +++ b/test/lsb/ctl-elem-id.c @@ -64,6 +64,38 @@ static void equality_by_numid_3(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) assert(!snd_ctl_elem_id_equal_by_numid(l, r)); } +// Case 1.0. The same tuple should result in true positive. +static void equality_by_tuple_0(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + set_elem_id_by_tuple(l, SND_CTL_ELEM_IFACE_CARD, 1000, 1010, "something", 1020); + set_elem_id_by_tuple(r, SND_CTL_ELEM_IFACE_CARD, 1000, 1010, "something", 1020); + assert(snd_ctl_elem_id_equal_by_tuple(l, r)); +} + +// Case 1.1. The different conpounds should result in true positive. +static void equality_by_tuple_1(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + set_elem_id_by_tuple(l, SND_CTL_ELEM_IFACE_CARD, 1030, 1040, "something", 1050); + set_elem_id_by_tuple(r, SND_CTL_ELEM_IFACE_MIXER, 1031, 1042, "something", 1053); + assert(!snd_ctl_elem_id_equal_by_tuple(l, r)); +} + +// Case 1.2. The same value of numid field should result in false positive. +static void equality_by_tuple_2(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + snd_ctl_elem_id_set_numid(l, 0xfeedc0de); + snd_ctl_elem_id_set_numid(r, 0xfeedc0de); + assert(!snd_ctl_elem_id_equal_by_tuple(l, r)); +} + +// Case 1.3. The different value of numid field should result in false positive. +static void equality_by_tuple_3(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + snd_ctl_elem_id_set_numid(l, 0xfeedc0de); + snd_ctl_elem_id_set_numid(r, 0xdeadbeef); + assert(!snd_ctl_elem_id_equal_by_tuple(l, r)); +} + int main() { void (*entries[])(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) = { @@ -71,6 +103,10 @@ int main() equality_by_numid_1, equality_by_numid_2, equality_by_numid_3, + equality_by_tuple_0, + equality_by_tuple_1, + equality_by_tuple_2, + equality_by_tuple_3, }; int count = sizeof(entries) / sizeof(*entries); int fd; -- 2.27.0