/* Copyright 2000-2004 The Apache Software Foundation
 *
 * Licensed 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.
 */

#include "apu.h"
#include "apu_config.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "apr_portable.h"
#include "apr_xlate.h"

/* If no implementation is available, don't generate code here since
 * apr_xlate.h emitted macros which return APR_ENOTIMPL.
 */

#if APR_HAS_XLATE

#ifdef HAVE_STDDEF_H
#include <stddef.h> /* for NULL */
#endif
#if APR_HAVE_STRING_H
#include <string.h>
#endif
#if APR_HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_ICONV_H
#include <iconv.h>
#endif
#if APU_HAVE_APR_ICONV
#include <apr_iconv.h>
#endif

#if defined(APU_ICONV_INBUF_CONST) || APU_HAVE_APR_ICONV
#define ICONV_INBUF_TYPE const char **
#else
#define ICONV_INBUF_TYPE char **
#endif

#ifndef min
#define min(x,y) ((x) <= (y) ? (x) : (y))
#endif

struct apr_xlate_t {
    apr_pool_t *pool;
    char *frompage;
    char *topage;
    char *sbcs_table;
#if APU_HAVE_ICONV
    iconv_t ich;
#elif APU_HAVE_APR_ICONV
    apr_iconv_t ich;
#endif
};


static const char *handle_special_names(const char *page, apr_pool_t *pool)
{
    if (page == APR_DEFAULT_CHARSET) {
        return apr_os_default_encoding(pool);
    }
    else if (page == APR_LOCALE_CHARSET) {
        return apr_os_locale_encoding(pool);
    }
    else {
        return page;
    }
}

static apr_status_t apr_xlate_cleanup(void *convset)
{
    apr_xlate_t *old = convset;

#if APU_HAVE_APR_ICONV
    if (old->ich != (apr_iconv_t)-1) {
        return apr_iconv_close(old->ich, old->pool);
    }

#elif APU_HAVE_ICONV
    if (old->ich != (iconv_t)-1) {
        if (iconv_close(old->ich)) {
            int rv = errno;

            /* Sometimes, iconv is not good about setting errno. */
            return rv ? rv : APR_EINVAL;
        }
    }
#endif

    return APR_SUCCESS;
}

#if APU_HAVE_ICONV
static void check_sbcs(apr_xlate_t *convset)
{
    char inbuf[256], outbuf[256];
    char *inbufptr = inbuf;
    char *outbufptr = outbuf;
    apr_size_t inbytes_left, outbytes_left;
    int i;
    apr_size_t translated;

    for (i = 0; i < sizeof(inbuf); i++) {
        inbuf[i] = i;
    }

    inbytes_left = outbytes_left = sizeof(inbuf);
    translated = iconv(convset->ich, (ICONV_INBUF_TYPE)&inbufptr,
                       &inbytes_left, &outbufptr, &outbytes_left);

    if (translated != (apr_size_t)-1
        && inbytes_left == 0
        && outbytes_left == 0) {
        /* hurray... this is simple translation; save the table,
         * close the iconv descriptor
         */

        convset->sbcs_table = apr_palloc(convset->pool, sizeof(outbuf));
        memcpy(convset->sbcs_table, outbuf, sizeof(outbuf));
        iconv_close(convset->ich);
        convset->ich = (iconv_t)-1;

        /* TODO: add the table to the cache */
    }
    else {
        /* reset the iconv descriptor, since it's now in an undefined
         * state. */
        iconv_close(convset->ich);
        convset->ich = iconv_open(convset->topage, convset->frompage);
    }
}
#elif APU_HAVE_APR_ICONV
static void check_sbcs(apr_xlate_t *convset)
{
    char inbuf[256], outbuf[256];
    char *inbufptr = inbuf;
    char *outbufptr = outbuf;
    apr_size_t inbytes_left, outbytes_left;
    int i;
    apr_size_t translated;
    apr_status_t rv;

    for (i = 0; i < sizeof(inbuf); i++) {
        inbuf[i] = i;
    }

    inbytes_left = outbytes_left = sizeof(inbuf);
    rv = apr_iconv(convset->ich, (ICONV_INBUF_TYPE)&inbufptr,
                   &inbytes_left, &outbufptr, &outbytes_left,
                   &translated);

    if ((rv == APR_SUCCESS)
        && (translated != (apr_size_t)-1)
        && inbytes_left == 0
        && outbytes_left == 0) {
        /* hurray... this is simple translation; save the table,
         * close the iconv descriptor
         */

        convset->sbcs_table = apr_palloc(convset->pool, sizeof(outbuf));
        memcpy(convset->sbcs_table, outbuf, sizeof(outbuf));
        apr_iconv_close(convset->ich, convset->pool);
        convset->ich = (apr_iconv_t)-1;

        /* TODO: add the table to the cache */
    }
    else {
        /* reset the iconv descriptor, since it's now in an undefined
         * state. */
        apr_iconv_close(convset->ich);
        convset->ich = apr_iconv_open(convset->topage, convset->frompage);
    }
}
#endif /* APU_HAVE_APR_ICONV */

