shared: merge nm-glib-aux/nm-json.[hc] into nm-json-aux.[hc]

They serve a similar purpose.

Previously, nm-json-aux.h contained the virtual function table for accessing
the dynamically loaded libjansson. But there is no reason why our own
helper functions from nm-json.h cannot be there too.
This commit is contained in:
Thomas Haller 2020-07-01 19:26:33 +02:00
parent bbb1f5df2f
commit 4a7da1ca4b
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
12 changed files with 392 additions and 413 deletions

View file

@ -403,8 +403,6 @@ shared_nm_glib_aux_libnm_glib_aux_la_SOURCES = \
shared/nm-glib-aux/nm-jansson.h \
shared/nm-glib-aux/nm-json-aux.c \
shared/nm-glib-aux/nm-json-aux.h \
shared/nm-glib-aux/nm-json.c \
shared/nm-glib-aux/nm-json.h \
shared/nm-glib-aux/nm-keyfile-aux.c \
shared/nm-glib-aux/nm-keyfile-aux.h \
shared/nm-glib-aux/nm-logging-base.c \

View file

@ -11,7 +11,6 @@
#include "nm-errors.h"
#include "nm-utils-private.h"
#include "nm-glib-aux/nm-json.h"
#include "nm-glib-aux/nm-json-aux.h"
#include "nm-core-internal.h"
#include "nm-setting-team.h"

View file

@ -16,7 +16,7 @@
#include <sys/stat.h>
#include <linux/pkt_sched.h>
#include "nm-glib-aux/nm-json.h"
#include "nm-glib-aux/nm-json-aux.h"
#include "nm-glib-aux/nm-str-buf.h"
#include "nm-glib-aux/nm-enum-utils.h"
#include "nm-glib-aux/nm-time-utils.h"

View file

@ -14,7 +14,7 @@
#include "nm-std-aux/c-list-util.h"
#include "nm-glib-aux/nm-enum-utils.h"
#include "nm-glib-aux/nm-str-buf.h"
#include "nm-glib-aux/nm-json.h"
#include "nm-glib-aux/nm-json-aux.h"
#include "systemd/nm-sd-utils-shared.h"
#include "nm-utils.h"

View file

@ -5,7 +5,7 @@
#include "nm-default.h"
#include "nm-glib-aux/nm-json.h"
#include "nm-glib-aux/nm-json-aux.h"
#include "nm-keyfile/nm-keyfile-utils.h"
#include "nm-keyfile/nm-keyfile-internal.h"
#include "nm-simple-connection.h"

View file

@ -8,7 +8,7 @@
#include <linux/pkt_sched.h>
#include <net/if.h>
#include "nm-glib-aux/nm-json.h"
#include "nm-glib-aux/nm-json-aux.h"
#include "nm-core-internal.h"
#include "nm-utils.h"
#include "nm-utils-private.h"

View file

