From: Takashi Sakamoto Date: Mon, 8 Jun 2020 14:10:10 +0000 (+0900) Subject: seq: event_cntr: add an API to calculate the number of events X-Git-Tag: v0.1.0~133 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=bdd9af6a209a01c310fad2d74021ba9a83d133d0;p=alsa-gobject.git seq: event_cntr: add an API to calculate the number of events Signed-off-by: Takashi Sakamoto --- diff --git a/src/seq/alsaseq.map b/src/seq/alsaseq.map index d03af9b..745ecd0 100644 --- a/src/seq/alsaseq.map +++ b/src/seq/alsaseq.map @@ -172,6 +172,7 @@ ALSA_GOBJECT_0_0_0 { "alsaseq_event_cntr_get_type"; "alsaseq_event_cntr_new"; + "alsaseq_event_cntr_count_events"; local: *; }; diff --git a/src/seq/event-cntr.c b/src/seq/event-cntr.c index cc935c2..598dbf7 100644 --- a/src/seq/event-cntr.c +++ b/src/seq/event-cntr.c @@ -74,3 +74,82 @@ ALSASeqEventCntr *alsaseq_event_cntr_new(guint count, GError **error) return self; } + +static gsize calculate_event_size(struct snd_seq_event *ev, gboolean aligned) +{ + gsize size = sizeof(*ev); + + switch (ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) { + case SNDRV_SEQ_EVENT_LENGTH_VARIABLE: + { + const struct snd_seq_ev_ext *ext = &ev->data.ext; + if (aligned) + size += ext->len; + else + size += (ext->len + sizeof(*ev) - 1) / sizeof(*ev) * sizeof(*ev); + break; + } + default: + break; + } + + return size; +} + +struct event_iterator { + guint8 *buf; + gsize length; + gboolean aligned; + + gsize offset; +}; + +static void event_iterator_init(struct event_iterator *iter, guint8 *buf, + gsize length, gboolean aligned) +{ + iter->buf = buf; + iter->length = length; + iter->aligned = aligned; + + iter->offset = 0; +} + +static struct snd_seq_event *event_iterator_next(struct event_iterator *iter) +{ + struct snd_seq_event *ev; + gsize ev_size; + + if (iter->offset + sizeof(*ev) > iter->length) + return NULL; + ev = (struct snd_seq_event *)(iter->buf + iter->offset); + + ev_size = calculate_event_size(ev, iter->aligned); + if (iter->offset + ev_size > iter->length) + return NULL; + iter->offset += ev_size; + + return ev; +} + +/** + * alsaseq_event_cntr_count_events: + * @self: A #ALSASeqEventCntr. + * @count: (out): The count of stored events. + * + * count stored events. + */ +void alsaseq_event_cntr_count_events(ALSASeqEventCntr *self, gsize *count) +{ + ALSASeqEventCntrPrivate *priv; + struct event_iterator iter; + struct snd_seq_event *ev; + + g_return_if_fail(ALSASEQ_IS_EVENT_CNTR(self)); + priv = alsaseq_event_cntr_get_instance_private(self); + + event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); + + *count = 0; + while ((ev = event_iterator_next(&iter))) + ++(*count); +} diff --git a/src/seq/event-cntr.h b/src/seq/event-cntr.h index c737606..ac7caaa 100644 --- a/src/seq/event-cntr.h +++ b/src/seq/event-cntr.h @@ -47,6 +47,8 @@ GType alsaseq_event_cntr_get_type() G_GNUC_CONST; ALSASeqEventCntr *alsaseq_event_cntr_new(guint count, GError **error); +void alsaseq_event_cntr_count_events(ALSASeqEventCntr *self, gsize *count); + G_END_DECLS #endif diff --git a/tests/alsaseq-event-cntr b/tests/alsaseq-event-cntr index 9623190..8727bf5 100644 --- a/tests/alsaseq-event-cntr +++ b/tests/alsaseq-event-cntr @@ -13,6 +13,7 @@ target = ALSASeq.EventCntr() props = () methods = ( 'new', + 'count_events', ) signals = ()