From 57e473b61cf373f8d9befb03d359b999eca4262b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 4 Sep 2004 00:27:36 +0000 Subject: add support for automatic termination of the daemon after the last client quit remove all gcc warnings add boolean types for tagstruct and modargs git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@178 fefdeb5f-60dc-0310-8127-8f9354f1896f --- doc/todo | 6 +----- polyp/client.c | 6 ++++++ polyp/cmdline.c | 7 ++++++- polyp/cmdline.h | 2 +- polyp/core.c | 28 +++++++++++++++++++++++++++ polyp/core.h | 6 ++++++ polyp/main.c | 1 + polyp/modargs.c | 40 +++++++++++++++++++++++++++++++++++++++ polyp/modargs.h | 2 ++ polyp/module-native-protocol-fd.c | 2 +- polyp/module-oss-mmap.c | 9 +++++---- polyp/module-oss.c | 11 ++++++----- polyp/module-protocol-stub.c | 9 +++++---- polyp/module.c | 5 ++++- polyp/polyplib-def.h | 2 +- polyp/polyplib-introspect.c | 2 +- polyp/polyplib-introspect.h | 4 ++-- polyp/polyplib-stream.c | 2 +- polyp/protocol-native.c | 8 ++++---- polyp/protocol-simple.c | 6 +++--- polyp/scache.c | 2 +- polyp/tagstruct.c | 30 +++++++++++++++++++++++++++-- polyp/tagstruct.h | 2 ++ 23 files changed, 155 insertions(+), 37 deletions(-) diff --git a/doc/todo b/doc/todo index bfc29fab..5a1a247c 100644 --- a/doc/todo +++ b/doc/todo @@ -9,17 +9,13 @@ kill client/... autoload management - more complete pactl -- cleanup tagstruct and modargs (add s32, pa_volume_t, pa_usec_t) -- remove all gcc warnings -- make fragments settings runtime configurable - logging -- automatic termination of daemon if unused - add sample directory -- paman: show scache and sample size - add timing parameter to write callback of stream in client API ** later *** - xmlrpc/http +- dbus - slp/rendezvous - modinfo - make alsa modules use mmap diff --git a/polyp/client.c b/polyp/client.c index 0cb42466..c7fb1e07 100644 --- a/polyp/client.c +++ b/polyp/client.c @@ -51,6 +51,8 @@ struct pa_client *pa_client_new(struct pa_core *core, const char *protocol_name, fprintf(stderr, "client: created %u \"%s\"\n", c->index, c->name); pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index); + + pa_core_check_quit(core); return c; } @@ -59,10 +61,14 @@ void pa_client_free(struct pa_client *c) { assert(c && c->core); pa_idxset_remove_by_data(c->core->clients, c, NULL); + + pa_core_check_quit(c->core); + fprintf(stderr, "client: freed %u \"%s\"\n", c->index, c->name); pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index); pa_xfree(c->name); pa_xfree(c); + } void pa_client_kill(struct pa_client *c) { diff --git a/polyp/cmdline.c b/polyp/cmdline.c index 265e0ec8..aba20af1 100644 --- a/polyp/cmdline.c +++ b/polyp/cmdline.c @@ -75,6 +75,7 @@ void pa_cmdline_help(const char *argv0) { " -d Disallow module loading after startup\n" " -f Dont quit when the startup fails\n" " -v Verbose startup\n" + " -X SECS Terminate the daemon after the last client quit and this time passed\n" " -h Show this help\n" " -V Show version\n", e, cfg); @@ -97,11 +98,12 @@ struct pa_cmdline* pa_cmdline_parse(int argc, char * const argv []) { cmdline->version = cmdline->disallow_module_loading = 0; cmdline->fail = 1; + cmdline->quit_after_last_client_time = -1; buf = pa_strbuf_new(); assert(buf); - while ((c = getopt(argc, argv, "L:F:CDhfvrRVnd")) != -1) { + while ((c = getopt(argc, argv, "L:F:CDhfvrRVndX:")) != -1) { switch (c) { case 'L': pa_strbuf_printf(buf, "load %s\n", optarg); @@ -139,6 +141,9 @@ struct pa_cmdline* pa_cmdline_parse(int argc, char * const argv []) { case 'd': cmdline->disallow_module_loading = 1; break; + case 'X': + cmdline->quit_after_last_client_time = atoi(optarg); + break; default: goto fail; } diff --git a/polyp/cmdline.h b/polyp/cmdline.h index 7330a716..d1c438d1 100644 --- a/polyp/cmdline.h +++ b/polyp/cmdline.h @@ -24,7 +24,7 @@ struct pa_cmdline { - int daemonize, help, fail, verbose, high_priority, stay_root, version, disallow_module_loading; + int daemonize, help, fail, verbose, high_priority, stay_root, version, disallow_module_loading, quit_after_last_client_time; char *cli_commands; }; diff --git a/polyp/core.c b/polyp/core.c index da6ace6a..4362f0cb 100644 --- a/polyp/core.c +++ b/polyp/core.c @@ -71,6 +71,9 @@ struct pa_core* pa_core_new(struct pa_mainloop_api *m) { c->memblock_stat = pa_memblock_stat_new(); c->disallow_module_loading = 0; + + c->quit_event = NULL; + c->quit_after_last_client_time = -1; pa_check_for_sigpipe(); @@ -102,6 +105,11 @@ void pa_core_free(struct pa_core *c) { pa_namereg_free(c); pa_autoload_free(c); pa_subscription_free_all(c); + + if (c->quit_event) { + c->mainloop->time_free(c->quit_event); + c->quit_event = NULL; + } pa_xfree(c->default_source_name); pa_xfree(c->default_sink_name); @@ -111,3 +119,23 @@ void pa_core_free(struct pa_core *c) { pa_xfree(c); } +static void quit_callback(struct pa_mainloop_api*m, struct pa_time_event *e, const struct timeval *tv, void *userdata) { + struct pa_core *c = userdata; + assert(c->quit_event = e); + + m->quit(m, 0); +} + +void pa_core_check_quit(struct pa_core *c) { + assert(c); + + if (!c->quit_event && c->quit_after_last_client_time >= 0 && pa_idxset_ncontents(c->clients) == 0) { + struct timeval tv; + gettimeofday(&tv, NULL); + tv.tv_sec+= c->quit_after_last_client_time; + c->quit_event = c->mainloop->time_new(c->mainloop, &tv, quit_callback, c); + } else if (c->quit_event && pa_idxset_ncontents(c->clients) > 0) { + c->mainloop->time_free(c->quit_event); + c->quit_event = NULL; + } +} diff --git a/polyp/core.h b/polyp/core.h index ffcd018b..513d8172 100644 --- a/polyp/core.h +++ b/polyp/core.h @@ -48,9 +48,15 @@ struct pa_core { struct pa_memblock_stat *memblock_stat; int disallow_module_loading; + int quit_after_last_client_time; + + struct pa_time_event *quit_event; + }; struct pa_core* pa_core_new(struct pa_mainloop_api *m); void pa_core_free(struct pa_core*c); +void pa_core_check_quit(struct pa_core *c); + #endif diff --git a/polyp/main.c b/polyp/main.c index 1c09276e..0f88a76e 100644 --- a/polyp/main.c +++ b/polyp/main.c @@ -213,6 +213,7 @@ int main(int argc, char *argv[]) { pa_loop_write(daemon_pipe[1], &retval, sizeof(retval)); c->disallow_module_loading = cmdline->disallow_module_loading; + c->quit_after_last_client_time = cmdline->quit_after_last_client_time; fprintf(stderr, __FILE__": mainloop entry.\n"); if (pa_mainloop_run(mainloop, &retval) < 0) diff --git a/polyp/modargs.c b/polyp/modargs.c index 87d99ad2..4874d808 100644 --- a/polyp/modargs.c +++ b/polyp/modargs.c @@ -207,6 +207,46 @@ int pa_modargs_get_value_u32(struct pa_modargs *ma, const char *key, uint32_t *v return 0; } +int pa_modargs_get_value_s32(struct pa_modargs *ma, const char *key, int32_t *value) { + const char *v; + char *e; + signed long l; + assert(ma && key && value); + + if (!(v = pa_modargs_get_value(ma, key, NULL))) + return 0; + + if (!*v) + return -1; + + l = strtol(v, &e, 0); + if (*e) + return -1; + + *value = (int32_t) l; + return 0; +} + +int pa_modargs_get_value_boolean(struct pa_modargs *ma, const char *key, int *value) { + const char *v; + assert(ma && key && value); + + if (!(v = pa_modargs_get_value(ma, key, NULL))) + return 0; + + if (!*v) + return -1; + + if (!strcmp(v, "1") || !strcasecmp(v, "yes") || !strcasecmp(v, "y") || !strcasecmp(v, "on")) + *value = 1; + else if (!strcmp(v, "0") || !strcasecmp(v, "no") || !strcasecmp(v, "n") || !strcasecmp(v, "off")) + *value = 0; + else + return -1; + + return 0; +} + int pa_modargs_get_sample_spec(struct pa_modargs *ma, struct pa_sample_spec *rss) { const char *format; uint32_t channels; diff --git a/polyp/modargs.h b/polyp/modargs.h index 872fb14f..705d9f43 100644 --- a/polyp/modargs.h +++ b/polyp/modargs.h @@ -33,6 +33,8 @@ void pa_modargs_free(struct pa_modargs*ma); const char *pa_modargs_get_value(struct pa_modargs *ma, const char *key, const char *def); int pa_modargs_get_value_u32(struct pa_modargs *ma, const char *key, uint32_t *value); +int pa_modargs_get_value_s32(struct pa_modargs *ma, const char *key, int32_t *value); +int pa_modargs_get_value_boolean(struct pa_modargs *ma, const char *key, int *value); int pa_modargs_get_sample_spec(struct pa_modargs *ma, struct pa_sample_spec *ss); diff --git a/polyp/module-native-protocol-fd.c b/polyp/module-native-protocol-fd.c index 58d09ffe..213e291e 100644 --- a/polyp/module-native-protocol-fd.c +++ b/polyp/module-native-protocol-fd.c @@ -50,7 +50,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { goto finish; } - if (pa_modargs_get_value_u32(ma, "fd", &fd) < 0) { + if (pa_modargs_get_value_s32(ma, "fd", &fd) < 0) { fprintf(stderr, __FILE__": invalid file descriptor.\n"); goto finish; } diff --git a/polyp/module-oss-mmap.c b/polyp/module-oss-mmap.c index 5c3be1ad..8a0dd9a4 100644 --- a/polyp/module-oss-mmap.c +++ b/polyp/module-oss-mmap.c @@ -234,20 +234,21 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { goto fail; } - if (pa_modargs_get_value_u32(ma, "record", &record) < 0 || pa_modargs_get_value_u32(ma, "playback", &playback) < 0) { + if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { fprintf(stderr, __FILE__": record= and playback= expect numeric arguments.\n"); goto fail; } - mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); - if (mode == 0) { + if (!playback && !record) { fprintf(stderr, __FILE__": neither playback nor record enabled for device.\n"); goto fail; } + mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); + nfrags = 12; frag_size = 1024; - if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) { + if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) { fprintf(stderr, __FILE__": failed to parse fragments arguments\n"); goto fail; } diff --git a/polyp/module-oss.c b/polyp/module-oss.c index 403716fd..4fd79624 100644 --- a/polyp/module-oss.c +++ b/polyp/module-oss.c @@ -177,7 +177,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { int fd = -1; int nfrags, frag_size, in_frag_size, out_frag_size; int mode; - uint32_t record = 1, playback = 1; + int record = 1, playback = 1; struct pa_sample_spec ss; struct pa_modargs *ma = NULL; assert(c && m); @@ -187,20 +187,21 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { goto fail; } - if (pa_modargs_get_value_u32(ma, "record", &record) < 0 || pa_modargs_get_value_u32(ma, "playback", &playback) < 0) { + if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { fprintf(stderr, __FILE__": record= and playback= expect numeric argument.\n"); goto fail; } - mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); - if (mode == 0) { + if (!playback && !record) { fprintf(stderr, __FILE__": neither playback nor record enabled for device.\n"); goto fail; } + mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); + nfrags = 12; frag_size = 1024; - if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) { + if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) { fprintf(stderr, __FILE__": failed to parse fragments arguments\n"); goto fail; } diff --git a/polyp/module-protocol-stub.c b/polyp/module-protocol-stub.c index e681732f..4d86c28e 100644 --- a/polyp/module-protocol-stub.c +++ b/polyp/module-protocol-stub.c @@ -83,15 +83,16 @@ static const char* const valid_modargs[] = { static struct pa_socket_server *create_socket_server(struct pa_core *c, struct pa_modargs *ma) { struct pa_socket_server *s; #ifdef USE_TCP_SOCKETS - uint32_t loopback = 1, port = IPV4_PORT; + int loopback = 1; + uint32_t port = IPV4_PORT; - if (pa_modargs_get_value_u32(ma, "loopback", &loopback) < 0) { + if (pa_modargs_get_value_boolean(ma, "loopback", &loopback) < 0) { fprintf(stderr, "loopback= expects a numerical argument.\n"); return NULL; } - if (pa_modargs_get_value_u32(ma, "port", &port) < 0) { - fprintf(stderr, "port= expects a numerical argument.\n"); + if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port < 1 || port > 0xFFFF) { + fprintf(stderr, "port= expects a numerical argument between 1 and 65535.\n"); return NULL; } diff --git a/polyp/module.c b/polyp/module.c index fc714953..a06b2754 100644 --- a/polyp/module.c +++ b/polyp/module.c @@ -117,6 +117,10 @@ fail: static void pa_module_free(struct pa_module *m) { assert(m && m->done && m->core); + + if (m->core->disallow_module_loading) + return; + m->done(m->core, m); lt_dlclose(m->dl); @@ -130,7 +134,6 @@ static void pa_module_free(struct pa_module *m) { pa_xfree(m); } - void pa_module_unload(struct pa_core *c, struct pa_module *m) { assert(c && m); diff --git a/polyp/polyplib-def.h b/polyp/polyplib-def.h index 6c3cd825..f0ecc5c4 100644 --- a/polyp/polyplib-def.h +++ b/polyp/polyplib-def.h @@ -140,7 +140,7 @@ struct pa_latency_info { pa_usec_t buffer_usec; /**< Time in usecs the current buffer takes to play */ pa_usec_t sink_usec; /**< Time in usecs a sample takes to be played on the sink. */ int playing; /**< Non-zero when the stream is currently playing */ - int queue_length; /**< Queue size in bytes. */ + uint32_t queue_length; /**< Queue size in bytes. */ }; PA_C_DECL_END diff --git a/polyp/polyplib-introspect.c b/polyp/polyplib-introspect.c index a4ecf5ee..b31a40c7 100644 --- a/polyp/polyplib-introspect.c +++ b/polyp/polyplib-introspect.c @@ -331,7 +331,7 @@ static void context_get_module_info_callback(struct pa_pdispatch *pd, uint32_t c pa_tagstruct_gets(t, &i.name) < 0 || pa_tagstruct_gets(t, &i.argument) < 0 || pa_tagstruct_getu32(t, &i.n_used) < 0 || - pa_tagstruct_getu32(t, &i.auto_unload) < 0) { + pa_tagstruct_get_boolean(t, &i.auto_unload) < 0) { pa_context_fail(o->context, PA_ERROR_PROTOCOL); goto finish; } diff --git a/polyp/polyplib-introspect.h b/polyp/polyplib-introspect.h index 1cc79d0f..0a14fad0 100644 --- a/polyp/polyplib-introspect.h +++ b/polyp/polyplib-introspect.h @@ -106,8 +106,8 @@ struct pa_module_info { uint32_t index; /**< Index of the module */ const char*name, /**< Name of the module */ *argument; /**< Argument string of the module */ - uint32_t n_used, /**< Usage counter or PA_INVALID_INDEX */ - auto_unload; /**< Non-zero if this is an autoloaded module */ + uint32_t n_used; /**< Usage counter or PA_INVALID_INDEX */ + int auto_unload; /**< Non-zero if this is an autoloaded module */ }; /** Get some information about a module by its index */ diff --git a/polyp/polyplib-stream.c b/polyp/polyplib-stream.c index 220e4a14..7170a32e 100644 --- a/polyp/polyplib-stream.c +++ b/polyp/polyplib-stream.c @@ -329,7 +329,7 @@ static void stream_get_latency_callback(struct pa_pdispatch *pd, uint32_t comman } else if (pa_tagstruct_getu32(t, &i.buffer_usec) < 0 || pa_tagstruct_getu32(t, &i.sink_usec) < 0 || - pa_tagstruct_getu32(t, &i.playing) < 0 || + pa_tagstruct_get_boolean(t, &i.playing) < 0 || pa_tagstruct_getu32(t, &i.queue_length) < 0 || !pa_tagstruct_eof(t)) { pa_context_fail(o->context, PA_ERROR_PROTOCOL); diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index cce6cc6c..2572810f 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -830,7 +830,7 @@ static void command_get_playback_latency(struct pa_pdispatch *pd, uint32_t comma pa_tagstruct_putu32(reply, tag); pa_tagstruct_putu32(reply, pa_sink_input_get_latency(s->sink_input)); pa_tagstruct_putu32(reply, pa_sink_get_latency(s->sink_input->sink)); - pa_tagstruct_putu32(reply, pa_memblockq_is_readable(s->memblockq)); + pa_tagstruct_put_boolean(reply, pa_memblockq_is_readable(s->memblockq)); pa_tagstruct_putu32(reply, pa_memblockq_get_length(s->memblockq)); pa_pstream_send_tagstruct(c->pstream, reply); } @@ -1012,7 +1012,7 @@ static void module_fill_tagstruct(struct pa_tagstruct *t, struct pa_module *modu pa_tagstruct_puts(t, module->name); pa_tagstruct_puts(t, module->argument ? module->argument : ""); pa_tagstruct_putu32(t, module->n_used); - pa_tagstruct_putu32(t, module->auto_unload); + pa_tagstruct_put_boolean(t, module->auto_unload); } static void sink_input_fill_tagstruct(struct pa_tagstruct *t, struct pa_sink_input *s) { @@ -1505,10 +1505,10 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo static struct pa_protocol_native* protocol_new_internal(struct pa_core *c, struct pa_module *m, struct pa_modargs *ma) { struct pa_protocol_native *p; - uint32_t public; + int public; assert(c && ma); - if (pa_modargs_get_value_u32(ma, "public", &public) < 0) { + if (pa_modargs_get_value_boolean(ma, "public", &public) < 0) { fprintf(stderr, __FILE__": public= expects numeric argument.\n"); return NULL; } diff --git a/polyp/protocol-simple.c b/polyp/protocol-simple.c index 41c1f484..3ccb3068 100644 --- a/polyp/protocol-simple.c +++ b/polyp/protocol-simple.c @@ -366,7 +366,7 @@ fail: struct pa_protocol_simple* pa_protocol_simple_new(struct pa_core *core, struct pa_socket_server *server, struct pa_module *m, struct pa_modargs *ma) { struct pa_protocol_simple* p = NULL; - uint32_t enable; + int enable; assert(core && server && ma); p = pa_xmalloc0(sizeof(struct pa_protocol_simple)); @@ -385,14 +385,14 @@ struct pa_protocol_simple* pa_protocol_simple_new(struct pa_core *core, struct p p->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); enable = 0; - if (pa_modargs_get_value_u32(ma, "record", &enable) < 0) { + if (pa_modargs_get_value_boolean(ma, "record", &enable) < 0) { fprintf(stderr, __FILE__": record= expects a numeric argument.\n"); goto fail; } p->mode = enable ? RECORD : 0; enable = 1; - if (pa_modargs_get_value_u32(ma, "playback", &enable) < 0) { + if (pa_modargs_get_value_boolean(ma, "playback", &enable) < 0) { fprintf(stderr, __FILE__": playback= expects a numeric argument.\n"); goto fail; } diff --git a/polyp/scache.c b/polyp/scache.c index b7a8ff02..53e8a3fe 100644 --- a/polyp/scache.c +++ b/polyp/scache.c @@ -172,7 +172,7 @@ uint32_t pa_scache_get_id_by_name(struct pa_core *c, const char *name) { uint32_t pa_scache_total_size(struct pa_core *c) { struct pa_scache_entry *e; uint32_t index; - uint32_t sum; + uint32_t sum = 0; if (!c->scache) return 0; diff --git a/polyp/tagstruct.c b/polyp/tagstruct.c index 742f6b9c..5aa79e6c 100644 --- a/polyp/tagstruct.c +++ b/polyp/tagstruct.c @@ -40,7 +40,9 @@ enum tags { TAG_U8 = 'B', TAG_S8 = 'b', TAG_SAMPLE_SPEC = 'a', - TAG_ARBITRARY = 'x' + TAG_ARBITRARY = 'x', + TAG_BOOLEAN_TRUE = '1', + TAG_BOOLEAN_FALSE = '0', }; struct pa_tagstruct { @@ -125,7 +127,6 @@ void pa_tagstruct_put_sample_spec(struct pa_tagstruct *t, const struct pa_sample t->length += 7; } - void pa_tagstruct_put_arbitrary(struct pa_tagstruct *t, const void *p, size_t length) { assert(t && p); @@ -137,6 +138,13 @@ void pa_tagstruct_put_arbitrary(struct pa_tagstruct *t, const void *p, size_t le t->length += 5+length; } +void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b) { + assert(t); + extend(t, 1); + t->data[t->length] = b ? TAG_BOOLEAN_TRUE : TAG_BOOLEAN_FALSE; + t->length += 1; +} + int pa_tagstruct_gets(struct pa_tagstruct*t, const char **s) { int error = 0; size_t n; @@ -238,3 +246,21 @@ const uint8_t* pa_tagstruct_data(struct pa_tagstruct*t, size_t *l) { return t->data; } +int pa_tagstruct_get_boolean(struct pa_tagstruct*t, int *b) { + assert(t && b); + + if (t->rindex+1 > t->length) + return -1; + + if (t->data[t->rindex] == TAG_BOOLEAN_TRUE) + *b = 1; + else if (t->data[t->rindex] == TAG_BOOLEAN_FALSE) + *b = 0; + else + return -1; + + t->rindex +=1; + return 0; +} + + diff --git a/polyp/tagstruct.h b/polyp/tagstruct.h index bcd7f456..9a91ee96 100644 --- a/polyp/tagstruct.h +++ b/polyp/tagstruct.h @@ -38,12 +38,14 @@ void pa_tagstruct_putu32(struct pa_tagstruct*t, uint32_t i); void pa_tagstruct_putu8(struct pa_tagstruct*t, uint8_t c); void pa_tagstruct_put_sample_spec(struct pa_tagstruct *t, const struct pa_sample_spec *ss); void pa_tagstruct_put_arbitrary(struct pa_tagstruct*t, const void *p, size_t length); +void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b); int pa_tagstruct_gets(struct pa_tagstruct*t, const char **s); int pa_tagstruct_getu32(struct pa_tagstruct*t, uint32_t *i); int pa_tagstruct_getu8(struct pa_tagstruct*t, uint8_t *c); int pa_tagstruct_get_sample_spec(struct pa_tagstruct *t, struct pa_sample_spec *ss); int pa_tagstruct_get_arbitrary(struct pa_tagstruct *t, const void **p, size_t length); +int pa_tagstruct_get_boolean(struct pa_tagstruct *t, int *b); int pa_tagstruct_eof(struct pa_tagstruct*t); const uint8_t* pa_tagstruct_data(struct pa_tagstruct*t, size_t *l); -- cgit