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

   Andrey Vasilkin.
*/

#define ICONV_THREAD_SAFE 1

#include "geniconv.h"
#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;
}

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