Protocol Buffers - Google's data interchange format (grpc依赖) https://developers.google.com/protocol-buffers/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
5.1 KiB

/*
* upb - a minimalist implementation of protocol buffers.
*
* vtable declarations for types that are implementing any of the src or sink
* interfaces. Only components that are implementing these interfaces need
* to worry about this file.
*
* Copyright (c) 2010 Joshua Haberman. See LICENSE for details.
*/
#ifndef UPB_SRCSINK_VTBL_H_
#define UPB_SRCSINK_VTBL_H_
#include <assert.h>
#include "upb_stream.h"
#ifdef __cplusplus
extern "C" {
#endif
// Typedefs for function pointers to all of the virtual functions.
// upb_bytesrc.
typedef bool (*upb_bytesrc_get_fptr)(
upb_bytesrc *src, upb_string *str, upb_strlen_t minlen);
typedef bool (*upb_bytesrc_append_fptr)(
upb_bytesrc *src, upb_string *str, upb_strlen_t len);
// upb_bytesink.
typedef int32_t (*upb_bytesink_put_fptr)(upb_bytesink *sink, upb_string *str);
// Vtables for the above interfaces.
typedef struct {
upb_bytesrc_get_fptr get;
upb_bytesrc_append_fptr append;
} upb_bytesrc_vtable;
typedef struct {
upb_bytesink_put_fptr put;
} upb_bytesink_vtable;
// "Base Class" definitions; components that implement these interfaces should
// contain one of these structures.
struct _upb_bytesrc {
upb_bytesrc_vtable *vtbl;
upb_status status;
bool eof;
};
struct _upb_bytesink {
upb_bytesink_vtable *vtbl;
upb_status status;
bool eof;
};
INLINE void upb_bytesrc_init(upb_bytesrc *s, upb_bytesrc_vtable *vtbl) {
s->vtbl = vtbl;
s->eof = false;
upb_status_init(&s->status);
}
INLINE void upb_bytesink_init(upb_bytesink *s, upb_bytesink_vtable *vtbl) {
s->vtbl = vtbl;
s->eof = false;
upb_status_init(&s->status);
}
// Implementation of virtual function dispatch.
// upb_bytesrc
INLINE bool upb_bytesrc_get(
upb_bytesrc *bytesrc, upb_string *str, upb_strlen_t minlen) {
return bytesrc->vtbl->get(bytesrc, str, minlen);
}
INLINE bool upb_bytesrc_append(
upb_bytesrc *bytesrc, upb_string *str, upb_strlen_t len) {
return bytesrc->vtbl->append(bytesrc, str, len);
}
INLINE upb_status *upb_bytesrc_status(upb_bytesrc *src) { return &src->status; }
INLINE bool upb_bytesrc_eof(upb_bytesrc *src) { return src->eof; }
// upb_handlers
struct _upb_handlers {
upb_handlerset *set;
void *closure;
};
INLINE void upb_handlers_init(upb_handlers *h) {
(void)h;
}
INLINE void upb_handlers_uninit(upb_handlers *h) {
(void)h;
}
INLINE void upb_handlers_reset(upb_handlers *h) {
h->set = NULL;
h->closure = NULL;
}
INLINE bool upb_handlers_isempty(upb_handlers *h) {
return !h->set && !h->closure;
}
INLINE void upb_register_handlerset(upb_handlers *h, upb_handlerset *set) {
h->set = set;
}
INLINE void upb_set_handler_closure(upb_handlers *h, void *closure) {
h->closure = closure;
}
// upb_dispatcher
typedef struct {
upb_handlers handlers;
int depth;
} upb_dispatcher_frame;
struct _upb_dispatcher {
upb_dispatcher_frame stack[UPB_MAX_NESTING], *top, *limit;
};
INLINE void upb_dispatcher_init(upb_dispatcher *d) {
d->limit = d->stack + sizeof(d->stack);
}
INLINE void upb_dispatcher_reset(upb_dispatcher *d, upb_handlers *h) {
d->top = d->stack;
d->top->depth = 1; // Never want to trigger end-of-delegation.
d->top->handlers = *h;
}
INLINE void upb_dispatch_startmsg(upb_dispatcher *d) {
assert(d->stack == d->top);
d->top->handlers.set->startmsg(d->top->handlers.closure);
}
INLINE void upb_dispatch_endmsg(upb_dispatcher *d) {
assert(d->stack == d->top);
d->top->handlers.set->endmsg(d->top->handlers.closure);
}
INLINE upb_flow_t upb_dispatch_startsubmsg(upb_dispatcher *d,
struct _upb_fielddef *f) {
upb_handlers handlers;
upb_handlers_init(&handlers);
upb_handlers_reset(&handlers);
upb_flow_t ret = d->top->handlers.set->startsubmsg(d->top->handlers.closure, f, &handlers);
assert((ret == UPB_DELEGATE) == !upb_handlers_isempty(&handlers));
if (ret == UPB_DELEGATE) {
++d->top;
d->top->handlers = handlers;
d->top->depth = 0;
d->top->handlers.set->startmsg(d->top->handlers.closure);
ret = UPB_CONTINUE;
}
++d->top->depth;
upb_handlers_uninit(&handlers);
return ret;
}
INLINE upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d) {
if (--d->top->depth == 0) {
d->top->handlers.set->endmsg(d->top->handlers.closure);
--d->top;
}
return d->top->handlers.set->endsubmsg(d->top->handlers.closure);
}
INLINE upb_flow_t upb_dispatch_value(upb_dispatcher *d,
struct _upb_fielddef *f,
upb_value val) {
return d->top->handlers.set->value(d->top->handlers.closure, f, val);
}
INLINE upb_flow_t upb_dispatch_unknownval(upb_dispatcher *d,
upb_field_number_t fieldnum,
upb_value val) {
return d->top->handlers.set->unknownval(d->top->handlers.closure,
fieldnum, val);
}
// upb_bytesink
INLINE int32_t upb_bytesink_put(upb_bytesink *sink, upb_string *str) {
return sink->vtbl->put(sink, str);
}
INLINE upb_status *upb_bytesink_status(upb_bytesink *sink) {
return &sink->status;
}
// upb_bytesink
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif