parent
2a617bf12c
commit
4e7dc9d8b6
1 changed files with 99 additions and 0 deletions
@ -0,0 +1,99 @@ |
|||||||
|
/*
|
||||||
|
* upb - a minimalist implementation of protocol buffers. |
||||||
|
* |
||||||
|
* Copyright (c) 2010 Joshua Haberman. See LICENSE for details. |
||||||
|
* |
||||||
|
* Data structure for storing a message of protobuf data. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef UPB_MSG_H |
||||||
|
#define UPB_MSG_H |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
upb_atomic_refcount_t refcount; |
||||||
|
uint32_t len; |
||||||
|
uint32_t size; |
||||||
|
upb_valueptr elements; |
||||||
|
}; |
||||||
|
|
||||||
|
upb_array *upb_array_new(void); |
||||||
|
|
||||||
|
INLINE uint32_t upb_array_len(upb_array *a) { |
||||||
|
return a->len; |
||||||
|
} |
||||||
|
|
||||||
|
void _upb_array_free(upb_array *a, upb_fielddef *f); |
||||||
|
INLINE void upb_array_unref(upb_array *a, upb_fielddef *f) { |
||||||
|
if (upb_atomic_unref(&a->refcount)) _upb_array_free(a, f); |
||||||
|
} |
||||||
|
|
||||||
|
INLINE upb_value upb_array_get(upb_array *a, upb_fielddef *f, uint32_t elem) { |
||||||
|
assert(elem < upb_array_len(a)); |
||||||
|
return upb_value_read(_upb_array_getptr(a, f, elem), f->type); |
||||||
|
} |
||||||
|
|
||||||
|
// For string or submessages, will release a ref on the previously set value.
|
||||||
|
INLINE void upb_array_set(upb_array *a, upb_fielddef *f, uint32_t elem, |
||||||
|
upb_value val) { |
||||||
|
} |
||||||
|
|
||||||
|
// Append an element with the default value, returning it. For strings or
|
||||||
|
// submessages, this will try to reuse previously allocated memory.
|
||||||
|
INLINE upb_value upb_array_append_mutable(upb_array *a, upb_fielddef *f) { |
||||||
|
} |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
upb_atomic_refcount_t refcount; |
||||||
|
uint8_t data[4]; // We allocate the appropriate amount per message.
|
||||||
|
} upb_msg; |
||||||
|
|
||||||
|
// Creates a new msg of the given type.
|
||||||
|
upb_msg *upb_msg_new(upb_msgdef *md); |
||||||
|
|
||||||
|
void _upb_msg_free(upb_msg *msg, upb_msgdef *md); |
||||||
|
INLINE void upb_msg_unref(upb_msg *msg, upb_msgdef *md) { |
||||||
|
if (upb_atomic_unref(&msg->refcount)) _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, upb_fielddef *f) { |
||||||
|
return (msg->data[f->field_index/8] & (1 << (f->field_index % 8))) != 0; |
||||||
|
} |
||||||
|
|
||||||
|
// Returns the current value of the given field if set, or the default value if
|
||||||
|
// not set.
|
||||||
|
INLINE upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f) { |
||||||
|
if (upb_msg_has(msg, f)) { |
||||||
|
return upb_value_read(_upb_msg_getptr(msg, f), f->type); |
||||||
|
} else { |
||||||
|
return f->default_value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// If the given string, submessage, or array is already set, returns it.
|
||||||
|
// Otherwise sets it and returns an empty instance, attempting to reuse any
|
||||||
|
// previously allocated memory.
|
||||||
|
INLINE upb_value upb_msg_getmutable(upb_msg *msg, upb_fielddef *f) { |
||||||
|
} |
||||||
|
|
||||||
|
// Sets the current value of the field. If this is a string, array, or
|
||||||
|
// submessage field, releases a ref on the value (if any) that was previously
|
||||||
|
// set.
|
||||||
|
INLINE void upb_msg_set(upb_msg *msg, upb_fielddef *f, upb_value val) { |
||||||
|
} |
||||||
|
|
||||||
|
// Unsets all field values back to their defaults.
|
||||||
|
INLINE void upb_msg_clear(upb_msg *msg, upb_msgdef *md) { |
||||||
|
memset(msg->data, 0, md->set_flags_bytes); |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} /* extern "C" */ |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue