summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-12-29 18:39:51 -0800
committerJoshua Haberman <joshua@reverberate.org>2009-12-29 18:39:51 -0800
commitcc396257679698852380822bc6bfb61d33244172 (patch)
treea8aa652251198a9a47bcd2434ae490140accb986
parent2876225d0547ea7833991b9da8a72427e4bc69b9 (diff)
Getting closer, only a few functions undefined now.
-rw-r--r--src/upb.h13
-rw-r--r--src/upb_data.c12
-rw-r--r--src/upb_data.h61
-rw-r--r--src/upb_def.h2
-rw-r--r--src/upb_inlinedefs.c8
-rw-r--r--src/upb_table.c1
-rw-r--r--src/upb_table.h1
7 files changed, 65 insertions, 33 deletions
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 <stdlib.h>
#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 <string.h>
#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 <assert.h>
#include <stdlib.h>
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 <assert.h>
#include "upb.h"
-#include "upb_data.h"
#ifdef __cplusplus
extern "C" {
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback