@@ -426,6 +426,7 @@ 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_by_numid(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);
@@ -88,6 +88,10 @@ 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.
+Many algorithms can be defined to find ordered pair of #snd_ctl_elem_id_t.
+For one of the comparison algorithms according to the numid,
+snd_ctl_elem_id_compare_by_numid() is available.
+
\section element_lists Element Lists
An element list can be used to obtain a list of all elements of the
@@ -1861,6 +1865,34 @@ int snd_ctl_elem_id_equal_by_tuple(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r)
(l->index == r->index);
}
+static int compare_unsigned_integer(unsigned int l, unsigned int r)
+{
+ if (l == r)
+ return 0;
+ else if (l < r)
+ return -1;
+ else
+ return 1;
+}
+
+/**
+ * \brief compare two arguments as orderd items by algorithm according to numid.
+ * \param l opaque pointer to element ID structure.
+ * \param r opaque pointer to another element ID structure.
+ * \retval positive if left is greater than right, negative if left is less
+ * than right, zero if they equal.
+ *
+ * The structure underlying #snd_ctl_elem_id_t is compound one. The
+ * comparison algorithm for it is not single and unique. The API implements
+ * one of comparison algorithms, according to the value of numid field.
+ */
+int snd_ctl_elem_id_compare_by_numid(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r)
+{
+ assert(l && r);
+
+ return compare_unsigned_integer(l->numid, r->numid);
+}
+
/**
* \brief compare one #snd_ctl_elem_id_t to another
* \param id1 pointer to first id
@@ -16,6 +16,8 @@
#include <unistd.h>
+#include <limits.h>
+
#include "../include/asoundlib.h"
static void set_elem_id_by_tuple(snd_ctl_elem_id_t *elem_id,
@@ -96,6 +98,43 @@ static void equality_by_tuple_3(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r)
assert(!snd_ctl_elem_id_equal_by_tuple(l, r));
}
+// Case 2.0. The left object with less value in numid field than right object
+// should result in negative value.
+static void comparison_by_numid_0(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r)
+{
+ snd_ctl_elem_id_set_numid(l, 0xdeadbeef);
+ snd_ctl_elem_id_set_numid(r, 0xfeedc0de);
+ assert(snd_ctl_elem_id_compare_by_numid(l, r) < 0);
+}
+
+// Case 2.1. The left object with the same value in numid field as right object
+// should result in zero.
+static void comparison_by_numid_1(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_compare_by_numid(l, r) == 0);
+}
+
+// Case 2.2. The left object with greater value in numid field than right object
+// should result in positive.
+static void comparison_by_numid_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, 0xdeadbeef);
+ assert(snd_ctl_elem_id_compare_by_numid(l, r) > 0);
+}
+
+// Case 2.3. The left object with lesser value in numid field than right object
+// should result in negative. The subtraction shoud be calculated in
+// storage larger than the storage of 'unsigned int'.
+static void comparison_by_numid_3(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r)
+{
+ snd_ctl_elem_id_set_numid(l, 0);
+ snd_ctl_elem_id_set_numid(r, UINT_MAX);
+ assert(snd_ctl_elem_id_compare_by_numid(l, r) < 0);
+}
+
int main()
{
void (*entries[])(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) = {
@@ -107,6 +146,10 @@ int main()
equality_by_tuple_1,
equality_by_tuple_2,
equality_by_tuple_3,
+ comparison_by_numid_0,
+ comparison_by_numid_1,
+ comparison_by_numid_2,
+ comparison_by_numid_3,
};
int count = sizeof(entries) / sizeof(*entries);
int fd;
The structure for control element ID is compound one. It means that it's not possible to decide single algorithm to find order of a pair of control element IDs. For convenience of application developers, it's better to produce API to decide the order by useful algorithm. This commit adds API for one of comparison algorithms. The value of numid field is used for the comparison. I note that the structure includes some 'unsigned integer' type of fields. The subtraction of the fields brings integer overflow as long as the calculation is done in the same storage size of the type itself. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> --- include/control.h | 1 + src/control/control.c | 32 +++++++++++++++++++++++++++++++ test/lsb/ctl-elem-id.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+)