1 /* lv2_event_helpers.h - Helper functions for the LV2 events extension.
3 * Copyright (C) 2008-2009 David Robillard <http://drobilla.net>
5 * This header is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This header is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13 * License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this header; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
20 #ifndef LV2_EVENT_HELPERS_H
21 #define LV2_EVENT_HELPERS_H
28 #include "lv2_event.h"
31 * Helper functions for the LV2 Event extension
32 * <http://lv2plug.in/ns/ext/event>.
34 * These functions are provided for convenience only, use of them is not
35 * required for supporting lv2ev (i.e. the events extension is defined by the
36 * raw buffer format described in lv2_event.h and NOT by this API).
38 * Note that these functions are all static inline which basically means:
39 * do not take the address of these functions. */
42 /** Pad a size to 64 bits (for event sizes) */
43 static inline uint16_t
44 lv2_event_pad_size(uint16_t size
)
46 return (size
+ 7) & (~7);
50 /** Initialize (empty, reset..) an existing event buffer.
51 * The contents of buf are ignored entirely and overwritten, except capacity
52 * which is unmodified. */
54 lv2_event_buffer_reset(LV2_Event_Buffer
* buf
, uint16_t stamp_type
, uint8_t *data
)
57 buf
->header_size
= sizeof(LV2_Event_Buffer
);
58 buf
->stamp_type
= stamp_type
;
64 /** Allocate a new, empty event buffer. */
65 static inline LV2_Event_Buffer
*
66 lv2_event_buffer_new(uint32_t capacity
, uint16_t stamp_type
)
68 LV2_Event_Buffer
* buf
= (LV2_Event_Buffer
*)malloc(sizeof(LV2_Event_Buffer
) + capacity
);
70 buf
->capacity
= capacity
;
71 lv2_event_buffer_reset(buf
, stamp_type
, (uint8_t *)(buf
+ 1));
79 /** An iterator over an LV2_Event_Buffer.
81 * Multiple simultaneous read iterators over a single buffer is fine,
82 * but changing the buffer invalidates all iterators (e.g. RW Lock). */
84 LV2_Event_Buffer
* buf
;
89 /** Reset an iterator to point to the start of @a buf.
90 * @return True if @a iter is valid, otherwise false (buffer is empty) */
92 lv2_event_begin(LV2_Event_Iterator
* iter
,
93 LV2_Event_Buffer
* buf
)
97 return (buf
->size
> 0);
101 /** Check if @a iter is valid.
102 * @return True if @a iter is valid, otherwise false (past end of buffer) */
104 lv2_event_is_valid(LV2_Event_Iterator
* iter
)
106 return (iter
->offset
< iter
->buf
->size
);
110 /** Advance @a iter forward one event.
111 * @a iter must be valid.
112 * @return True if @a iter is valid, otherwise false (reached end of buffer) */
114 lv2_event_increment(LV2_Event_Iterator
* iter
)
116 assert(lv2_event_is_valid(iter
));
118 LV2_Event
* const ev
= (LV2_Event
*)(
119 (uint8_t*)iter
->buf
->data
+ iter
->offset
);
121 iter
->offset
+= lv2_event_pad_size(sizeof(LV2_Event
) + ev
->size
);
127 /** Dereference an event iterator (get the event currently pointed at).
128 * @a iter must be valid.
129 * @a data if non-NULL, will be set to point to the contents of the event
131 * @return A Pointer to the event @a iter is currently pointing at, or NULL
132 * if the end of the buffer is reached (in which case @a data is
133 * also set to NULL). */
134 static inline LV2_Event
*
135 lv2_event_get(LV2_Event_Iterator
* iter
,
138 assert(lv2_event_is_valid(iter
));
140 LV2_Event
* const ev
= (LV2_Event
*)(
141 (uint8_t*)iter
->buf
->data
+ iter
->offset
);
144 *data
= (uint8_t*)ev
+ sizeof(LV2_Event
);
150 /** Write an event at @a iter.
151 * The event (if any) pointed to by @a iter will be overwritten, and @a iter
152 * incremented to point to the following event (i.e. several calls to this
153 * function can be done in sequence without twiddling iter in-between).
154 * @return True if event was written, otherwise false (buffer is full). */
156 lv2_event_write(LV2_Event_Iterator
* iter
,
163 if (iter
->buf
->capacity
- iter
->buf
->size
< sizeof(LV2_Event
) + size
)
166 LV2_Event
* const ev
= (LV2_Event
*)(
167 (uint8_t*)iter
->buf
->data
+ iter
->offset
);
170 ev
->subframes
= subframes
;
173 memcpy((uint8_t*)ev
+ sizeof(LV2_Event
), data
, size
);
174 ++iter
->buf
->event_count
;
176 size
= lv2_event_pad_size(sizeof(LV2_Event
) + size
);
177 iter
->buf
->size
+= size
;
178 iter
->offset
+= size
;
184 /** Reserve space for an event in the buffer and return a pointer to
185 the memory where the caller can write the event data, or NULL if there
186 is not enough room in the buffer. */
187 static inline uint8_t*
188 lv2_event_reserve(LV2_Event_Iterator
* iter
,
194 size
= lv2_event_pad_size(size
);
195 if (iter
->buf
->capacity
- iter
->buf
->size
< sizeof(LV2_Event
) + size
)
198 LV2_Event
* const ev
= (LV2_Event
*)((uint8_t*)iter
->buf
->data
+
202 ev
->subframes
= subframes
;
205 ++iter
->buf
->event_count
;
207 size
= lv2_event_pad_size(sizeof(LV2_Event
) + size
);
208 iter
->buf
->size
+= size
;
209 iter
->offset
+= size
;
211 return (uint8_t*)ev
+ sizeof(LV2_Event
);
215 /** Write an event at @a iter.
216 * The event (if any) pointed to by @a iter will be overwritten, and @a iter
217 * incremented to point to the following event (i.e. several calls to this
218 * function can be done in sequence without twiddling iter in-between).
219 * @return True if event was written, otherwise false (buffer is full). */
221 lv2_event_write_event(LV2_Event_Iterator
* iter
,
225 if (iter
->buf
->capacity
- iter
->buf
->size
< sizeof(LV2_Event
) + ev
->size
)
228 LV2_Event
* const write_ev
= (LV2_Event
*)(
229 (uint8_t*)iter
->buf
->data
+ iter
->offset
);
232 memcpy((uint8_t*)write_ev
+ sizeof(LV2_Event
), data
, ev
->size
);
233 ++iter
->buf
->event_count
;
235 const uint16_t size
= lv2_event_pad_size(sizeof(LV2_Event
) + ev
->size
);
236 iter
->buf
->size
+= size
;
237 iter
->offset
+= size
;
242 #endif /* LV2_EVENT_HELPERS_H */