diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/upb.h | 56 | ||||
-rw-r--r-- | src/upb_parse.h | 61 |
2 files changed, 78 insertions, 39 deletions
@@ -37,29 +37,63 @@ extern "C" { INLINE uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; } -/* Value type as defined in a .proto file. The values of this are defined by - * google_protobuf_FieldDescriptorProto_Type (from descriptor.proto). - * Note that descriptor.proto reserves "0" for errors, and we use it to - * represent exceptional circumstances. */ +/* Fundamental types and type constants. **************************************/ + +/* A list of types as they are encoded on-the-wire. */ +enum upb_wire_type { + UPB_WIRE_TYPE_VARINT = 0, + UPB_WIRE_TYPE_64BIT = 1, + UPB_WIRE_TYPE_DELIMITED = 2, + UPB_WIRE_TYPE_START_GROUP = 3, + UPB_WIRE_TYPE_END_GROUP = 4, + UPB_WIRE_TYPE_32BIT = 5 +}; +typedef uint8_t upb_wire_type_t; + +/* Value type as defined in a .proto file. eg. string, int32, etc. + * + * The values of this are defined by google_protobuf_FieldDescriptorProto_Type + * (from descriptor.proto). Note that descriptor.proto reserves "0" for + * errors, and we use it to represent exceptional circumstances. */ typedef uint8_t upb_field_type_t; +/* Information about a given value type (upb_field_type_t). */ struct upb_type_info { uint8_t align; uint8_t size; - uint8_t expected_wire_type; + upb_wire_type_t expected_wire_type; struct upb_string ctype; }; /* Contains information for all .proto types. Indexed by upb_field_type_t. */ extern struct upb_type_info upb_type_info[]; +/* The number of a field, eg. "optional string foo = 3". */ +typedef int32_t upb_field_number_t; + /* Label (optional, repeated, required) as defined in a .proto file. The values * of this are defined by google.protobuf.FieldDescriptorProto.Label (from * descriptor.proto). */ typedef uint8_t upb_label_t; -/* A pointer to a .proto value. The owner must have an out-of-band way of - * knowing the type, so it knows which union member to use. */ +/* A value as it is encoded on-the-wire, except delimited, which is handled + * separately. */ +union upb_wire_value { + uint64_t varint; + uint64_t _64bit; + uint32_t _32bit; +}; + +/* A tag occurs before each value on-the-wire. */ +struct upb_tag { + upb_field_number_t field_number; + upb_wire_type_t wire_type; +}; + +/* Polymorphic values of .proto types *****************************************/ + +/* 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. */ union upb_value { double _double; float _float; @@ -73,6 +107,8 @@ union upb_value { void *msg; }; +/* A pointer to a .proto value. The owner must have an out-of-band way of + * knowing the type, so it knows which union member to use. */ union upb_value_ptr { double *_double; float *_float; @@ -87,6 +123,9 @@ union upb_value_ptr { void *_void; }; +/* Converts upb_value_ptr -> upb_value by "dereferencing" the pointer. We need + * to know the field type to perform this operation, because we need to know + * how much memory to copy. */ INLINE union upb_value upb_deref(union upb_value_ptr ptr, upb_field_type_t t) { union upb_value val; memcpy(&val, ptr._void, upb_type_info[t].size); @@ -99,9 +138,6 @@ union upb_symbol_ref { struct upb_svc *svc; }; -/* The number of a field, eg. "optional string foo = 3". */ -typedef int32_t upb_field_number_t; - /* Status codes used as a return value. Codes >0 are not fatal and can be * resumed. */ typedef enum upb_status { diff --git a/src/upb_parse.h b/src/upb_parse.h index 9e95c9c..dfcb534 100644 --- a/src/upb_parse.h +++ b/src/upb_parse.h @@ -21,33 +21,6 @@ extern "C" { #endif -/* Definitions. ***************************************************************/ - -/* A list of types as they are encoded on-the-wire. */ -enum upb_wire_type { - UPB_WIRE_TYPE_VARINT = 0, - UPB_WIRE_TYPE_64BIT = 1, - UPB_WIRE_TYPE_DELIMITED = 2, - UPB_WIRE_TYPE_START_GROUP = 3, - UPB_WIRE_TYPE_END_GROUP = 4, - UPB_WIRE_TYPE_32BIT = 5 -}; -typedef uint8_t upb_wire_type_t; - -/* A value as it is encoded on-the-wire, except delimited, which is handled - * separately. */ -union upb_wire_value { - uint64_t varint; - uint64_t _64bit; - uint32_t _32bit; -}; - -/* A tag occurs before each value on-the-wire. */ -struct upb_tag { - upb_field_number_t field_number; - upb_wire_type_t wire_type; -}; - INLINE bool upb_issubmsgtype(upb_field_type_t type) { return type == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_GROUP || type == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_MESSAGE; @@ -150,11 +123,16 @@ upb_status_t upb_parse_value(uint8_t *buf, uint8_t *end, upb_field_type_t ft, upb_status_t upb_parse_wire_value(uint8_t *buf, uint8_t *end, upb_wire_type_t wt, union upb_wire_value *wv, uint8_t **outbuf); -/* Low-level parsing functions. **********************************************/ +/* Functions to read wire values. *********************************************/ + +/* In general, these should never be called directly from any code outside upb. + * They are included here only because we expect them to get inlined inside the + * value-reading functions below. */ upb_status_t upb_get_v_uint64_t_full(uint8_t *buf, uint8_t *end, uint64_t *val, uint8_t **outbuf); +/* Gets a varint (wire type: UPB_WIRE_TYPE_VARINT). */ INLINE upb_status_t upb_get_v_uint64_t(uint8_t *buf, uint8_t *end, uint64_t *val, uint8_t **outbuf) { @@ -175,6 +153,7 @@ INLINE upb_status_t upb_get_v_uint64_t(uint8_t *buf, uint8_t *end, uint64_t *val } } +/* Gets a varint -- called when we only need 32 bits of it. */ INLINE upb_status_t upb_get_v_uint32_t(uint8_t *buf, uint8_t *end, uint32_t *val, uint8_t **outbuf) { @@ -185,6 +164,7 @@ INLINE upb_status_t upb_get_v_uint32_t(uint8_t *buf, uint8_t *end, return UPB_STATUS_OK; } +/* Gets a fixed-length 32-bit integer (wire type: UPB_WIRE_TYPE_32BIT). */ INLINE upb_status_t upb_get_f_uint32_t(uint8_t *buf, uint8_t *end, uint32_t *val, uint8_t **outbuf) { @@ -201,6 +181,7 @@ INLINE upb_status_t upb_get_f_uint32_t(uint8_t *buf, uint8_t *end, return UPB_STATUS_OK; } +/* Gets a fixed-length 64-bit integer (wire type: UPB_WIRE_TYPE_64BIT). */ INLINE upb_status_t upb_get_f_uint64_t(uint8_t *buf, uint8_t *end, uint64_t *val, uint8_t **outbuf) { @@ -218,15 +199,36 @@ INLINE upb_status_t upb_get_f_uint64_t(uint8_t *buf, uint8_t *end, return UPB_STATUS_OK; } +/* Functions to read .proto values. *******************************************/ + +/* These functions read the appropriate wire value for a given .proto type + * and then convert it based on the .proto type. These are the most efficient + * functions to call if you want to decode a value for a known type. */ + +/* Performs zig-zag decoding, which is used by sint32 and sint64. */ INLINE int32_t zz_decode_32(uint32_t n) { return (n >> 1) ^ -(int32_t)(n & 1); } INLINE int64_t zz_decode_64(uint64_t n) { return (n >> 1) ^ -(int64_t)(n & 1); } +/* Use macros to define a set of two functions for each .proto type: + * + * // Reads and converts a .proto value from buf, placing it in d. + * // "end" indicates the end of the current buffer (if the buffer does + * // not contain the entire value UPB_STATUS_NEED_MORE_DATA is returned). + * // On success, *outbuf will point to the first byte that was not consumed. + * upb_status_t upb_get_INT32(uint8_t *buf, uint8_t *end, int32_t *d, + * uint8_t **outbuf); + * + * // Given an already read wire value s (source), convert it to a .proto + * // value and store it in *d (destination). + * void upb_wvtov_INT32(uint32_t s, int32_t *d); + */ #define WVTOV(type, wire_t, val_t) \ INLINE void upb_wvtov_ ## type(wire_t s, val_t *d) #define GET(type, v_or_f, wire_t, val_t, member_name) \ - INLINE upb_status_t upb_get_ ## type(uint8_t *buf, uint8_t *end, val_t *d, uint8_t **outbuf) { \ + INLINE upb_status_t upb_get_ ## type(uint8_t *buf, uint8_t *end, val_t *d, \ + uint8_t **outbuf) { \ wire_t tmp; \ UPB_CHECK(upb_get_ ## v_or_f ## _ ## wire_t(buf, end, &tmp, outbuf)); \ upb_wvtov_ ## type(tmp, d); \ @@ -256,6 +258,7 @@ T(ENUM, v, uint32_t, int32_t, int32) { *d = (int32_t)s; } #undef GET #undef T +/* Parses a tag, places the result in *tag. */ INLINE upb_status_t parse_tag(uint8_t *buf, uint8_t *end, struct upb_tag *tag, uint8_t **outbuf) { |