mirror of
https://gitlab.xiph.org/xiph/icecast-common.git
synced 2025-01-03 14:56:36 -05:00
Merge branch 'update-ro' into libigloo
This commit is contained in:
commit
c1b2715265
@ -81,6 +81,8 @@ void igloo_buffer_preallocate(igloo_buffer_t *buffer, size_t request);
|
|||||||
int igloo_buffer_get_data(igloo_buffer_t *buffer, const void **data, size_t *length);
|
int igloo_buffer_get_data(igloo_buffer_t *buffer, const void **data, size_t *length);
|
||||||
|
|
||||||
/* Gets data as a string. The string is '\0'-terminated.
|
/* Gets data as a string. The string is '\0'-terminated.
|
||||||
|
* igloo_ro_stringify(buffer) will also return this buffer.
|
||||||
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* buffery
|
* buffery
|
||||||
* The buffer to operate on.
|
* The buffer to operate on.
|
||||||
|
@ -42,7 +42,7 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
typedef int (*igloo_interface_free_t)(igloo_INTERFACE_BASIC_ARGS);
|
typedef int (*igloo_interface_free_t)(igloo_INTERFACE_BASIC_ARGS);
|
||||||
|
|
||||||
#define igloo_INTERFACE_DESCRIPTION_BASE__VERSION 1
|
#define igloo_INTERFACE_DESCRIPTION_BASE__VERSION 1
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t base_length;
|
size_t base_length;
|
||||||
|
@ -24,6 +24,11 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <igloo/config.h>
|
||||||
|
|
||||||
|
#ifdef IGLOO_CTC_HAVE_STDINT_H
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <igloo/config.h>
|
#include <igloo/config.h>
|
||||||
@ -49,6 +54,106 @@ typedef void (*igloo_ro_free_t)(igloo_ro_t self);
|
|||||||
*/
|
*/
|
||||||
typedef int (*igloo_ro_new_t)(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap);
|
typedef int (*igloo_ro_new_t)(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap);
|
||||||
|
|
||||||
|
/* Type used to store flags for clone operations.
|
||||||
|
*/
|
||||||
|
#ifdef IGLOO_CTC_HAVE_STDINT_H
|
||||||
|
typedef uint_least32_t igloo_ro_cf_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned long int igloo_ro_cf_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No clone flags set. Usefull for variable initialization. */
|
||||||
|
#define igloo_RO_CF_NONE ((igloo_ro_cf_t)0x0000)
|
||||||
|
/* Make a shallow copy of the object */
|
||||||
|
#define igloo_RO_CF_SHALLOW ((igloo_ro_cf_t)0x0001)
|
||||||
|
/* Make a deep copy of the object */
|
||||||
|
#define igloo_RO_CF_DEEP ((igloo_ro_cf_t)0x0002)
|
||||||
|
/* Make a copy of the object that shares part of it's state with the original.
|
||||||
|
* This is similar to using dup() on a POSIX filehandle.
|
||||||
|
* This is useful when interacting with IO.
|
||||||
|
*/
|
||||||
|
#define igloo_RO_CF_DUP ((igloo_ro_cf_t)0x0004)
|
||||||
|
/* Defaults to use if required and allowed is igloo_RO_CF_NONE */
|
||||||
|
#define igloo_RO_CF_DEFAULT (igloo_RO_CF_SHALLOW|igloo_RO_CF_DEEP)
|
||||||
|
|
||||||
|
/* Type uses for callback called when the object should be cloned.
|
||||||
|
*
|
||||||
|
* A clone of the object must never have the same address of the object that was cloned.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* self
|
||||||
|
* The object to clone.
|
||||||
|
* required, allowed
|
||||||
|
* See igloo_ro_clone().
|
||||||
|
* name, associated
|
||||||
|
* See igloo_ro_new().
|
||||||
|
*/
|
||||||
|
typedef igloo_ro_t (*igloo_ro_clone_t)(igloo_ro_t self, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated);
|
||||||
|
|
||||||
|
/* Type used for callback called when the object needs to be converted to another type.
|
||||||
|
*
|
||||||
|
* This callback is not used when a object of the same type is requested.
|
||||||
|
* On that case clone is requested.
|
||||||
|
*
|
||||||
|
* There are two cases that must be handled by the callback:
|
||||||
|
* 0) The object self is of the same type as this callback is set for and type is pointing to different type.
|
||||||
|
* 1) The object self is of any type and type is pointing to the type this callback was set to.
|
||||||
|
*
|
||||||
|
* If the callback can not convert it must return igloo_RO_NULL.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* self
|
||||||
|
* The object to convert.
|
||||||
|
* type
|
||||||
|
* The type to convert to.
|
||||||
|
* required, allowed
|
||||||
|
* See igloo_ro_clone().
|
||||||
|
* name, associated
|
||||||
|
* See igloo_ro_new().
|
||||||
|
*/
|
||||||
|
typedef igloo_ro_t (*igloo_ro_convert_t)(igloo_ro_t self, const igloo_ro_type_t *type, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated);
|
||||||
|
|
||||||
|
/* Type used for callback called when the object needs to be converted to a string.
|
||||||
|
*
|
||||||
|
* This is used mostly for debugging or preseting the object to the user.
|
||||||
|
* The callback is not expected to return a string that can be used to reconstruct the object.
|
||||||
|
*/
|
||||||
|
typedef char * (*igloo_ro_stringify_t)(igloo_ro_t self);
|
||||||
|
|
||||||
|
/* Type used as a result of a compare between objects.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/* The objects could not be compared.
|
||||||
|
* Common cases may be that when one is NULL and the other is not NULL
|
||||||
|
* or when both are of difference types that can not be compared to each other
|
||||||
|
* (e.g. a IO handle and a buffer.)
|
||||||
|
*/
|
||||||
|
igloo_RO_CR__ERROR = -1,
|
||||||
|
/* Both objects represent the same thing but are not the same object.
|
||||||
|
* See also igloo_RO_CR_SAME.
|
||||||
|
*/
|
||||||
|
igloo_RO_CR_EQUAL = 0,
|
||||||
|
/* Both objects are distinct and no other relation can be applied. */
|
||||||
|
igloo_RO_CR_NOTEQUAL,
|
||||||
|
/* Object A is less than object B. */
|
||||||
|
igloo_RO_CR_ALESSTHANB,
|
||||||
|
/* Object A is greather than object B. */
|
||||||
|
igloo_RO_CR_AGREATERTHANB,
|
||||||
|
/* Both objects are the same.
|
||||||
|
* That is then they share the same address in memory.
|
||||||
|
*/
|
||||||
|
igloo_RO_CR_SAME
|
||||||
|
} igloo_ro_cr_t;
|
||||||
|
|
||||||
|
/* Type used for callback called then two objects must be compared.
|
||||||
|
*
|
||||||
|
* Object a is always a object that belongs to the type this callback was set for.
|
||||||
|
* Objects a, and b are not igloo_RO_NULL.
|
||||||
|
* Objects a, and b may be of diffrent type.
|
||||||
|
* Objects a, and b are not the same (See igloo_RO_CR_SAME).
|
||||||
|
*/
|
||||||
|
typedef igloo_ro_cr_t (*igloo_ro_compare_t)(igloo_ro_t a, igloo_ro_t b);
|
||||||
|
|
||||||
/* Meta type used to defined types.
|
/* Meta type used to defined types.
|
||||||
* DO NOT use any of the members in here directly!
|
* DO NOT use any of the members in here directly!
|
||||||
*/
|
*/
|
||||||
@ -60,51 +165,69 @@ typedef int (*igloo_ro_new_t)(igloo_ro_t self, const igloo_ro_type_t *type, va_l
|
|||||||
*/
|
*/
|
||||||
struct igloo_ro_type_tag {
|
struct igloo_ro_type_tag {
|
||||||
/* Size of this control structure */
|
/* Size of this control structure */
|
||||||
size_t control_length;
|
size_t control_length;
|
||||||
/* ABI version of this structure */
|
/* ABI version of this structure */
|
||||||
int control_version;
|
int control_version;
|
||||||
|
|
||||||
/* Total length of the objects to be created */
|
/* Total length of the objects to be created */
|
||||||
size_t type_length;
|
size_t type_length;
|
||||||
/* Name of type */
|
/* Name of type */
|
||||||
const char * type_name;
|
const char * type_name;
|
||||||
|
|
||||||
|
/* STILL UNUSED: Parent type */
|
||||||
|
const igloo_ro_type_t * type_parent;
|
||||||
|
|
||||||
/* Callback to be called on final free() */
|
/* Callback to be called on final free() */
|
||||||
igloo_ro_free_t type_freecb;
|
igloo_ro_free_t type_freecb;
|
||||||
/* Callback to be callback by igloo_ro_new() */
|
/* Callback to be called by igloo_ro_new() */
|
||||||
igloo_ro_new_t type_newcb;
|
igloo_ro_new_t type_newcb;
|
||||||
|
|
||||||
|
/* Callback to be called by igloo_ro_clone() */
|
||||||
|
igloo_ro_clone_t type_clonecb;
|
||||||
|
/* Callback to be called by igloo_ro_convert() */
|
||||||
|
igloo_ro_convert_t type_convertcb;
|
||||||
|
/* Callback to be called by igloo_ro_stringify() */
|
||||||
|
igloo_ro_stringify_t type_stringifycb;
|
||||||
|
/* Callback to be called by igloo_ro_compare() */
|
||||||
|
igloo_ro_compare_t type_comparecb;
|
||||||
};
|
};
|
||||||
struct igloo_ro_base_tag {
|
struct igloo_ro_base_tag {
|
||||||
/* Type of the object */
|
/* Type of the object */
|
||||||
const igloo_ro_type_t * type;
|
const igloo_ro_type_t * type;
|
||||||
/* Reference counters */
|
/* Reference counters */
|
||||||
size_t refc;
|
size_t refc;
|
||||||
size_t wrefc;
|
size_t wrefc;
|
||||||
/* Mutex for igloo_ro_*(). */
|
/* Mutex for igloo_ro_*(). */
|
||||||
igloo_mutex_t lock;
|
igloo_mutex_t lock;
|
||||||
/* Name of the object. */
|
/* Name of the object. */
|
||||||
char * name;
|
char * name;
|
||||||
/* Associated objects */
|
/* Associated objects */
|
||||||
igloo_ro_t associated;
|
igloo_ro_t associated;
|
||||||
|
/* STILL UNUSED: Instance objects */
|
||||||
|
igloo_ro_t instance;
|
||||||
};
|
};
|
||||||
int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap);
|
int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap);
|
||||||
/* ---[ END PRIVATE ]--- */
|
/* ---[ END PRIVATE ]--- */
|
||||||
|
|
||||||
|
igloo_ro_t igloo_RO_TO_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type);
|
||||||
#ifdef IGLOO_CTC_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
|
#ifdef IGLOO_CTC_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
|
||||||
#define igloo_RO__GETBASE(x) (((igloo_ro_t)(x)).subtype__igloo_ro_base_t)
|
#define igloo_RO__GETBASE(x) (((igloo_ro_t)(x)).subtype__igloo_ro_base_t)
|
||||||
#define igloo_RO_NULL ((igloo_ro_t)(igloo_ro_base_t*)NULL)
|
#define igloo_RO_NULL ((igloo_ro_t)(igloo_ro_base_t*)NULL)
|
||||||
#define igloo_RO_IS_NULL(x) (igloo_RO__GETBASE((x)) == NULL)
|
#define igloo_RO_IS_NULL(x) (igloo_RO__GETBASE((x)) == NULL)
|
||||||
#define igloo_RO_TO_TYPE(x,type) (igloo_RO_IS_VALID((x),type) ? ((igloo_ro_t)(x)).subtype__ ## type : NULL)
|
#define igloo_RO_TO_TYPE(x,type) (((igloo_ro_t)igloo_RO_TO_TYPE_raw((x), (igloo_ro__type__ ## type))).subtype__ ## type)
|
||||||
#else
|
#else
|
||||||
#define igloo_RO__GETBASE(x) ((igloo_ro_base_t*)(x))
|
#define igloo_RO__GETBASE(x) ((igloo_ro_base_t*)(x))
|
||||||
#define igloo_RO_NULL NULL
|
#define igloo_RO_NULL NULL
|
||||||
#define igloo_RO_IS_NULL(x) ((x) == NULL)
|
#define igloo_RO_IS_NULL(x) ((x) == NULL)
|
||||||
#define igloo_RO_TO_TYPE(x,type) (igloo_RO_IS_VALID((x),type) ? (type*)(x) : (type*)NULL)
|
#define igloo_RO_TO_TYPE(x,type) ((type*)igloo_RO_TO_TYPE_raw((x), (igloo_ro__type__ ## type)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define igloo_RO_GET_TYPE(x) (igloo_RO__GETBASE((x)) == NULL ? NULL : igloo_RO__GETBASE((x))->type)
|
#define igloo_RO_GET_TYPE(x) (igloo_RO__GETBASE((x)) == NULL ? NULL : igloo_RO__GETBASE((x))->type)
|
||||||
#define igloo_RO_GET_TYPENAME(x) (igloo_RO_GET_TYPE((x)) == NULL ? NULL : igloo_RO_GET_TYPE((x))->type_name)
|
#define igloo_RO_GET_TYPENAME(x) (igloo_RO_GET_TYPE((x)) == NULL ? NULL : igloo_RO_GET_TYPE((x))->type_name)
|
||||||
#define igloo_RO_IS_VALID(x,type) (!igloo_RO_IS_NULL((x)) && igloo_RO_GET_TYPE((x)) == (igloo_ro__type__ ## type) && igloo_RO__GETBASE((x))->refc)
|
int igloo_RO_IS_VALID_raw(igloo_ro_t object, const igloo_ro_type_t *type);
|
||||||
#define igloo_RO_HAS_TYPE(x,type) (!igloo_RO_IS_NULL((x)) && igloo_RO_GET_TYPE((x)) == (type))
|
#define igloo_RO_IS_VALID(x,type) igloo_RO_IS_VALID_raw((x), (igloo_ro__type__ ## type))
|
||||||
|
int igloo_RO_HAS_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type);
|
||||||
|
#define igloo_RO_HAS_TYPE(x,type) igloo_RO_HAS_TYPE_raw((x), (type))
|
||||||
|
|
||||||
/* Create a new refobject
|
/* Create a new refobject
|
||||||
* The type argument gives the type for the new object,
|
* The type argument gives the type for the new object,
|
||||||
@ -112,12 +235,12 @@ int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_l
|
|||||||
* the associated refobject is given by associated.
|
* the associated refobject is given by associated.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated);
|
igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated);
|
||||||
#define igloo_ro_new_raw(type, name, associated) igloo_RO_TO_TYPE(igloo_ro_new__raw((igloo_ro__type__ ## type), (name), (associated)), type)
|
#define igloo_ro_new_raw(type, name, associated) igloo_RO_TO_TYPE(igloo_ro_new__raw((igloo_ro__type__ ## type), (name), (associated)), type)
|
||||||
|
|
||||||
igloo_ro_t igloo_ro_new__simple(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated, ...);
|
igloo_ro_t igloo_ro_new__simple(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated, ...);
|
||||||
#define igloo_ro_new(type, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), NULL, igloo_RO_NULL, ## __VA_ARGS__), type)
|
#define igloo_ro_new(type, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), NULL, igloo_RO_NULL, ## __VA_ARGS__), type)
|
||||||
#define igloo_ro_new_ext(type, name, associated, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), (name), (associated), ## __VA_ARGS__), type)
|
#define igloo_ro_new_ext(type, name, associated, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), (name), (associated), ## __VA_ARGS__), type)
|
||||||
|
|
||||||
/* This increases the reference counter of the object */
|
/* This increases the reference counter of the object */
|
||||||
int igloo_ro_ref(igloo_ro_t self);
|
int igloo_ro_ref(igloo_ro_t self);
|
||||||
@ -134,8 +257,72 @@ int igloo_ro_weak_unref(igloo_ro_t self);
|
|||||||
const char * igloo_ro_get_name(igloo_ro_t self);
|
const char * igloo_ro_get_name(igloo_ro_t self);
|
||||||
|
|
||||||
/* This gets the object's associated object. */
|
/* This gets the object's associated object. */
|
||||||
igloo_ro_t igloo_ro_get_associated(igloo_ro_t self);
|
igloo_ro_t igloo_ro_get_associated(igloo_ro_t self);
|
||||||
int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated);
|
int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated);
|
||||||
|
|
||||||
|
/* Clone the given object returning a copy of it.
|
||||||
|
*
|
||||||
|
* This creates a copy of the passed object if possible.
|
||||||
|
* The mode of copy is selected by the parameters required and allowed.
|
||||||
|
* Both list flags of modes. Modes listed as required are adhered to.
|
||||||
|
* However the application may select any additional mode from the allowed
|
||||||
|
* flags.
|
||||||
|
*
|
||||||
|
* If both required and allowed are zero a set of default flags is applied
|
||||||
|
* as allowed flags.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* self
|
||||||
|
* The object to copy.
|
||||||
|
* required
|
||||||
|
* Flags that must be adhered to when coping.
|
||||||
|
* allowed
|
||||||
|
* Flags that are allowed to be used.
|
||||||
|
* Flags that are listed as required are automatically added the list of allowed flags.
|
||||||
|
* name, associated
|
||||||
|
* See igloo_ro_new().
|
||||||
|
*/
|
||||||
|
igloo_ro_t igloo_ro_clone(igloo_ro_t self, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated);
|
||||||
|
|
||||||
|
/* Make a copy of a object but converts it to another type as well.
|
||||||
|
*
|
||||||
|
* This makes makes a copy of the object that is also of a diffrent type.
|
||||||
|
* If the type is the same as the type of self igloo_ro_clone() is called.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* self
|
||||||
|
* The object to copy and convert.
|
||||||
|
* type
|
||||||
|
* The type to convert to.
|
||||||
|
* required, allowed
|
||||||
|
* See igloo_ro_clone().
|
||||||
|
* name, associated
|
||||||
|
* See igloo_ro_new().
|
||||||
|
*/
|
||||||
|
igloo_ro_t igloo_ro_convert(igloo_ro_t self, const igloo_ro_type_t *type, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated);
|
||||||
|
|
||||||
|
/* Convert a object to a string.
|
||||||
|
* This is used for debugging and presenting to the user.
|
||||||
|
*
|
||||||
|
* The resulting string can not be used to recreate the object.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* self
|
||||||
|
* The object to convert to a string.
|
||||||
|
* Returns:
|
||||||
|
* A string as allocated using malloc(3). The caller must call free(3).
|
||||||
|
*/
|
||||||
|
char * igloo_ro_stringify(igloo_ro_t self);
|
||||||
|
|
||||||
|
/* Compare two objects.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* a, b
|
||||||
|
* The objects to compare.
|
||||||
|
* Returns:
|
||||||
|
* Thre result of the compare. See igloo_ro_cr_t.
|
||||||
|
*/
|
||||||
|
igloo_ro_cr_t igloo_ro_compare(igloo_ro_t a, igloo_ro_t b);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ typedef struct igloo_ro_type_tag igloo_ro_type_t;
|
|||||||
|
|
||||||
#define igloo_RO_TYPE(type) type * subtype__ ## type;
|
#define igloo_RO_TYPE(type) type * subtype__ ## type;
|
||||||
|
|
||||||
#define igloo_RO__CONTROL_VERSION 1
|
#define igloo_RO__CONTROL_VERSION 1
|
||||||
#define igloo_RO__DEFINE_TYPE(type, suffix, ...) \
|
#define igloo_RO__DEFINE_TYPE(type, suffix, ...) \
|
||||||
static const igloo_ro_type_t igloo_ro__typedef__ ## type = \
|
static const igloo_ro_type_t igloo_ro__typedef__ ## type = \
|
||||||
{ \
|
{ \
|
||||||
@ -49,6 +49,10 @@ static const igloo_ro_type_t igloo_ro__typedef__ ## type = \
|
|||||||
#define igloo_RO_TYPEDECL_FREE(cb) .type_freecb = (cb)
|
#define igloo_RO_TYPEDECL_FREE(cb) .type_freecb = (cb)
|
||||||
#define igloo_RO_TYPEDECL_NEW(cb) .type_newcb = (cb)
|
#define igloo_RO_TYPEDECL_NEW(cb) .type_newcb = (cb)
|
||||||
#define igloo_RO_TYPEDECL_NEW_NOOP() .type_newcb = igloo_ro_new__return_zero
|
#define igloo_RO_TYPEDECL_NEW_NOOP() .type_newcb = igloo_ro_new__return_zero
|
||||||
|
#define igloo_RO_TYPEDECL_CLONE(cb) .type_clonecb = (cb)
|
||||||
|
#define igloo_RO_TYPEDECL_CONVERT(cb) .type_convertcb = (cb)
|
||||||
|
#define igloo_RO_TYPEDECL_STRINGIFY(cb) .type_stringifycb = (cb)
|
||||||
|
#define igloo_RO_TYPEDECL_COMPARE(cb) .type_comparecb = (cb)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
18
src/buffer.c
18
src/buffer.c
@ -31,10 +31,12 @@ struct igloo_buffer_tag {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void __free(igloo_ro_t self);
|
static void __free(igloo_ro_t self);
|
||||||
|
static char * __stringify(igloo_ro_t self);
|
||||||
|
|
||||||
igloo_RO_PUBLIC_TYPE(igloo_buffer_t,
|
igloo_RO_PUBLIC_TYPE(igloo_buffer_t,
|
||||||
igloo_RO_TYPEDECL_FREE(__free),
|
igloo_RO_TYPEDECL_FREE(__free),
|
||||||
igloo_RO_TYPEDECL_NEW_NOOP()
|
igloo_RO_TYPEDECL_NEW_NOOP(),
|
||||||
|
igloo_RO_TYPEDECL_STRINGIFY(__stringify)
|
||||||
);
|
);
|
||||||
|
|
||||||
static void __free(igloo_ro_t self)
|
static void __free(igloo_ro_t self)
|
||||||
@ -139,6 +141,20 @@ int igloo_buffer_get_string(igloo_buffer_t *buffer, const char **string)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char * __stringify(igloo_ro_t self)
|
||||||
|
{
|
||||||
|
igloo_buffer_t *buffer = igloo_RO_TO_TYPE(self, igloo_buffer_t);
|
||||||
|
const char *ret;
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (igloo_buffer_get_string(buffer, &ret) != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return strdup(ret);
|
||||||
|
}
|
||||||
|
|
||||||
int igloo_buffer_set_length(igloo_buffer_t *buffer, size_t length)
|
int igloo_buffer_set_length(igloo_buffer_t *buffer, size_t length)
|
||||||
{
|
{
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
|
186
src/ro.c
186
src/ro.c
@ -21,6 +21,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -43,6 +44,29 @@ static inline int check_type(const igloo_ro_type_t *type)
|
|||||||
type->type_length >= sizeof(igloo_ro_base_t);
|
type->type_length >= sizeof(igloo_ro_base_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int igloo_RO_HAS_TYPE_raw_il(igloo_ro_t object, const igloo_ro_type_t *type)
|
||||||
|
{
|
||||||
|
return !igloo_RO_IS_NULL(object) && igloo_RO_GET_TYPE(object) == type;
|
||||||
|
}
|
||||||
|
int igloo_RO_HAS_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type)
|
||||||
|
{
|
||||||
|
return igloo_RO_HAS_TYPE_raw_il(object, type);
|
||||||
|
}
|
||||||
|
static inline int igloo_RO_IS_VALID_raw_li(igloo_ro_t object, const igloo_ro_type_t *type)
|
||||||
|
{
|
||||||
|
return igloo_RO_HAS_TYPE_raw_il(object, type) && igloo_RO__GETBASE(object)->refc;
|
||||||
|
}
|
||||||
|
int igloo_RO_IS_VALID_raw(igloo_ro_t object, const igloo_ro_type_t *type)
|
||||||
|
{
|
||||||
|
return igloo_RO_IS_VALID_raw_li(object, type);
|
||||||
|
}
|
||||||
|
igloo_ro_t igloo_RO_TO_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type)
|
||||||
|
{
|
||||||
|
return igloo_RO_IS_VALID_raw_li(object, type) ? object : igloo_RO_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated)
|
igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated)
|
||||||
{
|
{
|
||||||
igloo_ro_base_t *base;
|
igloo_ro_base_t *base;
|
||||||
@ -286,3 +310,165 @@ int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
igloo_ro_t igloo_ro_clone(igloo_ro_t self, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated)
|
||||||
|
{
|
||||||
|
igloo_ro_base_t *base = igloo_RO__GETBASE(self);
|
||||||
|
igloo_ro_t ret = igloo_RO_NULL;
|
||||||
|
|
||||||
|
if (!base)
|
||||||
|
return igloo_RO_NULL;
|
||||||
|
|
||||||
|
allowed |= required;
|
||||||
|
|
||||||
|
if (!allowed)
|
||||||
|
allowed = igloo_RO_CF_DEFAULT;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(base->lock));
|
||||||
|
if (!base->refc) {
|
||||||
|
igloo_thread_mutex_unlock(&(base->lock));
|
||||||
|
return igloo_RO_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base->type->type_clonecb)
|
||||||
|
ret = base->type->type_clonecb(self, required, allowed, name, associated);
|
||||||
|
igloo_thread_mutex_unlock(&(base->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
igloo_ro_t igloo_ro_convert(igloo_ro_t self, const igloo_ro_type_t *type, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated)
|
||||||
|
{
|
||||||
|
igloo_ro_base_t *base = igloo_RO__GETBASE(self);
|
||||||
|
igloo_ro_t ret = igloo_RO_NULL;
|
||||||
|
|
||||||
|
if (!base || !type)
|
||||||
|
return igloo_RO_NULL;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(base->lock));
|
||||||
|
if (!base->refc) {
|
||||||
|
igloo_thread_mutex_unlock(&(base->lock));
|
||||||
|
return igloo_RO_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base->type == type) {
|
||||||
|
igloo_thread_mutex_unlock(&(base->lock));
|
||||||
|
return igloo_ro_clone(self, required, allowed, name, associated);
|
||||||
|
}
|
||||||
|
|
||||||
|
allowed |= required;
|
||||||
|
|
||||||
|
if (!allowed)
|
||||||
|
allowed = igloo_RO_CF_DEFAULT;
|
||||||
|
|
||||||
|
if (base->type->type_convertcb)
|
||||||
|
ret = base->type->type_convertcb(self, type, required, allowed, name, associated);
|
||||||
|
|
||||||
|
if (igloo_RO_IS_NULL(ret))
|
||||||
|
if (type->type_convertcb)
|
||||||
|
ret = type->type_convertcb(self, type, required, allowed, name, associated);
|
||||||
|
igloo_thread_mutex_unlock(&(base->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * igloo_ro_stringify(igloo_ro_t self)
|
||||||
|
{
|
||||||
|
igloo_ro_base_t *base = igloo_RO__GETBASE(self);
|
||||||
|
char *ret = NULL;
|
||||||
|
|
||||||
|
if (!base)
|
||||||
|
return strdup("{igloo_RO_NULL}");
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(base->lock));
|
||||||
|
if (!base->refc) {
|
||||||
|
int len;
|
||||||
|
char buf;
|
||||||
|
|
||||||
|
#define STRINGIFY_FORMAT_WEAK "{%s@%p, weak}", base->type->type_name, base
|
||||||
|
len = snprintf(&buf, 1, STRINGIFY_FORMAT_WEAK);
|
||||||
|
if (len > 2) {
|
||||||
|
/* We add 2 bytes just to make sure no buggy interpretation of \0 inclusion could bite us. */
|
||||||
|
ret = calloc(1, len + 2);
|
||||||
|
if (ret) {
|
||||||
|
snprintf(ret, len + 1, STRINGIFY_FORMAT_WEAK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
igloo_thread_mutex_unlock(&(base->lock));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base->type->type_stringifycb) {
|
||||||
|
ret = base->type->type_stringifycb(self);
|
||||||
|
} else {
|
||||||
|
int len;
|
||||||
|
char buf;
|
||||||
|
|
||||||
|
#define STRINGIFY_FORMAT_FULL "{%s@%p, strong, name=\"%s\", associated=%p}", base->type->type_name, base, base->name, igloo_RO__GETBASE(base->associated)
|
||||||
|
len = snprintf(&buf, 1, STRINGIFY_FORMAT_FULL);
|
||||||
|
if (len > 2) {
|
||||||
|
/* We add 2 bytes just to make sure no buggy interpretation of \0 inclusion could bite us. */
|
||||||
|
ret = calloc(1, len + 2);
|
||||||
|
if (ret) {
|
||||||
|
snprintf(ret, len + 1, STRINGIFY_FORMAT_FULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
igloo_thread_mutex_unlock(&(base->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
igloo_ro_cr_t igloo_ro_compare(igloo_ro_t a, igloo_ro_t b)
|
||||||
|
{
|
||||||
|
igloo_ro_base_t *base_a = igloo_RO__GETBASE(a);
|
||||||
|
igloo_ro_base_t *base_b = igloo_RO__GETBASE(b);
|
||||||
|
igloo_ro_cr_t ret = igloo_RO_CR__ERROR;
|
||||||
|
|
||||||
|
if (base_a == base_b)
|
||||||
|
return igloo_RO_CR_SAME;
|
||||||
|
|
||||||
|
if (!base_a || !base_b)
|
||||||
|
return igloo_RO_CR__ERROR;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(base_a->lock));
|
||||||
|
igloo_thread_mutex_lock(&(base_b->lock));
|
||||||
|
|
||||||
|
if (!base_a->refc || !base_b->refc) {
|
||||||
|
igloo_thread_mutex_unlock(&(base_b->lock));
|
||||||
|
igloo_thread_mutex_unlock(&(base_a->lock));
|
||||||
|
return igloo_RO_CR__ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base_a->type->type_comparecb)
|
||||||
|
ret = base_a->type->type_comparecb(a, b);
|
||||||
|
|
||||||
|
if (ret == igloo_RO_CR__ERROR) {
|
||||||
|
ret = base_b->type->type_comparecb(b, a);
|
||||||
|
|
||||||
|
/* we switched arguments here, so we need to reverse the result */
|
||||||
|
switch (ret) {
|
||||||
|
case igloo_RO_CR__ERROR:
|
||||||
|
case igloo_RO_CR_EQUAL:
|
||||||
|
case igloo_RO_CR_NOTEQUAL:
|
||||||
|
/* those are the same in both directions */
|
||||||
|
break;
|
||||||
|
case igloo_RO_CR_ALESSTHANB:
|
||||||
|
ret = igloo_RO_CR_AGREATERTHANB;
|
||||||
|
break;
|
||||||
|
case igloo_RO_CR_AGREATERTHANB:
|
||||||
|
ret = igloo_RO_CR_ALESSTHANB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Cases we do not yet handle or that are not a valid result. */
|
||||||
|
ret = igloo_RO_CR__ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
igloo_thread_mutex_unlock(&(base_b->lock));
|
||||||
|
igloo_thread_mutex_unlock(&(base_a->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user