/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 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"

#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 = 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: */