static void make_identity_table(apr_xlate_t *convset)
{
  int i;

  convset->sbcs_table = apr_palloc(convset->pool, 256);
  for (i = 0; i < 256; i++)
      convset->sbcs_table[i] = i;
}

APU_DECLARE(apr_status_t) apr_xlate_open(apr_xlate_t **convset,
                                         const char *topage,
                                         const char *frompage,
                                         apr_pool_t *pool)
{
    apr_status_t rv;
    apr_xlate_t *new;
    int found = 0;

    *convset = NULL;

    topage = handle_special_names(topage, pool);
    frompage = handle_special_names(frompage, pool);

    new = (apr_xlate_t *)apr_pcalloc(pool, sizeof(apr_xlate_t));
    if (!new) {
        return APR_ENOMEM;
    }

    new->pool = pool;
    new->topage = apr_pstrdup(pool, topage);
    new->frompage = apr_pstrdup(pool, frompage);
    if (!new->topage || !new->frompage) {
        return APR_ENOMEM;
    }

#ifdef TODO
    /* search cache of codepage pairs; we may be able to avoid the
     * expensive iconv_open()
     */

    set found to non-zero if found in the cache
#endif

    if ((! found) && (strcmp(topage, frompage) == 0)) {
        /* to and from are the same */
        found = 1;
        make_identity_table(new);
    }

#if APU_HAVE_APR_ICONV
    if (!found) {
        rv = apr_iconv_open(topage, frompage, pool, &new->ich);
        if (rv != APR_SUCCESS) {
            return rv;
        }
        found = 1;
        check_sbcs(new);
    } else
        new->ich = (apr_iconv_t)-1;

#elif APU_HAVE_ICONV
    if (!found) {
        new->ich = iconv_open(topage, frompage);
        if (new->ich == (iconv_t)-1) {
            int rv = errno;
            /* Sometimes, iconv is not good about setting errno. */
            return rv ? rv : APR_EINVAL;
        }
        found = 1;
        check_sbcs(new);
    } else
        new->ich = (iconv_t)-1;
#endif /* APU_HAVE_ICONV */

    if (found) {
        *convset = new;
        apr_pool_cleanup_register(pool, (void *)new, apr_xlate_cleanup,
                            apr_pool_cleanup_null);
        rv = APR_SUCCESS;
    }
    else {
        rv = APR_EINVAL; /* iconv() would return EINVAL if it
                                couldn't handle the pair */
    }

    return rv;
}

APU_DECLARE(apr_status_t) apr_xlate_sb_get(apr_xlate_t *convset, int *onoff)
{
    *onoff = convset->sbcs_table != NULL;
    return APR_SUCCESS;
}