@ -134,7 +134,6 @@ sources = files(
'nm-glib-aux/nm-hash-utils.c',
'nm-glib-aux/nm-io-utils.c',
'nm-glib-aux/nm-json-aux.c',
'nm-glib-aux/nm-json.c',
'nm-glib-aux/nm-keyfile-aux.c',
'nm-glib-aux/nm-logging-base.c',
'nm-glib-aux/nm-random-utils.c',

View file

@ -1,12 +1,14 @@
// SPDX-License-Identifier: LGPL-2.1+
/*
* Copyright (C) 2019 Red Hat, Inc.
* Copyright (C) 2017 - 2019 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-json-aux.h"
#include <dlfcn.h>
/*****************************************************************************/
static void
@ -133,3 +135,129 @@ nm_json_aux_gstr_append_obj_name (GString *gstr,
} else
g_string_append (gstr, ": ");
}
/*****************************************************************************/
typedef struct {
NMJsonVt vt;
void *dl_handle;
} NMJsonVtInternal;
static NMJsonVtInternal *
_nm_json_vt_internal_load (void)
{
NMJsonVtInternal *v;
void *handle = NULL;
int mode;
v = g_new0 (NMJsonVtInternal, 1);
#ifndef JANSSON_SONAME
#define JANSSON_SONAME ""
#endif
mode = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE | RTLD_DEEPBIND;
#if defined (ASAN_BUILD)
/* Address sanitizer is incompatible with RTLD_DEEPBIND. */
mode &= ~RTLD_DEEPBIND;
#endif
if (strlen (JANSSON_SONAME) > 0)
handle = dlopen (JANSSON_SONAME, mode);
if (!handle)
return v;
#define TRY_BIND_SYMBOL(symbol) \
G_STMT_START { \
void *_sym = dlsym (handle, #symbol); \
\
if (!_sym) \
goto fail_symbol; \
v->vt.nm_ ## symbol = _sym; \
} G_STMT_END
TRY_BIND_SYMBOL (json_array);
TRY_BIND_SYMBOL (json_array_append_new);
TRY_BIND_SYMBOL (json_array_get);
TRY_BIND_SYMBOL (json_array_size);
TRY_BIND_SYMBOL (json_delete);
TRY_BIND_SYMBOL (json_dumps);
TRY_BIND_SYMBOL (json_false);
TRY_BIND_SYMBOL (json_integer);
TRY_BIND_SYMBOL (json_integer_value);
TRY_BIND_SYMBOL (json_loads);
TRY_BIND_SYMBOL (json_object);
TRY_BIND_SYMBOL (json_object_del);
TRY_BIND_SYMBOL (json_object_get);
TRY_BIND_SYMBOL (json_object_iter);
TRY_BIND_SYMBOL (json_object_iter_key);
TRY_BIND_SYMBOL (json_object_iter_next);
TRY_BIND_SYMBOL (json_object_iter_value);
TRY_BIND_SYMBOL (json_object_key_to_iter);
TRY_BIND_SYMBOL (json_object_set_new);
TRY_BIND_SYMBOL (json_object_size);
TRY_BIND_SYMBOL (json_string);
TRY_BIND_SYMBOL (json_string_value);
TRY_BIND_SYMBOL (json_true);
v->vt.loaded = TRUE;
v->dl_handle = handle;
return v;
fail_symbol:
dlclose (&handle);
*v = (NMJsonVtInternal) { };
return v;
}
const NMJsonVt *_nm_json_vt_ptr = NULL;
const NMJsonVt *
_nm_json_vt_init (void)
{
NMJsonVtInternal *v;
again:
v = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
if (G_UNLIKELY (!v)) {
v = _nm_json_vt_internal_load ();
if (!g_atomic_pointer_compare_and_exchange ((gpointer *) &_nm_json_vt_ptr, NULL, v)) {
if (v->dl_handle)
dlclose (v->dl_handle);
g_free (v);
goto again;
}
/* we transfer ownership. */
}
nm_assert (v && v == g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr));
return &v->vt;
}
const NMJsonVt *
nmtst_json_vt_reset (gboolean loaded)
{
NMJsonVtInternal *v_old;
NMJsonVtInternal *v;
v_old = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
if (!loaded) {
/* load a fake instance for testing. */
v = g_new0 (NMJsonVtInternal, 1);
} else
v = _nm_json_vt_internal_load ();
if (!g_atomic_pointer_compare_and_exchange ((gpointer *) &_nm_json_vt_ptr, v_old, v))
g_assert_not_reached ();
if (v_old) {
if (v_old->dl_handle)
dlclose (v_old->dl_handle);
g_free ((gpointer *) v_old);
}
return v->vt.loaded ? &v->vt : NULL;
}

View file

@ -1,11 +1,13 @@
// SPDX-License-Identifier: LGPL-2.1+
/*
* Copyright (C) 2019 Red Hat, Inc.
* Copyright (C) 2017 - 2019 Red Hat, Inc.
*/
#ifndef __NM_JSON_AUX_H__
#define __NM_JSON_AUX_H__
#include "nm-value-type.h"
/*****************************************************************************/
static inline GString *
@ -42,8 +44,238 @@ void nm_json_aux_gstr_append_obj_name (GString *gstr,
/*****************************************************************************/
#define NM_JSON_REJECT_DUPLICATES 0x1
typedef enum {
NM_JSON_OBJECT,
NM_JSON_ARRAY,
NM_JSON_STRING,
NM_JSON_INTEGER,
NM_JSON_REAL,
NM_JSON_TRUE,
NM_JSON_FALSE,
NM_JSON_NULL,
} nm_json_type;
typedef struct nm_json_t {
nm_json_type type;
volatile size_t refcount;
} nm_json_t;
typedef long long nm_json_int_t;
#define NM_JSON_ERROR_TEXT_LENGTH 160
#define NM_JSON_ERROR_SOURCE_LENGTH 80
typedef struct nm_json_error_t {
int line;
int column;
int position;
char source[NM_JSON_ERROR_SOURCE_LENGTH];
char text[NM_JSON_ERROR_TEXT_LENGTH];
} nm_json_error_t;
typedef struct {
gboolean loaded;
char *(*nm_json_dumps) (const nm_json_t *json, size_t flags);
const char *(*nm_json_object_iter_key) (void *iter);
const char *(*nm_json_string_value) (const nm_json_t *json);
int (*nm_json_array_append_new) (nm_json_t *json, nm_json_t *value);
int (*nm_json_object_del) (nm_json_t *json, const char *key);
int (*nm_json_object_set_new) (nm_json_t *json, const char *key, nm_json_t *value);
nm_json_int_t (*nm_json_integer_value) (const nm_json_t *json);
nm_json_t *(*nm_json_array) (void);
nm_json_t *(*nm_json_array_get) (const nm_json_t *json, size_t index);
nm_json_t *(*nm_json_false) (void);
nm_json_t *(*nm_json_integer) (nm_json_int_t value);
nm_json_t *(*nm_json_loads) (const char *string, size_t flags, nm_json_error_t *error);
nm_json_t *(*nm_json_object) (void);
nm_json_t *(*nm_json_object_get) (const nm_json_t *json, const char *key);
nm_json_t *(*nm_json_object_iter_value) (void *);
nm_json_t *(*nm_json_string) (const char *value);
nm_json_t *(*nm_json_true) (void);
size_t (*nm_json_array_size) (const nm_json_t *json);
size_t (*nm_json_object_size) (const nm_json_t *json);
void (*nm_json_delete) (nm_json_t *json);
void *(*nm_json_object_iter) (nm_json_t *json);
void *(*nm_json_object_iter_next) (nm_json_t *json, void *iter);
void *(*nm_json_object_key_to_iter) (const char *key);
} NMJsonVt;
extern const NMJsonVt *_nm_json_vt_ptr;
const NMJsonVt *_nm_json_vt_init (void);
static inline const NMJsonVt *
_nm_json_vt (void)
{
const NMJsonVt *vt;
vt = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
if (G_UNLIKELY (!vt)) {
vt = _nm_json_vt_init ();
nm_assert (vt);
}
return vt;
}
static inline const NMJsonVt *
nm_json_vt (void)
{
const NMJsonVt *vt;
vt = _nm_json_vt();
return vt->loaded ? vt : NULL;
}
static inline const NMJsonVt *
nm_json_vt_assert (void)
{
const NMJsonVt *vt;
vt = _nm_json_vt();
nm_assert (vt->loaded);
return vt;
}
const NMJsonVt *nmtst_json_vt_reset (gboolean loaded);
/*****************************************************************************/
#define nm_json_boolean(vt, val) \
((val) ? (vt)->nm_json_true () : (vt)->nm_json_false ())
static inline void
nm_json_decref (const NMJsonVt *vt, nm_json_t *json)
{
/* Our ref-counting is not threadsafe, unlike libjansson's. But we never
* share one json_t instance between threads, and if we would, we would very likely
* wrap a mutex around it. */
if ( json
&& json->refcount != (size_t) -1
&& --json->refcount == 0)
vt->nm_json_delete (json);
}
static inline void
_nm_auto_decref_json (nm_json_t **p_json)
{
if ( *p_json
&& (*p_json)->refcount != (size_t) -1
&& --(*p_json)->refcount == 0)
nm_json_vt ()->nm_json_delete (*p_json);
}
#define nm_auto_decref_json nm_auto(_nm_auto_decref_json)
/*****************************************************************************/
/* the following are implemented as pure macros in jansson.h.
* They can be used directly, however, add a nm_json* variant,
* to make it explict we don't accidentally use jansson ABI. */
#define nm_json_typeof(json) ((json)->type)
#define nm_json_is_object(json) ((json) && nm_json_typeof(json) == NM_JSON_OBJECT)
#define nm_json_is_array(json) ((json) && nm_json_typeof(json) == NM_JSON_ARRAY)
#define nm_json_is_string(json) ((json) && nm_json_typeof(json) == NM_JSON_STRING)
#define nm_json_is_integer(json) ((json) && nm_json_typeof(json) == NM_JSON_INTEGER)
#define nm_json_is_real(json) ((json) && nm_json_typeof(json) == NM_JSON_REAL)
#define nm_json_is_number(json) (nm_json_is_integer(json) || nm_json_is_real(json))
#define nm_json_is_true(json) ((json) && nm_json_typeof(json) == NM_JSON_TRUE)
#define nm_json_is_false(json) ((json) && nm_json_typeof(json) == NM_JSON_FALSE)
#define nm_json_boolean_value nm_json_is_true
#define nm_json_is_boolean(json) (nm_json_is_true(json) || nm_json_is_false(json))
#define nm_json_is_null(json) ((json) && nm_json_typeof(json) == NM_JSON_NULL)
#define nm_json_array_foreach(vt, array, index, value) \
for(index = 0; \
index < vt->nm_json_array_size (array) && (value = vt->nm_json_array_get (array, index)); \
index++)
#define nm_json_object_foreach(vt, object, key, value) \
for(key = vt->nm_json_object_iter_key (vt->nm_json_object_iter (object)); \
key && (value = vt->nm_json_object_iter_value (vt->nm_json_object_key_to_iter (key))); \
key = vt->nm_json_object_iter_key (vt->nm_json_object_iter_next (object, vt->nm_json_object_key_to_iter (key))))
/*****************************************************************************/
static inline int
nm_jansson_json_as_bool (const nm_json_t *elem,
bool *out_val)
{
if (!elem)
return 0;
if (!nm_json_is_boolean (elem))
return -EINVAL;
NM_SET_OUT (out_val, nm_json_boolean_value (elem));
return 1;
}
static inline int
nm_jansson_json_as_int32 (const NMJsonVt *vt,
const nm_json_t *elem,
gint32 *out_val)
{
nm_json_int_t v;
if (!elem)
return 0;
if (!nm_json_is_integer (elem))
return -EINVAL;
v = vt->nm_json_integer_value (elem);
if ( v < (gint64) G_MININT32
|| v > (gint64) G_MAXINT32)
return -ERANGE;
NM_SET_OUT (out_val, v);
return 1;
}
static inline int
nm_jansson_json_as_int (const NMJsonVt *vt,
const nm_json_t *elem,
int *out_val)
{
nm_json_int_t v;
if (!elem)
return 0;
if (!nm_json_is_integer (elem))
return -EINVAL;
v = vt->nm_json_integer_value (elem);
if ( v < (gint64) G_MININT
|| v > (gint64) G_MAXINT)
return -ERANGE;
NM_SET_OUT (out_val, v);
return 1;
}
static inline int
nm_jansson_json_as_string (const NMJsonVt *vt,
const nm_json_t *elem,
const char **out_val)
{
if (!elem)
return 0;
if (!nm_json_is_string (elem))
return -EINVAL;
NM_SET_OUT (out_val, vt->nm_json_string_value (elem));
return 1;
}
/*****************************************************************************/
#ifdef NM_VALUE_TYPE_DEFINE_FUNCTIONS
#include "nm-value-type.h"
static inline void
nm_value_type_to_json (NMValueType value_type,
GString *gstr,
@ -62,8 +294,29 @@ nm_value_type_to_json (NMValueType value_type,
}
nm_assert_not_reached ();
}
#endif
/*****************************************************************************/
static inline gboolean
nm_value_type_from_json (const NMJsonVt *vt,
NMValueType value_type,
const nm_json_t *elem,
gpointer out_val)
{
switch (value_type) {
case NM_VALUE_TYPE_BOOL: return (nm_jansson_json_as_bool (elem, out_val) > 0);
case NM_VALUE_TYPE_INT32: return (nm_jansson_json_as_int32 (vt, elem, out_val) > 0);
case NM_VALUE_TYPE_INT: return (nm_jansson_json_as_int (vt, elem, out_val) > 0);
#endif /* __NM_JSON_AUX_H__ */
/* warning: this overwrites/leaks the previous value. You better have *out_val
* point to uninitialized memory or NULL. */
case NM_VALUE_TYPE_STRING: return (nm_jansson_json_as_string (vt, elem, out_val) > 0);
case NM_VALUE_TYPE_UNSPEC:
break;
}
nm_assert_not_reached ();
return FALSE;
}
#endif /* NM_VALUE_TYPE_DEFINE_FUNCTIONS */
#endif /* __NM_JSON_AUX_H__ */

View file

@ -1,134 +0,0 @@
// SPDX-License-Identifier: LGPL-2.1+
/*
* Copyright (C) 2017, 2018 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-json.h"
#include <dlfcn.h>
typedef struct {
NMJsonVt vt;
void *dl_handle;
} NMJsonVtInternal;
static NMJsonVtInternal *
_nm_json_vt_internal_load (void)
{
NMJsonVtInternal *v;
void *handle = NULL;
int mode;
v = g_new0 (NMJsonVtInternal, 1);
#ifndef JANSSON_SONAME
#define JANSSON_SONAME ""
#endif
mode = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE | RTLD_DEEPBIND;
#if defined (ASAN_BUILD)
/* Address sanitizer is incompatible with RTLD_DEEPBIND. */
mode &= ~RTLD_DEEPBIND;
#endif
if (strlen (JANSSON_SONAME) > 0)
handle = dlopen (JANSSON_SONAME, mode);
if (!handle)
return v;
#define TRY_BIND_SYMBOL(symbol) \
G_STMT_START { \
void *_sym = dlsym (handle, #symbol); \
\
if (!_sym) \
goto fail_symbol; \
v->vt.nm_ ## symbol = _sym; \
} G_STMT_END
TRY_BIND_SYMBOL (json_array);
TRY_BIND_SYMBOL (json_array_append_new);
TRY_BIND_SYMBOL (json_array_get);
TRY_BIND_SYMBOL (json_array_size);
TRY_BIND_SYMBOL (json_delete);
TRY_BIND_SYMBOL (json_dumps);
TRY_BIND_SYMBOL (json_false);
TRY_BIND_SYMBOL (json_integer);
TRY_BIND_SYMBOL (json_integer_value);
TRY_BIND_SYMBOL (json_loads);
TRY_BIND_SYMBOL (json_object);
TRY_BIND_SYMBOL (json_object_del);
TRY_BIND_SYMBOL (json_object_get);
TRY_BIND_SYMBOL (json_object_iter);
TRY_BIND_SYMBOL (json_object_iter_key);
TRY_BIND_SYMBOL (json_object_iter_next);
TRY_BIND_SYMBOL (json_object_iter_value);
TRY_BIND_SYMBOL (json_object_key_to_iter);
TRY_BIND_SYMBOL (json_object_set_new);
TRY_BIND_SYMBOL (json_object_size);
TRY_BIND_SYMBOL (json_string);
TRY_BIND_SYMBOL (json_string_value);
TRY_BIND_SYMBOL (json_true);
v->vt.loaded = TRUE;
v->dl_handle = handle;
return v;
fail_symbol:
dlclose (&handle);
*v = (NMJsonVtInternal) { };
return v;
}
const NMJsonVt *_nm_json_vt_ptr = NULL;
const NMJsonVt *
_nm_json_vt_init (void)
{
NMJsonVtInternal *v;
again:
v = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
if (G_UNLIKELY (!v)) {
v = _nm_json_vt_internal_load ();
if (!g_atomic_pointer_compare_and_exchange ((gpointer *) &_nm_json_vt_ptr, NULL, v)) {
if (v->dl_handle)
dlclose (v->dl_handle);
g_free (v);
goto again;
}
/* we transfer ownership. */
}
nm_assert (v && v == g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr));
return &v->vt;
}
const NMJsonVt *
nmtst_json_vt_reset (gboolean loaded)
{
NMJsonVtInternal *v_old;
NMJsonVtInternal *v;
v_old = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
if (!loaded) {
/* load a fake instance for testing. */
v = g_new0 (NMJsonVtInternal, 1);
} else
v = _nm_json_vt_internal_load ();
if (!g_atomic_pointer_compare_and_exchange ((gpointer *) &_nm_json_vt_ptr, v_old, v))
g_assert_not_reached ();
if (v_old) {
if (v_old->dl_handle)
dlclose (v_old->dl_handle);
g_free ((gpointer *) v_old);
}
return v->vt.loaded ? &v->vt : NULL;
}

View file

@ -1,264 +0,0 @@
// SPDX-License-Identifier: LGPL-2.1+
/*
* Copyright (C) 2017, 2018 Red Hat, Inc.
*/
#ifndef __NM_JSON_H__
#define __NM_JSON_H__
/*****************************************************************************/
#define NM_JSON_REJECT_DUPLICATES 0x1
typedef enum {
NM_JSON_OBJECT,
NM_JSON_ARRAY,
NM_JSON_STRING,
NM_JSON_INTEGER,
NM_JSON_REAL,
NM_JSON_TRUE,
NM_JSON_FALSE,
NM_JSON_NULL,
} nm_json_type;
typedef struct nm_json_t {
nm_json_type type;
volatile size_t refcount;
} nm_json_t;
typedef long long nm_json_int_t;
#define NM_JSON_ERROR_TEXT_LENGTH 160
#define NM_JSON_ERROR_SOURCE_LENGTH 80
typedef struct nm_json_error_t {
int line;
int column;
int position;
char source[NM_JSON_ERROR_SOURCE_LENGTH];
char text[NM_JSON_ERROR_TEXT_LENGTH];
} nm_json_error_t;
typedef struct {
gboolean loaded;
char *(*nm_json_dumps) (const nm_json_t *json, size_t flags);
const char *(*nm_json_object_iter_key) (void *iter);
const char *(*nm_json_string_value) (const nm_json_t *json);
int (*nm_json_array_append_new) (nm_json_t *json, nm_json_t *value);
int (*nm_json_object_del) (nm_json_t *json, const char *key);
int (*nm_json_object_set_new) (nm_json_t *json, const char *key, nm_json_t *value);
nm_json_int_t (*nm_json_integer_value) (const nm_json_t *json);
nm_json_t *(*nm_json_array) (void);
nm_json_t *(*nm_json_array_get) (const nm_json_t *json, size_t index);
nm_json_t *(*nm_json_false) (void);
nm_json_t *(*nm_json_integer) (nm_json_int_t value);
nm_json_t *(*nm_json_loads) (const char *string, size_t flags, nm_json_error_t *error);
nm_json_t *(*nm_json_object) (void);
nm_json_t *(*nm_json_object_get) (const nm_json_t *json, const char *key);
nm_json_t *(*nm_json_object_iter_value) (void *);
nm_json_t *(*nm_json_string) (const char *value);
nm_json_t *(*nm_json_true) (void);
size_t (*nm_json_array_size) (const nm_json_t *json);
size_t (*nm_json_object_size) (const nm_json_t *json);
void (*nm_json_delete) (nm_json_t *json);
void *(*nm_json_object_iter) (nm_json_t *json);
void *(*nm_json_object_iter_next) (nm_json_t *json, void *iter);
void *(*nm_json_object_key_to_iter) (const char *key);
} NMJsonVt;
extern const NMJsonVt *_nm_json_vt_ptr;
const NMJsonVt *_nm_json_vt_init (void);
static inline const NMJsonVt *
_nm_json_vt (void)
{
const NMJsonVt *vt;
vt = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
if (G_UNLIKELY (!vt)) {
vt = _nm_json_vt_init ();
nm_assert (vt);
}
return vt;
}
static inline const NMJsonVt *
nm_json_vt (void)
{
const NMJsonVt *vt;
vt = _nm_json_vt();
return vt->loaded ? vt : NULL;
}
static inline const NMJsonVt *
nm_json_vt_assert (void)
{
const NMJsonVt *vt;
vt = _nm_json_vt();
nm_assert (vt->loaded);
return vt;
}
const NMJsonVt *nmtst_json_vt_reset (gboolean loaded);
/*****************************************************************************/
#define nm_json_boolean(vt, val) \
((val) ? (vt)->nm_json_true () : (vt)->nm_json_false ())
static inline void
nm_json_decref (const NMJsonVt *vt, nm_json_t *json)
{
/* Our ref-counting is not threadsafe, unlike libjansson's. But we never
* share one json_t instance between threads, and if we would, we would very likely
* wrap a mutex around it. */
if ( json
&& json->refcount != (size_t) -1
&& --json->refcount == 0)
vt->nm_json_delete (json);
}
static inline void
_nm_auto_decref_json (nm_json_t **p_json)
{
if ( *p_json
&& (*p_json)->refcount != (size_t) -1
&& --(*p_json)->refcount == 0)
nm_json_vt ()->nm_json_delete (*p_json);
}
#define nm_auto_decref_json nm_auto(_nm_auto_decref_json)
/*****************************************************************************/
/* the following are implemented as pure macros in jansson.h.
* They can be used directly, however, add a nm_json* variant,
* to make it explict we don't accidentally use jansson ABI. */
#define nm_json_typeof(json) ((json)->type)
#define nm_json_is_object(json) ((json) && nm_json_typeof(json) == NM_JSON_OBJECT)
#define nm_json_is_array(json) ((json) && nm_json_typeof(json) == NM_JSON_ARRAY)
#define nm_json_is_string(json) ((json) && nm_json_typeof(json) == NM_JSON_STRING)
#define nm_json_is_integer(json) ((json) && nm_json_typeof(json) == NM_JSON_INTEGER)
#define nm_json_is_real(json) ((json) && nm_json_typeof(json) == NM_JSON_REAL)
#define nm_json_is_number(json) (nm_json_is_integer(json) || nm_json_is_real(json))
#define nm_json_is_true(json) ((json) && nm_json_typeof(json) == NM_JSON_TRUE)
#define nm_json_is_false(json) ((json) && nm_json_typeof(json) == NM_JSON_FALSE)
#define nm_json_boolean_value nm_json_is_true
#define nm_json_is_boolean(json) (nm_json_is_true(json) || nm_json_is_false(json))
#define nm_json_is_null(json) ((json) && nm_json_typeof(json) == NM_JSON_NULL)
#define nm_json_object_foreach(vt, object, key, value) \
for(key = vt->nm_json_object_iter_key (vt->nm_json_object_iter (object)); \
key && (value = vt->nm_json_object_iter_value (vt->nm_json_object_key_to_iter (key))); \
key = vt->nm_json_object_iter_key (vt->nm_json_object_iter_next (object, vt->nm_json_object_key_to_iter (key))))
/*****************************************************************************/
static inline int
nm_jansson_json_as_bool (const nm_json_t *elem,
bool *out_val)
{
if (!elem)
return 0;
if (!nm_json_is_boolean (elem))
return -EINVAL;
NM_SET_OUT (out_val, nm_json_boolean_value (elem));
return 1;
}
static inline int
nm_jansson_json_as_int32 (const NMJsonVt *vt,
const nm_json_t *elem,
gint32 *out_val)
{
nm_json_int_t v;
if (!elem)
return 0;
if (!nm_json_is_integer (elem))
return -EINVAL;
v = vt->nm_json_integer_value (elem);
if ( v < (gint64) G_MININT32
|| v > (gint64) G_MAXINT32)
return -ERANGE;
NM_SET_OUT (out_val, v);
return 1;
}
static inline int
nm_jansson_json_as_int (const NMJsonVt *vt,
const nm_json_t *elem,
int *out_val)
{
nm_json_int_t v;
if (!elem)
return 0;
if (!nm_json_is_integer (elem))
return -EINVAL;
v = vt->nm_json_integer_value (elem);
if ( v < (gint64) G_MININT
|| v > (gint64) G_MAXINT)
return -ERANGE;
NM_SET_OUT (out_val, v);
return 1;
}
static inline int
nm_jansson_json_as_string (const NMJsonVt *vt,
const nm_json_t *elem,
const char **out_val)
{
if (!elem)
return 0;
if (!nm_json_is_string (elem))
return -EINVAL;
NM_SET_OUT (out_val, vt->nm_json_string_value (elem));
return 1;
}
/*****************************************************************************/
#ifdef NM_VALUE_TYPE_DEFINE_FUNCTIONS
#include "nm-glib-aux/nm-value-type.h"
static inline gboolean
nm_value_type_from_json (const NMJsonVt *vt,
NMValueType value_type,
const nm_json_t *elem,
gpointer out_val)
{
switch (value_type) {
case NM_VALUE_TYPE_BOOL: return (nm_jansson_json_as_bool (elem, out_val) > 0);
case NM_VALUE_TYPE_INT32: return (nm_jansson_json_as_int32 (vt, elem, out_val) > 0);
case NM_VALUE_TYPE_INT: return (nm_jansson_json_as_int (vt, elem, out_val) > 0);
/* warning: this overwrites/leaks the previous value. You better have *out_val
* point to uninitialized memory or NULL. */
case NM_VALUE_TYPE_STRING: return (nm_jansson_json_as_string (vt, elem, out_val) > 0);
case NM_VALUE_TYPE_UNSPEC:
break;
}
nm_assert_not_reached ();
return FALSE;
}
#endif /* NM_VALUE_TYPE_DEFINE_FUNCTIONS */
#endif /* __NM_JSON_H__ */

View file

@ -15,7 +15,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include "nm-glib-aux/nm-json.h"
#include "nm-glib-aux/nm-json-aux.h"
#include "nm-utils.h"
#include "nm-setting-connection.h"
#include "nm-setting-wired.h"