Only remaining undefined symbol is upb_msg_parsestr.

pull/13171/head
Joshua Haberman 15 years ago
parent cc39625767
commit 3f0d126b2a
  1. 2
      Makefile
  2. 96
      src/upb_data.c
  3. 48
      src/upb_data.h
  4. 45
      src/upb_text.c

@ -47,7 +47,7 @@ clean:
# The core library (src/libupb.a)
SRC=src/upb.c src/upb_parse.c src/upb_table.c src/upb_def.c src/upb_data.c \
descriptor/descriptor.c
descriptor/descriptor.c src/upb_text.c
# Override the optimization level for upb_def.o, because it is not in the
# critical path but gets very large when -O3 is used.
src/upb_def.o: src/upb_def.c

@ -8,10 +8,6 @@
#include "upb_data.h"
#include "upb_def.h"
INLINE void data_init(upb_data *d, int flags) {
d->v = flags;
}
static uint32_t round_up_to_pow2(uint32_t v)
{
/* cf. http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 */
@ -25,6 +21,28 @@ static uint32_t round_up_to_pow2(uint32_t v)
return v;
}
/* upb_data *******************************************************************/
static void data_elem_unref(void *d, struct upb_fielddef *f) {
if(f->type == UPB_TYPE(MESSAGE) || f->type == UPB_TYPE(GROUP)) {
upb_msg_unref((upb_msg*)d, upb_downcast_msgdef(f->def));
} else if(f->type == UPB_TYPE(STRING) || f->type == UPB_TYPE(BYTES)) {
upb_string_unref((upb_string*)d);
}
}
static void data_unref(void *d, struct upb_fielddef *f) {
if(upb_isarray(f)) {
upb_array_unref((upb_array*)d, f);
} else {
data_elem_unref(d, f);
}
}
INLINE void data_init(upb_data *d, int flags) {
d->v = flags;
}
static void check_not_frozen(upb_data *d) {
// On one hand I am reluctant to put abort() calls in a low-level library
// that are enabled in a production build. On the other hand, this is a bug
@ -50,6 +68,9 @@ static void string_set_bytesize(upb_string *s, upb_strlen_t newsize) {
}
}
/* 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);
@ -76,6 +97,43 @@ void upb_string_resize(upb_string *s, upb_strlen_t byte_len) {
s->common.byte_len = byte_len;
}
upb_string *upb_strreadfile(const char *filename) {
FILE *f = fopen(filename, "rb");
if(!f) return false;
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();
char *buf = upb_string_getrwbuf(s, size);
if(fread(buf, size, 1, f) != 1) goto error;
fclose(f);
return s;
error:
fclose(f);
return NULL;
}
/* upb_array ******************************************************************/
// ONLY handles refcounted arrays for the moment.
void _upb_array_free(upb_array *a, struct upb_fielddef *f)
{
if(upb_elem_ismm(f)) {
for(upb_arraylen_t i = 0; i < a->refcounted.size; i++) {
union upb_value_ptr p = _upb_array_getptr(a, f, i);
data_elem_unref(p._void, f);
}
}
if(a->refcounted.size != 0) free(a->common.elements._void);
free(a);
}
/* upb_msg ********************************************************************/
upb_msg *upb_msg_new(struct upb_msgdef *md) {
upb_msg *msg = malloc(md->size);
memset(msg, 0, md->size);
@ -83,28 +141,16 @@ upb_msg *upb_msg_new(struct upb_msgdef *md) {
return msg;
}
#if 0
void upb_msg_destroy(struct upb_msg *msg) {
for(upb_field_count_t i = 0; i < msg->def->num_fields; i++) {
struct upb_fielddef *f = &msg->def->fields[i];
if(!upb_msg_isset(msg, f) || !upb_field_ismm(f)) continue;
upb_mm_destroy(upb_msg_getptr(msg, f), upb_field_ptrtype(f));
// ONLY handles refcounted messages for the moment.
void _upb_msg_free(upb_msg *msg, struct upb_msgdef *md)
{
for(int i = 0; i < md->num_fields; i++) {
struct upb_fielddef *f = &md->fields[i];
union upb_value_ptr p = _upb_msg_getptr(msg, f);
if(!upb_field_ismm(f) || !p._void) continue;
data_unref(p._void, f);
}
upb_def_unref(UPB_UPCAST(msg->def));
upb_def_unref(UPB_UPCAST(md));
free(msg);
}
void upb_array_destroy(struct upb_array *arr)
{
if(upb_elem_ismm(arr->fielddef)) {
upb_arraylen_t i;
/* Unref elements. */
for(i = 0; i < arr->size; i++) {
union upb_value_ptr p = upb_array_getelementptr(arr, i);
upb_mm_destroy(p, upb_elem_ptrtype(arr->fielddef));
}
}
if(arr->size != 0) free(arr->elements._void);
free(arr);
}
#endif

@ -378,12 +378,29 @@ typedef struct type ## _array { \
// empty. Caller owns one ref on it.
upb_array *upb_array_new(void);
INLINE union upb_value upb_array_get(upb_array *a, struct upb_fielddef *f,
int elem) {
// INTERNAL-ONLY:
// Frees the given message and releases references on members.
void _upb_array_free(upb_array *a, struct upb_fielddef *f);
// INTERNAL-ONLY:
// Returns a pointer to the given elem.
INLINE union upb_value_ptr _upb_array_getptr(upb_array *a,
struct upb_fielddef *f, int elem) {
assert(elem < upb_array_len(a));
size_t type_size = upb_type_info[f->type].size;
union upb_value_ptr p = {._void = &a->common.elements.uint8[elem * type_size]};
return upb_value_read(p, f->type);
return p;
}
INLINE union upb_value upb_array_get(upb_array *a, struct upb_fielddef *f,
int elem) {
return upb_value_read(_upb_array_getptr(a, f, elem), f->type);
}
// The caller releases a ref on the given array, which it must previously have
// owned a ref on.
INLINE void upb_array_unref(upb_array *a, struct upb_fielddef *f) {
if(_upb_data_unref(&a->common.base)) _upb_array_free(a, f);
}
#if 0
@ -392,10 +409,6 @@ INLINE union upb_value upb_array_get(upb_array *a, struct upb_fielddef *f,
// were incompatible with src's.
INLINE upb_array *upb_array_getref(upb_array *src, int ref_flags);
// The caller releases a ref on the given array, which it must previously have
// owned a ref on.
INLINE void upb_array_unref(upb_array *a, struct upb_fielddef *f);
// Sets the given element in the array to val. The current length of the array
// must be greater than elem. If the field type is dynamic, the array will
// take a ref on val and release a ref on what was previously in the array.
@ -429,20 +442,33 @@ struct upb_msg {
// Creates a new msg of the given type.
upb_msg *upb_msg_new(struct upb_msgdef *md);
// INTERNAL-ONLY:
// Frees the given message and releases references on members.
void _upb_msg_free(upb_msg *msg, struct upb_msgdef *md);
// INTERNAL-ONLY:
// Returns a pointer to the given field.
INLINE union upb_value_ptr _upb_msg_getptr(upb_msg *msg, struct upb_fielddef *f) {
union upb_value_ptr p = {._void = &msg->data[f->byte_offset]};
return p;
}
// Releases a references on msg.
INLINE void upb_msg_unref(upb_msg *msg, struct upb_msgdef *md) {
if(_upb_data_unref(&msg->base)) _upb_msg_free(msg, md);
}
// Tests whether the given field is explicitly set, or whether it will return
// a default.
INLINE bool upb_msg_has(upb_msg *msg, struct upb_fielddef *f) {
return msg->data[f->field_index/8] % (1 << (f->field_index % 8));
}
void upb_msg_unref(upb_msg *msg, struct upb_msgdef *md);
// Returns the current value if set, or the default value if not set, of the
// specified field. The caller does *not* own a ref.
INLINE union upb_value upb_msg_get(upb_msg *msg, struct upb_fielddef *f) {
if(upb_msg_has(msg, f)) {
union upb_value_ptr p = {._void = &msg->data[f->byte_offset]};
return upb_value_read(p, f->type);
return upb_value_read(_upb_msg_getptr(msg, f), f->type);
} else {
return f->default_value;
}

@ -7,9 +7,7 @@
#include <inttypes.h>
#include "descriptor.h"
#include "upb_text.h"
#include "upb_string.h"
#include "upb_msg.h"
#include "upb_array.h"
#include "upb_data.h"
void upb_text_printval(upb_field_type_t type, union upb_value val, FILE *file)
{
@ -51,7 +49,7 @@ static void print_indent(struct upb_text_printer *p, FILE *stream)
}
void upb_text_printfield(struct upb_text_printer *p,
struct upb_string *name,
upb_string *name,
upb_field_type_t valtype, union upb_value val,
FILE *stream)
{
@ -65,7 +63,7 @@ void upb_text_printfield(struct upb_text_printer *p,
}
void upb_text_push(struct upb_text_printer *p,
struct upb_string *submsg_type,
upb_string *submsg_type,
FILE *stream)
{
print_indent(p, stream);
@ -82,49 +80,48 @@ void upb_text_pop(struct upb_text_printer *p,
fprintf(stream, "}\n");
}
static void printval(struct upb_text_printer *printer, union upb_value_ptr p,
static void printval(struct upb_text_printer *printer, union upb_value v,
struct upb_fielddef *f,
FILE *stream);
static void printmsg(struct upb_text_printer *printer, struct upb_msg *msg,
FILE *stream)
static void printmsg(struct upb_text_printer *printer,
upb_msg *msg, struct upb_msgdef *md, FILE *stream)
{
struct upb_msgdef *m = msg->def;
for(upb_field_count_t i = 0; i < m->num_fields; i++) {
struct upb_fielddef *f = &m->fields[i];
if(!upb_msg_isset(msg, f)) continue;
union upb_value_ptr p = upb_msg_getptr(msg, f);
for(upb_field_count_t i = 0; i < md->num_fields; i++) {
struct upb_fielddef *f = &md->fields[i];
if(!upb_msg_has(msg, f)) continue;
union upb_value v = upb_msg_get(msg, f);
if(upb_isarray(f)) {
struct upb_array *arr = *p.arr;
for(uint32_t j = 0; j < arr->len; j++) {
union upb_value_ptr elem_p = upb_array_getelementptr(arr, j);
printval(printer, elem_p, f, stream);
upb_array *arr = v.arr;
for(uint32_t j = 0; j < upb_array_len(arr); j++) {
union upb_value elem = upb_array_get(arr, f, j);
printval(printer, elem, f, stream);
}
} else {
printval(printer, p, f, stream);
printval(printer, v, f, stream);
}
}
}
static void printval(struct upb_text_printer *printer, union upb_value_ptr p,
static void printval(struct upb_text_printer *printer, union upb_value v,
struct upb_fielddef *f,
FILE *stream)
{
if(upb_issubmsg(f)) {
upb_text_push(printer, f->name, stream);
printmsg(printer, *p.msg, stream);
printmsg(printer, v.msg, upb_downcast_msgdef(f->def), stream);
upb_text_pop(printer, stream);
} else {
upb_text_printfield(printer, f->name, f->type,
upb_value_read(p, f->type), stream);
upb_text_printfield(printer, f->name, f->type, v, stream);
}
}
void upb_msg_print(struct upb_msg *msg, bool single_line, FILE *stream)
void upb_msg_print(upb_msg *msg, struct upb_msgdef *md, bool single_line,
FILE *stream)
{
struct upb_text_printer printer;
upb_text_printer_init(&printer, single_line);
printmsg(&printer, msg, stream);
printmsg(&printer, msg, md, stream);
}

Loading…
Cancel
Save