summaryrefslogtreecommitdiff
path: root/upb/handlers.h
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2014-06-26 20:24:32 -0700
committerJosh Haberman <jhaberman@gmail.com>2014-06-26 20:24:32 -0700
commit2d10fa33071d52d7a35ce3b13bc459cd16a0aa33 (patch)
treebf47d38e2e1cc8ddb4711b23b26e7fd10742e07d /upb/handlers.h
parent7d565f1e7a0f107506d3cf31ef2e33e22a504d2b (diff)
Sync from internal Google development.
Diffstat (limited to 'upb/handlers.h')
-rw-r--r--upb/handlers.h42
1 files changed, 26 insertions, 16 deletions
diff --git a/upb/handlers.h b/upb/handlers.h
index a03c99e..6a8193a 100644
--- a/upb/handlers.h
+++ b/upb/handlers.h
@@ -91,7 +91,6 @@ extern char _upb_noclosure;
// A selector refers to a specific field handler in the Handlers object
// (for example: the STARTSUBMSG handler for field "field15").
typedef int32_t upb_selector_t;
-typedef void upb_func();
#ifdef __cplusplus
extern "C" {
@@ -140,12 +139,9 @@ class upb::HandlerAttributes {
~HandlerAttributes();
// Sets the handler data that will be passed as the second parameter of the
- // handler.
- //
- // Warning: if you use these attributes for multiple handlers, the
- // cleanup handler will be called once for each handler it was successfully
- // set on.
- bool SetHandlerData(void *handler_data, upb_handlerfree *cleanup);
+ // handler. To free this pointer when the handlers are freed, call
+ // Handlers::AddCleanup().
+ bool SetHandlerData(const void *handler_data);
const void* handler_data() const;
// Use this to specify the type of the closure. This will be checked against
@@ -175,14 +171,13 @@ class upb::HandlerAttributes {
#else
struct upb_handlerattr {
#endif
- void *handler_data_;
- upb_handlerfree *cleanup;
+ const void *handler_data_;
const void *closure_type_;
const void *return_closure_type_;
bool alwaysok_;
};
-#define UPB_HANDLERATTR_INITIALIZER {NULL, NULL, NULL, NULL, false}
+#define UPB_HANDLERATTR_INITIALIZER {NULL, NULL, NULL, false}
typedef struct {
upb_func *func;
@@ -292,7 +287,7 @@ class upb::Handlers {
// correct type.
typedef void GenericFunction();
- typedef void HandlersCallback(void *closure, upb_handlers *h);
+ typedef void HandlersCallback(const void *closure, upb_handlers *h);
// Returns a new handlers object for the given frozen msgdef.
// Returns NULL if memory allocation failed.
@@ -305,7 +300,7 @@ class upb::Handlers {
// subhandlers set by the callback will be overwritten.
static reffed_ptr<const Handlers> NewFrozen(const MessageDef *m,
HandlersCallback *callback,
- void *closure);
+ const void *closure);
// Functionality from upb::RefCounted.
bool IsFrozen() const;
@@ -335,6 +330,11 @@ class upb::Handlers {
// Returns the msgdef associated with this handlers object.
const MessageDef* message_def() const;
+ // Adds the given pointer and function to the list of cleanup functions that
+ // will be run when these handlers are freed. If this pointer has previously
+ // been registered, the function returns false and does nothing.
+ bool AddCleanup(void *ptr, upb_handlerfree *cleanup);
+
// Sets the startmsg handler for the message, which is defined as follows:
//
// bool startmsg(MyType* closure) {
@@ -534,6 +534,7 @@ struct upb_handlers {
const upb_msgdef *msg;
const upb_handlers **sub;
const void *top_closure_type;
+ upb_inttable cleanup_;
upb_status status_; // Used only when mutable.
upb_handlers_tabent table[1]; // Dynamically-sized field handler array.
};
@@ -619,11 +620,20 @@ template <class T> class Handler {
~Handler();
private:
+ void AddCleanup(Handlers* h) const {
+ if (cleanup_func_) {
+ bool ok = h->AddCleanup(cleanup_data_, cleanup_func_);
+ UPB_ASSERT_VAR(ok, ok);
+ }
+ }
+
UPB_DISALLOW_COPY_AND_ASSIGN(Handler);
friend class Handlers;
FuncPtr handler_;
mutable HandlerAttributes attr_;
mutable bool registered_;
+ void *cleanup_data_;
+ upb_handlerfree *cleanup_func_;
};
} // namespace upb
@@ -657,8 +667,7 @@ size_t upb_bufhandle_objofs(const upb_bufhandle *h);
void upb_handlerattr_init(upb_handlerattr *attr);
void upb_handlerattr_uninit(upb_handlerattr *attr);
-bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, void *hd,
- upb_handlerfree *cleanup);
+bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, const void *hd);
bool upb_handlerattr_setclosuretype(upb_handlerattr *attr, const void *type);
const void *upb_handlerattr_closuretype(const upb_handlerattr *attr);
bool upb_handlerattr_setreturnclosuretype(upb_handlerattr *attr,
@@ -673,13 +682,13 @@ UPB_INLINE const void *upb_handlerattr_handlerdata(
}
// upb_handlers
-typedef void upb_handlers_callback(void *closure, upb_handlers *h);
+typedef void upb_handlers_callback(const void *closure, upb_handlers *h);
upb_handlers *upb_handlers_new(const upb_msgdef *m,
const void *owner);
const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
const void *owner,
upb_handlers_callback *callback,
- void *closure);
+ const void *closure);
bool upb_handlers_isfrozen(const upb_handlers *h);
void upb_handlers_ref(const upb_handlers *h, const void *owner);
void upb_handlers_unref(const upb_handlers *h, const void *owner);
@@ -690,6 +699,7 @@ void upb_handlers_checkref(const upb_handlers *h, const void *owner);
const upb_status *upb_handlers_status(upb_handlers *h);
void upb_handlers_clearerr(upb_handlers *h);
const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h);
+bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *hfree);
bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
upb_handlerattr *attr);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback