PipeWire: spa/pod/dynamic.h Source File

PipeWire 0.3.51

dynamic.h
1/* Simple Plugin API
2 *
3 * Copyright © 2018 Wim Taymans
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef SPA_POD_DYNAMIC_H
26#define SPA_POD_DYNAMIC_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include <spa/pod/builder.h>
33
34struct spa_pod_dynamic_builder {
35 struct spa_pod_builder b;
36 void *data;
37 uint32_t extend;
38 uint32_t _padding;
39};
40
41 static int spa_pod_dynamic_builder_overflow(void *data, uint32_t size)
42{
43 struct spa_pod_dynamic_builder *d = (struct spa_pod_dynamic_builder*)data;
44 int32_t old_size = d->b.size;
45 int32_t new_size = SPA_ROUND_UP_N(size, d->extend);
46 void *old_data = d->b.data;
47
48 if (old_data == d->data)
49 d->b.data = NULL;
50 if ((d->b.data = realloc(d->b.data, new_size)) == NULL)
51 return -errno;
52 if (old_data == d->data && d->b.data != old_data && old_size > 0)
53 memcpy(d->b.data, old_data, old_size);
54 d->b.size = new_size;
55 return 0;
56}
57
58static inline void spa_pod_dynamic_builder_init(struct spa_pod_dynamic_builder *builder,
59 void *data, uint32_t size, uint32_t extend)
60{
61 static const struct spa_pod_builder_callbacks spa_pod_dynamic_builder_callbacks = {
62 SPA_VERSION_POD_BUILDER_CALLBACKS,
63 .overflow = spa_pod_dynamic_builder_overflow
64 };
65 builder->b = SPA_POD_BUILDER_INIT(data, size);
66 spa_pod_builder_set_callbacks(&builder->b, &spa_pod_dynamic_builder_callbacks, builder);
67 builder->extend = extend;
68 builder->data = data;
69}
70
71static inline void spa_pod_dynamic_builder_clean(struct spa_pod_dynamic_builder *builder)
72{
73 if (builder->data != builder->b.data)
74 free(builder->b.data);
75}
76
77#ifdef __cplusplus
78} /* extern "C" */
79#endif
80
81#endif /* SPA_POD_DYNAMIC_H */
builder.h
spa/pod/builder.h
spa_pod_builder_set_callbacks
static void spa_pod_builder_set_callbacks(struct spa_pod_builder *builder, const struct spa_pod_builder_callbacks *callbacks, void *data)
Definition: builder.h:91
SPA_POD_BUILDER_INIT
#define SPA_POD_BUILDER_INIT(buffer, size)
Definition: builder.h:82
SPA_VERSION_POD_BUILDER_CALLBACKS
#define SPA_VERSION_POD_BUILDER_CALLBACKS
Definition: builder.h:67
SPA_ROUND_UP_N
#define SPA_ROUND_UP_N(num, align)
Definition: defs.h:296
spa_pod_builder_callbacks
Definition: builder.h:65
spa_pod_builder
Definition: builder.h:73
spa_pod_builder::data
void * data
Definition: builder.h:74
spa_pod_builder::size
uint32_t size
Definition: builder.h:75
spa_pod_dynamic_builder
Definition: dynamic.h:38
spa_pod_dynamic_builder::extend
uint32_t extend
Definition: dynamic.h:41
spa_pod_dynamic_builder::_padding
uint32_t _padding
Definition: dynamic.h:42
spa_pod_dynamic_builder::b
struct spa_pod_builder b
Definition: dynamic.h:39
spa_pod_dynamic_builder::data
void * data
Definition: dynamic.h:40