Move string representations back upb.h -> upb_data.h.

pull/13171/head
Joshua Haberman 15 years ago
parent fa5710f1ca
commit 15604083c7
  1. 2
      descriptor/descriptor.c
  2. 34
      src/upb.h
  3. 2
      src/upb_data.c
  4. 31
      src/upb_data.h
  5. 2
      tools/upbc.c

@ -41,7 +41,7 @@ static char strdata[] =
"dpositive_int_valueservicestartstring_valuetypetype_nameuninterpreted_optionv" "dpositive_int_valueservicestartstring_valuetypetype_nameuninterpreted_optionv"
"alue"; "alue";
static upb_norefcount_string strings[] = { static upb_static_string strings[] = {
UPB_STATIC_STRING_INIT_LEN(&strdata[0], 32), UPB_STATIC_STRING_INIT_LEN(&strdata[0], 32),
UPB_STATIC_STRING_INIT_LEN(&strdata[32], 47), UPB_STATIC_STRING_INIT_LEN(&strdata[32], 47),
UPB_STATIC_STRING_INIT_LEN(&strdata[79], 36), UPB_STATIC_STRING_INIT_LEN(&strdata[79], 36),

@ -134,39 +134,13 @@ typedef upb_atomic_refcount_t upb_data;
typedef uint32_t upb_strlen_t; typedef uint32_t upb_strlen_t;
// We have several different representations for string, depending on whether struct upb_norefcount_string;
// it has a refcount (and likely in the future, depending on whether it is a struct upb_refcounted_string;
// 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 { typedef union {
// Must be first, for the UPB_STATIC_STRING_PTR_INIT() macro. // Must be first, for the UPB_STATIC_STRING_PTR_INIT() macro.
upb_norefcount_string *norefcount; struct upb_norefcount_string *norefcount;
struct upb_refcounted_string *refcounted;
upb_data *base; upb_data *base;
upb_refcounted_string *refcounted;
} upb_strptr; } upb_strptr;
// A single .proto value. The owner must have an out-of-band way of knowing // A single .proto value. The owner must have an out-of-band way of knowing

@ -74,7 +74,7 @@ static void _upb_string_set_bytelen(upb_strptr s, upb_strlen_t newlen) {
upb_strptr upb_string_new() { upb_strptr upb_string_new() {
upb_strptr s; upb_strptr s;
s.refcounted = malloc(sizeof(upb_refcounted_string)); s.refcounted = malloc(sizeof(struct upb_refcounted_string));
data_init(s.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED); data_init(s.base, UPB_DATA_HEAPALLOCATED | UPB_DATA_REFCOUNTED);
s.refcounted->byte_size = 0; s.refcounted->byte_size = 0;
s.refcounted->byte_len = 0; s.refcounted->byte_len = 0;

@ -165,6 +165,35 @@ INLINE bool _upb_data_unref(upb_data *d) {
/* upb_string *****************************************************************/ /* upb_string *****************************************************************/
// 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.
struct upb_norefcount_string {
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;
};
// Used for a string with a refcount.
struct upb_refcounted_string {
upb_data base;
upb_strlen_t byte_len;
char *ptr;
uint32_t byte_size;
};
// Returns a newly constructed, refcounted string which starts out empty. // Returns a newly constructed, refcounted string which starts out empty.
// Caller owns one ref on it. The returned string will not be frozen. // Caller owns one ref on it. The returned string will not be frozen.
upb_strptr upb_string_new(void); upb_strptr upb_string_new(void);
@ -296,7 +325,7 @@ upb_strptr upb_strreadfile(const char *filename);
// //
// upb_strtr mystr_ptr = UPB_STRLIT("biscuits"); // upb_strtr mystr_ptr = UPB_STRLIT("biscuits");
// //
typedef upb_norefcount_string upb_static_string; typedef struct 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_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_INIT(str) UPB_STATIC_STRING_INIT_LEN(str, sizeof(str)-1)
#define UPB_STATIC_STRING_PTR_INIT(static_string) {&static_string} #define UPB_STATIC_STRING_PTR_INIT(static_string) {&static_string}

@ -437,7 +437,7 @@ static void write_message_c(upb_msg *msg, struct upb_msgdef *md,
} }
fputs("\";\n\n", stream); fputs("\";\n\n", stream);
fputs("static upb_norefcount_string strings[] = {\n", stream); fputs("static upb_static_string strings[] = {\n", stream);
for(int i = 0; i < size; i++) { for(int i = 0; i < size; i++) {
struct strtable_entry *e = str_entries[i]; struct strtable_entry *e = str_entries[i];
fprintf(stream, " UPB_STATIC_STRING_INIT_LEN(&strdata[%d], %d),\n", e->offset, upb_strlen(e->e.key)); fprintf(stream, " UPB_STATIC_STRING_INIT_LEN(&strdata[%d], %d),\n", e->offset, upb_strlen(e->e.key));

Loading…
Cancel
Save