summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/upb.h43
-rw-r--r--src/upb_data.c100
-rw-r--r--src/upb_data.h133
-rw-r--r--src/upb_def.c74
-rw-r--r--src/upb_def.h20
-rw-r--r--src/upb_parse.c2
-rw-r--r--src/upb_parse.h4
-rw-r--r--src/upb_table.c14
-rw-r--r--src/upb_table.h4
-rw-r--r--src/upb_text.c4
-rw-r--r--src/upb_text.h4
11 files changed, 224 insertions, 178 deletions
diff --git a/src/upb.h b/src/upb.h
index e130dd8..ecd5637 100644
--- a/src/upb.h
+++ b/src/upb.h
@@ -125,15 +125,50 @@ struct upb_tag {
// INTERNAL-ONLY: never refer to these types with a tag ("union", "struct").
// Always use the typedefs.
-union _upb_string;
union _upb_array;
struct _upb_msg;
-typedef union _upb_string upb_string;
typedef union _upb_array upb_array;
typedef struct _upb_msg upb_msg;
typedef upb_atomic_refcount_t upb_data;
+typedef uint32_t upb_strlen_t;
+
+// We have several different representations for string, depending on whether
+// it has a refcount (and likely in the future, depending on whether it is a
+// slice of another string). We could just have one representation with
+// members that are sometimes unused, but this is wasteful in memory. The
+// flags that are always part of the first word tell us which representation
+// to use.
+//
+// In a way, this is like inheritance but instead of using a virtual pointer,
+// we do switch/case in every "virtual" method. This may sound expensive but
+// in many cases the different cases compile to exactly the same code, so there
+// is no branch.
+
+typedef struct {
+ uint32_t byte_size_and_flags;
+ upb_strlen_t byte_len;
+ // We expect the data to be 8-bit clean (uint8_t), but char* is such an
+ // ingrained convention that we follow it.
+ char *ptr;
+} upb_norefcount_string;
+
+// Used for a string with a refcount.
+typedef struct {
+ upb_data base;
+ upb_strlen_t byte_len;
+ char *ptr;
+ uint32_t byte_size;
+} upb_refcounted_string;
+
+typedef union {
+ // Must be first, for the UPB_STATIC_STRING_PTR_INIT() macro.
+ upb_norefcount_string *norefcount;
+ upb_data *base;
+ upb_refcounted_string *refcounted;
+} upb_strptr;
+
// A single .proto value. The owner must have an out-of-band way of knowing
// the type, so that it knows which union member to use.
union upb_value {
@@ -144,7 +179,7 @@ union upb_value {
uint32_t uint32;
uint64_t uint64;
bool _bool;
- upb_string *str;
+ upb_strptr str;
upb_array *arr;
upb_msg *msg;
upb_data *data;
@@ -161,7 +196,7 @@ union upb_value_ptr {
uint32_t *uint32;
uint64_t *uint64;
bool *_bool;
- upb_string **str;
+ upb_strptr *str;
upb_array **arr;
upb_msg **msg;
upb_data **data;
diff --git a/src/upb_data.c b/src/upb_data.c
index e1aebdf..01acef8 100644
--- a/src/upb_data.c
+++ b/src/upb_data.c
@@ -57,65 +57,81 @@ static void check_not_frozen(upb_data *d) {
/* upb_string *******************************************************************/
-upb_string *upb_string_new() {
- upb_string *s = malloc(sizeof(upb_refcounted_string));
- data_init(&s->common.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED);
- s->refcounted.byte_size = 0;
- s->common.byte_len = 0;
- s->common.ptr = NULL;
+static char *_upb_string_setptr(upb_strptr s, char *ptr) {
+ if(upb_data_hasflag(s.base, UPB_DATA_REFCOUNTED))
+ return s.refcounted->ptr = ptr;
+ else
+ return s.norefcount->ptr = ptr;
+}
+
+static void _upb_string_set_bytelen(upb_strptr s, upb_strlen_t newlen) {
+ if(upb_data_hasflag(s.base, UPB_DATA_REFCOUNTED)) {
+ s.refcounted->byte_len = newlen;
+ } else {
+ s.norefcount->byte_len = newlen;
+ }
+}
+
+upb_strptr upb_string_new() {
+ upb_strptr s;
+ s.refcounted = malloc(sizeof(upb_refcounted_string));
+ data_init(s.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED);
+ s.refcounted->byte_size = 0;
+ s.refcounted->byte_len = 0;
+ s.refcounted->ptr = NULL;
return s;
}
-static upb_strlen_t string_get_bytesize(upb_string *s) {
- if(upb_data_hasflag(&s->common.base, UPB_DATA_REFCOUNTED)) {
- return s->refcounted.byte_size;
+static upb_strlen_t string_get_bytesize(upb_strptr s) {
+ if(upb_data_hasflag(s.base, UPB_DATA_REFCOUNTED)) {
+ return s.refcounted->byte_size;
} else {
- return (s->norefcount.byte_size_and_flags & 0xFFFFFFF8) >> 3;
+ return (s.norefcount->byte_size_and_flags & 0xFFFFFFF8) >> 3;
}
}
-static void string_set_bytesize(upb_string *s, upb_strlen_t newsize) {
- if(upb_data_hasflag(&s->common.base, UPB_DATA_REFCOUNTED)) {
- s->refcounted.byte_size = newsize;
+static void string_set_bytesize(upb_strptr s, upb_strlen_t newsize) {
+ if(upb_data_hasflag(s.base, UPB_DATA_REFCOUNTED)) {
+ s.refcounted->byte_size = newsize;
} else {
- s->norefcount.byte_size_and_flags &= 0x7;
- s->norefcount.byte_size_and_flags |= (newsize << 3);
+ s.norefcount->byte_size_and_flags &= 0x7;
+ s.norefcount->byte_size_and_flags |= (newsize << 3);
}
}
-void _upb_string_free(upb_string *s)
+void _upb_string_free(upb_strptr s)
{
- if(string_get_bytesize(s) != 0) free(s->common.ptr);
- free(s);
+ if(string_get_bytesize(s) != 0) free((void*)upb_string_getrobuf(s));
+ free(s.base);
}
-void upb_string_resize(upb_string *s, upb_strlen_t byte_len) {
- check_not_frozen(&s->common.base);
+void upb_string_resize(upb_strptr s, upb_strlen_t byte_len) {
+ check_not_frozen(s.base);
if(string_get_bytesize(s) < byte_len) {
// Need to resize.
size_t new_byte_size = round_up_to_pow2(byte_len);
- s->common.ptr = realloc(s->common.ptr, new_byte_size);
+ _upb_string_setptr(s, realloc(_upb_string_getptr(s), new_byte_size));
string_set_bytesize(s, new_byte_size);
}
- s->common.byte_len = byte_len;
+ _upb_string_set_bytelen(s, byte_len);
}
-upb_string *upb_string_getref(upb_string *s, int ref_flags) {
- if(_upb_data_incref(&s->common.base, ref_flags)) return s;
- upb_string *copy = upb_strdup(s);
+upb_strptr upb_string_getref(upb_strptr s, int ref_flags) {
+ if(_upb_data_incref(s.base, ref_flags)) return s;
+ upb_strptr copy = upb_strdup(s);
if(ref_flags == UPB_REF_FROZEN)
- upb_data_setflag(&copy->common.base, UPB_DATA_FROZEN);
+ upb_data_setflag(copy.base, UPB_DATA_FROZEN);
return copy;
}
-upb_string *upb_strreadfile(const char *filename) {
+upb_strptr upb_strreadfile(const char *filename) {
FILE *f = fopen(filename, "rb");
- if(!f) return false;
+ if(!f) return UPB_STRING_NULL;
if(fseek(f, 0, SEEK_END) != 0) goto error;
long size = ftell(f);
if(size < 0) goto error;
if(fseek(f, 0, SEEK_SET) != 0) goto error;
- upb_string *s = upb_string_new();
+ upb_strptr s = upb_string_new();
char *buf = upb_string_getrwbuf(s, size);
if(fread(buf, size, 1, f) != 1) goto error;
fclose(f);
@@ -123,18 +139,18 @@ upb_string *upb_strreadfile(const char *filename) {
error:
fclose(f);
- return NULL;
+ return UPB_STRING_NULL;
}
-upb_string *upb_strdupc(const char *src) {
- upb_string *copy = upb_string_new();
+upb_strptr upb_strdupc(const char *src) {
+ upb_strptr copy = upb_string_new();
upb_strlen_t len = strlen(src);
char *buf = upb_string_getrwbuf(copy, len);
memcpy(buf, src, len);
return copy;
}
-void upb_strcat(upb_string *s, upb_string *append) {
+void upb_strcat(upb_strptr s, upb_strptr append) {
upb_strlen_t s_len = upb_strlen(s);
upb_strlen_t append_len = upb_strlen(append);
upb_strlen_t newlen = s_len + append_len;
@@ -142,20 +158,20 @@ void upb_strcat(upb_string *s, upb_string *append) {
upb_string_getrobuf(append), append_len);
}
-upb_string *upb_strslice(upb_string *s, int offset, int len) {
- upb_string *slice = upb_string_new();
+upb_strptr upb_strslice(upb_strptr s, int offset, int len) {
+ upb_strptr slice = upb_string_new();
len = UPB_MIN((upb_strlen_t)len, upb_strlen(s) - (upb_strlen_t)offset);
memcpy(upb_string_getrwbuf(slice, len), upb_string_getrobuf(s) + offset, len);
return slice;
}
-upb_string *upb_strdup(upb_string *s) {
- upb_string *copy = upb_string_new();
+upb_strptr upb_strdup(upb_strptr s) {
+ upb_strptr copy = upb_string_new();
upb_strcpy(copy, s);
return copy;
}
-int upb_strcmp(upb_string *s1, upb_string *s2) {
+int upb_strcmp(upb_strptr s1, upb_strptr s2) {
upb_strlen_t common_length = UPB_MIN(upb_strlen(s1), upb_strlen(s2));
int common_diff = memcmp(upb_string_getrobuf(s1), upb_string_getrobuf(s2),
common_length);
@@ -315,8 +331,8 @@ static bool str_cb(void *udata, struct upb_msgdef *msgdef,
union upb_value_ptr p = get_value_ptr(msg, f);
upb_msg_sethas(msg, f);
if(avail_len != total_len) abort(); /* TODO: support streaming. */
- if(!*p.str || !upb_data_only(*p.data)) {
- if(*p.str)
+ if(upb_string_isnull(*p.str) || !upb_data_only(*p.data)) {
+ if(!upb_string_isnull(*p.str))
upb_string_unref(*p.str);
*p.str = upb_string_new();
}
@@ -373,7 +389,7 @@ void upb_msgparser_free(struct upb_msgparser *s)
free(s);
}
-void upb_msg_parsestr(upb_msg *msg, struct upb_msgdef *md, upb_string *str,
+void upb_msg_parsestr(upb_msg *msg, struct upb_msgdef *md, upb_strptr str,
struct upb_status *status)
{
struct upb_msgparser *mp = upb_msgparser_new(md);
@@ -383,7 +399,7 @@ void upb_msg_parsestr(upb_msg *msg, struct upb_msgdef *md, upb_string *str,
upb_msgparser_free(mp);
}
-size_t upb_msgparser_parse(struct upb_msgparser *s, upb_string *str,
+size_t upb_msgparser_parse(struct upb_msgparser *s, upb_strptr str,
struct upb_status *status)
{
return upb_cbparser_parse(s->s, str, status);
diff --git a/src/upb_data.h b/src/upb_data.h
index 6dc343b..9c55cee 100644
--- a/src/upb_data.h
+++ b/src/upb_data.h
@@ -165,88 +165,70 @@ INLINE bool _upb_data_unref(upb_data *d) {
/* upb_string *****************************************************************/
-typedef uint32_t upb_strlen_t;
-
-// We have several different representations for string, depending on whether
-// it has a refcount (and likely in the future, depending on whether it is a
-// slice of another string). We could just have one representation with
-// members that are sometimes unused, but this is wasteful in memory. The
-// flags that are always part of the first word tell us which representation
-// to use.
-//
-// upb_string_common is the members that are common to all representations.
-typedef struct {
- upb_data base;
- upb_strlen_t byte_len;
- // We expect the data to be 8-bit clean (uint8_t), but char* is such an
- // ingrained convention that we follow it.
- char *ptr;
-} upb_string_common;
-
-// Used for a string without a refcount.
-typedef struct {
- uint32_t byte_size_and_flags;
- upb_strlen_t byte_len;
- char *ptr;
-} upb_norefcount_string;
-
-// Used for a string with a refcount.
-typedef struct {
- upb_data base;
- upb_strlen_t byte_len;
- char *ptr;
- uint32_t byte_size;
-} upb_refcounted_string;
-
-union _upb_string {
- upb_norefcount_string norefcount;
- upb_string_common common;
- upb_refcounted_string refcounted;
-};
-
// Returns a newly constructed, refcounted string which starts out empty.
// Caller owns one ref on it. The returned string will not be frozen.
-upb_string *upb_string_new(void);
+upb_strptr upb_string_new(void);
// INTERNAL-ONLY:
// Frees the given string, alone with any memory the string owned.
-void _upb_string_free(upb_string *s);
+void _upb_string_free(upb_strptr s);
// Returns a string to which caller owns a ref, and contains the same contents
// as src. The returned value may be a copy of src, if the requested flags
// were incompatible with src's.
-upb_string *upb_string_getref(upb_string *s, int ref_flags);
+upb_strptr upb_string_getref(upb_strptr s, int ref_flags);
+
+#define UPB_STRING_NULL_INITIALIZER {NULL}
+static const upb_strptr UPB_STRING_NULL = UPB_STRING_NULL_INITIALIZER;
+INLINE bool upb_string_isnull(upb_strptr s) {
+ return s.base == NULL;
+}
// The caller releases a ref on src, which it must previously have owned a ref
// on.
-INLINE void upb_string_unref(upb_string *s) {
- if(_upb_data_unref(&s->common.base)) _upb_string_free(s);
+INLINE void upb_string_unref(upb_strptr s) {
+ if(_upb_data_unref(s.base)) _upb_string_free(s);
}
// The string is resized to byte_len. The string must not be frozen.
-void upb_string_resize(upb_string *s, upb_strlen_t len);
+void upb_string_resize(upb_strptr s, upb_strlen_t len);
// Returns a buffer to which the caller may write. The string is resized to
// byte_len (which may or may not trigger a reallocation). The string must not
// be frozen.
-INLINE char *upb_string_getrwbuf(upb_string *s, upb_strlen_t byte_len) {
+INLINE char *upb_string_getrwbuf(upb_strptr s, upb_strlen_t byte_len) {
upb_string_resize(s, byte_len);
- return s->common.ptr;
+ if(upb_data_hasflag(s.base, UPB_DATA_REFCOUNTED))
+ return s.refcounted->ptr;
+ else
+ return s.norefcount->ptr;
}
-INLINE void upb_string_clear(upb_string *s) {
+INLINE void upb_string_clear(upb_strptr s) {
upb_string_getrwbuf(s, 0);
}
+// INTERNAL-ONLY:
+// Gets/sets the pointer.
+INLINE char *_upb_string_getptr(upb_strptr s) {
+ if(upb_data_hasflag(s.base, UPB_DATA_REFCOUNTED))
+ return s.refcounted->ptr;
+ else
+ return s.norefcount->ptr;
+}
+
// Returns a buffer that the caller may use to read the current contents of
// the string. The number of bytes available is upb_strlen(s).
-INLINE const char *upb_string_getrobuf(upb_string *s) {
- return s->common.ptr;
+INLINE const char *upb_string_getrobuf(upb_strptr s) {
+ return _upb_string_getptr(s);
}
// Returns the current length of the string.
-INLINE upb_strlen_t upb_strlen(upb_string *s) {
- return s->common.byte_len;
+INLINE upb_strlen_t upb_strlen(upb_strptr s) {
+ if(upb_data_hasflag(s.base, UPB_DATA_REFCOUNTED))
+ return s.refcounted->byte_len;
+ else
+ return s.norefcount->byte_len;
}
/* upb_string library functions ***********************************************/
@@ -255,7 +237,7 @@ INLINE upb_strlen_t upb_strlen(upb_string *s) {
// overflow. These only use the public upb_string interface.
// More efficient than upb_strcmp if all you need is to test equality.
-INLINE bool upb_streql(upb_string *s1, upb_string *s2) {
+INLINE bool upb_streql(upb_strptr s1, upb_strptr s2) {
upb_strlen_t len = upb_strlen(s1);
if(len != upb_strlen(s2)) {
return false;
@@ -265,54 +247,65 @@ INLINE bool upb_streql(upb_string *s1, upb_string *s2) {
}
// Like strcmp().
-int upb_strcmp(upb_string *s1, upb_string *s2);
+int upb_strcmp(upb_strptr s1, upb_strptr s2);
// Like upb_strcpy, but copies from a buffer and length.
-INLINE void upb_strcpylen(upb_string *dest, const void *src, upb_strlen_t len) {
+INLINE void upb_strcpylen(upb_strptr dest, const void *src, upb_strlen_t len) {
memcpy(upb_string_getrwbuf(dest, len), src, len);
}
// Replaces the contents of "dest" with the contents of "src".
-INLINE void upb_strcpy(upb_string *dest, upb_string *src) {
+INLINE void upb_strcpy(upb_strptr dest, upb_strptr src) {
upb_strcpylen(dest, upb_string_getrobuf(src), upb_strlen(src));
}
// Like upb_strcpy, but copies from a NULL-terminated string.
-INLINE void upb_strcpyc(upb_string *dest, const char *src) {
+INLINE void upb_strcpyc(upb_strptr dest, const char *src) {
// This does two passes over src, but that is necessary unless we want to
// repeatedly re-allocate dst, which seems worse.
upb_strcpylen(dest, src, strlen(src));
}
// Returns a new string whose contents are a copy of s.
-upb_string *upb_strdup(upb_string *s);
+upb_strptr upb_strdup(upb_strptr s);
// Like upb_strdup(), but duplicates a C NULL-terminated string.
-upb_string *upb_strdupc(const char *src);
+upb_strptr upb_strdupc(const char *src);
// Appends 'append' to 's' in-place, resizing s if necessary.
-void upb_strcat(upb_string *s, upb_string *append);
+void upb_strcat(upb_strptr s, upb_strptr append);
// Returns a string that is a substring of the given string. Currently this
// returns a copy, but in the future this may return an object that references
// the original string data instead of copying it. Both now and in the future,
// the caller owns a ref on whatever is returned.
-upb_string *upb_strslice(upb_string *s, int offset, int len);
+upb_strptr upb_strslice(upb_strptr s, int offset, int len);
// Reads an entire file into a newly-allocated string (caller owns one ref).
-upb_string *upb_strreadfile(const char *filename);
+upb_strptr upb_strreadfile(const char *filename);
// Typedef for a read-only string that is allocated statically or on the stack.
// Initialize with the given macro, which must resolve to a const char*. You
-// must not dynamically allocate this type.
-typedef upb_string upb_static_string;
-#define UPB_STRLIT_LEN(str, len) {0 | UPB_DATA_FROZEN, len, str}
-#define UPB_STRLIT(str) {{0 | UPB_DATA_FROZEN, sizeof(str)-1, str}}
+// must not dynamically allocate this type. Example usage:
+//
+// upb_static_string mystr = UPB_STATIC_STRING_INIT("biscuits");
+// upb_strptr mystr_ptr = UPB_STATIC_STRING_PTR_INIT(mystr);
+//
+// If C99 compund literals are available, the much nicer UPB_STRLIT macro is
+// available instead:
+//
+// upb_strtr mystr_ptr = UPB_STRLIT("biscuits");
+//
+typedef upb_norefcount_string upb_static_string;
+#define UPB_STATIC_STRING_INIT_LEN(str, len) {0 | UPB_DATA_FROZEN, len, str}
+#define UPB_STATIC_STRING_INIT(str) UPB_STATIC_STRING_INIT_LEN(str, sizeof(str)-1)
+#define UPB_STATIC_STRING_PTR_INIT(static_string) {&static_string}
+#define UPB_STRLIT(str) (upb_strptr){&(upb_static_string)UPB_STATIC_STRING_INIT(str)}
// Allows using upb_strings in printf, ie:
-// upb_string str = UPB_STRLIT("Hello, World!\n");
+// upb_strptr str = UPB_STRLIT("Hello, World!\n");
// printf("String is: " UPB_STRFMT, UPB_STRARG(str)); */
-#define UPB_STRARG(str) (str)->common.byte_len, (str)->common.ptr
+#define UPB_STRARG(str) upb_strlen(str), upb_string_getrobuf(str)
#define UPB_STRFMT "%.*s"
/* upb_array ******************************************************************/
@@ -472,7 +465,7 @@ INLINE void upb_msg_clear(upb_msg *msg, struct upb_msgdef *md) {
/* Parsing ********************************************************************/
-void upb_msg_parsestr(upb_msg *msg, struct upb_msgdef *md, upb_string *str,
+void upb_msg_parsestr(upb_msg *msg, struct upb_msgdef *md, upb_strptr str,
struct upb_status *status);
struct upb_msgparser *upb_msgparser_new(struct upb_msgdef *def);
@@ -480,7 +473,7 @@ void upb_msgparser_free(struct upb_msgparser *mp);
void upb_msgparser_reset(struct upb_msgparser *mp, upb_msg *m);
-size_t upb_msgparser_parse(struct upb_msgparser *mp, upb_string *str,
+size_t upb_msgparser_parse(struct upb_msgparser *mp, upb_strptr str,
struct upb_status *status);
#endif
diff --git a/src/upb_def.c b/src/upb_def.c
index b1c4ab2..4f57407 100644
--- a/src/upb_def.c
+++ b/src/upb_def.c
@@ -150,7 +150,7 @@ void _upb_def_cyclic_ref(struct upb_def *def) {
}
static void upb_def_init(struct upb_def *def, enum upb_def_type type,
- upb_string *fqname) {
+ upb_strptr fqname) {
def->type = type;
def->is_cyclic = 0; // We detect this later, after resolving refs.
def->search_depth = 0;
@@ -166,12 +166,12 @@ static void upb_def_uninit(struct upb_def *def) {
struct upb_unresolveddef {
struct upb_def base;
- upb_string *name;
+ upb_strptr name;
};
-static struct upb_unresolveddef *upb_unresolveddef_new(upb_string *str) {
+static struct upb_unresolveddef *upb_unresolveddef_new(upb_strptr str) {
struct upb_unresolveddef *def = malloc(sizeof(*def));
- upb_string *name = upb_string_getref(str, UPB_REF_THREADUNSAFE_READONLY);
+ upb_strptr name = upb_string_getref(str, UPB_REF_THREADUNSAFE_READONLY);
upb_def_init(&def->base, UPB_DEF_UNRESOLVED, name);
def->name = name;
return def;
@@ -273,7 +273,7 @@ static void fielddef_sort(struct upb_fielddef **defs, size_t num)
static struct upb_msgdef *msgdef_new(struct upb_fielddef **fields,
int num_fields,
- upb_string *fqname,
+ upb_strptr fqname,
struct upb_status *status)
{
if(num_fields > UPB_MAX_FIELDS) {
@@ -356,11 +356,11 @@ struct ntoi_ent {
struct iton_ent {
struct upb_inttable_entry e;
- upb_string *string;
+ upb_strptr string;
};
static struct upb_enumdef *enumdef_new(google_protobuf_EnumDescriptorProto *ed,
- upb_string *fqname)
+ upb_strptr fqname)
{
struct upb_enumdef *e = malloc(sizeof(*e));
upb_def_init(&e->base, UPB_DEF_ENUM, fqname);
@@ -428,8 +428,8 @@ static int my_memrchr(char *data, char c, size_t len)
/* Given a symbol and the base symbol inside which it is defined, find the
* symbol's definition in t. */
static struct symtab_ent *resolve(struct upb_strtable *t,
- upb_string *base,
- upb_string *symbol)
+ upb_strptr base,
+ upb_strptr symbol)
{
if(upb_strlen(base) + upb_strlen(symbol) + 1 >= UPB_SYMBOL_MAXLEN ||
upb_strlen(symbol) == 0) return NULL;
@@ -437,13 +437,13 @@ static struct symtab_ent *resolve(struct upb_strtable *t,
if(upb_string_getrobuf(symbol)[0] == UPB_SYMBOL_SEPARATOR) {
// Symbols starting with '.' are absolute, so we do a single lookup.
// Slice to omit the leading '.'
- upb_string *sym_str = upb_strslice(symbol, 1, INT_MAX);
+ upb_strptr sym_str = upb_strslice(symbol, 1, INT_MAX);
struct symtab_ent *e = upb_strtable_lookup(t, sym_str);
upb_string_unref(sym_str);
return e;
} else {
// Remove components from base until we find an entry or run out.
- upb_string *sym_str = upb_string_new();
+ upb_strptr sym_str = upb_string_new();
int baselen = upb_strlen(base);
while(1) {
// sym_str = base[0...base_len] + UPB_SYMBOL_SEPARATOR + symbol
@@ -466,8 +466,8 @@ static struct symtab_ent *resolve(struct upb_strtable *t,
* join("Foo.Bar", "Baz") -> "Foo.Bar.Baz"
* join("", "Baz") -> "Baz"
* Caller owns a ref on the returned string. */
-static upb_string *join(upb_string *base, upb_string *name) {
- upb_string *joined = upb_strdup(base);
+static upb_strptr join(upb_strptr base, upb_strptr name) {
+ upb_strptr joined = upb_strdup(base);
upb_strlen_t len = upb_strlen(joined);
if(len > 0) {
upb_string_getrwbuf(joined, len + 1)[len] = UPB_SYMBOL_SEPARATOR;
@@ -476,34 +476,34 @@ static upb_string *join(upb_string *base, upb_string *name) {
return joined;
}
-static upb_string *try_define(struct upb_strtable *t, upb_string *base,
- upb_string *name, struct upb_status *status)
+static upb_strptr try_define(struct upb_strtable *t, upb_strptr base,
+ upb_strptr name, struct upb_status *status)
{
- if(!name) {
+ if(upb_string_isnull(name)) {
upb_seterr(status, UPB_STATUS_ERROR,
"symbol in context '" UPB_STRFMT "' does not have a name",
UPB_STRARG(base));
- return NULL;
+ return UPB_STRING_NULL;
}
- upb_string *fqname = join(base, name);
+ upb_strptr fqname = join(base, name);
if(upb_strtable_lookup(t, fqname)) {
upb_seterr(status, UPB_STATUS_ERROR,
"attempted to redefine symbol '" UPB_STRFMT "'",
UPB_STRARG(fqname));
upb_string_unref(fqname);
- return NULL;
+ return UPB_STRING_NULL;
}
return fqname;
}
static void insert_enum(struct upb_strtable *t,
google_protobuf_EnumDescriptorProto *ed,
- upb_string *base,
+ upb_strptr base,
struct upb_status *status)
{
- upb_string *name = ed->set_flags.has.name ? ed->name : NULL;
- upb_string *fqname = try_define(t, base, name, status);
- if(!fqname) return;
+ upb_strptr name = ed->set_flags.has.name ? ed->name : UPB_STRING_NULL;
+ upb_strptr fqname = try_define(t, base, name, status);
+ if(upb_string_isnull(fqname)) return;
struct symtab_ent e;
e.e.key = fqname;
@@ -514,12 +514,12 @@ static void insert_enum(struct upb_strtable *t,
static void insert_message(struct upb_strtable *t,
google_protobuf_DescriptorProto *d,
- upb_string *base, bool sort,
+ upb_strptr base, bool sort,
struct upb_status *status)
{
- upb_string *name = d->set_flags.has.name ? d->name : NULL;
- upb_string *fqname = try_define(t, base, name, status);
- if(!fqname) return;
+ upb_strptr name = d->set_flags.has.name ? d->name : UPB_STRING_NULL;
+ upb_strptr fqname = try_define(t, base, name, status);
+ if(upb_string_isnull(fqname)) return;
int num_fields = d->set_flags.has.field ? d->field->len : 0;
struct symtab_ent e;
@@ -610,7 +610,7 @@ static void addfd(struct upb_strtable *addto, struct upb_strtable *existingdefs,
google_protobuf_FileDescriptorProto *fd, bool sort,
struct upb_status *status)
{
- upb_string *pkg;
+ upb_strptr pkg;
if(fd->set_flags.has.package) {
pkg = upb_string_getref(fd->package, UPB_REF_FROZEN);
} else {
@@ -639,11 +639,11 @@ static void addfd(struct upb_strtable *addto, struct upb_strtable *existingdefs,
for(e = upb_strtable_begin(addto); e; e = upb_strtable_next(addto, &e->e)) {
struct upb_msgdef *m = upb_dyncast_msgdef(e->def);
if(!m) continue;
- upb_string *base = e->e.key;
+ upb_strptr base = e->e.key;
for(upb_field_count_t i = 0; i < m->num_fields; i++) {
struct upb_fielddef *f = &m->fields[i];
if(!upb_hasdef(f)) continue; // No resolving necessary.
- upb_string *name = upb_downcast_unresolveddef(f->def)->name;
+ upb_strptr name = upb_downcast_unresolveddef(f->def)->name;
struct symtab_ent *found = resolve(existingdefs, base, name);
if(!found) found = resolve(addto, base, name);
upb_field_type_t expected = upb_issubmsg(f) ? UPB_DEF_MSG : UPB_DEF_ENUM;
@@ -695,8 +695,10 @@ struct upb_symtab *upb_symtab_new()
assert(false);
return NULL; // Indicates that upb is buggy or corrupt.
}
- upb_string name = UPB_STRLIT("google.protobuf.FileDescriptorSet");
- struct symtab_ent *e = upb_strtable_lookup(&s->psymtab, &name);
+ upb_static_string name =
+ UPB_STATIC_STRING_INIT("google.protobuf.FileDescriptorSet");
+ upb_strptr nameptr = UPB_STATIC_STRING_PTR_INIT(name);
+ struct symtab_ent *e = upb_strtable_lookup(&s->psymtab, nameptr);
assert(e);
s->fds_msgdef = upb_downcast_msgdef(e->def);
return s;
@@ -741,7 +743,7 @@ struct upb_def **upb_symtab_getdefs(struct upb_symtab *s, int *count,
return defs;
}
-struct upb_def *upb_symtab_lookup(struct upb_symtab *s, upb_string *sym)
+struct upb_def *upb_symtab_lookup(struct upb_symtab *s, upb_strptr sym)
{
upb_rwlock_rdlock(&s->lock);
struct symtab_ent *e = upb_strtable_lookup(&s->symtab, sym);
@@ -755,8 +757,8 @@ struct upb_def *upb_symtab_lookup(struct upb_symtab *s, upb_string *sym)
}
-struct upb_def *upb_symtab_resolve(struct upb_symtab *s, upb_string *base,
- upb_string *symbol) {
+struct upb_def *upb_symtab_resolve(struct upb_symtab *s, upb_strptr base,
+ upb_strptr symbol) {
upb_rwlock_rdlock(&s->lock);
struct symtab_ent *e = resolve(&s->symtab, base, symbol);
struct upb_def *ret = NULL;
@@ -818,7 +820,7 @@ void upb_symtab_addfds(struct upb_symtab *s,
return;
}
-void upb_symtab_add_desc(struct upb_symtab *s, upb_string *desc,
+void upb_symtab_add_desc(struct upb_symtab *s, upb_strptr desc,
struct upb_status *status)
{
upb_msg *fds = upb_msg_new(s->fds_msgdef);
diff --git a/src/upb_def.h b/src/upb_def.h
index d44f879..15af25a 100644
--- a/src/upb_def.h
+++ b/src/upb_def.h
@@ -53,7 +53,7 @@ enum upb_def_type {
typedef int8_t upb_def_type_t;
struct upb_def {
- upb_string *fqname; // Fully qualified.
+ upb_strptr fqname; // Fully qualified.
upb_atomic_refcount_t refcount;
upb_def_type_t type;
@@ -121,7 +121,7 @@ struct upb_fielddef {
upb_field_type_t type;
upb_label_t label;
upb_field_number_t number;
- upb_string *name;
+ upb_strptr name;
union upb_value default_value;
// These are set only when this fielddef is part of a msgdef.
@@ -206,7 +206,7 @@ INLINE struct upb_fielddef *upb_msg_itof(struct upb_msgdef *m, uint32_t num) {
}
INLINE struct upb_fielddef *upb_msg_ntof(struct upb_msgdef *m,
- upb_string *name) {
+ upb_strptr name) {
struct upb_ntof_ent *e;
e = (struct upb_ntof_ent*)upb_strtable_lookup(&m->ntof, name);
return e ? e->f : NULL;
@@ -223,9 +223,9 @@ struct upb_enumdef {
typedef int32_t upb_enumval_t;
// Lookups from name to integer and vice-versa.
-bool upb_enumdef_ntoi(struct upb_enumdef *e, upb_string *name,
+bool upb_enumdef_ntoi(struct upb_enumdef *e, upb_strptr name,
upb_enumval_t *num);
-upb_string *upb_enumdef_iton(struct upb_enumdef *e, upb_enumval_t num);
+upb_strptr upb_enumdef_iton(struct upb_enumdef *e, upb_enumval_t num);
// Iteration over name/value pairs. The order is undefined.
// struct upb_enumd_iter i;
@@ -235,7 +235,7 @@ upb_string *upb_enumdef_iton(struct upb_enumdef *e, upb_enumval_t num);
struct upb_enum_iter {
struct upb_enumdef *e;
void *state; // Internal iteration state.
- upb_string *name;
+ upb_strptr name;
upb_enumval_t val;
};
void upb_enum_begin(struct upb_enum_iter *iter, struct upb_enumdef *e);
@@ -279,12 +279,12 @@ INLINE void upb_symtab_unref(struct upb_symtab *s) {
//
// If a def is found, the caller owns one ref on the returned def. Otherwise
// returns NULL.
-struct upb_def *upb_symtab_resolve(struct upb_symtab *s, upb_string *base,
- upb_string *symbol);
+struct upb_def *upb_symtab_resolve(struct upb_symtab *s, upb_strptr base,
+ upb_strptr symbol);
// 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.
-struct upb_def *upb_symtab_lookup(struct upb_symtab *s, upb_string *sym);
+struct upb_def *upb_symtab_lookup(struct upb_symtab *s, upb_strptr 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
@@ -298,7 +298,7 @@ struct upb_def **upb_symtab_getdefs(struct upb_symtab *s, int *count,
// defined in desc). desc may not attempt to define any names that are already
// defined in this symtab. Caller retains ownership of desc. status indicates
// whether the operation was successful or not, and the error message (if any).
-void upb_symtab_add_desc(struct upb_symtab *s, upb_string *desc,
+void upb_symtab_add_desc(struct upb_symtab *s, upb_strptr desc,
struct upb_status *status);
#ifdef __cplusplus
diff --git a/src/upb_parse.c b/src/upb_parse.c
index 32332d9..c4790c6 100644
--- a/src/upb_parse.c
+++ b/src/upb_parse.c
@@ -416,7 +416,7 @@ static const void *pop(struct upb_cbparser *p, const uint8_t *start)
}
-size_t upb_cbparser_parse(struct upb_cbparser *p, upb_string *str,
+size_t upb_cbparser_parse(struct upb_cbparser *p, upb_strptr str,
struct upb_status *status)
{
// buf is our current offset, moves from start to end.
diff --git a/src/upb_parse.h b/src/upb_parse.h
index 7086204..056750f 100644
--- a/src/upb_parse.h
+++ b/src/upb_parse.h
@@ -80,7 +80,7 @@ void upb_cbparser_reset(struct upb_cbparser *p, void *udata);
//
// TODO: see if we can provide the following guarantee efficiently:
// retval will always be >= len. */
-size_t upb_cbparser_parse(struct upb_cbparser *p, upb_string *str,
+size_t upb_cbparser_parse(struct upb_cbparser *p, upb_strptr str,
struct upb_status *status);
/* Pick parser interface. ************************************************/
@@ -119,7 +119,7 @@ struct upb_pickparser *upb_pickparser_new(struct upb_msgdef *msgdef,
upb_pp_str_cb str_cb);
void upb_pickparser_free(struct upb_pickparser *p);
void upb_pickparser_reset(struct upb_pickparser *p, void *udata);
-size_t upb_pickparser_parse(struct upb_pickparser *p, upb_string *str,
+size_t upb_pickparser_parse(struct upb_pickparser *p, upb_strptr str,
struct upb_status *status);
#ifdef __cplusplus
diff --git a/src/upb_table.c b/src/upb_table.c
index f6f6d22..14902df 100644
--- a/src/upb_table.c
+++ b/src/upb_table.c
@@ -57,19 +57,19 @@ void upb_strtable_free(struct upb_strtable *t) {
upb_table_free(&t->t);
}
-static uint32_t strtable_bucket(struct upb_strtable *t, upb_string *key)
+static uint32_t strtable_bucket(struct upb_strtable *t, upb_strptr key)
{
uint32_t hash = MurmurHash2(upb_string_getrobuf(key), upb_strlen(key), 0);
return (hash & (upb_strtable_size(t)-1)) + 1;
}
-void *upb_strtable_lookup(struct upb_strtable *t, upb_string *key)
+void *upb_strtable_lookup(struct upb_strtable *t, upb_strptr key)
{
uint32_t bucket = strtable_bucket(t, key);
struct upb_strtable_entry *e;
do {
e = strent(t, bucket);
- if(e->key && upb_streql(e->key, key)) return e;
+ if(!upb_string_isnull(e->key) && upb_streql(e->key, key)) return e;
} while((bucket = e->next) != UPB_END_OF_CHAIN);
return NULL;
}
@@ -149,7 +149,7 @@ static uint32_t empty_strbucket(struct upb_strtable *table)
/* TODO: does it matter that this is biased towards the front of the table? */
for(uint32_t i = 1; i <= upb_strtable_size(table); i++) {
struct upb_strtable_entry *e = strent(table, i);
- if(e->key == NULL) return i;
+ if(upb_string_isnull(e->key)) return i;
}
assert(false);
return 0;
@@ -162,7 +162,7 @@ static void strinsert(struct upb_strtable *t, struct upb_strtable_entry *e)
t->t.count++;
uint32_t bucket = strtable_bucket(t, e->key);
struct upb_strtable_entry *table_e = strent(t, bucket);
- if(table_e->key != NULL) { /* Collision. */
+ if(!upb_string_isnull(table_e->key)) { /* Collision. */
if(bucket == strtable_bucket(t, table_e->key)) {
/* Existing element is in its main posisiton. Find an empty slot to
* place our new element and append it to this key's chain. */
@@ -179,7 +179,7 @@ static void strinsert(struct upb_strtable *t, struct upb_strtable_entry *e)
memcpy(strent(t, empty_bucket), table_e, t->t.entry_size); /* copies next */
struct upb_strtable_entry *evictee_e = strent(t, evictee_bucket);
while(1) {
- assert(evictee_e->key != NULL);
+ assert(!upb_string_isnull(evictee_e->key));
assert(evictee_e->next != UPB_END_OF_CHAIN);
if(evictee_e->next == bucket) {
evictee_e->next = empty_bucket;
@@ -232,7 +232,7 @@ void *upb_strtable_next(struct upb_strtable *t, struct upb_strtable_entry *cur)
do {
cur = (void*)((char*)cur + t->t.entry_size);
if(cur == end) return NULL;
- } while(cur->key == NULL);
+ } while(upb_string_isnull(cur->key));
return cur;
}
diff --git a/src/upb_table.h b/src/upb_table.h
index b89906d..f7f548b 100644
--- a/src/upb_table.h
+++ b/src/upb_table.h
@@ -38,7 +38,7 @@ struct upb_inttable_entry {
// performance by letting us compare hashes before comparing lengths or the
// strings themselves.
struct upb_strtable_entry {
- upb_string *key; // We own a frozen ref.
+ upb_strptr key; // We own a frozen ref.
uint32_t next; // Internal chaining.
};
@@ -116,7 +116,7 @@ INLINE void *upb_inttable_lookup(struct upb_inttable *t, uint32_t key) {
return upb_inttable_fast_lookup(t, key, t->t.entry_size);
}
-void *upb_strtable_lookup(struct upb_strtable *t, upb_string *key);
+void *upb_strtable_lookup(struct upb_strtable *t, upb_strptr key);
/* Provides iteration over the table. The order in which the entries are
* returned is undefined. Insertions invalidate iterators. The _next
diff --git a/src/upb_text.c b/src/upb_text.c
index 17efa9f..225b344 100644
--- a/src/upb_text.c
+++ b/src/upb_text.c
@@ -49,7 +49,7 @@ static void print_indent(struct upb_text_printer *p, FILE *stream)
}
void upb_text_printfield(struct upb_text_printer *p,
- upb_string *name,
+ upb_strptr name,
upb_field_type_t valtype, union upb_value val,
FILE *stream)
{
@@ -63,7 +63,7 @@ void upb_text_printfield(struct upb_text_printer *p,
}
void upb_text_push(struct upb_text_printer *p,
- upb_string *submsg_type,
+ upb_strptr submsg_type,
FILE *stream)
{
print_indent(p, stream);
diff --git a/src/upb_text.h b/src/upb_text.h
index 6b2f4eb..bc15c3f 100644
--- a/src/upb_text.h
+++ b/src/upb_text.h
@@ -23,10 +23,10 @@ INLINE void upb_text_printer_init(struct upb_text_printer *p, bool single_line)
p->single_line = single_line;
}
void upb_text_printval(upb_field_type_t type, union upb_value p, FILE *file);
-void upb_text_printfield(struct upb_text_printer *p, upb_string *name,
+void upb_text_printfield(struct upb_text_printer *p, upb_strptr name,
upb_field_type_t valtype, union upb_value val,
FILE *stream);
-void upb_text_push(struct upb_text_printer *p, upb_string *submsg_type,
+void upb_text_push(struct upb_text_printer *p, upb_strptr submsg_type,
FILE *stream);
void upb_text_pop(struct upb_text_printer *p, FILE *stream);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback