1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "obuf.h"
/** Write a large block of data to the \c obuf, avoiding copying. */
int obuf_write_large(obuf* out, const char* data, unsigned datalen)
{
iobuf* io;
unsigned wr;
io = &out->io;
if (iobuf_bad(io)) return 0;
out->count = 0;
if (!obuf_flush(out)) return 0;
while (datalen > 0) {
if (io->timeout && !iobuf_timeout(io, 1)) return 0;
if ((wr = out->writefn(io->fd, data, datalen)) == (unsigned)-1)
IOBUF_SET_ERROR(io);
datalen -= wr;
data += wr;
io->offset += wr;
out->count += wr;
}
return 1;
}
/** Write a block of data to the \c obuf */
int obuf_write(obuf* out, const char* data, unsigned datalen)
{
iobuf* io;
unsigned avail;
io = &out->io;
if (iobuf_bad(io)) return 0;
if (datalen >= io->bufsize) return obuf_write_large(out, data, datalen);
out->count = 0;
avail = io->bufsize - out->bufpos;
while (datalen >= avail) {
memcpy(io->buffer+out->bufpos, data, avail);
out->bufpos = io->bufsize;
io->buflen = io->bufsize;
datalen -= avail;
data += avail;
if (!obuf_flush(out)) return 0;
out->count += avail;
avail = io->bufsize - out->bufpos;
}
memcpy(io->buffer+out->bufpos, data, datalen);
out->count += datalen;
out->bufpos += datalen;
if (out->bufpos > io->buflen) io->buflen = out->bufpos;
return 1;
}
#ifdef SELFTEST_MAIN
MAIN
{
obuf buf;
obuf_init(&buf, 1, 0, 0, 8);
/* Test proper merging of short writes */
obuf_puts(&buf, "0123"); write(1,"brk\n",4);
obuf_puts(&buf, "456789\n"); write(1,"brk\n",4);
/* Test pass-through of large writes */
obuf_write(&buf, "01234567\n", 9); write(1,"brk\n",4);
}
#endif
#ifdef SELFTEST_EXP
brk
01234567brk
89
01234567
brk
#endif
|