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

   Andrey Vasilkin.
*/

#define ICONV_THREAD_SAFE 1
//#undef ICONV_THREAD_SAFE

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