/*
 *  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$                                           *
 ***************************************************************************/

#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;
}
