Some progress on upb_stdio.

It's still not correct, but it's closer.
pull/13171/head
Josh Haberman 13 years ago
parent 6c6013e51e
commit 9d2fcd3692
  1. 61
      upb/bytestream.c
  2. 1
      upb/bytestream.h

@ -35,30 +35,46 @@ static upb_stdio_buf *upb_stdio_findbuf(upb_stdio *s, uint64_t ofs) {
return bsearch(&ofs, s->bufs, s->nbuf, sizeof(*s->bufs), &upb_stdio_cmpbuf);
}
//static upb_strlen_t upb_stdio_read(void *src, uint32_t ofs, upb_buf *b,
// upb_status *status) {
// upb_stdio *stdio = (upb_stdio*)src;
// size_t read = fread(buf, 1, BLOCK_SIZE, stdio->file);
// if(read < (size_t)BLOCK_SIZE) {
// // Error or EOF.
// if(feof(stdio->file)) {
// upb_seterr(status, UPB_EOF, "");
// } else if(ferror(stdio->file)) {
// upb_status_fromerrno(s);
// return 0;
// }
// }
// b->len = read;
// stdio->next_ofs += read;
// return stdio->next_ofs;
//}
static upb_stdio_buf *upb_stdio_rotatebufs(upb_stdio *s) {
upb_stdio_buf *reuse[s->nbuf];
uint32_t num_reused = 0, num_inuse = 0;
// Could sweep only a subset of bufs if this was a hotspot.
for (uint32_t i = 0; i < s->nbuf; i++) {
upb_stdio_buf *buf = s->bufs[i];
if (buf->refcount > 0) {
s->bufs[num_inuse++] = buf;
} else {
reuse[num_reused++] = buf;
}
}
assert(num_reused + num_inuse == s->nbuf);
memcpy(s->bufs + num_inuse, reuse, num_reused * sizeof(upb_stdio_buf*));
if (num_reused == 0) {
++s->nbuf;
s->bufs = realloc(s->bufs, s->nbuf * sizeof(*s->bufs));
s->bufs[s->nbuf-1] = malloc(sizeof(upb_stdio_buf) + BUF_SIZE);
return s->bufs[s->nbuf-1];
}
return s->bufs[s->nbuf-num_reused];
}
size_t upb_stdio_fetch(void *src, uint64_t ofs, upb_status *s) {
(void)src;
(void)ofs;
(void)s;
upb_stdio *stdio = (upb_stdio*)src;
upb_stdio_buf *buf = upb_stdio_rotatebufs(stdio);
size_t read = fread(&buf->data, 1, BUF_SIZE, stdio->file);
if(read < (size_t)BUF_SIZE) {
// Error or EOF.
if(feof(stdio->file)) {
upb_status_setf(s, UPB_EOF, "");
} else if(ferror(stdio->file)) {
upb_status_fromerrno(s);
return 0;
}
}
buf->len = read;
return buf->ofs + buf->len;
}
void upb_stdio_read(void *src, uint64_t src_ofs, size_t len, char *dst) {
@ -88,6 +104,7 @@ void upb_stdio_refregion(void *src, uint64_t ofs, size_t len) {
len -= (BUF_SIZE - ofs);
++buf->refcount;
while (len > 0) {
len -= BUF_SIZE;
++buf;
++buf->refcount;
}
@ -218,10 +235,6 @@ void upb_stringsink_uninit(upb_stringsink *s) {
free(s->str);
}
// Resets the stringsink to a state where it will append to the given string.
// The string must be newly created or recycled. The stringsink will take a
// reference on the string, so the caller need not ensure that it outlives the
// stringsink. A stringsink can be reset multiple times.
void upb_stringsink_reset(upb_stringsink *s, char *str, size_t size) {
free(s->str);
s->str = str;

@ -199,6 +199,7 @@ INLINE int32_t upb_bytesink_printf(upb_bytesink *sink, upb_status *status,
typedef struct {
uint64_t ofs;
uint32_t len;
uint32_t refcount;
char data[];
} upb_stdio_buf;

Loading…
Cancel
Save