/*
*******************************************************************************
*
*   Copyright (C) 1998-1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*
*  ucnv.c:
*  Implements APIs for the ICU's codeset conversion library
*  mostly calls through internal functions created and maintained 
*  by Bertrand A. Damiba
*
* Modification History:
*
*   Date        Name        Description
*   04/04/99    helena      Fixed internal header inclusion.
*   05/09/00    helena      Added implementation to handle fallback mappings.
*   06/20/2000  helena      OS/400 port changes; mostly typecast.
*/
#include "umutex.h"
#include "unicode/ures.h"
#include "uhash.h"
#include "ucmp16.h"
#include "ucmp8.h"
#include "ucnv_io.h"
#include "unicode/ucnv_err.h"
#include "ucnv_cnv.h"
#include "ucnv_imp.h"
#include "unicode/ucnv.h"
#include "cmemory.h"
#include "cstring.h"
#include "unicode/ustring.h"
#include "unicode/uloc.h"
#include "ucnv_bld.h"

#if 0
/* debugging for converters */
# include <stdio.h>
void UCNV_DEBUG_LOG(char *what, char *who, void *p, int l)
{
   static FILE *f = NULL;
   if(f==NULL)
   {
       f = fopen("c:\\UCNV_DEBUG_LOG.txt", "w");
   }
   fprintf(f, "%-20s %-10s %p@%d\n",
        who,what,p,l);
   fflush(f);
}
# define UCNV_DEBUG_LOG(x,y,z) UCNV_DEBUG_LOG(x,y,z,__LINE__)
#else
# define UCNV_DEBUG_LOG(x,y,z)
#endif

#define CHUNK_SIZE 5*1024

/* Internal function : begin */
static int32_t ucnv_getAmbiguousCCSID (const UConverter* cnv);
/* Internal function : end */

static void T_UConverter_fromCodepageToCodepage (UConverter * outConverter,
                                                 UConverter * inConverter,
                                                 char **target,
                                                 const char *targetLimit,
                                                 const char **source,
                                                 const char *sourceLimit,
                                                 int32_t* offsets,
                                                 UBool flush,
                                                 UErrorCode * err);


const char* ucnv_getDefaultName ()
{
  return ucnv_io_getDefaultConverterName();
}

void   ucnv_setDefaultName (const char *converterName)
{
  ucnv_io_setDefaultConverterName(converterName);
}
/*Calls through createConverter */
UConverter* ucnv_open (const char *name,
                       UErrorCode * err)
{
  if (err == NULL || U_FAILURE (*err)) {
    return NULL;
  }

  return createConverter (name, err);
}

/*Extracts the UChar* to a char* and calls through createConverter */
UConverter*  ucnv_openU (const UChar * name,
                         UErrorCode * err)
{
  char asciiName[UCNV_MAX_CONVERTER_NAME_LENGTH];
  
  if (U_FAILURE (*err))
    return NULL;
  if (name == NULL)
    return ucnv_open (NULL, err);
  if (u_strlen (name) > UCNV_MAX_CONVERTER_NAME_LENGTH)
    {
      *err = U_ILLEGAL_ARGUMENT_ERROR;
      return NULL;
    }
  return ucnv_open (u_austrcpy (asciiName, name), err);
}

/*Assumes a $platform-#codepage.$CONVERTER_FILE_EXTENSION scheme and calls
 *through createConverter*/
UConverter*  ucnv_openCCSID (int32_t codepage,
                             UConverterPlatform platform,
                             UErrorCode * err)
{
  char myName[UCNV_MAX_CONVERTER_NAME_LENGTH];

  if (U_FAILURE (*err))
    return NULL;

  copyPlatformString (myName, platform);
  uprv_strcat (myName, "-");
  T_CString_integerToString (myName + uprv_strlen (myName), codepage, 10);


  return createConverter (myName, err);
}

/*Decreases the reference counter in the shared immutable section of the object
 *and frees the mutable part*/

void ucnv_close (UConverter * converter)
{
  /* first, notify the callback functions that the converter is closed */
  UConverterToUnicodeArgs toUArgs = {
    sizeof(UConverterToUnicodeArgs),
    TRUE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
  };
  UConverterFromUnicodeArgs fromUArgs = {
    sizeof(UConverterFromUnicodeArgs),
    TRUE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
  };
  UErrorCode errorCode;

  if (converter == NULL)
  {
    return;
  }

  toUArgs.converter = fromUArgs.converter = converter;
  errorCode = U_ZERO_ERROR;
  converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_CLOSE, &errorCode);
  errorCode = U_ZERO_ERROR;
  converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_CLOSE, &errorCode);

  if (converter->sharedData->impl->close != NULL) {
    converter->sharedData->impl->close(converter);
  }

  if (converter->sharedData->referenceCounter != ~0) {
    umtx_lock (NULL);
    if (converter->sharedData->referenceCounter != 0) {
      converter->sharedData->referenceCounter--;
    }
    umtx_unlock (NULL);
  }
  uprv_free (converter);

  return;
}

