#ifdef WIN32
#define _WILLWINSOCK_
#endif
#include <X11/Xos.h>
#include <X11/Xfuncs.h>
#include <errno.h>
#if !defined(WIN32) && !defined(Lynx)
#include <sys/param.h>
#endif
#include <X11/extensions/lbxbufstr.h>
#include "lbx_zlib.h"
#include <stddef.h>
#if defined(WIN32) || defined(__sxg__)
static int
writev(int fildes, const struct iovec *iov, int iovcnt)
{
int i, len, total;
char *base;
ESET(0);
for (i = 0, total = 0; i < iovcnt; i++, iov++) {
len = iov->iov_len;
base = iov->iov_base;
while (len > 0) {
register int nbytes;
nbytes = write(fildes, base, len);
if (nbytes < 0 && total == 0) return -1;
if (nbytes <= 0) return total;
ESET(0);
len -= nbytes;
total += nbytes;
base += nbytes;
}
}
return total;
}
#endif
int
InitZlibBuffer(b, size)
ZlibBufferPtr b;
int size;
{
if ((b->bufbase = (char *)Xalloc(size)) == NULL)
return -1;
b->bufend = b->bufbase + size;
b->bufptr = b->bufbase;
b->bufcnt = 0;
return 0;
}
void
FreeZlibBuffer(b)
ZlibBufferPtr b;
{
if (b->bufbase) {
Xfree(b->bufbase);
b->bufbase = NULL;
}
}
int
GetInputPtr(fd, inbuf, reqlen, ppkt)
int fd;
ZlibBufferPtr inbuf;
int reqlen;
unsigned char **ppkt;
{
int readbytes;
int gotbytes;
if (inbuf->bufcnt == 0)
inbuf->bufptr = inbuf->bufbase;
if (reqlen <= inbuf->bufcnt) {
*ppkt = (unsigned char *)inbuf->bufptr;
return 1;
}
if (reqlen > inbuf->bufend - inbuf->bufptr) {
memmove(inbuf->bufbase, inbuf->bufptr, inbuf->bufcnt);
inbuf->bufptr = inbuf->bufbase;
}
readbytes = (inbuf->bufend - inbuf->bufptr) - inbuf->bufcnt;
gotbytes = read(fd, inbuf->bufptr + inbuf->bufcnt, readbytes);
if (gotbytes > 0) {
if (reqlen <= (inbuf->bufcnt += gotbytes)) {
*ppkt = (unsigned char *)inbuf->bufptr;
return 1;
}
}
else
return gotbytes;
errno = EWOULDBLOCK;
return -1;
}
int
StuffInput(inbuf, pkt, reqlen)
ZlibBufferPtr inbuf;
unsigned char *pkt;
int reqlen;
{
int readbytes;
char *last;
last = inbuf->bufptr + inbuf->bufcnt;
if (reqlen > inbuf->bufend - last)
{
memmove(inbuf->bufbase, inbuf->bufptr, inbuf->bufcnt);
inbuf->bufptr = inbuf->bufbase;
last = inbuf->bufptr + inbuf->bufcnt;
}
readbytes = MIN(reqlen, inbuf->bufend - last);
memmove(last, pkt, readbytes);
inbuf->bufcnt += readbytes;
return readbytes;
}
void
FreeInput(inbuf, len)
ZlibBufferPtr inbuf;
int len;
{
inbuf->bufptr += len;
if ((inbuf->bufcnt -= len) == 0)
inbuf->bufptr = inbuf->bufbase;
}
char *
ReserveOutBuf(outbuf, outlen)
ZlibBufferPtr outbuf;
int outlen;
{
int left;
left = (outbuf->bufend - outbuf->bufptr) - outbuf->bufcnt;
if (left < outlen)
return NULL;
else
return outbuf->bufptr + outbuf->bufcnt;
}
void
CommitOutBuf(outbuf, outlen)
ZlibBufferPtr outbuf;
int outlen;
{
outbuf->bufcnt += outlen;
}
int
FlushOutBuf(fd, outbuf)
int fd;
ZlibBufferPtr outbuf;
{
int bytes;
if (outbuf->bufcnt == 0)
return 0;
bytes = write(fd, outbuf->bufptr, outbuf->bufcnt);
if (bytes > 0) {
outbuf->bufptr += bytes;
if ((outbuf->bufcnt -= bytes) == 0)
outbuf->bufptr = outbuf->bufbase;
return outbuf->bufcnt;
}
else if (bytes == 0) {
errno = EWOULDBLOCK;
bytes = -1;
}
return bytes;
}
int
FlushIovBuf(fd, iovbuf)
int fd;
struct iovec *iovbuf;
{
int bytes;
int niov = 2;
struct iovec *iov = iovbuf;
if (iov[0].iov_len == 0) {
++iov;
--niov;
}
bytes = writev(fd, iov, niov);
if (bytes > 0) {
int i;
int len;
for (i = 0; i < niov; i++) {
len = MIN(bytes, iov[i].iov_len);
iov[i].iov_len -= len;
iov[i].iov_base = ((char*)(iov[i].iov_base)) + len;
if ((bytes -= len) == 0)
break;
}
return iovbuf[1].iov_len;
}
else if (bytes == 0) {
errno = EWOULDBLOCK;
bytes = -1;
}
return bytes;
}