From 0e3d5d76cb7f3ff2fd2a43edd02978e96115ad09 Mon Sep 17 00:00:00 2001 From: pjd Date: Wed, 17 May 2006 17:56:00 +0000 Subject: - Implement cuio_apply(), an equivalent to m_apply(9). - Implement CUIO_SKIP() macro which is only responsible for skipping the given number of bytes from iovec list. This allows to avoid duplicating the same code in three functions. Reviewed by: sam --- sys/opencrypto/criov.c | 79 +++++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 30 deletions(-) (limited to 'sys/opencrypto/criov.c') diff --git a/sys/opencrypto/criov.c b/sys/opencrypto/criov.c index f90404e..fff52fb 100644 --- a/sys/opencrypto/criov.c +++ b/sys/opencrypto/criov.c @@ -40,6 +40,23 @@ __FBSDID("$FreeBSD$"); #include +/* + * This macro is only for avoiding code duplication, as we need to skip + * given number of bytes in the same way in three functions below. + */ +#define CUIO_SKIP() do { \ + KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \ + KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \ + while (off > 0) { \ + KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \ + if (off < iov->iov_len) \ + break; \ + off -= iov->iov_len; \ + iol--; \ + iov++; \ + } \ +} while (0) + void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp) { @@ -47,22 +64,9 @@ cuio_copydata(struct uio* uio, int off, int len, caddr_t cp) int iol = uio->uio_iovcnt; unsigned count; - if (off < 0) - panic("cuio_copydata: off %d < 0", off); - if (len < 0) - panic("cuio_copydata: len %d < 0", len); - while (off > 0) { - if (iol == 0) - panic("iov_copydata: empty in skip"); - if (off < iov->iov_len) - break; - off -= iov->iov_len; - iol--; - iov++; - } + CUIO_SKIP(); while (len > 0) { - if (iol == 0) - panic("cuio_copydata: empty"); + KASSERT(iol >= 0, ("%s: empty", __func__)); count = min(iov->iov_len - off, len); bcopy(((caddr_t)iov->iov_base) + off, cp, count); len -= count; @@ -80,22 +84,9 @@ cuio_copyback(struct uio* uio, int off, int len, caddr_t cp) int iol = uio->uio_iovcnt; unsigned count; - if (off < 0) - panic("cuio_copyback: off %d < 0", off); - if (len < 0) - panic("cuio_copyback: len %d < 0", len); - while (off > 0) { - if (iol == 0) - panic("cuio_copyback: empty in skip"); - if (off < iov->iov_len) - break; - off -= iov->iov_len; - iol--; - iov++; - } + CUIO_SKIP(); while (len > 0) { - if (iol == 0) - panic("uio_copyback: empty"); + KASSERT(iol >= 0, ("%s: empty", __func__)); count = min(iov->iov_len - off, len); bcopy(cp, ((caddr_t)iov->iov_base) + off, count); len -= count; @@ -137,3 +128,31 @@ cuio_getptr(struct uio *uio, int loc, int *off) return (NULL); } + +/* + * Apply function f to the data in an iovec list starting "off" bytes from + * the beginning, continuing for "len" bytes. + */ +int +cuio_apply(struct uio *uio, int off, int len, int (*f)(void *, void *, u_int), + void *arg) +{ + struct iovec *iov = uio->uio_iov; + int iol = uio->uio_iovcnt; + unsigned count; + int rval; + + CUIO_SKIP(); + while (len > 0) { + KASSERT(iol >= 0, ("%s: empty", __func__)); + count = min(iov->iov_len - off, len); + rval = (*f)(arg, ((caddr_t)iov->iov_base) + off, count); + if (rval) + return (rval); + len -= count; + off = 0; + iol--; + iov++; + } + return (0); +} -- cgit v1.1