APU_DECLARE(apr_status_t) apr_xlate_conv_buffer(apr_xlate_t *convset,
                                                const char *inbuf,
                                                apr_size_t *inbytes_left,
                                                char *outbuf,
                                                apr_size_t *outbytes_left)
{
    apr_status_t status = APR_SUCCESS;

#if APU_HAVE_APR_ICONV
    if (convset->ich != (apr_iconv_t)-1) {
        const char *inbufptr = inbuf;
        apr_size_t translated;
        char *outbufptr = outbuf;
        status = apr_iconv(convset->ich, &inbufptr, inbytes_left,
                           &outbufptr, outbytes_left, &translated);

        /* If everything went fine but we ran out of buffer, don't
         * report it as an error.  Caller needs to look at the two
         * bytes-left values anyway.
         *
         * There are three expected cases where rc is -1.  In each of
         * these cases, *inbytes_left != 0.
         * a) the non-error condition where we ran out of output
         *    buffer
         * b) the non-error condition where we ran out of input (i.e.,
         *    the last input character is incomplete)
         * c) the error condition where the input is invalid
         */
        switch (status) {

            case E2BIG:  /* out of space on output */
                status = 0; /* change table lookup code below if you
                               make this an error */
                break;

            case EINVAL: /* input character not complete (yet) */
                status = APR_INCOMPLETE;
                break;

            case EILSEQ: /* bad input byte */
                status = APR_EINVAL;
                break;

             /* Sometimes, iconv is not good about setting errno. */
            case 0:
                if (*inbytes_left)
                    status = APR_INCOMPLETE;
                break;

            default:
                break;
        }
    }
    else

#elif APU_HAVE_ICONV
    if (convset->ich != (iconv_t)-1) {
        const char *inbufptr = inbuf;
        char *outbufptr = outbuf;
        apr_size_t translated;
        translated = iconv(convset->ich, (ICONV_INBUF_TYPE)&inbufptr,
                           inbytes_left, &outbufptr, outbytes_left);

        /* If everything went fine but we ran out of buffer, don't
         * report it as an error.  Caller needs to look at the two
         * bytes-left values anyway.
         *
         * There are three expected cases where rc is -1.  In each of
         * these cases, *inbytes_left != 0.
         * a) the non-error condition where we ran out of output
         *    buffer
         * b) the non-error condition where we ran out of input (i.e.,
         *    the last input character is incomplete)
         * c) the error condition where the input is invalid
         */
        if (translated == (apr_size_t)-1) {
            int rv = errno;
            switch (rv) {

            case E2BIG:  /* out of space on output */
                status = 0; /* change table lookup code below if you
                               make this an error */
                break;

            case EINVAL: /* input character not complete (yet) */
                status = APR_INCOMPLETE;
                break;

            case EILSEQ: /* bad input byte */
                status = APR_EINVAL;
                break;

             /* Sometimes, iconv is not good about setting errno. */
            case 0:
                status = APR_INCOMPLETE;
                break;

            default:
                status = rv;
                break;
            }
        }
    }
    else
#endif

    {
        int to_convert = min(*inbytes_left, *outbytes_left);
        int converted = to_convert;
        char *table = convset->sbcs_table;

        while (to_convert) {
            *outbuf = table[(unsigned char)*inbuf];
            ++outbuf;
            ++inbuf;
            --to_convert;
        }
        *inbytes_left -= converted;
        *outbytes_left -= converted;
    }

    return status;
}

APU_DECLARE(apr_int32_t) apr_xlate_conv_byte(apr_xlate_t *convset,
                                             unsigned char inchar)
{
    if (convset->sbcs_table) {
        return convset->sbcs_table[inchar];
    }
    else {
        return -1;
    }
}

APU_DECLARE(apr_status_t) apr_xlate_close(apr_xlate_t *convset)
{
    return apr_pool_cleanup_run(convset->pool, convset, apr_xlate_cleanup);
}

#else /* !APR_HAS_XLATE */

APU_DECLARE(apr_status_t) apr_xlate_open(apr_xlate_t **convset,
                                         const char *topage,
                                         const char *frompage,
                                         apr_pool_t *pool)
{
    return APR_ENOTIMPL;
}

APU_DECLARE(apr_status_t) apr_xlate_sb_get(apr_xlate_t *convset, int *onoff)
{
    return APR_ENOTIMPL;
}

APU_DECLARE(apr_int32_t) apr_xlate_conv_byte(apr_xlate_t *convset,
                                             unsigned char inchar)
{
    return (-1);
}

APU_DECLARE(apr_status_t) apr_xlate_conv_buffer(apr_xlate_t *convset,
                                                const char *inbuf,
                                                apr_size_t *inbytes_left,
                                                char *outbuf,
                                                apr_size_t *outbytes_left)
{
    return APR_ENOTIMPL;
}

APU_DECLARE(apr_status_t) apr_xlate_close(apr_xlate_t *convset)
{
    return APR_ENOTIMPL;
}

#endif /* APR_HAS_XLATE */
