Commit a18d14e9 authored by Simon Morlat's avatar Simon Morlat

add belle_sip_object_t

parent 5d3f6210
......@@ -6,6 +6,7 @@ bellesip_HEADERS=\
mainloop.h \
transaction.h \
message.h \
transport.h \
belle-sip.h
EXTRA_DIST=$(bellesip_HEADERS)
......@@ -20,28 +20,53 @@
#include <stdlib.h>
#define BELLE_SIP_MAGIC(_type) _type##_magic
#define BELLE_SIP_TYPE_ID(_type) _type##_id
typedef enum belle_sip_magic{
belle_sip_magic_first=0x32445191,
BELLE_SIP_MAGIC(belle_sip_transaction_t),
BELLE_SIP_MAGIC(belle_sip_server_transaction_t),
BELLE_SIP_MAGIC(belle_sip_client_transaction_t),
belle_sip_magic_end
}belle_sip_magic_t;
typedef enum belle_sip_type_id{
belle_sip_type_id_first=1,
BELLE_SIP_TYPE_ID(belle_sip_transaction_t),
BELLE_SIP_TYPE_ID(belle_sip_server_transaction_t),
BELLE_SIP_TYPE_ID(belle_sip_client_transaction_t),
BELLE_SIP_TYPE_ID(belle_sip_transport_t),
belle_sip_type_id_end
}belle_sip_type_id_t;
#define BELLE_SIP_IMPLEMENT_CAST(_type) \
_type *_type##_cast(void *obj, const char *file, int line){ \
if (((_type*)obj)->magic==BELLE_SIP_MAGIC(_type)) return (_type*)obj; \
belle_sip_fatal("Bad cast to "#_type " at %s:%i", file, line);\
return NULL; \
}
/**
* belle_sip_object_t is the base object.
* It is the base class for all belle sip non trivial objects.
* It owns a reference count which allows to trigger the destruction of the object when the last
* user of it calls belle_sip_object_unref().
**/
#define BELLE_SIP_DECLARE_CAST(_type)\
_type *_type##_cast(void *obj, const char *file, int line);
typedef struct _belle_sip_object belle_sip_object_t;
int belle_sip_object_is_unowed(const belle_sip_object_t *obj);
/**
* Increments reference counter, which prevents the object from being destroyed.
* If the object is initially unowed, this acquires the first reference.
**/
#define belle_sip_object_ref(obj) _belle_sip_object_ref((belle_sip_object_t*)obj)
void _belle_sip_object_ref(belle_sip_object_t *obj);
/**
* Decrements the reference counter. When it drops to zero, the object is destroyed.
**/
#define belle_sip_object_unref(obj) _belle_sip_object_unref((belle_sip_object_t*)obj)
void _belle_sip_object_unref(belle_sip_object_t *obj);
/**
* Destroy the object: this function is intended for unowed object, that is objects
* that were created with a 0 reference count.
**/
#define belle_sip_object_destroy(obj) _belle_sip_object_destroy((belle_sip_object_t*)obj)
void _belle_sip_object_destroy(belle_sip_object_t *obj);
void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno);
#define BELLE_SIP_CAST(obj,_type) (_type*)belle_sip_object_cast((belle_sip_object_t *)(obj), _type##_id, #_type, __FILE__, __LINE__)
#define BELLE_SIP_CAST(obj,_type) _type##_cast(obj, __FILE__, __LINE__)
#include "belle-sip/list.h"
#include "belle-sip/mainloop.h"
#include "belle-sip/uri.h"
......
......@@ -46,9 +46,6 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *
belle_sip_request_t * belle_sip_client_transaction_create_cancel(belle_sip_client_transaction_t *t);
void belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t);
BELLE_SIP_DECLARE_CAST(belle_sip_transaction_t);
BELLE_SIP_DECLARE_CAST(belle_sip_client_transaction_t);
BELLE_SIP_DECLARE_CAST(belle_sip_server_transaction_t);
#define BELLE_SIP_TRANSACTION(t) BELLE_SIP_CAST(t,belle_sip_transaction_t)
#define BELLE_SIP_SERVER_TRANSACTION(t) BELLE_SIP_CAST(t,belle_sip_server_transaction_t)
......
......@@ -27,6 +27,7 @@ lib_LTLIBRARIES=libbellesip.la
libbellesip_la_SOURCES=belle_sip_uri_impl.c \
belle_sip_headers_impl.c \
belle_sip_utils.c belle_sip_internal.h \
belle_sip_object.c \
belle_sip_loop.c \
belle_sip_resolver.c belle_sip_resolver.h \
transaction.c
......
......@@ -29,6 +29,20 @@
/* include all public headers*/
#include "belle-sip/belle-sip.h"
typedef void (*belle_sip_object_destroy_t)(belle_sip_object_t*);
struct _belle_sip_object{
uint8_t type_ids[8]; /*table of belle_sip_type_id_t for all inheritance chain*/
int ref;
belle_sip_object_destroy_t destroy;
};
belle_sip_object_t * _belle_sip_object_new(size_t objsize, belle_sip_type_id_t id, belle_sip_object_destroy_t destroy_func, int initially_unowed);
void _belle_sip_object_init_type(belle_sip_object_t *obj, belle_sip_type_id_t id);
#define belle_sip_object_new(_type,destroy) (_type*)_belle_sip_object_new(sizeof(_type),BELLE_SIP_TYPE_ID(_type),destroy,0)
#define belle_sip_object_new_unowed(_type,destroy) (_type*)_belle_sip_object_new(sizeof(_type),BELLE_SIP_TYPE_ID(_type),destroy,1)
#define belle_sip_object_init_type(obj, _type) _belle_sip_object_init_type((belle_sip_object_t*)obj, BELLE_SIP_TYPE_ID(_type))
struct _belle_sip_list {
struct _belle_sip_list *next;
......
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
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/>.
*/
#include "belle_sip_internal.h"
static uint8_t *find_type(belle_sip_object_t *obj, belle_sip_type_id_t id){
int i;
for(i=0;i<sizeof(obj->type_ids);++i){
if (obj->type_ids[i]==(uint8_t)id)
return &obj->type_ids[i];
}
return NULL;
}
void _belle_sip_object_init_type(belle_sip_object_t *obj, belle_sip_type_id_t id){
uint8_t * t=find_type(obj,id);
if (t!=NULL) belle_sip_fatal("This object already inherits type %i",id);
t=find_type(obj,0);
if (t==NULL) belle_sip_fatal("This object has too much inheritance !");
*t=id;
}
belle_sip_object_t * _belle_sip_object_new(size_t objsize, belle_sip_type_id_t id, belle_sip_object_destroy_t destroy_func, int initially_unowed){
belle_sip_object_t *obj=(belle_sip_object_t *)belle_sip_malloc0(objsize);
obj->type_ids[0]=id;
obj->ref=initially_unowed ? 0 : 1;
obj->destroy=destroy_func;
return obj;
}
int belle_sip_object_is_unowed(const belle_sip_object_t *obj){
return obj->ref==0;
}
void _belle_sip_object_ref(belle_sip_object_t *obj){
obj->ref++;
}
void _belle_sip_object_unref(belle_sip_object_t *obj){
if (obj->ref==0){
belle_sip_warning("Destroying unowed object");
belle_sip_object_destroy(obj);
return;
}
obj->ref--;
if (obj->ref==0){
belle_sip_object_destroy(obj);
}
}
void _belle_sip_object_destroy(belle_sip_object_t *obj){
if (obj->ref!=0){
belle_sip_error("Destroying referenced object !");
if (obj->destroy) obj->destroy(obj);
belle_sip_free(obj);
}
}
void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno){
if (find_type(obj,id)==NULL){
belle_sip_fatal("Bad cast to %s at %s:%i",castname,file,fileno);
return NULL;
}
return obj;
}
......@@ -19,7 +19,7 @@
#include "belle_sip_internal.h"
struct belle_sip_transaction{
belle_sip_magic_t magic;
belle_sip_object_t base;
char *branch_id;
belle_sip_transaction_state_t state;
void *appdata;
......@@ -28,18 +28,12 @@ struct belle_sip_transaction{
struct belle_sip_server_transaction{
belle_sip_transaction_t base;
belle_sip_magic_t magic;
};
struct belle_sip_client_transaction{
belle_sip_transaction_t base;
belle_sip_magic_t magic;
};
BELLE_SIP_IMPLEMENT_CAST(belle_sip_transaction_t);
BELLE_SIP_IMPLEMENT_CAST(belle_sip_server_transaction_t);
BELLE_SIP_IMPLEMENT_CAST(belle_sip_client_transaction_t);
void *belle_sip_transaction_get_application_data(const belle_sip_transaction_t *t){
return t->appdata;
}
......@@ -75,21 +69,32 @@ void belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t
}
static void belle_sip_transaction_init(belle_sip_transaction_t *t, belle_sip_request_t *req){
t->magic=BELLE_SIP_MAGIC(belle_sip_transaction_t);
belle_sip_object_init_type(t,belle_sip_transaction_t);
if (req) belle_sip_object_ref(req);
t->request=req;
}
static void transaction_destroy(belle_sip_transaction_t *t){
if (t->request) belle_sip_object_unref(t->request);
}
static void client_transaction_destroy(belle_sip_client_transaction_t *t ){
transaction_destroy((belle_sip_transaction_t*)t);
}
static void server_transaction_destroy(belle_sip_server_transaction_t *t){
transaction_destroy((belle_sip_transaction_t*)t);
}
belle_sip_client_transaction_t * belle_sip_client_transaction_new(belle_sip_request_t *req){
belle_sip_client_transaction_t *t=belle_sip_new0(belle_sip_client_transaction_t);
belle_sip_client_transaction_t *t=belle_sip_object_new(belle_sip_client_transaction_t,(belle_sip_object_destroy_t)client_transaction_destroy);
belle_sip_transaction_init((belle_sip_transaction_t*)t,req);
t->magic=BELLE_SIP_MAGIC(belle_sip_client_transaction_t);
return t;
}
belle_sip_server_transaction_t * belle_sip_server_transaction_new(belle_sip_request_t *req){
belle_sip_server_transaction_t *t=belle_sip_new0(belle_sip_server_transaction_t);
belle_sip_server_transaction_t *t=belle_sip_object_new(belle_sip_server_transaction_t,(belle_sip_object_destroy_t)server_transaction_destroy);
belle_sip_transaction_init((belle_sip_transaction_t*)t,req);
t->magic=BELLE_SIP_MAGIC(belle_sip_server_transaction_t);
return t;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment