src/server/netbuf.c

changeset 8
f4d56bf9de40
--- /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;
+        }
+    }
+}

mercurial