summaryrefslogtreecommitdiffstats
path: root/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_sockbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_sockbuf.c')
-rw-r--r--rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_sockbuf.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_sockbuf.c b/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_sockbuf.c
new file mode 100644
index 00000000..da956258
--- /dev/null
+++ b/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_sockbuf.c
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/***************************************************************************
+ * Description: Simple buffer object to handle buffered socket IO *
+ * Author: Gal Shachor <shachor@il.ibm.com> *
+ * Version: $Revision: 466585 $ *
+ ***************************************************************************/
+
+#include "jk_global.h"
+#include "jk_sockbuf.h"
+
+static int fill_buffer(jk_sockbuf_t *sb);
+
+int jk_sb_open(jk_sockbuf_t *sb, jk_sock_t sd)
+{
+ if (sb && sd >= 0) {
+ sb->end = 0;
+ sb->start = 0;
+ sb->sd = sd;
+ return JK_TRUE;
+ }
+
+ return JK_FALSE;
+}
+
+int jk_sb_write(jk_sockbuf_t *sb, const void *buf, unsigned sz)
+{
+ if (sb && buf && sz) {
+ if ((SOCKBUF_SIZE - sb->end) >= sz) {
+ memcpy(sb->buf + sb->end, buf, sz);
+ sb->end += sz;
+ }
+ else {
+ if (!jk_sb_flush(sb)) {
+ return JK_FALSE;
+ }
+ if (sz > SOCKBUF_SIZE) {
+ return (send(sb->sd, (char *)buf, sz, 0) == (int)sz);
+ }
+
+ memcpy(sb->buf + sb->end, buf, sz);
+ sb->end += sz;
+ }
+
+ return JK_TRUE;
+ }
+
+ return JK_FALSE;
+}
+
+int jk_sb_flush(jk_sockbuf_t *sb)
+{
+ if (sb) {
+ int save_out = sb->end;
+ sb->end = sb->start = 0;
+ if (save_out) {
+ return send(sb->sd, sb->buf, save_out, 0) == save_out;
+ }
+ return JK_TRUE;
+ }
+
+ return JK_FALSE;
+}
+
+
+int jk_sb_read(jk_sockbuf_t *sb, char **buf, unsigned sz, unsigned *ac)
+{
+ if (sb && buf && ac) {
+ unsigned avail;
+
+ *ac = 0;
+ *buf = NULL;
+
+ if (sb->end == sb->start) {
+ sb->end = sb->start = 0;
+ if (fill_buffer(sb) < 0) {
+ return JK_FALSE;
+ }
+ }
+
+ *buf = sb->buf + sb->start;
+ avail = sb->end - sb->start;
+ if (avail > sz) {
+ *ac = sz;
+ }
+ else {
+ *ac = avail;
+ }
+ sb->start += *ac;
+
+ return JK_TRUE;
+ }
+
+ return JK_FALSE;
+}
+
+int jk_sb_gets(jk_sockbuf_t *sb, char **ps)
+{
+ int ret;
+ if (sb) {
+ while (1) {
+ unsigned i;
+ for (i = sb->start; i < sb->end; i++) {
+ if (JK_LF == sb->buf[i]) {
+ if (i > sb->start && JK_CR == sb->buf[i - 1]) {
+ sb->buf[i - 1] = '\0';
+ }
+ else {
+ sb->buf[i] = '\0';
+ }
+ *ps = sb->buf + sb->start;
+ sb->start = (i + 1);
+ return JK_TRUE;
+ }
+ }
+ if ((ret = fill_buffer(sb)) < 0) {
+ return JK_FALSE;
+ }
+ else if (ret == 0) {
+ *ps = sb->buf + sb->start;
+ if ((SOCKBUF_SIZE - sb->end) > 0) {
+ sb->buf[sb->end] = '\0';
+ }
+ else {
+ sb->buf[sb->end - 1] = '\0';
+ }
+ return JK_TRUE;
+ }
+ }
+ }
+
+ return JK_FALSE;
+}
+
+/*
+ * Read data from the socket into the associated buffer, and update the
+ * start and end indices. May move the data currently in the buffer. If
+ * new data is read into the buffer (or if it is already full), returns 1.
+ * If EOF is received on the socket, returns 0. In case of error returns
+ * -1.
+ */
+static int fill_buffer(jk_sockbuf_t *sb)
+{
+ int ret;
+
+ /*
+ * First move the current data to the beginning of the buffer
+ */
+ if (sb->start < sb->end) {
+ if (sb->start > 0) {
+ unsigned to_copy = sb->end - sb->start;
+ memmove(sb->buf, sb->buf + sb->start, to_copy);
+ sb->start = 0;
+ sb->end = to_copy;
+ }
+ }
+ else {
+ sb->start = sb->end = 0;
+ }
+
+ /*
+ * In the unlikely case where the buffer is already full, we won't be
+ * reading anything and we'd be calling recv with a 0 count.
+ */
+ if ((SOCKBUF_SIZE - sb->end) > 0) {
+ /*
+ * Now, read more data
+ */
+ ret = recv(sb->sd, sb->buf + sb->end, SOCKBUF_SIZE - sb->end, 0);
+
+ /* 0 is EOF/SHUTDOWN, -1 is SOCK_ERROR */
+ if (ret <= 0) {
+ return ret;
+ }
+
+ sb->end += ret;
+ }
+
+ return 1;
+}