// Unix MsgQ functions
// try writing these suckers for windoze, it's horrible
#include "MsgQ.h"
#include "debug.h"
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>

void SendQ(int sock, MsgQ *q)
{
  // first insert a message with the size of the queue
  ushort *ptr = new ushort;
  *ptr = htons(q->Count());
  q->InsertHead(Msg((char *)ptr, sizeof(ushort)));
  while (q->Count() > 0) {
    Msg m;
    *q >> m;
    ushort len = htons(m.len);
    while (write(sock, (char *)&len, sizeof(len)) == -1);
    while (write(sock, m.buf, m.len) == -1);
    delete m.buf;
  }
  delete q;
}

void NonDestructiveSendQ(int sock, MsgQ *q)
{
  ushort len = htons(q->Count());
  ushort lenOflen = htons(sizeof(ushort));
  while (write(sock, (char *)&lenOflen, sizeof(ushort)) == -1);
  while (write(sock, (char *)&len, sizeof(ushort)) == -1);
  Lister<Msg> mesgl = q->mesgs;
  while (mesgl) {
    Msg m = mesgl.Elem();
    ushort len = htons(m.len);
    while (write(sock, (char *)&len, sizeof(len)) == -1);
    while (write(sock, m.buf, m.len) == -1);
    mesgl.Next();
  }
}

void ReadBytes(int sock, char *buf, int len)
{
  while (len > 0) {
    int n = read(sock, buf, len);
    if (n == -1) continue;
    buf += n;
    len -= n;
  }
}

// this is when we get data ready on a socket
MsgQ *RecvQ(int sock)
{
  ushort qLen;
  ReadBytes(sock, (char *)&qLen, sizeof(qLen));
  ReadBytes(sock, (char *)&qLen, sizeof(qLen));
  qLen = ntohs(qLen);
  MsgQ *q = new MsgQ;
  while (qLen-- > 0) {
    ushort msgLen;
    ReadBytes(sock, (char *)&msgLen, sizeof(msgLen));
    msgLen = ntohs(msgLen);
    char *buf = new char[msgLen];
    ReadBytes(sock, buf, msgLen);
    *q << Msg(buf, msgLen);
  }
  return q;
}
