summaryrefslogtreecommitdiff
path: root/upb
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2011-09-04 19:29:36 -0700
committerJoshua Haberman <jhaberman@gmail.com>2011-09-04 19:29:36 -0700
commit621c0cdcb5efc4f7c2382031becded018ef0b62b (patch)
treed6af78ef0872c9db0f48c99e6c93b8d4c43fa689 /upb
parent8f2758dda2ba12b78ae8f8c7170decc5e88dd28c (diff)
Const invasion: large parts of upb made const-correct.
Diffstat (limited to 'upb')
-rw-r--r--upb/atomic.h20
-rw-r--r--upb/bytestream.c11
-rw-r--r--upb/bytestream.h10
-rw-r--r--upb/def.c71
-rw-r--r--upb/def.h172
-rw-r--r--upb/handlers.c4
-rw-r--r--upb/handlers.h14
-rw-r--r--upb/msg.c31
-rw-r--r--upb/msg.h24
-rw-r--r--upb/pb/decoder_x86.dasc4
-rw-r--r--upb/pb/glue.c27
-rw-r--r--upb/pb/glue.h23
-rw-r--r--upb/pb/textprinter.c14
-rw-r--r--upb/pb/textprinter.h2
-rw-r--r--upb/table.c27
-rw-r--r--upb/table.h24
-rw-r--r--upb/upb.c5
-rw-r--r--upb/upb.h13
18 files changed, 280 insertions, 216 deletions
diff --git a/upb/atomic.h b/upb/atomic.h
index e82ad8f..2478fe4 100644
--- a/upb/atomic.h
+++ b/upb/atomic.h
@@ -130,11 +130,11 @@ INLINE bool upb_atomic_only(upb_atomic_t *a) {
typedef struct {
} upb_rwlock_t;
-INLINE void upb_rwlock_init(upb_rwlock_t *l) { (void)l; }
-INLINE void upb_rwlock_destroy(upb_rwlock_t *l) { (void)l; }
-INLINE void upb_rwlock_rdlock(upb_rwlock_t *l) { (void)l; }
-INLINE void upb_rwlock_wrlock(upb_rwlock_t *l) { (void)l; }
-INLINE void upb_rwlock_unlock(upb_rwlock_t *l) { (void)l; }
+INLINE void upb_rwlock_init(const upb_rwlock_t *l) { (void)l; }
+INLINE void upb_rwlock_destroy(const upb_rwlock_t *l) { (void)l; }
+INLINE void upb_rwlock_rdlock(const upb_rwlock_t *l) { (void)l; }
+INLINE void upb_rwlock_wrlock(const upb_rwlock_t *l) { (void)l; }
+INLINE void upb_rwlock_unlock(const upb_rwlock_t *l) { (void)l; }
#elif defined(UPB_USE_PTHREADS)
@@ -144,27 +144,27 @@ typedef struct {
pthread_rwlock_t lock;
} upb_rwlock_t;
-INLINE void upb_rwlock_init(upb_rwlock_t *l) {
+INLINE void upb_rwlock_init(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_init(&l->lock, NULL);
}
-INLINE void upb_rwlock_destroy(upb_rwlock_t *l) {
+INLINE void upb_rwlock_destroy(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_destroy(&l->lock);
}
-INLINE void upb_rwlock_rdlock(upb_rwlock_t *l) {
+INLINE void upb_rwlock_rdlock(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_rdlock(&l->lock);
}
-INLINE void upb_rwlock_wrlock(upb_rwlock_t *l) {
+INLINE void upb_rwlock_wrlock(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_wrlock(&l->lock);
}
-INLINE void upb_rwlock_unlock(upb_rwlock_t *l) {
+INLINE void upb_rwlock_unlock(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_unlock(&l->lock);
}
diff --git a/upb/bytestream.c b/upb/bytestream.c
index 09a1fb9..36be4b1 100644
--- a/upb/bytestream.c
+++ b/upb/bytestream.c
@@ -14,7 +14,7 @@
// We can make this configurable if necessary.
#define BUF_SIZE 32768
-char *upb_strref_dup(struct _upb_strref *r) {
+char *upb_strref_dup(const struct _upb_strref *r) {
char *ret = (char*)malloc(r->len + 1);
upb_bytesrc_read(r->bytesrc, r->stream_offset, r->len, ret);
ret[r->len] = '\0';
@@ -38,7 +38,7 @@ int upb_stdio_cmpbuf(const void *_key, const void *_elem) {
return (*ofs / BUF_SIZE) - (buf->ofs / BUF_SIZE);
}
-static upb_stdio_buf *upb_stdio_findbuf(upb_stdio *s, uint64_t ofs) {
+static upb_stdio_buf *upb_stdio_findbuf(const upb_stdio *s, uint64_t ofs) {
// TODO: it is probably faster to linear search short lists, and to
// special-case the last one or two bufs.
return bsearch(&ofs, s->bufs, s->nbuf, sizeof(*s->bufs), &upb_stdio_cmpbuf);
@@ -86,7 +86,7 @@ size_t upb_stdio_fetch(void *src, uint64_t ofs, upb_status *s) {
return buf->ofs + buf->len;
}
-void upb_stdio_read(void *src, uint64_t src_ofs, size_t len, char *dst) {
+void upb_stdio_read(const void *src, uint64_t src_ofs, size_t len, char *dst) {
upb_stdio_buf *buf = upb_stdio_findbuf(src, src_ofs);
src_ofs -= buf->ofs;
memcpy(dst, &buf->data[src_ofs], BUF_SIZE - src_ofs);
@@ -203,8 +203,9 @@ size_t upb_stringsrc_fetch(void *_src, uint64_t ofs, upb_status *s) {
return src->len - ofs;
}
-void upb_stringsrc_read(void *_src, uint64_t src_ofs, size_t len, char *dst) {
- upb_stringsrc *src = _src;
+void upb_stringsrc_read(const void *_src, uint64_t src_ofs,
+ size_t len, char *dst) {
+ const upb_stringsrc *src = _src;
memcpy(dst, src->str + src_ofs, len);
}
diff --git a/upb/bytestream.h b/upb/bytestream.h
index 0a744f6..96d840c 100644
--- a/upb/bytestream.h
+++ b/upb/bytestream.h
@@ -36,7 +36,7 @@ extern "C" {
// data around for later use, without requiring a copy out of the input
// buffers.
typedef size_t upb_bytesrc_fetch_func(void*, uint64_t, upb_status*);
-typedef void upb_bytesrc_read_func(void*, uint64_t, size_t, char*);
+typedef void upb_bytesrc_read_func(const void*, uint64_t, size_t, char*);
typedef const char *upb_bytesrc_getptr_func(void*, uint64_t, size_t*);
typedef void upb_bytesrc_refregion_func(void*, uint64_t, size_t);
typedef void upb_bytesrc_ref_func(void*);
@@ -74,8 +74,8 @@ INLINE size_t upb_bytesrc_fetch(upb_bytesrc *src, uint64_t ofs, upb_status *s) {
// Copies "len" bytes of data from offset src_ofs to "dst", which must be at
// least "len" bytes long. The caller must own a ref on the given region.
-INLINE void upb_bytesrc_read(upb_bytesrc *src, uint64_t src_ofs, size_t len,
- char *dst) {
+INLINE void upb_bytesrc_read(const upb_bytesrc *src, uint64_t src_ofs,
+ size_t len, char *dst) {
src->vtbl->read(src, src_ofs, len, dst);
}
@@ -149,9 +149,9 @@ typedef struct _upb_strref {
// Copies the contents of the strref into a newly-allocated, NULL-terminated
// string.
-char *upb_strref_dup(struct _upb_strref *r);
+char *upb_strref_dup(const struct _upb_strref *r);
-INLINE void upb_strref_read(struct _upb_strref *r, char *buf) {
+INLINE void upb_strref_read(const struct _upb_strref *r, char *buf) {
if (r->ptr) {
memcpy(buf, r->ptr, r->len);
} else {
diff --git a/upb/def.c b/upb/def.c
index ee793a9..555d763 100644
--- a/upb/def.c
+++ b/upb/def.c
@@ -38,7 +38,7 @@ static void upb_msgdef_free(upb_msgdef *m);
static void upb_enumdef_free(upb_enumdef *e);
static void upb_unresolveddef_free(struct _upb_unresolveddef *u);
-bool upb_def_ismutable(upb_def *def) { return def->symtab == NULL; }
+bool upb_def_ismutable(const upb_def *def) { return def->symtab == NULL; }
bool upb_def_setfqname(upb_def *def, const char *fqname) {
assert(upb_def_ismutable(def));
@@ -58,10 +58,12 @@ static void upb_def_free(upb_def *def) {
}
}
-upb_def *upb_def_dup(upb_def *def) {
+upb_def *upb_def_dup(const upb_def *def) {
switch (def->type) {
- case UPB_DEF_MSG: return UPB_UPCAST(upb_msgdef_dup(upb_downcast_msgdef(def)));
- case UPB_DEF_ENUM: return UPB_UPCAST(upb_enumdef_dup(upb_downcast_enumdef(def)));
+ case UPB_DEF_MSG:
+ return UPB_UPCAST(upb_msgdef_dup(upb_downcast_msgdef_const(def)));
+ case UPB_DEF_ENUM:
+ return UPB_UPCAST(upb_enumdef_dup(upb_downcast_enumdef_const(def)));
default: assert(false); return NULL;
}
}
@@ -70,7 +72,8 @@ upb_def *upb_def_dup(upb_def *def) {
// def itself. If the refcount falls to zero, the def is deleted. Once the
// def belongs to a symtab, the def is owned by the symtab and its refcount
// determines whether the def owns a ref on the symtab or not.
-void upb_def_ref(upb_def *def) {
+void upb_def_ref(const upb_def *_def) {
+ upb_def *def = (upb_def*)_def; // Need to modify refcount.
if (upb_atomic_ref(&def->refcount) && def->symtab)
upb_symtab_ref(def->symtab);
}
@@ -83,7 +86,8 @@ static void upb_def_movetosymtab(upb_def *d, upb_symtab *s) {
if (m) upb_inttable_compact(&m->itof);
}
-void upb_def_unref(upb_def *def) {
+void upb_def_unref(const upb_def *_def) {
+ upb_def *def = (upb_def*)_def; // Need to modify refcount.
if (!def) return;
if (upb_atomic_unref(&def->refcount)) {
if (def->symtab) {
@@ -152,7 +156,7 @@ static void upb_enumdef_free(upb_enumdef *e) {
free(e);
}
-upb_enumdef *upb_enumdef_dup(upb_enumdef *e) {
+upb_enumdef *upb_enumdef_dup(const upb_enumdef *e) {
upb_enumdef *new_e = upb_enumdef_new();
upb_enum_iter i;
for(i = upb_enum_begin(e); !upb_enum_done(i); i = upb_enum_next(e, i)) {
@@ -176,12 +180,12 @@ void upb_enumdef_setdefault(upb_enumdef *e, int32_t val) {
e->defaultval = val;
}
-upb_enum_iter upb_enum_begin(upb_enumdef *e) {
+upb_enum_iter upb_enum_begin(const upb_enumdef *e) {
// We could iterate over either table here; the choice is arbitrary.
return upb_inttable_begin(&e->iton);
}
-upb_enum_iter upb_enum_next(upb_enumdef *e, upb_enum_iter iter) {
+upb_enum_iter upb_enum_next(const upb_enumdef *e, upb_enum_iter iter) {
return upb_inttable_next(&e->iton, iter);
}
@@ -267,11 +271,11 @@ upb_fielddef *upb_fielddef_dup(upb_fielddef *f) {
return f;
}
-bool upb_fielddef_ismutable(upb_fielddef *f) {
+bool upb_fielddef_ismutable(const upb_fielddef *f) {
return !f->msgdef || upb_def_ismutable(UPB_UPCAST(f->msgdef));
}
-upb_def *upb_fielddef_subdef(upb_fielddef *f) {
+upb_def *upb_fielddef_subdef(const upb_fielddef *f) {
if (upb_hassubdef(f) && !upb_fielddef_ismutable(f))
return f->def;
else
@@ -403,7 +407,7 @@ static void upb_msgdef_free(upb_msgdef *m) {
free(m);
}
-upb_msgdef *upb_msgdef_dup(upb_msgdef *m) {
+upb_msgdef *upb_msgdef_dup(const upb_msgdef *m) {
upb_msgdef *newm = upb_msgdef_new();
newm->size = m->size;
newm->hasbit_bytes = m->hasbit_bytes;
@@ -512,31 +516,24 @@ void upb_msgdef_layout(upb_msgdef *m) {
free(sorted_fields);
}
-upb_msg_iter upb_msg_begin(upb_msgdef *m) {
+upb_msg_iter upb_msg_begin(const upb_msgdef *m) {
return upb_inttable_begin(&m->itof);
}
-upb_msg_iter upb_msg_next(upb_msgdef *m, upb_msg_iter iter) {
+upb_msg_iter upb_msg_next(const upb_msgdef *m, upb_msg_iter iter) {
return upb_inttable_next(&m->itof, iter);
}
/* upb_symtab *****************************************************************/
-struct _upb_symtab {
- upb_atomic_t refcount;
- upb_rwlock_t lock; // Protects all members except the refcount.
- upb_strtable symtab; // The symbol table.
- upb_deflist olddefs;
-};
-
typedef struct {
upb_def *def;
} upb_symtab_ent;
// Given a symbol and the base symbol inside which it is defined, find the
// symbol's definition in t.
-static upb_symtab_ent *upb_resolve(upb_strtable *t,
+static upb_symtab_ent *upb_resolve(const upb_strtable *t,
const char *base, const char *sym) {
if(strlen(sym) == 0) return NULL;
if(sym[0] == UPB_SYMBOL_SEPARATOR) {
@@ -575,9 +572,13 @@ static void upb_symtab_free(upb_symtab *s) {
free(s);
}
-void upb_symtab_ref(upb_symtab *s) { upb_atomic_ref(&s->refcount); }
+void upb_symtab_ref(const upb_symtab *_s) {
+ upb_symtab *s = (upb_symtab*)_s;
+ upb_atomic_ref(&s->refcount);
+}
-void upb_symtab_unref(upb_symtab *s) {
+void upb_symtab_unref(const upb_symtab *_s) {
+ upb_symtab *s = (upb_symtab*)_s;
if(s && upb_atomic_unref(&s->refcount)) {
upb_symtab_free(s);
}
@@ -592,12 +593,13 @@ upb_symtab *upb_symtab_new() {
return s;
}
-upb_def **upb_symtab_getdefs(upb_symtab *s, int *count, upb_deftype_t type) {
+const upb_def **upb_symtab_getdefs(const upb_symtab *s, int *count,
+ upb_deftype_t type) {
upb_rwlock_rdlock(&s->lock);
int total = upb_strtable_count(&s->symtab);
// We may only use part of this, depending on how many symbols are of the
// correct type.
- upb_def **defs = malloc(sizeof(*defs) * total);
+ const upb_def **defs = malloc(sizeof(*defs) * total);
upb_strtable_iter iter;
upb_strtable_begin(&iter, &s->symtab);
int i = 0;
@@ -614,7 +616,7 @@ upb_def **upb_symtab_getdefs(upb_symtab *s, int *count, upb_deftype_t type) {
return defs;
}
-upb_def *upb_symtab_lookup(upb_symtab *s, const char *sym) {
+const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym) {
upb_rwlock_rdlock(&s->lock);
upb_symtab_ent *e = upb_strtable_lookup(&s->symtab, sym);
upb_def *ret = NULL;
@@ -626,7 +628,20 @@ upb_def *upb_symtab_lookup(upb_symtab *s, const char *sym) {
return ret;
}
-upb_def *upb_symtab_resolve(upb_symtab *s, const char *base, const char *sym) {
+const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
+ upb_rwlock_rdlock(&s->lock);
+ upb_symtab_ent *e = upb_strtable_lookup(&s->symtab, sym);
+ upb_msgdef *ret = NULL;
+ if(e && e->def->type == UPB_DEF_MSG) {
+ ret = upb_downcast_msgdef(e->def);
+ upb_def_ref(UPB_UPCAST(ret));
+ }
+ upb_rwlock_unlock(&s->lock);
+ return ret;
+}
+
+const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
+ const char *sym) {
upb_rwlock_rdlock(&s->lock);
upb_symtab_ent *e = upb_resolve(&s->symtab, base, sym);
upb_def *ret = NULL;
diff --git a/upb/def.h b/upb/def.h
index 4dc9c16..361753c 100644
--- a/upb/def.h
+++ b/upb/def.h
@@ -11,13 +11,36 @@
* - upb_enumdef: describes an enum.
* (TODO: definitions of services).
*
- * These defs are mutable (and not thread-safe) when first created.
- * Once they are added to a defbuilder (and later its symtab) they become
- * immutable.
*
- * TODO: consider making thread-safe even when first created by using mutexes
- * internally. Would also have to change any methods returning pointers to
- * return copies instead.
+ * Defs go through two distinct phases of life:
+ *
+ * 1. MUTABLE: when first created, the properties of the def can be set freely
+ * (for example a message's name, its list of fields, the name/number of
+ * fields, etc). During this phase the def is *not* thread-safe, and may
+ * not be used for any purpose except to set its properties (it can't be
+ * used to parse anything, create any messages in memory, etc).
+ *
+ * 2. IMMUTABLE: after being added to a symtab (which links the defs together)
+ * the defs become thread-safe and immutable. Programs may only access defs
+ * through a CONST POINTER during this stage -- upb_symtab will help you out
+ * with this requirement by only vending const pointers, but you need to
+ * make sure not to use any non-const pointers you still have sitting
+ * around. In practice this means that you may not call any setters on the
+ * defs (or functions that themselves call the setters). If you want to
+ * modify an existing immutable def, copy it with upb_*_dup(), modify the
+ * copy, and add the modified def to the symtab (replacing the existing
+ * def).
+ *
+ * You can test for which stage of life a def is in by calling
+ * upb_def_ismutable(). This is particularly useful for dynamic language
+ * bindings, which must properly guarantee that the dynamic language cannot
+ * break the rules laid out above.
+ *
+ * It would be possible to make the defs thread-safe during stage 1 by using
+ * mutexes internally and changing any methods returning pointers to return
+ * copies instead. This could be important if we are integrating with a VM or
+ * interpreter that does not naturally serialize access to wrapped objects (for
+ * example, in the case of Python this is not necessary because of the GIL).
*/
#ifndef UPB_DEF_H_
@@ -58,13 +81,13 @@ typedef struct {
// until the def is in a symtab. While a def is in a symtab, everything
// reachable from that def (the symtab and all defs in the symtab) are
// guaranteed to be alive.
-void upb_def_ref(upb_def *def);
-void upb_def_unref(upb_def *def);
-upb_def *upb_def_dup(upb_def *def);
+void upb_def_ref(const upb_def *def);
+void upb_def_unref(const upb_def *def);
+upb_def *upb_def_dup(const upb_def *def);
// A def is mutable until it has been added to a symtab.
-bool upb_def_ismutable(upb_def *def);
-INLINE const char *upb_def_fqname(upb_def *def) { return def->fqname; }
+bool upb_def_ismutable(const upb_def *def);
+INLINE const char *upb_def_fqname(const upb_def *def) { return def->fqname; }
bool upb_def_setfqname(upb_def *def, const char *fqname); // Only if mutable.
#define UPB_UPCAST(ptr) (&(ptr)->base)
@@ -103,7 +126,7 @@ void upb_fielddef_unref(upb_fielddef *f);
upb_fielddef *upb_fielddef_dup(upb_fielddef *f);
// A fielddef is mutable until its msgdef has been added to a symtab.
-bool upb_fielddef_ismutable(upb_fielddef *f);
+bool upb_fielddef_ismutable(const upb_fielddef *f);
// Read accessors. May be called any time.
INLINE uint8_t upb_fielddef_type(upb_fielddef *f) { return f->type; }
@@ -127,7 +150,7 @@ INLINE const char *upb_fielddef_typename(upb_fielddef *f) {
// submessage, group, and enum fields (ie. when upb_hassubdef(f) is true).
// Since defs are not linked together until they are in a symtab, this
// will return NULL until the msgdef is in a symtab.
-upb_def *upb_fielddef_subdef(upb_fielddef *f);
+upb_def *upb_fielddef_subdef(const upb_fielddef *f);
// Write accessors. "Number" and "name" must be set before the fielddef is
// added to a msgdef. For the moment we do not allow these to be set once
@@ -155,12 +178,12 @@ INLINE bool upb_isstringtype(upb_fieldtype_t type) {
INLINE bool upb_isprimitivetype(upb_fieldtype_t type) {
return !upb_issubmsgtype(type) && !upb_isstringtype(type);
}
-INLINE bool upb_issubmsg(upb_fielddef *f) { return upb_issubmsgtype(f->type); }
-INLINE bool upb_isstring(upb_fielddef *f) { return upb_isstringtype(f->type); }
-INLINE bool upb_isseq(upb_fielddef *f) { return f->label == UPB_LABEL(REPEATED); }
+INLINE bool upb_issubmsg(const upb_fielddef *f) { return upb_issubmsgtype(f->type); }
+INLINE bool upb_isstring(const upb_fielddef *f) { return upb_isstringtype(f->type); }
+INLINE bool upb_isseq(const upb_fielddef *f) { return f->label == UPB_LABEL(REPEATED); }
// Does the type of this field imply that it should contain an associated def?
-INLINE bool upb_hassubdef(upb_fielddef *f) {
+INLINE bool upb_hassubdef(const upb_fielddef *f) {
return upb_issubmsg(f) || f->type == UPB_TYPE(ENUM);
}
@@ -192,22 +215,22 @@ typedef struct {
} upb_ntof_ent;
upb_msgdef *upb_msgdef_new(void);
-INLINE void upb_msgdef_unref(upb_msgdef *md) { upb_def_unref(UPB_UPCAST(md)); }
-INLINE void upb_msgdef_ref(upb_msgdef *md) { upb_def_ref(UPB_UPCAST(md)); }
+INLINE void upb_msgdef_unref(const upb_msgdef *md) { upb_def_unref(UPB_UPCAST(md)); }
+INLINE void upb_msgdef_ref(const upb_msgdef *md) { upb_def_ref(UPB_UPCAST(md)); }
// Returns a new msgdef that is a copy of the given msgdef (and a copy of all
// the fields) but with any references to submessages broken and replaced with
// just the name of the submessage. This can be put back into another symtab
// and the names will be re-resolved in the new context.
-upb_msgdef *upb_msgdef_dup(upb_msgdef *m);
+upb_msgdef *upb_msgdef_dup(const upb_msgdef *m);
// Read accessors. May be called at any time.
-INLINE uint16_t upb_msgdef_size(upb_msgdef *m) { return m->size; }
-INLINE uint8_t upb_msgdef_hasbit_bytes(upb_msgdef *m) {
+INLINE uint16_t upb_msgdef_size(const upb_msgdef *m) { return m->size; }
+INLINE uint8_t upb_msgdef_hasbit_bytes(const upb_msgdef *m) {
return m->hasbit_bytes;
}
-INLINE uint32_t upb_msgdef_extstart(upb_msgdef *m) { return m->extstart; }
-INLINE uint32_t upb_msgdef_extend(upb_msgdef *m) { return m->extend; }
+INLINE uint32_t upb_msgdef_extstart(const upb_msgdef *m) { return m->extstart; }
+INLINE uint32_t upb_msgdef_extend(const upb_msgdef *m) { return m->extend; }
// Write accessors. May only be called before the msgdef is in a symtab.
void upb_msgdef_setsize(upb_msgdef *m, uint16_t size);
@@ -248,7 +271,7 @@ INLINE upb_fielddef *upb_msgdef_ntof(upb_msgdef *m, const char *name) {
return e ? e->f : NULL;
}
-INLINE int upb_msgdef_numfields(upb_msgdef *m) {
+INLINE int upb_msgdef_numfields(const upb_msgdef *m) {
return upb_strtable_count(&m->ntof);
}
@@ -262,8 +285,8 @@ INLINE int upb_msgdef_numfields(upb_msgdef *m) {
// }
typedef upb_inttable_iter upb_msg_iter;
-upb_msg_iter upb_msg_begin(upb_msgdef *m);
-upb_msg_iter upb_msg_next(upb_msgdef *m, upb_msg_iter iter);
+upb_msg_iter upb_msg_begin(const upb_msgdef *m);
+upb_msg_iter upb_msg_next(const upb_msgdef *m, upb_msg_iter iter);
INLINE bool upb_msg_done(upb_msg_iter iter) { return upb_inttable_done(iter); }
// Iterator accessor.
@@ -292,9 +315,9 @@ typedef struct {
} upb_iton_ent;
upb_enumdef *upb_enumdef_new(void);
-INLINE void upb_enumdef_ref(upb_enumdef *e) { upb_def_ref(UPB_UPCAST(e)); }
-INLINE void upb_enumdef_unref(upb_enumdef *e) { upb_def_unref(UPB_UPCAST(e)); }
-upb_enumdef *upb_enumdef_dup(upb_enumdef *e);
+INLINE void upb_enumdef_ref(const upb_enumdef *e) { upb_def_ref(UPB_UPCAST(e)); }
+INLINE void upb_enumdef_unref(const upb_enumdef *e) { upb_def_unref(UPB_UPCAST(e)); }
+upb_enumdef *upb_enumdef_dup(const upb_enumdef *e);
INLINE int32_t upb_enumdef_default(upb_enumdef *e) { return e->defaultval; }
@@ -320,8 +343,8 @@ const char *upb_enumdef_iton(upb_enumdef *e, int32_t num);
// }
typedef upb_inttable_iter upb_enum_iter;
-upb_enum_iter upb_enum_begin(upb_enumdef *e);
-upb_enum_iter upb_enum_next(upb_enumdef *e, upb_enum_iter iter);
+upb_enum_iter upb_enum_begin(const upb_enumdef *e);
+upb_enum_iter upb_enum_next(const upb_enumdef *e, upb_enum_iter iter);
INLINE bool upb_enum_done(upb_enum_iter iter) { return upb_inttable_done(iter); }
// Iterator accessors.
@@ -334,15 +357,36 @@ INLINE int32_t upb_enum_iter_number(upb_enum_iter iter) {
}
+/* upb_deflist ****************************************************************/
+
+// upb_deflist is an internal-only dynamic array for storing a growing list of
+// upb_defs.
+typedef struct {
+ upb_def **defs;
+ uint32_t len;
+ uint32_t size;
+} upb_deflist;
+
+void upb_deflist_init(upb_deflist *l);
+void upb_deflist_uninit(upb_deflist *l);
+void upb_deflist_push(upb_deflist *l, upb_def *d);
+
+
/* upb_symtab *****************************************************************/
// A symtab (symbol table) is where upb_defs live. It is empty when first
// constructed. Clients add definitions to the symtab (or replace existing
// definitions) by calling upb_symtab_add().
+struct _upb_symtab {
+ upb_atomic_t refcount;
+ upb_rwlock_t lock; // Protects all members except the refcount.
+ upb_strtable symtab; // The symbol table.
+ upb_deflist olddefs;
+};
upb_symtab *upb_symtab_new(void);
-void upb_symtab_ref(upb_symtab *s);
-void upb_symtab_unref(upb_symtab *s);
+void upb_symtab_ref(const upb_symtab *s);
+void upb_symtab_unref(const upb_symtab *s);
// Resolves the given symbol using the rules described in descriptor.proto,
// namely:
@@ -354,20 +398,19 @@ void upb_symtab_unref(upb_symtab *s);
//
// If a def is found, the caller owns one ref on the returned def. Otherwise
// returns NULL.
-// TODO: make return const
-upb_def *upb_symtab_resolve(upb_symtab *s, const char *base, const char *sym);
+const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
+ const char *sym);
// Find an entry in the symbol table with this exact name. If a def is found,
// the caller owns one ref on the returned def. Otherwise returns NULL.
-// TODO: make return const
-upb_def *upb_symtab_lookup(upb_symtab *s, const char *sym);
+const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym);
+const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym);
// Gets an array of pointers to all currently active defs in this symtab. The
// caller owns the returned array (which is of length *count) as well as a ref
// to each symbol inside. If type is UPB_DEF_ANY then defs of all types are
// returned, otherwise only defs of the required type are returned.
-// TODO: make return const
-upb_def **upb_symtab_getdefs(upb_symtab *s, int *n, upb_deftype_t type);
+const upb_def **upb_symtab_getdefs(const upb_symtab *s, int *n, upb_deftype_t type);
// Adds the given defs to the symtab, resolving all symbols. Only one def per
// name may be in the list, but defs can replace existing defs in the symtab.
@@ -385,46 +428,31 @@ void upb_symtab_gc(upb_symtab *s);
/* upb_def casts **************************************************************/
// Dynamic casts, for determining if a def is of a particular type at runtime.
-#define UPB_DYNAMIC_CAST_DEF(lower, upper) \
+// Downcasts, for when some wants to assert that a def is of a particular type.
+// These are only checked if we are building debug.
+#define UPB_DEF_CASTS(lower, upper) \
struct _upb_ ## lower; /* Forward-declare. */ \
INLINE struct _upb_ ## lower *upb_dyncast_ ## lower(upb_def *def) { \
if(def->type != UPB_DEF_ ## upper) return NULL; \
return (struct _upb_ ## lower*)def; \
- }
-UPB_DYNAMIC_CAST_DEF(msgdef, MSG);
-UPB_DYNAMIC_CAST_DEF(enumdef, ENUM);
-UPB_DYNAMIC_CAST_DEF(svcdef, SERVICE);
-UPB_DYNAMIC_CAST_DEF(unresolveddef, UNRESOLVED);
-#undef UPB_DYNAMIC_CAST_DEF
-
-// Downcasts, for when some wants to assert that a def is of a particular type.
-// These are only checked if we are building debug.
-#define UPB_DOWNCAST_DEF(lower, upper) \
- struct _upb_ ## lower; /* Forward-declare. */ \
+ } \
+ INLINE const struct _upb_ ## lower *upb_dyncast_ ## lower ## _const(const upb_def *def) { \
+ if(def->type != UPB_DEF_ ## upper) return NULL; \
+ return (const struct _upb_ ## lower*)def; \
+ } \
INLINE struct _upb_ ## lower *upb_downcast_ ## lower(upb_def *def) { \
assert(def->type == UPB_DEF_ ## upper); \
return (struct _upb_ ## lower*)def; \
+ } \
+ INLINE const struct _upb_ ## lower *upb_downcast_ ## lower ## _const(const upb_def *def) { \
+ assert(def->type == UPB_DEF_ ## upper); \
+ return (const struct _upb_ ## lower*)def; \
}
-UPB_DOWNCAST_DEF(msgdef, MSG);
-UPB_DOWNCAST_DEF(enumdef, ENUM);
-UPB_DOWNCAST_DEF(svcdef, SERVICE);
-UPB_DOWNCAST_DEF(unresolveddef, UNRESOLVED);
-#undef UPB_DOWNCAST_DEF
-
-
-/* upb_deflist ****************************************************************/
-
-// upb_deflist is an internal-only dynamic array for storing a growing list of
-// upb_defs.
-typedef struct {
- upb_def **defs;
- uint32_t len;
- uint32_t size;
-} upb_deflist;
-
-void upb_deflist_init(upb_deflist *l);
-void upb_deflist_uninit(upb_deflist *l);
-void upb_deflist_push(upb_deflist *l, upb_def *d);
+UPB_DEF_CASTS(msgdef, MSG);
+UPB_DEF_CASTS(enumdef, ENUM);
+UPB_DEF_CASTS(svcdef, SERVICE);
+UPB_DEF_CASTS(unresolveddef, UNRESOLVED);
+#undef UPB_DEF_CASTS
#ifdef __cplusplus
} /* extern "C" */
diff --git a/upb/handlers.c b/upb/handlers.c
index b2d9f94..0af09ef 100644
--- a/upb/handlers.c
+++ b/upb/handlers.c
@@ -107,7 +107,7 @@ typedef struct {
upb_mhandlers *mh;
} upb_mtab_ent;
-static upb_mhandlers *upb_regmsg_dfs(upb_handlers *h, upb_msgdef *m,
+static upb_mhandlers *upb_regmsg_dfs(upb_handlers *h, const upb_msgdef *m,
upb_onmsgreg *msgreg_cb,
upb_onfieldreg *fieldreg_cb,
void *closure, upb_strtable *mtab) {
@@ -139,7 +139,7 @@ static upb_mhandlers *upb_regmsg_dfs(upb_handlers *h, upb_msgdef *m,
return mh;
}
-upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, upb_msgdef *m,
+upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, const upb_msgdef *m,
upb_onmsgreg *msgreg_cb,
upb_onfieldreg *fieldreg_cb,
void *closure) {
diff --git a/upb/handlers.h b/upb/handlers.h
index a7c1d9d..c127741 100644
--- a/upb/handlers.h
+++ b/upb/handlers.h
@@ -166,7 +166,7 @@ void upb_fhandlers_unref(upb_fhandlers *m);
// upb_fhandlers accessors
#define UPB_FHANDLERS_ACCESSORS(name, type) \
INLINE void upb_fhandlers_set ## name(upb_fhandlers *f, type v){f->name = v;} \
- INLINE type upb_fhandlers_get ## name(upb_fhandlers *f) { return f->name; }
+ INLINE type upb_fhandlers_get ## name(const upb_fhandlers *f) { return f->name; }
UPB_FHANDLERS_ACCESSORS(fval, upb_value)
UPB_FHANDLERS_ACCESSORS(value, upb_value_handler*)
UPB_FHANDLERS_ACCESSORS(startsubmsg, upb_startfield_handler*)
@@ -257,9 +257,9 @@ upb_mhandlers *upb_handlers_getmhandlers(upb_handlers *h, int index);
// with "fieldreg_cb"
//
// See upb_handlers_reghandlerset() below for an example.
-typedef void upb_onmsgreg(void *closure, upb_mhandlers *mh, upb_msgdef *m);
-typedef void upb_onfieldreg(void *closure, upb_fhandlers *mh, upb_fielddef *m);
-upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, upb_msgdef *m,
+typedef void upb_onmsgreg(void *closure, upb_mhandlers *mh, const upb_msgdef *m);
+typedef void upb_onfieldreg(void *closure, upb_fhandlers *mh, const upb_fielddef *m);
+upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, const upb_msgdef *m,
upb_onmsgreg *msgreg_cb,
upb_onfieldreg *fieldreg_cb,
void *closure);
@@ -278,13 +278,13 @@ typedef struct {
upb_endfield_handler *endseq;
} upb_handlerset;
-INLINE void upb_onmreg_hset(void *c, upb_mhandlers *mh, upb_msgdef *m) {
+INLINE void upb_onmreg_hset(void *c, upb_mhandlers *mh, const upb_msgdef *m) {
(void)m;
upb_handlerset *hs = (upb_handlerset*)c;
if (hs->startmsg) upb_mhandlers_setstartmsg(mh, hs->startmsg);
if (hs->endmsg) upb_mhandlers_setendmsg(mh, hs->endmsg);
}
-INLINE void upb_onfreg_hset(void *c, upb_fhandlers *fh, upb_fielddef *f) {
+INLINE void upb_onfreg_hset(void *c, upb_fhandlers *fh, const upb_fielddef *f) {
upb_handlerset *hs = (upb_handlerset*)c;
if (hs->value) upb_fhandlers_setvalue(fh, hs->value);
if (hs->startsubmsg) upb_fhandlers_setstartsubmsg(fh, hs->startsubmsg);
@@ -295,7 +295,7 @@ INLINE void upb_onfreg_hset(void *c, upb_fhandlers *fh, upb_fielddef *f) {
upb_value_setfielddef(&val, f);
upb_fhandlers_setfval(fh, val);
}
-INLINE upb_mhandlers *upb_handlers_reghandlerset(upb_handlers *h, upb_msgdef *m,
+INLINE upb_mhandlers *upb_handlers_reghandlerset(upb_handlers *h, const upb_msgdef *m,
upb_handlerset *hs) {
return upb_handlers_regmsgdef(h, m, &upb_onmreg_hset, &upb_onfreg_hset, hs);
}
diff --git a/upb/msg.c b/upb/msg.c
index 65c358e..ece22ab 100644
--- a/upb/msg.c
+++ b/upb/msg.c
@@ -10,7 +10,7 @@
#include "upb/upb.h"
#include "upb/msg.h"
-void upb_msg_clear(void *msg, upb_msgdef *md) {
+void upb_msg_clear(void *msg, const upb_msgdef *md) {
assert(msg != NULL);
memset(msg, 0, md->hasbit_bytes);
// TODO: set primitive fields to defaults?
@@ -85,14 +85,14 @@ void upb_msg_runhandlers(upb_msg *msg, upb_msgdef *md, upb_handlers *h,
void upb_stdmsg_sethas(void *_m, upb_value fval) {
assert(_m != NULL);
char *m = _m;
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
if (f->hasbit >= 0) m[f->hasbit / 8] |= (1 << (f->hasbit % 8));
}
bool upb_stdmsg_has(void *_m, upb_value fval) {
assert(_m != NULL);
char *m = _m;
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
return f->hasbit < 0 || (m[f->hasbit / 8] & (1 << (f->hasbit % 8)));
}
@@ -100,7 +100,7 @@ bool upb_stdmsg_has(void *_m, upb_value fval) {
upb_flow_t upb_stdmsg_set ## type (void *_m, upb_value fval, \
upb_value val) { \
assert(_m != NULL); \
- upb_fielddef *f = upb_value_getfielddef(fval); \
+ const upb_fielddef *f = upb_value_getfielddef(fval); \
uint8_t *m = _m; \
/* Hasbit is set automatically by the handlers. */ \
*(ctype*)&m[f->offset] = upb_value_get ## type(val); \
@@ -119,7 +119,7 @@ bool upb_stdmsg_has(void *_m, upb_value fval) {
upb_value upb_stdmsg_get ## type(void *_m, upb_value fval) { \
assert(_m != NULL); \
uint8_t *m = _m; \
- upb_fielddef *f = upb_value_getfielddef(fval); \
+ const upb_fielddef *f = upb_value_getfielddef(fval); \
upb_value ret; \
upb_value_set ## type(&ret, *(ctype*)&m[f->offset]); \
return ret; \
@@ -151,7 +151,7 @@ static void _upb_stdmsg_setstr(void *_dst, upb_value src) {
*dstp = dst;
}
dst->len = 0;
- upb_strref *ref = upb_value_getstrref(src);
+ const upb_strref *ref = upb_value_getstrref(src);
if (ref->len > dst->size) {
dst->size = ref->len;
dst->ptr = realloc(dst->ptr, dst->size);
@@ -163,7 +163,7 @@ static void _upb_stdmsg_setstr(void *_dst, upb_value src) {
upb_flow_t upb_stdmsg_setstr(void *_m, upb_value fval, upb_value val) {
assert(_m != NULL);
char *m = _m;
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
// Hasbit automatically set by the handlers.
_upb_stdmsg_setstr(&m[f->offset], val);
return UPB_CONTINUE;
@@ -186,7 +186,7 @@ upb_value upb_stdmsg_seqgetstr(void *i) {
return upb_stdmsg_seqgetptr(i);
}
-void *upb_stdmsg_new(upb_msgdef *md) {
+void *upb_stdmsg_new(const upb_msgdef *md) {
void *m = malloc(md->size);
memset(m, 0, md->size);
upb_msg_clear(m, md);
@@ -211,7 +211,7 @@ void upb_stdseq_free(void *s, upb_fielddef *f) {
free(a);
}
-void upb_stdmsg_free(void *m, upb_msgdef *md) {
+void upb_stdmsg_free(void *m, const upb_msgdef *md) {
if (m == NULL) return;
upb_msg_iter i;
for(i = upb_msg_begin(md); !upb_msg_done(i); i = upb_msg_next(md, i)) {
@@ -234,7 +234,7 @@ void upb_stdmsg_free(void *m, upb_msgdef *md) {
upb_sflow_t upb_stdmsg_startseq(void *_m, upb_value fval) {
char *m = _m;
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
upb_stdarray **arr = (void*)&m[f->offset];
if (!upb_stdmsg_has(_m, fval)) {
if (!*arr) {
@@ -248,7 +248,7 @@ upb_sflow_t upb_stdmsg_startseq(void *_m, upb_value fval) {
return UPB_CONTINUE_WITH(*arr);
}
-void upb_stdmsg_recycle(void **m, upb_msgdef *md) {
+void upb_stdmsg_recycle(void **m, const upb_msgdef *md) {
if (*m)
upb_msg_clear(*m, md);
else
@@ -258,7 +258,7 @@ void upb_stdmsg_recycle(void **m, upb_msgdef *md) {
upb_sflow_t upb_stdmsg_startsubmsg(void *_m, upb_value fval) {
assert(_m != NULL);
char *m = _m;
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
void **subm = (void*)&m[f->offset];
if (!upb_stdmsg_has(m, fval)) {
upb_stdmsg_recycle(subm, upb_downcast_msgdef(f->def));
@@ -269,7 +269,7 @@ upb_sflow_t upb_stdmsg_startsubmsg(void *_m, upb_value fval) {
upb_sflow_t upb_stdmsg_startsubmsg_r(void *a, upb_value fval) {
assert(a != NULL);
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
void **subm = upb_stdarray_append((upb_stdarray*)a, sizeof(void*));
upb_stdmsg_recycle(subm, upb_downcast_msgdef(f->def));
return UPB_CONTINUE_WITH(*subm);
@@ -329,7 +329,8 @@ upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f) {
return NULL;
}
-static void upb_accessors_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f) {
+static void upb_accessors_onfreg(void *c, upb_fhandlers *fh,
+ const upb_fielddef *f) {
(void)c;
if (f->accessor) {
upb_fhandlers_setfval(fh, f->fval);
@@ -345,6 +346,6 @@ static void upb_accessors_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f) {
}
}
-upb_mhandlers *upb_accessors_reghandlers(upb_handlers *h, upb_msgdef *m) {
+upb_mhandlers *upb_accessors_reghandlers(upb_handlers *h, const upb_msgdef *m) {
return upb_handlers_regmsgdef(h, m, NULL, &upb_accessors_onfreg, NULL);
}
diff --git a/upb/msg.h b/upb/msg.h
index 7ad97d0..fa53056 100644
--- a/upb/msg.h
+++ b/upb/msg.h
@@ -69,7 +69,7 @@ typedef struct _upb_accessor_vtbl {
} upb_accessor_vtbl;
// Registers handlers for writing into a message of the given type.
-upb_mhandlers *upb_accessors_reghandlers(upb_handlers *h, upb_msgdef *m);
+upb_mhandlers *upb_accessors_reghandlers(upb_handlers *h, const upb_msgdef *m);
// Returns an stdmsg accessor for the given fielddef.
upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f);
@@ -85,9 +85,9 @@ upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f);
// Clears all hasbits.
// TODO: Add a separate function for setting primitive values back to their
// defaults (but not strings, submessages, or arrays).
-void upb_msg_clear(void *msg, upb_msgdef *md);
+void upb_msg_clear(void *msg, const upb_msgdef *md);
-INLINE void upb_msg_clearbit(void *msg, upb_fielddef *f) {
+INLINE void upb_msg_clearbit(void *msg, const upb_fielddef *f) {
((char*)msg)[f->hasbit / 8] &= ~(1 << (f->hasbit % 8));
}
@@ -97,37 +97,37 @@ INLINE void upb_msg_clearbit(void *msg, upb_fielddef *f) {
// or arrays. Also this could be desired to provide proto2 operations on
// generated messages.
-INLINE bool upb_msg_has(void *m, upb_fielddef *f) {
+INLINE bool upb_msg_has(void *m, const upb_fielddef *f) {
return f->accessor && f->accessor->has(m, f->fval);
}
// May only be called for fields that have accessors.
-INLINE upb_value upb_msg_get(void *m, upb_fielddef *f) {
+INLINE upb_value upb_msg_get(void *m, const upb_fielddef *f) {
assert(f->accessor && !upb_isseq(f));
return f->accessor->get(m, f->fval);
}
// May only be called for fields that have accessors.
-INLINE upb_value upb_msg_getseq(void *m, upb_fielddef *f) {
+INLINE upb_value upb_msg_getseq(void *m, const upb_fielddef *f) {
assert(f->accessor && upb_isseq(f));
return f->accessor->getseq(m, f->fval);
}
-INLINE void upb_msg_set(void *m, upb_fielddef *f, upb_value val) {
+INLINE void upb_msg_set(void *m, const upb_fielddef *f, upb_value val) {
assert(f->accessor);
f->accessor->set(m, f->fval, val);
}
-INLINE void *upb_seq_begin(void *s, upb_fielddef *f) {
+INLINE void *upb_seq_begin(void *s, const upb_fielddef *f) {
assert(f->accessor);
return f->accessor->seqbegin(s);
}
-INLINE void *upb_seq_next(void *s, void *iter, upb_fielddef *f) {
+INLINE void *upb_seq_next(void *s, void *iter, const upb_fielddef *f) {
assert(f->accessor);
assert(!upb_seq_done(iter));
return f->accessor->seqnext(s, iter);
}
-INLINE upb_value upb_seq_get(void *iter, upb_fielddef *f) {
+INLINE upb_value upb_seq_get(void *iter, const upb_fielddef *f) {
assert(f->accessor);
assert(!upb_seq_done(iter));
return f->accessor->seqget(iter);
@@ -175,10 +175,10 @@ void upb_msgvisitor_visit(upb_msgvisitor *v, upb_status *status);
/* Standard writers. **********************************************************/
// Allocates a new stdmsg.
-void *upb_stdmsg_new(upb_msgdef *md);
+void *upb_stdmsg_new(const upb_msgdef *md);
// Recursively frees any strings or submessages that the message refers to.
-void upb_stdmsg_free(void *m, upb_msgdef *md);
+void upb_stdmsg_free(void *m, const upb_msgdef *md);
void upb_stdmsg_sethas(void *_m, upb_value fval);
diff --git a/upb/pb/decoder_x86.dasc b/upb/pb/decoder_x86.dasc
index fe15174..0657af6 100644
--- a/upb/pb/decoder_x86.dasc
+++ b/upb/pb/decoder_x86.dasc
@@ -413,7 +413,7 @@ static void upb_decoder_jit_doappend(upb_decoder *d, uint8_t size,
#endif
static void upb_decoder_jit_callcb(upb_decoder *d, upb_fhandlers *f) {
- upb_fielddef *fd = upb_value_getfielddef(f->fval);
+ const upb_fielddef *fd = upb_value_getfielddef(f->fval);
// Call callbacks.
if (upb_issubmsgtype(f->type)) {
// Load closure and fval into arg registers.
@@ -439,7 +439,7 @@ static void upb_decoder_jit_callcb(upb_decoder *d, upb_fhandlers *f) {
}
| pushframe f, rdx, esi, false
- upb_mhandlers *sub_m = upb_fhandlers_getsubmsg(f);
+ const upb_mhandlers *sub_m = upb_fhandlers_getsubmsg(f);
if (sub_m->jit_parent_field_done_pclabel != UPB_MULTIPLE) {
| jmp =>sub_m->jit_startmsg_pclabel;
} else {
diff --git a/upb/pb/glue.c b/upb/pb/glue.c
index 6981aa2..b364a6d 100644
--- a/upb/pb/glue.c
+++ b/upb/pb/glue.c
@@ -12,7 +12,7 @@
#include "upb/pb/glue.h"
#include "upb/pb/textprinter.h"
-void upb_strtomsg(const char *str, size_t len, void *msg, upb_msgdef *md,
+void upb_strtomsg(const char *str, size_t len, void *msg, const upb_msgdef *md,
upb_status *status) {
upb_stringsrc strsrc;
upb_stringsrc_init(&strsrc);
@@ -56,8 +56,8 @@ void upb_msgtotext(upb_string *str, upb_msg *msg, upb_msgdef *md,
#endif
// TODO: read->load.
-upb_def **upb_load_descriptor(const char *str, size_t len, int *n,
- upb_status *status) {
+upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
+ upb_status *status) {
upb_stringsrc strsrc;
upb_stringsrc_init(&strsrc);
upb_stringsrc_reset(&strsrc, str, len);
@@ -98,13 +98,15 @@ upb_def **upb_load_descriptor(const char *str, size_t len, int *n,
return defscopy;
}
-void upb_read_descriptor(upb_symtab *s, const char *str, size_t len,
- upb_status *status) {
+bool upb_load_descriptor_into_symtab(upb_symtab *s, const char *str, size_t len,
+ upb_status *status) {
int n;
- upb_def **defs = upb_load_descriptor(str, len, &n, status);
- if (upb_ok(status)) upb_symtab_add(s, defs, n, status);
+ upb_def **defs = upb_load_defs_from_descriptor(str, len, &n, status);
+ if (!defs) return false;
+ bool success = upb_symtab_add(s, defs, n, status);
for(int i = 0; i < n; i++) upb_def_unref(defs[i]);
free(defs);
+ return success;
}
char *upb_readfile(const char *filename, size_t *len) {
@@ -125,14 +127,15 @@ error:
return NULL;
}
-void upb_read_descriptorfile(upb_symtab *symtab, const char *fname,
- upb_status *status) {
+bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
+ upb_status *status) {
size_t len;
char *data = upb_readfile(fname, &len);
if (!data) {
- upb_status_seterrf(status, "Couldn't read file: %s", fname);
- return;
+ if (status) upb_status_seterrf(status, "Couldn't read file: %s", fname);
+ return false;
}
- upb_read_descriptor(symtab, data, len, status);
+ bool success = upb_load_descriptor_into_symtab(symtab, data, len, status);
free(data);
+ return success;
}
diff --git a/upb/pb/glue.h b/upb/pb/glue.h
index a2a478c..7aa4a5f 100644
--- a/upb/pb/glue.h
+++ b/upb/pb/glue.h
@@ -42,20 +42,29 @@ struct _upb_symtab;
// Decodes the given string, which must be in protobuf binary format, to the
// given upb_msg with msgdef "md", storing the status of the operation in "s".
void upb_strtomsg(const char *str, size_t len, void *msg,
- struct _upb_msgdef *md, upb_status *s);
+ const struct _upb_msgdef *md, upb_status *s);
//void upb_msgtotext(struct _upb_string *str, void *msg,
// struct _upb_msgdef *md, bool single_line);
-upb_def **upb_load_descriptor(const char *str, size_t len, int *n,
- upb_status *status);
-void upb_read_descriptor(struct _upb_symtab *symtab, const char *str, size_t len,
- upb_status *status);
+// Loads all defs from the given protobuf binary descriptor, setting default
+// accessors and a default layout on all messages. The caller owns the
+// returned array of defs, which will be of length *n. On error NULL is
+// returned and status is set (if non-NULL).
+upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
+ upb_status *status);
-void upb_read_descriptorfile(struct _upb_symtab *symtab, const char *fname,
- upb_status *status);
+// Like the previous but also adds the loaded defs to the given symtab.
+bool upb_load_descriptor_into_symtab(struct _upb_symtab *symtab, const char *str,
+ size_t len, upb_status *status);
+// Like the previous but also reads the descriptor from the given filename.
+bool upb_load_descriptor_file_into_symtab(struct _upb_symtab *symtab,
+ const char *fname, upb_status *status);
+
+// Reads the given filename into a character string, returning NULL if there
+// was an error.
char *upb_readfile(const char *filename, size_t *len);
#ifdef __cplusplus
diff --git a/upb/pb/textprinter.c b/upb/pb/textprinter.c
index 37f5699..434a482 100644
--- a/upb/pb/textprinter.c
+++ b/upb/pb/textprinter.c
@@ -35,7 +35,7 @@ err:
return -1;
}
-static int upb_textprinter_putescaped(upb_textprinter *p, upb_strref *strref,
+static int upb_textprinter_putescaped(upb_textprinter *p, const upb_strref *strref,
bool preserve_utf8) {
// Based on CEscapeInternal() from Google's protobuf release.
// TODO; we could read directly from a bytesrc's buffer instead.
@@ -90,7 +90,7 @@ err:
static upb_flow_t upb_textprinter_put ## member(void *_p, upb_value fval, \
upb_value val) { \
upb_textprinter *p = _p; \
- upb_fielddef *f = upb_value_getfielddef(fval); \
+ const upb_fielddef *f = upb_value_getfielddef(fval); \
uint64_t start_ofs = upb_bytesink_getoffset(p->sink); \
CHECK(upb_textprinter_indent(p)); \
CHECK(upb_bytesink_writestr(p->sink, f->name)); \
@@ -120,7 +120,7 @@ static upb_flow_t upb_textprinter_putenum(void *_p, upb_value fval,
upb_textprinter *p = _p;
uint64_t start_ofs = upb_bytesink_getoffset(p->sink);
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
upb_enumdef *enum_def = upb_downcast_enumdef(f->def);
const char *label = upb_enumdef_iton(enum_def, upb_value_getint32(val));
if (label) {
@@ -138,7 +138,7 @@ static upb_flow_t upb_textprinter_putstr(void *_p, upb_value fval,
upb_value val) {
upb_textprinter *p = _p;
uint64_t start_ofs = upb_bytesink_getoffset(p->sink);
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
CHECK(upb_bytesink_putc(p->sink, '"'));
CHECK(upb_textprinter_putescaped(p, upb_value_getstrref(val),
f->type == UPB_TYPE(STRING)));
@@ -152,7 +152,7 @@ err:
static upb_sflow_t upb_textprinter_startsubmsg(void *_p, upb_value fval) {
upb_textprinter *p = _p;
uint64_t start_ofs = upb_bytesink_getoffset(p->sink);
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
CHECK(upb_textprinter_indent(p));
CHECK(upb_bytesink_printf(p->sink, "%s {", f->name));
if (!p->single_line)
@@ -192,7 +192,7 @@ void upb_textprinter_reset(upb_textprinter *p, upb_bytesink *sink,
p->indent_depth = 0;
}
-static void upb_textprinter_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f) {
+static void upb_textprinter_onfreg(void *c, upb_fhandlers *fh, const upb_fielddef *f) {
(void)c;
upb_fhandlers_setstartsubmsg(fh, &upb_textprinter_startsubmsg);
upb_fhandlers_setendsubmsg(fh, &upb_textprinter_endsubmsg);
@@ -207,7 +207,7 @@ static void upb_textprinter_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f)
upb_fhandlers_setfval(fh, fval);
}
-upb_mhandlers *upb_textprinter_reghandlers(upb_handlers *h, upb_msgdef *m) {
+upb_mhandlers *upb_textprinter_reghandlers(upb_handlers *h, const upb_msgdef *m) {
return upb_handlers_regmsgdef(
h, m, NULL, &upb_textprinter_onfreg, NULL);
}
diff --git a/upb/pb/textprinter.h b/upb/pb/textprinter.h
index 9455208..25f364e 100644
--- a/upb/pb/textprinter.h
+++ b/upb/pb/textprinter.h
@@ -22,7 +22,7 @@ upb_textprinter *upb_textprinter_new();
void upb_textprinter_free(upb_textprinter *p);
void upb_textprinter_reset(upb_textprinter *p, upb_bytesink *sink,
bool single_line);
-upb_mhandlers *upb_textprinter_reghandlers(upb_handlers *h, upb_msgdef *m);
+upb_mhandlers *upb_textprinter_reghandlers(upb_handlers *h, const upb_msgdef *m);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/upb/table.c b/upb/table.c
index 71aca16..f0d8d3e 100644
--- a/upb/table.c
+++ b/upb/table.c
@@ -25,9 +25,9 @@ static uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed);
/* Base table (shared code) ***************************************************/
-static uint32_t upb_table_size(upb_table *t) { return 1 << t->size_lg2; }
-static size_t upb_table_entrysize(upb_table *t) { return t->entry_size; }
-static size_t upb_table_valuesize(upb_table *t) { return t->value_size; }
+static uint32_t upb_table_size(const upb_table *t) { return 1 << t->size_lg2; }
+static size_t upb_table_entrysize(const upb_table *t) { return t->entry_size; }
+static size_t upb_table_valuesize(const upb_table *t) { return t->value_size; }
void upb_table_init(upb_table *t, uint32_t size, uint16_t entry_size) {
t->count = 0;
@@ -43,12 +43,12 @@ void upb_table_free(upb_table *t) { free(t->entries); }
/* upb_inttable ***************************************************************/
-static upb_inttable_entry *intent(upb_inttable *t, int32_t i) {
+static upb_inttable_entry *intent(const upb_inttable *t, int32_t i) {
//printf("looking up int entry %d, size of entry: %d\n", i, t->t.entry_size);
return UPB_INDEX(t->t.entries, i, t->t.entry_size);
}
-static uint32_t upb_inttable_hashtablesize(upb_inttable *t) {
+static uint32_t upb_inttable_hashtablesize(const upb_inttable *t) {
return upb_table_size(&t->t);
}
@@ -219,12 +219,13 @@ void upb_inttable_compact(upb_inttable *t) {
*t = new_table;
}
-upb_inttable_iter upb_inttable_begin(upb_inttable *t) {
+upb_inttable_iter upb_inttable_begin(const upb_inttable *t) {
upb_inttable_iter iter = {-1, NULL, true}; // -1 will overflow to 0 on the first iteration.
return upb_inttable_next(t, iter);
}
-upb_inttable_iter upb_inttable_next(upb_inttable *t, upb_inttable_iter iter) {
+upb_inttable_iter upb_inttable_next(const upb_inttable *t,
+ upb_inttable_iter iter) {
const size_t hdrsize = sizeof(upb_inttable_header);
const size_t entsize = upb_table_entrysize(&t->t);
if (iter.array_part) {
@@ -259,13 +260,13 @@ upb_inttable_iter upb_inttable_next(upb_inttable *t, upb_inttable_iter iter) {
/* upb_strtable ***************************************************************/
-static upb_strtable_entry *strent(upb_strtable *t, int32_t i) {
+static upb_strtable_entry *strent(const upb_strtable *t, int32_t i) {
//fprintf(stderr, "i: %d, table_size: %d\n", i, upb_table_size(&t->t));
assert(i <= (int32_t)upb_table_size(&t->t));
return UPB_INDEX(t->t.entries, i, t->t.entry_size);
}
-static uint32_t upb_strtable_size(upb_strtable *t) {
+static uint32_t upb_strtable_size(const upb_strtable *t) {
return upb_table_size(&t->t);
}
@@ -288,12 +289,12 @@ void upb_strtable_free(upb_strtable *t) {
upb_table_free(&t->t);
}
-static uint32_t strtable_bucket(upb_strtable *t, const char *key) {
+static uint32_t strtable_bucket(const upb_strtable *t, const char *key) {
uint32_t hash = MurmurHash2(key, strlen(key), 0);
return (hash & t->t.mask);
}
-void *upb_strtable_lookup(upb_strtable *t, const char *key) {
+void *upb_strtable_lookup(const upb_strtable *t, const char *key) {
uint32_t bucket = strtable_bucket(t, key);
upb_strtable_entry *e;
do {
@@ -303,7 +304,7 @@ void *upb_strtable_lookup(upb_strtable *t, const char *key) {
return NULL;
}
-void *upb_strtable_lookupl(upb_strtable *t, const char *key, size_t len) {
+void *upb_strtable_lookupl(const upb_strtable *t, const char *key, size_t len) {
// TODO: improve.
char key2[len+1];
memcpy(key2, key, len);
@@ -383,7 +384,7 @@ void upb_strtable_insert(upb_strtable *t, const char *key, const void *val) {
strinsert(t, key, val);
}
-void upb_strtable_begin(upb_strtable_iter *i, upb_strtable *t) {
+void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
i->e = strent(t, -1);
i->t = t;
upb_strtable_next(i);
diff --git a/upb/table.h b/upb/table.h
index 4a44a6f..a8c2015 100644
--- a/upb/table.h
+++ b/upb/table.h
@@ -90,11 +90,11 @@ void upb_strtable_init(upb_strtable *table, uint32_t size, uint16_t value_size);
void upb_strtable_free(upb_strtable *table);
// Number of values in the hash table.
-INLINE uint32_t upb_table_count(upb_table *t) { return t->count; }
-INLINE uint32_t upb_inttable_count(upb_inttable *t) {
+INLINE uint32_t upb_table_count(const upb_table *t) { return t->count; }
+INLINE uint32_t upb_inttable_count(const upb_inttable *t) {
return t->array_count + upb_table_count(&t->t);
}
-INLINE uint32_t upb_strtable_count(upb_strtable *t) {
+INLINE uint32_t upb_strtable_count(const upb_strtable *t) {
return upb_table_count(&t->t);
}
@@ -111,14 +111,14 @@ void upb_inttable_insert(upb_inttable *t, uint32_t key, const void *val);
void upb_strtable_insert(upb_strtable *t, const char *key, const void *val);
void upb_inttable_compact(upb_inttable *t);
-INLINE uint32_t _upb_inttable_bucket(upb_inttable *t, uint32_t k) {
+INLINE uint32_t _upb_inttable_bucket(const upb_inttable *t, uint32_t k) {
uint32_t bucket = k & t->t.mask; // Identity hash for ints.
assert(bucket != UPB_END_OF_CHAIN);
return bucket;
}
// Returns true if this key belongs in the array part of the table.
-INLINE bool _upb_inttable_isarrkey(upb_inttable *t, uint32_t k) {
+INLINE bool _upb_inttable_isarrkey(const upb_inttable *t, uint32_t k) {
return (k < t->array_size);
}
@@ -126,7 +126,7 @@ INLINE bool _upb_inttable_isarrkey(upb_inttable *t, uint32_t k) {
// We have the caller specify the entry_size because fixing this as a literal
// (instead of reading table->entry_size) gives the compiler more ability to
// optimize.
-INLINE void *_upb_inttable_fastlookup(upb_inttable *t, uint32_t key,
+INLINE void *_upb_inttable_fastlookup(const upb_inttable *t, uint32_t key,
size_t entry_size, size_t value_size) {
upb_inttable_value *arrval =
(upb_inttable_value*)UPB_INDEX(t->array, key, value_size);
@@ -158,8 +158,8 @@ INLINE void *upb_inttable_lookup(upb_inttable *t, uint32_t key) {
return _upb_inttable_fastlookup(t, key, t->t.entry_size, t->t.value_size);
}
-void *upb_strtable_lookupl(upb_strtable *t, const char *key, size_t len);
-void *upb_strtable_lookup(upb_strtable *t, const char *key);
+void *upb_strtable_lookupl(const upb_strtable *t, const char *key, size_t len);
+void *upb_strtable_lookup(const upb_strtable *t, const char *key);
/* upb_strtable_iter **********************************************************/
@@ -172,11 +172,11 @@ void *upb_strtable_lookup(upb_strtable *t, const char *key);
// // ...
// }
typedef struct {
- upb_strtable *t;
+ const upb_strtable *t;
upb_strtable_entry *e;
} upb_strtable_iter;
-void upb_strtable_begin(upb_strtable_iter *i, upb_strtable *t);
+void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t);
void upb_strtable_next(upb_strtable_iter *i);
INLINE bool upb_strtable_done(upb_strtable_iter *i) { return i->e == NULL; }
INLINE const char *upb_strtable_iter_key(upb_strtable_iter *i) {
@@ -200,8 +200,8 @@ typedef struct {
bool array_part;
} upb_inttable_iter;
-upb_inttable_iter upb_inttable_begin(upb_inttable *t);
-upb_inttable_iter upb_inttable_next(upb_inttable *t, upb_inttable_iter iter);
+upb_inttable_iter upb_inttable_begin(const upb_inttable *t);
+upb_inttable_iter upb_inttable_next(const upb_inttable *t, upb_inttable_iter iter);
INLINE bool upb_inttable_done(upb_inttable_iter iter) { return iter.value == NULL; }
INLINE uint32_t upb_inttable_iter_key(upb_inttable_iter iter) {
return iter.key;
diff --git a/upb/upb.c b/upb/upb.c
index bb85afc..a7c4ea0 100644
--- a/upb/upb.c
+++ b/upb/upb.c
@@ -87,7 +87,10 @@ void upb_status_copy(upb_status *to, upb_status *from) {
}
}
-const char *upb_status_getstr(upb_status *status) {
+const char *upb_status_getstr(const upb_status *_status) {
+ // Function is logically const but can modify internal state to materialize
+ // the string.
+ upb_status *status = (upb_status*)_status;
if (status->str == NULL && status->space && status->space->code_to_string) {
status->space->code_to_string(status->code, status->buf, status->bufsize);
status->str = status->buf;
diff --git a/upb/upb.h b/upb/upb.h
index 708de7c..b79ca6d 100644
--- a/upb/upb.h
+++ b/upb/upb.h
@@ -144,8 +144,8 @@ typedef struct {
int64_t int64;
uint32_t uint32;
bool _bool;
- struct _upb_strref *strref;
- struct _upb_fielddef *fielddef;
+ const struct _upb_strref *strref;
+ const struct _upb_fielddef *fielddef;
void *_void;
} val;
@@ -178,10 +178,13 @@ UPB_VALUE_ACCESSORS(int64, int64, int64_t, UPB_TYPE(INT64));
UPB_VALUE_ACCESSORS(uint32, uint32, uint32_t, UPB_TYPE(UINT32));
UPB_VALUE_ACCESSORS(uint64, uint64, uint64_t, UPB_TYPE(UINT64));
UPB_VALUE_ACCESSORS(bool, _bool, bool, UPB_TYPE(BOOL));
-UPB_VALUE_ACCESSORS(strref, strref, struct _upb_strref*, UPB_TYPE(STRING));
-UPB_VALUE_ACCESSORS(fielddef, fielddef, struct _upb_fielddef*, UPB_VALUETYPE_FIELDDEF);
UPB_VALUE_ACCESSORS(ptr, _void, void*, UPB_VALUETYPE_PTR);
+// upb_fielddef and upb_strref should never be modified from a callback
+// (ie. when they're getting passed through a upb_value).
+UPB_VALUE_ACCESSORS(strref, strref, const struct _upb_strref*, UPB_TYPE(STRING));
+UPB_VALUE_ACCESSORS(fielddef, fielddef, const struct _upb_fielddef*, UPB_VALUETYPE_FIELDDEF);
+
extern upb_value UPB_NO_VALUE;
@@ -223,7 +226,7 @@ void upb_status_seterrliteral(upb_status *status, const char *msg);
void upb_status_seterrf(upb_status *s, const char *msg, ...);
void upb_status_setcode(upb_status *s, upb_errorspace *space, int code);
// The returned string is invalidated by any other call into the status.
-const char *upb_status_getstr(upb_status *s);
+const char *upb_status_getstr(const upb_status *s);
void upb_status_copy(upb_status *to, upb_status *from);
extern upb_errorspace upb_posix_errorspace;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback