/* crypto/bio/bf_buff.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <openssl/opensslconf.h>
#if !defined(OPENSSL_SYS_STARBOARD)
#include <errno.h>
#include <stdio.h>
#endif  // !defined(OPENSSL_SYS_STARBOARD)
#include "cryptlib.h"
#include <openssl/bio.h>

static int buffer_write(BIO *h, const char *buf, int num);
static int buffer_read(BIO *h, char *buf, int size);
static int buffer_puts(BIO *h, const char *str);
static int buffer_gets(BIO *h, char *str, int size);
static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int buffer_new(BIO *h);
static int buffer_free(BIO *data);
static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
#define DEFAULT_BUFFER_SIZE     4096

static BIO_METHOD methods_buffer = {
    BIO_TYPE_BUFFER,
    "buffer",
    buffer_write,
    buffer_read,
    buffer_puts,
    buffer_gets,
    buffer_ctrl,
    buffer_new,
    buffer_free,
    buffer_callback_ctrl,
};

BIO_METHOD *BIO_f_buffer(void)
{
    return (&methods_buffer);
}

static int buffer_new(BIO *bi)
{
    BIO_F_BUFFER_CTX *ctx;

    ctx = (BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
    if (ctx == NULL)
        return (0);
    ctx->ibuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
    if (ctx->ibuf == NULL) {
        OPENSSL_free(ctx);
        return (0);
    }
    ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
    if (ctx->obuf == NULL) {
        OPENSSL_free(ctx->ibuf);
        OPENSSL_free(ctx);
        return (0);
    }
    ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
    ctx->obuf_size = DEFAULT_BUFFER_SIZE;
    ctx->ibuf_len = 0;
    ctx->ibuf_off = 0;
    ctx->obuf_len = 0;
    ctx->obuf_off = 0;

    bi->init = 1;
    bi->ptr = (char *)ctx;
    bi->flags = 0;
    return (1);
}

static int buffer_free(BIO *a)
{
    BIO_F_BUFFER_CTX *b;

    if (a == NULL)
        return (0);
    b = (BIO_F_BUFFER_CTX *)a->ptr;
    if (b->ibuf != NULL)
        OPENSSL_free(b->ibuf);
    if (b->obuf != NULL)
        OPENSSL_free(b->obuf);
    OPENSSL_free(a->ptr);
    a->ptr = NULL;
    a->init = 0;
    a->flags = 0;
    return (1);
}

static int buffer_read(BIO *b, char *out, int outl)
{
    int i, num = 0;
    BIO_F_BUFFER_CTX *ctx;

    if (out == NULL)
        return (0);
    ctx = (BIO_F_BUFFER_CTX *)b->ptr;

    if ((ctx == NULL) || (b->next_bio == NULL))
        return (0);
    num = 0;
    BIO_clear_retry_flags(b);

 start:
    i = ctx->ibuf_len;
    /* If there is stuff left over, grab it */
    if (i != 0) {
        if (i > outl)
            i = outl;
        OPENSSL_port_memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
        ctx->ibuf_off += i;
        ctx->ibuf_len -= i;
        num += i;
        if (outl == i)
            return (num);
        outl -= i;
        out += i;
    }

    /*
     * We may have done a partial read. try to do more. We have nothing in
     * the buffer. If we get an error and have read some data, just return it
     * and let them retry to get the error again. copy direct to parent
     * address space
     */
    if (outl > ctx->ibuf_size) {
        for (;;) {
            i = BIO_read(b->next_bio, out, outl);
            if (i <= 0) {
                BIO_copy_next_retry(b);
                if (i < 0)
                    return ((num > 0) ? num : i);
                if (i == 0)
                    return (num);
            }
            num += i;
            if (outl == i)
                return (num);
            out += i;
            outl -= i;
        }
    }
    /* else */

    /* we are going to be doing some buffering */
    i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
    if (i <= 0) {
        BIO_copy_next_retry(b);
        if (i < 0)
            return ((num > 0) ? num : i);
        if (i == 0)
            return (num);
    }
    ctx->ibuf_off = 0;
    ctx->ibuf_len = i;

    /* Lets re-read using ourselves :-) */
    goto start;
}

static int buffer_write(BIO *b, const char *in, int inl)
{
    int i, num = 0;
    BIO_F_BUFFER_CTX *ctx;

    if ((in == NULL) || (inl <= 0))
        return (0);
    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
    if ((ctx == NULL) || (b->next_bio == NULL))
        return (0);

    BIO_clear_retry_flags(b);
 start:
    i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
    /* add to buffer and return */
    if (i >= inl) {
        OPENSSL_port_memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
        ctx->obuf_len += inl;
        return (num + inl);
    }
    /* else */
    /* stuff already in buffer, so add to it first, then flush */
    if (ctx->obuf_len != 0) {
        if (i > 0) {            /* lets fill it up if we can */
            OPENSSL_port_memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
            in += i;
            inl -= i;
            num += i;
            ctx->obuf_len += i;
        }
        /* we now have a full buffer needing flushing */
        for (;;) {
            i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
                          ctx->obuf_len);
            if (i <= 0) {
                BIO_copy_next_retry(b);

                if (i < 0)
                    return ((num > 0) ? num : i);
                if (i == 0)
                    return (num);
            }
            ctx->obuf_off += i;
            ctx->obuf_len -= i;
            if (ctx->obuf_len == 0)
                break;
        }
    }
    /*
     * we only get here if the buffer has been flushed and we still have
     * stuff to write
     */
    ctx->obuf_off = 0;

    /* we now have inl bytes to write */
    while (inl >= ctx->obuf_size) {
        i = BIO_write(b->next_bio, in, inl);
        if (i <= 0) {
            BIO_copy_next_retry(b);
            if (i < 0)
                return ((num > 0) ? num : i);
            if (i == 0)
                return (num);
        }
        num += i;
        in += i;
        inl -= i;
        if (inl == 0)
            return (num);
    }

    /*
     * copy the rest into the buffer since we have only a small amount left
     */
    goto start;
}

static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
{
    BIO *dbio;
    BIO_F_BUFFER_CTX *ctx;
    long ret = 1;
    char *p1, *p2;
    int r, i, *ip;
    int ibs, obs;

    ctx = (BIO_F_BUFFER_CTX *)b->ptr;

    switch (cmd) {
    case BIO_CTRL_RESET:
        ctx->ibuf_off = 0;
        ctx->ibuf_len = 0;
        ctx->obuf_off = 0;
        ctx->obuf_len = 0;
        if (b->next_bio == NULL)
            return (0);
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;
    case BIO_CTRL_INFO:
        ret = (long)ctx->obuf_len;
        break;
    case BIO_C_GET_BUFF_NUM_LINES:
        ret = 0;
        p1 = ctx->ibuf;
        for (i = 0; i < ctx->ibuf_len; i++) {
            if (p1[ctx->ibuf_off + i] == '\n')
                ret++;
        }
        break;
    case BIO_CTRL_WPENDING:
        ret = (long)ctx->obuf_len;
        if (ret == 0) {
            if (b->next_bio == NULL)
                return (0);
            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        }
        break;
    case BIO_CTRL_PENDING:
        ret = (long)ctx->ibuf_len;
        if (ret == 0) {
            if (b->next_bio == NULL)
                return (0);
            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        }
        break;
    case BIO_C_SET_BUFF_READ_DATA:
        if (num > ctx->ibuf_size) {
            p1 = OPENSSL_malloc((int)num);
            if (p1 == NULL)
                goto malloc_error;
            if (ctx->ibuf != NULL)
                OPENSSL_free(ctx->ibuf);
            ctx->ibuf = p1;
        }
        ctx->ibuf_off = 0;
        ctx->ibuf_len = (int)num;
        OPENSSL_port_memcpy(ctx->ibuf, ptr, (int)num);
        ret = 1;
        break;
    case BIO_C_SET_BUFF_SIZE:
        if (ptr != NULL) {
            ip = (int *)ptr;
            if (*ip == 0) {
                ibs = (int)num;
                obs = ctx->obuf_size;
            } else {            /* if (*ip == 1) */

                ibs = ctx->ibuf_size;
                obs = (int)num;
            }
        } else {
            ibs = (int)num;
            obs = (int)num;
        }
        p1 = ctx->ibuf;
        p2 = ctx->obuf;
        if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
            p1 = (char *)OPENSSL_malloc((int)num);
            if (p1 == NULL)
                goto malloc_error;
        }
        if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
            p2 = (char *)OPENSSL_malloc((int)num);
            if (p2 == NULL) {
                if (p1 != ctx->ibuf)
                    OPENSSL_free(p1);
                goto malloc_error;
            }
        }
        if (ctx->ibuf != p1) {
            OPENSSL_free(ctx->ibuf);
            ctx->ibuf = p1;
            ctx->ibuf_off = 0;
            ctx->ibuf_len = 0;
            ctx->ibuf_size = ibs;
        }
        if (ctx->obuf != p2) {
            OPENSSL_free(ctx->obuf);
            ctx->obuf = p2;
            ctx->obuf_off = 0;
            ctx->obuf_len = 0;
            ctx->obuf_size = obs;
        }
        break;
    case BIO_C_DO_STATE_MACHINE:
        if (b->next_bio == NULL)
            return (0);
        BIO_clear_retry_flags(b);
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        BIO_copy_next_retry(b);
        break;

    case BIO_CTRL_FLUSH:
        if (b->next_bio == NULL)
            return (0);
        if (ctx->obuf_len <= 0) {
            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
            break;
        }

        for (;;) {
            BIO_clear_retry_flags(b);
            if (ctx->obuf_len > 0) {
                r = BIO_write(b->next_bio,
                              &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len);
#if 0
                OPENSSL_port_printferr("FLUSH [%3d] %3d -> %3d\n", ctx->obuf_off,
                        ctx->obuf_len, r);
#endif
                BIO_copy_next_retry(b);
                if (r <= 0)
                    return ((long)r);
                ctx->obuf_off += r;
                ctx->obuf_len -= r;
            } else {
                ctx->obuf_len = 0;
                ctx->obuf_off = 0;
                ret = 1;
                break;
            }
        }
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;
    case BIO_CTRL_DUP:
        dbio = (BIO *)ptr;
        if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
            !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
            ret = 0;
        break;
    default:
        if (b->next_bio == NULL)
            return (0);
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;
    }
    return (ret);
 malloc_error:
    BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
    return (0);
}

static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
    long ret = 1;

    if (b->next_bio == NULL)
        return (0);
    switch (cmd) {
    default:
        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
        break;
    }
    return (ret);
}

static int buffer_gets(BIO *b, char *buf, int size)
{
    BIO_F_BUFFER_CTX *ctx;
    int num = 0, i, flag;
    char *p;

    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
    size--;                     /* reserve space for a '\0' */
    BIO_clear_retry_flags(b);

    for (;;) {
        if (ctx->ibuf_len > 0) {
            p = &(ctx->ibuf[ctx->ibuf_off]);
            flag = 0;
            for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
                *(buf++) = p[i];
                if (p[i] == '\n') {
                    flag = 1;
                    i++;
                    break;
                }
            }
            num += i;
            size -= i;
            ctx->ibuf_len -= i;
            ctx->ibuf_off += i;
            if (flag || size == 0) {
                *buf = '\0';
                return (num);
            }
        } else {                /* read another chunk */

            i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
            if (i <= 0) {
                BIO_copy_next_retry(b);
                *buf = '\0';
                if (i < 0)
                    return ((num > 0) ? num : i);
                if (i == 0)
                    return (num);
            }
            ctx->ibuf_len = i;
            ctx->ibuf_off = 0;
        }
    }
}

static int buffer_puts(BIO *b, const char *str)
{
    return (buffer_write(b, str, OPENSSL_port_strlen(str)));
}