/*Frees all shared immutable objects that aren't referred to (reference count = 0)
 */
int32_t  ucnv_flushCache ()
{
  UConverterSharedData *mySharedData = NULL;
  int32_t pos = -1;
  int32_t tableDeletedNum = 0;
  const UHashElement *e;

  /*if shared data hasn't even been lazy evaluated yet
   * return 0
   */
  if (SHARED_DATA_HASHTABLE == NULL)
    return 0;

  /*creates an enumeration to iterate through every element in the
   *table
   */
  umtx_lock (NULL);
  while ((e = uhash_nextElement (SHARED_DATA_HASHTABLE, &pos)) != NULL)
    {
      mySharedData = (UConverterSharedData *) e->value;
      /*deletes only if reference counter == 0 */
      if (mySharedData->referenceCounter == 0)
        {
          tableDeletedNum++;

          UCNV_DEBUG_LOG("del",mySharedData->staticData->name,mySharedData);

          uhash_removeElement(SHARED_DATA_HASHTABLE, e);
          deleteSharedConverterData (mySharedData);
        }
    }
  umtx_unlock (NULL);

  return tableDeletedNum;
}

/*returns a single Name from the list, will return NULL if out of bounds
 */
const char*  ucnv_getAvailableName (int32_t n)
{
  if (0 <= n && n <= 0xffff) {
    UErrorCode err = U_ZERO_ERROR;
    const char *name = ucnv_io_getAvailableConverter((uint16_t)n, &err);
    if (U_SUCCESS(err)) {
      return name;
    }
  }
  return NULL;
}

int32_t  ucnv_countAvailable ()
{
  UErrorCode err = U_ZERO_ERROR;
  return ucnv_io_countAvailableConverters(&err);
}

U_CAPI uint16_t
ucnv_countAliases(const char *alias, UErrorCode *pErrorCode) {
    const char *p;
    return ucnv_io_getAliases(alias, &p, pErrorCode);
}


U_CAPI const char *
ucnv_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode) {
    return ucnv_io_getAlias(alias, n, pErrorCode);
}

U_CAPI void
ucnv_getAliases(const char *alias, const char **aliases, UErrorCode *pErrorCode) {
    const char *p;
    uint16_t count=ucnv_io_getAliases(alias, &p, pErrorCode);
    while(count>0) {
        *aliases++=p;
        /* skip a name, first the canonical converter name */
        p+=uprv_strlen(p)+1;
        --count;
    }
}

U_CAPI uint16_t
ucnv_countStandards(void) {
    UErrorCode err = U_ZERO_ERROR;
    return ucnv_io_countStandards(&err);
}

void   ucnv_getSubstChars (const UConverter * converter,
                           char *mySubChar,
                           int8_t * len,
                           UErrorCode * err)
{
  if (U_FAILURE (*err))
    return;

  if (*len < converter->subCharLen)	/*not enough space in subChars */
    {
      *err = U_INDEX_OUTOFBOUNDS_ERROR;
      return;
    }

  uprv_memcpy (mySubChar, converter->subChar, converter->subCharLen);	/*fills in the subchars */
  *len = converter->subCharLen;	/*store # of bytes copied to buffer */

  return;
}

void   ucnv_setSubstChars (UConverter * converter,
                           const char *mySubChar,
                           int8_t len,
                           UErrorCode * err)
{
  if (U_FAILURE (*err))
    return;

  /*Makes sure that the subChar is within the codepages char length boundaries */
  if ((len > converter->sharedData->staticData->maxBytesPerChar)
      || (len < converter->sharedData->staticData->minBytesPerChar))
    {
      *err = U_ILLEGAL_ARGUMENT_ERROR;
      return;
    }

  uprv_memcpy (converter->subChar, mySubChar, len);	/*copies the subchars */
  converter->subCharLen = len;	/*sets the new len */

  return;
}




