/*  
**********************************************************************
*   Copyright (C) 2000, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   file name:  ucnvsbcs.cpp
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2000feb03
*   created by: Markus W. Scherer
*
*   Change history:
*
*   05/09/00    helena      Added implementation to handle fallback mappings.
*   06/20/2000  helena      OS/400 port changes; mostly typecast.
*   06/29/2000  helena      Major rewrite of the callback APIs.
*/

#include "unicode/utypes.h"
#include "cmemory.h"
#include "ucmp16.h"
#include "ucmp8.h"
#include "unicode/ucnv_err.h"
#include "ucnv_bld.h"
#include "unicode/ucnv.h"
#include "ucnv_cnv.h"

/* SBCS --------------------------------------------------------------------- */

static void
_SBCSLoad(UConverterSharedData *sharedData, const uint8_t *raw, UErrorCode *pErrorCode) {
    const uint8_t *oldraw = raw;
    sharedData->table->sbcs.toUnicode = (UChar *)raw;
    raw += sizeof(uint16_t)*256; oldraw = raw;
    ucmp8_initFromData(&sharedData->table->sbcs.fromUnicode, &raw, pErrorCode);
    if (sharedData->staticData->hasFromUnicodeFallback == TRUE)
    {
        if(((raw-oldraw)&3)!=0) {
            raw+=4-((raw-oldraw)&3);    /* pad to 4 */
        }
        ucmp8_initFromData(&sharedData->table->sbcs.fromUnicodeFallback, &raw, pErrorCode);    
    }
    if (sharedData->staticData->hasToUnicodeFallback == TRUE)
    {
        if(((raw-oldraw)&3)!=0) {
            raw+=4-((raw-oldraw)&3);    /* pad to 4 */
        }
        sharedData->table->sbcs.toUnicodeFallback = (UChar *)raw;
    }
}

static void
_SBCSUnload(UConverterSharedData *sharedData) {
    ucmp8_close (&sharedData->table->sbcs.fromUnicode);
    if (sharedData->staticData->hasFromUnicodeFallback == TRUE)
        ucmp8_close (&sharedData->table->sbcs.fromUnicodeFallback);
}

U_CFUNC void T_UConverter_toUnicode_SBCS (UConverterToUnicodeArgs * args,
                                  UErrorCode * err)
{
  char *mySource = (char *) args->source;
  UChar *myTarget = args->target;
  int32_t mySourceIndex = 0;
  int32_t myTargetIndex = 0;
  int32_t targetLength = args->targetLimit - myTarget;
  int32_t sourceLength = args->sourceLimit - (char *) mySource;
  UChar *myToUnicode = NULL, *myToUnicodeFallback = NULL;
  UChar targetUniChar = 0x0000;
  
  myToUnicode = args->converter->sharedData->table->sbcs.toUnicode;
  myToUnicodeFallback = args->converter->sharedData->table->sbcs.toUnicodeFallback;
  while (mySourceIndex < sourceLength)
    {

      /*writing the UniChar to the output stream */
      if (myTargetIndex < targetLength)
        {
          /*gets the corresponding UniChar */
          targetUniChar = myToUnicode[(unsigned char) mySource[mySourceIndex++]];

          if (targetUniChar < 0xfffe)
            {
              /* writes the UniChar to the output stream */
              myTarget[myTargetIndex++] = targetUniChar;
            }
          else
            {
              if (UCNV_TO_U_USE_FALLBACK(args->converter) &&
                  (args->converter->sharedData->staticData->hasToUnicodeFallback == TRUE))
              {
                  /* Look up in the fallback table first */
                  UChar fallbackUniChar = myToUnicodeFallback[(unsigned char) mySource[mySourceIndex-1]];
                  if (fallbackUniChar < 0xfffe)
                  {
                      myTarget[myTargetIndex++] = targetUniChar = fallbackUniChar;
                  }
              }
              if (targetUniChar >= 0xfffe)
              {
                  const char *saveSource = args->source;
                  UChar *saveTarget = args->target;
                  int32_t *saveOffsets = args->offsets;
                  UConverterCallbackReason reason;

                  if (targetUniChar == 0xfffe)
                  {
                    reason = UCNV_UNASSIGNED;
                    *err = U_INVALID_CHAR_FOUND;
                  }
                  else
                  {
                    reason = UCNV_ILLEGAL;
                    *err = U_ILLEGAL_CHAR_FOUND;
                  }

                  args->converter->invalidCharBuffer[0] = (char) mySource[mySourceIndex - 1];
                  args->converter->invalidCharLength = 1;

                  args->target = myTarget + myTargetIndex;
                  args->source = mySource + mySourceIndex;

                  /* to do hsys: add more smarts to the codeUnits and length later */
                  ToU_CALLBACK_MACRO(args->converter->toUContext,
                                     args,
                                     args->converter->invalidCharBuffer,
                                     args->converter->invalidCharLength, 
                                     reason,
                                     err);
                  /* Hsys: calculate the source and target advancement */
                  args->source = saveSource;
                  args->target = saveTarget;
                  args->offsets = saveOffsets;
                  if (U_FAILURE (*err)) break;
                  args->converter->invalidCharLength = 0;
              }
            }
        }
      else
        {
          *err = U_BUFFER_OVERFLOW_ERROR;
          break;
        }
    }
  
  args->target += myTargetIndex;
  args->source += mySourceIndex;

  return;
}

U_CFUNC void T_UConverter_fromUnicode_SBCS (UConverterFromUnicodeArgs * args,
                                 UErrorCode * err)
{
  const UChar *mySource = args->source;
  unsigned char *myTarget = (unsigned char *) args->target;
  int32_t mySourceIndex = 0;
  int32_t myTargetIndex = 0;
  int32_t targetLength = args->targetLimit - (char *) myTarget;
  int32_t sourceLength = args->sourceLimit - mySource;
  CompactByteArray *myFromUnicode = NULL, *myFromUnicodeFallback = NULL;
  unsigned char targetChar = 0x00;
  UConverterCallbackReason reason;

  myFromUnicode = &args->converter->sharedData->table->sbcs.fromUnicode;
  myFromUnicodeFallback = &args->converter->sharedData->table->sbcs.fromUnicodeFallback;
  /*writing the char to the output stream */
  /* HSYS : to do : finish the combining of the surrogate characters later */
  /*
  if (args->converter->fromUSurrogateLead != 0 && UTF_IS_TRAIL(mySource[mySourceIndex]))
  {
  }
  */
  while (mySourceIndex < sourceLength)
    {
      targetChar = ucmp8_getu (myFromUnicode, mySource[mySourceIndex]);

      if (myTargetIndex < targetLength)
        {
          mySourceIndex++;
          if (targetChar != 0 || !mySource[mySourceIndex - 1])
            {
              /*writes the char to the output stream */
              myTarget[myTargetIndex++] = targetChar;
            }
          else if (UCNV_FROM_U_USE_FALLBACK(args->converter, mySource[mySourceIndex-1]) &&
                  (args->converter->sharedData->staticData->hasFromUnicodeFallback == TRUE))
          {
              /* Look up in the fallback table first */
              targetChar = ucmp8_getu (myFromUnicodeFallback, mySource[mySourceIndex-1]);
              if (targetChar != 0 || !mySource[mySourceIndex - 1])
                {
                  /*writes the char to the output stream */
                  myTarget[myTargetIndex++] = targetChar;
                }
          }
          if (targetChar == 0 && mySource[mySourceIndex-1] != 0)
          {
              *err = U_INVALID_CHAR_FOUND;
              reason = UCNV_UNASSIGNED;
              
              args->converter->invalidUCharBuffer[0] = (UChar)mySource[mySourceIndex - 1];
              args->converter->invalidUCharLength = 1;
              if (UTF_IS_LEAD(mySource[mySourceIndex-1]))
              {
                  /*if (mySource < args->sourceLimit)*/
                  if(mySourceIndex < sourceLength)
                  {
                      if (UTF_IS_TRAIL(mySource[mySourceIndex]))
                      {
                          args->converter->invalidUCharBuffer[1] = (UChar)mySource[mySourceIndex];
                          args->converter->invalidUCharLength++;
                          mySourceIndex++;
                      }
                      else 
                      {
                          reason = UCNV_ILLEGAL;
                      }                          
                  }
                  else if (args->flush == TRUE)
                  {
                      reason = UCNV_ILLEGAL;
                      *err = U_TRUNCATED_CHAR_FOUND;
                  } 
                  else 
                  {
                      args->converter->fromUSurrogateLead = args->converter->invalidUCharBuffer[0];
                      /* do not call the callback */
                  }
              }
              if (args->converter->fromUSurrogateLead == 0) 
              {
                  const UChar *saveSource = args->source;
                  char *saveTarget = args->target;
                  int32_t *saveOffsets = args->offsets;
                  args->target = (char *)myTarget+myTargetIndex;
                  args->source = mySource+mySourceIndex;
                  /* Needed explicit cast for myTarget on MVS to make compiler happy - JJD */
                  /* Check if we have encountered a surrogate pair.  If first UChar is lead byte
                   and second UChar is trail byte, it's a surrogate char.  If UChar is lead byte 
                   but second UChar is not trail byte, it's illegal sequence.  If neither, it's
                   plain unassigned code point.*/
                   FromU_CALLBACK_MACRO(args->converter->fromUContext,
                                         args,
                                         args->converter->invalidUCharBuffer,
                                         args->converter->invalidUCharLength,
                                         (UChar32) (args->converter->invalidUCharLength == 2 ? 
                                             UTF16_GET_PAIR_VALUE(args->converter->invalidUCharBuffer[0], 
                                                                  args->converter->invalidUCharBuffer[1]) 
                                                    : args->converter->invalidUCharBuffer[0]),
                                         reason,
                                         err);
                  args->source = saveSource;
                  args->target = saveTarget;
                  args->offsets = saveOffsets;
                  if (U_FAILURE (*err))
                    {
                      break;
                    }
                  args->converter->invalidUCharLength = 0;
              }
          }               
        }
      else
        {
          *err = U_BUFFER_OVERFLOW_ERROR;
          break;
        }

    }

  args->target += myTargetIndex;
  args->source += mySourceIndex;


  return;
}

U_CFUNC UChar32 T_UConverter_getNextUChar_SBCS(UConverterToUnicodeArgs* args,
                                               UErrorCode* err)
{
  UChar myUChar;
  
  if (U_FAILURE(*err)) return 0xffff;

  if (args->source+1 > args->sourceLimit) 
    {
      *err = U_INDEX_OUTOFBOUNDS_ERROR;
      return 0xffff;
    }
  
  /*Gets the corresponding codepoint*/
  myUChar = args->converter->sharedData->table->sbcs.toUnicode[(unsigned char)*(args->source++)];
  
  if (myUChar < 0xfffe) return myUChar;
  else
    {      
      UChar* myUCharPtr = &myUChar;
      UConverterCallbackReason reason;

      /* Do the fallback stuff */
      if (UCNV_TO_U_USE_FALLBACK(args->converter) &&
          (args->converter->sharedData->staticData->hasToUnicodeFallback == TRUE))
      {
          UChar fallbackUChar = args->converter->sharedData->table->sbcs.toUnicodeFallback[ (unsigned char)*(args->source-1)];
          if (fallbackUChar < 0xfffe) return fallbackUChar;
      }

      if (myUChar == 0xfffe)
      {
        reason = UCNV_UNASSIGNED;
        *err = U_INVALID_CHAR_FOUND;
      }
      else
      {
        reason = UCNV_ILLEGAL;
        *err = U_ILLEGAL_CHAR_FOUND;
      }

      /*Calls the ErrorFunctor */
      /*It's is very likely that the ErrorFunctor will write to the
       *internal buffers */
      args->target = myUCharPtr;
      args->targetLimit = myUCharPtr + 1;
      args->converter->fromCharErrorBehaviour(args->converter->toUContext,
                                    args,
                                    args->source - 1,
                                    1,
                                    reason,
                                    err);

      /*makes the internal caching transparent to the user*/
      if (*err == U_BUFFER_OVERFLOW_ERROR) *err = U_ZERO_ERROR;
      
      return myUChar;
    }
}

static const UConverterImpl _SBCSImpl={
    UCNV_SBCS,

    _SBCSLoad,
    _SBCSUnload,

    NULL,
    NULL,
    NULL,

    T_UConverter_toUnicode_SBCS,
    NULL,
    T_UConverter_fromUnicode_SBCS,
    NULL,
    T_UConverter_getNextUChar_SBCS,

    NULL,
    NULL
};


/* Static data is in tools/makeconv/ucnvstat.c for data-based
 * converters. Be sure to update it as well.
 */

const UConverterSharedData _SBCSData={
    sizeof(UConverterSharedData), 1,
    NULL, NULL, NULL, FALSE, &_SBCSImpl, 
    0
};

/* DBCS --------------------------------------------------------------------- */

U_CFUNC void
_DBCSLoad(UConverterSharedData *sharedData, const uint8_t *raw, UErrorCode *pErrorCode) {
    const uint8_t *oldraw = raw;
    ucmp16_initFromData(&sharedData->table->dbcs.toUnicode,&raw, pErrorCode);
    if(((raw-oldraw)&3)!=0) {
        raw+=4-((raw-oldraw)&3);    /* pad to 4 */
    }
    oldraw = raw;
    ucmp16_initFromData(&sharedData->table->dbcs.fromUnicode, &raw, pErrorCode);
    if (sharedData->staticData->hasFromUnicodeFallback == TRUE)
    {
        if(((raw-oldraw)&3)!=0) {
            raw+=4-((raw-oldraw)&3);    /* pad to 4 */
        }
        ucmp16_initFromData(&sharedData->table->dbcs.fromUnicodeFallback, &raw, pErrorCode);
        oldraw = raw;
    }
    if (sharedData->staticData->hasToUnicodeFallback == TRUE)
    {
        if(((raw-oldraw)&3)!=0) {
            raw+=4-((raw-oldraw)&3);    /* pad to 4 */
        }
        ucmp16_initFromData(&sharedData->table->dbcs.toUnicodeFallback, &raw, pErrorCode);
    }    
}

U_CFUNC void
_DBCSUnload(UConverterSharedData *sharedData) {
    ucmp16_close (&sharedData->table->dbcs.fromUnicode);
    ucmp16_close (&sharedData->table->dbcs.toUnicode);
    if (sharedData->staticData->hasFromUnicodeFallback == TRUE)
        ucmp16_close (&sharedData->table->dbcs.fromUnicodeFallback);
    if (sharedData->staticData->hasToUnicodeFallback == TRUE)
        ucmp16_close (&sharedData->table->dbcs.toUnicodeFallback);
}

U_CFUNC void   T_UConverter_toUnicode_DBCS (UConverterToUnicodeArgs * args,
                                    UErrorCode * err)
{
  const char *mySource = ( char *) args->source;
  UChar *myTarget = args->target;
  int32_t mySourceIndex = 0;
  int32_t myTargetIndex = 0;
  int32_t targetLength = args->targetLimit - myTarget;
  int32_t sourceLength = args->sourceLimit - (char *) mySource;
  CompactShortArray *myToUnicode = NULL, *myToUnicodeFallback = NULL;
  UChar targetUniChar = 0x0000;
  UChar mySourceChar = 0x0000;

  myToUnicode = &args->converter->sharedData->table->dbcs.toUnicode;
  myToUnicodeFallback = &args->converter->sharedData->table->dbcs.toUnicodeFallback;

  while (mySourceIndex < sourceLength)
    {
      if (myTargetIndex < targetLength)
        {
          /*gets the corresponding UniChar */
          mySourceChar = (unsigned char) mySource[mySourceIndex++];

          /*We have no internal state, we should */
          if (args->converter->toUnicodeStatus == 0x00)
            {
              args->converter->toUnicodeStatus = (unsigned char) mySourceChar;
            }
          else
            {
              if (args->converter->toUnicodeStatus != 0x00)
                {
                  mySourceChar = (UChar) ((args->converter->toUnicodeStatus << 8) | (mySourceChar & 0x00FF));
                  args->converter->toUnicodeStatus = 0x00;
                }

              targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);

              /*writing the UniChar to the output stream */
              if (targetUniChar < 0xfffe)
                {
                  /*writes the UniChar to the output stream */
                  myTarget[myTargetIndex++] = targetUniChar;
                }
              else if (UCNV_TO_U_USE_FALLBACK(args->converter) &&
                  (args->converter->sharedData->staticData->hasToUnicodeFallback == TRUE))
              {
                  UChar fallbackUniChar = (UChar) ucmp16_getu(myToUnicodeFallback, mySourceChar);
                  if (fallbackUniChar < 0xfffe)
                  {
                      myTarget[myTargetIndex++] = targetUniChar = fallbackUniChar;
                  }
              }
              if (targetUniChar >= 0xfffe)
                {
                  const char *saveSource = args->source;
                  UChar *saveTarget = args->target;
                  int32_t *saveOffsets = args->offsets;
                  UConverterCallbackReason reason;

                  if (targetUniChar == 0xfffe)
                  {
                    reason = UCNV_UNASSIGNED;
                    *err = U_INVALID_CHAR_FOUND;
                  }
                  else
                  {
                    reason = UCNV_ILLEGAL;
                    *err = U_ILLEGAL_CHAR_FOUND;
                  }

                  args->converter->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
                  args->converter->invalidCharBuffer[1] = (char) mySourceChar;
                  args->converter->invalidCharLength = 2;
                  
                  args->target = myTarget + myTargetIndex;
                  args->source = mySource + mySourceIndex;

                  /* to do hsys: add more smarts to the codeUnits and length later */
                  ToU_CALLBACK_MACRO(args->converter->toUContext,
                                     args,
                                     args->converter->invalidCharBuffer,
                                     args->converter->invalidCharLength, 
                                     reason,
                                     err);
                  /* Hsys: calculate the source and target advancement */
                  args->source = saveSource;
                  args->target = saveTarget;
                  args->offsets = saveOffsets;
                  if (U_FAILURE (*err)) break;
                  args->converter->invalidCharLength = 0;
                }
            }
        }
      else
        {
          *err = U_BUFFER_OVERFLOW_ERROR;
          break;
        }
    }

  /*If at the end of conversion we are still carrying state information
   *flush is TRUE, we can deduce that the input stream is truncated
   */
  if ((args->flush == TRUE)
      && (mySourceIndex == sourceLength)
      && (args->converter->toUnicodeStatus != 0x00))
    {
       
      if (U_SUCCESS(*err)) 
        {
          *err = U_TRUNCATED_CHAR_FOUND;
          args->converter->toUnicodeStatus = 0x00;
        }
    }

  args->target += myTargetIndex;
  args->source += mySourceIndex;

  return;
}

