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. 63
      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); 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, static upb_stdio_buf *upb_stdio_rotatebufs(upb_stdio *s) {
// upb_status *status) { upb_stdio_buf *reuse[s->nbuf];
// upb_stdio *stdio = (upb_stdio*)src; uint32_t num_reused = 0, num_inuse = 0;
// size_t read = fread(buf, 1, BLOCK_SIZE, stdio->file);
// if(read < (size_t)BLOCK_SIZE) { // Could sweep only a subset of bufs if this was a hotspot.
// // Error or EOF. for (uint32_t i = 0; i < s->nbuf; i++) {
// if(feof(stdio->file)) { upb_stdio_buf *buf = s->bufs[i];
// upb_seterr(status, UPB_EOF, ""); if (buf->refcount > 0) {
// } else if(ferror(stdio->file)) { s->bufs[num_inuse++] = buf;
// upb_status_fromerrno(s); } else {
// return 0; reuse[num_reused++] = buf;
// } }
// } }
// b->len = read; assert(num_reused + num_inuse == s->nbuf);
// stdio->next_ofs += read; memcpy(s->bufs + num_inuse, reuse, num_reused * sizeof(upb_stdio_buf*));
// return stdio->next_ofs; 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) { size_t upb_stdio_fetch(void *src, uint64_t ofs, upb_status *s) {
(void)src;
(void)ofs; (void)ofs;
(void)s; upb_stdio *stdio = (upb_stdio*)src;
upb_stdio_buf *buf = upb_stdio_rotatebufs(stdio);
return 0; 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) { 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); len -= (BUF_SIZE - ofs);
++buf->refcount; ++buf->refcount;
while (len > 0) { while (len > 0) {
len -= BUF_SIZE;
++buf; ++buf;
++buf->refcount; ++buf->refcount;
} }
@ -218,10 +235,6 @@ void upb_stringsink_uninit(upb_stringsink *s) {
free(s->str); 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) { void upb_stringsink_reset(upb_stringsink *s, char *str, size_t size) {
free(s->str); free(s->str);
s->str = str; s->str = str;

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

Loading…
Cancel
Save