mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
properties: add some more features to properties serialize
Add an option to put {} around the properties.
Add option to skip the keys and put [] around the properties.
Add option to recursively serialize properties.
This commit is contained in:
parent
048ba15f7f
commit
543965a8c3
2 changed files with 99 additions and 22 deletions
|
|
@ -640,12 +640,13 @@ const char *pw_properties_iterate(const struct pw_properties *properties, void *
|
||||||
return pw_array_get_unchecked(&impl->items, index, struct spa_dict_item)->key;
|
return pw_array_get_unchecked(&impl->items, index, struct spa_dict_item)->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_string(FILE *f, const char *val)
|
static int encode_string(FILE *f, const char *val, int size)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int i, len = 0;
|
||||||
len += fprintf(f, "\"");
|
len += fprintf(f, "\"");
|
||||||
while (*val) {
|
for (i = 0; i < size; i++) {
|
||||||
switch (*val) {
|
char v = val[i];
|
||||||
|
switch (v) {
|
||||||
case '\n':
|
case '\n':
|
||||||
len += fprintf(f, "\\n");
|
len += fprintf(f, "\\n");
|
||||||
break;
|
break;
|
||||||
|
|
@ -661,43 +662,114 @@ static int encode_string(FILE *f, const char *val)
|
||||||
case '\f':
|
case '\f':
|
||||||
len += fprintf(f, "\\f");
|
len += fprintf(f, "\\f");
|
||||||
break;
|
break;
|
||||||
case '\\':
|
case '\\': case '"':
|
||||||
case '"':
|
len += fprintf(f, "\\%c", v);
|
||||||
len += fprintf(f, "\\%c", *val);
|
break;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
if (*val > 0 && *val < 0x20)
|
if (v > 0 && v < 0x20)
|
||||||
len += fprintf(f, "\\u%04x", *val);
|
len += fprintf(f, "\\u%04x", v);
|
||||||
else
|
else
|
||||||
len += fprintf(f, "%c", *val);
|
len += fprintf(f, "%c", v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
val++;
|
|
||||||
}
|
}
|
||||||
len += fprintf(f, "\"");
|
len += fprintf(f, "\"");
|
||||||
return len-1;
|
return len-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct dump_config {
|
||||||
|
FILE *file;
|
||||||
|
int indent;
|
||||||
|
const char *sep;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int dump(struct dump_config *c, int indent, struct spa_json *it, const char *value, int len)
|
||||||
|
{
|
||||||
|
FILE *file = c->file;
|
||||||
|
struct spa_json sub;
|
||||||
|
int count = 0;
|
||||||
|
char key[1024];
|
||||||
|
|
||||||
|
if (value == NULL) {
|
||||||
|
fprintf(file, "null");
|
||||||
|
} else if (spa_json_is_array(value, len)) {
|
||||||
|
fprintf(file, "[");
|
||||||
|
spa_json_enter(it, &sub);
|
||||||
|
indent += c->indent;
|
||||||
|
while ((len = spa_json_next(&sub, &value)) > 0) {
|
||||||
|
fprintf(file, "%s%s%*s", count++ > 0 ? "," : "",
|
||||||
|
c->sep, indent, "");
|
||||||
|
dump(c, indent, &sub, value, len);
|
||||||
|
}
|
||||||
|
indent -= c->indent;
|
||||||
|
fprintf(file, "%s%*s]", count > 0 ? c->sep : "",
|
||||||
|
count > 0 ? indent : 0, "");
|
||||||
|
} else if (spa_json_is_object(value, len)) {
|
||||||
|
fprintf(file, "{");
|
||||||
|
spa_json_enter(it, &sub);
|
||||||
|
indent += c->indent;
|
||||||
|
while (spa_json_get_string(&sub, key, sizeof(key)) > 0) {
|
||||||
|
fprintf(file, "%s%s%*s",
|
||||||
|
count++ > 0 ? "," : "",
|
||||||
|
c->sep, indent, "");
|
||||||
|
encode_string(file, key, strlen(key));
|
||||||
|
fprintf(file, ": ");
|
||||||
|
if ((len = spa_json_next(&sub, &value)) <= 0)
|
||||||
|
break;
|
||||||
|
dump(c, indent, &sub, value, len);
|
||||||
|
}
|
||||||
|
indent -= c->indent;
|
||||||
|
fprintf(file, "%s%*s}", count > 0 ? c->sep : "",
|
||||||
|
count > 0 ? indent : 0, "");
|
||||||
|
} else if (spa_json_is_string(value, len) ||
|
||||||
|
spa_json_is_null(value, len) ||
|
||||||
|
spa_json_is_bool(value, len) ||
|
||||||
|
spa_json_is_int(value, len) ||
|
||||||
|
spa_json_is_float(value, len)) {
|
||||||
|
fprintf(file, "%.*s", len, value);
|
||||||
|
} else {
|
||||||
|
encode_string(file, value, len);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT
|
||||||
int pw_properties_serialize_dict(FILE *f, const struct spa_dict *dict, uint32_t flags)
|
int pw_properties_serialize_dict(FILE *f, const struct spa_dict *dict, uint32_t flags)
|
||||||
{
|
{
|
||||||
const struct spa_dict_item *it;
|
const struct spa_dict_item *it;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char key[1024];
|
struct dump_config cfg = {
|
||||||
|
.file = f,
|
||||||
|
.indent = flags & PW_PROPERTIES_FLAG_NL ? 2 : 0,
|
||||||
|
.sep = flags & PW_PROPERTIES_FLAG_NL ? "\n" : " "
|
||||||
|
};
|
||||||
|
const char *enc = flags & PW_PROPERTIES_FLAG_ARRAY ? "[]" : "{}";
|
||||||
|
|
||||||
|
if (SPA_FLAG_IS_SET(flags, PW_PROPERTIES_FLAG_ENCLOSE))
|
||||||
|
fprintf(f, "%c", enc[0]);
|
||||||
|
|
||||||
spa_dict_for_each(it, dict) {
|
spa_dict_for_each(it, dict) {
|
||||||
size_t len = it->value ? strlen(it->value) : 0;
|
char key[1024];
|
||||||
|
int len = it->value ? strlen(it->value) : 0;
|
||||||
|
const char *value;
|
||||||
|
|
||||||
if (spa_json_encode_string(key, sizeof(key)-1, it->key) >= (int)sizeof(key)-1)
|
fprintf(f, "%s%s%*s", count == 0 ? "" : ",", cfg.sep, cfg.indent, "");
|
||||||
continue;
|
|
||||||
|
|
||||||
fprintf(f, "%s%s %s: ",
|
if (!(flags & PW_PROPERTIES_FLAG_ARRAY)) {
|
||||||
count == 0 ? "" : ",",
|
if (spa_json_encode_string(key, sizeof(key)-1, it->key) >= (int)sizeof(key)-1)
|
||||||
flags & PW_PROPERTIES_FLAG_NL ? "\n" : "",
|
continue;
|
||||||
key);
|
fprintf(f, "%s: ", key);
|
||||||
|
}
|
||||||
|
|
||||||
if (it->value == NULL) {
|
if (it->value == NULL) {
|
||||||
fprintf(f, "null");
|
fprintf(f, "null");
|
||||||
|
} else if (SPA_FLAG_IS_SET(flags, PW_PROPERTIES_FLAG_RECURSE)) {
|
||||||
|
struct spa_json sub;
|
||||||
|
spa_json_init(&sub, it->value, len);
|
||||||
|
if ((len = spa_json_next(&sub, &value)) <= 0)
|
||||||
|
break;
|
||||||
|
dump(&cfg, cfg.indent, &sub, value, len);
|
||||||
} else if (spa_json_is_null(it->value, len) ||
|
} else if (spa_json_is_null(it->value, len) ||
|
||||||
spa_json_is_float(it->value, len) ||
|
spa_json_is_float(it->value, len) ||
|
||||||
spa_json_is_bool(it->value, len) ||
|
spa_json_is_bool(it->value, len) ||
|
||||||
|
|
@ -705,9 +777,11 @@ int pw_properties_serialize_dict(FILE *f, const struct spa_dict *dict, uint32_t
|
||||||
spa_json_is_string(it->value, len)) {
|
spa_json_is_string(it->value, len)) {
|
||||||
fprintf(f, "%s", it->value);
|
fprintf(f, "%s", it->value);
|
||||||
} else {
|
} else {
|
||||||
encode_string(f, it->value);
|
encode_string(f, it->value, len);
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
if (SPA_FLAG_IS_SET(flags, PW_PROPERTIES_FLAG_ENCLOSE))
|
||||||
|
fprintf(f, "%s%c", cfg.sep, enc[1]);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,10 @@ pw_properties_get_bool(const struct pw_properties *properties, const char *key,
|
||||||
const char *
|
const char *
|
||||||
pw_properties_iterate(const struct pw_properties *properties, void **state);
|
pw_properties_iterate(const struct pw_properties *properties, void **state);
|
||||||
|
|
||||||
#define PW_PROPERTIES_FLAG_NL (1<<0)
|
#define PW_PROPERTIES_FLAG_NL (1<<0)
|
||||||
|
#define PW_PROPERTIES_FLAG_RECURSE (1<<1)
|
||||||
|
#define PW_PROPERTIES_FLAG_ENCLOSE (1<<2)
|
||||||
|
#define PW_PROPERTIES_FLAG_ARRAY (1<<3)
|
||||||
int pw_properties_serialize_dict(FILE *f, const struct spa_dict *dict, uint32_t flags);
|
int pw_properties_serialize_dict(FILE *f, const struct spa_dict *dict, uint32_t flags);
|
||||||
|
|
||||||
static inline bool pw_properties_parse_bool(const char *value) {
|
static inline bool pw_properties_parse_bool(const char *value) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue