diff options
Diffstat (limited to 'upb_parse.h')
-rw-r--r-- | upb_parse.h | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/upb_parse.h b/upb_parse.h index fbc5898..9d3d52d 100644 --- a/upb_parse.h +++ b/upb_parse.h @@ -29,14 +29,32 @@ void upb_parse_state_init(struct upb_parse_state *state, size_t udata_size); void upb_parse_state_free(struct upb_parse_state *state); /* The callback that is called immediately after a tag has been parsed. The - * client must either advance the stream beyond the corresponding value or - * return an error to indicate that the stream should rewind to before the - * tag. + * client should determine whether it wants to parse or skip the corresponding + * value. If it wants to parse it, it must discover and return the correct + * .proto type (the tag only contains the wire type) and check that the wire + * type is appropriate for the .proto type. To skip the value (which means + * skipping all submessages, in the case of a submessage), the callback should + * return zero. */ +typedef upb_field_type_t (*upb_tag_cb)(struct upb_parse_state *s, + struct upb_tag *tag, + void **user_field_desc); + +/* The callback that is called when a regular value (ie. not a string or + * submessage) is encountered which the client has opted to parse (by not + * returning 0 from the tag_cb). The client must parse the value and update + * buf accordingly, returning success or failure. * - * The client advances the stream beyond the corresponding value by either - * parsing the value or skipping it. */ -typedef upb_field_type_t (*upb_tag_cb)(void **buf, struct upb_parse_state *s, - struct upb_tag *tag); + * Note that this callback can be called several times in a row for a single + * call to tag_cb in the case of packed arrays. */ +typedef upb_status_t (*upb_value_cb)(struct upb_parse_state *s, + void **buf, void *end, + upb_field_type_t type, + void *user_field_desc); + +/* The callback that is called when a string is parsed. */ +typedef upb_status_t (*upb_str_cb)(struct upb_parse_state *s, + struct upb_string *str, + void *user_field_desc); /* Callbacks that are called when a submessage begins and ends, respectively. * Both are called with the submessage's stack frame at the top of the stack. */ @@ -55,13 +73,11 @@ struct upb_parse_state { size_t offset; struct upb_parse_stack_frame *stack, *top, *limit; size_t udata_size; /* How many bytes the user gets in each frame. */ - bool done; /* Any callback can abort processing by setting done=true. */ - /* These are only set if we're in the middle of a packed array. */ - size_t packed_end_offset; /* 0 if not in a packed array. */ - upb_field_type_t packed_type; - upb_tag_cb tag_cb; + upb_tag_cb tag_cb; + upb_value_cb value_cb; + upb_str_cb str_cb; upb_submsg_start_cb submsg_start_cb; - upb_submsg_end_cb submsg_end_cb; + upb_submsg_end_cb submsg_end_cb; }; /* Parses up to len bytes of protobuf data out of buf, calling cb as needed. @@ -71,37 +87,35 @@ struct upb_parse_state { upb_status_t upb_parse(struct upb_parse_state *s, void *buf, size_t len, size_t *read); -/* Low-level parsing functions. ***********************************************/ - -/* Parses a single tag from the character data starting at buf, and updates - * buf to point one past the bytes that were consumed. buf will be incremented - * by at most ten bytes. */ -upb_status_t upb_parse_tag(void **buf, size_t len, struct upb_tag *tag); - extern upb_wire_type_t upb_expected_wire_types[]; /* Returns true if wt is the correct on-the-wire type for ft. */ INLINE bool upb_check_type(upb_wire_type_t wt, upb_field_type_t ft) { return upb_expected_wire_types[ft] == wt; } +/* Data-consuming functions (to be called from value cb). *********************/ + +/* Parses a single tag from the character data starting at buf, and updates + * buf to point one past the bytes that were consumed. buf will be incremented + * by at most ten bytes. */ +upb_status_t upb_parse_tag(void **buf, void *end, struct upb_tag *tag); + /* Parses and converts a value from the character data starting at buf. The * caller must have previously checked that the wire type is appropriate for * this field type. For delimited data, buf is advanced to the beginning of * the delimited data, not the end. */ -upb_status_t upb_parse_value(void **buf, size_t len, upb_field_type_t ft, - union upb_value *value); +upb_status_t upb_parse_value(void **buf, void *end, upb_field_type_t ft, + union upb_value *v); /* Parses a wire value with the given type (which must have been obtained from * a tag that was just parsed) and adds the number of bytes that were consumed * to *offset. For delimited types, offset is advanced past the delimited * data. */ -upb_status_t upb_parse_wire_value(void *buf, size_t len, size_t *offset, - upb_wire_type_t wt, +upb_status_t upb_parse_wire_value(void **buf, void *end, upb_wire_type_t wt, union upb_wire_value *wv); /* Like the above, but discards the wire value instead of saving it. */ -upb_status_t upb_skip_wire_value(void *buf, size_t len, size_t *offset, - upb_wire_type_t wt); +upb_status_t upb_skip_wire_value(void **buf, void *end, upb_wire_type_t wt); #ifdef __cplusplus } /* extern "C" */ |