int32_t  ucnv_getDisplayName (const UConverter * converter,
                              const char *displayLocale,
                              UChar * displayName,
                              int32_t displayNameCapacity,
                              UErrorCode * err)
{
  UChar stringToWriteBuffer[UCNV_MAX_CONVERTER_NAME_LENGTH];
  UChar const *stringToWrite;
  int32_t stringToWriteLength;
  UResourceBundle *rb = NULL;

  if (U_FAILURE (*err))
    return 0;

  /*create an RB, init the fill-in string, gets it from the RB */
  rb = ures_open (NULL, displayLocale, err);

  stringToWrite = ures_getStringByKey(rb,
                converter->sharedData->staticData->name,
                &stringToWriteLength,
                err);
  if (rb)
    ures_close (rb);

  if(U_FAILURE(*err))
    {
      /*Error While creating or getting resource from the resource bundle
       *use the internal name instead
       *
       *sets stringToWriteLength (which accounts for a NULL terminator)
       *and stringToWrite
       */
      stringToWriteLength = uprv_strlen (converter->sharedData->staticData->name) + 1;
      stringToWrite = u_uastrcpy (stringToWriteBuffer, converter->sharedData->staticData->name);

      /*Hides the fallback to the internal name from the user */
      if (*err == U_MISSING_RESOURCE_ERROR)
        *err = U_ZERO_ERROR;
    }

  /*At this point we have a displayName and its length
   *we want to see if it fits in the user provided params
   */

  if (stringToWriteLength <= displayNameCapacity)
    {
      /*it fits */
      u_strcpy (displayName, stringToWrite);
    }
  else
    {
      /*it doesn't fit */
      *err = U_BUFFER_OVERFLOW_ERROR;

      u_strncpy (displayName, stringToWrite, displayNameCapacity);
      /*Zero terminates the string */
      if (displayNameCapacity > 0)
        displayName[displayNameCapacity - 1] = 0x0000;
    }

  /*if the user provided us with a with an outputLength
   *buffer we'll store in it the theoretical size of the
   *displayString
   */
  return stringToWriteLength;
}


/*resets the internal states of a converter
 *goal : have the same behaviour than a freshly created converter
 */
void  ucnv_reset (UConverter * converter)
{
  /* first, notify the callback functions that the converter is reset */
  UConverterToUnicodeArgs toUArgs = {
    sizeof(UConverterToUnicodeArgs),
    TRUE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
  };
  UConverterFromUnicodeArgs fromUArgs = {
    sizeof(UConverterFromUnicodeArgs),
    TRUE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
  };
  UErrorCode errorCode;

  if(converter == NULL) {
    return;
  }
  toUArgs.converter = fromUArgs.converter = converter;
  errorCode = U_ZERO_ERROR;
  converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_RESET, &errorCode);
  errorCode = U_ZERO_ERROR;
  converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_RESET, &errorCode);

  /* now reset the converter itself */
  converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus;
  converter->fromUnicodeStatus = 0;
  converter->UCharErrorBufferLength = 0;
  converter->charErrorBufferLength = 0;
  if (converter->sharedData->impl->reset != NULL) {
    /* call the custom reset function */
    converter->sharedData->impl->reset(converter);
  } else {
    converter->mode = UCNV_SI;
  }
}

void ucnv_resetToUnicode(UConverter *converter)
{
#if 0
  UConverterToUnicodeArgs toUArgs = {
    sizeof(UConverterToUnicodeArgs),
    TRUE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
  };
  UErrorCode errorCode = U_ZERO_ERROR;

  if(converter == NULL) {
    return;
  }

  toUArgs.converter = converter;
  converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_RESET, &errorCode);

  /* now reset the converter itself */
  converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus;
  converter->fromUnicodeStatus = 0;
  converter->UCharErrorBufferLength = 0;
  converter->charErrorBufferLength = 0;

  /* Todo: Needs rest of implementation */
#endif
}

void ucnv_resetFromUnicode(UConverter *converter)
{
#if 0
  UConverterFromUnicodeArgs fromUArgs = {
    sizeof(UConverterFromUnicodeArgs),
    TRUE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
  };
  UErrorCode errorCode = U_ZERO_ERROR;

  if(converter == NULL) {
    return;
  }

  fromUArgs.converter = converter;
  converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_RESET, &errorCode);

  /* now reset the converter itself */
  converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus;
  converter->fromUnicodeStatus = 0;
  converter->UCharErrorBufferLength = 0;
  converter->charErrorBufferLength = 0;

  /* Todo: Needs rest of implementation */
#endif
}

int8_t  ucnv_getMaxCharSize (const UConverter * converter)
{
  return converter->sharedData->staticData->maxBytesPerChar;
}


int8_t  ucnv_getMinCharSize (const UConverter * converter)
{
  return converter->sharedData->staticData->minBytesPerChar;
}

const char*  ucnv_getName (const UConverter * converter, UErrorCode * err)
     
{
  if (U_FAILURE (*err))
    return NULL;
  if(converter->sharedData->impl->getName){
      const char* temp= converter->sharedData->impl->getName(converter);
      if(temp)
          return temp;
  }
  return converter->sharedData->staticData->name;
}

int32_t  ucnv_getCCSID (const UConverter * converter,
                        UErrorCode * err)
{
  if (U_FAILURE (*err))
    return -1;

  return converter->sharedData->staticData->codepage;
}


UConverterPlatform  ucnv_getPlatform (const UConverter * converter,
                                      UErrorCode * err)
{
  if (U_FAILURE (*err))
    return UCNV_UNKNOWN;
  
  return (UConverterPlatform)converter->sharedData->staticData->platform;
}

U_CAPI void U_EXPORT2
    ucnv_getToUCallBack (const UConverter * converter,
                         UConverterToUCallback *action,
                         void **context)
{
  *action = converter->fromCharErrorBehaviour;
  *context = converter->toUContext;
}

U_CAPI void U_EXPORT2
    ucnv_getFromUCallBack (const UConverter * converter,
                           UConverterFromUCallback *action,
                           void **context)
{
  *action = converter->fromUCharErrorBehaviour;
  *context = converter->fromUContext;
}

void   ucnv_setToUCallBack (UConverter * converter,
                            UConverterToUCallback newAction,
                            void* newContext,
                            UConverterToUCallback *oldAction,
                            void** oldContext,
                            UErrorCode * err)
{
  if (U_FAILURE (*err))
    return;
  *oldAction = converter->fromCharErrorBehaviour;
  converter->fromCharErrorBehaviour = newAction;
  *oldContext = converter->toUContext;
  converter->toUContext = newContext;
}

void ucnv_setFromUCallBack (UConverter * converter,
                            UConverterFromUCallback newAction,
                            void* newContext,
                            UConverterFromUCallback *oldAction,
                            void** oldContext,
                            UErrorCode * err)
{
  
  if (U_FAILURE (*err))
    return;
  *oldAction = converter->fromUCharErrorBehaviour;
  converter->fromUCharErrorBehaviour = newAction;
  *oldContext = converter->fromUContext;
  converter->fromUContext = newContext;
}

void ucnv_fromUnicode (UConverter * _this,
                       char **target,
                       const char *targetLimit,
                       const UChar ** source,
                       const UChar * sourceLimit,
                       int32_t* offsets,
                       UBool flush,
                       UErrorCode * err)
{
  UConverterFromUnicodeArgs args;
  /*
   * Check parameters in for all conversions
   */
  if (U_FAILURE (*err))   return;
  if ((_this == NULL) || ((char *) targetLimit < *target) || (sourceLimit < *source))
    {
      *err = U_ILLEGAL_ARGUMENT_ERROR;
      return;
    }
  

  /*
   * Deal with stored carry over data.  This is done in the common location
   * to avoid doing it for each conversion.
   */
  if (_this->charErrorBufferLength > 0)
    {
      int32_t myTargetIndex = 0;

      flushInternalCharBuffer (_this, 
                               (char *) *target,
                               &myTargetIndex,
                               targetLimit - *target,
                               offsets?&offsets:NULL,
                               err);
      *target += myTargetIndex;
      if (U_FAILURE (*err)) return;
    }

  args.converter = _this;
  args.flush = flush;
  args.offsets = offsets;
  args.source = *source;
  args.sourceLimit = sourceLimit;
  args.target = *target;
  args.targetLimit = targetLimit;
  args.size = sizeof(args);
  if (offsets) {
    if (_this->sharedData->impl->fromUnicodeWithOffsets != NULL) {
       _this->sharedData->impl->fromUnicodeWithOffsets(&args, err);
       *source = args.source;
       *target = args.target;
       return;
    } else {
      /* all code points are of the same length */
      int32_t targetSize = targetLimit - *target;
      int32_t i, bytesPerChar = _this->sharedData->staticData->maxBytesPerChar;

      if(bytesPerChar == 1) {
        for (i=0; i<targetSize; i++) {
          args.offsets[i] = i;
        }
      } else if(bytesPerChar == 2) {
        for (i=0; i<targetSize; i++) {
          args.offsets[i] = i>>1;
        }
      } else {
        int32_t j = 0, k = bytesPerChar;

        for (i=0; i<targetSize; i++) {
          /* offsets[i] = i/bytesPerChar; -- without division */
          args.offsets[i] = j;
          if(--k == 0) {
            k = bytesPerChar;
            ++j;
          }
        }
      }
    }
  }

  /*calls the specific conversion routines */
  _this->sharedData->impl->fromUnicode(&args, err);
  *source = args.source;
  *target = args.target;
  return;
}



void   ucnv_toUnicode (UConverter * _this,
                       UChar ** target,
                       const UChar * targetLimit,
                       const char **source,
                       const char *sourceLimit,
                       int32_t* offsets,
                       UBool flush,
                       UErrorCode * err)
{
  UConverterToUnicodeArgs args;
  /*
   * Check parameters in for all conversions
   */
  if (U_FAILURE (*err))   return;
  if ((_this == NULL) || ((UChar *) targetLimit < *target) || (sourceLimit < *source))
    {
      *err = U_ILLEGAL_ARGUMENT_ERROR;
      return;
    }

  /*
   * Deal with stored carry over data.  This is done in the common location
   * to avoid doing it for each conversion.
   */
  if (_this->UCharErrorBufferLength > 0)
    {
      int32_t myTargetIndex = 0;

      flushInternalUnicodeBuffer (_this, 
                                  *target,
                                  &myTargetIndex,
                                  targetLimit - *target,
                                  offsets?&offsets:NULL,
                                  err);
      *target += myTargetIndex;
      if (U_FAILURE (*err))
        return;
    }

  args.converter = _this;
  args.flush = flush;
  args.offsets = offsets;
  args.source = (char *) *source;
  args.sourceLimit = sourceLimit;
  args.target =  *target;
  args.targetLimit = targetLimit;
  args.size = sizeof(args);
  if (offsets) {
    if (_this->sharedData->impl->toUnicodeWithOffsets != NULL) {
      _this->sharedData->impl->toUnicodeWithOffsets(&args, err);
      *source = args.source;
      *target = args.target;
      return;
    } else {
      /* all code points are of the same length */
      int32_t targetSize = targetLimit - *target;
      int32_t i, bytesPerChar = _this->sharedData->staticData->maxBytesPerChar;

      if(bytesPerChar == 1) {
        for (i=0; i<targetSize; i++) {
          offsets[i] = i;
        }
      } else if(bytesPerChar == 2) {
        for (i=0; i<targetSize; i++) {
          offsets[i] = i<<1;
        }
      } else {
        for (i=0; i<targetSize; i++) {
          offsets[i] = i*bytesPerChar;
        }
      }
    }
  }

  /*calls the specific conversion routines */
  _this->sharedData->impl->toUnicode(&args, err); 

  *source = args.source;
  *target = args.target;
  return;
}

int32_t   ucnv_fromUChars (const UConverter * converter,
                           char *target,
                           int32_t targetSize,
                           const UChar * source,
                           int32_t sourceSize,
                           UErrorCode * err)
{
  const UChar *mySource_limit;
  int32_t mySourceLength = sourceSize;
  UConverter myConverter;
  char *myTarget_limit;
  int32_t targetCapacity = 0;
  UConverterFromUnicodeArgs args;

  if (U_FAILURE (*err))
    return 0;

  if ((converter == NULL) || (targetSize < 0))
    {
      *err = U_ILLEGAL_ARGUMENT_ERROR;
      return 0;
    }

  /*makes a local copy of the UConverter */
  myConverter = *converter;


  /*Removes all state info on the UConverter */
  ucnv_reset (&myConverter);

  /*if the source is empty we return immediately */
  if (sourceSize == -1) {
    mySourceLength = u_strlen (source);
  } 
  if (mySourceLength == 0)
    {
      /*for consistency we still need to
       *store 0 in the targetCapacity
       *if the user requires it
       */
      return 0;
    }

  mySource_limit = source + mySourceLength;
  myTarget_limit = target + targetSize;

  /* Pin the limit to U_MAX_PTR.  NULL check is for AS/400. */
  if((myTarget_limit < target) || (myTarget_limit == NULL)) {
    myTarget_limit = (char *)U_MAX_PTR;
  }

  args.converter = &myConverter;
  args.flush = TRUE;
  args.offsets = NULL;
  args.source = source;
  args.sourceLimit = mySource_limit;
  args.target = target;
  args.targetLimit = myTarget_limit;
  args.size = sizeof(args);
  if (targetSize > 0)
    {
      /*calls the specific conversion routines */
      args.converter->sharedData->impl->fromUnicode(&args, err); 
  
      targetCapacity = args.target - target;
    }

  /*Updates targetCapacity to contain the number of bytes written to target */

  /* If the output buffer is exhausted, we need to stop writing
   * to it but continue the conversion in order to store in targetSize
   * the number of bytes that was required*/
  if (*err == U_BUFFER_OVERFLOW_ERROR || targetSize == 0)
    {
      char target2[CHUNK_SIZE];
      const char *target2_limit = target2 + CHUNK_SIZE;

      /*We use a stack allocated buffer around which we loop
       *(in case the output is greater than CHUNK_SIZE)
       */
      do
        {
          *err = U_ZERO_ERROR;
          args.target = target2;
          args.targetLimit = target2_limit;
          args.converter->sharedData->impl->fromUnicode(&args, err); 
          /*updates the output parameter to contain the number of char required */
          targetCapacity += (args.target - target2);
        } while (*err == U_BUFFER_OVERFLOW_ERROR);
      /*We will set the error code to U_BUFFER_OVERFLOW_ERROR only if
       *nothing graver happened in the previous loop*/
      if (U_SUCCESS (*err))
        *err = U_BUFFER_OVERFLOW_ERROR;
    }

  return targetCapacity;
}

