summaryrefslogtreecommitdiff
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
parent8f2758dda2ba12b78ae8f8c7170decc5e88dd28c (diff)
Const invasion: large parts of upb made const-correct.
-rw-r--r--Makefile10
-rw-r--r--benchmarks/parsestream.upb.c6
-rw-r--r--benchmarks/parsetoproto2.upb.cc18
-rw-r--r--benchmarks/parsetostruct.upb.c6
-rw-r--r--bindings/cpp/upb/def.hpp17
-rw-r--r--bindings/cpp/upb/handlers.hpp3
-rw-r--r--bindings/lua/upb.c44
-rw-r--r--bindings/python/upb.c26
-rw-r--r--tests/test_cpp.cc2
-rw-r--r--tests/test_decoder.c6
-rw-r--r--tests/test_def.c2
-rw-r--r--tests/test_vs_proto2.cc14
-rw-r--r--tests/tests.c20
-rw-r--r--tools/upbc.c12
-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
32 files changed, 378 insertions, 304 deletions
diff --git a/Makefile b/Makefile
index 34027fe..6acb930 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,11 @@
.PHONY: clean_leave_profile
# Default rule: just build libupb.
-all: lib
+default: lib
+
+# All: build absolutely everything
+all: lib tests benchmarks tools/upbc lua python
+testall: test pythontest
# User-specified CFLAGS.
USER_CFLAGS=$(strip $(shell test -f perf-cppflags && cat perf-cppflags))
@@ -46,6 +50,7 @@ endif
CC=gcc
CXX=g++
CFLAGS=-std=gnu99
+CXXFLAGS=-Ibindings/cpp
INCLUDE=-Itests -I.
CPPFLAGS=$(INCLUDE) -Wall -Wextra $(USER_CFLAGS)
LDLIBS=-lpthread upb/libupb.a
@@ -200,7 +205,8 @@ INTERACTIVE_TESTS= \
SIMPLE_CXX_TESTS= \
- tests/test_table
+ tests/test_table \
+ tests/test_cpp \
VARIADIC_TESTS= \
tests/t.test_vs_proto2.googlemessage1 \
diff --git a/benchmarks/parsestream.upb.c b/benchmarks/parsestream.upb.c
index 2d34206..4d13e9d 100644
--- a/benchmarks/parsestream.upb.c
+++ b/benchmarks/parsestream.upb.c
@@ -9,7 +9,7 @@
static char *input_str;
static size_t input_len;
-static upb_msgdef *def;
+static const upb_msgdef *def;
static upb_decoder decoder;
static upb_stringsrc stringsrc;
@@ -31,14 +31,14 @@ static bool initialize()
// Initialize upb state, decode descriptor.
upb_status status = UPB_STATUS_INIT;
upb_symtab *s = upb_symtab_new();
- upb_read_descriptorfile(s, MESSAGE_DESCRIPTOR_FILE, &status);
+ upb_load_descriptor_file_into_symtab(s, MESSAGE_DESCRIPTOR_FILE, &status);
if(!upb_ok(&status)) {
fprintf(stderr, "Error reading descriptor: %s\n",
upb_status_getstr(&status));
return false;
}
- def = upb_dyncast_msgdef(upb_symtab_lookup(s, MESSAGE_NAME));
+ def = upb_dyncast_msgdef_const(upb_symtab_lookup(s, MESSAGE_NAME));
if(!def) {
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
return false;
diff --git a/benchmarks/parsetoproto2.upb.cc b/benchmarks/parsetoproto2.upb.cc
index 286c7f3..75cd10c 100644
--- a/benchmarks/parsetoproto2.upb.cc
+++ b/benchmarks/parsetoproto2.upb.cc
@@ -29,7 +29,7 @@ MESSAGE_CIDENT msg[NUM_MESSAGES];
MESSAGE_CIDENT msg2;
static upb_stringsrc strsrc;
static upb_decoder d;
-upb_msgdef *def;
+static const upb_msgdef *def;
#define PROTO2_APPEND(type, ctype) \
upb_flow_t proto2_append_ ## type(void *_r, upb_value fval, upb_value val) { \
@@ -50,10 +50,10 @@ PROTO2_APPEND(bool, bool)
upb_flow_t proto2_setstr(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);
std::string **str = (std::string**)UPB_INDEX(m, f->offset, 1);
if (*str == f->default_ptr) *str = new std::string;
- upb_strref *ref = upb_value_getstrref(val);
+ const upb_strref *ref = upb_value_getstrref(val);
// XXX: only supports contiguous strings atm.
(*str)->assign(ref->ptr, ref->len);
return UPB_CONTINUE;
@@ -64,7 +64,7 @@ upb_flow_t proto2_append_str(void *_r, upb_value fval, upb_value val) {
typedef google::protobuf::RepeatedPtrField<std::string> R;
(void)fval;
R *r = (R*)_r;
- upb_strref *ref = upb_value_getstrref(val);
+ const upb_strref *ref = upb_value_getstrref(val);
// XXX: only supports contiguous strings atm.
r->Add()->assign(ref->ptr, ref->len);
return UPB_CONTINUE;
@@ -72,13 +72,13 @@ upb_flow_t proto2_append_str(void *_r, upb_value fval, upb_value val) {
upb_sflow_t proto2_startseq(void *m, upb_value fval) {
assert(m != NULL);
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
return UPB_CONTINUE_WITH(UPB_INDEX(m, f->offset, 1));
}
upb_sflow_t proto2_startsubmsg(void *m, upb_value fval) {
assert(m != NULL);
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
google::protobuf::Message *prototype = (google::protobuf::Message*)f->prototype;
void **subm = (void**)UPB_INDEX(m, f->offset, 1);
if (*subm == NULL || *subm == f->default_ptr)
@@ -122,7 +122,7 @@ upb_sflow_t proto2_startsubmsg_r(void *_r, upb_value fval) {
public:
typedef void Type;
};
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
UpbRepeatedPtrField *r = (UpbRepeatedPtrField*)_r;
void *submsg = r->Add((google::protobuf::Message*)f->prototype);
assert(submsg != NULL);
@@ -225,7 +225,7 @@ static bool initialize()
return false;
}
int n;
- upb_def **defs = upb_load_descriptor(data, len, &n, &status);
+ upb_def **defs = upb_load_defs_from_descriptor(data, len, &n, &status);
free(data);
if(!upb_ok(&status)) {
fprintf(stderr, "Error reading descriptor: %s\n",
@@ -257,7 +257,7 @@ static bool initialize()
for(int i = 0; i < n; i++) upb_def_unref(defs[i]);
free(defs);
- def = upb_dyncast_msgdef(upb_symtab_lookup(s, MESSAGE_NAME));
+ def = upb_dyncast_msgdef_const(upb_symtab_lookup(s, MESSAGE_NAME));
if(!def) {
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
return false;
diff --git a/benchmarks/parsetostruct.upb.c b/benchmarks/parsetostruct.upb.c
index 6a36544..5e7aa35 100644
--- a/benchmarks/parsetostruct.upb.c
+++ b/benchmarks/parsetostruct.upb.c
@@ -7,7 +7,7 @@
#include "upb/pb/decoder.h"
#include "upb/pb/glue.h"
-static upb_msgdef *def;
+static const upb_msgdef *def;
static size_t len;
static void *msg[NUM_MESSAGES];
static upb_stringsrc strsrc;
@@ -18,14 +18,14 @@ static bool initialize()
// Initialize upb state, decode descriptor.
upb_status status = UPB_STATUS_INIT;
upb_symtab *s = upb_symtab_new();
- upb_read_descriptorfile(s, MESSAGE_DESCRIPTOR_FILE, &status);
+ upb_load_descriptor_file_into_symtab(s, MESSAGE_DESCRIPTOR_FILE, &status);
if(!upb_ok(&status)) {
fprintf(stderr, "Error reading descriptor: %s\n",
upb_status_getstr(&status));
return false;
}
- def = upb_dyncast_msgdef(upb_symtab_lookup(s, MESSAGE_NAME));
+ def = upb_dyncast_msgdef_const(upb_symtab_lookup(s, MESSAGE_NAME));
if(!def) {
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
return false;
diff --git a/bindings/cpp/upb/def.hpp b/bindings/cpp/upb/def.hpp
index 6500243..d64625c 100644
--- a/bindings/cpp/upb/def.hpp
+++ b/bindings/cpp/upb/def.hpp
@@ -17,9 +17,14 @@ namespace upb {
class MessageDef : public upb_msgdef {
public:
+ // Converting from C types to C++ wrapper types.
static MessageDef* Cast(upb_msgdef *md) { return (MessageDef*)md; }
+ static const MessageDef* Cast(const upb_msgdef *md) {
+ return (const MessageDef*)md;
+ }
- void Unref() { return upb_msgdef_unref(this); }
+ void Ref() const { upb_msgdef_ref(this); }
+ void Unref() const { upb_msgdef_unref(this); }
private:
MessageDef();
@@ -28,14 +33,20 @@ class MessageDef : public upb_msgdef {
class SymbolTable : public upb_symtab {
public:
+ // Converting from C types to C++ wrapper types.
static SymbolTable* Cast(upb_symtab *s) { return (SymbolTable*)s; }
+ static const SymbolTable* Cast(const upb_symtab *s) {
+ return (SymbolTable*)s;
+ }
+
static SymbolTable* New() { return Cast(upb_symtab_new()); }
- void Unref() { return upb_symtab_unref(this); }
+ void Ref() const { upb_symtab_unref(this); }
+ void Unref() const { upb_symtab_unref(this); }
// If the given name refers to a message in this symbol table, returns a new
// ref to that MessageDef object, otherwise returns NULL.
- MessageDef* LookupMessage(const char *name) {
+ const MessageDef* LookupMessage(const char *name) const {
return MessageDef::Cast(upb_symtab_lookupmsg(this, name));
}
diff --git a/bindings/cpp/upb/handlers.hpp b/bindings/cpp/upb/handlers.hpp
index e72c0a4..07683f6 100644
--- a/bindings/cpp/upb/handlers.hpp
+++ b/bindings/cpp/upb/handlers.hpp
@@ -4,9 +4,6 @@
* Copyright (c) 2011 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
- * Note! This file is a proof-of-concept for C++ wrappers and does not
- * yet build.
- *
* upb::Handlers is a generic visitor-like interface for iterating over a
* stream of protobuf data. You can register function pointers that will be
* called for each message and/or field as the data is being parsed or iterated
diff --git a/bindings/lua/upb.c b/bindings/lua/upb.c
index fe523e7..4cce4b6 100644
--- a/bindings/lua/upb.c
+++ b/bindings/lua/upb.c
@@ -37,7 +37,7 @@ static uint32_t lupb_touint32(lua_State *L, int narg, const char *name) {
return n;
}
-static void lupb_pushstring(lua_State *L, upb_strref *ref) {
+static void lupb_pushstring(lua_State *L, const upb_strref *ref) {
if (ref->ptr) {
lua_pushlstring(L, ref->ptr, ref->len);
} else {
@@ -146,15 +146,15 @@ static void lupb_typecheck(lua_State *L, int narg, upb_fielddef *f) {
//static void lupb_msg_getorcreate(lua_State *L, upb_msg *msg, upb_msgdef *md);
static void lupb_fielddef_getorcreate(lua_State *L, upb_fielddef *f);
static upb_msgdef *lupb_msgdef_check(lua_State *L, int narg);
-static void lupb_msg_pushnew(lua_State *L, void *md);
+static void lupb_msg_pushnew(lua_State *L, const void *md);
void lupb_checkstatus(lua_State *L, upb_status *s) {
if (!upb_ok(s)) {
- upb_status_print(s, stderr);
// Need to copy the string to the stack, so we can free it and not leak
// it (since luaL_error() does not return).
- char buf[strlen(s->str)+1];
- strcpy(buf, s->str);
+ const char *str = upb_status_getstr(s);
+ char buf[strlen(str)+1];
+ strcpy(buf, str);
upb_status_uninit(s);
luaL_error(L, "%s", buf);
}
@@ -226,14 +226,14 @@ static lupb_def *lupb_def_check(lua_State *L, int narg) {
return ldef;
}
-static void lupb_def_getorcreate(lua_State *L, upb_def *def, int owned) {
+static void lupb_def_getorcreate(lua_State *L, const upb_def *def, int owned) {
bool created = false;
switch(def->type) {
case UPB_DEF_MSG:
- created = lupb_cache_getorcreate(L, def, "upb.msgdef");
+ created = lupb_cache_getorcreate(L, (void*)def, "upb.msgdef");
break;
case UPB_DEF_ENUM:
- created = lupb_cache_getorcreate(L, def, "upb.enumdef");
+ created = lupb_cache_getorcreate(L, (void*)def, "upb.enumdef");
break;
default:
luaL_error(L, "unknown deftype %d", def->type);
@@ -564,7 +564,7 @@ static int lupb_symtab_gc(lua_State *L) {
static int lupb_symtab_lookup(lua_State *L) {
lupb_symtab *s = lupb_symtab_check(L, 1);
for (int i = 2; i <= lua_gettop(L); i++) {
- upb_def *def = upb_symtab_lookup(s->symtab, luaL_checkstring(L, i));
+ const upb_def *def = upb_symtab_lookup(s->symtab, luaL_checkstring(L, i));
if (def) {
lupb_def_getorcreate(L, def, true);
} else {
@@ -579,12 +579,12 @@ static int lupb_symtab_getdefs(lua_State *L) {
lupb_symtab *s = lupb_symtab_check(L, 1);
upb_deftype_t type = luaL_checkint(L, 2);
int count;
- upb_def **defs = upb_symtab_getdefs(s->symtab, &count, type);
+ const upb_def **defs = upb_symtab_getdefs(s->symtab, &count, type);
// Create the table in which we will return the defs.
lua_createtable(L, count, 0);
for (int i = 0; i < count; i++) {
- upb_def *def = defs[i];
+ const upb_def *def = defs[i];
lupb_def_getorcreate(L, def, true);
lua_rawseti(L, -2, i + 1);
}
@@ -616,7 +616,7 @@ static const struct luaL_Reg lupb_symtab_mm[] = {
// {msgdef, <string, submessage, and array fields>}
// Must pass a upb_fielddef as the pointer.
-static void lupb_array_pushnew(lua_State *L, void *f);
+static void lupb_array_pushnew(lua_State *L, const void *f);
static void *lupb_msg_check(lua_State *L, int narg, upb_msgdef **md) {
void *msg = luaL_checkudata(L, narg, "upb.msg");
@@ -632,14 +632,14 @@ static void *lupb_msg_check(lua_State *L, int narg, upb_msgdef **md) {
return msg;
}
-static void lupb_msg_pushnew(lua_State *L, void *md) {
+static void lupb_msg_pushnew(lua_State *L, const void *md) {
void *msg = lua_newuserdata(L, upb_msgdef_size(md));
luaL_getmetatable(L, "upb.msg");
assert(!lua_isnil(L, -1)); // Should have been created by luaopen_upb.
lua_setmetatable(L, -2);
upb_msg_clear(msg, md);
lua_getfenv(L, -1);
- lupb_cache_getorcreate(L, md, "upb.msgdef");
+ lupb_cache_getorcreate(L, (void*)md, "upb.msgdef");
lua_rawseti(L, -2, 1);
lua_pop(L, 1); // Pop the fenv.
}
@@ -755,10 +755,10 @@ static int lupb_msgdef(lua_State *L) {
//
// - use thread-local storage. Convenient and efficient, but not portable.
-typedef void createfunc_t(lua_State *L, void *param);
+typedef void createfunc_t(lua_State *L, const void *param);
-static upb_sflow_t lupb_msg_start(void *m, upb_fielddef *f, bool array,
- createfunc_t *pushnew, void *param) {
+static upb_sflow_t lupb_msg_start(void *m, const upb_fielddef *f, bool array,
+ createfunc_t *pushnew, const void *param) {
lua_State *L = *(lua_State**)m;
int offset = array ? lua_rawlen(L, -1) : f->offset;
if (!lua_checkstack(L, 3)) luaL_error(L, "stack full");
@@ -778,7 +778,7 @@ static upb_sflow_t lupb_msg_start(void *m, upb_fielddef *f, bool array,
static upb_flow_t lupb_msg_string(void *m, upb_value fval, upb_value val,
bool array) {
// Could add lazy materialization of strings here.
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
lua_State *L = *(lua_State**)m;
int offset = array ? lua_rawlen(L, -1) : f->offset;
if (!lua_checkstack(L, 1)) luaL_error(L, "stack full");
@@ -788,17 +788,17 @@ static upb_flow_t lupb_msg_string(void *m, upb_value fval, upb_value val,
}
static upb_sflow_t lupb_msg_startseq(void *m, upb_value fval) {
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
return lupb_msg_start(m, f, false, lupb_array_pushnew, f);
}
static upb_sflow_t lupb_msg_startsubmsg(void *m, upb_value fval) {
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
return lupb_msg_start(m, f, false, lupb_msg_pushnew, upb_fielddef_subdef(f));
}
static upb_sflow_t lupb_msg_startsubmsg_r(void *a, upb_value fval) {
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
return lupb_msg_start(a, f, true, lupb_msg_pushnew, upb_fielddef_subdef(f));
}
@@ -877,7 +877,7 @@ static void lupb_array_check(lua_State *L, int narg) {
luaL_typerror(L, narg, "upb array");
}
-static void lupb_array_pushnew(lua_State *L, void *f) {
+static void lupb_array_pushnew(lua_State *L, const void *f) {
(void)L;
(void)f;
}
diff --git a/bindings/python/upb.c b/bindings/python/upb.c
index ffb3d52..497074b 100644
--- a/bindings/python/upb.c
+++ b/bindings/python/upb.c
@@ -36,8 +36,8 @@ static upb_accessor_vtbl *PyUpb_AccessorForField(upb_fielddef *f);
// For objects that are just wrappers around a C object pointer, we keep a
// cache mapping C pointer -> wrapper object. This allows us to consistently
// vend the same Python object given the same C object. This prevents us from
-// creating too many Python objects unnecessarily. More importantly, it provides
-// the expected semantics:
+// creating too many Python objects unnecessarily. Just as importantly, it
+// provides the expected semantics:
//
// if field.subdef is field.subdef:
// print "Sanity prevails."
@@ -66,7 +66,7 @@ static PyObject *weakref_callback = NULL;
// Utility functions for manipulating Python dictionaries keyed by pointer.
-static PyObject *PyUpb_StringForPointer(void *ptr) {
+static PyObject *PyUpb_StringForPointer(const void *ptr) {
PyObject *o = PyString_FromStringAndSize((const char *)&ptr, sizeof(void*));
assert(o);
return o;
@@ -86,7 +86,7 @@ static PyObject *PyUpb_ObjCacheDeleteCallback(PyObject *self, PyObject *ref) {
return Py_None;
}
-static PyObject *PyUpb_ObjCacheGet(void *obj, PyTypeObject *type) {
+static PyObject *PyUpb_ObjCacheGet(const void *obj, PyTypeObject *type) {
PyObject *kv = PyUpb_StringForPointer(obj);
PyObject *ref = PyDict_GetItem(obj_cache, kv);
PyObject *ret;
@@ -96,7 +96,7 @@ static PyObject *PyUpb_ObjCacheGet(void *obj, PyTypeObject *type) {
Py_INCREF(ret);
} else {
PyUpb_ObjWrapper *wrapper = (PyUpb_ObjWrapper*)type->tp_alloc(type, 0);
- wrapper->obj = obj;
+ wrapper->obj = (void*)obj;
wrapper->weakreflist = NULL;
ret = (PyObject*)wrapper;
ref = PyWeakref_NewRef(ret, weakref_callback);
@@ -113,7 +113,7 @@ static PyObject *PyUpb_ObjCacheGet(void *obj, PyTypeObject *type) {
/* PyUpb_Def ******************************************************************/
-static PyTypeObject *PyUpb_TypeForDef(upb_def *def);
+static PyTypeObject *PyUpb_TypeForDef(const upb_def *def);
static void PyUpb_Def_dealloc(PyObject *obj) {
PyUpb_ObjWrapper *wrapper = (void*)obj;
@@ -121,7 +121,7 @@ static void PyUpb_Def_dealloc(PyObject *obj) {
obj->ob_type->tp_free(obj);
}
-PyObject *PyUpb_Def_GetOrCreate(upb_def *def) {
+PyObject *PyUpb_Def_GetOrCreate(const upb_def *def) {
return def ? PyUpb_ObjCacheGet(def, PyUpb_TypeForDef(def)) : Py_None;
}
@@ -142,7 +142,7 @@ static int PyUpb_FieldDef_setattro(PyObject *o, PyObject *key, PyObject *val);
} \
} while(0)
-static PyObject *PyUpb_FieldDef_GetOrCreate(upb_fielddef *f) {
+static PyObject *PyUpb_FieldDef_GetOrCreate(const upb_fielddef *f) {
return PyUpb_ObjCacheGet(f, &PyUpb_FieldDefType);
}
@@ -424,7 +424,7 @@ static PyTypeObject PyUpb_MessageDefType = {
};
-static PyTypeObject *PyUpb_TypeForDef(upb_def *def) {
+static PyTypeObject *PyUpb_TypeForDef(const upb_def *def) {
switch(def->type) {
case UPB_DEF_MSG: return &PyUpb_MessageDefType;
default: return NULL;
@@ -499,7 +499,7 @@ static PyObject *PyUpb_SymbolTable_add_def(PyObject *o, PyObject *def) {
static PyObject *PyUpb_SymbolTable_defs(PyObject *o, PyObject *none) {
upb_symtab *s = Check_SymbolTable(o, NULL);
int count;
- upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
+ const upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
PyObject *ret = PyList_New(count);
int i;
for(i = 0; i < count; i++)
@@ -510,7 +510,7 @@ static PyObject *PyUpb_SymbolTable_defs(PyObject *o, PyObject *none) {
static PyObject *PyUpb_SymbolTable_lookup(PyObject *o, PyObject *arg) {
upb_symtab *s = Check_SymbolTable(o, NULL);
const char *name = PyString_AsString(arg);
- upb_def *def = upb_symtab_lookup(s, name);
+ const upb_def *def = upb_symtab_lookup(s, name);
return PyUpb_Def_GetOrCreate(def);
}
@@ -581,7 +581,7 @@ typedef struct {
PyObject **PyUpb_Accessor_GetPtr(PyObject *_m, upb_value fval) {
PyUpb_Message *m = (PyUpb_Message*)_m;
- upb_fielddef *f = upb_value_getfielddef(fval);
+ const upb_fielddef *f = upb_value_getfielddef(fval);
return (PyObject**)&m->data[f->offset];
}
@@ -611,7 +611,7 @@ static upb_sflow_t PyUpb_Message_StartRepeatedSubmessage(void *a, upb_value fval
static upb_flow_t PyUpb_Message_StringValue(void *m, upb_value fval, upb_value val) {
PyObject **str = PyUpb_Accessor_GetPtr(m, fval);
- if (*str) Py_DECREF(*str);
+ if (*str) { Py_DECREF(*str); }
*str = PyString_FromStringAndSize(NULL, upb_value_getstrref(val)->len);
upb_strref_read(upb_value_getstrref(val), PyString_AsString(*str));
upb_stdmsg_sethas(m, fval);
diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc
index ac5a3be..35526fb 100644
--- a/tests/test_cpp.cc
+++ b/tests/test_cpp.cc
@@ -10,7 +10,7 @@ static void TestSymbolTable() {
std::cerr << "Couldn't load descriptor: " << status;
exit(1);
}
- upb::MessageDef *md = s->LookupMessage("A");
+ const upb::MessageDef *md = s->LookupMessage("A");
assert(md);
s->Unref();
diff --git a/tests/test_decoder.c b/tests/test_decoder.c
index 3ad9c08..1994501 100644
--- a/tests/test_decoder.c
+++ b/tests/test_decoder.c
@@ -20,20 +20,20 @@ int main(int argc, char *argv[]) {
}
upb_status status = UPB_STATUS_INIT;
- upb_read_descriptor(symtab, desc, desc_len, &status);
+ upb_load_descriptor_into_symtab(symtab, desc, desc_len, &status);
if (!upb_ok(&status)) {
fprintf(stderr, "Error parsing descriptor: %s", upb_status_getstr(&status));
return 1;
}
free((void*)desc);
- upb_def *md = upb_symtab_lookup(symtab, argv[2]);
+ const upb_def *md = upb_symtab_lookup(symtab, argv[2]);
if (!md) {
fprintf(stderr, "Descriptor did not contain message: %s\n", argv[2]);
return 1;
}
- upb_msgdef *m = upb_dyncast_msgdef(md);
+ const upb_msgdef *m = upb_dyncast_msgdef_const(md);
if (!m) {
fprintf(stderr, "Def was not a msgdef.\n");
return 1;
diff --git a/tests/test_def.c b/tests/test_def.c
index 1f014f6..3ca3064 100644
--- a/tests/test_def.c
+++ b/tests/test_def.c
@@ -8,7 +8,7 @@ int main() {
// Will be empty atm since we haven't added anything to the symtab.
int count;
- upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
+ const upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
for (int i = 0; i < count; i++) {
upb_def_unref(defs[i]);
}
diff --git a/tests/test_vs_proto2.cc b/tests/test_vs_proto2.cc
index a313aa5..22aa2e2 100644
--- a/tests/test_vs_proto2.cc
+++ b/tests/test_vs_proto2.cc
@@ -21,7 +21,7 @@
size_t string_size;
void compare(const google::protobuf::Message& proto2_msg,
- void *upb_msg, upb_msgdef *upb_md);
+ void *upb_msg, const upb_msgdef *upb_md);
void compare_arrays(const google::protobuf::Reflection *r,
const google::protobuf::Message& proto2_msg,
@@ -143,7 +143,7 @@ void compare_values(const google::protobuf::Reflection *r,
}
void compare(const google::protobuf::Message& proto2_msg,
- void *upb_msg, upb_msgdef *upb_md)
+ void *upb_msg, const upb_msgdef *upb_md)
{
const google::protobuf::Reflection *r = proto2_msg.GetReflection();
const google::protobuf::Descriptor *d = proto2_msg.GetDescriptor();
@@ -179,7 +179,7 @@ void compare(const google::protobuf::Message& proto2_msg,
}
void parse_and_compare(MESSAGE_CIDENT *proto2_msg,
- void *upb_msg, upb_msgdef *upb_md,
+ void *upb_msg, const upb_msgdef *upb_md,
const char *str, size_t len)
{
// Parse to both proto2 and upb.
@@ -223,7 +223,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Couldn't read " MESSAGE_DESCRIPTOR_FILE ".\n");
return 1;
}
- upb_read_descriptor(symtab, fds, fds_len, &status);
+ upb_load_descriptor_into_symtab(symtab, fds, fds_len, &status);
if(!upb_ok(&status)) {
fprintf(stderr, "Error importing " MESSAGE_DESCRIPTOR_FILE ": %s",
upb_status_getstr(&status));
@@ -231,9 +231,9 @@ int main(int argc, char *argv[])
}
free((void*)fds);
- upb_def *def = upb_symtab_lookup(symtab, MESSAGE_NAME);
- upb_msgdef *msgdef;
- if(!def || !(msgdef = upb_dyncast_msgdef(def))) {
+ const upb_def *def = upb_symtab_lookup(symtab, MESSAGE_NAME);
+ const upb_msgdef *msgdef;
+ if(!def || !(msgdef = upb_dyncast_msgdef_const(def))) {
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
return 1;
}
diff --git a/tests/tests.c b/tests/tests.c
index 64e3ef3..99e13cb 100644
--- a/tests/tests.c
+++ b/tests/tests.c
@@ -1,4 +1,5 @@
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -11,17 +12,12 @@
static upb_symtab *load_test_proto() {
upb_symtab *s = upb_symtab_new();
ASSERT(s);
- size_t len;
- char *descriptor = upb_readfile("tests/test.proto.pb", &len);
- if(!descriptor) {
- fprintf(stderr, "Couldn't read input file tests/test.proto.pb\n");
+ upb_status status = UPB_STATUS_INIT;
+ if (!upb_load_descriptor_file_into_symtab(s, "tests/test.proto.pb", &status)) {
+ fprintf(stderr, "Error loading descriptor file: %s\n", upb_status_getstr(&status));
exit(1);
}
- upb_status status = UPB_STATUS_INIT;
- upb_read_descriptor(s, descriptor, len, &status);
- ASSERT(upb_ok(&status));
upb_status_uninit(&status);
- free(descriptor);
return s;
}
@@ -34,12 +30,12 @@ static upb_flow_t upb_test_onvalue(void *closure, upb_value fval, upb_value val)
static void test_upb_jit() {
upb_symtab *s = load_test_proto();
- upb_def *def = upb_symtab_lookup(s, "SimplePrimitives");
+ const upb_def *def = upb_symtab_lookup(s, "SimplePrimitives");
ASSERT(def);
upb_handlers *h = upb_handlers_new();
upb_handlerset hset = {NULL, NULL, &upb_test_onvalue, NULL, NULL, NULL, NULL};
- upb_handlers_reghandlerset(h, upb_downcast_msgdef(def), &hset);
+ upb_handlers_reghandlerset(h, upb_downcast_msgdef_const(def), &hset);
upb_decoder d;
upb_decoder_init(&d, h);
upb_decoder_uninit(&d);
@@ -53,10 +49,10 @@ static void test_upb_symtab() {
// Test cycle detection by making a cyclic def's main refcount go to zero
// and then be incremented to one again.
- upb_def *def = upb_symtab_lookup(s, "A");
+ const upb_def *def = upb_symtab_lookup(s, "A");
ASSERT(def);
upb_symtab_unref(s);
- upb_msgdef *m = upb_downcast_msgdef(def);
+ const upb_msgdef *m = upb_downcast_msgdef_const(def);
upb_msg_iter i = upb_msg_begin(m);
upb_fielddef *f = upb_msg_iter_field(i);
ASSERT(upb_hassubdef(f));
diff --git a/tools/upbc.c b/tools/upbc.c
index 37ea2fe..a5d8897 100644
--- a/tools/upbc.c
+++ b/tools/upbc.c
@@ -36,8 +36,8 @@ static void to_preproc(char *str) {
/* The _const.h file defines the constants (enums) defined in the .proto
* file. */
-static void write_const_h(upb_def *defs[], int num_entries, char *outfile_name,
- FILE *stream) {
+static void write_const_h(const upb_def *defs[], int num_entries,
+ char *outfile_name, FILE *stream) {
/* Header file prologue. */
char *include_guard_name = strdup(outfile_name);
to_preproc(include_guard_name);
@@ -54,7 +54,7 @@ static void write_const_h(upb_def *defs[], int num_entries, char *outfile_name,
fprintf(stream, "/* Enums. */\n\n");
for(int i = 0; i < num_entries; i++) { /* Foreach enum */
if(defs[i]->type != UPB_DEF_ENUM) continue;
- upb_enumdef *enumdef = upb_downcast_enumdef(defs[i]);
+ const upb_enumdef *enumdef = upb_downcast_enumdef_const(defs[i]);
char *enum_name = strdup(upb_def_fqname(UPB_UPCAST(enumdef)));
char *enum_val_prefix = strdup(enum_name);
to_cident(enum_name);
@@ -83,7 +83,7 @@ static void write_const_h(upb_def *defs[], int num_entries, char *outfile_name,
/* Constants for field names and numbers. */
fprintf(stream, "/* Constants for field names and numbers. */\n\n");
for(int i = 0; i < num_entries; i++) { /* Foreach enum */
- upb_msgdef *m = upb_dyncast_msgdef(defs[i]);
+ const upb_msgdef *m = upb_dyncast_msgdef_const(defs[i]);
if(!m) continue;
char *msg_name = strdup(upb_def_fqname(UPB_UPCAST(m)));
char *msg_val_prefix = strdup(msg_name);
@@ -167,7 +167,7 @@ int main(int argc, char *argv[]) {
// importing descriptor.proto.
upb_symtab *s = upb_symtab_new();
upb_status status = UPB_STATUS_INIT;
- upb_read_descriptor(s, descriptor, len, &status);
+ upb_load_descriptor_into_symtab(s, descriptor, len, &status);
if(!upb_ok(&status)) {
error("Failed to parse input file descriptor: %s\n",
upb_status_getstr(&status));
@@ -184,7 +184,7 @@ int main(int argc, char *argv[]) {
if(!h_const_file) error("Failed to open _const.h output file\n");
int symcount;
- upb_def **defs = upb_symtab_getdefs(s, &symcount, UPB_DEF_ANY);
+ const upb_def **defs = upb_symtab_getdefs(s, &symcount, UPB_DEF_ANY);
write_const_h(defs, symcount, h_const_filename, h_const_file);
for (int i = 0; i < symcount; i++) upb_def_unref(defs[i]);
free(defs);
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