Sketches of serialization.

pull/13171/head
Joshua Haberman 16 years ago
parent a952e42e99
commit e8c58eb78d
  1. 4
      Makefile
  2. 68
      src/upb_msg.c
  3. 4
      src/upb_msg.h
  4. 9
      src/upb_parse.h
  5. 4
      src/upb_serialize.h

@ -4,9 +4,9 @@ CC=gcc
CXX=g++
CFLAGS=-std=c99
INCLUDE=-Idescriptor -Isrc -Itests -I.
CPPFLAGS=-O3 -fomit-frame-pointer -Wall -Wextra -g -DUPB_UNALIGNED_READS_OK -DNDEBUG $(INCLUDE)
CPPFLAGS=-O3 -fomit-frame-pointer -Wall -Wextra -g -DNDEBUG $(INCLUDE)
OBJ=src/upb_parse.o src/upb_table.o src/upb_msg.o src/upb_enum.o src/upb_context.o \
src/upb_string.o src/upb_text.o descriptor/descriptor.o
src/upb_string.o src/upb_text.o src/upb_serialize.o descriptor/descriptor.o
SRC=src/*.c src/*.h descriptor/*.c descriptor/*.h tests/*.c tests/*.h tools/*.c
ALL=$(OBJ) src/libupb.a tests/test_table tests/tests tools/upbc benchmark/benchmark
all: $(ALL)

@ -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,

@ -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 *****************************************************************/

@ -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);

@ -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);
}

Loading…
Cancel
Save