mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
pw-cli: move json to pod code to SPA
This commit is contained in:
parent
67dcc0d291
commit
5ebbe09371
2 changed files with 197 additions and 122 deletions
191
spa/include/spa/utils/json-pod.h
Normal file
191
spa/include/spa/utils/json-pod.h
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/* Simple Plugin API
|
||||
*
|
||||
* Copyright © 2022 Wim Taymans
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SPA_UTILS_JSON_POD_H
|
||||
#define SPA_UTILS_JSON_POD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <spa/utils/string.h>
|
||||
#include <spa/utils/json.h>
|
||||
#include <spa/pod/pod.h>
|
||||
#include <spa/pod/builder.h>
|
||||
#include <spa/debug/types.h>
|
||||
|
||||
/** \defgroup spa_json_pod JSON to POD
|
||||
* JSON to POD conversion
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup spa_json_pod
|
||||
* \{
|
||||
*/
|
||||
|
||||
static inline const struct spa_type_info *spa_debug_type_info_short(const struct spa_type_info *info, const char *name)
|
||||
{
|
||||
while (info && info->name) {
|
||||
if (spa_streq(info->name, name))
|
||||
return info;
|
||||
if (spa_streq(spa_debug_type_short_name(info->name), name))
|
||||
return info;
|
||||
if (info->type != 0 && info->type == (uint32_t)atoi(name))
|
||||
return info;
|
||||
info++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int spa_json_to_pod_part(struct spa_pod_builder *b, uint32_t flags, uint32_t id,
|
||||
const struct spa_type_info *info, struct spa_json *iter, const char *value, int len)
|
||||
{
|
||||
const struct spa_type_info *ti;
|
||||
char key[256];
|
||||
struct spa_pod_frame f[1];
|
||||
struct spa_json it[1];
|
||||
int l, res;
|
||||
const char *v;
|
||||
uint32_t type;
|
||||
|
||||
if (spa_json_is_object(value, len) && info != NULL) {
|
||||
if ((ti = spa_debug_type_find(NULL, info->parent)) == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
spa_pod_builder_push_object(b, &f[0], info->parent, id);
|
||||
|
||||
spa_json_enter(iter, &it[0]);
|
||||
while (spa_json_get_string(&it[0], key, sizeof(key)) > 0) {
|
||||
const struct spa_type_info *pi;
|
||||
if ((l = spa_json_next(&it[0], &v)) <= 0)
|
||||
break;
|
||||
if ((pi = spa_debug_type_info_short(ti->values, key)) != NULL)
|
||||
type = pi->type;
|
||||
else if (!spa_atou32(key, &type, 0))
|
||||
continue;
|
||||
spa_pod_builder_prop(b, type, 0);
|
||||
if ((res = spa_json_to_pod_part(b, flags, id, pi, &it[0], v, l)) < 0)
|
||||
return res;
|
||||
}
|
||||
spa_pod_builder_pop(b, &f[0]);
|
||||
}
|
||||
else if (spa_json_is_array(value, len)) {
|
||||
if (info == NULL || info->parent == SPA_TYPE_Struct) {
|
||||
spa_pod_builder_push_struct(b, &f[0]);
|
||||
} else {
|
||||
spa_pod_builder_push_array(b, &f[0]);
|
||||
info = info->values;
|
||||
}
|
||||
spa_json_enter(iter, &it[0]);
|
||||
while ((l = spa_json_next(&it[0], &v)) > 0)
|
||||
if ((res = spa_json_to_pod_part(b, flags, id, info, &it[0], v, l)) < 0)
|
||||
return res;
|
||||
spa_pod_builder_pop(b, &f[0]);
|
||||
}
|
||||
else if (spa_json_is_float(value, len)) {
|
||||
float val = 0.0f;
|
||||
spa_json_parse_float(value, len, &val);
|
||||
switch (info ? info->parent : (uint32_t)SPA_TYPE_Struct) {
|
||||
case SPA_TYPE_Bool:
|
||||
spa_pod_builder_bool(b, val >= 0.5f);
|
||||
break;
|
||||
case SPA_TYPE_Id:
|
||||
spa_pod_builder_id(b, val);
|
||||
break;
|
||||
case SPA_TYPE_Int:
|
||||
spa_pod_builder_int(b, val);
|
||||
break;
|
||||
case SPA_TYPE_Long:
|
||||
spa_pod_builder_long(b, val);
|
||||
break;
|
||||
case SPA_TYPE_Struct:
|
||||
if (spa_json_is_int(value, len))
|
||||
spa_pod_builder_int(b, val);
|
||||
else
|
||||
spa_pod_builder_float(b, val);
|
||||
break;
|
||||
case SPA_TYPE_Float:
|
||||
spa_pod_builder_float(b, val);
|
||||
break;
|
||||
case SPA_TYPE_Double:
|
||||
spa_pod_builder_double(b, val);
|
||||
break;
|
||||
default:
|
||||
spa_pod_builder_none(b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (spa_json_is_bool(value, len)) {
|
||||
bool val = false;
|
||||
spa_json_parse_bool(value, len, &val);
|
||||
spa_pod_builder_bool(b, val);
|
||||
}
|
||||
else if (spa_json_is_null(value, len)) {
|
||||
spa_pod_builder_none(b);
|
||||
}
|
||||
else {
|
||||
char *val = (char*)alloca(len+1);
|
||||
spa_json_parse_stringn(value, len, val, len+1);
|
||||
switch (info ? info->parent : (uint32_t)SPA_TYPE_Struct) {
|
||||
case SPA_TYPE_Id:
|
||||
if ((ti = spa_debug_type_info_short(info->values, val)) != NULL)
|
||||
type = ti->type;
|
||||
else if (!spa_atou32(val, &type, 0))
|
||||
return -EINVAL;
|
||||
spa_pod_builder_id(b, type);
|
||||
break;
|
||||
case SPA_TYPE_Struct:
|
||||
case SPA_TYPE_String:
|
||||
spa_pod_builder_string(b, val);
|
||||
break;
|
||||
default:
|
||||
spa_pod_builder_none(b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int spa_json_to_pod(struct spa_pod_builder *b, uint32_t flags,
|
||||
const struct spa_type_info *info, const char *value, int len)
|
||||
{
|
||||
struct spa_json iter;
|
||||
const char *val;
|
||||
|
||||
spa_json_init(&iter, value, len);
|
||||
if ((len = spa_json_next(&iter, &val)) <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
return spa_json_to_pod_part(b, flags, info->type, info, &iter, val, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* \}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SPA_UTILS_JSON_POD_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue