summaryrefslogtreecommitdiffstats
path: root/sys/xdr
diff options
context:
space:
mode:
Diffstat (limited to 'sys/xdr')
-rw-r--r--sys/xdr/xdr_mbuf.c70
1 files changed, 65 insertions, 5 deletions
diff --git a/sys/xdr/xdr_mbuf.c b/sys/xdr/xdr_mbuf.c
index 770dfc3..e6f7c9d 100644
--- a/sys/xdr/xdr_mbuf.c
+++ b/sys/xdr/xdr_mbuf.c
@@ -78,6 +78,51 @@ xdrmbuf_create(XDR *xdrs, struct mbuf *m, enum xdr_op op)
}
}
+void
+xdrmbuf_append(XDR *xdrs, struct mbuf *madd)
+{
+ struct mbuf *m;
+
+ KASSERT(xdrs->x_ops == &xdrmbuf_ops && xdrs->x_op == XDR_ENCODE,
+ ("xdrmbuf_append: invalid XDR stream"));
+
+ if (m_length(madd, NULL) == 0) {
+ m_freem(madd);
+ return;
+ }
+
+ m = (struct mbuf *) xdrs->x_private;
+ m->m_next = madd;
+
+ m = m_last(madd);
+ xdrs->x_private = m;
+ xdrs->x_handy = m->m_len;
+}
+
+struct mbuf *
+xdrmbuf_getall(XDR *xdrs)
+{
+ struct mbuf *m0, *m;
+
+ KASSERT(xdrs->x_ops == &xdrmbuf_ops && xdrs->x_op == XDR_DECODE,
+ ("xdrmbuf_append: invalid XDR stream"));
+
+ m0 = (struct mbuf *) xdrs->x_base;
+ m = (struct mbuf *) xdrs->x_private;
+ if (m0 != m) {
+ while (m0->m_next != m)
+ m0 = m0->m_next;
+ m0->m_next = NULL;
+ xdrs->x_private = NULL;
+ } else {
+ xdrs->x_base = NULL;
+ xdrs->x_private = NULL;
+ }
+
+ m_adj(m, xdrs->x_handy);
+ return (m);
+}
+
static void
xdrmbuf_destroy(XDR *xdrs)
{
@@ -92,9 +137,16 @@ xdrmbuf_destroy(XDR *xdrs)
static bool_t
xdrmbuf_getlong(XDR *xdrs, long *lp)
{
+ int32_t *p;
int32_t t;
- xdrmbuf_getbytes(xdrs, (char *) &t, sizeof(int32_t));
+ p = xdrmbuf_inline(xdrs, sizeof(int32_t));
+ if (p) {
+ t = *p;
+ } else {
+ xdrmbuf_getbytes(xdrs, (char *) &t, sizeof(int32_t));
+ }
+
*lp = ntohl(t);
return (TRUE);
}
@@ -104,10 +156,16 @@ xdrmbuf_putlong(xdrs, lp)
XDR *xdrs;
const long *lp;
{
+ int32_t *p;
int32_t t = htonl(*lp);
- xdrmbuf_putbytes(xdrs, (char *) &t, sizeof(int32_t));
- return (TRUE);
+ p = xdrmbuf_inline(xdrs, sizeof(int32_t));
+ if (p) {
+ *p = t;
+ return (TRUE);
+ } else {
+ return (xdrmbuf_putbytes(xdrs, (char *) &t, sizeof(int32_t)));
+ }
}
static bool_t
@@ -130,7 +188,7 @@ xdrmbuf_getbytes(XDR *xdrs, char *addr, u_int len)
sz = m->m_len - xdrs->x_handy;
if (sz > len)
sz = len;
- memcpy(addr, mtod(m, const char *) + xdrs->x_handy, sz);
+ bcopy(mtod(m, const char *) + xdrs->x_handy, addr, sz);
addr += sz;
xdrs->x_handy += sz;
@@ -157,7 +215,7 @@ xdrmbuf_putbytes(XDR *xdrs, const char *addr, u_int len)
sz = M_TRAILINGSPACE(m) + (m->m_len - xdrs->x_handy);
if (sz > len)
sz = len;
- memcpy(mtod(m, char *) + xdrs->x_handy, addr, sz);
+ bcopy(addr, mtod(m, char *) + xdrs->x_handy, sz);
addr += sz;
xdrs->x_handy += sz;
if (xdrs->x_handy > m->m_len)
@@ -167,6 +225,8 @@ xdrmbuf_putbytes(XDR *xdrs, const char *addr, u_int len)
if (xdrs->x_handy == m->m_len && M_TRAILINGSPACE(m) == 0) {
if (!m->m_next) {
MGET(n, M_TRYWAIT, m->m_type);
+ if (m->m_flags & M_EXT)
+ MCLGET(n, M_TRYWAIT);
m->m_next = n;
}
m = m->m_next;
OpenPOWER on IntegriCloud