From 78a3cd61b8bbce4ae70ec21dd675005019034039 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 7 Mar 2017 17:23:35 +0100 Subject: [PATCH] pod-builder: make more generic builder Make a vararg based builder that produces much smaller code. Catch demarshal errors. Simplify array handling --- pinos/client/context.c | 7 +- pinos/client/protocol-native.c | 569 ++++++++++++---------- pinos/client/protocol-native.h | 2 +- pinos/modules/module-protocol-native.c | 7 +- pinos/server/protocol-native.c | 639 ++++++++++++++----------- pinos/server/protocol-native.h | 2 +- spa/include/spa/pod-builder.h | 159 ++++-- spa/include/spa/pod.h | 65 +-- spa/tests/test-props.c | 49 +- 9 files changed, 862 insertions(+), 637 deletions(-) diff --git a/pinos/client/context.c b/pinos/client/context.c index c20f66860..f004c3c2d 100644 --- a/pinos/client/context.c +++ b/pinos/client/context.c @@ -402,9 +402,10 @@ on_context_data (SpaSource *source, pinos_log_debug ("context %p: object demarshal %u, %u", this, id, opcode); demarshal = proxy->demarshal; - if (demarshal[opcode]) - demarshal[opcode] (proxy, message, size); - else + if (demarshal[opcode]) { + if (!demarshal[opcode] (proxy, message, size)) + pinos_log_error ("context %p: invalid message received", this); + } else pinos_log_error ("context %p: function %d not implemented", this, opcode); } diff --git a/pinos/client/protocol-native.c b/pinos/client/protocol-native.c index cdc8ae4c8..fe335a22a 100644 --- a/pinos/client/protocol-native.c +++ b/pinos/client/protocol-native.c @@ -47,7 +47,7 @@ write_pod (SpaPODBuilder *b, uint32_t ref, const void *data, uint32_t size) static void core_marshal_client_update (void *object, - const SpaDict *props) + const SpaDict *props) { PinosProxy *proxy = object; PinosConnection *connection = proxy->context->protocol_private; @@ -55,78 +55,93 @@ core_marshal_client_update (void *object, SpaPODFrame f; int i, n_items; - spa_pod_builder_push_struct (&b.b, &f); n_items = props ? props->n_items : 0; - spa_pod_builder_int (&b.b, n_items); + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, n_items, 0); + for (i = 0; i < n_items; i++) { - spa_pod_builder_string (&b.b, props->items[i].key); - spa_pod_builder_string (&b.b, props->items[i].value); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRING, props->items[i].key, + SPA_POD_TYPE_STRING, props->items[i].value, + 0); } - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, proxy->id, 0, b.b.offset); } static void core_marshal_sync (void *object, - uint32_t seq) + uint32_t seq) { PinosProxy *proxy = object; PinosConnection *connection = proxy->context->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + -SPA_POD_TYPE_STRUCT, &f, + 0); pinos_connection_end_write (connection, proxy->id, 1, b.b.offset); } static void core_marshal_get_registry (void *object, - uint32_t seq, - uint32_t new_id) + uint32_t seq, + uint32_t new_id) { PinosProxy *proxy = object; PinosConnection *connection = proxy->context->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_int (&b.b, new_id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_INT, new_id, + -SPA_POD_TYPE_STRUCT, &f, + 0); pinos_connection_end_write (connection, proxy->id, 2, b.b.offset); } static void core_marshal_create_node (void *object, - uint32_t seq, - const char *factory_name, - const char *name, - const SpaDict *props, - uint32_t new_id) + uint32_t seq, + const char *factory_name, + const char *name, + const SpaDict *props, + uint32_t new_id) { PinosProxy *proxy = object; PinosConnection *connection = proxy->context->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - int i, n_items; + uint32_t i, n_items; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_string (&b.b, factory_name); - spa_pod_builder_string (&b.b, name); n_items = props ? props->n_items : 0; - spa_pod_builder_int (&b.b, n_items); + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_STRING, factory_name, + SPA_POD_TYPE_STRING, name, + SPA_POD_TYPE_INT, n_items, 0); + for (i = 0; i < n_items; i++) { - spa_pod_builder_string (&b.b, props->items[i].key); - spa_pod_builder_string (&b.b, props->items[i].value); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRING, props->items[i].key, + SPA_POD_TYPE_STRING, props->items[i].value, + 0); } - spa_pod_builder_int (&b.b, new_id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_INT, new_id, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, proxy->id, 3, b.b.offset); } @@ -142,24 +157,30 @@ core_marshal_create_client_node (void *object, PinosConnection *connection = proxy->context->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - int i, n_items; + uint32_t i, n_items; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_string (&b.b, name); n_items = props ? props->n_items : 0; - spa_pod_builder_int (&b.b, n_items); + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_STRING, name, + SPA_POD_TYPE_INT, n_items, 0); + for (i = 0; i < n_items; i++) { - spa_pod_builder_string (&b.b, props->items[i].key); - spa_pod_builder_string (&b.b, props->items[i].value); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRING, props->items[i].key, + SPA_POD_TYPE_STRING, props->items[i].value, + 0); } - spa_pod_builder_int (&b.b, new_id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_INT, new_id, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, proxy->id, 4, b.b.offset); } -static void +static bool core_demarshal_info (void *object, void *data, size_t size) @@ -181,7 +202,7 @@ core_demarshal_info (void *object, SPA_POD_TYPE_INT, &info.cookie, SPA_POD_TYPE_INT, &props.n_items, 0)) - return; + return false; info.props = &props; props.items = alloca (props.n_items * sizeof (SpaDictItem)); @@ -190,12 +211,13 @@ core_demarshal_info (void *object, SPA_POD_TYPE_STRING, &props.items[i].key, SPA_POD_TYPE_STRING, &props.items[i].value, 0)) - return; + return false; } pinos_core_notify_info (proxy, &info); + return true; } -static void +static bool core_demarshal_done (void *object, void *data, size_t size) @@ -208,12 +230,13 @@ core_demarshal_done (void *object, !spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &seq, 0)) - return; + return false; pinos_core_notify_done (proxy, seq); + return true; } -static void +static bool core_demarshal_error (void *object, void *data, size_t size) @@ -229,12 +252,13 @@ core_demarshal_error (void *object, SPA_POD_TYPE_INT, &res, SPA_POD_TYPE_STRING, &error, 0)) - return; + return false; pinos_core_notify_error (proxy, id, res, error); + return true; } -static void +static bool core_demarshal_remove_id (void *object, void *data, size_t size) @@ -247,12 +271,13 @@ core_demarshal_remove_id (void *object, !spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &id, 0)) - return; + return false; pinos_core_notify_remove_id (proxy, id); + return true; } -static void +static bool module_demarshal_info (void *object, void *data, size_t size) @@ -272,7 +297,7 @@ module_demarshal_info (void *object, SPA_POD_TYPE_STRING, &info.args, SPA_POD_TYPE_INT, &props.n_items, 0)) - return; + return false; info.props = &props; props.items = alloca (props.n_items * sizeof (SpaDictItem)); @@ -281,12 +306,13 @@ module_demarshal_info (void *object, SPA_POD_TYPE_STRING, &props.items[i].key, SPA_POD_TYPE_STRING, &props.items[i].value, 0)) - return; + return false; } pinos_module_notify_info (proxy, &info); + return true; } -static void +static bool node_demarshal_done (void *object, void *data, size_t size) @@ -299,12 +325,13 @@ node_demarshal_done (void *object, !spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &seq, 0)) - return; + return false; pinos_node_notify_done (proxy, seq); + return true; } -static void +static bool node_demarshal_info (void *object, void *data, size_t size) @@ -324,30 +351,31 @@ node_demarshal_info (void *object, SPA_POD_TYPE_INT, &info.n_inputs, SPA_POD_TYPE_INT, &info.n_input_formats, 0)) - return; + return false; info.input_formats = alloca (info.n_input_formats * sizeof (SpaFormat*)); for (i = 0; i < info.n_input_formats; i++) - spa_pod_iter_get (&it, - SPA_POD_TYPE_OBJECT, &info.input_formats[i], 0); + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &info.input_formats[i], 0)) + return false; if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &info.max_outputs, SPA_POD_TYPE_INT, &info.n_outputs, SPA_POD_TYPE_INT, &info.n_output_formats, 0)) - return; + return false; info.output_formats = alloca (info.n_output_formats * sizeof (SpaFormat*)); for (i = 0; i < info.n_output_formats; i++) - spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &info.output_formats[i], 0); + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &info.output_formats[i], 0)) + return false; if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &info.state, SPA_POD_TYPE_STRING, &info.error, SPA_POD_TYPE_INT, &props.n_items, 0)) - return; + return false; info.props = &props; props.items = alloca (props.n_items * sizeof (SpaDictItem)); @@ -356,9 +384,10 @@ node_demarshal_info (void *object, SPA_POD_TYPE_STRING, &props.items[i].key, SPA_POD_TYPE_STRING, &props.items[i].value, 0)) - return; + return false; } pinos_node_notify_info (proxy, &info); + return true; } static void @@ -373,14 +402,17 @@ client_node_marshal_update (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, change_mask); - spa_pod_builder_int (&b.b, max_input_ports); - spa_pod_builder_int (&b.b, max_output_ports); - spa_pod_builder_int (&b.b, props ? 1 : 0); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, change_mask, + SPA_POD_TYPE_INT, max_input_ports, + SPA_POD_TYPE_INT, max_output_ports, + SPA_POD_TYPE_INT, props ? 1 : 0, + 0); + if (props) - spa_pod_builder_raw (&b.b, props, SPA_POD_SIZE (props), true); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, props, 0); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, proxy->id, 0, b.b.offset); } @@ -402,37 +434,46 @@ client_node_marshal_port_update (void *object, SpaPODFrame f; int i, n_items; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, direction); - spa_pod_builder_int (&b.b, port_id); - spa_pod_builder_int (&b.b, change_mask); - spa_pod_builder_int (&b.b, n_possible_formats); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, direction, + SPA_POD_TYPE_INT, port_id, + SPA_POD_TYPE_INT, change_mask, + SPA_POD_TYPE_INT, n_possible_formats, + 0); + for (i = 0; i < n_possible_formats; i++) - spa_pod_builder_raw (&b.b, possible_formats[i], SPA_POD_SIZE (possible_formats[i]), true); - spa_pod_builder_int (&b.b, format ? 1 : 0); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, possible_formats[i], 0); + + spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, format ? 1 : 0, 0); if (format) - spa_pod_builder_raw (&b.b, format, SPA_POD_SIZE (format), true); - spa_pod_builder_int (&b.b, props ? 1 : 0); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, format, 0); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, props ? 1 : 0, 0); if (props) - spa_pod_builder_raw (&b.b, props, SPA_POD_SIZE (props), true); - spa_pod_builder_int (&b.b, info ? 1 : 0); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, props, 0); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, info ? 1 : 0, 0); if (info) { - spa_pod_builder_int (&b.b, info->flags); - spa_pod_builder_long (&b.b, info->maxbuffering); - spa_pod_builder_long (&b.b, info->latency); - spa_pod_builder_int (&b.b, info->n_params); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_INT, info->flags, + SPA_POD_TYPE_LONG, info->maxbuffering, + SPA_POD_TYPE_LONG, info->latency, + SPA_POD_TYPE_INT, info->n_params, + 0); + for (i = 0; i < info->n_params; i++) { SpaAllocParam *p = info->params[i]; - spa_pod_builder_bytes (&b.b, p, p->size); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_BYTES, p, p->size, 0); } n_items = info->extra ? info->extra->n_items : 0; - spa_pod_builder_int (&b.b, n_items); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, n_items, 0); for (i = 0; i < n_items; i++) { - spa_pod_builder_string (&b.b, info->extra->items[i].key); - spa_pod_builder_string (&b.b, info->extra->items[i].value); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRING, info->extra->items[i].key, + SPA_POD_TYPE_STRING, info->extra->items[i].value, + 0); } } - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, proxy->id, 1, b.b.offset); } @@ -446,9 +487,11 @@ client_node_marshal_state_change (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, state); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, state, + -SPA_POD_TYPE_STRUCT, &f, + 0); pinos_connection_end_write (connection, proxy->id, 2, b.b.offset); } @@ -462,9 +505,11 @@ client_node_marshal_event (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_bytes (&b.b, event, event->size); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_BYTES, event, event->size, + -SPA_POD_TYPE_STRUCT, &f, + 0); pinos_connection_end_write (connection, proxy->id, 3, b.b.offset); } @@ -478,14 +523,16 @@ client_node_marshal_destroy (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + -SPA_POD_TYPE_STRUCT, &f, + 0); pinos_connection_end_write (connection, proxy->id, 4, b.b.offset); } -static void +static bool client_node_demarshal_done (void *object, void *data, size_t size) @@ -501,13 +548,14 @@ client_node_demarshal_done (void *object, SPA_POD_TYPE_INT, &seq, SPA_POD_TYPE_INT, &idx, 0)) - return; + return false; fd = pinos_connection_get_fd (connection, idx); pinos_client_node_notify_done (proxy, seq, fd); + return true; } -static void +static bool client_node_demarshal_event (void *object, void *data, size_t size) @@ -521,12 +569,13 @@ client_node_demarshal_event (void *object, !spa_pod_iter_get (&it, SPA_POD_TYPE_BYTES, &event, &s, 0)) - return; + return false; pinos_client_node_notify_event (proxy, event); + return true; } -static void +static bool client_node_demarshal_add_port (void *object, void *data, size_t size) @@ -541,15 +590,16 @@ client_node_demarshal_add_port (void *object, SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, 0)) - return; + return false; pinos_client_node_notify_add_port (proxy, seq, direction, port_id); + return true; } -static void +static bool client_node_demarshal_remove_port (void *object, - void *data, - size_t size) + void *data, + size_t size) { PinosProxy *proxy = object; SpaPODIter it; @@ -561,15 +611,16 @@ client_node_demarshal_remove_port (void *object, SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, 0)) - return; + return false; pinos_client_node_notify_remove_port (proxy, seq, direction, port_id); + return true; } -static void +static bool client_node_demarshal_set_format (void *object, - void *data, - size_t size) + void *data, + size_t size) { PinosProxy *proxy = object; SpaPODIter it; @@ -584,16 +635,17 @@ client_node_demarshal_set_format (void *object, SPA_POD_TYPE_INT, &flags, SPA_POD_TYPE_INT, &have_format, 0)) - return; + return false; if (have_format && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &format, 0)) - return; + return false; pinos_client_node_notify_set_format (proxy, seq, direction, port_id, flags, format); + return true; } -static void +static bool client_node_demarshal_set_property (void *object, void *data, size_t size) @@ -610,12 +662,13 @@ client_node_demarshal_set_property (void *object, SPA_POD_TYPE_INT, &id, SPA_POD_TYPE_BYTES, &value, &s, 0)) - return; + return false; pinos_client_node_notify_set_property (proxy, seq, id, s, value); + return true; } -static void +static bool client_node_demarshal_add_mem (void *object, void *data, size_t size) @@ -637,7 +690,7 @@ client_node_demarshal_add_mem (void *object, SPA_POD_TYPE_INT, &offset, SPA_POD_TYPE_INT, &sz, 0)) - return; + return false; memfd = pinos_connection_get_fd (connection, memfd_idx); @@ -650,12 +703,13 @@ client_node_demarshal_add_mem (void *object, flags, offset, sz); + return true; } -static void +static bool client_node_demarshal_use_buffers (void *object, - void *data, - size_t size) + void *data, + size_t size) { PinosProxy *proxy = object; SpaPODIter it; @@ -670,7 +724,7 @@ client_node_demarshal_use_buffers (void *object, SPA_POD_TYPE_INT, &port_id, SPA_POD_TYPE_INT, &n_buffers, 0)) - return; + return false; buffers = alloca (sizeof (PinosClientNodeBuffer) * n_buffers); for (i = 0; i < n_buffers; i++) { @@ -682,7 +736,7 @@ client_node_demarshal_use_buffers (void *object, SPA_POD_TYPE_INT, &buffers[i].size, SPA_POD_TYPE_INT, &buf->id, SPA_POD_TYPE_INT, &buf->n_metas, 0)) - return; + return false; buf->metas = alloca (sizeof (SpaMeta) * buf->n_metas); for (j = 0; j < buf->n_metas; j++) { @@ -691,12 +745,12 @@ client_node_demarshal_use_buffers (void *object, if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &m->type, SPA_POD_TYPE_INT, &size, 0)) - return; + return false; m->size = size; } if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &buf->n_datas, 0)) - return; + return false; buf->datas = alloca (sizeof (SpaData) * buf->n_datas); for (j = 0; j < buf->n_datas; j++) { @@ -709,7 +763,7 @@ client_node_demarshal_use_buffers (void *object, SPA_POD_TYPE_INT, &d->mapoffset, SPA_POD_TYPE_INT, &d->maxsize, 0)) - return; + return false; d->data = SPA_UINT32_TO_PTR (data_id); } @@ -720,153 +774,169 @@ client_node_demarshal_use_buffers (void *object, port_id, n_buffers, buffers); + return true; } -static void +static bool client_node_demarshal_node_command (void *object, - void *data, - size_t size) + void *data, + size_t size) { PinosProxy *proxy = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); + SpaPODIter it; const SpaNodeCommand *command; - int32_t i1; - uint32_t s; + uint32_t seq, s; - if (!spa_pod_get_int (&p, &i1) || - !spa_pod_get_bytes (&p, (const void**)&command, &s)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &seq, + SPA_POD_TYPE_BYTES, &command, &s, + 0)) + return false; - pinos_client_node_notify_node_command (proxy, i1, command); + pinos_client_node_notify_node_command (proxy, seq, command); + return true; } -static void +static bool client_node_demarshal_port_command (void *object, void *data, size_t size) { PinosProxy *proxy = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); + SpaPODIter it; const SpaNodeCommand *command; - int32_t i1; - uint32_t s; + uint32_t port_id, s; - if (!spa_pod_get_int (&p, &i1) || - !spa_pod_get_bytes (&p, (const void**)&command, &s)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &port_id, + SPA_POD_TYPE_BYTES, &command, &s, + 0)) + return false; - pinos_client_node_notify_port_command (proxy, i1, command); + pinos_client_node_notify_port_command (proxy, port_id, command); + return true; } -static void +static bool client_node_demarshal_transport (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - PinosConnection *connection = proxy->context->protocol_private; - int32_t memfd, offset, sz; - - if (!spa_pod_get_int (&p, &memfd) || - !spa_pod_get_int (&p, &offset) || - !spa_pod_get_int (&p, &sz)) - return; - - memfd = pinos_connection_get_fd (connection, memfd); - pinos_client_node_notify_transport (proxy, memfd, offset, sz); -} - -static void -client_demarshal_info (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - SpaDict props; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - PinosClientInfo info; - int32_t i1, i2; - int64_t l1; - int i; - - if (!spa_pod_get_int (&p, &i1) || - !spa_pod_get_long (&p, &l1) || - !spa_pod_get_int (&p, &i2)) - return; - - info.id = i1; - info.change_mask = l1; - info.props = &props; - props.n_items = i2; - props.items = alloca (props.n_items * sizeof (SpaDictItem)); - for (i = 0; i < props.n_items; i++) { - if (!spa_pod_get_string (&p, &props.items[i].key) || - !spa_pod_get_string (&p, &props.items[i].value)) - return; - } - pinos_client_notify_info (proxy, &info); -} - -static void -link_demarshal_info (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - PinosLinkInfo info; - int32_t i1, i2, i3, i4, i5; - int64_t l1; - - if (!spa_pod_get_int (&p, &i1) || - !spa_pod_get_long (&p, &l1) || - !spa_pod_get_int (&p, &i2) || - !spa_pod_get_int (&p, &i3) || - !spa_pod_get_int (&p, &i4) || - !spa_pod_get_int (&p, &i5)) - return; - - info.id = i1; - info.change_mask = l1; - info.output_node_id = i2; - info.output_port_id = i3; - info.input_node_id = i4; - info.input_port_id = i5; - - pinos_link_notify_info (proxy, &info); -} - -static void -registry_demarshal_global (void *object, - void *data, - size_t size) -{ - PinosProxy *proxy = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t i1; - const char *type; - - if (!spa_pod_get_int (&p, &i1) || - !spa_pod_get_string (&p, &type)) - return; - - pinos_registry_notify_global (proxy, i1, type); -} - -static void -registry_demarshal_global_remove (void *object, void *data, size_t size) { PinosProxy *proxy = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t i1; + SpaPODIter it; + PinosConnection *connection = proxy->context->protocol_private; + uint32_t memfd_idx, offset, sz; + int memfd; - if (!spa_pod_get_int (&p, &i1)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &memfd_idx, + SPA_POD_TYPE_INT, &offset, + SPA_POD_TYPE_INT, &sz, + 0)) + return false; - pinos_registry_notify_global_remove (proxy, i1); + memfd = pinos_connection_get_fd (connection, memfd_idx); + pinos_client_node_notify_transport (proxy, memfd, offset, sz); + return true; +} + +static bool +client_demarshal_info (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + SpaPODIter it; + SpaDict props; + PinosClientInfo info; + uint32_t i; + + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &info.id, + SPA_POD_TYPE_LONG, &info.change_mask, + SPA_POD_TYPE_INT, &props.n_items, + 0)) + return false; + + info.props = &props; + props.items = alloca (props.n_items * sizeof (SpaDictItem)); + for (i = 0; i < props.n_items; i++) { + if (!spa_pod_iter_get (&it, + SPA_POD_TYPE_STRING, &props.items[i].key, + SPA_POD_TYPE_STRING, &props.items[i].value, + 0)) + return false; + } + pinos_client_notify_info (proxy, &info); + return true; +} + +static bool +link_demarshal_info (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + SpaPODIter it; + PinosLinkInfo info; + + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &info.id, + SPA_POD_TYPE_LONG, &info.change_mask, + SPA_POD_TYPE_INT, &info.output_node_id, + SPA_POD_TYPE_INT, &info.output_port_id, + SPA_POD_TYPE_INT, &info.input_node_id, + SPA_POD_TYPE_INT, &info.input_port_id, + 0)) + return false; + + pinos_link_notify_info (proxy, &info); + return true; +} + +static bool +registry_demarshal_global (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + SpaPODIter it; + uint32_t id; + const char *type; + + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &id, + SPA_POD_TYPE_STRING, &type, + 0)) + return false; + + pinos_registry_notify_global (proxy, id, type); + return true; +} + +static bool +registry_demarshal_global_remove (void *object, + void *data, + size_t size) +{ + PinosProxy *proxy = object; + SpaPODIter it; + uint32_t id; + + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &id, + 0)) + return false; + + pinos_registry_notify_global_remove (proxy, id); + return true; } static void @@ -879,10 +949,11 @@ registry_marshal_bind (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, id); - spa_pod_builder_int (&b.b, new_id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, id, + SPA_POD_TYPE_INT, new_id, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, proxy->id, 0, b.b.offset); } diff --git a/pinos/client/protocol-native.h b/pinos/client/protocol-native.h index a5120593c..e153b0603 100644 --- a/pinos/client/protocol-native.h +++ b/pinos/client/protocol-native.h @@ -20,7 +20,7 @@ #include "pinos/client/pinos.h" #include "pinos/client/interfaces.h" -typedef void (*PinosDemarshalFunc) (void *object, void *data, size_t size); +typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); extern const PinosCoreInterface pinos_protocol_native_client_core_interface; extern const PinosRegistryInterface pinos_protocol_native_client_registry_interface; diff --git a/pinos/modules/module-protocol-native.c b/pinos/modules/module-protocol-native.c index aa1c320f0..e3928821c 100644 --- a/pinos/modules/module-protocol-native.c +++ b/pinos/modules/module-protocol-native.c @@ -163,9 +163,10 @@ connection_data (SpaSource *source, continue; } demarshal = resource->demarshal; - if (demarshal[opcode]) - demarshal[opcode] (resource, message, size); - else + if (demarshal[opcode]) { + if (!demarshal[opcode] (resource, message, size)) + pinos_log_error ("protocol-native %p: invalid message received", client->impl); + } else pinos_log_error ("protocol-native %p: function %d not implemented", client->impl, opcode); } } diff --git a/pinos/server/protocol-native.c b/pinos/server/protocol-native.c index 239d926b4..64bef14a2 100644 --- a/pinos/server/protocol-native.c +++ b/pinos/server/protocol-native.c @@ -17,6 +17,9 @@ * Boston, MA 02110-1301, USA. */ + +#include "spa/pod-iter.h" + #include "pinos/client/interfaces.h" #include "pinos/server/resource.h" #include "pinos/server/protocol-native.h" @@ -49,23 +52,28 @@ core_marshal_info (void *object, PinosConnection *connection = resource->client->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - int i, n_items; + uint32_t i, n_items; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, info->id); - spa_pod_builder_long (&b.b, info->change_mask); - spa_pod_builder_string (&b.b, info->user_name); - spa_pod_builder_string (&b.b, info->host_name); - spa_pod_builder_string (&b.b, info->version); - spa_pod_builder_string (&b.b, info->name); - spa_pod_builder_int (&b.b, info->cookie); n_items = info->props ? info->props->n_items : 0; - spa_pod_builder_int (&b.b, n_items); + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, info->id, + SPA_POD_TYPE_LONG, info->change_mask, + SPA_POD_TYPE_STRING, info->user_name, + SPA_POD_TYPE_STRING, info->host_name, + SPA_POD_TYPE_STRING, info->version, + SPA_POD_TYPE_STRING, info->name, + SPA_POD_TYPE_INT, info->cookie, + SPA_POD_TYPE_INT, n_items, 0); + for (i = 0; i < n_items; i++) { - spa_pod_builder_string (&b.b, info->props->items[i].key); - spa_pod_builder_string (&b.b, info->props->items[i].value); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRING, info->props->items[i].key, + SPA_POD_TYPE_STRING, info->props->items[i].value, + 0); } - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } @@ -79,9 +87,10 @@ core_marshal_done (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 1, b.b.offset); } @@ -104,11 +113,12 @@ core_marshal_error (void *object, vsnprintf (buffer, sizeof (buffer), error, ap); va_end (ap); - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, id); - spa_pod_builder_int (&b.b, res); - spa_pod_builder_string (&b.b, buffer); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, id, + SPA_POD_TYPE_INT, res, + SPA_POD_TYPE_STRING, buffer, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 2, b.b.offset); } @@ -122,95 +132,111 @@ core_marshal_remove_id (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, id, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 3, b.b.offset); } -static void +static bool core_demarshal_client_update (void *object, - void *data, - size_t size) + void *data, + size_t size) { PinosResource *resource = object; SpaDict props; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t i32; - int i; + SpaPODIter it; + uint32_t i; + + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &props.n_items, + 0)) + return false; - if (!spa_pod_get_int (&p, &i32)) - return; - props.n_items = i32; props.items = alloca (props.n_items * sizeof (SpaDictItem)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_get_string (&p, &props.items[i].key) || - !spa_pod_get_string (&p, &props.items[i].value)) - return; + if (!spa_pod_iter_get (&it, + SPA_POD_TYPE_STRING, &props.items[i].key, + SPA_POD_TYPE_STRING, &props.items[i].value, + 0)) + return false; } - pinos_core_do_client_update (resource, &props); + return true; } -static void +static bool core_demarshal_sync (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t seq; + SpaPODIter it; + uint32_t seq; - if (!spa_pod_get_int (&p, &seq)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &seq, + 0)) + return false; pinos_core_do_sync (resource, seq); + return true; } -static void +static bool core_demarshal_get_registry (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); + SpaPODIter it; int32_t seq, new_id; - if (!spa_pod_get_int (&p, &seq) || - !spa_pod_get_int (&p, &new_id)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &seq, + SPA_POD_TYPE_INT, &new_id, + 0)) + return false; pinos_core_do_get_registry (resource, seq, new_id); + return true; } -static void +static bool core_demarshal_create_node (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t seq, new_id, i32; + SpaPODIter it; + uint32_t seq, new_id, i; const char *factory_name, *name; - int i; SpaDict props; - if (!spa_pod_get_int (&p, &seq) || - !spa_pod_get_string (&p, &factory_name) || - !spa_pod_get_string (&p, &name) || - !spa_pod_get_int (&p, &i32)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &seq, + SPA_POD_TYPE_STRING, &factory_name, + SPA_POD_TYPE_STRING, &name, + SPA_POD_TYPE_INT, &props.n_items, + 0)) + return false; - props.n_items = i32; props.items = alloca (props.n_items * sizeof (SpaDictItem)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_get_string (&p, &props.items[i].key) || - !spa_pod_get_string (&p, &props.items[i].value)) - return; + if (!spa_pod_iter_get (&it, + SPA_POD_TYPE_STRING, &props.items[i].key, + SPA_POD_TYPE_STRING, &props.items[i].value, + 0)) + return false; } - if (!spa_pod_get_int (&p, &new_id)) - return; + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &new_id, 0)) + return false; pinos_core_do_create_node (resource, seq, @@ -218,40 +244,45 @@ core_demarshal_create_node (void *object, name, &props, new_id); + return true; } -static void +static bool core_demarshal_create_client_node (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t seq, new_id, i32; + SpaPODIter it; + uint32_t seq, new_id, i; const char *name; - int i; SpaDict props; - if (!spa_pod_get_int (&p, &seq) || - !spa_pod_get_string (&p, &name) || - !spa_pod_get_int (&p, &i32)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &seq, + SPA_POD_TYPE_STRING, &name, + SPA_POD_TYPE_INT, &props.n_items, + 0)) + return false; - props.n_items = i32; props.items = alloca (props.n_items * sizeof (SpaDictItem)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_get_string (&p, &props.items[i].key) || - !spa_pod_get_string (&p, &props.items[i].value)) - return; + if (!spa_pod_iter_get (&it, + SPA_POD_TYPE_STRING, &props.items[i].key, + SPA_POD_TYPE_STRING, &props.items[i].value, + 0)) + return false; } - if (!spa_pod_get_int (&p, &new_id)) - return; + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &new_id, 0)) + return false; pinos_core_do_create_client_node (resource, seq, name, &props, new_id); + return true; } static void @@ -264,10 +295,11 @@ registry_marshal_global (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, id); - spa_pod_builder_string (&b.b, type); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, id, + SPA_POD_TYPE_STRING, type, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } @@ -281,27 +313,32 @@ registry_marshal_global_remove (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, id, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 1, b.b.offset); } -static void +static bool registry_demarshal_bind (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t i1, i2; + SpaPODIter it; + uint32_t id, new_id; - if (!spa_pod_get_int (&p, &i1) || - !spa_pod_get_int (&p, &i2)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &id, + SPA_POD_TYPE_INT, &new_id, + 0)) + return false; - pinos_registry_do_bind (resource, i1, i2); + pinos_registry_do_bind (resource, id, new_id); + return true; } static void @@ -312,21 +349,26 @@ module_marshal_info (void *object, PinosConnection *connection = resource->client->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - int i, n_items; + uint32_t i, n_items; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, info->id); - spa_pod_builder_long (&b.b, info->change_mask); - spa_pod_builder_string (&b.b, info->name); - spa_pod_builder_string (&b.b, info->filename); - spa_pod_builder_string (&b.b, info->args); n_items = info->props ? info->props->n_items : 0; - spa_pod_builder_int (&b.b, n_items); + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, info->id, + SPA_POD_TYPE_LONG, info->change_mask, + SPA_POD_TYPE_STRING, info->name, + SPA_POD_TYPE_STRING, info->filename, + SPA_POD_TYPE_STRING, info->args, + SPA_POD_TYPE_INT, n_items, 0); + for (i = 0; i < n_items; i++) { - spa_pod_builder_string (&b.b, info->props->items[i].key); - spa_pod_builder_string (&b.b, info->props->items[i].value); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRING, info->props->items[i].key, + SPA_POD_TYPE_STRING, info->props->items[i].value, + 0); } - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } @@ -340,9 +382,10 @@ node_marshal_done (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } @@ -355,31 +398,41 @@ node_marshal_info (void *object, PinosConnection *connection = resource->client->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - int i, n_items; + uint32_t i, n_items; + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, info->id, + SPA_POD_TYPE_LONG, info->change_mask, + SPA_POD_TYPE_STRING, info->name, + SPA_POD_TYPE_INT, info->max_inputs, + SPA_POD_TYPE_INT, info->n_inputs, + SPA_POD_TYPE_INT, info->n_input_formats, 0); - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, info->id); - spa_pod_builder_long (&b.b, info->change_mask); - spa_pod_builder_string (&b.b, info->name); - spa_pod_builder_int (&b.b, info->max_inputs); - spa_pod_builder_int (&b.b, info->n_inputs); - spa_pod_builder_int (&b.b, info->n_input_formats); for (i = 0; i < info->n_input_formats; i++) - spa_pod_builder_raw (&b.b, info->input_formats[i], SPA_POD_SIZE (info->input_formats[i]), true); - spa_pod_builder_int (&b.b, info->max_outputs); - spa_pod_builder_int (&b.b, info->n_outputs); - spa_pod_builder_int (&b.b, info->n_output_formats); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, info->input_formats[i], 0); + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_INT, info->max_outputs, + SPA_POD_TYPE_INT, info->n_outputs, + SPA_POD_TYPE_INT, info->n_output_formats, 0); + for (i = 0; i < info->n_output_formats; i++) - spa_pod_builder_raw (&b.b, info->output_formats[i], SPA_POD_SIZE (info->output_formats[i]), true); - spa_pod_builder_int (&b.b, info->state); - spa_pod_builder_string (&b.b, info->error); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, info->output_formats[i], 0); + n_items = info->props ? info->props->n_items : 0; - spa_pod_builder_int (&b.b, n_items); + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_INT, info->state, + SPA_POD_TYPE_STRING, info->error, + SPA_POD_TYPE_INT, n_items, 0); + for (i = 0; i < n_items; i++) { - spa_pod_builder_string (&b.b, info->props->items[i].key); - spa_pod_builder_string (&b.b, info->props->items[i].value); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRING, info->props->items[i].key, + SPA_POD_TYPE_STRING, info->props->items[i].value, 0); } - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 1, b.b.offset); } @@ -392,18 +445,22 @@ client_marshal_info (void *object, PinosConnection *connection = resource->client->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - int i, n_items; + uint32_t i, n_items; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, info->id); - spa_pod_builder_long (&b.b, info->change_mask); n_items = info->props ? info->props->n_items : 0; - spa_pod_builder_int (&b.b, n_items); + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, info->id, + SPA_POD_TYPE_LONG, info->change_mask, + SPA_POD_TYPE_INT, n_items, 0); + for (i = 0; i < n_items; i++) { - spa_pod_builder_string (&b.b, info->props->items[i].key); - spa_pod_builder_string (&b.b, info->props->items[i].value); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRING, info->props->items[i].key, + SPA_POD_TYPE_STRING, info->props->items[i].value, 0); } - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } @@ -418,10 +475,11 @@ client_node_marshal_done (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_int (&b.b, pinos_connection_add_fd (connection, datafd)); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_INT, pinos_connection_add_fd (connection, datafd), + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } @@ -435,9 +493,10 @@ client_node_marshal_event (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_bytes (&b.b, event, event->size); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_BYTES, event, event->size, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 1, b.b.offset); } @@ -453,11 +512,12 @@ client_node_marshal_add_port (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_int (&b.b, direction); - spa_pod_builder_int (&b.b, port_id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_INT, direction, + SPA_POD_TYPE_INT, port_id, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 2, b.b.offset); } @@ -473,11 +533,12 @@ client_node_marshal_remove_port (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_int (&b.b, direction); - spa_pod_builder_int (&b.b, port_id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_INT, direction, + SPA_POD_TYPE_INT, port_id, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 3, b.b.offset); } @@ -495,15 +556,16 @@ client_node_marshal_set_format (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_int (&b.b, direction); - spa_pod_builder_int (&b.b, port_id); - spa_pod_builder_int (&b.b, flags); - spa_pod_builder_int (&b.b, format ? 1 : 0); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_INT, direction, + SPA_POD_TYPE_INT, port_id, + SPA_POD_TYPE_INT, flags, + SPA_POD_TYPE_INT, format ? 1 : 0, 0); if (format) - spa_pod_builder_raw (&b.b, format, SPA_POD_SIZE (format), true); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, format, 0); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 4, b.b.offset); } @@ -520,11 +582,12 @@ client_node_marshal_set_property (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_int (&b.b, id); - spa_pod_builder_bytes (&b.b, value, size); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_INT, id, + SPA_POD_TYPE_BYTES, value, size, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 5, b.b.offset); } @@ -545,16 +608,17 @@ client_node_marshal_add_mem (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, direction); - spa_pod_builder_int (&b.b, port_id); - spa_pod_builder_int (&b.b, mem_id); - spa_pod_builder_int (&b.b, type); - spa_pod_builder_int (&b.b, pinos_connection_add_fd (connection, memfd)); - spa_pod_builder_int (&b.b, flags); - spa_pod_builder_int (&b.b, offset); - spa_pod_builder_int (&b.b, size); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, direction, + SPA_POD_TYPE_INT, port_id, + SPA_POD_TYPE_INT, mem_id, + SPA_POD_TYPE_INT, type, + SPA_POD_TYPE_INT, pinos_connection_add_fd (connection, memfd), + SPA_POD_TYPE_INT, flags, + SPA_POD_TYPE_INT, offset, + SPA_POD_TYPE_INT, size, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 6, b.b.offset); } @@ -571,37 +635,43 @@ client_node_marshal_use_buffers (void *object, PinosConnection *connection = resource->client->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - int i, j; + uint32_t i, j; + + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_INT, direction, + SPA_POD_TYPE_INT, port_id, + SPA_POD_TYPE_INT, n_buffers, 0); - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_int (&b.b, direction); - spa_pod_builder_int (&b.b, port_id); - spa_pod_builder_int (&b.b, n_buffers); for (i = 0; i < n_buffers; i++) { SpaBuffer *buf = buffers[i].buffer; - spa_pod_builder_int (&b.b, buffers[i].mem_id); - spa_pod_builder_int (&b.b, buffers[i].offset); - spa_pod_builder_int (&b.b, buffers[i].size); - spa_pod_builder_int (&b.b, buf->id); - spa_pod_builder_int (&b.b, buf->n_metas); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_INT, buffers[i].mem_id, + SPA_POD_TYPE_INT, buffers[i].offset, + SPA_POD_TYPE_INT, buffers[i].size, + SPA_POD_TYPE_INT, buf->id, + SPA_POD_TYPE_INT, buf->n_metas, 0); + for (j = 0; j < buf->n_metas; j++) { SpaMeta *m = &buf->metas[j]; - spa_pod_builder_int (&b.b, m->type); - spa_pod_builder_int (&b.b, m->size); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_INT, m->type, + SPA_POD_TYPE_INT, m->size, 0); } - spa_pod_builder_int (&b.b, buf->n_datas); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, buf->n_datas, 0); for (j = 0; j < buf->n_datas; j++) { SpaData *d = &buf->datas[j]; - spa_pod_builder_int (&b.b, d->type); - spa_pod_builder_int (&b.b, SPA_PTR_TO_UINT32 (d->data)); - spa_pod_builder_int (&b.b, d->flags); - spa_pod_builder_int (&b.b, d->mapoffset); - spa_pod_builder_int (&b.b, d->maxsize); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_INT, d->type, + SPA_POD_TYPE_INT, SPA_PTR_TO_UINT32 (d->data), + SPA_POD_TYPE_INT, d->flags, + SPA_POD_TYPE_INT, d->mapoffset, + SPA_POD_TYPE_INT, d->maxsize, 0); } } - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 7, b.b.offset); } @@ -616,10 +686,11 @@ client_node_marshal_node_command (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, seq); - spa_pod_builder_bytes (&b.b, command, command->size); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_BYTES, command, command->size, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 8, b.b.offset); } @@ -634,10 +705,11 @@ client_node_marshal_port_command (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, port_id); - spa_pod_builder_bytes (&b.b, command, command->size); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, port_id, + SPA_POD_TYPE_BYTES, command, command->size, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 9, b.b.offset); } @@ -653,102 +725,107 @@ client_node_marshal_transport (void *object, Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, pinos_connection_add_fd (connection, memfd)); - spa_pod_builder_int (&b.b, offset); - spa_pod_builder_int (&b.b, size); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, pinos_connection_add_fd (connection, memfd), + SPA_POD_TYPE_INT, offset, + SPA_POD_TYPE_INT, size, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 10, b.b.offset); } -static void +static bool client_node_demarshal_update (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t i1, i2, i3, i4; - const SpaPOD *props = NULL; + SpaPODIter it; + uint32_t change_mask, max_input_ports, max_output_ports, have_props; + const SpaProps *props = NULL; - if (!spa_pod_get_int (&p, &i1) || - !spa_pod_get_int (&p, &i2) || - !spa_pod_get_int (&p, &i3) || - !spa_pod_get_int (&p, &i4)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &change_mask, + SPA_POD_TYPE_INT, &max_input_ports, + SPA_POD_TYPE_INT, &max_output_ports, + SPA_POD_TYPE_INT, &have_props, + 0)) + return false; - if (i4 && !spa_pod_get_object (&p, &props)) - return; + if (have_props && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &props, 0)) + return false; - pinos_client_node_do_update (resource, i1, i2, i3, (SpaProps *)props); + pinos_client_node_do_update (resource, change_mask, max_input_ports, max_output_ports, props); + return true; } -static void +static bool client_node_demarshal_port_update (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t i1, i2, direction, port_id, change_mask, n_possible_formats; - int64_t l1, l2; + SpaPODIter it; + uint32_t i, t, direction, port_id, change_mask, n_possible_formats, sz; const SpaProps *props = NULL; const SpaFormat **possible_formats = NULL, *format = NULL; SpaPortInfo info, *infop = NULL; - int i; - uint32_t sz; - if (!spa_pod_get_int (&p, &direction) || - !spa_pod_get_int (&p, &port_id) || - !spa_pod_get_int (&p, &change_mask) || - !spa_pod_get_int (&p, &n_possible_formats)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &direction, + SPA_POD_TYPE_INT, &port_id, + SPA_POD_TYPE_INT, &change_mask, + SPA_POD_TYPE_INT, &n_possible_formats, + 0)) + return false; possible_formats = alloca (n_possible_formats * sizeof (SpaFormat*)); for (i = 0; i < n_possible_formats; i++) - spa_pod_get_object (&p, (const SpaPOD**)&possible_formats[i]); + if (!spa_pod_iter_get (&it,SPA_POD_TYPE_OBJECT, &possible_formats[i], 0)) + return false; - if (!spa_pod_get_int (&p, &i1) || - (i1 && !spa_pod_get_object (&p, (const SpaPOD**)&format))) - return; + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &t, 0) || + (t && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &format, 0))) + return false; - if (!spa_pod_get_int (&p, &i1) || - (i1 && !spa_pod_get_object (&p, (const SpaPOD**)&props))) - return; + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &t, 0) || + (t && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &props, 0))) + return false; - if (!spa_pod_get_int (&p, &i1)) - return; + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &t, 0)) + return false; - if (i1) { + if (t) { SpaDict dict; infop = &info; - if (!spa_pod_get_int (&p, &i1) || - !spa_pod_get_long (&p, &l1) || - !spa_pod_get_long (&p, &l2) || - !spa_pod_get_int (&p, &i2)) - return; + if (!spa_pod_iter_get (&it, + SPA_POD_TYPE_INT, &info.flags, + SPA_POD_TYPE_LONG, &info.maxbuffering, + SPA_POD_TYPE_LONG, &info.latency, + SPA_POD_TYPE_INT, &info.n_params, + 0)) + return false; - info.flags = i1; - info.maxbuffering = l1; - info.latency = l2; - info.n_params = i2; info.params = alloca (info.n_params * sizeof (SpaAllocParam *)); - for (i = 0; i < info.n_params; i++) - spa_pod_get_bytes (&p, (const void **)&info.params[i], &sz); + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_BYTES, &info.params[i], &sz, 0)) + return false; - if (!spa_pod_get_int (&p, &i1)) - return; + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &dict.n_items, 0)) + return false; info.extra = &dict; - dict.n_items = i1; dict.items = alloca (dict.n_items * sizeof (SpaDictItem)); for (i = 0; i < dict.n_items; i++) { - if (!spa_pod_get_string (&p, &dict.items[i].key) || - !spa_pod_get_string (&p, &dict.items[i].value)) - return; + if (!spa_pod_iter_get (&it, + SPA_POD_TYPE_STRING, &dict.items[i].key, + SPA_POD_TYPE_STRING, &dict.items[i].value, + 0)) + return false; } } @@ -761,71 +838,79 @@ client_node_demarshal_port_update (void *object, format, props, infop); + return true; } -static void +static bool client_node_demarshal_state_change (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t state; + SpaPODIter it; + uint32_t state; - if (!spa_pod_get_int (&p, &state)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &state, 0)) + return false; pinos_client_node_do_state_change (resource, state); + return true; } -static void +static bool client_node_demarshal_event (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); + SpaPODIter it; SpaNodeEvent *event; uint32_t sz; - if (!spa_pod_get_bytes (&p, (const void **)&event, &sz)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, SPA_POD_TYPE_BYTES, &event, &sz, 0)) + return false; pinos_client_node_do_event (resource, event); + return true; } -static void +static bool client_node_demarshal_destroy (void *object, void *data, size_t size) { PinosResource *resource = object; - SpaPOD *p = SPA_POD_CONTENTS (SpaPODStruct, data); - int32_t seq; + SpaPODIter it; + uint32_t seq; - if (!spa_pod_get_int (&p, &seq)) - return; + if (!spa_pod_iter_struct (&it, data, size) || + !spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &seq, 0)) + return false; pinos_client_node_do_destroy (resource, seq); + return true; } static void link_marshal_info (void *object, - PinosLinkInfo *info) + PinosLinkInfo *info) { PinosResource *resource = object; PinosConnection *connection = resource->client->protocol_private; Builder b = { { NULL, 0, 0, NULL, write_pod }, connection }; SpaPODFrame f; - spa_pod_builder_push_struct (&b.b, &f); - spa_pod_builder_int (&b.b, info->id); - spa_pod_builder_long (&b.b, info->change_mask); - spa_pod_builder_int (&b.b, info->output_node_id); - spa_pod_builder_int (&b.b, info->output_port_id); - spa_pod_builder_int (&b.b, info->input_node_id); - spa_pod_builder_int (&b.b, info->input_port_id); - spa_pod_builder_pop (&b.b, &f); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_STRUCT, &f, + SPA_POD_TYPE_INT, info->id, + SPA_POD_TYPE_LONG, info->change_mask, + SPA_POD_TYPE_LONG, info->output_node_id, + SPA_POD_TYPE_LONG, info->output_port_id, + SPA_POD_TYPE_LONG, info->input_node_id, + SPA_POD_TYPE_LONG, info->input_port_id, + -SPA_POD_TYPE_STRUCT, &f, 0); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } diff --git a/pinos/server/protocol-native.h b/pinos/server/protocol-native.h index 77160741d..cff412cfe 100644 --- a/pinos/server/protocol-native.h +++ b/pinos/server/protocol-native.h @@ -19,7 +19,7 @@ #include "pinos/client/pinos.h" -typedef void (*PinosDemarshalFunc) (void *object, void *data, size_t size); +typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size); extern const PinosCoreEvent pinos_protocol_native_server_core_event; extern const PinosRegistryEvent pinos_protocol_native_server_registry_event; diff --git a/spa/include/spa/pod-builder.h b/spa/include/spa/pod-builder.h index b781ace57..142d7a65f 100644 --- a/spa/include/spa/pod-builder.h +++ b/spa/include/spa/pod-builder.h @@ -39,6 +39,8 @@ typedef struct _SpaPODBuilder { uint32_t offset; SpaPODFrame *stack; uint32_t (*write) (struct _SpaPODBuilder *builder, uint32_t ref, const void *data, uint32_t size); + bool in_array; + bool first; } SpaPODBuilder; #define SPA_POD_BUILDER_DEREF(b,ref,type) SPA_MEMBER ((b)->data, (ref), type) @@ -54,23 +56,6 @@ spa_pod_builder_init (SpaPODBuilder *builder, builder->stack = NULL; } -static inline bool -spa_pod_builder_in_array (SpaPODBuilder *builder, bool *first) -{ - SpaPODFrame *f; - if ((f = builder->stack)) { - if (f->pod.type == SPA_POD_TYPE_ARRAY) { - *first = f->pod.size == 0; - return true; - } - if (f->pod.type == SPA_POD_TYPE_PROP) { - *first = f->pod.size == (sizeof (SpaPODPropBody) - sizeof(SpaPOD)); - return true; - } - } - return false; -} - static inline uint32_t spa_pod_builder_push (SpaPODBuilder *builder, SpaPODFrame *frame, @@ -81,6 +66,8 @@ spa_pod_builder_push (SpaPODBuilder *builder, frame->pod = *pod; frame->ref = ref; builder->stack = frame; + builder->in_array = builder->first = (pod->type == SPA_POD_TYPE_ARRAY || + pod->type == SPA_POD_TYPE_PROP); return ref; } @@ -110,6 +97,8 @@ spa_pod_builder_pop (SpaPODBuilder *builder, memcpy (builder->data + frame->ref, &frame->pod, sizeof(SpaPOD)); } builder->stack = frame->parent; + builder->in_array = (builder->stack && (builder->stack->pod.type == SPA_POD_TYPE_ARRAY || + builder->stack->pod.type == SPA_POD_TYPE_PROP)); spa_pod_builder_advance (builder, SPA_ROUND_UP_N(builder->offset, 8) - builder->offset, false); } @@ -143,29 +132,21 @@ spa_pod_builder_string_body (SpaPODBuilder *builder, return out; } -static inline uint32_t -spa_pod_builder_pod (SpaPODBuilder *builder, uint32_t size, uint32_t type) -{ - const SpaPOD p = { size, type }; - return spa_pod_builder_raw (builder, &p, sizeof (p), false); -} - static inline uint32_t spa_pod_builder_primitive (SpaPODBuilder *builder, const SpaPOD *p) { const void *data; uint32_t size; - bool in_array, first = false; - in_array = spa_pod_builder_in_array (builder, &first); - if (in_array && !first) { + if (builder->in_array && !builder->first) { data = SPA_POD_BODY_CONST (p); size = SPA_POD_BODY_SIZE (p); } else { data = p; size = SPA_POD_SIZE (p); + builder->first = false; } - return spa_pod_builder_raw (builder, data, size, !in_array); + return spa_pod_builder_raw (builder, data, size, !builder->in_array); } static inline uint32_t @@ -348,12 +329,8 @@ spa_pod_builder_propv (SpaPODBuilder *builder, spa_pod_builder_double (builder, va_arg (args, double)); break; case SPA_POD_TYPE_STRING: - { - const char *str = va_arg (args, char *); - uint32_t len = va_arg (args, uint32_t); - spa_pod_builder_string_len (builder, str, len); + spa_pod_builder_string (builder, va_arg (args, char *)); break; - } case SPA_POD_TYPE_RECTANGLE: { uint32_t width = va_arg (args, uint32_t), height = va_arg (args, uint32_t); @@ -414,6 +391,122 @@ spa_pod_builder_prop (SpaPODBuilder *builder, va_end (args); } +static inline void +spa_pod_builder_addv (SpaPODBuilder *builder, + uint32_t type, + va_list args) +{ + uint32_t n_values = 0; + while (type != 0) { + switch (type) { + case SPA_POD_TYPE_INVALID: + break; + case SPA_POD_TYPE_BOOL: + spa_pod_builder_bool (builder, va_arg (args, int)); + break; + case SPA_POD_TYPE_URI: + spa_pod_builder_uri (builder, va_arg (args, int32_t)); + break; + case SPA_POD_TYPE_INT: + spa_pod_builder_int (builder, va_arg (args, int32_t)); + break; + case SPA_POD_TYPE_LONG: + spa_pod_builder_long (builder, va_arg (args, int64_t)); + break; + case SPA_POD_TYPE_FLOAT: + spa_pod_builder_float (builder, va_arg (args, double)); + break; + case SPA_POD_TYPE_DOUBLE: + spa_pod_builder_double (builder, va_arg (args, double)); + break; + case SPA_POD_TYPE_STRING: + spa_pod_builder_string (builder, va_arg (args, char *)); + break; + case SPA_POD_TYPE_RECTANGLE: + { + uint32_t width = va_arg (args, uint32_t), height = va_arg (args, uint32_t); + spa_pod_builder_rectangle (builder, width, height); + break; + } + case SPA_POD_TYPE_FRACTION: + { + uint32_t num = va_arg (args, uint32_t), denom = va_arg (args, uint32_t); + spa_pod_builder_fraction (builder, num, denom); + break; + } + case SPA_POD_TYPE_BITMASK: + break; + case SPA_POD_TYPE_ARRAY: + { + SpaPODFrame *f = va_arg (args, SpaPODFrame *); + spa_pod_builder_push_array (builder, f); + break; + } + case SPA_POD_TYPE_STRUCT: + { + SpaPODFrame *f = va_arg (args, SpaPODFrame *); + spa_pod_builder_push_struct (builder, f); + break; + } + case SPA_POD_TYPE_OBJECT: + { + SpaPODFrame *f = va_arg (args, SpaPODFrame *); + uint32_t id = va_arg (args, uint32_t); + uint32_t type = va_arg (args, uint32_t); + spa_pod_builder_push_object (builder, f, id, type); + break; + } + case SPA_POD_TYPE_PROP: + { + SpaPODFrame *f = va_arg (args, SpaPODFrame *); + uint32_t key = va_arg (args, uint32_t); + uint32_t flags = va_arg (args, uint32_t); + type = va_arg (args, uint32_t); + n_values = va_arg (args, uint32_t); + spa_pod_builder_push_prop (builder, f, key, flags); + break; + } + case -SPA_POD_TYPE_ARRAY: + case -SPA_POD_TYPE_STRUCT: + case -SPA_POD_TYPE_OBJECT: + case -SPA_POD_TYPE_PROP: + { + SpaPODFrame *f = va_arg (args, SpaPODFrame *); + spa_pod_builder_pop (builder, f); + break; + } + case SPA_POD_TYPE_BYTES: + { + void *value = va_arg (args, void *); + uint32_t size = va_arg (args, uint32_t); + spa_pod_builder_bytes (builder, value, size); + break; + } + case SPA_POD_TYPE_POD: + { + SpaPOD *value = va_arg (args, SpaPOD *); + spa_pod_builder_raw (builder, value, SPA_POD_SIZE (value), true); + break; + } + } + if (n_values > 0) + n_values--; + else + type = va_arg (args, uint32_t); + } +} + +static inline void +spa_pod_builder_add (SpaPODBuilder *builder, + uint32_t type, ...) +{ + va_list args; + + va_start (args, type); + spa_pod_builder_addv (builder, type, args); + va_end (args); +} + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/spa/include/spa/pod.h b/spa/include/spa/pod.h index cff87fca6..b5b4abf43 100644 --- a/spa/include/spa/pod.h +++ b/spa/include/spa/pod.h @@ -48,7 +48,8 @@ typedef enum { SPA_POD_TYPE_STRUCT, SPA_POD_TYPE_OBJECT, SPA_POD_TYPE_PROP, - SPA_POD_TYPE_BYTES + SPA_POD_TYPE_BYTES, + SPA_POD_TYPE_POD } SpaPODType; typedef struct { @@ -71,16 +72,6 @@ typedef struct { int32_t value; } SpaPODInt; -static inline bool -spa_pod_get_int (SpaPOD **pod, int32_t *val) -{ - if (*pod == NULL || (*pod)->type != SPA_POD_TYPE_INT) - return false; - *val = ((SpaPODInt *)(*pod))->value; - *pod = SPA_MEMBER (*pod, SPA_ROUND_UP_N (SPA_POD_SIZE (*pod), 8), SpaPOD); - return true; -} - typedef SpaPODInt SpaPODBool; typedef SpaPODInt SpaPODURI; @@ -89,16 +80,6 @@ typedef struct { int64_t value; } SpaPODLong; -static inline bool -spa_pod_get_long (SpaPOD **pod, int64_t *val) -{ - if (*pod == NULL || (*pod)->type != SPA_POD_TYPE_LONG) - return false; - *val = ((SpaPODLong *)*pod)->value; - *pod = SPA_MEMBER (*pod, SPA_ROUND_UP_N (SPA_POD_SIZE (*pod), 8), SpaPOD); - return true; -} - typedef struct { SpaPOD pod; float value; @@ -114,16 +95,6 @@ typedef struct { /* value here */ } SpaPODString; -static inline bool -spa_pod_get_string (SpaPOD **pod, const char **val) -{ - if (*pod == NULL || (*pod)->type != SPA_POD_TYPE_STRING) - return false; - *val = SPA_POD_CONTENTS (SpaPODString, *pod); - *pod = SPA_MEMBER (*pod, SPA_ROUND_UP_N (SPA_POD_SIZE (*pod), 8), SpaPOD); - return true; -} - typedef struct { SpaPOD pod; /* value here */ @@ -159,16 +130,6 @@ typedef struct { /* one or more SpaPOD follow */ } SpaPODStruct; -static inline bool -spa_pod_get_struct (SpaPOD **pod, SpaPOD **val) -{ - if (*pod == NULL || (*pod)->type != SPA_POD_TYPE_STRUCT) - return false; - *val = *pod; - *pod = SPA_MEMBER (*pod, SPA_ROUND_UP_N (SPA_POD_SIZE (*pod), 8), SpaPOD); - return true; -} - typedef struct { uint32_t key; #define SPA_POD_PROP_RANGE_NONE 0 @@ -207,28 +168,6 @@ typedef struct { SpaPODObjectBody body; } SpaPODObject; -static inline bool -spa_pod_get_object (SpaPOD **pod, const SpaPOD **val) -{ - if (*pod == NULL || (*pod)->type != SPA_POD_TYPE_OBJECT) - return false; - *val = *pod; - *pod = SPA_MEMBER (*pod, SPA_ROUND_UP_N (SPA_POD_SIZE (*pod), 8), SpaPOD); - return true; -} - -static inline bool -spa_pod_get_bytes (SpaPOD **pod, const void **val, uint32_t *size) -{ - if (*pod == NULL || (*pod)->type != SPA_POD_TYPE_BYTES) - return false; - *val = SPA_POD_CONTENTS (SpaPODBytes, *pod); - *size = SPA_POD_SIZE (*pod); - *pod = SPA_MEMBER (*pod, SPA_ROUND_UP_N (SPA_POD_SIZE (*pod), 8), SpaPOD); - return true; -} - - #define SPA_POD_ARRAY_BODY_FOREACH(body, _size, iter) \ for ((iter) = SPA_MEMBER ((body), sizeof(SpaPODArrayBody), __typeof__(*(iter))); \ (iter) < SPA_MEMBER ((body), (_size), __typeof__(*(iter))); \ diff --git a/spa/tests/test-props.c b/spa/tests/test-props.c index cca7b6df1..126aaa7e0 100644 --- a/spa/tests/test-props.c +++ b/spa/tests/test-props.c @@ -102,7 +102,7 @@ static const struct _test_format { SPA_POD_TYPE_PROP } , { SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET, { sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE } }, }, - { { 320, 240 }, + { { 320, 243 }, { 1, 1 }, { INT32_MAX, INT32_MAX } }, @@ -125,8 +125,7 @@ main (int argc, char *argv[]) SpaFormat *fmt; off_t o; - b.data = buffer; - b.size = 1024; + spa_pod_builder_init (&b, buffer, sizeof (buffer)); fmt = SPA_MEMBER (buffer, spa_pod_builder_push_format (&b, &frame[0], SPA_MEDIA_TYPE_VIDEO, @@ -159,9 +158,7 @@ main (int argc, char *argv[]) spa_debug_pod (&fmt->pod); - memset (&b, 0, sizeof(b)); - b.data = buffer; - b.size = 1024; + spa_pod_builder_init (&b, buffer, sizeof (buffer)); o = spa_pod_builder_format (&b, SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, @@ -171,7 +168,7 @@ main (int argc, char *argv[]) SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2, SPA_PROP_ID_VIDEO_SIZE , SPA_POD_TYPE_RECTANGLE, - 320, 240, + 320, 241, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, 1, 1, @@ -187,6 +184,44 @@ main (int argc, char *argv[]) spa_debug_pod (&fmt->pod); spa_debug_format (fmt); + spa_pod_builder_init (&b, buffer, sizeof (buffer)); + + spa_pod_builder_add (&b, + SPA_POD_TYPE_OBJECT, &frame[0], 0, 0, + SPA_POD_TYPE_INT, SPA_MEDIA_TYPE_VIDEO, + SPA_POD_TYPE_INT, SPA_MEDIA_SUBTYPE_RAW, + SPA_POD_TYPE_PROP, &frame[1], + SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_UNSET | + SPA_POD_PROP_RANGE_ENUM, + SPA_POD_TYPE_INT, 3, + SPA_VIDEO_FORMAT_I420, + SPA_VIDEO_FORMAT_I420, + SPA_VIDEO_FORMAT_YUY2, + -SPA_POD_TYPE_PROP, &frame[1], + SPA_POD_TYPE_PROP, &frame[1], + SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_UNSET | + SPA_POD_PROP_RANGE_MIN_MAX, + SPA_POD_TYPE_RECTANGLE, 3, + 320, 242, + 1, 1, + INT32_MAX, INT32_MAX, + -SPA_POD_TYPE_PROP, &frame[1], + SPA_POD_TYPE_PROP, &frame[1], + SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_UNSET | + SPA_POD_PROP_RANGE_MIN_MAX, + SPA_POD_TYPE_FRACTION, 3, + 25, 1, + 0, 1, + INT32_MAX, 1, + -SPA_POD_TYPE_PROP, &frame[1], + -SPA_POD_TYPE_OBJECT, &frame[0], + 0); + spa_pod_builder_pop (&b, &frame[0]); + + fmt = SPA_MEMBER (buffer, o, SpaFormat); + spa_debug_pod (&fmt->pod); + spa_debug_format (fmt); + spa_debug_pod (&test_format.fmt.pod); spa_debug_format (&test_format.fmt);