From e8c58eb78dbd7fc161a82da321dad028a0acbb3d Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 1 Aug 2009 23:06:22 -0700 Subject: Sketches of serialization. --- src/upb_msg.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/upb_msg.h | 4 ++-- src/upb_parse.h | 9 +++++-- src/upb_serialize.h | 4 ++-- 4 files changed, 79 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/upb_msg.c b/src/upb_msg.c index 513c0c5..f74e96d 100644 --- a/src/upb_msg.c +++ b/src/upb_msg.c @@ -503,6 +503,74 @@ size_t upb_msgsizes_totalsize(struct upb_msgsizes *sizes) return sizes->sizes[sizes->len-1]; } +struct upb_msg_serialize_state { + struct { + int field_iter; + int elem_iter; + struct upb_msg *m; + void *msg; + } stack[UPB_MAX_NESTING], *top, *limit; +}; + +void upb_msg_serialize_alloc(struct upb_msg_serialize_state *s) +{ + (void)s; +} + +void upb_msg_serialize_free(struct upb_msg_serialize_state *s) +{ + (void)s; +} + +void upb_msg_serialize_init(struct upb_msg_serialize_state *s, void *data, + struct upb_msg *m, struct upb_msgsizes *sizes) +{ + (void)s; + (void)data; + (void)m; + (void)sizes; +} + +static upb_status_t serialize_tag(uint8_t *buf, uint8_t *end, + struct upb_msg_field *f, uint8_t **outptr) +{ + /* TODO: need to have the field number also. */ + UPB_CHECK(upb_put_UINT32(buf, end, f->type, outptr)); + return UPB_STATUS_OK; +} + +/* Serializes the next set of bytes into buf (which has size len). Returns + * UPB_STATUS_OK if serialization is complete, or UPB_STATUS_NEED_MORE_DATA + * if there is more data from the message left to be serialized. + * + * The number of bytes written to buf is returned in *read. This will be + * equal to len unless we finished serializing. */ +upb_status_t upb_msg_serialize(struct upb_msg_serialize_state *s, + void *_buf, size_t len, size_t *written) +{ + uint8_t *buf = _buf; + uint8_t *end = buf + len; + uint8_t *const start = buf; + int i = s->top->field_iter; + int j = s->top->elem_iter; + void *msg = s->top->msg; + struct upb_msg *m = s->top->m; + + while(buf < end) { + struct upb_msg_field *f = &m->fields[i]; + union upb_value_ptr p = upb_msg_getptr(msg, f); + serialize_tag(buf, end, f, &buf); + if(f->type == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_MESSAGE) { + } else if(f->type == GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_GROUP) { + } else if(upb_isstring(f)) { + } else { + upb_serialize_value(buf, end, f->type, p, &buf); + } + } + *written = buf - start; + return UPB_STATUS_OK; +} + /* Comparison. ***************************************************************/ bool upb_value_eql(union upb_value_ptr p1, union upb_value_ptr p2, diff --git a/src/upb_msg.h b/src/upb_msg.h index 8699fbf..043af23 100644 --- a/src/upb_msg.h +++ b/src/upb_msg.h @@ -398,10 +398,10 @@ void upb_msg_serialize_init(struct upb_msg_serialize_state *s, void *data, * UPB_STATUS_OK if serialization is complete, or UPB_STATUS_NEED_MORE_DATA * if there is more data from the message left to be serialized. * - * The number of bytes written to buf is returned in *read. This will be + * The number of bytes written to buf is returned in *written. This will be * equal to len unless we finished serializing. */ upb_status_t upb_msg_serialize(struct upb_msg_serialize_state *s, - void *buf, size_t len, size_t *read); + void *buf, size_t len, size_t *written); /* Text dump *****************************************************************/ diff --git a/src/upb_parse.h b/src/upb_parse.h index 193c307..e727c11 100644 --- a/src/upb_parse.h +++ b/src/upb_parse.h @@ -99,7 +99,9 @@ struct upb_parse_state { upb_submsg_end_cb submsg_end_cb; }; -/* Parses up to len bytes of protobuf data out of buf, calling cb as needed. +/* Parses up to len bytes of protobuf data out of buf, calling the appropriate + * callbacks as values are parsed. + * * The function returns a status indicating the success of the operation. Data * is parsed until no more data can be read from buf, or the callback returns an * error like UPB_STATUS_USER_CANCELLED, or an error occurs. @@ -109,7 +111,10 @@ struct upb_parse_state { * of the currently provided data. * * The next call to upb_parse must be the first byte after buf + *read, even in - * the case that *read > len. */ + * the case that *read > len. + * + * TODO: see if we can provide the following guarantee efficiently: + * *read will always be >= len. */ upb_status_t upb_parse(struct upb_parse_state *s, void *buf, size_t len, size_t *read); diff --git a/src/upb_serialize.h b/src/upb_serialize.h index ec735c2..e1468de 100644 --- a/src/upb_serialize.h +++ b/src/upb_serialize.h @@ -170,7 +170,7 @@ T(INT64, v, uint64_t, int64_t, int64) { return (uint64_t)s; } T(UINT32, v, uint32_t, uint32_t, uint32) { return s; } T(UINT64, v, uint64_t, uint64_t, uint64) { return s; } T(SINT32, v, uint32_t, int32_t, int32) { return upb_zzenc_32(s); } -T(SINT64, v, uint64_t, int64_t, int64) { return upb_zzdec_64(s); } +T(SINT64, v, uint64_t, int64_t, int64) { return upb_zzenc_64(s); } T(FIXED32, f, uint32_t, uint32_t, uint32) { return s; } T(FIXED64, f, uint64_t, uint64_t, uint64) { return s; } T(SFIXED32, f, uint32_t, int32_t, int32) { return (uint32_t)s; } @@ -191,7 +191,7 @@ T(FLOAT, f, uint32_t, float, _float) { #undef PUT #undef T -size_t upb_get_tag_size(uint32_t fieldnum) { +INLINE size_t upb_get_tag_size(uint32_t fieldnum) { return upb_v_uint64_t_size((uint64_t)fieldnum << 3); } -- cgit v1.2.3