summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-08-01 23:06:22 -0700
committerJoshua Haberman <joshua@reverberate.org>2009-08-01 23:06:22 -0700
commite8c58eb78dbd7fc161a82da321dad028a0acbb3d (patch)
treeb7c1a8b0b0d76ab2236dc7eb961f1af5095b10ef /src
parenta952e42e996fcab8f13e48d0078c0e95a4d507d9 (diff)
Sketches of serialization.
Diffstat (limited to 'src')
-rw-r--r--src/upb_msg.c68
-rw-r--r--src/upb_msg.h4
-rw-r--r--src/upb_parse.h9
-rw-r--r--src/upb_serialize.h4
4 files changed, 79 insertions, 6 deletions
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);
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback