/*
 * Copyright (c) 1995 Danny Gasparovski.
 *
 * Please read the file COPYRIGHT for the
 * terms and conditions of the copyright.
 */

#include <slirp.h>
#include <qemu/main-loop.h>

static void sbappendsb(struct sbuf *sb, struct mbuf *m);

void
sbfree(struct sbuf *sb)
{
	free(sb->sb_data);
}

void
sbdrop(struct sbuf *sb, int num)
{
    int limit = sb->sb_datalen / 2;

	/*
	 * We can only drop how much we have
	 * This should never succeed
	 */
	if(num > sb->sb_cc)
		num = sb->sb_cc;
	sb->sb_cc -= num;
	sb->sb_rptr += num;
	if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
		sb->sb_rptr -= sb->sb_datalen;

    if (sb->sb_cc < limit && sb->sb_cc + num >= limit) {
        qemu_notify_event();
    }
}

void
sbreserve(struct sbuf *sb, int size)
{
	if (sb->sb_data) {
		/* Already alloced, realloc if necessary */
		if (sb->sb_datalen != size) {
			sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size);
			sb->sb_cc = 0;
			if (sb->sb_wptr)
			   sb->sb_datalen = size;
			else
			   sb->sb_datalen = 0;
		}
	} else {
		sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size);
		sb->sb_cc = 0;
		if (sb->sb_wptr)
		   sb->sb_datalen = size;
		else
		   sb->sb_datalen = 0;
	}
}

/*
 * Try and write() to the socket, whatever doesn't get written
 * append to the buffer... for a host with a fast net connection,
 * this prevents an unnecessary copy of the data
 * (the socket is non-blocking, so we won't hang)
 */
void
sbappend(struct socket *so, struct mbuf *m)
{
	int ret = 0;

	DEBUG_CALL("sbappend");
	DEBUG_ARG("so = %lx", (long)so);
	DEBUG_ARG("m = %lx", (long)m);
	DEBUG_ARG("m->m_len = %d", m->m_len);

	/* Shouldn't happen, but...  e.g. foreign host closes connection */
	if (m->m_len <= 0) {
		m_free(m);
		return;
	}

	/*
	 * If there is urgent data, call sosendoob
	 * if not all was sent, sowrite will take care of the rest
	 * (The rest of this function is just an optimisation)
	 */
	if (so->so_urgc) {
		sbappendsb(&so->so_rcv, m);
		m_free(m);
		sosendoob(so);
		return;
	}

	/*
	 * We only write if there's nothing in the buffer,
	 * ottherwise it'll arrive out of order, and hence corrupt
	 */
	if (!so->so_rcv.sb_cc)
	   ret = slirp_send(so, m->m_data, m->m_len, 0);

	if (ret <= 0) {
		/*
		 * Nothing was written
		 * It's possible that the socket has closed, but
		 * we don't need to check because if it has closed,
		 * it will be detected in the normal way by soread()
		 */
		sbappendsb(&so->so_rcv, m);
	} else if (ret != m->m_len) {
		/*
		 * Something was written, but not everything..
		 * sbappendsb the rest
		 */
		m->m_len -= ret;
		m->m_data += ret;
		sbappendsb(&so->so_rcv, m);
	} /* else */
	/* Whatever happened, we free the mbuf */
	m_free(m);
}

/*
 * Copy the data from m into sb
 * The caller is responsible to make sure there's enough room
 */
static void
sbappendsb(struct sbuf *sb, struct mbuf *m)
{
	int len, n,  nn;

	len = m->m_len;

	if (sb->sb_wptr < sb->sb_rptr) {
		n = sb->sb_rptr - sb->sb_wptr;
		if (n > len) n = len;
		memcpy(sb->sb_wptr, m->m_data, n);
	} else {
		/* Do the right edge first */
		n = sb->sb_data + sb->sb_datalen - sb->sb_wptr;
		if (n > len) n = len;
		memcpy(sb->sb_wptr, m->m_data, n);
		len -= n;
		if (len) {
			/* Now the left edge */
			nn = sb->sb_rptr - sb->sb_data;
			if (nn > len) nn = len;
			memcpy(sb->sb_data,m->m_data+n,nn);
			n += nn;
		}
	}

	sb->sb_cc += n;
	sb->sb_wptr += n;
	if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen)
		sb->sb_wptr -= sb->sb_datalen;
}

/*
 * Copy data from sbuf to a normal, straight buffer
 * Don't update the sbuf rptr, this will be
 * done in sbdrop when the data is acked
 */
void
sbcopy(struct sbuf *sb, int off, int len, char *to)
{
	char *from;

	from = sb->sb_rptr + off;
	if (from >= sb->sb_data + sb->sb_datalen)
		from -= sb->sb_datalen;

	if (from < sb->sb_wptr) {
		if (len > sb->sb_cc) len = sb->sb_cc;
		memcpy(to,from,len);
	} else {
		/* re-use off */
		off = (sb->sb_data + sb->sb_datalen) - from;
		if (off > len) off = len;
		memcpy(to,from,off);
		len -= off;
		if (len)
		   memcpy(to+off,sb->sb_data,len);
	}
}
