Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Icecast-Server
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
94
Issues
94
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
External Wiki
External Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Xiph.Org
Icecast-Server
Commits
ed78741e
Commit
ed78741e
authored
Oct 11, 2018
by
Philipp Schafft
🦁
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ph3-update-refobject'
parents
07899c4a
d8c887aa
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
397 additions
and
124 deletions
+397
-124
src/buffer.c
src/buffer.c
+8
-6
src/buffer.h
src/buffer.h
+5
-1
src/cfgfile.c
src/cfgfile.c
+1
-1
src/client.c
src/client.c
+1
-1
src/connection.c
src/connection.c
+1
-1
src/fastevent.c
src/fastevent.c
+16
-15
src/fastevent.h
src/fastevent.h
+1
-1
src/global.c
src/global.c
+1
-1
src/listensocket.c
src/listensocket.c
+18
-11
src/listensocket.h
src/listensocket.h
+5
-0
src/module.c
src/module.c
+15
-9
src/module.h
src/module.h
+4
-1
src/refobject.c
src/refobject.c
+50
-6
src/refobject.h
src/refobject.h
+107
-2
src/reportxml.c
src/reportxml.c
+40
-26
src/reportxml.h
src/reportxml.h
+10
-3
src/tests/ctest_buffer.c
src/tests/ctest_buffer.c
+11
-11
src/tests/ctest_refobject.c
src/tests/ctest_refobject.c
+103
-28
No files found.
src/buffer.c
View file @
ed78741e
...
...
@@ -37,16 +37,18 @@ static void __free(refobject_t self, void **userdata)
free
(
buffer
->
buffer
);
}
REFOBJECT_DEFINE_TYPE
(
buffer_t
,
REFOBJECT_DEFINE_TYPE_FREE
(
__free
),
REFOBJECT_DEFINE_TYPE_NEW_NOOP
()
);
buffer_t
*
buffer_new
(
ssize_t
preallocation
,
void
*
userdata
,
const
char
*
name
,
refobject_t
associated
)
{
buffer_t
*
buffer
=
NULL
;
refobject_t
refobject
=
refobject_new
(
sizeof
(
*
buffer
),
__free
,
userdata
,
name
,
associated
);
buffer_t
*
buffer
=
refobject_new_ext
(
buffer_t
,
userdata
,
name
,
associated
);
if
(
REFOBJECT_IS_NULL
(
refobject
)
)
if
(
!
buffer
)
return
NULL
;
buffer
=
REFOBJECT_TO_TYPE
(
refobject
,
buffer_t
*
);
if
(
preallocation
>
0
)
buffer_preallocate
(
buffer
,
preallocation
);
...
...
@@ -55,7 +57,7 @@ buffer_t * buffer_new(ssize_t preallocation, void *userdata, const char *name,
buffer_t
*
buffer_new_simple
(
void
)
{
return
buffer_new
(
-
1
,
NULL
,
NULL
,
REFOBJECT_NULL
);
return
refobject_new
(
buffer_t
);
}
void
buffer_preallocate
(
buffer_t
*
buffer
,
size_t
request
)
...
...
src/buffer.h
View file @
ed78741e
...
...
@@ -28,6 +28,8 @@
* This set of functions is intentinally not thread safe.
*/
REFOBJECT_FORWARD_TYPE
(
buffer_t
);
/* This creates a new buffer object.
* Parameters:
* preallocation
...
...
@@ -37,7 +39,9 @@
*/
buffer_t
*
buffer_new
(
ssize_t
preallocation
,
void
*
userdata
,
const
char
*
name
,
refobject_t
associated
);
/* This creates a new buffer with defaults.
/* Depreciated: This creates a new buffer with defaults.
* Do NOT use this. Use refobject_new(buffer_t)
*
* This is the same as:
* buffer_new(-1, NULL, NULL, REFOBJECT_NULL)
*/
...
...
src/cfgfile.c
View file @
ed78741e
...
...
@@ -232,7 +232,7 @@ void config_init_configuration(ice_config_t *configuration)
{
memset
(
configuration
,
0
,
sizeof
(
ice_config_t
));
_set_defaults
(
configuration
);
configuration
->
reportxml_db
=
re
portxml_database_new
(
);
configuration
->
reportxml_db
=
re
fobject_new
(
reportxml_database_t
);
}
static
inline
void
__read_int
(
xmlDocPtr
doc
,
xmlNodePtr
node
,
int
*
val
,
const
char
*
warning
)
...
...
src/client.c
View file @
ed78741e
...
...
@@ -661,7 +661,7 @@ reportxml_t *client_get_reportxml(const char *state_definition, const char *stat
if
(
!
report
)
{
reportxml_node_t
*
rootnode
,
*
incidentnode
,
*
statenode
;
report
=
re
portxml_new
(
);
report
=
re
fobject_new
(
reportxml_t
);
rootnode
=
reportxml_get_root_node
(
report
);
incidentnode
=
reportxml_node_new
(
REPORTXML_NODE_TYPE_INCIDENT
,
NULL
,
NULL
,
NULL
);
statenode
=
reportxml_node_new
(
REPORTXML_NODE_TYPE_STATE
,
NULL
,
state_definition
,
state_akindof
);
...
...
src/connection.c
View file @
ed78741e
...
...
@@ -1703,7 +1703,7 @@ void connection_setup_sockets (ice_config_t *config)
allowed_ip
=
matchfile_new
(
config
->
allowfile
);
}
global
.
listensockets
=
listensocket_container_new
(
);
global
.
listensockets
=
refobject_new
(
listensocket_container_t
);
listensocket_container_configure
(
global
.
listensockets
,
config
);
global_unlock
();
...
...
src/fastevent.c
View file @
ed78741e
...
...
@@ -26,19 +26,19 @@
#ifdef FASTEVENT_ENABLED
struct
registration
{
typedef
struct
{
refobject_base_t
__base
;
fastevent_type_t
type
;
fastevent_cb_t
cb
;
fastevent_freecb_t
freecb
;
void
*
userdata
;
};
}
fastevent_registration_t
;
struct
eventrow
{
size_t
length
;
size_t
used
;
struct
registration
**
registrations
;
fastevent_registration_t
**
registrations
;
};
static
struct
eventrow
fastevent_registrations
[
FASTEVENT_TYPE__END
];
...
...
@@ -54,9 +54,9 @@ static inline struct eventrow * __get_row(fastevent_type_t type)
return
&
(
fastevent_registrations
[
idx
]);
}
static
int
__add_to_row
(
struct
eventrow
*
row
,
struct
registration
*
registration
)
static
int
__add_to_row
(
struct
eventrow
*
row
,
fastevent_registration_t
*
registration
)
{
struct
registration
**
n
;
fastevent_registration_t
**
n
;
if
(
row
==
NULL
)
return
-
1
;
...
...
@@ -77,7 +77,7 @@ static int __add_to_row(struct eventrow * row, struct registration *registration
return
0
;
}
static
int
__remove_from_row
(
struct
eventrow
*
row
,
struct
registration
*
registration
)
static
int
__remove_from_row
(
struct
eventrow
*
row
,
fastevent_registration_t
*
registration
)
{
size_t
i
;
...
...
@@ -98,7 +98,7 @@ static int __remove_from_row(struct eventrow * row, struct registration *registr
static
void
__unregister
(
refobject_t
self
,
void
**
userdata
)
{
struct
registration
*
registration
=
REFOBJECT_TO_TYPE
(
self
,
struct
registration
*
);
fastevent_registration_t
*
registration
=
REFOBJECT_TO_TYPE
(
self
,
fastevent_registration_t
*
);
struct
eventrow
*
row
;
(
void
)
userdata
;
...
...
@@ -143,11 +143,14 @@ int fastevent_shutdown(void)
return
0
;
}
REFOBJECT_DEFINE_PRIVATE_TYPE
(
fastevent_registration_t
,
REFOBJECT_DEFINE_TYPE_FREE
(
__unregister
)
);
refobject_t
fastevent_register
(
fastevent_type_t
type
,
fastevent_cb_t
cb
,
fastevent_freecb_t
freecb
,
void
*
userdata
)
{
struct
eventrow
*
row
;
struct
registration
*
registration
;
refobject_t
ret
;
fastevent_registration_t
*
registration
;
if
(
cb
==
NULL
)
return
REFOBJECT_NULL
;
...
...
@@ -160,15 +163,13 @@ refobject_t fastevent_register(fastevent_type_t type, fastevent_cb_t cb, fasteve
return
REFOBJECT_NULL
;
}
re
t
=
refobject_new
(
sizeof
(
struct
registration
),
__unregister
,
NULL
,
NULL
,
NULL
);
re
gistration
=
refobject_new__new
(
fastevent_registration_t
,
NULL
,
NULL
,
NULL
);
if
(
REFOBJECT_IS_NULL
(
ret
)
)
{
if
(
!
registration
)
{
thread_rwlock_unlock
(
&
fastevent_lock
);
return
REFOBJECT_NULL
;
}
registration
=
REFOBJECT_TO_TYPE
(
ret
,
struct
registration
*
);
registration
->
type
=
type
;
registration
->
cb
=
cb
;
registration
->
freecb
=
freecb
;
...
...
@@ -176,12 +177,12 @@ refobject_t fastevent_register(fastevent_type_t type, fastevent_cb_t cb, fasteve
if
(
__add_to_row
(
row
,
registration
)
!=
0
)
{
thread_rwlock_unlock
(
&
fastevent_lock
);
refobject_unref
(
ret
);
refobject_unref
(
REFOBJECT_FROM_TYPE
(
registration
)
);
return
REFOBJECT_NULL
;
}
thread_rwlock_unlock
(
&
fastevent_lock
);
return
ret
;
return
REFOBJECT_FROM_TYPE
(
registration
)
;
}
void
fastevent_emit
(
fastevent_type_t
type
,
fastevent_flag_t
flags
,
fastevent_datatype_t
datatype
,
...)
...
...
src/fastevent.h
View file @
ed78741e
...
...
@@ -15,7 +15,7 @@
#endif
#include <stdarg.h>
#include
<refobject.h>
#include
"refobject.h"
typedef
enum
{
FASTEVENT_TYPE_SLOWEVENT
=
0
,
...
...
src/global.c
View file @
ed78741e
...
...
@@ -38,7 +38,7 @@ void global_initialize(void)
global
.
clients
=
0
;
global
.
sources
=
0
;
global
.
source_tree
=
avl_tree_new
(
source_compare_sources
,
NULL
);
global
.
modulecontainer
=
module_container_new
(
);
global
.
modulecontainer
=
refobject_new
(
module_container_t
);
thread_mutex_create
(
&
_global_mutex
);
}
...
...
src/listensocket.c
View file @
ed78741e
...
...
@@ -150,22 +150,25 @@ static void __listensocket_container_free(refobject_t self, void **userdata)
thread_mutex_destroy
(
&
container
->
lock
);
}
listensocket_container_t
*
listensocket_container_new
(
void
)
int
__listensocket_container_new
(
refobject_t
self
,
const
refobject_type_t
*
type
,
va_list
ap
)
{
listensocket_container_t
*
self
=
REFOBJECT_TO_TYPE
(
refobject_new
(
sizeof
(
listensocket_container_t
),
__listensocket_container_free
,
NULL
,
NULL
,
NULL
),
listensocket_container_t
*
);
if
(
!
self
)
return
NULL
;
listensocket_container_t
*
ret
=
REFOBJECT_TO_TYPE
(
self
,
listensocket_container_t
*
);
self
->
sock
=
NULL
;
self
->
sock_len
=
0
;
self
->
sockcount_cb
=
NULL
;
self
->
sockcount_userdata
=
NULL
;
ret
->
sock
=
NULL
;
ret
->
sock_len
=
0
;
ret
->
sockcount_cb
=
NULL
;
ret
->
sockcount_userdata
=
NULL
;
thread_mutex_create
(
&
self
->
lock
);
thread_mutex_create
(
&
ret
->
lock
);
return
self
;
return
0
;
}
REFOBJECT_DEFINE_TYPE
(
listensocket_container_t
,
REFOBJECT_DEFINE_TYPE_FREE
(
__listensocket_container_free
),
REFOBJECT_DEFINE_TYPE_NEW
(
__listensocket_container_new
)
);
static
inline
void
__find_matching_entry
(
listensocket_container_t
*
self
,
const
listener_t
*
listener
,
listensocket_t
***
found
,
int
**
ref
)
{
const
listener_t
*
b
;
...
...
@@ -527,13 +530,17 @@ static void __listensocket_free(refobject_t self, void **userdata)
thread_mutex_destroy
(
&
listensocket
->
lock
);
}
REFOBJECT_DEFINE_TYPE
(
listensocket_t
,
REFOBJECT_DEFINE_TYPE_FREE
(
__listensocket_free
)
);
static
listensocket_t
*
listensocket_new
(
const
listener_t
*
listener
)
{
listensocket_t
*
self
;
if
(
listener
==
NULL
)
return
NULL
;
self
=
REFOBJECT_TO_TYPE
(
refobject_new
(
sizeof
(
listensocket_t
),
__listensocket_free
,
NULL
,
NULL
,
NULL
),
listensocket_t
*
);
self
=
refobject_new__new
(
listensocket_t
,
NULL
,
NULL
,
NULL
);
if
(
!
self
)
return
NULL
;
...
...
src/listensocket.h
View file @
ed78741e
...
...
@@ -10,8 +10,11 @@
#define __LISTENSOCKET_H__
#include "icecasttypes.h"
#include "refobject.h"
#include "cfgfile.h"
REFOBJECT_FORWARD_TYPE
(
listensocket_container_t
);
listensocket_container_t
*
listensocket_container_new
(
void
);
int
listensocket_container_configure
(
listensocket_container_t
*
self
,
const
ice_config_t
*
config
);
int
listensocket_container_configure_and_setup
(
listensocket_container_t
*
self
,
const
ice_config_t
*
config
);
...
...
@@ -20,6 +23,8 @@ connection_t * listensocket_container_accept(listensocket_container
int
listensocket_container_set_sockcount_cb
(
listensocket_container_t
*
self
,
void
(
*
cb
)(
size_t
count
,
void
*
userdata
),
void
*
userdata
);
ssize_t
listensocket_container_sockcount
(
listensocket_container_t
*
self
);
REFOBJECT_FORWARD_TYPE
(
listensocket_t
);
int
listensocket_refsock
(
listensocket_t
*
self
);
int
listensocket_unrefsock
(
listensocket_t
*
self
);
connection_t
*
listensocket_accept
(
listensocket_t
*
self
,
listensocket_container_t
*
container
);
...
...
src/module.c
View file @
ed78741e
...
...
@@ -50,20 +50,22 @@ static void __module_container_free(refobject_t self, void **userdata)
avl_tree_free
(
cont
->
module
,
(
avl_free_key_fun_type
)
refobject_unref
);
}
module_container_t
*
module_container_new
(
void
)
int
__module_container_new
(
refobject_t
self
,
const
refobject_type_t
*
type
,
va_list
ap
)
{
module_container_t
*
ret
=
REFOBJECT_TO_TYPE
(
refobject_new
(
sizeof
(
module_container_t
),
__module_container_free
,
NULL
,
NULL
,
NULL
),
module_container_t
*
);
if
(
!
ret
)
return
NULL
;
module_container_t
*
ret
=
REFOBJECT_TO_TYPE
(
self
,
module_container_t
*
);
thread_mutex_create
(
&
(
ret
->
lock
));
ret
->
module
=
avl_tree_new
(
compare_refobject_t_name
,
NULL
);
return
ret
;
return
0
;
}
REFOBJECT_DEFINE_TYPE
(
module_container_t
,
REFOBJECT_DEFINE_TYPE_FREE
(
__module_container_free
),
REFOBJECT_DEFINE_TYPE_NEW
(
__module_container_new
)
);
int
module_container_add_module
(
module_container_t
*
self
,
module_t
*
module
)
{
if
(
!
self
)
...
...
@@ -101,13 +103,13 @@ int module_container_delete_module(module_container_t *self,
module_t
*
module_container_get_module
(
module_container_t
*
self
,
const
char
*
name
)
{
refobject_
t
search
;
refobject_
base_t
*
search
;
module_t
*
ret
;
if
(
!
self
||
!
name
)
return
NULL
;
search
=
refobject_new
(
sizeof
(
refobject_base_t
),
NULL
,
NULL
,
name
,
NULL
);
search
=
refobject_new
__new
(
refobject_base_t
,
NULL
,
name
,
NULL
);
thread_mutex_lock
(
&
(
self
->
lock
));
if
(
avl_get_by_key
(
self
->
module
,
REFOBJECT_TO_TYPE
(
search
,
void
*
),
(
void
**
)
&
ret
)
!=
0
)
{
...
...
@@ -168,9 +170,13 @@ static void __module_free(refobject_t self, void **userdata)
thread_mutex_destroy
(
&
(
mod
->
lock
));
}
REFOBJECT_DEFINE_TYPE
(
module_t
,
REFOBJECT_DEFINE_TYPE_FREE
(
__module_free
)
);
module_t
*
module_new
(
const
char
*
name
,
module_setup_handler_t
newcb
,
module_setup_handler_t
freecb
,
void
*
userdata
)
{
module_t
*
ret
=
REFOBJECT_TO_TYPE
(
refobject_new
(
sizeof
(
module_t
),
__module_free
,
NULL
,
name
,
NULL
),
module_t
*
);
module_t
*
ret
=
refobject_new__new
(
module_t
,
NULL
,
name
,
NULL
);
if
(
!
ret
)
return
NULL
;
...
...
src/module.h
View file @
ed78741e
...
...
@@ -12,6 +12,7 @@
#include <libxml/tree.h>
#include "icecasttypes.h"
#include "refobject.h"
typedef
void
(
*
module_client_handler_function_t
)(
module_t
*
self
,
client_t
*
client
);
typedef
int
(
*
module_setup_handler_t
)(
module_t
*
self
,
void
**
userdata
);
...
...
@@ -21,7 +22,9 @@ typedef struct {
module_client_handler_function_t
cb
;
}
module_client_handler_t
;
module_container_t
*
module_container_new
(
void
);
REFOBJECT_FORWARD_TYPE
(
module_container_t
);
REFOBJECT_FORWARD_TYPE
(
module_t
);
int
module_container_add_module
(
module_container_t
*
self
,
module_t
*
module
);
int
module_container_delete_module
(
module_container_t
*
self
,
const
char
*
name
);
module_t
*
module_container_get_module
(
module_container_t
*
self
,
const
char
*
name
);
...
...
src/refobject.c
View file @
ed78741e
...
...
@@ -19,19 +19,35 @@
#define TO_BASE(x) REFOBJECT_TO_TYPE((x), refobject_base_t *)
refobject_t
refobject_new
(
size_t
len
,
refobject_free_t
freecb
,
void
*
userdata
,
const
char
*
name
,
refobject_t
associated
)
int
refobject_new__return_zero
(
refobject_t
self
,
const
refobject_type_t
*
type
,
va_list
ap
)
{
(
void
)
self
,
(
void
)
type
,
(
void
)
ap
;
return
0
;
}
REFOBJECT_DEFINE_TYPE
(
refobject_base_t
,
REFOBJECT_DEFINE_TYPE_NEW_NOOP
()
);
static
inline
int
check_type
(
const
refobject_type_t
*
type
)
{
return
type
->
control_length
==
sizeof
(
refobject_type_t
)
&&
type
->
control_version
==
REFOBJECT_CONTROL_VERSION
&&
type
->
type_length
>=
sizeof
(
refobject_base_t
);
}
refobject_t
refobject_new__real
(
const
refobject_type_t
*
type
,
void
*
userdata
,
const
char
*
name
,
refobject_t
associated
)
{
refobject_base_t
*
ret
=
NULL
;
if
(
len
<
sizeof
(
refobject_base_t
))
if
(
!
check_type
(
type
))
return
(
refobject_t
)
ret
;
ret
=
calloc
(
1
,
len
);
ret
=
calloc
(
1
,
type
->
type_length
);
if
(
ret
==
NULL
)
return
(
refobject_t
)
ret
;
ret
->
type
=
type
;
ret
->
refc
=
1
;
ret
->
freecb
=
freecb
;
ret
->
userdata
=
userdata
;
thread_mutex_create
(
&
(
ret
->
lock
));
...
...
@@ -56,6 +72,34 @@ refobject_t refobject_new(size_t len, refobject_free_t freecb, void *userdat
return
(
refobject_t
)
ret
;
}
refobject_t
refobject_new__simple
(
const
refobject_type_t
*
type
,
void
*
userdata
,
const
char
*
name
,
refobject_t
associated
,
...)
{
refobject_t
ret
;
int
res
;
va_list
ap
;
if
(
!
check_type
(
type
))
return
REFOBJECT_NULL
;
if
(
!
type
->
type_newcb
)
return
REFOBJECT_NULL
;
ret
=
refobject_new__real
(
type
,
userdata
,
name
,
associated
);
if
(
REFOBJECT_IS_NULL
(
ret
))
return
REFOBJECT_NULL
;
va_start
(
ap
,
associated
);
res
=
type
->
type_newcb
(
ret
,
type
,
ap
);
va_end
(
ap
);
if
(
res
!=
0
)
{
refobject_unref
(
ret
);
return
REFOBJECT_NULL
;
}
return
ret
;
}
int
refobject_ref
(
refobject_t
self
)
{
if
(
REFOBJECT_IS_NULL
(
self
))
...
...
@@ -82,8 +126,8 @@ int refobject_unref(refobject_t self)
return
0
;
}
if
(
base
->
freecb
)
base
->
freecb
(
self
,
&
(
base
->
userdata
));
if
(
base
->
type
->
type_
freecb
)
base
->
type
->
type_
freecb
(
self
,
&
(
base
->
userdata
));
if
(
base
->
userdata
)
free
(
base
->
userdata
);
...
...
src/refobject.h
View file @
ed78741e
...
...
@@ -17,6 +17,8 @@
#include <config.h>
#endif
#include <stdarg.h>
#include "common/thread/thread.h"
#include "icecasttypes.h"
...
...
@@ -35,17 +37,82 @@
* as the operation is only defined for it's members.
* REFOBJECT_TO_TYPE(type,x)
* This casts the refobject (x) to the type (type).
* REFOBJECT_FROM_TYPE(x)
* Converts an object to a (refobject_t). This is the inverse of REFOBJECT_TO_TYPE().
* REFOBJECT_GET_TYPENAME(x)
* Get the name of the type of the object.
* REFOBJECT_IS_VALID(x,type)
* This returns true if x is not NULL and of type type.
* REFOBJECT_GET_BASE(x)
* REFOBJECT_GET_TYPE(x)
* Not to be used by the user.
*/
#ifdef HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
#define REFOBJECT_NULL ((refobject_t)(refobject_base_t*)NULL)
#define REFOBJECT_GET_BASE(x) (((refobject_t)(x)).refobject_base)
#define REFOBJECT_IS_NULL(x) (((refobject_t)(x)).refobject_base == NULL)
#define REFOBJECT_TO_TYPE(x,y) ((y)(((refobject_t)(x)).refobject_base))
#else
#define REFOBJECT_NULL NULL
#define REFOBJECT_GET_BASE(x) ((refobject_base_t)(x))
#define REFOBJECT_IS_NULL(x) ((x) == NULL)
#define REFOBJECT_TO_TYPE(x,y) ((y)(x))
#endif
#define REFOBJECT_FROM_TYPE(x) ((refobject_t)(refobject_base_t*)(x))
#define REFOBJECT_GET_TYPE(x) (REFOBJECT_GET_BASE((x)) == NULL ? NULL : REFOBJECT_GET_BASE((x))->type)
#define REFOBJECT_GET_TYPENAME(x) (REFOBJECT_GET_TYPE((x)) == NULL ? NULL : REFOBJECT_GET_TYPE((x))->type_name)
#define REFOBJECT_IS_VALID(x,type) (!REFOBJECT_IS_NULL((x)) && REFOBJECT_GET_TYPE((x)) == (refobject_type__ ## type))
/* The following macros are used to define types.
*
* REFOBJECT_FORWARD_TYPE(type)
* Adds a forward decleration for the type. This is useful for non private types.
* REFOBJECT_DEFINE_TYPE(type,extras...)
* This defines a public type. One or more of the EXTRA macros be used.
* REFOBJECT_DEFINE_PRIVATE_TYPE(type,extras...)
* Same as REFOBJECT_DEFINE_TYPE() but defines private type.
*
* EXTRA Marcos:
* REFOBJECT_DEFINE_TYPE_FREE(cb)
* This defines a callback to be called when the object is freed.
* cb must be of type refobject_free_t.
* REFOBJECT_DEFINE_TYPE_NEW(cb)
* This defines a callback to be called when a new object is created.
* cb must be of type refobject_new_t.
* REFOBJECT_DEFINE_TYPE_NEW_NOOP()
* This installs a dummy callback for creation. This allows the type
* to be created using refobject_new(type) as with REFOBJECT_DEFINE_TYPE_NEW().
* This is useful for types that do not need to be initialized more than what
* refobject_new() already does.
*
* Other Macros:
* REFOBJECT_CONTROL_VERSION
* REFOBJECT_DEFINE_TYPE__RAW()
* Not to be used by the user.
*/
#define REFOBJECT_CONTROL_VERSION 1
#define REFOBJECT_FORWARD_TYPE(type) extern const refobject_type_t * refobject_type__ ## type;
#define REFOBJECT_DEFINE_TYPE__RAW(type, ...) \
static const refobject_type_t refobject_typedef__ ## type = \
{ \
.control_length = sizeof(refobject_type_t), \
.control_version = REFOBJECT_CONTROL_VERSION, \
.type_length = sizeof(type), \
.type_name = # type \
, ## __VA_ARGS__ \
}
#define REFOBJECT_DEFINE_TYPE(type, ...) REFOBJECT_DEFINE_TYPE__RAW(type, ## __VA_ARGS__); const refobject_type_t * refobject_type__ ## type = &refobject_typedef__ ## type
#define REFOBJECT_DEFINE_PRIVATE_TYPE(type, ...) REFOBJECT_DEFINE_TYPE__RAW(type, ## __VA_ARGS__); static const refobject_type_t * refobject_type__ ## type = &refobject_typedef__ ## type
#define REFOBJECT_DEFINE_TYPE_FREE(cb) .type_freecb = (cb)
#define REFOBJECT_DEFINE_TYPE_NEW(cb) .type_newcb = (cb)
#define REFOBJECT_DEFINE_TYPE_NEW_NOOP() .type_newcb = refobject_new__return_zero
typedef
struct
refobject_type_tag
refobject_type_t
;
int
refobject_new__return_zero
(
refobject_t
self
,
const
refobject_type_t
*
type
,
va_list
ap
);
/* Type used for callback called then the object is actually freed
* That is once all references to it are gone.
*
...
...
@@ -56,18 +123,52 @@
*/
typedef
void
(
*
refobject_free_t
)(
refobject_t
self
,
void
**
userdata
);
/* Type used for callback called then the object is created
* using the generic refobject_new().
*
* Additional parameters passed to refobject_new() are passed
* in the list ap. All limitations of <stdarg.h> apply.
*
* This function must return zero in case of success and
* non-zero in case of error. In case of error refobject_unref()
* is called internally to clear the object.
*/
typedef
int
(
*
refobject_new_t
)(
refobject_t
self
,
const
refobject_type_t
*
type
,
va_list
ap
);
/* Meta type used to defined types.
* DO NOT use any of the members in here directly!
*/
struct
refobject_type_tag
{
/* Size of this control structure */
size_t
control_length
;
/* ABI version of this structure */
int
control_version
;
/* Total length of the objects to be created */
size_t
type_length
;
/* Name of type */
const
char
*
type_name
;
/* Callback to be called on final free() */
refobject_free_t
type_freecb
;
/* Callback to be callback by refobject_new() */
refobject_new_t
type_newcb
;
};
/* Only defined here as the size must be publically known.
* DO NOT use any of the members in here directly!
*/
struct
refobject_base_tag
{
const
refobject_type_t
*
type
;
size_t
refc
;
mutex_t
lock
;
void
*
userdata
;
refobject_free_t
freecb
;
char
*
name
;
refobject_t
associated
;
};
REFOBJECT_FORWARD_TYPE
(
refobject_base_t
);
/* Create a new refobject
* The total length of the new object is given by len (see malloc(3)),
* the callback called on free is given by freecb (see refobject_free_t above),
...
...
@@ -78,7 +179,11 @@ struct refobject_base_tag {
* All parameters beside len are optional and can be NULL/REFOBJECT_NULL.
* If no freecb is given the userdata is freed (see refobject_free_t above).
*/
refobject_t
refobject_new
(
size_t
len
,
refobject_free_t
freecb
,
void
*
userdata
,
const
char
*
name
,
refobject_t
associated
);
#define refobject_new__new(type, userdata, name, associated) REFOBJECT_TO_TYPE(refobject_new__real((refobject_type__ ## type), (userdata), (name), (associated)), type*)
refobject_t
refobject_new__real
(
const
refobject_type_t
*
type
,
void
*
userdata
,
const
char
*
name
,
refobject_t
associated
);
#define refobject_new(type, ...) REFOBJECT_TO_TYPE(refobject_new__simple((refobject_type__ ## type), NULL, NULL, REFOBJECT_NULL, ## __VA_ARGS__), type*)
#define refobject_new_ext(type, userdata, name, associated, ...) REFOBJECT_TO_TYPE(refobject_new__simple((refobject_type__ ## type), (userdata), (name), (associated), ## __VA_ARGS__), type*)
refobject_t
refobject_new__simple
(
const
refobject_type_t
*
type
,
void
*
userdata
,
const
char
*
name
,
refobject_t
associated
,
...);
/* This increases the reference counter of the object */
int
refobject_ref
(
refobject_t
self
);
...
...
src/reportxml.c
View file @
ed78741e
...
...
@@ -236,37 +236,42 @@ static void __report_free(refobject_t self, void **userdata)
refobject_unref
(
report
->
root
);
}
static
reportxml_t
*
reportxml_new_with_root
(
reportxml_node_t
*
root
)
static
int
__report_new
(
refobject_t
self
,
const
refobject_type_t
*
type
,
va_list
ap
)
{
reportxml_t
*
ret
;
reportxml_t
*
ret
=
REFOBJECT_TO_TYPE
(
self
,
reportxml_t
*
);
reportxml_node_t
*
root
=
reportxml_node_new
(
REPORTXML_NODE_TYPE_REPORT
,
NULL
,
NULL
,
NULL
);
if
(
!
root
)
return
NULL
;
return
-
1
;
ret
=
REFOBJECT_TO_TYPE
(
refobject_new
(
sizeof
(
reportxml_t
),
__report_free
,
NULL
,
NULL
,
NULL
),
reportxml_t
*
);
ret
->
root
=
root
;
return
ret
;
return
0
;
}
reportxml_t
*
reportxml_new
(
void
)
REFOBJECT_DEFINE_TYPE
(
reportxml_t
,
REFOBJECT_DEFINE_TYPE_FREE
(
__report_free
),
REFOBJECT_DEFINE_TYPE_NEW
(
__report_new
)
);
static
reportxml_t
*
reportxml_new_with_root
(
reportxml_node_t
*
root
)
{
reportxml_node_t
*
root
=
reportxml_node_new
(
REPORTXML_NODE_TYPE_REPORT
,
NULL
,
NULL
,
NULL
);
reportxml_t
*
ret
;
if
(
!
root
)
return
NULL
;
ret
=
reportxml_new_with_root
(
root
);
if
(
!
ret
)
{
refobject_unref
(
root
);
return
NULL
;
}
ret
=
refobject_new__new
(
reportxml_t
,
NULL
,
NULL
,
NULL
);
ret
->
root
=
root
;
return
ret
;