Blame shared/nm-glib-aux/nm-value-type.h

Packit Service b23acc
// SPDX-License-Identifier: LGPL-2.1+
Packit Service b23acc
/*
Packit Service b23acc
 * Copyright (C) 2019 Red Hat, Inc.
Packit Service b23acc
 */
Packit Service b23acc
Packit Service b23acc
#ifndef __NM_VALUE_TYPE_H__
Packit Service b23acc
#define __NM_VALUE_TYPE_H__
Packit Service b23acc
Packit Service b23acc
typedef enum {
Packit Service b23acc
	NM_VALUE_TYPE_UNSPEC = 1,
Packit Service b23acc
	NM_VALUE_TYPE_BOOL   = 2,
Packit Service b23acc
	NM_VALUE_TYPE_INT32  = 3,
Packit Service b23acc
	NM_VALUE_TYPE_INT    = 4,
Packit Service b23acc
	NM_VALUE_TYPE_STRING = 5,
Packit Service b23acc
} NMValueType;
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
#ifdef NM_VALUE_TYPE_DEFINE_FUNCTIONS
Packit Service b23acc
Packit Service b23acc
typedef union {
Packit Service b23acc
	bool             v_bool;
Packit Service b23acc
	gint32           v_int32;
Packit Service b23acc
	int              v_int;
Packit Service b23acc
	const char      *v_string;
Packit Service b23acc
Packit Service b23acc
	/* for convenience, also let the union contain other pointer types. These are
Packit Service b23acc
	 * for NM_VALUE_TYPE_UNSPEC. */
Packit Service b23acc
	gconstpointer   *v_ptr;
Packit Service b23acc
	const GPtrArray *v_ptrarray;
Packit Service b23acc
Packit Service b23acc
} NMValueTypUnion;
Packit Service b23acc
Packit Service b23acc
/* Set the NMValueTypUnion. You can also assign the member directly.
Packit Service b23acc
 * The only purpose of this is that it also returns a pointer to the
Packit Service b23acc
 * union. So, you can do
Packit Service b23acc
 *
Packit Service b23acc
 *   ptr = NM_VALUE_TYP_UNION_SET (&value_typ_union_storage, v_bool, TRUE);
Packit Service b23acc
 */
Packit Service b23acc
#define NM_VALUE_TYP_UNION_SET(_arg, _type, _val) \
Packit Service b23acc
	({ \
Packit Service b23acc
		NMValueTypUnion *const _arg2 = (_arg); \
Packit Service b23acc
		\
Packit Service b23acc
		*_arg2 = (NMValueTypUnion) { \
Packit Service b23acc
			._type = (_val), \
Packit Service b23acc
		}; \
Packit Service b23acc
		_arg2; \
Packit Service b23acc
	})
Packit Service b23acc
Packit Service b23acc
typedef struct {
Packit Service b23acc
	bool has;
Packit Service b23acc
	NMValueTypUnion val;
Packit Service b23acc
} NMValueTypUnioMaybe;
Packit Service b23acc
Packit Service b23acc
#define NM_VALUE_TYP_UNIO_MAYBE_SET(_arg, _type, _val) \
Packit Service b23acc
	({ \
Packit Service b23acc
		NMValueTypUnioMaybe *const _arg2 = (_arg); \
Packit Service b23acc
		\
Packit Service b23acc
		*_arg2 = (NMValueTypUnioMaybe) { \
Packit Service b23acc
			.has       = TRUE, \
Packit Service b23acc
			.val._type = (_val), \
Packit Service b23acc
		}; \
Packit Service b23acc
		_arg2; \
Packit Service b23acc
	})
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static inline int
Packit Service b23acc
nm_value_type_cmp (NMValueType value_type,
Packit Service b23acc
                   gconstpointer p_a,
Packit Service b23acc
                   gconstpointer p_b)
