summaryrefslogtreecommitdiff
path: root/src/upb_string.h
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-08-12 13:47:24 -0700
committerJoshua Haberman <joshua@reverberate.org>2009-08-12 13:47:24 -0700
commit2282d2489bd8db3cd4ddbe0dd813732bffcf6452 (patch)
tree814fc94cd8ca4993363fb0ebe45b14e320a7a792 /src/upb_string.h
parent89a6c6d71f87bab63ee17c60f0feb56215f5c116 (diff)
Refactoring: unify upb_msg.
The cost is that a upb_msg will now always have an overhead of 2*sizeof(void*). This is comparable to proto2 overhead. The benefit is that upb_msg is now self-describing, and read-only algorithms can now operate on a upb_msg regardless of the memory-management scheme. Also, upb_array and upb_string now know inherently if they own their associated memory, and upb_array has a generic pointer for memory management purposes like upb_msg does.
Diffstat (limited to 'src/upb_string.h')
-rw-r--r--src/upb_string.h78
1 files changed, 57 insertions, 21 deletions
diff --git a/src/upb_string.h b/src/upb_string.h
index 528c8c8..7b63f1c 100644
--- a/src/upb_string.h
+++ b/src/upb_string.h
@@ -37,6 +37,7 @@ extern "C" {
#define INLINE static inline
#endif
+#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
struct upb_string {
@@ -44,45 +45,80 @@ struct upb_string {
* ingrained convention that we follow it. */
char *ptr;
uint32_t byte_len;
+ uint32_t byte_size; /* How many bytes of ptr we own. */
};
+INLINE void upb_strinit(struct upb_string *str)
+{
+ str->ptr = NULL;
+ str->byte_len = 0;
+ str->byte_size = 0;
+}
+
+INLINE void upb_struninit(struct upb_string *str)
+{
+ if(str->byte_size) free(str->ptr);
+}
+
+INLINE struct upb_string *upb_strnew()
+{
+ struct upb_string *str = (struct upb_string*)malloc(sizeof(*str));
+ upb_strinit(str);
+ return str;
+}
+
+INLINE void upb_strfree(struct upb_string *str)
+{
+ upb_struninit(str);
+ free(str);
+}
+
+INLINE void upb_stralloc(struct upb_string *str, uint32_t size)
+{
+ if(str->byte_size < size) {
+ /* Need to resize. */
+ str->byte_size = size;
+ void *oldptr = str->byte_size == 0 ? NULL : str->ptr;
+ str->ptr = (char*)realloc(oldptr, str->byte_size);
+ }
+}
+
+INLINE void upb_strdrop(struct upb_string *str)
+{
+ upb_struninit(str);
+}
+
INLINE bool upb_streql(struct upb_string *s1, struct upb_string *s2) {
return s1->byte_len == s2->byte_len &&
memcmp(s1->ptr, s2->ptr, s1->byte_len) == 0;
}
-INLINE int upb_strcmp(struct upb_string s1, struct upb_string s2) {
- size_t common_length = UPB_MIN(s1.byte_len, s2.byte_len);
- int common_diff = memcmp(s1.ptr, s2.ptr, common_length);
- if(common_diff == 0) return s1.byte_len - s2.byte_len;
- else return common_diff;
+INLINE int upb_strcmp(struct upb_string *s1, struct upb_string *s2) {
+ size_t common_length = UPB_MIN(s1->byte_len, s2->byte_len);
+ int common_diff = memcmp(s1->ptr, s2->ptr, common_length);
+ return common_diff == 0 ? (int)s1->byte_len - (int)s2->byte_len : common_diff;
}
INLINE void upb_strcpy(struct upb_string *dest, struct upb_string *src) {
- memcpy(dest->ptr, src->ptr, src->byte_len);
dest->byte_len = src->byte_len;
+ upb_stralloc(dest, dest->byte_len);
+ memcpy(dest->ptr, src->ptr, src->byte_len);
}
-INLINE struct upb_string upb_strdup(struct upb_string s) {
- struct upb_string copy;
- copy.ptr = (char*)malloc(s.byte_len);
- copy.byte_len = s.byte_len;
- memcpy(copy.ptr, s.ptr, s.byte_len);
+INLINE struct upb_string *upb_strdup(struct upb_string *s) {
+ struct upb_string *copy = upb_strnew();
+ upb_strcpy(copy, s);
return copy;
}
-INLINE struct upb_string upb_strdupc(char *s) {
- struct upb_string copy;
- copy.byte_len = strlen(s);
- copy.ptr = (char*)malloc(copy.byte_len);
- memcpy(copy.ptr, s, copy.byte_len);
+INLINE struct upb_string *upb_strdupc(char *s) {
+ struct upb_string *copy = upb_strnew();
+ copy->byte_len = strlen(s);
+ upb_stralloc(copy, copy->byte_len);
+ memcpy(copy->ptr, s, copy->byte_len);
return copy;
}
-INLINE void upb_strfree(struct upb_string s) {
- free(s.ptr);
-}
-
/* Reads an entire file into a newly-allocated string. */
bool upb_strreadfile(const char *filename, struct upb_string *data);
@@ -95,7 +131,7 @@ bool upb_strreadfile(const char *filename, struct upb_string *data);
/* Allows using upb_strings in printf, ie:
* struct upb_string str = UPB_STRLIT("Hello, World!\n");
* printf("String is: " UPB_STRFMT, UPB_STRARG(str)); */
-#define UPB_STRARG(str) (str).byte_len, (str).ptr
+#define UPB_STRARG(str) (str)->byte_len, (str)->ptr
#define UPB_STRFMT "%.*s"
#ifdef __cplusplus
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback