/*
*******************************************************************************
*
*   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.
*/
#include "umutex.h"
#include "unicode/ures.h"
#include "uhash.h"
#include "ucmp16.h"
#include "ucmp8.h"
#include "unicode/ucnv_bld.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"

#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)
{
  if (converter == NULL)
    return;

  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++;

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

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)
{
  converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus;
  converter->fromUnicodeStatus = 0;
  converter->UCharErrorBufferLength = 0;
  converter->charErrorBufferLength = 0;
  if (converter->sharedData->impl->reset != NULL) {
    converter->sharedData->impl->reset(converter);
  } else {
    converter->mode = UCNV_SI;
  }

  return;
}

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;

  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 converter->sharedData->staticData->platform;
}

UConverterToUCallback  ucnv_getToUCallBack (const UConverter * converter)
{
  return converter->fromCharErrorBehaviour;
}

UConverterFromUCallback  ucnv_getFromUCallBack (const UConverter * converter)
{
  return converter->fromUCharErrorBehaviour;
}

UConverterToUCallback   ucnv_setToUCallBack (UConverter * converter,
					UConverterToUCallback action,
					UErrorCode * err)
{
  UConverterToUCallback myReturn = NULL;

  if (U_FAILURE (*err))
    return NULL;
  myReturn = converter->fromCharErrorBehaviour;
  converter->fromCharErrorBehaviour = action;

  return myReturn;
}

UConverterFromUCallback   ucnv_setFromUCallBack (UConverter * converter,
					    UConverterFromUCallback action,
					    UErrorCode * err)
{
  UConverterFromUCallback myReturn = NULL;
  
  if (U_FAILURE (*err))
    return NULL;
  myReturn = converter->fromUCharErrorBehaviour;
  converter->fromUCharErrorBehaviour = action;

  return myReturn;
}
void   ucnv_fromUnicode (UConverter * _this,
			 char **target,
			 const char *targetLimit,
			 const UChar ** source,
			 const UChar * sourceLimit,
			 int32_t* offsets,
			 UBool flush,
			 UErrorCode * err)
{
  /*
   * 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;
    }

  if (offsets) {
    if (_this->sharedData->impl->fromUnicodeWithOffsets != NULL) {
	   _this->sharedData->impl->fromUnicodeWithOffsets(_this,
								   target,
								   targetLimit,
								   source,
								   sourceLimit,
								   offsets,
								   flush,
								   err);
       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 {
        int32_t j = 0, k = bytesPerChar;

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

  /*calls the specific conversion routines */
  _this->sharedData->impl->fromUnicode(_this,
					   target,
					   targetLimit,
					   source,
					   sourceLimit,
					   offsets,
					   flush,
					   err);
  
  return;
}



void   ucnv_toUnicode (UConverter * _this,
		       UChar ** target,
		       const UChar * targetLimit,
		       const char **source,
		       const char *sourceLimit,
		       int32_t* offsets,
		       UBool flush,
		       UErrorCode * err)
{
  /*
   * 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;
    }

  if (offsets) {
    if (_this->sharedData->impl->toUnicodeWithOffsets != NULL) {
	  _this->sharedData->impl->toUnicodeWithOffsets(_this,
								target,
								targetLimit,
								source,
								sourceLimit,
								offsets,
								flush,
								err);
	  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(_this,
					  target,
					  targetLimit,
					  source,
					  sourceLimit,
					  offsets,
					  flush,
					  err);
  
  
  return;
}

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

  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 = mySource + 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;
  }

  if (targetSize > 0)
    {
      ucnv_fromUnicode (&myConverter,
			&myTarget,
			myTarget_limit,
			&mySource,
			mySource_limit,
			NULL,
			TRUE,
			err);
      targetCapacity = myTarget - target;
    }

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

  if (targetSize == 0)
    {
      *err = U_INDEX_OUTOFBOUNDS_ERROR;
    }

  /* 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_INDEX_OUTOFBOUNDS_ERROR)
    {
      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)
       */

      while (*err == U_INDEX_OUTOFBOUNDS_ERROR)
	{
	  *err = U_ZERO_ERROR;
	  target2_alias = target2;
	  ucnv_fromUnicode (&myConverter,
			    &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) + 1;
	}
      /*We will set the erro code to U_BUFFER_OVERFLOW_ERROR only if
       *nothing graver happened in the previous loop*/
      (targetCapacity)--;
      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 = source;
  const char *mySource_limit = source + sourceSize;
  UConverter myConverter;
  UChar *myTarget = target;
  UChar *myTarget_limit;
  int32_t targetCapacity;

  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);

  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 */

      ucnv_toUnicode (&myConverter,
		      &myTarget,
		      myTarget_limit,	  /*Save a spot for the Null terminator */
		      &mySource,
		      mySource_limit,
		      NULL,
		      TRUE,
		      err);

      /*Null terminates the string */
      *(myTarget) = 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 += myTarget - target;
  if (targetSize == 0)
    {
      *err = U_INDEX_OUTOFBOUNDS_ERROR;
    }
  /* 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_INDEX_OUTOFBOUNDS_ERROR)
    {
      UChar target2[CHUNK_SIZE];
      UChar *target2_alias = target2;
      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) */

      while (*err == U_INDEX_OUTOFBOUNDS_ERROR)
	{
	  *err = U_ZERO_ERROR;
	  target2_alias = target2;
	  ucnv_toUnicode (&myConverter,
			  &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 + 1;
	}
      (targetCapacity)--;	/*adjust for last one */
      if (U_SUCCESS (*err))
	*err = U_BUFFER_OVERFLOW_ERROR;
    }

  return targetCapacity;
}

UChar32 ucnv_getNextUChar (UConverter * converter,
			 const char **source,
			 const char *sourceLimit,
			 UErrorCode * err)
{
  /* 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 */
  return converter->sharedData->impl->getNextUChar(converter,
										  source,
										  sourceLimit,
										  err);
}



/**************************
* 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
*/
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_INDEX_OUTOFBOUNDS_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_INDEX_OUTOFBOUNDS_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 (targetSize == 0)
    {
      *err = U_INDEX_OUTOFBOUNDS_ERROR;
    }

  /* 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_INDEX_OUTOFBOUNDS_ERROR)
    {
      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)
       */

      while (*err == U_INDEX_OUTOFBOUNDS_ERROR)
	{
	  *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) + 1;
	}
      /*We will set the erro code to U_BUFFER_OVERFLOW_ERROR only if
       *nothing graver happened in the previous loop*/
      (targetCapacity)--;
      if (U_SUCCESS (*err))
	*err = U_BUFFER_OVERFLOW_ERROR;
    }

  ucnv_close (inConverter);
  ucnv_close (outConverter);

  return targetCapacity;
}

UConverterType ucnv_getType(const UConverter* converter)
{
  return 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;
    }
}

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