U_CFUNC void   T_UConverter_fromUnicode_DBCS (UConverterFromUnicodeArgs * args,
                                      UErrorCode * err)
{
  const UChar *mySource = args->source;
  unsigned char *myTarget = (unsigned char *) args->target;
  int32_t mySourceIndex = 0;
  int32_t myTargetIndex = 0;
  int32_t targetLength = args->targetLimit - (char *) myTarget;
  int32_t sourceLength = args->sourceLimit - mySource;
  CompactShortArray *myFromUnicode = NULL, *myFromUnicodeFallback = NULL;
  UChar targetUniChar = 0x0000;
  UChar mySourceChar = 0x0000;
  UConverterCallbackReason reason;

  myFromUnicode = &args->converter->sharedData->table->dbcs.fromUnicode;
  myFromUnicodeFallback = &args->converter->sharedData->table->dbcs.fromUnicodeFallback;

  /*writing the char to the output stream */
  while (mySourceIndex < sourceLength)
    {

      if (myTargetIndex < targetLength)
        {
          mySourceChar = (UChar) mySource[mySourceIndex++];

          /*Gets the corresponding codepoint */
          targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
          if (targetUniChar != missingCharMarker)
            {
              /*writes the char to the output stream */
              myTarget[myTargetIndex++] = (char) (targetUniChar >> 8);
              if (myTargetIndex < targetLength)
                {
                  myTarget[myTargetIndex++] = (char) targetUniChar;
                }
              else
                {
                  args->converter->charErrorBuffer[0] = (char) targetUniChar;
                  args->converter->charErrorBufferLength = 1;
                  *err = U_BUFFER_OVERFLOW_ERROR;
                }
            }
          else if (UCNV_FROM_U_USE_FALLBACK(args->converter, mySourceChar) &&
                  (args->converter->sharedData->staticData->hasFromUnicodeFallback == TRUE))
          {

              targetUniChar = (UChar) ucmp16_getu (myFromUnicodeFallback, mySourceChar);
              if (targetUniChar != missingCharMarker)
                {
                    /*writes the char to the output stream */
                    myTarget[myTargetIndex++] = (char) (targetUniChar >> 8);
                    if (myTargetIndex < targetLength)
                      {
                        myTarget[myTargetIndex++] = (char) targetUniChar;
                      }
                    else
                      {
                        args->converter->charErrorBuffer[0] = (char) targetUniChar;
                        args->converter->charErrorBufferLength = 1;
                        *err = U_BUFFER_OVERFLOW_ERROR;
                      }
                }
          }
          if (targetUniChar == missingCharMarker)  
          {
              *err = U_INVALID_CHAR_FOUND;
              reason = UCNV_UNASSIGNED;
              
              args->converter->invalidUCharBuffer[0] = (UChar)mySource[mySourceIndex - 1];
              args->converter->invalidUCharLength = 1;
              if (UTF_IS_LEAD(mySource[mySourceIndex-1]))
              {
                  /*if (mySource < args->sourceLimit) */
                  if(mySourceIndex < sourceLength)
                  {
                      if (UTF_IS_TRAIL(mySource[mySourceIndex]))
                      {
                          args->converter->invalidUCharBuffer[1] = (UChar)mySource[mySourceIndex];
                          args->converter->invalidUCharLength++;
                          mySourceIndex++;
                      }
                      else 
                      {
                          reason = UCNV_ILLEGAL;
                      }                          
                  }
                  else if (args->flush == TRUE)
                  {
                      reason = UCNV_ILLEGAL;
                      *err = U_TRUNCATED_CHAR_FOUND;
                  } 
                  else 
                  {
                      args->converter->fromUSurrogateLead = args->converter->invalidUCharBuffer[0];
                      /* do not call the callback */
                  }
              }
              if (args->converter->fromUSurrogateLead == 0) 
              {
                  /* Needed explicit cast for myTarget on MVS to make compiler happy - JJD */
                  /* Check if we have encountered a surrogate pair.  If first UChar is lead byte
                   and second UChar is trail byte, it's a surrogate char.  If UChar is lead byte 
                   but second UChar is not trail byte, it's illegal sequence.  If neither, it's
                   plain unassigned code point.*/
                  const UChar *saveSource = args->source;
                  char *saveTarget = args->target;
                  int32_t *saveOffsets = args->offsets;
                  args->target = (char*)myTarget + myTargetIndex;
                  args->source = mySource + mySourceIndex;
                  FromU_CALLBACK_MACRO(args->converter->fromUContext,
                                         args,
                                         args->converter->invalidUCharBuffer,
                                         args->converter->invalidUCharLength,
                                         (UChar32) (args->converter->invalidUCharLength == 2 ? 
                                             UTF16_GET_PAIR_VALUE(args->converter->invalidUCharBuffer[0], 
                                                                  args->converter->invalidUCharBuffer[1]) 
                                                    : args->converter->invalidUCharBuffer[0]),
                                         reason,
                                         err);
                  args->source = saveSource;
                  args->target = saveTarget;
                  args->offsets = saveOffsets;
                  if (U_FAILURE (*err))
                    {
                      break;
                    }
                  args->converter->invalidUCharLength = 0;
              }
            }
        }
      else
        {
          *err = U_BUFFER_OVERFLOW_ERROR;
          break;
        }
    }

  args->target += myTargetIndex;
  args->source += mySourceIndex;;


  return;
}

U_CFUNC UChar32 T_UConverter_getNextUChar_DBCS(UConverterToUnicodeArgs* args,
                                               UErrorCode* err)
{
  UChar myUChar;
  
  if (U_FAILURE(*err)) return 0xffff;
  /*Checks boundaries and set appropriate error codes*/
  if (args->source+2 > args->sourceLimit) 
    {
      if (args->source >= args->sourceLimit)
        {
          /*Either caller has reached the end of the byte stream*/
          *err = U_INDEX_OUTOFBOUNDS_ERROR;
        }
      else if ((args->source+1) == args->sourceLimit)
        {
          /* a character was cut in half*/
          *err = U_TRUNCATED_CHAR_FOUND;
        }
      
      return 0xffff;
    }

  /*Gets the corresponding codepoint*/
  myUChar = ucmp16_getu((&args->converter->sharedData->table->dbcs.toUnicode),
                        (uint16_t)(((UChar)((*(args->source))) << 8) |((uint8_t)*(args->source+1))));
  
  /*update the input pointer*/
  args->source += 2;
  if (myUChar < 0xfffe) return myUChar;
  else
    {      
      UChar* myUCharPtr = &myUChar;
      UConverterCallbackReason reason;

      /* Do the fallback stuff */
      if (UCNV_TO_U_USE_FALLBACK(args->converter) &&
          (args->converter->sharedData->staticData->hasToUnicodeFallback == TRUE))
      {
          UChar fallbackUChar = ucmp16_getu((&args->converter->sharedData->table->dbcs.toUnicodeFallback),
                            (uint16_t)(((UChar)((*(args->source))) << 8) |((uint8_t)*(args->source-1))));
          if (fallbackUChar < 0xfffe)
          {
              args->source += 2;
              return fallbackUChar;
          }
      }
      
      if (myUChar == 0xfffe)
      {
        reason = UCNV_UNASSIGNED;
        *err = U_INVALID_CHAR_FOUND;
      }
      else
      {
        reason = UCNV_ILLEGAL;
        *err = U_ILLEGAL_CHAR_FOUND;
      }

      args->target = myUCharPtr;
      args->targetLimit = myUCharPtr + 1;
      /*It's is very likely that the ErrorFunctor will write to the
       *internal buffers */
      args->converter->fromCharErrorBehaviour(args->converter->toUContext,
                                    args,
                                    args->source - 2,
                                    2,
                                    reason,
                                    err);
      /*makes the internal caching transparent to the user*/
      if (*err == U_BUFFER_OVERFLOW_ERROR) *err = U_ZERO_ERROR;

      return myUChar;
    }
} 

static const UConverterImpl _DBCSImpl={
    UCNV_DBCS,

    _DBCSLoad,
    _DBCSUnload,

    NULL,
    NULL,
    NULL,

    T_UConverter_toUnicode_DBCS,
    NULL,
    T_UConverter_fromUnicode_DBCS,
    NULL,
    T_UConverter_getNextUChar_DBCS,

    NULL,
    NULL
};


/* Static data is in tools/makeconv/ucnvstat.c for data-based
 * converters. Be sure to update it as well.
 */

const UConverterSharedData _DBCSData={
    sizeof(UConverterSharedData), 1,
    NULL, NULL, NULL, FALSE, &_DBCSImpl, 
    0, /* tounicodestatus */
};
