--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/server/netbuf.c Wed Dec 28 22:02:08 2011 +0100 @@ -0,0 +1,191 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * netbuf.c: Handles buffered I/O on network sockets + * + * Rob McCool + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "nspr.h" +#include "nsapi.h" +#include "io.h" + +//include "buffer.h" + + +#define NETBUF_RDTIMEOUT 120 + + +/* ----------------------------- netbuf_open ------------------------------ */ + + +NSAPI_PUBLIC netbuf *netbuf_open(SYS_NETFD sd, int sz) { + netbuf *buf = (netbuf *) malloc(sizeof(netbuf)); + + buf->rdtimeout = NETBUF_RDTIMEOUT; + buf->pos = sz; + buf->cursize = sz; /* force buffer_next on first getc */ + buf->maxsize = sz; + buf->sd = sd; + + buf->inbuf = NULL; + buf->errmsg = NULL; + + return buf; +} + + +/* ----------------------------- netbuf_close ----------------------------- */ + + +NSAPI_PUBLIC void netbuf_close(netbuf *buf) { + if(buf->inbuf) + free(buf->inbuf); + free(buf); +} + + +/* ----------------------------- netbuf_replace --------------------------- */ + + +NSAPI_PUBLIC unsigned char * netbuf_replace(netbuf *buf, + unsigned char *inbuf, int pos, int cursize, int maxsize) +{ + unsigned char *oldbuf = buf->inbuf; + + buf->inbuf = inbuf; + buf->pos = pos; + buf->cursize = cursize; + buf->maxsize = maxsize; + + return oldbuf; +} + + +/* ----------------------------- netbuf_next ------------------------------ */ + + +NSAPI_PUBLIC int netbuf_next(netbuf *buf, int advance) { + int n; + + if(!buf->inbuf) + buf->inbuf = (unsigned char *) malloc(buf->maxsize); + + while(1) { + switch(n = net_read(buf->sd, (char *)(buf->inbuf), buf->maxsize)) { + //case IO_EOF: + case 0: + return IO_EOF; + case -1: + return IO_ERROR; + //case IO_ERROR: + //buf->errmsg = system_errmsg(); + // return IO_ERROR; + default: + buf->pos = advance; + buf->cursize = n; + return buf->inbuf[0]; + } + } +} + +NSAPI_PUBLIC int netbuf_getbytes(netbuf *buf, char *buffer, int size) +{ + int bytes; + + if (!buf->inbuf) { + buf->inbuf = (unsigned char *) malloc(buf->maxsize); + } else { + if (buf->pos < buf->cursize) { + int bytes_in_buffer = buf->cursize - buf->pos; + + if (bytes_in_buffer > size) + bytes_in_buffer = size; + + memcpy(buffer, &(buf->inbuf[buf->pos]), bytes_in_buffer); + + buf->pos += bytes_in_buffer; + return bytes_in_buffer; + } + } + + /* The netbuf is empty. Read data directly into the caller's buffer */ + bytes = net_read(buf->sd, buffer, size); + if (bytes == 0) + return NETBUF_EOF; + if (bytes < 0) { + //buf->errmsg = system_errmsg(); + return NETBUF_ERROR; + } + return bytes; +} + + +/* ----------------------------- netbuf_grab ------------------------------ */ + + +NSAPI_PUBLIC int netbuf_grab(netbuf *buf, int sz) { + int n; + + if(!buf->inbuf) { + buf->inbuf = (unsigned char *) malloc(sz); + buf->maxsize = sz; + } + else if(sz > buf->maxsize) { + buf->inbuf = (unsigned char *) realloc(buf->inbuf, sz); + buf->maxsize = sz; + } + + PR_ASSERT(buf->pos == buf->cursize); + buf->pos = 0; + buf->cursize = 0; + + while(1) { + switch(n = net_read(buf->sd, (char *)(buf->inbuf), sz)) { + case 0: + return IO_EOF; + case -1: { + //buf->errmsg = system_errmsg(); + return IO_ERROR; + } + default: + buf->cursize = n; + return n; + } + } +}