From cc396257679698852380822bc6bfb61d33244172 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 29 Dec 2009 18:39:51 -0800 Subject: Getting closer, only a few functions undefined now. --- src/upb.h | 13 ++++++++--- src/upb_data.c | 12 ++++++++--- src/upb_data.h | 61 ++++++++++++++++++++++++++++++++++++---------------- src/upb_def.h | 2 +- src/upb_inlinedefs.c | 8 ++----- src/upb_table.c | 1 + src/upb_table.h | 1 - 7 files changed, 65 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/upb.h b/src/upb.h index aeef349..158d631 100644 --- a/src/upb.h +++ b/src/upb.h @@ -122,9 +122,15 @@ struct upb_tag { /* Polymorphic values of .proto types *****************************************/ +// INTERNAL-ONLY: never refer to these types with a tag ("union", "struct"). +// Always use the typedefs. union upb_string; union upb_array; -union upb_msg; +struct upb_msg; + +typedef union upb_string upb_string; +typedef union upb_array upb_array; +typedef struct upb_msg upb_msg; // 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. @@ -138,7 +144,7 @@ union upb_value { bool _bool; union upb_string *str; union upb_array *arr; - union upb_msg *msg; + struct upb_msg *msg; }; // A pointer to a .proto value. The owner must have an out-of-band way of @@ -148,12 +154,13 @@ union upb_value_ptr { float *_float; int32_t *int32; int64_t *int64; + uint8_t *uint8; uint32_t *uint32; uint64_t *uint64; bool *_bool; union upb_string **str; union upb_array **arr; - union upb_msg **msg; + struct upb_msg **msg; void *_void; }; diff --git a/src/upb_data.c b/src/upb_data.c index 73a880f..b654fac 100644 --- a/src/upb_data.c +++ b/src/upb_data.c @@ -6,6 +6,7 @@ #include #include "upb_data.h" +#include "upb_def.h" INLINE void data_init(upb_data *d, int flags) { d->v = flags; @@ -64,8 +65,7 @@ void _upb_string_free(upb_string *s) free(s); } -char *upb_string_getrwbuf(upb_string *s, upb_strlen_t byte_len) -{ +void upb_string_resize(upb_string *s, upb_strlen_t byte_len) { check_not_frozen(&s->common.base); if(string_get_bytesize(s) < byte_len) { // Need to resize. @@ -74,7 +74,13 @@ char *upb_string_getrwbuf(upb_string *s, upb_strlen_t byte_len) string_set_bytesize(s, new_byte_size); } s->common.byte_len = byte_len; - return s->common.ptr; +} + +upb_msg *upb_msg_new(struct upb_msgdef *md) { + upb_msg *msg = malloc(md->size); + memset(msg, 0, md->size); + data_init(&msg->base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED); + return msg; } #if 0 diff --git a/src/upb_data.h b/src/upb_data.h index ac886fe..471272f 100644 --- a/src/upb_data.h +++ b/src/upb_data.h @@ -25,6 +25,7 @@ #include #include "upb.h" #include "upb_atomic.h" +#include "upb_def.h" struct upb_msgdef; struct upb_fielddef; @@ -195,11 +196,11 @@ typedef struct { uint32_t byte_size; } upb_refcounted_string; -typedef union upb_string { +union upb_string { upb_norefcount_string norefcount; upb_string_common common; upb_refcounted_string refcounted; -} upb_string; +}; // Returns a newly constructed, refcounted string which starts out empty. // Caller owns one ref on it. The returned string will not be frozen. @@ -228,13 +229,17 @@ INLINE void upb_string_unref(upb_string *s) { if(_upb_data_unref(&s->common.base)) _upb_string_free(s); } -// 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 src string must -// not be frozen otherwise the program will assert-fail or abort(). -char *upb_string_getrwbuf(upb_string *s, upb_strlen_t byte_len); - +// The string is resized to byte_len. The string must not be frozen. void upb_string_resize(upb_string *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) { + upb_string_resize(s, byte_len); + return s->common.ptr; +} + INLINE void upb_string_clear(upb_string *s) { upb_string_getrwbuf(s, 0); } @@ -352,11 +357,11 @@ typedef struct { upb_arraylen_t size; } upb_refcounted_array; -typedef union upb_array { +union upb_array { upb_norefcount_array norefcount; upb_array_common common; upb_refcounted_array refcounted; -} upb_array; +}; // This type can be used either to perform read-only access on an array, // or to statically define a non-reference-counted static array. @@ -373,7 +378,13 @@ typedef struct type ## _array { \ // empty. Caller owns one ref on it. upb_array *upb_array_new(void); -union upb_value upb_array_get(upb_array *a, struct upb_fielddef *f, int elem); +INLINE union upb_value upb_array_get(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); +} #if 0 // Returns an array to which caller owns a ref, and contains the same contents @@ -407,23 +418,35 @@ INLINE size_t upb_array_len(upb_array *a) { /* upb_msg ********************************************************************/ -typedef union upb_msg { - uint8_t data[1]; -} upb_msg; +// Note that some inline functions for upb_msg are defined in upb_def.h since +// they rely on the defs. + +struct upb_msg { + upb_data base; + uint8_t data[4]; // We allocate the appropriate amount per message. +}; // Creates a new msg of the given type. upb_msg *upb_msg_new(struct upb_msgdef *md); -void upb_msg_unref(upb_msg *msg, struct upb_msgdef *md); - // Tests whether the given field is explicitly set, or whether it will return // a default. -bool upb_msg_has(upb_msg *msg, struct upb_fielddef *f); +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 mutable version will first replace the value with a -// mutable copy if it is not already mutable. -union upb_value upb_msg_get(upb_msg *msg, struct upb_fielddef *f); +// 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); + } else { + return f->default_value; + } +} // Sets the given field to the given value. The msg will take a ref on val, // and will drop a ref on whatever was there before. diff --git a/src/upb_def.h b/src/upb_def.h index b013c40..d44f879 100644 --- a/src/upb_def.h +++ b/src/upb_def.h @@ -26,7 +26,6 @@ #ifndef UPB_DEF_H_ #define UPB_DEF_H_ -#include "upb_data.h" #include "upb_atomic.h" #include "upb_table.h" @@ -123,6 +122,7 @@ struct upb_fielddef { upb_label_t label; upb_field_number_t number; upb_string *name; + union upb_value default_value; // These are set only when this fielddef is part of a msgdef. uint32_t byte_offset; // Where in a upb_msg to find the data. diff --git a/src/upb_inlinedefs.c b/src/upb_inlinedefs.c index 7100849..5db04f6 100644 --- a/src/upb_inlinedefs.c +++ b/src/upb_inlinedefs.c @@ -12,13 +12,9 @@ */ #define INLINE -#include "upb_array.h" -#include "upb_context.h" +#include "upb.h" +#include "upb_data.h" #include "upb_def.h" -#include "upb_mm.h" -#include "upb_msg.h" #include "upb_parse.h" -#include "upb_serialize.h" -#include "upb_string.h" #include "upb_table.h" #include "upb_text.h" diff --git a/src/upb_table.c b/src/upb_table.c index 41252a2..f6f6d22 100644 --- a/src/upb_table.c +++ b/src/upb_table.c @@ -5,6 +5,7 @@ */ #include "upb_table.h" +#include "upb_data.h" #include #include diff --git a/src/upb_table.h b/src/upb_table.h index 31ff7d2..b89906d 100644 --- a/src/upb_table.h +++ b/src/upb_table.h @@ -17,7 +17,6 @@ #include #include "upb.h" -#include "upb_data.h" #ifdef __cplusplus extern "C" { -- cgit v1.2.3