mirror of https://github.com/mpv-player/mpv
client API: implement setting options using their native type too
This is only half-implemented: actually the option will first be converted from mpv_node to its native type, then it's converted to a string, and then back to its native type. This is because the option API was made for strings and not anything else. Other than being grossly inelegant, the only downside is probably with string lists and key/value lists, which don't escape strings containing syntax elements correctly.
This commit is contained in:
parent
a6ebfbea69
commit
942fb43d0c
|
@ -28,6 +28,8 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libmpv/client.h"
|
||||
|
||||
#include "talloc.h"
|
||||
|
||||
#include "m_config.h"
|
||||
|
@ -606,6 +608,35 @@ int m_config_set_option(struct m_config *config, struct bstr name,
|
|||
return m_config_set_option_ext(config, name, param, 0);
|
||||
}
|
||||
|
||||
int m_config_set_option_node(struct m_config *config, bstr name,
|
||||
struct mpv_node *data, int flags)
|
||||
{
|
||||
char *value = NULL;
|
||||
if (data->format == MPV_FORMAT_STRING) {
|
||||
value = *(char **)data;
|
||||
} else {
|
||||
// This is pretty lame, but the simplest for now. It will fail very
|
||||
// hard for string lists with items that contain ',' characters.
|
||||
union m_option_value val = {0};
|
||||
const struct m_option *opt = m_config_get_option(config, name);
|
||||
if (!opt)
|
||||
return M_OPT_UNKNOWN;
|
||||
if (m_option_set_node(opt, &val, data) < 0)
|
||||
return M_OPT_INVALID;
|
||||
value = m_option_print(opt, &val);
|
||||
m_option_free(opt, &val);
|
||||
}
|
||||
int r;
|
||||
if (value) {
|
||||
r = m_config_set_option_ext(config, name, bstr0(value), flags);
|
||||
} else {
|
||||
r = M_OPT_OUT_OF_RANGE;
|
||||
}
|
||||
if (data->format != MPV_FORMAT_STRING)
|
||||
talloc_free(value);
|
||||
return r;
|
||||
}
|
||||
|
||||
const struct m_option *m_config_get_option(const struct m_config *config,
|
||||
struct bstr name)
|
||||
{
|
||||
|
|
|
@ -139,6 +139,12 @@ static inline int m_config_set_option0(struct m_config *config,
|
|||
return m_config_set_option(config, bstr0(name), bstr0(param));
|
||||
}
|
||||
|
||||
// Same as m_config_set_option_ext(), but set as data using mpv_node.
|
||||
struct mpv_node;
|
||||
int m_config_set_option_node(struct m_config *config, bstr name,
|
||||
struct mpv_node *data, int flags);
|
||||
|
||||
|
||||
int m_config_parse_suboptions(struct m_config *config, char *name,
|
||||
char *subopts);
|
||||
|
||||
|
|
|
@ -508,15 +508,24 @@ int mpv_set_option(mpv_handle *ctx, const char *name, mpv_format format,
|
|||
return err;
|
||||
}
|
||||
} else {
|
||||
if (format != MPV_FORMAT_STRING)
|
||||
const struct m_option *type = get_mp_type(format);
|
||||
if (!type)
|
||||
return MPV_ERROR_OPTION_FORMAT;
|
||||
const char *value = *(char **)data;
|
||||
int err = m_config_set_option0(ctx->mpctx->mconfig, name, value);
|
||||
struct mpv_node tmp;
|
||||
if (format != MPV_FORMAT_NODE) {
|
||||
tmp.format = format;
|
||||
memcpy(&tmp.u, data, type->type->size);
|
||||
format = MPV_FORMAT_NODE;
|
||||
data = &tmp;
|
||||
}
|
||||
int err = m_config_set_option_node(ctx->mpctx->mconfig, bstr0(name),
|
||||
data, 0);
|
||||
switch (err) {
|
||||
case M_OPT_MISSING_PARAM:
|
||||
case M_OPT_INVALID:
|
||||
case M_OPT_OUT_OF_RANGE:
|
||||
return MPV_ERROR_OPTION_ERROR;
|
||||
case M_OPT_OUT_OF_RANGE:
|
||||
return MPV_ERROR_OPTION_FORMAT;
|
||||
case M_OPT_UNKNOWN:
|
||||
return MPV_ERROR_OPTION_NOT_FOUND;
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue