version 1.67, 2008/02/03 15:08:04 |
version 1.68, 2008/02/11 20:33:10 |
|
|
#define BUF_INCR 128 |
#define BUF_INCR 128 |
|
|
struct cvs_buf { |
struct cvs_buf { |
u_int cb_flags; |
|
|
|
/* buffer handle, buffer size, and data length */ |
/* buffer handle, buffer size, and data length */ |
u_char *cb_buf; |
u_char *cb_buf; |
size_t cb_size; |
size_t cb_size; |
|
|
* once the buffer is no longer needed. |
* once the buffer is no longer needed. |
*/ |
*/ |
BUF * |
BUF * |
cvs_buf_alloc(size_t len, u_int flags) |
cvs_buf_alloc(size_t len) |
{ |
{ |
BUF *b; |
BUF *b; |
|
|
|
|
else |
else |
b->cb_buf = NULL; |
b->cb_buf = NULL; |
|
|
b->cb_flags = flags; |
|
b->cb_size = len; |
b->cb_size = len; |
b->cb_len = 0; |
b->cb_len = 0; |
|
|
|
|
} |
} |
|
|
BUF * |
BUF * |
cvs_buf_load(const char *path, u_int flags) |
cvs_buf_load(const char *path) |
{ |
{ |
int fd; |
int fd; |
BUF *bp; |
BUF *bp; |
|
|
fatal("cvs_buf_load: failed to load '%s' : %s", path, |
fatal("cvs_buf_load: failed to load '%s' : %s", path, |
strerror(errno)); |
strerror(errno)); |
|
|
bp = cvs_buf_load_fd(fd, flags); |
bp = cvs_buf_load_fd(fd); |
(void)close(fd); |
(void)close(fd); |
return (bp); |
return (bp); |
} |
} |
|
|
BUF * |
BUF * |
cvs_buf_load_fd(int fd, u_int flags) |
cvs_buf_load_fd(int fd) |
{ |
{ |
struct stat st; |
struct stat st; |
BUF *buf; |
BUF *buf; |
|
|
if (lseek(fd, 0, SEEK_SET) == -1) |
if (lseek(fd, 0, SEEK_SET) == -1) |
fatal("cvs_buf_load_fd: lseek: %s", strerror(errno)); |
fatal("cvs_buf_load_fd: lseek: %s", strerror(errno)); |
|
|
buf = cvs_buf_alloc(st.st_size, flags); |
buf = cvs_buf_alloc(st.st_size); |
if (atomicio(read, fd, buf->cb_buf, buf->cb_size) != buf->cb_size) |
if (atomicio(read, fd, buf->cb_buf, buf->cb_size) != buf->cb_size) |
fatal("cvs_buf_load_fd: read: %s", strerror(errno)); |
fatal("cvs_buf_load_fd: read: %s", strerror(errno)); |
buf->cb_len = buf->cb_size; |
buf->cb_len = buf->cb_size; |
|
|
bp = b->cb_buf + b->cb_len; |
bp = b->cb_buf + b->cb_len; |
if (bp == (b->cb_buf + b->cb_size)) { |
if (bp == (b->cb_buf + b->cb_size)) { |
/* extend */ |
/* extend */ |
if (b->cb_flags & BUF_AUTOEXT) |
cvs_buf_grow(b, (size_t)BUF_INCR); |
cvs_buf_grow(b, (size_t)BUF_INCR); |
|
else |
|
fatal("cvs_buf_putc failed"); |
|
|
|
/* the buffer might have been moved */ |
/* the buffer might have been moved */ |
bp = b->cb_buf + b->cb_len; |
bp = b->cb_buf + b->cb_len; |
|
|
* will get resized to an appropriate size to accept all data. |
* will get resized to an appropriate size to accept all data. |
* Returns the number of bytes successfully appended to the buffer. |
* Returns the number of bytes successfully appended to the buffer. |
*/ |
*/ |
ssize_t |
void |
cvs_buf_append(BUF *b, const void *data, size_t len) |
cvs_buf_append(BUF *b, const void *data, size_t len) |
{ |
{ |
size_t left, rlen; |
size_t left; |
u_char *bp, *bep; |
u_char *bp, *bep; |
|
|
bp = b->cb_buf + b->cb_len; |
bp = b->cb_buf + b->cb_len; |
bep = b->cb_buf + b->cb_size; |
bep = b->cb_buf + b->cb_size; |
left = bep - bp; |
left = bep - bp; |
rlen = len; |
|
|
|
if (left < len) { |
if (left < len) { |
if (b->cb_flags & BUF_AUTOEXT) { |
cvs_buf_grow(b, len - left); |
cvs_buf_grow(b, len - left); |
bp = b->cb_buf + b->cb_len; |
bp = b->cb_buf + b->cb_len; |
|
} else |
|
rlen = bep - bp; |
|
} |
} |
|
|
memcpy(bp, data, rlen); |
memcpy(bp, data, len); |
b->cb_len += rlen; |
b->cb_len += len; |
|
|
return (rlen); |
|
} |
|
|
|
/* |
|
* cvs_buf_fappend() |
|
* |
|
*/ |
|
ssize_t |
|
cvs_buf_fappend(BUF *b, const char *fmt, ...) |
|
{ |
|
ssize_t ret; |
|
char *str; |
|
va_list vap; |
|
|
|
va_start(vap, fmt); |
|
ret = vasprintf(&str, fmt, vap); |
|
va_end(vap); |
|
|
|
if (ret == -1) |
|
fatal("cvs_buf_fappend: failed to format data"); |
|
|
|
ret = cvs_buf_append(b, str, (size_t)ret); |
|
xfree(str); |
|
return (ret); |
|
} |
} |
|
|
/* |
/* |