int32_t ucnv_toUChars (const UConverter * converter,
                       UChar * target,
                       int32_t targetSize,
                       const char *source,
                       int32_t sourceSize,
                       UErrorCode * err)
{
  const char *mySource_limit = source + sourceSize;
  UConverter myConverter;
  UChar *myTarget_limit;
  int32_t targetCapacity;
  UConverterToUnicodeArgs args;

  if (U_FAILURE (*err))
    return 0;

  if ((converter == NULL) || (targetSize < 0) || (sourceSize < 0))
    {
      *err = U_ILLEGAL_ARGUMENT_ERROR;
      return 0;
    }
  /*Means there is no work to be done */
  if (sourceSize == 0)
    {
      /*for consistency we still need to
       *store 0 in the targetCapacity
       *if the user requires it
       */
      if (targetSize >= 1)
        {
          target[0] = 0x0000;
          return 1;
        }
      else
        return 0;
    }

  /*makes a local copy of the UConverter */
  myConverter = *converter;

  /*Removes all state info on the UConverter */
  ucnv_reset (&myConverter);

  args.converter = &myConverter;
  args.flush = TRUE;
  args.offsets = NULL;
  args.source = source;
  args.sourceLimit = mySource_limit;
  args.target = target;
  args.size = sizeof(args);
  if (targetSize > 0)
  {
      myTarget_limit = target + targetSize - 1;

      /* Pin the limit to U_MAX_PTR.  NULL check is for AS/400. */
      if ((myTarget_limit == NULL) || (myTarget_limit < target)) {
          myTarget_limit = ((UChar*)U_MAX_PTR) - 1; 
      }

      /*Not in pure pre-flight mode */

      args.targetLimit = myTarget_limit;
      args.converter->sharedData->impl->toUnicode(&args, err); 

      /*Null terminates the string */
      *(args.target) = 0x0000;
    }


  /*Rigs targetCapacity to have at least one cell for zero termination */
  /*Updates targetCapacity to contain the number of bytes written to target */
  targetCapacity = 1;
  targetCapacity += args.target - target;

  /* If the output buffer is exhausted, we need to stop writing
   * to it but if the input buffer is not exhausted,
   * we need to continue the conversion in order to store in targetSize
   * the number of bytes that was required
   */
  if (*err == U_BUFFER_OVERFLOW_ERROR || targetSize == 0)
    {
      UChar target2[CHUNK_SIZE];
      const UChar *target2_limit = target2 + CHUNK_SIZE;

      /*We use a stack allocated buffer around which we loop
         (in case the output is greater than CHUNK_SIZE) */
      do
        {
          *err = U_ZERO_ERROR;
          args.target = target2;
          args.targetLimit = target2_limit;
          args.converter->sharedData->impl->toUnicode(&args, err); 
          /*updates the output parameter to contain the number of char required */
          targetCapacity += args.target - target2;
        } while (*err == U_BUFFER_OVERFLOW_ERROR);

      if (U_SUCCESS (*err))
        *err = U_BUFFER_OVERFLOW_ERROR;
    }

  return targetCapacity;
}

UChar32 ucnv_getNextUChar(UConverter * converter,
                          const char **source,
                          const char *sourceLimit,
                          UErrorCode * err)
{
  UConverterToUnicodeArgs args;
  UChar32 ch;

  if(err == NULL || U_FAILURE(*err)) {
      return 0xffff;
  }

  /* In case internal data had been stored
   * we return the first UChar32 in the internal buffer,
   * and update the internal state accordingly
   */
  if (converter->UCharErrorBufferLength > 0)
    {
      UTextOffset i = 0;
      UChar32 myUChar;
      UTF_NEXT_CHAR(converter->UCharErrorBuffer, i, sizeof(converter->UCharErrorBuffer), myUChar);
      /*In this memmove we update the internal buffer by
       *popping the first character.
         *Note that in the call itself we decrement
         *UCharErrorBufferLength
       */
      uprv_memmove (converter->UCharErrorBuffer,
                   converter->UCharErrorBuffer + i,
                   (converter->UCharErrorBufferLength - i) * sizeof (UChar));
      converter->UCharErrorBufferLength -= (int8_t)i;
      return myUChar;
    }
  /*calls the specific conversion routines */
  /*as dictated in a code review, avoids a switch statement */
  args.converter = converter;
  args.flush = TRUE;
  args.offsets = NULL;
  args.source = *source;
  args.sourceLimit = sourceLimit;
  args.target = NULL;
  args.targetLimit = NULL;
  args.size = sizeof(args);
  ch = converter->sharedData->impl->getNextUChar(&args, err);
  *source = args.source;
  return ch;
}



