summaryrefslogtreecommitdiff
path: root/upb_parse.h
diff options
context:
space:
mode:
Diffstat (limited to 'upb_parse.h')
-rw-r--r--upb_parse.h66
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" */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback