mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	json: move utils to separate file
The core json functions are in json.h and the more highlevel functions building on them are in json-utils.h
This commit is contained in:
		
							parent
							
								
									ce390d5b22
								
							
						
					
					
						commit
						a05b8b0f7b
					
				
					 2 changed files with 172 additions and 119 deletions
				
			
		
							
								
								
									
										170
									
								
								spa/include/spa/utils/json-utils.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								spa/include/spa/utils/json-utils.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,170 @@
 | 
			
		|||
/* Simple Plugin API */
 | 
			
		||||
/* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */
 | 
			
		||||
/* SPDX-License-Identifier: MIT */
 | 
			
		||||
 | 
			
		||||
#ifndef SPA_UTILS_JSON_UTILS_H
 | 
			
		||||
#define SPA_UTILS_JSON_UTILS_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#else
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <float.h>
 | 
			
		||||
 | 
			
		||||
#include <spa/utils/json.h>
 | 
			
		||||
 | 
			
		||||
/** \defgroup spa_json_utils JSON Utils
 | 
			
		||||
 * Relaxed JSON variant parsing Utils
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \addtogroup spa_json
 | 
			
		||||
 * \{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_begin(struct spa_json * iter, const char *data, size_t size, const char **val)
 | 
			
		||||
{
 | 
			
		||||
	spa_json_init(iter, data, size);
 | 
			
		||||
	return spa_json_next(iter, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* float */
 | 
			
		||||
