/*
 *	Functions for copying data from/to io vectors to/from one
 *	continuous memory block.
 *
 *	PROBLEM: Should buf2iov_cpy change `iov_size' of the
 *	last element of iov[] to reflect the number of bytes
 *	actually copied into this buffer ??
 *
 *	01/01/94, kay roemer.
 */

#include "iov.h"
#include "util.h"

extern void *memcpy (void *, const void *, unsigned long n);

long
iov2buf_cpy (buf, nbytes, iov, niov, skip)
	char *buf;
	long nbytes;
	struct iovec *iov;
	short niov;
	long skip;
{
	long cando, todo = nbytes;

	if (niov <= 0 || todo <= 0 || skip < 0) return 0;

	for (; skip > 0 && niov; ++iov, --niov) {
		skip -= iov->iov_len;
	}
	if (skip < 0) {
		cando = MIN (-skip, todo);
		memcpy (buf, iov[-1].iov_base + skip + iov[-1].iov_len, cando);
		buf  += cando;
		todo -= cando;
	}
	for (; todo > 0 && niov; ++iov, --niov) {
		cando = MIN (todo, iov->iov_len);
		memcpy (buf, iov->iov_base, cando);
		todo -= cando;
		buf  += cando;
	}
	return (nbytes - todo);
}

long
buf2iov_cpy (buf, nbytes, iov, niov, skip)
	char *buf;
	long nbytes;
	struct iovec *iov;
	short niov;
	long skip;
{
	long cando, todo = nbytes;

	if (niov <= 0 || todo <= 0 || skip < 0) return 0;

	for (; skip > 0 && niov; ++iov, --niov) {
		skip -= iov->iov_len;
	}
	if (skip < 0) {
		cando = MIN (-skip, todo);
		memcpy (iov[-1].iov_base + skip + iov[-1].iov_len, buf, cando);
		buf  += cando;
		todo -= cando;
	}
	for (; todo > 0 && niov; ++iov, --niov) {
		cando = MIN (todo, iov->iov_len);
		memcpy (iov->iov_base, buf, cando);
		todo -= cando;
		buf  += cando;
	}
	return (nbytes - todo);
}
