From 94a2f5bd9c476c7860c412b434b535f472c9a701 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 4 Jul 2009 11:28:09 -0700 Subject: Move upb_string into its own header file. --- upb.h | 27 ----------------------- upb_string.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ upb_table.h | 1 + 3 files changed, 71 insertions(+), 27 deletions(-) create mode 100644 upb_string.h diff --git a/upb.h b/upb.h index d76ba75..1267662 100644 --- a/upb.h +++ b/upb.h @@ -38,33 +38,6 @@ extern "C" { INLINE uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; } -/* Represents a string or bytes. */ -struct upb_string { - /* We expect the data to be 8-bit clean (uint8_t), but char* is such an - * ingrained convention that we follow it. */ - char *ptr; - uint32_t byte_len; -}; - -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 void upb_strcpy(struct upb_string *dest, struct upb_string *src) { - memcpy(dest->ptr, src->ptr, dest->byte_len); - dest->byte_len = src->byte_len; -} - -INLINE void upb_print(struct upb_string *str) { - fwrite(str->ptr, str->byte_len, 1, stdout); - fputc('\n', stdout); -} - -#define UPB_STRLIT(strlit) {.ptr=strlit, .byte_len=sizeof(strlit)-1} -#define UPB_STRFARG(str) (str).byte_len, (str).ptr -#define UPB_STRFMT "%.*s" - /* A list of types as they are encoded on-the-wire. */ enum upb_wire_type { UPB_WIRE_TYPE_VARINT = 0, diff --git a/upb_string.h b/upb_string.h new file mode 100644 index 0000000..d91fa69 --- /dev/null +++ b/upb_string.h @@ -0,0 +1,70 @@ +/* + * upb - a minimalist implementation of protocol buffers. + * + * Defines a delimited (as opposed to null-terminated) string type and some + * library functions for manipulating them. + * + * There are two primary reasons upb uses delimited strings. One is that they + * can be more efficient for some operations because they do not have to scan + * the string to find its length. For example, streql can start by just + * comparing the lengths (very efficient) and scan the strings themselves only + * if the lengths are equal. + * + * More importantly, using delimited strings makes it possible for strings to + * reference substrings of other strings. For example, if I am parsing a + * protobuf I can create a string that references the original protobuf's + * string data. With NULL-termination I would be forced to write a NULL + * into the middle of the protobuf's data, which is less than ideal and in + * some cases not practical or possible. + * + * Copyright (c) 2009 Joshua Haberman. See LICENSE for details. + */ + +#ifndef UPB_STRING_H_ +#define UPB_STRING_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +struct upb_string { + /* We expect the data to be 8-bit clean (uint8_t), but char* is such an + * ingrained convention that we follow it. */ + char *ptr; + uint32_t byte_len; +}; + +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 void upb_strcpy(struct upb_string *dest, struct upb_string *src) { + memcpy(dest->ptr, src->ptr, dest->byte_len); + dest->byte_len = 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); + return copy; +} + +INLINE void upb_strfree(struct upb_string s) { + free(s.ptr); +} + +#define UPB_STRLIT(strlit) {.ptr=strlit, .byte_len=sizeof(strlit)-1} +#define UPB_STRARG(str) (str).byte_len, (str).ptr +#define UPB_STRFMT "%.*s" + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_H_ */ diff --git a/upb_table.h b/upb_table.h index d024b85..5f9be99 100644 --- a/upb_table.h +++ b/upb_table.h @@ -17,6 +17,7 @@ #include #include "upb.h" +#include "upb_string.h" #ifdef __cplusplus extern "C" { -- cgit v1.2.3