summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2010-06-12 11:03:03 -0700
committerJoshua Haberman <joshua@reverberate.org>2010-06-12 11:03:03 -0700
commit00b403a7373d783744bebdffde3696824d68b745 (patch)
tree09902f17426b1cd37316433b8902bc7719e3de89 /src
parent61a0f0bc5f6b3ddd8a495a05bf1a06096e99a859 (diff)
Decoder is finally complete, now just needs testing.
Diffstat (limited to 'src')
-rw-r--r--src/upb_decoder.c68
1 files changed, 35 insertions, 33 deletions
diff --git a/src/upb_decoder.c b/src/upb_decoder.c
index e6fcec5..6f1e437 100644
--- a/src/upb_decoder.c
+++ b/src/upb_decoder.c
@@ -136,17 +136,18 @@ static const uint8_t *upb_decoder_getbuf_full(upb_decoder *d, uint32_t *bytes)
*bytes = d->buf_bytesleft;
return (uint8_t*)upb_string_getrobuf(d->buf) + d->buf_offset;
} else {
- upb_strlen_t residual_bytes = -d->buf_offset;
+ // We need to accumulate UPB_MAX_ENCODED_SIZE bytes; len is how many we
+ // have so far.
+ upb_strlen_t len = -d->buf_offset;
if(d->buf) {
- memcpy(d->tmpbuf + residual_bytes, upb_string_getrobuf(d->buf),
- UPB_MAX_ENCODED_SIZE - residual_bytes);
- *bytes = 10;
- } else {
- // All we have are residual bytes; pad them with 0x80.
- memset(d->tmpbuf + residual_bytes, 0x80,
- UPB_MAX_ENCODED_SIZE - residual_bytes);
- *bytes = residual_bytes;
+ upb_strlen_t to_copy =
+ UPB_MIN(UPB_MAX_ENCODED_SIZE - len, upb_string_len(d->buf));
+ memcpy(d->tmpbuf + len, upb_string_getrobuf(d->buf), to_copy);
+ len += to_copy;
}
+ // Pad the buffer out to UPB_MAX_ENCODED_SIZE.
+ memset(d->tmpbuf + len, 0x80, UPB_MAX_ENCODED_SIZE - len);
+ *bytes = len;
return d->tmpbuf;
}
}
@@ -194,14 +195,6 @@ static bool upb_decoder_skipbytes(upb_decoder *d, int32_t bytes)
return true;
}
-static upb_strlen_t upb_decoder_append(uint8_t *buf, upb_string *frombuf,
- upb_strlen_t len, upb_strlen_t total_len)
-{
- upb_strlen_t copy = UPB_MIN(total_len - len, upb_string_len(frombuf));
- //memcpy(buf, upb_string_getrobuf(frombuf) )
- return 0;
-}
-
/* Functions to read wire values. *********************************************/
@@ -383,29 +376,38 @@ bool upb_decoder_getval(upb_decoder *d, upb_valueptr val)
// technically a string, but can be gotten as one to perform lazy parsing.
d->str = upb_string_tryrecycle(d->str);
const upb_strlen_t total_len = d->delimited_len;
- if ((int32_t)total_len <= d->buf_bytesleft) {
+ if (d->buf_offset >= 0 && (int32_t)total_len <= d->buf_bytesleft) {
// The entire string is inside our current buffer, so we can just
// return a substring of the buffer without copying.
upb_string_substr(d->str, d->buf,
upb_string_len(d->buf) - d->buf_bytesleft,
total_len);
- d->buf_bytesleft -= total_len;
+ upb_decoder_skipbytes(d, total_len);
*val.str = d->str;
} else {
- //// The string spans buffers, so we must copy from the current buffer,
- //// the next buffer (if we have one), and finally from the bytesrc.
- //uint8_t *str = (uint8_t*)upb_string_getrwbuf(d->str, total_len);
- //upb_strlen_t len = 0;
- //len += upb_decoder_append(str, d->buf, len, total_len);
- //upb_decoder_advancebuf(d);
- //if(d->buf) len += upb_decoder_append(str, d->buf, len, total_len);
- //upb_string_getrwbuf(d->str, len); // Cheap resize.
- //if(len < total_len) {
- // if(!upb_bytesrc_append(d->bytesrc, d->str, total_len - len)) {
- // upb_copyerr(&d->src.status, upb_bytesrc_status(d->bytesrc));
- // return false;
- // }
- //}
+ // The string spans buffers, so we must copy from the current buffer,
+ // the next buffer (if we have one), and finally from the bytesrc.
+ uint8_t *str = (uint8_t*)upb_string_getrwbuf(d->str, total_len);
+ upb_strlen_t len = 0;
+ if(d->buf_offset < 0) {
+ // Residual bytes we need to copy from tmpbuf.
+ memcpy(str, d->tmpbuf, -d->buf_offset);
+ len += -d->buf_offset;
+ }
+ if(d->buf) {
+ upb_strlen_t to_copy =
+ UPB_MIN(total_len - len, upb_string_len(d->buf) - d->buf_offset);
+ memcpy(str + len, upb_string_getrobuf(d->buf) + d->buf_offset, to_copy);
+ }
+ upb_decoder_skipbytes(d, len);
+ upb_string_getrwbuf(d->str, len); // Cheap resize.
+ if(len < total_len) {
+ if(!upb_bytesrc_append(d->bytesrc, d->str, total_len - len)) {
+ upb_copyerr(&d->src.status, upb_bytesrc_status(d->bytesrc));
+ return false;
+ }
+ d->buf_stream_offset += total_len - len;
+ }
}
d->field = NULL;
} else {
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback