summaryrefslogtreecommitdiff
path: root/src/upb_descriptor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/upb_descriptor.c')
-rw-r--r--src/upb_descriptor.c188
1 files changed, 85 insertions, 103 deletions
diff --git a/src/upb_descriptor.c b/src/upb_descriptor.c
index 127d19c..f70f1ba 100644
--- a/src/upb_descriptor.c
+++ b/src/upb_descriptor.c
@@ -9,19 +9,22 @@
#include <stdlib.h>
#include <errno.h>
-#include "upb_string.h"
#include "upb_def.h"
-/* Joins strings together, for example:
- * join("Foo.Bar", "Baz") -> "Foo.Bar.Baz"
- * join("", "Baz") -> "Baz"
- * Caller owns a ref on the returned string. */
-static upb_string *upb_join(upb_string *base, upb_string *name) {
- if (!base || upb_string_len(base) == 0) {
- return upb_string_getref(name);
+// Returns a newly allocated string that joins input strings together, for example:
+// join("Foo.Bar", "Baz") -> "Foo.Bar.Baz"
+// join("", "Baz") -> "Baz"
+// Caller owns a ref on the returned string. */
+static char *upb_join(char *base, char *name) {
+ if (!base || strlen(base) == 0) {
+ return strdup(name);
} else {
- return upb_string_asprintf(UPB_STRFMT "." UPB_STRFMT,
- UPB_STRARG(base), UPB_STRARG(name));
+ char *ret = malloc(strlen(base) + strlen(name) + 2);
+ ret[0] = '\0';
+ strcat(ret, base);
+ strcat(ret, ".");
+ strcat(ret, name);
+ return ret;
}
}
@@ -36,12 +39,12 @@ static upb_def *upb_deflist_last(upb_deflist *l) {
}
// Qualify the defname for all defs starting with offset "start" with "str".
-static void upb_deflist_qualify(upb_deflist *l, upb_string *str, int32_t start) {
+static void upb_deflist_qualify(upb_deflist *l, char *str, int32_t start) {
for(uint32_t i = start; i < l->len; i++) {
upb_def *def = l->defs[i];
- upb_string *name = def->fqname;
+ char *name = def->fqname;
def->fqname = upb_join(str, name);
- upb_string_unref(name);
+ free(name);
}
}
@@ -59,13 +62,13 @@ void upb_descreader_init(upb_descreader *r, upb_symtabtxn *txn) {
}
void upb_descreader_uninit(upb_descreader *r) {
- upb_string_unref(r->name);
+ free(r->name);
upb_status_uninit(&r->status);
upb_deflist_uninit(&r->defs);
- upb_string_unref(r->default_string);
+ free(r->default_string);
while (r->stack_len > 0) {
upb_descreader_frame *f = &r->stack[--r->stack_len];
- upb_string_unref(f->name);
+ free(f->name);
}
}
@@ -91,13 +94,14 @@ void upb_descreader_startcontainer(upb_descreader *r) {
void upb_descreader_endcontainer(upb_descreader *r) {
upb_descreader_frame *f = &r->stack[--r->stack_len];
upb_deflist_qualify(&r->defs, f->name, f->start);
- upb_string_unref(f->name);
+ free(f->name);
+ f->name = NULL;
}
-void upb_descreader_setscopename(upb_descreader *r, upb_string *str) {
+void upb_descreader_setscopename(upb_descreader *r, char *str) {
upb_descreader_frame *f = &r->stack[r->stack_len-1];
- upb_string_unref(f->name);
- f->name = upb_string_getref(str);
+ free(f->name);
+ f->name = str;
}
// Handlers for google.protobuf.FileDescriptorProto.
@@ -119,7 +123,7 @@ static upb_flow_t upb_descreader_FileDescriptorProto_package(void *_r,
upb_value val) {
(void)fval;
upb_descreader *r = _r;
- upb_descreader_setscopename(r, upb_value_getstr(val));
+ upb_descreader_setscopename(r, upb_strref_dup(upb_value_getstrref(val)));
return UPB_CONTINUE;
}
@@ -190,8 +194,8 @@ static upb_flow_t upb_enumdef_EnumValueDescriptorProto_name(void *_r,
upb_value val) {
(void)fval;
upb_descreader *r = _r;
- upb_string_unref(r->name);
- r->name = upb_string_getref(upb_value_getstr(val));
+ free(r->name);
+ r->name = upb_strref_dup(upb_value_getstrref(val));
r->saw_name = true;
return UPB_CONTINUE;
}
@@ -210,7 +214,7 @@ static void upb_enumdef_EnumValueDescriptorProto_endmsg(void *_r,
upb_status *status) {
upb_descreader *r = _r;
if(!r->saw_number || !r->saw_name) {
- upb_seterr(status, UPB_ERROR, "Enum value missing name or number.");
+ upb_status_setf(status, UPB_ERROR, "Enum value missing name or number.");
return;
}
upb_enumdef *e = upb_downcast_enumdef(upb_descreader_last(r));
@@ -220,7 +224,7 @@ static void upb_enumdef_EnumValueDescriptorProto_endmsg(void *_r,
upb_enumdef_setdefault(e, r->number);
}
upb_enumdef_addval(e, r->name, r->number);
- upb_string_unref(r->name);
+ free(r->name);
r->name = NULL;
}
@@ -254,11 +258,11 @@ static void upb_enumdef_EnumDescriptorProto_endmsg(void *_r, upb_status *status)
upb_descreader *r = _r;
upb_enumdef *e = upb_downcast_enumdef(upb_descreader_last(r));
if (upb_descreader_last((upb_descreader*)_r)->fqname == NULL) {
- upb_seterr(status, UPB_ERROR, "Enum had no name.");
+ upb_status_setf(status, UPB_ERROR, "Enum had no name.");
return;
}
if (upb_inttable_count(&e->iton) == 0) {
- upb_seterr(status, UPB_ERROR, "Enum had no values.");
+ upb_status_setf(status, UPB_ERROR, "Enum had no values.");
return;
}
}
@@ -269,8 +273,8 @@ static upb_flow_t upb_enumdef_EnumDescriptorProto_name(void *_r,
(void)fval;
upb_descreader *r = _r;
upb_enumdef *e = upb_downcast_enumdef(upb_descreader_last(r));
- upb_string_unref(e->base.fqname);
- e->base.fqname = upb_string_getref(upb_value_getstr(val));
+ free(e->base.fqname);
+ e->base.fqname = upb_strref_dup(upb_value_getstrref(val));
return UPB_CONTINUE;
}
@@ -298,99 +302,73 @@ static upb_flow_t upb_fielddef_startmsg(void *_r) {
return UPB_CONTINUE;
}
-// Converts the default value in string "dstr" into "d". Passes a ref on dstr.
+// Converts the default value in string "str" into "d". Passes a ref on str.
// Returns true on success.
-static bool upb_fielddef_parsedefault(upb_string *dstr, upb_value *d, int type) {
+static bool upb_fielddef_parsedefault(char *str, upb_value *d, int type) {
bool success = true;
if (type == UPB_TYPE(STRING) || type == UPB_TYPE(BYTES) || type == UPB_TYPE(ENUM)) {
// We'll keep the ref we had on it. We include enums in this case because
// we need the enumdef to resolve the name, but we may not have it yet.
// We'll resolve it later.
- if (dstr) {
- upb_value_setstr(d, dstr);
- } else {
- upb_value_setstr(d, upb_emptystring());
- }
+ if (!str) str = strdup("");
+ upb_value_setptr(d, str);
} else if (type == UPB_TYPE(MESSAGE) || type == UPB_TYPE(GROUP)) {
// We don't expect to get a default value.
- upb_string_unref(dstr);
- if (dstr != NULL) success = false;
+ free(str);
+ if (str != NULL) success = false;
+ } else if (type == UPB_TYPE(BOOL)) {
+ if (!str || strcmp(str, "false") == 0)
+ upb_value_setbool(d, false);
+ else if (strcmp(str, "true") == 0)
+ upb_value_setbool(d, true);
+ else
+ success = false;
+ free(str);
} else {
// The strto* functions need the string to be NULL-terminated.
- char *strz = upb_string_isempty(dstr) ? NULL : upb_string_newcstr(dstr);
+ if (!str) str = strdup("0");
char *end;
- upb_string_unref(dstr);
switch (type) {
case UPB_TYPE(INT32):
case UPB_TYPE(SINT32):
- case UPB_TYPE(SFIXED32):
- if (strz) {
- long val = strtol(strz, &end, 0);
- if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end)
- success = false;
- else
- upb_value_setint32(d, val);
- } else {
- upb_value_setint32(d, 0);
- }
+ case UPB_TYPE(SFIXED32): {
+ long val = strtol(str, &end, 0);
+ if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end)
+ success = false;
+ else
+ upb_value_setint32(d, val);
break;
+ }
case UPB_TYPE(INT64):
case UPB_TYPE(SINT64):
case UPB_TYPE(SFIXED64):
- if (strz) {
- upb_value_setint64(d, strtoll(strz, &end, 0));
- if (errno == ERANGE || *end) success = false;
- } else {
- upb_value_setint64(d, 0);
- }
+ upb_value_setint64(d, strtoll(str, &end, 0));
+ if (errno == ERANGE || *end) success = false;
break;
case UPB_TYPE(UINT32):
- case UPB_TYPE(FIXED32):
- if (strz) {
- unsigned long val = strtoul(strz, &end, 0);
- if (val > UINT32_MAX || errno == ERANGE || *end)
- success = false;
- else
- upb_value_setuint32(d, val);
- } else {
- upb_value_setuint32(d, 0);
- }
+ case UPB_TYPE(FIXED32): {
+ unsigned long val = strtoul(str, &end, 0);
+ if (val > UINT32_MAX || errno == ERANGE || *end)
+ success = false;
+ else
+ upb_value_setuint32(d, val);
break;
+ }
case UPB_TYPE(UINT64):
case UPB_TYPE(FIXED64):
- if (strz) {
- upb_value_setuint64(d, strtoull(strz, &end, 0));
- if (errno == ERANGE || *end) success = false;
- } else {
- upb_value_setuint64(d, 0);
- }
+ upb_value_setuint64(d, strtoull(str, &end, 0));
+ if (errno == ERANGE || *end) success = false;
break;
case UPB_TYPE(DOUBLE):
- if (strz) {
- upb_value_setdouble(d, strtod(strz, &end));
- if (errno == ERANGE || *end) success = false;
- } else {
- upb_value_setdouble(d, 0.0);
- }
+ upb_value_setdouble(d, strtod(str, &end));
+ if (errno == ERANGE || *end) success = false;
break;
case UPB_TYPE(FLOAT):
- if (strz) {
- upb_value_setfloat(d, strtof(strz, &end));
- if (errno == ERANGE || *end) success = false;
- } else {
- upb_value_setfloat(d, 0.0);
- }
- break;
- case UPB_TYPE(BOOL):
- if (!strz || strcmp(strz, "false") == 0)
- upb_value_setbool(d, false);
- else if (strcmp(strz, "true") == 0)
- upb_value_setbool(d, true);
- else
- success = false;
+ upb_value_setfloat(d, strtof(str, &end));
+ if (errno == ERANGE || *end) success = false;
break;
}
- free(strz);
+ free(str);
}
return success;
}
@@ -405,13 +383,13 @@ static void upb_fielddef_endmsg(void *_r, upb_status *status) {
// Field was successfully read, add it as a field of the msgdef.
upb_msgdef *m = upb_descreader_top(r);
upb_msgdef_addfield(m, f);
- upb_string *dstr = r->default_string;
+ char *dstr = r->default_string;
r->default_string = NULL;
upb_value val;
if (!upb_fielddef_parsedefault(dstr, &val, f->type)) {
// We don't worry too much about giving a great error message since the
// compiler should have ensured this was correct.
- upb_seterr(status, UPB_ERROR, "Error converting default value.");
+ upb_status_setf(status, UPB_ERROR, "Error converting default value.");
return;
}
upb_fielddef_setdefault(f, val);
@@ -441,7 +419,9 @@ static upb_flow_t upb_fielddef_onnumber(void *_r, upb_value fval, upb_value val)
static upb_flow_t upb_fielddef_onname(void *_r, upb_value fval, upb_value val) {
(void)fval;
upb_descreader *r = _r;
- upb_fielddef_setname(r->f, upb_value_getstr(val));
+ char *name = upb_strref_dup(upb_value_getstrref(val));
+ upb_fielddef_setname(r->f, name);
+ free(name);
return UPB_CONTINUE;
}
@@ -449,7 +429,9 @@ static upb_flow_t upb_fielddef_ontypename(void *_r, upb_value fval,
upb_value val) {
(void)fval;
upb_descreader *r = _r;
- upb_fielddef_settypename(r->f, upb_value_getstr(val));
+ char *name = upb_strref_dup(upb_value_getstrref(val));
+ upb_fielddef_settypename(r->f, name);
+ free(name);
return UPB_CONTINUE;
}
@@ -459,8 +441,8 @@ static upb_flow_t upb_fielddef_ondefaultval(void *_r, upb_value fval,
upb_descreader *r = _r;
// Have to convert from string to the correct type, but we might not know the
// type yet.
- upb_string_unref(r->default_string);
- r->default_string = upb_string_getref(upb_value_getstr(val));
+ free(r->default_string);
+ r->default_string = upb_strref_dup(upb_value_getstrref(val));
return UPB_CONTINUE;
}
@@ -501,7 +483,7 @@ static void upb_msgdef_endmsg(void *_r, upb_status *status) {
upb_descreader *r = _r;
upb_msgdef *m = upb_descreader_top(r);
if(!m->base.fqname) {
- upb_seterr(status, UPB_ERROR, "Encountered message with no name.");
+ upb_status_setf(status, UPB_ERROR, "Encountered message with no name.");
return;
}
@@ -514,9 +496,9 @@ static upb_flow_t upb_msgdef_onname(void *_r, upb_value fval, upb_value val) {
upb_descreader *r = _r;
assert(val.type == UPB_TYPE(STRING));
upb_msgdef *m = upb_descreader_top(r);
- upb_string_unref(m->base.fqname);
- m->base.fqname = upb_string_getref(upb_value_getstr(val));
- upb_descreader_setscopename(r, upb_value_getstr(val));
+ free(m->base.fqname);
+ m->base.fqname = upb_strref_dup(upb_value_getstrref(val));
+ upb_descreader_setscopename(r, strdup(m->base.fqname));
return UPB_CONTINUE;
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback