spa: add spa_json_begin_array/object and relaxed versions

Add spa_json_begin_array/object to replace
spa_json_init+spa_json_begin_array/object

This function is better because it does not waste a useless spa_json
structure as an iterator. The relaxed versions also error out when the
container is mismatched because parsing a mismatched container is not
going to give any results anyway.
This commit is contained in:
Wim Taymans 2024-09-13 13:09:54 +02:00
parent feccb882b6
commit cd81b5f39a
51 changed files with 401 additions and 452 deletions

View file

@ -274,20 +274,18 @@ get_server_name(const struct spa_dict *props)
static int parse_socket_args(struct impl *impl, const char *str)
{
struct spa_json it[2];
struct spa_json it[1];
char socket[PATH_MAX];
spa_json_init(&it[0], str, strlen(str));
if (spa_json_enter_object(&it[0], &it[1]) <= 0)
if (spa_json_begin_object(&it[0], str, strlen(str)) <= 0)
return -EINVAL;
while (spa_json_get_string(&it[1], socket, sizeof(socket)) > 0) {
while (spa_json_get_string(&it[0], socket, sizeof(socket)) > 0) {
char value[256];
const char *val;
int len;
if ((len = spa_json_next(&it[1], &val)) <= 0)
if ((len = spa_json_next(&it[0], &val)) <= 0)
return -EINVAL;
if (spa_json_parse_stringn(val, len, value, sizeof(value)) <= 0)

View file

@ -283,20 +283,19 @@ static int do_help(struct adp *adp, const char *args, FILE *out)
static int do_discover(struct adp *adp, const char *args, FILE *out)
{
struct spa_json it[2];
struct spa_json it[1];
char key[128];
uint64_t entity_id = 0ULL;
spa_json_init(&it[0], args, strlen(args));
if (spa_json_enter_object(&it[0], &it[1]) <= 0)
if (spa_json_begin_object(&it[0], args, strlen(args)) <= 0)
return -EINVAL;
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
int len;
const char *value;
uint64_t id_val;
if ((len = spa_json_next(&it[1], &value)) <= 0)
if ((len = spa_json_next(&it[0], &value)) <= 0)
break;
if (spa_json_is_null(value, len))

View file

@ -253,7 +253,7 @@ static int load_state(struct maap *maap)
{
const char *str;
char key[512];
struct spa_json it[3];
struct spa_json it[2];
bool have_offset = false;
int count = 0, offset = 0;
@ -263,18 +263,17 @@ static int load_state(struct maap *maap)
if ((str = pw_properties_get(maap->props, "maap.addresses")) == NULL)
return 0;
spa_json_init(&it[0], str, strlen(str));
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
if (spa_json_begin_array(&it[0], str, strlen(str)) <= 0)
return 0;
if (spa_json_enter_object(&it[1], &it[2]) <= 0)
if (spa_json_enter_object(&it[0], &it[1]) <= 0)
return 0;
while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
const char *val;
int len;
if ((len = spa_json_next(&it[2], &val)) <= 0)
if ((len = spa_json_next(&it[1], &val)) <= 0)
break;
if (spa_streq(key, "start")) {

View file

@ -330,15 +330,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -1201,15 +1201,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -457,15 +457,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -292,15 +292,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -298,15 +298,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -1416,15 +1416,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_devices(struct impl *impl, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[FFADO_MAX_SPECSTRING_LENGTH];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
impl->n_devices = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
impl->n_devices < FFADO_MAX_SPECSTRINGS) {
impl->devices[impl->n_devices++] = strdup(v);
}
@ -1435,12 +1434,11 @@ static void parse_position(struct spa_audio_info_raw *info, const char *val, siz
struct spa_json it[2];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -2714,7 +2714,7 @@ error:
*/
static int load_graph(struct graph *graph, struct pw_properties *props)
{
struct spa_json it[3];
struct spa_json it[2];
struct spa_json inputs, outputs, *pinputs = NULL, *poutputs = NULL;
struct spa_json cvolumes, pvolumes, *pcvolumes = NULL, *ppvolumes = NULL;
struct spa_json nodes, *pnodes = NULL, links, *plinks = NULL;
@ -2730,57 +2730,56 @@ static int load_graph(struct graph *graph, struct pw_properties *props)
return -EINVAL;
}
spa_json_init(&it[0], json, strlen(json));
if (spa_json_enter_object(&it[0], &it[1]) <= 0) {
if (spa_json_begin_object(&it[0], json, strlen(json)) <= 0) {
pw_log_error("filter.graph must be an object");
return -EINVAL;
}
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
if (spa_streq("nodes", key)) {
if (spa_json_enter_array(&it[1], &nodes) <= 0) {
if (spa_json_enter_array(&it[0], &nodes) <= 0) {
pw_log_error("nodes expects an array");
return -EINVAL;
}
pnodes = &nodes;
}
else if (spa_streq("links", key)) {
if (spa_json_enter_array(&it[1], &links) <= 0) {
if (spa_json_enter_array(&it[0], &links) <= 0) {
pw_log_error("links expects an array");
return -EINVAL;
}
plinks = &links;
}
else if (spa_streq("inputs", key)) {
if (spa_json_enter_array(&it[1], &inputs) <= 0) {
if (spa_json_enter_array(&it[0], &inputs) <= 0) {
pw_log_error("inputs expects an array");
return -EINVAL;
}
pinputs = &inputs;
}
else if (spa_streq("outputs", key)) {
if (spa_json_enter_array(&it[1], &outputs) <= 0) {
if (spa_json_enter_array(&it[0], &outputs) <= 0) {
pw_log_error("outputs expects an array");
return -EINVAL;
}
poutputs = &outputs;
}
else if (spa_streq("capture.volumes", key)) {
if (spa_json_enter_array(&it[1], &cvolumes) <= 0) {
if (spa_json_enter_array(&it[0], &cvolumes) <= 0) {
pw_log_error("capture.volumes expects an array");
return -EINVAL;
}
pcvolumes = &cvolumes;
}
else if (spa_streq("playback.volumes", key)) {
if (spa_json_enter_array(&it[1], &pvolumes) <= 0) {
if (spa_json_enter_array(&it[0], &pvolumes) <= 0) {
pw_log_error("playback.volumes expects an array");
return -EINVAL;
}
ppvolumes = &pvolumes;
} else {
pw_log_warn("unexpected graph key '%s'", key);
if (spa_json_next(&it[1], &val) < 0)
if (spa_json_next(&it[0], &val) < 0)
break;
}
}
@ -2788,25 +2787,25 @@ static int load_graph(struct graph *graph, struct pw_properties *props)
pw_log_error("filter.graph is missing a nodes array");
return -EINVAL;
}
while (spa_json_enter_object(pnodes, &it[2]) > 0) {
if ((res = load_node(graph, &it[2])) < 0)
while (spa_json_enter_object(pnodes, &it[1]) > 0) {
if ((res = load_node(graph, &it[1])) < 0)
return res;
}
if (plinks != NULL) {
while (spa_json_enter_object(plinks, &it[2]) > 0) {
if ((res = parse_link(graph, &it[2])) < 0)
while (spa_json_enter_object(plinks, &it[1]) > 0) {
if ((res = parse_link(graph, &it[1])) < 0)
return res;
}
}
if (pcvolumes != NULL) {
while (spa_json_enter_object(pcvolumes, &it[2]) > 0) {
if ((res = parse_volume(graph, &it[2], true)) < 0)
while (spa_json_enter_object(pcvolumes, &it[1]) > 0) {
if ((res = parse_volume(graph, &it[1], true)) < 0)
return res;
}
}
if (ppvolumes != NULL) {
while (spa_json_enter_object(ppvolumes, &it[2]) > 0) {
if ((res = parse_volume(graph, &it[2], false)) < 0)
while (spa_json_enter_object(ppvolumes, &it[1]) > 0) {
if ((res = parse_volume(graph, &it[1], false)) < 0)
return res;
}
}
@ -2913,15 +2912,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -278,7 +278,7 @@ static void *bq_instantiate(const struct fc_descriptor * Descriptor,
unsigned long SampleRate, int index, const char *config)
{
struct builtin *impl;
struct spa_json it[4];
struct spa_json it[3];
const char *val;
char key[256];
uint32_t best_rate = 0;
@ -298,69 +298,68 @@ static void *bq_instantiate(const struct fc_descriptor * Descriptor,
goto error;
}
spa_json_init(&it[0], config, strlen(config));
if (spa_json_enter_object(&it[0], &it[1]) <= 0) {
if (spa_json_begin_object(&it[0], config, strlen(config)) <= 0) {
pw_log_error("biquads:config section must be an object");
goto error;
}
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
if (spa_streq(key, "coefficients")) {
if (spa_json_enter_array(&it[1], &it[2]) <= 0) {
if (spa_json_enter_array(&it[0], &it[1]) <= 0) {
pw_log_error("biquads:coefficients require an array");
goto error;
}
while (spa_json_enter_object(&it[2], &it[3]) > 0) {
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
int32_t rate = 0;
float b0 = 1.0f, b1 = 0.0f, b2 = 0.0f;
float a0 = 1.0f, a1 = 0.0f, a2 = 0.0f;
while (spa_json_get_string(&it[3], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
if (spa_streq(key, "rate")) {
if (spa_json_get_int(&it[3], &rate) <= 0) {
if (spa_json_get_int(&it[2], &rate) <= 0) {
pw_log_error("biquads:rate requires a number");
goto error;
}
}
else if (spa_streq(key, "b0")) {
if (spa_json_get_float(&it[3], &b0) <= 0) {
if (spa_json_get_float(&it[2], &b0) <= 0) {
pw_log_error("biquads:b0 requires a float");
goto error;
}
}
else if (spa_streq(key, "b1")) {
if (spa_json_get_float(&it[3], &b1) <= 0) {
if (spa_json_get_float(&it[2], &b1) <= 0) {
pw_log_error("biquads:b1 requires a float");
goto error;
}
}
else if (spa_streq(key, "b2")) {
if (spa_json_get_float(&it[3], &b2) <= 0) {
if (spa_json_get_float(&it[2], &b2) <= 0) {
pw_log_error("biquads:b2 requires a float");
goto error;
}
}
else if (spa_streq(key, "a0")) {
if (spa_json_get_float(&it[3], &a0) <= 0) {
if (spa_json_get_float(&it[2], &a0) <= 0) {
pw_log_error("biquads:a0 requires a float");
goto error;
}
}
else if (spa_streq(key, "a1")) {
if (spa_json_get_float(&it[3], &a1) <= 0) {
if (spa_json_get_float(&it[2], &a1) <= 0) {
pw_log_error("biquads:a1 requires a float");
goto error;
}
}
else if (spa_streq(key, "a2")) {
if (spa_json_get_float(&it[3], &a2) <= 0) {
if (spa_json_get_float(&it[2], &a2) <= 0) {
pw_log_error("biquads:a0 requires a float");
goto error;
}
}
else {
pw_log_warn("biquads: ignoring coefficients key: '%s'", key);
if (spa_json_next(&it[3], &val) < 0)
if (spa_json_next(&it[2], &val) < 0)
break;
}
}
@ -373,7 +372,7 @@ static void *bq_instantiate(const struct fc_descriptor * Descriptor,
}
else {
pw_log_warn("biquads: ignoring config key: '%s'", key);
if (spa_json_next(&it[1], &val) < 0)
if (spa_json_next(&it[0], &val) < 0)
break;
}
}
@ -865,7 +864,7 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
float *samples;
int offset = 0, length = 0, channel = index, n_samples = 0, len;
uint32_t i = 0;
struct spa_json it[3];
struct spa_json it[2];
const char *val;
char key[256], v[256];
char *filenames[MAX_RATES] = { 0 };
@ -881,45 +880,44 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
return NULL;
}
spa_json_init(&it[0], config, strlen(config));
if (spa_json_enter_object(&it[0], &it[1]) <= 0) {
if (spa_json_begin_object(&it[0], config, strlen(config)) <= 0) {
pw_log_error("convolver:config must be an object");
return NULL;
}
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
if (spa_streq(key, "blocksize")) {
if (spa_json_get_int(&it[1], &blocksize) <= 0) {
if (spa_json_get_int(&it[0], &blocksize) <= 0) {
pw_log_error("convolver:blocksize requires a number");
return NULL;
}
}
else if (spa_streq(key, "tailsize")) {
if (spa_json_get_int(&it[1], &tailsize) <= 0) {
if (spa_json_get_int(&it[0], &tailsize) <= 0) {
pw_log_error("convolver:tailsize requires a number");
return NULL;
}
}
else if (spa_streq(key, "gain")) {
if (spa_json_get_float(&it[1], &gain) <= 0) {
if (spa_json_get_float(&it[0], &gain) <= 0) {
pw_log_error("convolver:gain requires a number");
return NULL;
}
}
else if (spa_streq(key, "delay")) {
if (spa_json_get_int(&it[1], &delay) <= 0) {
if (spa_json_get_int(&it[0], &delay) <= 0) {
pw_log_error("convolver:delay requires a number");
return NULL;
}
}
else if (spa_streq(key, "filename")) {
if ((len = spa_json_next(&it[1], &val)) <= 0) {
if ((len = spa_json_next(&it[0], &val)) <= 0) {
pw_log_error("convolver:filename requires a string or an array");
return NULL;
}
if (spa_json_is_array(val, len)) {
spa_json_enter(&it[1], &it[2]);
while (spa_json_get_string(&it[2], v, sizeof(v)) > 0 &&
spa_json_enter(&it[0], &it[1]);
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
i < SPA_N_ELEMENTS(filenames)) {
filenames[i] = strdup(v);
i++;
@ -933,32 +931,32 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
}
}
else if (spa_streq(key, "offset")) {
if (spa_json_get_int(&it[1], &offset) <= 0) {
if (spa_json_get_int(&it[0], &offset) <= 0) {
pw_log_error("convolver:offset requires a number");
return NULL;
}
}
else if (spa_streq(key, "length")) {
if (spa_json_get_int(&it[1], &length) <= 0) {
if (spa_json_get_int(&it[0], &length) <= 0) {
pw_log_error("convolver:length requires a number");
return NULL;
}
}
else if (spa_streq(key, "channel")) {
if (spa_json_get_int(&it[1], &channel) <= 0) {
if (spa_json_get_int(&it[0], &channel) <= 0) {
pw_log_error("convolver:channel requires a number");
return NULL;
}
}
else if (spa_streq(key, "resample_quality")) {
if (spa_json_get_int(&it[1], &resample_quality) <= 0) {
if (spa_json_get_int(&it[0], &resample_quality) <= 0) {
pw_log_error("convolver:resample_quality requires a number");
return NULL;
}
}
else {
pw_log_warn("convolver: ignoring config key: '%s'", key);
if (spa_json_next(&it[1], &val) < 0)
if (spa_json_next(&it[0], &val) < 0)
break;
}
}
@ -1097,7 +1095,7 @@ static void *delay_instantiate(const struct fc_descriptor * Descriptor,
unsigned long SampleRate, int index, const char *config)
{
struct delay_impl *impl;
struct spa_json it[2];
struct spa_json it[1];
const char *val;
char key[256];
float max_delay = 1.0f;
@ -1108,21 +1106,20 @@ static void *delay_instantiate(const struct fc_descriptor * Descriptor,
return NULL;
}
spa_json_init(&it[0], config, strlen(config));
if (spa_json_enter_object(&it[0], &it[1]) <= 0) {
if (spa_json_begin_object(&it[0], config, strlen(config)) <= 0) {
pw_log_error("delay:config must be an object");
return NULL;
}
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
if (spa_streq(key, "max-delay")) {
if (spa_json_get_float(&it[1], &max_delay) <= 0) {
if (spa_json_get_float(&it[0], &max_delay) <= 0) {
pw_log_error("delay:max-delay requires a number");
return NULL;
}
} else {
pw_log_warn("delay: ignoring config key: '%s'", key);
if (spa_json_next(&it[1], &val) < 0)
if (spa_json_next(&it[0], &val) < 0)
break;
}
}

View file

@ -36,7 +36,7 @@ static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
unsigned long SampleRate, int index, const char *config)
{
struct spatializer_impl *impl;
struct spa_json it[2];
struct spa_json it[1];
const char *val;
char key[256];
char filename[PATH_MAX] = "";
@ -47,8 +47,7 @@ static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
return NULL;
}
spa_json_init(&it[0], config, strlen(config));
if (spa_json_enter_object(&it[0], &it[1]) <= 0) {
if (spa_json_begin_object(&it[0], config, strlen(config)) <= 0) {
pw_log_error("spatializer: expected object in config");
return NULL;
}
@ -59,29 +58,29 @@ static void * spatializer_instantiate(const struct fc_descriptor * Descriptor,
return NULL;
}
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
if (spa_streq(key, "blocksize")) {
if (spa_json_get_int(&it[1], &impl->blocksize) <= 0) {
if (spa_json_get_int(&it[0], &impl->blocksize) <= 0) {
pw_log_error("spatializer:blocksize requires a number");
errno = EINVAL;
goto error;
}
}
else if (spa_streq(key, "tailsize")) {
if (spa_json_get_int(&it[1], &impl->tailsize) <= 0) {
if (spa_json_get_int(&it[0], &impl->tailsize) <= 0) {
pw_log_error("spatializer:tailsize requires a number");
errno = EINVAL;
goto error;
}
}
else if (spa_streq(key, "filename")) {
if (spa_json_get_string(&it[1], filename, sizeof(filename)) <= 0) {
if (spa_json_get_string(&it[0], filename, sizeof(filename)) <= 0) {
pw_log_error("spatializer:filename requires a string");
errno = EINVAL;
goto error;
}
}
else if (spa_json_next(&it[1], &val) < 0)
else if (spa_json_next(&it[0], &val) < 0)
break;
}
if (!filename[0]) {

View file

@ -1001,15 +1001,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -773,15 +773,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -66,21 +66,20 @@ struct factory_data {
*/
static int fill_metadata(struct pw_metadata *metadata, const char *str)
{
struct spa_json it[3];
struct spa_json it[2];
spa_json_init(&it[0], str, strlen(str));
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
if (spa_json_begin_array(&it[0], str, strlen(str)) <= 0)
return -EINVAL;
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
while (spa_json_enter_object(&it[0], &it[1]) > 0) {
char key[256], *k = NULL, *v = NULL, *t = NULL;
int id = 0;
while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
int len;
const char *val;
if ((len = spa_json_next(&it[2], &val)) <= 0)
if ((len = spa_json_next(&it[1], &val)) <= 0)
return -EINVAL;
if (spa_streq(key, "id")) {
@ -94,7 +93,7 @@ static int fill_metadata(struct pw_metadata *metadata, const char *str)
spa_json_parse_stringn(val, len, t, len+1);
} else if (spa_streq(key, "value")) {
if (spa_json_is_container(val, len))
len = spa_json_container_len(&it[2], val, len);
len = spa_json_container_len(&it[1], val, len);
if ((v = malloc(len+1)) != NULL)
spa_json_parse_stringn(val, len, v, len+1);
}

View file

@ -1156,15 +1156,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -1182,15 +1182,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -764,15 +764,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -1659,7 +1659,7 @@ static int create_servers(struct pw_protocol *this, struct pw_impl_core *core,
const struct pw_properties *props, const struct pw_properties *args)
{
const char *sockets = args ? pw_properties_get(args, "sockets") : NULL;
struct spa_json it[3];
struct spa_json it[2];
spa_autoptr(pw_properties) p = pw_properties_copy(props);
if (sockets == NULL) {
@ -1681,12 +1681,10 @@ static int create_servers(struct pw_protocol *this, struct pw_impl_core *core,
return 0;
}
spa_json_init(&it[0], sockets, strlen(sockets));
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
if (spa_json_begin_array(&it[0], sockets, strlen(sockets)) <= 0)
goto error_invalid;
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
while (spa_json_enter_object(&it[0], &it[1]) > 0) {
struct socket_info info = {0};
char key[256];
char name[PATH_MAX];
@ -1698,11 +1696,11 @@ static int create_servers(struct pw_protocol *this, struct pw_impl_core *core,
pw_properties_clear(p);
pw_properties_update(p, &props->dict);
while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
const char *value;
int len;
if ((len = spa_json_next(&it[2], &value)) <= 0)
if ((len = spa_json_next(&it[1], &value)) <= 0)
goto error_invalid;
if (spa_streq(key, "name")) {
@ -1762,7 +1760,7 @@ static int create_servers(struct pw_protocol *this, struct pw_impl_core *core,
info.has_mode = true;
} else if (spa_streq(key, "props")) {
if (spa_json_is_container(value, len))
len = spa_json_container_len(&it[2], value, len);
len = spa_json_container_len(&it[1], value, len);
pw_properties_update_string(p, value, len);
}

View file

@ -152,7 +152,7 @@ int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client,
void *data)
{
const char *name;
struct spa_json it[2];
struct spa_json it[1];
char path[PATH_MAX];
int res = -EINVAL;
@ -160,12 +160,10 @@ int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client,
if (name == NULL)
return -EINVAL;
spa_json_init(&it[0], name, strlen(name));
if (spa_json_enter_array(&it[0], &it[1]) < 0)
if (spa_json_begin_array(&it[0], name, strlen(name)) <= 0)
return try_connect_name(client, name, done_callback, data);
while (spa_json_get_string(&it[1], path, sizeof(path)) > 0) {
while (spa_json_get_string(&it[0], path, sizeof(path)) > 0) {
res = try_connect_name(client, path, done_callback, data);
if (res < 0)
continue;

View file

@ -68,25 +68,24 @@ static int parse_cmd(void *user_data, const char *location,
const char *section, const char *str, size_t len)
{
struct impl *impl = user_data;
struct spa_json it[3];
struct spa_json it[2];
char key[512];
int res = 0;
spa_autofree char *s = strndup(str, len);
spa_json_init(&it[0], s, len);
if (spa_json_enter_array(&it[0], &it[1]) < 0) {
if (spa_json_begin_array(&it[0], s, len) < 0) {
pw_log_error("config file error: pulse.cmd is not an array");
return -EINVAL;
}
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
while (spa_json_enter_object(&it[0], &it[1]) > 0) {
char *cmd = NULL, *args = NULL, *flags = NULL;
while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
const char *val;
int len;
if ((len = spa_json_next(&it[2], &val)) <= 0)
if ((len = spa_json_next(&it[1], &val)) <= 0)
break;
if (spa_streq(key, "cmd")) {
@ -97,7 +96,7 @@ static int parse_cmd(void *user_data, const char *location,
spa_json_parse_stringn(val, len, args, len+1);
} else if (spa_streq(key, "flags")) {
if (spa_json_is_container(val, len))
len = spa_json_container_len(&it[2], val, len);
len = spa_json_container_len(&it[1], val, len);
flags = (char*)val;
spa_json_parse_stringn(val, len, flags, len+1);
}

View file

@ -440,15 +440,14 @@ void channel_map_parse(const char *str, struct channel_map *map)
void channel_map_parse_position(const char *str, struct channel_map *map)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], str, strlen(str));
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], str, strlen(str));
if (spa_json_begin_array_relax(&it[0], str, strlen(str)) <= 0)
return;
map->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
map->channels < SPA_AUDIO_MAX_CHANNELS) {
map->map[map->channels++] = channel_name2id(v);
}

View file

@ -177,7 +177,7 @@ static int do_extension_stream_restore_read(struct module *module, struct client
reply = reply_new(client, tag);
spa_dict_for_each(item, &client->routes->dict) {
struct spa_json it[3];
struct spa_json it[2];
const char *value;
char name[1024], key[128];
char device_name[1024] = "\0";
@ -191,45 +191,44 @@ static int do_extension_stream_restore_read(struct module *module, struct client
pw_log_debug("%s -> %s: %s", item->key, name, item->value);
spa_json_init(&it[0], item->value, strlen(item->value));
if (spa_json_enter_object(&it[0], &it[1]) <= 0)
if (spa_json_begin_object(&it[0], item->value, strlen(item->value)) <= 0)
continue;
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
if (spa_streq(key, "volume")) {
if (spa_json_get_float(&it[1], &volume) <= 0)
if (spa_json_get_float(&it[0], &volume) <= 0)
continue;
}
else if (spa_streq(key, "mute")) {
if (spa_json_get_bool(&it[1], &mute) <= 0)
if (spa_json_get_bool(&it[0], &mute) <= 0)
continue;
}
else if (spa_streq(key, "volumes")) {
vol = VOLUME_INIT;
if (spa_json_enter_array(&it[1], &it[2]) <= 0)
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
continue;
for (vol.channels = 0; vol.channels < CHANNELS_MAX; vol.channels++) {
if (spa_json_get_float(&it[2], &vol.values[vol.channels]) <= 0)
if (spa_json_get_float(&it[1], &vol.values[vol.channels]) <= 0)
break;
}
}
else if (spa_streq(key, "channels")) {
if (spa_json_enter_array(&it[1], &it[2]) <= 0)
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
continue;
for (map.channels = 0; map.channels < CHANNELS_MAX; map.channels++) {
char chname[16];
if (spa_json_get_string(&it[2], chname, sizeof(chname)) <= 0)
if (spa_json_get_string(&it[1], chname, sizeof(chname)) <= 0)
break;
map.map[map.channels] = channel_name2id(chname);
}
}
else if (spa_streq(key, "target-node")) {
if (spa_json_get_string(&it[1], device_name, sizeof(device_name)) <= 0)
if (spa_json_get_string(&it[0], device_name, sizeof(device_name)) <= 0)
continue;
}
else if (spa_json_next(&it[1], &value) <= 0)
else if (spa_json_next(&it[0], &value) <= 0)
break;
}
message_put(reply,

View file

@ -930,21 +930,20 @@ static void manager_object_data_timeout(void *data, struct pw_manager_object *o,
static int json_object_find(const char *obj, const char *key, char *value, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
const char *v;
char k[128];
spa_json_init(&it[0], obj, strlen(obj));
if (spa_json_enter_object(&it[0], &it[1]) <= 0)
if (spa_json_begin_object(&it[0], obj, strlen(obj)) <= 0)
return -EINVAL;
while (spa_json_get_string(&it[1], k, sizeof(k)) > 0) {
while (spa_json_get_string(&it[0], k, sizeof(k)) > 0) {
if (spa_streq(k, key)) {
if (spa_json_get_string(&it[1], value, len) <= 0)
if (spa_json_get_string(&it[0], value, len) <= 0)
continue;
return 0;
} else {
if (spa_json_next(&it[1], &v) <= 0)
if (spa_json_next(&it[0], &v) <= 0)
break;
}
}

View file

@ -977,29 +977,28 @@ int servers_create_and_start(struct impl *impl, const char *addresses, struct pw
{
int len, res, count = 0, err = 0; /* store the first error to return when no servers could be created */
const char *v;
struct spa_json it[3];
struct spa_json it[2];
/* update `err` if it hasn't been set to an errno */
#define UPDATE_ERR(e) do { if (err == 0) err = (e); } while (false)
/* collect addresses into an array of `struct sockaddr_storage` */
spa_json_init(&it[0], addresses, strlen(addresses));
/* [ <server-spec> ... ] */
if (spa_json_enter_array(&it[0], &it[1]) < 0)
if (spa_json_begin_array(&it[0], addresses, strlen(addresses)) < 0)
return -EINVAL;
/* a server-spec is either an address or an object */
while ((len = spa_json_next(&it[1], &v)) > 0) {
while ((len = spa_json_next(&it[0], &v)) > 0) {
char addr_str[FORMATTED_SOCKET_ADDR_STRLEN] = { 0 };
char key[128], client_access[64] = { 0 };
struct sockaddr_storage addrs[2];
int i, max_clients = MAX_CLIENTS, listen_backlog = LISTEN_BACKLOG, n_addr;
if (spa_json_is_object(v, len)) {
spa_json_enter(&it[1], &it[2]);
while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
if ((len = spa_json_next(&it[2], &v)) <= 0)
spa_json_enter(&it[0], &it[1]);
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
if ((len = spa_json_next(&it[1], &v)) <= 0)
break;
if (spa_streq(key, "address")) {

View file

@ -805,15 +805,14 @@ static inline uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}
@ -890,7 +889,7 @@ static void copy_props(struct impl *impl, const char *key)
static int parse_params(struct impl *impl)
{
const char *str;
struct spa_json it[2];
struct spa_json it[1];
char value[512];
pw_properties_fetch_bool(impl->props, "capture", &impl->capture);
@ -965,9 +964,8 @@ static int parse_params(struct impl *impl)
if ((str = pw_properties_get(impl->props, "server.address")) == NULL)
str = DEFAULT_SERVER;
spa_json_init(&it[0], str, strlen(str));
if (spa_json_enter_array(&it[0], &it[1]) > 0) {
while (spa_json_get_string(&it[1], value, sizeof(value)) > 0) {
if (spa_json_begin_array_relax(&it[0], str, strlen(str)) > 0) {
while (spa_json_get_string(&it[0], value, sizeof(value)) > 0) {
if (create_server(impl, value) == NULL) {
pw_log_warn("%p: can't create server for %s: %m",
impl, value);

View file

@ -1074,15 +1074,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -965,19 +965,16 @@ static struct session *session_new_announce(struct impl *impl, struct node *node
sess->ts_refclk_ptp = pw_properties_get_bool(props, "rtp.fetch-ts-refclk", false);
if ((str = pw_properties_get(props, PW_KEY_NODE_CHANNELNAMES)) != NULL) {
struct spa_strbuf buf;
struct spa_json it[1];
char v[256];
int count = 0;
spa_strbuf_init(&buf, sdp->channelmap, sizeof(sdp->channelmap));
struct spa_json it[2];
char v[256];
spa_json_init(&it[0], str, strlen(str));
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], str, strlen(str));
if (spa_json_get_string(&it[1], v, sizeof(v)) > 0)
spa_strbuf_append(&buf, "%s", v);
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0)
spa_strbuf_append(&buf, ", %s", v);
if (spa_json_begin_array_relax(&it[0], str, strlen(str)) > 0) {
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0)
spa_strbuf_append(&buf, "%s%s", count++ > 0 ? ", " : "", v);
}
}
pw_log_info("created new session for node:%u", node->id);
@ -1799,30 +1796,24 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
struct spa_strbuf buf;
if ((str = pw_properties_get(props, "sap.preamble-extra")) != NULL) {
spa_strbuf_init(&buf, buffer, sizeof(buffer));
struct spa_json it[2];
struct spa_json it[1];
char line[256];
spa_json_init(&it[0], str, strlen(str));
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], str, strlen(str));
while (spa_json_get_string(&it[1], line, sizeof(line)) > 0)
spa_strbuf_append(&buf, "%s\n", line);
if (spa_json_begin_array_relax(&it[0], str, strlen(str)) > 0) {
while (spa_json_get_string(&it[0], line, sizeof(line)) > 0)
spa_strbuf_append(&buf, "%s\n", line);
}
impl->extra_attrs_preamble = strdup(buffer);
}
if ((str = pw_properties_get(props, "sap.end-extra")) != NULL) {
spa_strbuf_init(&buf, buffer, sizeof(buffer));
struct spa_json it[2];
struct spa_json it[1];
char line[256];
spa_json_init(&it[0], str, strlen(str));
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], str, strlen(str));
while (spa_json_get_string(&it[1], line, sizeof(line)) > 0)
spa_strbuf_append(&buf, "%s\n", line);
if (spa_json_begin_array_relax(&it[0], str, strlen(str)) > 0) {
while (spa_json_get_string(&it[0], line, sizeof(line)) > 0)
spa_strbuf_append(&buf, "%s\n", line);
}
impl->extra_attrs_end = strdup(buffer);
}

View file

@ -291,15 +291,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -486,14 +486,13 @@ static int snapcast_connect(struct tunnel *t)
static int add_snapcast_stream(struct impl *impl, struct tunnel *t,
struct pw_properties *props, const char *servers)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], servers, strlen(servers));
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], servers, strlen(servers));
if (spa_json_begin_array_relax(&it[0], servers, strlen(servers)) <= 0)
return -EINVAL;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0) {
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0) {
t->server_address = strdup(v);
snapcast_connect(t);
return 0;
@ -523,15 +522,14 @@ static inline uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}

View file

@ -209,15 +209,14 @@ static uint32_t channel_from_name(const char *name)
static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len)
{
struct spa_json it[2];
struct spa_json it[1];
char v[256];
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
if (spa_json_begin_array_relax(&it[0], val, len) <= 0)
return;
info->channels = 0;
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 &&
while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 &&
info->channels < SPA_AUDIO_MAX_CHANNELS) {
info->position[info->channels++] = channel_from_name(v);
}