This is an automated email from the ASF dual-hosted git repository. astitcher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
commit b18da591521709102d3957b7407706d8060796cf Author: Andrew Stitcher <astitc...@apache.org> AuthorDate: Mon May 16 23:06:25 2022 -0400 PROTON-2558: Add make class operation to hide class details The new operation is used by the bindings to create proton objects without needing to know the details of the pn_class_t struct. --- c/include/proton/object.h | 9 ++++++++- c/src/core/object/object.c | 20 ++++++++++++++++++++ cpp/src/contexts.cpp | 11 +++-------- python/cproton.i | 17 +++++------------ ruby/cproton.i | 17 +++++++++-------- 5 files changed, 45 insertions(+), 29 deletions(-) diff --git a/c/include/proton/object.h b/c/include/proton/object.h index ce76c6941..11f039624 100644 --- a/c/include/proton/object.h +++ b/c/include/proton/object.h @@ -51,7 +51,7 @@ typedef struct pn_record_t pn_record_t; struct pn_class_t { const char *name; - const pn_cid_t cid; + pn_cid_t cid; void *(*newinst)(const pn_class_t *, size_t); void (*initialize)(void *); void (*incref)(void *); @@ -105,6 +105,13 @@ PN_EXTERN void pn_object_incref(void *object); PREFIX ## _inspect \ } +PN_EXTERN pn_class_t *pn_class_create(const char *name, + void (*initialize)(void*), + void (*finalize)(void*), + void (*incref)(void*), + void (*decref)(void*), + int (*refcount)(void*)); + PN_EXTERN void *pn_void_new(const pn_class_t *clazz, size_t size); PN_EXTERN void pn_void_incref(void *object); PN_EXTERN void pn_void_decref(void *object); diff --git a/c/src/core/object/object.c b/c/src/core/object/object.c index a3ee2cbfd..e498f9fb0 100644 --- a/c/src/core/object/object.c +++ b/c/src/core/object/object.c @@ -59,6 +59,26 @@ typedef struct { #define pni_head(PTR) \ (((pni_head_t *) (PTR)) - 1) +pn_class_t *pn_class_create(const char *name, + void (*initialize)(void*), + void (*finalize)(void*), + void (*incref)(void*), + void (*decref)(void*), + int (*refcount)(void*)) +{ + pn_class_t *clazz = malloc(sizeof( pn_class_t)); + *clazz = (pn_class_t) { + .name = name, + .cid = CID_pn_void, + .initialize = initialize, + .finalize = finalize, + .incref = incref, + .decref = decref, + .refcount = refcount + }; + return clazz; +} + const char *pn_class_name(const pn_class_t *clazz) { return clazz->name; diff --git a/cpp/src/contexts.cpp b/cpp/src/contexts.cpp index 7bc6c3f01..9dc13dbf0 100644 --- a/cpp/src/contexts.cpp +++ b/cpp/src/contexts.cpp @@ -42,12 +42,7 @@ namespace proton { namespace { void cpp_context_finalize(void* v) { reinterpret_cast<context*>(v)->~context(); } -#define CID_cpp_context CID_pn_object -#define cpp_context_initialize NULL -#define cpp_context_hashcode NULL -#define cpp_context_compare NULL -#define cpp_context_inspect NULL -pn_class_t cpp_context_class = PN_CLASS(cpp_context); +pn_class_t* cpp_context_class = pn_class_create("cpp_context", nullptr, cpp_context_finalize, nullptr, nullptr, nullptr); // Handles PN_HANDLE(CONNECTION_CONTEXT) @@ -64,9 +59,9 @@ T* get_context(pn_record_t* record, pn_handle_t handle) { context::~context() {} -void *context::alloc(size_t n) { return pn_class_new(&cpp_context_class, n); } +void *context::alloc(size_t n) { return pn_class_new(cpp_context_class, n); } -pn_class_t* context::pn_class() { return &cpp_context_class; } +pn_class_t* context::pn_class() { return cpp_context_class; } connection_context::connection_context() : container(0), default_session(0), link_gen(0), handler(0), listener_context_(0) diff --git a/python/cproton.i b/python/cproton.i index 6bb68e4b9..7a3407ee1 100644 --- a/python/cproton.i +++ b/python/cproton.i @@ -415,16 +415,7 @@ int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl, char *OUTPUT, size_t MAX_OUTPUT_S %immutable PN_PYREF; %inline %{ - extern const pn_class_t PN_PYREF[]; - - #define CID_pn_pyref CID_pn_void - #define pn_pyref_new NULL - #define pn_pyref_initialize NULL - #define pn_pyref_finalize NULL - #define pn_pyref_free NULL - #define pn_pyref_hashcode NULL - #define pn_pyref_compare NULL - #define pn_pyref_inspect NULL + pn_class_t* PN_PYREF; static void pn_pyref_incref(void *object) { PyObject* p = (PyObject*) object; @@ -444,8 +435,6 @@ int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl, char *OUTPUT, size_t MAX_OUTPUT_S return 1; } - const pn_class_t PN_PYREF[] = {PN_METACLASS(pn_pyref)}; - void *pn_py2void(PyObject *object) { return object; } @@ -501,4 +490,8 @@ int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl, char *OUTPUT, size_t MAX_OUTPUT_S %} +%init %{ + PN_PYREF = pn_class_create("pn_pyref", NULL, NULL, pn_pyref_incref, pn_pyref_decref, pn_pyref_refcount); +%} + %include "proton/cproton.i" diff --git a/ruby/cproton.i b/ruby/cproton.i index f8a0f3d77..00b3593dc 100644 --- a/ruby/cproton.i +++ b/ruby/cproton.i @@ -510,19 +510,14 @@ void Pn_rbkey_finalize(void *vp_rbkey) { } } -/* NOTE: no macro or preprocessor definitions in %inline sections */ -#define CID_Pn_rbkey CID_pn_void -#define Pn_rbkey_inspect NULL -#define Pn_rbkey_compare NULL -#define Pn_rbkey_hashcode NULL +static pn_class_t *Pn_rbkey_class; pn_class_t* Pn_rbkey__class(void) { - static pn_class_t clazz = PN_CLASS(Pn_rbkey); - return &clazz; + return Pn_rbkey_class; } Pn_rbkey_t *Pn_rbkey_new(void) { - return (Pn_rbkey_t *) pn_class_new(Pn_rbkey__class(), sizeof(Pn_rbkey_t)); + return (Pn_rbkey_t *) pn_class_new(Pn_rbkey_class, sizeof(Pn_rbkey_t)); } %} @@ -674,6 +669,12 @@ int pn_ssl_get_peer_hostname(pn_ssl_t *ssl, char *OUTPUT, size_t *OUTPUT_SIZE); %} +%init +%{ +Pn_rbkey_class = + pn_class_create("Pn_rbkey", Pn_rbkey_initialize, Pn_rbkey_finalize, NULL, NULL, NULL); +%} + %include "proton/cproton.i" %include "proton/url.h" --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org