/**************************
* Will convert a sequence of bytes from one codepage to another.
* @param toConverterName: The name of the converter that will be used to encode the output buffer
* @param fromConverterName: The name of the converter that will be used to decode the input buffer
* @param target: Pointer to the output buffer* written
* @param targetLength: on input contains the capacity of target, on output the number of bytes copied to target
* @param source: Pointer to the input buffer
* @param sourceLength: on input contains the capacity of source, on output the number of bytes processed in "source"
* @param internal: used internally to store store state data across calls
* @param err: fills in an error status
*/
static void 
T_UConverter_fromCodepageToCodepage (UConverter * outConverter,
                                     UConverter * inConverter,
                                     char **target,
                                     const char *targetLimit,
                                     const char **source,
                                     const char *sourceLimit,
                                     int32_t* offsets,
                                     UBool flush,
                                     UErrorCode * err)
{

  UChar out_chunk[CHUNK_SIZE];
  const UChar *out_chunk_limit = out_chunk + CHUNK_SIZE;
  UChar *out_chunk_alias;
  UChar const *out_chunk_alias2;


  if (U_FAILURE (*err))    return;


  /*loops until the input buffer is completely consumed
   *or if an error has be encountered
   *first we convert from inConverter codepage to Unicode
   *then from Unicode to outConverter codepage
   */
  while ((*source != sourceLimit) && U_SUCCESS (*err))
    {
      out_chunk_alias = out_chunk;
      ucnv_toUnicode (inConverter,
                      &out_chunk_alias,
                      out_chunk_limit,
                      source,
                      sourceLimit,
                      NULL,
                      flush,
                      err);

      /*U_BUFFER_OVERFLOW_ERROR means that the output "CHUNK" is full
       *we will require at least another loop (it's a recoverable error)
       */
      if (U_SUCCESS (*err) || (*err == U_BUFFER_OVERFLOW_ERROR))
        {
          *err = U_ZERO_ERROR;
          out_chunk_alias2 = out_chunk;

          while ((out_chunk_alias2 != out_chunk_alias) && U_SUCCESS (*err))
            {
              ucnv_fromUnicode (outConverter,
                                target,
                                targetLimit,
                                &out_chunk_alias2,
                                out_chunk_alias,
                                NULL,
                                TRUE,
                                err);
            }
        }
      else
        break;
    }

  return;
}

int32_t  ucnv_convert(const char *toConverterName,
                      const char *fromConverterName,
                      char *target,
                      int32_t targetSize,
                      const char *source,
                      int32_t sourceSize,
                      UErrorCode * err)
{
  const char *mySource = source;
  const char *mySource_limit = source + sourceSize;
  UConverter *inConverter;
  UConverter *outConverter;
  char *myTarget = target;
  int32_t targetCapacity = 0;

  if (U_FAILURE (*err))
    return 0;

  if ((targetSize < 0) || (sourceSize < 0))
    {
      *err = U_ILLEGAL_ARGUMENT_ERROR;
      return 0;
    }

  /*if there is no input data, we're done */
  if (sourceSize == 0)
    {
      /*in case the caller passed an output ptr
       *we update it
       */
      return 0;
    }

  /*create the converters */
  inConverter = ucnv_open (fromConverterName, err);
  if (U_FAILURE (*err)) return 0;
  outConverter = ucnv_open (toConverterName, err);
  if (U_FAILURE (*err))
    {
      ucnv_close (inConverter);
      return 0;
    }


  if (targetSize > 0)
    {
      T_UConverter_fromCodepageToCodepage (outConverter,
                                           inConverter,
                                           &myTarget,
                                           target + targetSize,
                                           &mySource,
                                           mySource_limit,
                                           NULL,
                                           TRUE,
                                           err);
      /*Updates targetCapacity to contain the number of bytes written to target */
      targetCapacity = myTarget - target;
    }

  /* If the output buffer is exhausted (or we are "pre-flighting"), we need to stop writing
   * to it but continue the conversion in order to store in targetSize
   * the number of bytes that was required*/
  if (*err == U_BUFFER_OVERFLOW_ERROR || targetSize == 0)
    {
      char target2[CHUNK_SIZE];
      char *target2_alias = target2;
      const char *target2_limit = target2 + CHUNK_SIZE;

      /*We use a stack allocated buffer around which we loop
       *(in case the output is greater than CHUNK_SIZE)
       */

      do
        {
          *err = U_ZERO_ERROR;
          target2_alias = target2;
          T_UConverter_fromCodepageToCodepage (outConverter,
                                               inConverter,
                                               &target2_alias,
                                               target2_limit,
                                               &mySource,
                                               mySource_limit,
                                               NULL,
                                               TRUE,
                                               err);

          /*updates the output parameter to contain the number of char required */
          targetCapacity += (target2_alias - target2);
    } while (*err == U_BUFFER_OVERFLOW_ERROR);

      /*We will set the error code to U_BUFFER_OVERFLOW_ERROR only if
       *nothing graver happened in the previous loop*/
      if (U_SUCCESS (*err))
        *err = U_BUFFER_OVERFLOW_ERROR;
    }

  ucnv_close (inConverter);
  ucnv_close (outConverter);

  return targetCapacity;
}

UConverterType ucnv_getType(const UConverter* converter)
{
  return (UConverterType)converter->sharedData->staticData->conversionType;
}

void ucnv_getStarters(const UConverter* converter, 
                      UBool starters[256],
                      UErrorCode* err)
{
    if (err == NULL || U_FAILURE(*err)) {
        return;
    }

    if(converter->sharedData->impl->getStarters != NULL) {
        converter->sharedData->impl->getStarters(converter, starters, err);
    } else {
        *err = U_ILLEGAL_ARGUMENT_ERROR;
    }
}

static int32_t ucnv_getAmbiguousCCSID(const UConverter *cnv)
{
    UErrorCode status = U_ZERO_ERROR;
    int32_t i = 0;
    int32_t ccsid = 0;
    if (cnv == NULL) 
    {
        return -1;
    }
    ccsid = ucnv_getCCSID(cnv, &status);
    if (U_FAILURE(status)) 
    {
        return -1;
    }
    for (i = 0; i < UCNV_MAX_AMBIGUOUSCCSIDS; i++) {
        if (ccsid == UCNV_AMBIGUOUSCONVERTERS[i].ccsid) 
        {
            return i;
        }
    }
    return -1;
}

void ucnv_fixFileSeparator(const UConverter *cnv, 
                           UChar* source, 
                           int32_t sourceLength)
{
    int32_t i = 0;
    int32_t offset = 0;
    if ((source == NULL) || (cnv == NULL))
    {
        return;
    }
    if ((offset = ucnv_getAmbiguousCCSID(cnv)) != -1)
    {
        for (i = 0; i < sourceLength; i++) 
        {
            if (source[i] == UCNV_AMBIGUOUSCONVERTERS[offset].mismapped)
            {
                source[i] = UCNV_AMBIGUOUSCONVERTERS[offset].replacement;
            }
        }
    }
}

UBool ucnv_isAmbiguous(const UConverter *cnv)
{
    return (UBool)(ucnv_getAmbiguousCCSID(cnv) == -1 ? FALSE : TRUE);
}

void ucnv_setFallback(UConverter *cnv, UBool usesFallback)
{
    cnv->useFallback = usesFallback;
}

UBool ucnv_usesFallback(const UConverter *cnv)
{
    return cnv->useFallback;
}

void 
ucnv_getInvalidChars (const UConverter * converter,
                      char *errBytes,
                      int8_t * len,
                      UErrorCode * err)
{
    if (err == NULL || U_FAILURE(*err))
    {
        return;
    }
    if (len == NULL || errBytes == NULL || converter == NULL)
    {
        *err = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    if (*len < converter->invalidCharLength)
    {
        *err = U_INDEX_OUTOFBOUNDS_ERROR;
        return;
    }
    if ((*len = converter->invalidCharLength) > 0)
    {
        uprv_memcpy (errBytes, converter->invalidCharBuffer, *len);
    }
}

void 
ucnv_getInvalidUChars (const UConverter * converter,
                       UChar *errChars,
                       int8_t * len,
                       UErrorCode * err)
{
    if (err == NULL || U_FAILURE(*err))
    {
        return;
    }
    if (len == NULL || errChars == NULL || converter == NULL)
    {
        *err = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    if (*len < converter->invalidUCharLength)
    {
        *err = U_INDEX_OUTOFBOUNDS_ERROR;
        return;
    }
    if ((*len = converter->invalidUCharLength) > 0)
    {
        uprv_memcpy (errChars, converter->invalidUCharBuffer, sizeof(UChar) * (*len));
    }
}

/*
 * Hey, Emacs, please set the following:
 *
 * Local Variables:
 * indent-tabs-mode: nil
 * End:
 *
 */