static inline int spa_json_get_float(struct spa_json *iter, float *res)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	return spa_json_parse_float(value, len, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* int */
 | 
			
		||||
static inline int spa_json_get_int(struct spa_json *iter, int *res)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	return spa_json_parse_int(value, len, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* bool */
 | 
			
		||||
static inline int spa_json_get_bool(struct spa_json *iter, bool *res)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	return spa_json_parse_bool(value, len, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* string */
 | 
			
		||||
static inline int spa_json_get_string(struct spa_json *iter, char *res, int maxlen)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	return spa_json_parse_stringn(value, len, res, maxlen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_enter_container(struct spa_json *iter, struct spa_json *sub, char type)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	if (!spa_json_is_container(value, len))
 | 
			
		||||
		return -EPROTO;
 | 
			
		||||
	if (*value != type)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	spa_json_enter(iter, sub);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_begin_container(struct spa_json * iter,
 | 
			
		||||
		const char *data, size_t size, char type, bool relax)
 | 
			
		||||
{
 | 
			
		||||
	int res;
 | 
			
		||||
	spa_json_init(iter, data, size);
 | 
			
		||||
	res = spa_json_enter_container(iter, iter, type);
 | 
			
		||||
	if (res == -EPROTO && relax)
 | 
			
		||||
		spa_json_init(iter, data, size);
 | 
			
		||||
	else if (res <= 0)
 | 
			
		||||
		return res;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * Return length of container at current position, starting at \a value.
 | 
			
		||||
 *
 | 
			
		||||
 * \return Length of container including {} or [], or 0 on error.
 | 
			
		||||
 */
 | 
			
		||||
static inline int spa_json_container_len(struct spa_json *iter, const char *value, int len SPA_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
	const char *val;
 | 
			
		||||
	struct spa_json sub;
 | 
			
		||||
	int res;
 | 
			
		||||
	spa_json_enter(iter, &sub);
 | 
			
		||||
	while ((res = spa_json_next(&sub, &val)) > 0);
 | 
			
		||||
	if (res < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	return sub.cur + 1 - value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* object */
 | 
			
		||||
static inline int spa_json_enter_object(struct spa_json *iter, struct spa_json *sub)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_enter_container(iter, sub, '{');
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_begin_object_relax(struct spa_json * iter, const char *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_begin_container(iter, data, size, '{', true);
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_begin_object(struct spa_json * iter, const char *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_begin_container(iter, data, size, '{', false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_object_next(struct spa_json *iter, char *key, int maxkeylen, const char **value)
 | 
			
		||||
{
 | 
			
		||||
	int res1, res2;
 | 
			
		||||
	while (true) {
 | 
			
		||||
		res1 = spa_json_get_string(iter, key, maxkeylen);
 | 
			
		||||
		if (res1 <= 0 && res1 != -ENOSPC)
 | 
			
		||||
			return res1;
 | 
			
		||||
		res2 = spa_json_next(iter, value);
 | 
			
		||||
		if (res2 <= 0 || res1 != -ENOSPC)
 | 
			
		||||
			return res2;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* array */
 | 
			
		||||
static inline int spa_json_enter_array(struct spa_json *iter, struct spa_json *sub)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_enter_container(iter, sub, '[');
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_begin_array_relax(struct spa_json * iter, const char *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_begin_container(iter, data, size, '[', true);
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_begin_array(struct spa_json * iter, const char *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_begin_container(iter, data, size, '[', false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \}
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
} /* extern "C" */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* SPA_UTILS_JSON_UTILS_H */
 | 
			
		||||
| 
						 | 
				
			
			@ -308,7 +308,7 @@ error:
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return it there was a parse error, and its possible location.
 | 
			
		||||
 * Return if there was a parse error, and its possible location.
 | 
			
		||||
 *
 | 
			
		||||
 * \since 1.1.0
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -358,95 +358,22 @@ static inline bool spa_json_get_error(struct spa_json *iter, const char *start,
 | 
			
		|||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_begin(struct spa_json * iter, const char *data, size_t size, const char **val)
 | 
			
		||||
{
 | 
			
		||||
	spa_json_init(iter, data, size);
 | 
			
		||||
	return spa_json_next(iter, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_is_container(const char *val, int len)
 | 
			
		||||
{
 | 
			
		||||
	return len > 0 && (*val == '{'  || *val == '[');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_enter_container(struct spa_json *iter, struct spa_json *sub, char type)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	if (!spa_json_is_container(value, len))
 | 
			
		||||
		return -EPROTO;
 | 
			
		||||
	if (*value != type)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	spa_json_enter(iter, sub);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_begin_container(struct spa_json * iter,
 | 
			
		||||
		const char *data, size_t size, char type, bool relax)
 | 
			
		||||
{
 | 
			
		||||
	int res;
 | 
			
		||||
	spa_json_init(iter, data, size);
 | 
			
		||||
	res = spa_json_enter_container(iter, iter, type);
 | 
			
		||||
	if (res == -EPROTO && relax)
 | 
			
		||||
		spa_json_init(iter, data, size);
 | 
			
		||||
	else if (res <= 0)
 | 
			
		||||
		return res;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * Return length of container at current position, starting at \a value.
 | 
			
		||||
 *
 | 
			
		||||
 * \return Length of container including {} or [], or 0 on error.
 | 
			
		||||
 */
 | 
			
		||||
static inline int spa_json_container_len(struct spa_json *iter, const char *value, int len SPA_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
	const char *val;
 | 
			
		||||
	struct spa_json sub;
 | 
			
		||||
	int res;
 | 
			
		||||
	spa_json_enter(iter, &sub);
 | 
			
		||||
	while ((res = spa_json_next(&sub, &val)) > 0);
 | 
			
		||||
	if (res < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	return sub.cur + 1 - value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* object */
 | 
			
		||||
static inline int spa_json_is_object(const char *val, int len)
 | 
			
		||||
{
 | 
			
		||||
	return len > 0 && *val == '{';
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_enter_object(struct spa_json *iter, struct spa_json *sub)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_enter_container(iter, sub, '{');
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_begin_object_relax(struct spa_json * iter, const char *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_begin_container(iter, data, size, '{', true);
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_begin_object(struct spa_json * iter, const char *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_begin_container(iter, data, size, '{', false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* array */
 | 
			
		||||
static inline bool spa_json_is_array(const char *val, int len)
 | 
			
		||||
{
 | 
			
		||||
	return len > 0 && *val == '[';
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_enter_array(struct spa_json *iter, struct spa_json *sub)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_enter_container(iter, sub, '[');
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_begin_array_relax(struct spa_json * iter, const char *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_begin_container(iter, data, size, '[', true);
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_begin_array(struct spa_json * iter, const char *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return spa_json_begin_container(iter, data, size, '[', false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* null */
 | 
			
		||||
static inline bool spa_json_is_null(const char *val, int len)
 | 
			
		||||
| 
						 | 
				
			
			@ -483,14 +410,6 @@ static inline bool spa_json_is_float(const char *val, int len)
 | 
			
		|||
	float dummy;
 | 
			
		||||
	return spa_json_parse_float(val, len, &dummy);
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_get_float(struct spa_json *iter, float *res)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	return spa_json_parse_float(value, len, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline char *spa_json_format_float(char *str, int size, float val)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -525,14 +444,6 @@ static inline bool spa_json_is_int(const char *val, int len)
 | 
			
		|||
	int dummy;
 | 
			
		||||
	return spa_json_parse_int(val, len, &dummy);
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_get_int(struct spa_json *iter, int *res)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	return spa_json_parse_int(value, len, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* bool */
 | 
			
		||||
static inline bool spa_json_is_true(const char *val, int len)
 | 
			
		||||
| 
						 | 
				
			
			@ -558,14 +469,6 @@ static inline int spa_json_parse_bool(const char *val, int len, bool *result)
 | 
			
		|||
		return 1;
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
static inline int spa_json_get_bool(struct spa_json *iter, bool *res)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	return spa_json_parse_bool(value, len, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* string */
 | 
			
		||||
static inline bool spa_json_is_string(const char *val, int len)
 | 
			
		||||
| 
						 | 
				
			
			@ -660,15 +563,6 @@ static inline int spa_json_parse_string(const char *val, int len, char *result)
 | 
			
		|||
	return spa_json_parse_stringn(val, len, result, len+1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_get_string(struct spa_json *iter, char *res, int maxlen)
 | 
			
		||||
{
 | 
			
		||||
	const char *value;
 | 
			
		||||
	int len;
 | 
			
		||||
	if ((len = spa_json_next(iter, &value)) <= 0)
 | 
			
		||||
		return len;
 | 
			
		||||
	return spa_json_parse_stringn(value, len, res, maxlen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_encode_string(char *str, int size, const char *val)
 | 
			
		||||
{
 | 
			
		||||
	int len = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -714,18 +608,7 @@ static inline int spa_json_encode_string(char *str, int size, const char *val)
 | 
			
		|||
	return len-1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int spa_json_object_next(struct spa_json *iter, char *key, int maxkeylen, const char **value)
 | 
			
		||||
{
 | 
			
		||||
	int res1, res2;
 | 
			
		||||
	while (true) {
 | 
			
		||||
		res1 = spa_json_get_string(iter, key, maxkeylen);
 | 
			
		||||
		if (res1 <= 0 && res1 != -ENOSPC)
 | 
			
		||||
			return res1;
 | 
			
		||||
		res2 = spa_json_next(iter, value);
 | 
			
		||||
		if (res2 <= 0 || res1 != -ENOSPC)
 | 
			
		||||
			return res2;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#include <spa/utils/json-utils.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue