tvheadend/src/htsmsg.h

267 lines
7.1 KiB
C

/*
* Functions for manipulating HTS messages
* Copyright (C) 2007 Andreas Öman
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HTSMSG_H_
#define HTSMSG_H_
#include <inttypes.h>
#include "queue.h"
#define HTSMSG_ERR_FIELD_NOT_FOUND -1
#define HTSMSG_ERR_CONVERSION_IMPOSSIBLE -2
TAILQ_HEAD(htsmsg_field_queue, htsmsg_field);
typedef struct htsmsg {
/**
* fields
*/
struct htsmsg_field_queue hm_fields;
/**
* Set if this message is a list, otherwise it is a map.
*/
int hm_islist;
/**
* Data to be free'd when the message is destroyed
*/
const void *hm_data;
} htsmsg_t;
#define HMF_MAP 1
#define HMF_S64 2
#define HMF_STR 3
#define HMF_BIN 4
#define HMF_LIST 5
typedef struct htsmsg_field {
TAILQ_ENTRY(htsmsg_field) hmf_link;
const char *hmf_name;
uint8_t hmf_type;
uint8_t hmf_flags;
#define HMF_ALLOCED 0x1
#define HMF_NAME_ALLOCED 0x2
union {
int64_t s64;
const char *str;
struct {
const char *data;
size_t len;
} bin;
htsmsg_t msg;
} u;
} htsmsg_field_t;
#define hmf_s64 u.s64
#define hmf_msg u.msg
#define hmf_str u.str
#define hmf_bin u.bin.data
#define hmf_binsize u.bin.len
#define htsmsg_get_map_by_field(f) \
((f)->hmf_type == HMF_MAP ? &(f)->hmf_msg : NULL)
#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH(f, &(msg)->hm_fields, hmf_link)
/**
* Create a new map
*/
htsmsg_t *htsmsg_create_map(void);
/**
* Create a new list
*/
htsmsg_t *htsmsg_create_list(void);
/**
* Destroys a message (map or list)
*/
void htsmsg_destroy(htsmsg_t *msg);
/**
* Add an integer field where source is unsigned 32 bit.
*/
void htsmsg_add_u32(htsmsg_t *msg, const char *name, uint32_t u32);
/**
* Add an integer field where source is signed 32 bit.
*/
void htsmsg_add_s32(htsmsg_t *msg, const char *name, int32_t s32);
/**
* Add an integer field where source is signed 64 bit.
*/
void htsmsg_add_s64(htsmsg_t *msg, const char *name, int64_t s64);
/**
* Add a string field.
*/
void htsmsg_add_str(htsmsg_t *msg, const char *name, const char *str);
/**
* Add an field where source is a list or map message.
*/
void htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub);
/**
* Add an field where source is a list or map message.
*
* This function will not strdup() \p name but relies on the caller
* to keep the string allocated for as long as the message is valid.
*/
void htsmsg_add_msg_extname(htsmsg_t *msg, const char *name, htsmsg_t *sub);
/**
* Add an binary field. The data is copied to a malloced storage
*/
void htsmsg_add_bin(htsmsg_t *msg, const char *name, const void *bin,
size_t len);
/**
* Add an binary field. The data is not copied, instead the caller
* is responsible for keeping the data valid for as long as the message
* is around.
*/
void htsmsg_add_binptr(htsmsg_t *msg, const char *name, const void *bin,
size_t len);
/**
* Get an integer as an unsigned 32 bit integer.
*
* @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
* HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or
* out of range for the requested storage.
*/
int htsmsg_get_u32(htsmsg_t *msg, const char *name, uint32_t *u32p);
/**
* Get an integer as an signed 32 bit integer.
*
* @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
* HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or
* out of range for the requested storage.
*/
int htsmsg_get_s32(htsmsg_t *msg, const char *name, int32_t *s32p);
/**
* Get an integer as an signed 64 bit integer.
*
* @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
* HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or
* out of range for the requested storage.
*/
int htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p);
/**
* Get pointer to a binary field. No copying of data is performed.
*
* @param binp Pointer to a void * that will be filled in with a pointer
* to the data
* @param lenp Pointer to a size_t that will be filled with the size of
* the data
*
* @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
* HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not a binary blob.
*/
int htsmsg_get_bin(htsmsg_t *msg, const char *name, const void **binp,
size_t *lenp);
/**
* Get a field of type 'list'. No copying is done.
*
* @return NULL if the field can not be found or not of list type.
* Otherwise a htsmsg is returned.
*/
htsmsg_t *htsmsg_get_list(htsmsg_t *msg, const char *name);
/**
* Get a field of type 'string'. No copying is done.
*
* @return NULL if the field can not be found or not of string type.
* Otherwise a pointer to the data is returned.
*/
const char *htsmsg_get_str(htsmsg_t *msg, const char *name);
/**
* Get a field of type 'map'. No copying is done.
*
* @return NULL if the field can not be found or not of map type.
* Otherwise a htsmsg is returned.
*/
htsmsg_t *htsmsg_get_map(htsmsg_t *msg, const char *name);
/**
* Traverse a hierarchy of htsmsg's to find a specific child.
*/
htsmsg_t *htsmsg_get_map_multi(htsmsg_t *msg, ...);
/**
* Given the field \p f, return a string if it is of type string, otherwise
* return NULL
*/
const char *htsmsg_field_get_string(htsmsg_field_t *f);
/**
* Return the field \p name as an u32.
*
* @return An unsigned 32 bit integer or NULL if the field can not be found
* or if conversion is not possible.
*/
int htsmsg_get_u32_or_default(htsmsg_t *msg, const char *name, uint32_t def);
/**
* Remove the given field called \p name from the message \p msg.
*/
int htsmsg_delete_field(htsmsg_t *msg, const char *name);
/**
* Detach will remove the given field (and only if it is a list or map)
* from the message and make it a 'standalone message'. This means
* the the contents of the sub message will stay valid if the parent is
* destroyed. The caller is responsible for freeing this new message.
*/
htsmsg_t *htsmsg_detach_submsg(htsmsg_field_t *f);
/**
* Print a message to stdout.
*/
void htsmsg_print(htsmsg_t *msg);
/**
* Create a new field. Primarily intended for htsmsg internal functions.
*/
htsmsg_field_t *htsmsg_field_add(htsmsg_t *msg, const char *name,
int type, int flags);
/**
* Clone a message.
*/
htsmsg_t *htsmsg_copy(htsmsg_t *src);
#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH(f, &(msg)->hm_fields, hmf_link)
extern void htsmsg_dtor(htsmsg_t **mp);
#define htsmsg_autodtor(n) htsmsg_t *n __attribute__((cleanup(htsmsg_dtor)))
#endif /* HTSMSG_H_ */