Packit Service b23acc
{
Packit Service b23acc
	switch (value_type) {
Packit Service b23acc
	case NM_VALUE_TYPE_BOOL:   NM_CMP_DIRECT (*((const bool   *) p_a), *((const bool   *) p_b)); return 0;
Packit Service b23acc
	case NM_VALUE_TYPE_INT32:  NM_CMP_DIRECT (*((const gint32 *) p_a), *((const gint32 *) p_b)); return 0;
Packit Service b23acc
	case NM_VALUE_TYPE_INT:    NM_CMP_DIRECT (*((const int    *) p_a), *((const int    *) p_b)); return 0;
Packit Service b23acc
	case NM_VALUE_TYPE_STRING: return nm_strcmp0 (*((const char *const*) p_a), *((const char *const*) p_b));
Packit Service b23acc
	case NM_VALUE_TYPE_UNSPEC:
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
	nm_assert_not_reached ();
Packit Service b23acc
	return 0;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static inline gboolean
Packit Service b23acc
nm_value_type_equal (NMValueType value_type,
Packit Service b23acc
                     gconstpointer p_a,
Packit Service b23acc
                     gconstpointer p_b)
Packit Service b23acc
{
Packit Service b23acc
	return nm_value_type_cmp (value_type, p_a, p_b) == 0;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static inline void
Packit Service b23acc
nm_value_type_copy (NMValueType value_type,
Packit Service b23acc
                    gpointer dst,
Packit Service b23acc
                    gconstpointer src)
Packit Service b23acc
{
Packit Service b23acc
	switch (value_type) {
Packit Service b23acc
	case NM_VALUE_TYPE_BOOL:   (*((bool   *) dst) = *((const bool   *) src)); return;
Packit Service b23acc
	case NM_VALUE_TYPE_INT32:  (*((gint32 *) dst) = *((const gint32 *) src)); return;
Packit Service b23acc
	case NM_VALUE_TYPE_INT:    (*((int    *) dst) = *((const int    *) src)); return;
Packit Service b23acc
	case NM_VALUE_TYPE_STRING:
Packit Service b23acc
		/* self assignment safe! */
Packit Service b23acc
		if (*((char **) dst) != *((const char *const*) src)) {
Packit Service b23acc
			g_free (*((char **) dst));
Packit Service b23acc
			*((char **) dst) = g_strdup (*((const char *const*) src));
Packit Service b23acc
		}
Packit Service b23acc
		return;
Packit Service b23acc
	case NM_VALUE_TYPE_UNSPEC:
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
	nm_assert_not_reached ();
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static inline void
Packit Service b23acc
nm_value_type_get_from_variant (NMValueType value_type,
Packit Service b23acc
                                gpointer dst,
Packit Service b23acc
                                GVariant *variant,
Packit Service b23acc
                                gboolean clone)
Packit Service b23acc
{
Packit Service b23acc
	switch (value_type) {
Packit Service b23acc
	case NM_VALUE_TYPE_BOOL:   *((bool   *) dst) = g_variant_get_boolean (variant); return;
Packit Service b23acc
	case NM_VALUE_TYPE_INT32:  *((gint32 *) dst) = g_variant_get_int32 (variant);   return;
Packit Service b23acc
	case NM_VALUE_TYPE_STRING:
Packit Service b23acc
		if (clone) {
Packit Service b23acc
			g_free (*((char **) dst));
Packit Service b23acc
			*((char **) dst) = g_variant_dup_string (variant, NULL);
Packit Service b23acc
		} else {
Packit Service b23acc
			/* we don't clone the string, nor free the previous value. */
Packit Service b23acc
			*((const char **) dst) = g_variant_get_string (variant, NULL);
Packit Service b23acc
		}
Packit Service b23acc
		return;
Packit Service b23acc
Packit Service b23acc
	case NM_VALUE_TYPE_INT:
Packit Service b23acc
		/* "int" also does not have a define variant type, because it's not
Packit Service b23acc
		 * clear how many bits we would need. */
Packit Service b23acc
Packit Service b23acc
		/* fall-through */
Packit Service b23acc
	case NM_VALUE_TYPE_UNSPEC:
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
	nm_assert_not_reached ();
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static inline GVariant *
Packit Service b23acc
nm_value_type_to_variant (NMValueType value_type,
Packit Service b23acc
                          gconstpointer src)
Packit Service b23acc
{
Packit Service b23acc
	const char *v_string;
Packit Service b23acc
Packit Service b23acc
	switch (value_type) {
Packit Service b23acc
	case NM_VALUE_TYPE_BOOL:   return g_variant_new_boolean (*((const bool   *) src));
Packit Service b23acc
	case NM_VALUE_TYPE_INT32:  return g_variant_new_int32   (*((const gint32 *) src));;
Packit Service b23acc
	case NM_VALUE_TYPE_STRING:
Packit Service b23acc
		v_string = *((const char *const*) src);
Packit Service b23acc
		return v_string ? g_variant_new_string (v_string) : NULL;
Packit Service b23acc
Packit Service b23acc
	case NM_VALUE_TYPE_INT:
Packit Service b23acc
		/* "int" also does not have a define variant type, because it's not
Packit Service b23acc
		 * clear how many bits we would need. */
Packit Service b23acc
Packit Service b23acc
		/* fall-through */
Packit Service b23acc
	case NM_VALUE_TYPE_UNSPEC:
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
	nm_assert_not_reached ();
Packit Service b23acc
	return NULL;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static inline const GVariantType *
Packit Service b23acc
nm_value_type_get_variant_type (NMValueType value_type)
Packit Service b23acc
{
Packit Service b23acc
	switch (value_type) {
Packit Service b23acc
	case NM_VALUE_TYPE_BOOL:   return G_VARIANT_TYPE_BOOLEAN;
Packit Service b23acc
	case NM_VALUE_TYPE_INT32:  return G_VARIANT_TYPE_INT32;
Packit Service b23acc
	case NM_VALUE_TYPE_STRING: return G_VARIANT_TYPE_STRING;
Packit Service b23acc
Packit Service b23acc
	case NM_VALUE_TYPE_INT:
Packit Service b23acc
		/* "int" also does not have a define variant type, because it's not
Packit Service b23acc
		 * clear how many bits we would need. */
Packit Service b23acc
Packit Service b23acc
		/* fall-through */
Packit Service b23acc
	case NM_VALUE_TYPE_UNSPEC:
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
	nm_assert_not_reached ();
Packit Service b23acc
	return NULL;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
#endif /* NM_VALUE_TYPE_DEFINE_FUNCTIONS */
Packit Service b23acc
Packit Service b23acc
#endif  /* __NM_VALUE_TYPE_H__ */