/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

/*
   Implementation iconv via OS/2 conversion objects API.

   Andrey Vasilkin.
*/

#define ICONV_THREAD_SAFE 1

#include "geniconv.h"
#define _ULS_CALLCONV_
#define CALLCONV _System
#include <uconv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef ICONV_THREAD_SAFE
#define INCL_DOSSEMAPHORES
#define INCL_DOSERRORS
#include <os2.h>
#endif
#include "os2cp.h"

#if !defined(min)
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif

#define MAX_CP_NAME_LEN 64

typedef struct iuconv_obj {
  UconvObject	uo_tocode;
  UconvObject	uo_fromcode;
  int		buf_len;
  UniChar	*buf;
#ifdef ICONV_THREAD_SAFE
  HMTX		hMtx;
#endif
} iuconv_obj;


static int _createUconvObj(const char *code, UconvObject *uobj)
{
    UniChar uc_code[MAX_CP_NAME_LEN];
    int i;
    const char *ch = code;

    if (code == NULL)
        uc_code[0] = 0;
    else {
        for (i = 0; i < MAX_CP_NAME_LEN; i++) {
            uc_code[i] = (unsigned short)*ch;
            if (! (*ch))
                break;
            ch++;
        }
    }

    return UniCreateUconvObject(uc_code, uobj);
}

static int uconv_open(const char *code, UconvObject *uobj)
{
    int rc;

    if (!stricmp(code, "UTF-16")) {
        *uobj = NULL;
        return ULS_SUCCESS;
    }

    rc = _createUconvObj(code, uobj);
    if (rc != ULS_SUCCESS) {
        unsigned long cp = os2cpFromName((char *)code);
        char cp_name[16];

        if (cp != 0 && _snprintf(cp_name, sizeof(cp_name), "IBM-%u", cp) > 0)
            rc = _createUconvObj(cp_name, uobj);
    }

    return rc;
}


extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode)
{
    UconvObject uo_tocode;
    UconvObject uo_fromcode;
    int rc;
    iuconv_obj *iuobj;

    if (tocode == NULL)
        tocode = "";

    if (fromcode == NULL)
        fromcode = "";

    if (stricmp(tocode, fromcode) != 0) {
        rc = uconv_open(fromcode, &uo_fromcode);
        if (rc != ULS_SUCCESS) {
            errno = EINVAL;
            return (iconv_t)(-1);
        }

        rc = uconv_open(tocode, &uo_tocode);
        if (rc != ULS_SUCCESS) {
            UniFreeUconvObject(uo_fromcode);
            errno = EINVAL;
            return (iconv_t)(-1);
        }
    } else {
        uo_tocode = NULL;
        uo_fromcode = NULL;
    }

    iuobj = (iuconv_obj *) malloc(sizeof(iuconv_obj));
    iuobj->uo_tocode = uo_tocode;
    iuobj->uo_fromcode = uo_fromcode;
    iuobj->buf_len = 0;
    iuobj->buf = NULL;
#ifdef ICONV_THREAD_SAFE
    DosCreateMutexSem(NULL, &iuobj->hMtx, 0, FALSE);
#endif

    return iuobj;
}

extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
                                size_t *inbytesleft,
                                char* * outbuf, size_t *outbytesleft)
{
    UconvObject uo_tocode = ((iuconv_obj *)(cd))->uo_tocode;
    UconvObject uo_fromcode = ((iuconv_obj *)(cd))->uo_fromcode;
    size_t nonIdenticalConv = 0;
    UniChar *uc_buf;
    size_t uc_buf_len;
    UniChar **uc_str;
    size_t *uc_str_len;
    int rc;
    size_t ret = (size_t)(-1);

    if (uo_tocode == NULL && uo_fromcode == NULL) {
        uc_buf_len = min(*inbytesleft, *outbytesleft);
        memcpy(*outbuf, *inbuf, uc_buf_len);
        *inbytesleft -= uc_buf_len;
        *outbytesleft -= uc_buf_len;
        outbuf += uc_buf_len;
        inbuf += uc_buf_len;
        return uc_buf_len;
    }

#ifdef ICONV_THREAD_SAFE
    DosRequestMutexSem(((iuconv_obj *)(cd))->hMtx, SEM_INDEFINITE_WAIT);
#endif

    if (uo_tocode && uo_fromcode &&
        (((iuconv_obj *)cd)->buf_len >> 1) < *inbytesleft) {
        if (((iuconv_obj *)cd)->buf != NULL)
            free(((iuconv_obj *)cd)->buf);
        ((iuconv_obj *)cd)->buf_len = *inbytesleft << 1;
        ((iuconv_obj *)cd)->buf = (UniChar *)malloc(((iuconv_obj *)cd)->buf_len);
    }

    if (uo_fromcode) {
        if (uo_tocode) {
            uc_buf = ((iuconv_obj *)cd)->buf;
            uc_buf_len = ((iuconv_obj *)cd)->buf_len;
            uc_str = &uc_buf;
        } else {
            uc_str = (UniChar **)outbuf;
            uc_buf_len = *outbytesleft;
        }
        uc_buf_len = uc_buf_len >> 1;
        uc_str_len = &uc_buf_len;
        rc = UniUconvToUcs(uo_fromcode, (void **)inbuf, inbytesleft,
                           uc_str, uc_str_len, &nonIdenticalConv);
        uc_buf_len = uc_buf_len << 1;
        if (!uo_tocode)
            *outbytesleft = uc_buf_len;

        if (rc != ULS_SUCCESS) {
            errno = EILSEQ;
            goto done;
        } else if (*inbytesleft && !*uc_str_len) {
            errno = E2BIG;
            goto done;
        }

        if (!uo_tocode)
            return nonIdenticalConv;

        uc_buf = ((iuconv_obj *)cd)->buf;
        uc_buf_len = ((iuconv_obj *)cd)->buf_len - uc_buf_len;
        uc_str = &uc_buf;
        uc_str_len = &uc_buf_len;
    } else {
        uc_str = (UniChar **)inbuf;
        uc_str_len = inbytesleft;
    }

    *uc_str_len = *uc_str_len>>1;
    rc = UniUconvFromUcs(uo_tocode, uc_str, uc_str_len, (void **)outbuf,
                         outbytesleft, &nonIdenticalConv);
    if (rc != ULS_SUCCESS) {
        switch (rc) {
        case ULS_BUFFERFULL:
            errno = E2BIG;
            break;
        case ULS_ILLEGALSEQUENCE:
            errno = EILSEQ;
            break;
        case ULS_INVALID:
            errno = EINVAL;
            break;
        }
        goto done;
    } else if (*uc_str_len && !*outbytesleft) {
        errno = E2BIG;
        goto done;
    }

    ret = nonIdenticalConv;

done:

#ifdef ICONV_THREAD_SAFE
    DosReleaseMutexSem(((iuconv_obj *)cd)->hMtx);
#endif
    return ret;
}

int _System os2_iconv_close(iconv_t cd)
{
    if (!cd) return 0;

#ifdef ICONV_THREAD_SAFE
    DosCloseMutexSem(((iuconv_obj *)cd)->hMtx);
#endif
    if (((iuconv_obj *)cd)->uo_tocode != NULL)
        UniFreeUconvObject(((iuconv_obj *)cd)->uo_tocode);
    if (((iuconv_obj *)cd)->uo_fromcode != NULL)
        UniFreeUconvObject(((iuconv_obj *)cd)->uo_fromcode);

    if (((iuconv_obj *)cd)->buf != NULL)
        free(((iuconv_obj *)cd)->buf);

    free(cd);

    return 0;
}

/* vi: set ts=4 sw=4 expandtab: */
