/*  
**********************************************************************
*   Copyright (C) 2000, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   file name:  ucnvebcdic.c
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2000Aug29
*   created by: Ram Viswanadha
*
*   Change history:
*
*   
*/

#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"
#include "unicode/ustring.h"
#include "cstring.h"


/* Protos */
U_CFUNC void T_UConverter_fromUnicode_EBCDIC_STATEFUL(UConverterFromUnicodeArgs * args,
                                                    UErrorCode * err);

U_CFUNC void T_UConverter_fromUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args,
                                                                     UErrorCode * err);

U_CFUNC void T_UConverter_toUnicode_EBCDIC_STATEFUL(UConverterToUnicodeArgs * args,
                                                    UErrorCode * err);

U_CFUNC void T_UConverter_toUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (UConverterToUnicodeArgs * args,
                                                                   UErrorCode * err);


U_CFUNC UChar32 T_UConverter_getNextUChar_EBCDIC_STATEFUL (UConverterToUnicodeArgs * args,
                                                           UErrorCode * err);

/* Forward declaration */

U_CFUNC void
_DBCSLoad(UConverterSharedData *sharedData, const uint8_t *raw, UErrorCode *pErrorCode);

U_CFUNC void
_DBCSUnload(UConverterSharedData *sharedData);





U_CFUNC void T_UConverter_toUnicode_EBCDIC_STATEFUL (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 - args->target;
  int32_t sourceLength = args->sourceLimit - args->source;
  CompactShortArray *myToUnicode = NULL;
  UChar targetUniChar = 0x0000;
  UChar mySourceChar = 0x0000;
  int32_t myMode = args->converter->mode;

  myToUnicode = &(args->converter->sharedData->table->dbcs.toUnicode);
    while (mySourceIndex < sourceLength)
    {
      if (myTargetIndex < targetLength)
        {
          /*gets the corresponding UniChar */
          mySourceChar = (unsigned char) (args->source[mySourceIndex++]);
          if (mySourceChar == UCNV_SI) myMode = UCNV_SI;
          else if (mySourceChar == UCNV_SO) myMode = UCNV_SO;
         else if ((myMode == UCNV_SO) &&
              (args->converter->toUnicodeStatus == 0x00))
            {
              args->converter->toUnicodeStatus = (unsigned char) mySourceChar;
            }
          else
            {
              /*In case there is a state, we update the source char
               *by concatenating the previous char with the current
               *one
               */
              if (args->converter->toUnicodeStatus != 0x00)
                {
                  mySourceChar |= (UChar) (args->converter->toUnicodeStatus << 8);
                  args->converter->toUnicodeStatus = 0x00;
                }
              else mySourceChar &= 0x00FF;

              /*gets the corresponding Unicode codepoint */
              targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);

              /*writing the UniChar to the output stream */
              if (targetUniChar < 0xfffe)
                {
                  /*writes the UniChar to the output stream */
                  args->target[myTargetIndex++] = targetUniChar;
                }

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

                  if (mySourceChar > 0xff)
                    {
                      args->converter->invalidCharLength = 2;
                      args->converter->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
                      args->converter->invalidCharBuffer[1] = (char) mySourceChar;
                    }
                  else
                    {
                      args->converter->invalidCharLength = 1;
                      args->converter->invalidCharBuffer[0] = (char) mySourceChar;
                    }
                  args->converter->mode = myMode;
                  args->target += myTargetIndex;
                  args->source += mySourceIndex;
                  ToU_CALLBACK_MACRO(args->converter->toUContext,
                                     args,
                                     args->converter->invalidCharBuffer,
                                     args->converter->invalidCharLength,
                                     reason,
                                     err);

                  myMode = args->converter->mode;
                  args->source = saveSource;
                  args->target = saveTarget;
                  args->offsets = saveOffsets;
                  myMode = args->converter->mode;
                  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->converter->toUnicodeStatus
        && (mySourceIndex == sourceLength)
        && (args->flush == TRUE))
      {
        if (U_SUCCESS(*err)) 
          {
            *err = U_TRUNCATED_CHAR_FOUND;
            args->converter->toUnicodeStatus = 0x00;
          }
      }

  args->target += myTargetIndex;
  args->source += mySourceIndex;
  args->converter->mode = myMode;

  return;
}

U_CFUNC void T_UConverter_toUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (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 - args->target;
  int32_t sourceLength = args->sourceLimit - args->source;
  CompactShortArray *myToUnicode = NULL;
  UChar targetUniChar = 0x0000;
  UChar mySourceChar = 0x0000;
  int32_t myMode = args->converter->mode;

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

    while (mySourceIndex < sourceLength)
    {
      if (myTargetIndex < targetLength)
        {
          /*gets the corresponding UniChar */
          mySourceChar = (unsigned char) (args->source[mySourceIndex++]);
          if (mySourceChar == UCNV_SI) myMode = UCNV_SI;
          else if (mySourceChar == UCNV_SO) myMode = UCNV_SO;
          else if ((myMode == UCNV_SO) &&
                   (args->converter->toUnicodeStatus == 0x00))
            {
              args->converter->toUnicodeStatus = (unsigned char) mySourceChar;
            }
          else
            {
              /*In case there is a state, we update the source char
               *by concatenating the previous char with the current
               *one
               */
              if (args->converter->toUnicodeStatus != 0x00)
                {
                  mySourceChar |= (UChar) (args->converter->toUnicodeStatus << 8);
                  args->converter->toUnicodeStatus = 0x00;
                }
              else mySourceChar &= 0x00FF;

              /*gets the corresponding Unicode codepoint */
              targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);

              /*writing the UniChar to the output stream */
              if (targetUniChar < 0xfffe)
                {
                  /*writes the UniChar to the output stream */
                  {
                        if(myMode == UCNV_SO)
                         args->offsets[myTargetIndex] = mySourceIndex-2; /* double byte */
                        else
                         args->offsets[myTargetIndex] = mySourceIndex-1; /* single byte */
                  }
                  args->target[myTargetIndex++] = targetUniChar;
                }
              else
                {
                  int32_t currentOffset = args->offsets[myTargetIndex-1] + 2;/* Because mySourceIndex was already incremented */
                  int32_t My_i = myTargetIndex;
                  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;
                  }

                  if (mySourceChar > 0xFF)
                    {
                      args->converter->invalidCharLength = 2;
                      args->converter->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
                      args->converter->invalidCharBuffer[1] = (char) mySourceChar;
                    }
                  else
                    {
                      args->converter->invalidCharLength = 1;
                      args->converter->invalidCharBuffer[0] = (char) mySourceChar;
                    }
                  args->converter->mode = myMode;

                  args->target = args->target + myTargetIndex;
                  args->source = args->source + mySourceIndex;
                  args->offsets = args->offsets?args->offsets+myTargetIndex:0;
                  /* call back handles the offset array */
                  ToU_CALLBACK_OFFSETS_LOGIC_MACRO(args->converter->toUContext,
                                     args,
                                     args->source,
                                     1, 
                                     reason,
                                     err);                  
                  
                  args->source = saveSource;
                  args->target = saveTarget;
                  myMode = args->converter->mode;
                  if (U_FAILURE (*err))   break;
                  args->converter->invalidCharLength = 0;
                  myMode = args->converter->mode;
                }
            }
        }
      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->converter->toUnicodeStatus
        && (mySourceIndex == sourceLength)
        && (args->flush == TRUE))
      {
        if (U_SUCCESS(*err)) 
          {
            *err = U_TRUNCATED_CHAR_FOUND;
            args->converter->toUnicodeStatus = 0x00;
          }
      }

  args->target += myTargetIndex;
  args->source += mySourceIndex;
  args->converter->mode = myMode;

  return;
}

U_CFUNC void T_UConverter_fromUnicode_EBCDIC_STATEFUL (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 - args->target;
  int32_t sourceLength = args->sourceLimit - args->source;
  CompactShortArray *myFromUnicode = NULL;
  UChar targetUniChar = 0x0000;
  UChar mySourceChar = 0x0000;
  UBool isTargetUCharDBCS = (UBool)args->converter->fromUnicodeStatus;
  UBool oldIsTargetUCharDBCS = isTargetUCharDBCS;

  myFromUnicode = &args->converter->sharedData->table->dbcs.fromUnicode;
  /*writing the char to the output stream */
  while (mySourceIndex < sourceLength)
    {
      if (myTargetIndex < targetLength)
        {
          mySourceChar = (UChar) args->source[mySourceIndex++];
          targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
          oldIsTargetUCharDBCS = isTargetUCharDBCS;
          isTargetUCharDBCS = (UBool)(targetUniChar>0x00FF);
          
          if (targetUniChar != missingCharMarker)
            {
              if (oldIsTargetUCharDBCS != isTargetUCharDBCS)
                {
                  if (isTargetUCharDBCS) args->target[myTargetIndex++] = UCNV_SO;
                  else args->target[myTargetIndex++] = UCNV_SI;
                  
                  
                  if ((!isTargetUCharDBCS)&&(myTargetIndex+1 >= targetLength))
                    {
                      args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (char) targetUniChar;
                      *err = U_BUFFER_OVERFLOW_ERROR;
                      break;
                    }
                  else if (myTargetIndex+1 >= targetLength)
                    {
                      args->converter->charErrorBuffer[0] = (char) (targetUniChar >> 8);
                      args->converter->charErrorBuffer[1] = (char)(targetUniChar & 0x00FF);
                      args->converter->charErrorBufferLength = 2;
                      *err = U_BUFFER_OVERFLOW_ERROR;
                      break;
                    }
                  
                }
              
              if (!isTargetUCharDBCS)
                {
                  args->target[myTargetIndex++] = (char) targetUniChar;
                }
              else
                {
                  args->target[myTargetIndex++] = (char) (targetUniChar >> 8);
                  if (myTargetIndex < targetLength)
                    {
                      args->target[myTargetIndex++] = (char) targetUniChar;
                    }
                  else
                    {
                      args->converter->charErrorBuffer[0] = (char) targetUniChar;
                      args->converter->charErrorBufferLength = 1;
                      *err = U_BUFFER_OVERFLOW_ERROR;
                      break;
                    }
                }
            }
          else
            {
              const UChar* saveSource = args->source;
              char* saveTarget = args->target;
              int32_t *saveOffsets = args->offsets;

              isTargetUCharDBCS = oldIsTargetUCharDBCS;
              *err = U_INVALID_CHAR_FOUND;
              args->converter->invalidUCharBuffer[0] = (UChar) mySourceChar;
              args->converter->invalidUCharLength = 1;

              args->converter->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
              args->target += myTargetIndex;
              args->source += mySourceIndex;
              FromU_CALLBACK_MACRO(args->converter->fromUContext,
                                 args,
                                 args->converter->invalidUCharBuffer,
                                 1,
                                 (UChar32) mySourceChar,
                                 UCNV_UNASSIGNED,
                                 err);
              args->source = saveSource;
              args->target = saveTarget;
              args->offsets = saveOffsets;
              isTargetUCharDBCS  = (UBool) args->converter->fromUnicodeStatus;
              if (U_FAILURE (*err)) break;
              args->converter->invalidUCharLength = 0;
            }
        }
      else
        {
          *err = U_BUFFER_OVERFLOW_ERROR;
          break;
        }

    }


  args->target += myTargetIndex;
  args->source += mySourceIndex;
  
  args->converter->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;

  return;
}

U_CFUNC void T_UConverter_fromUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (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 - args->target;
  int32_t sourceLength = args->sourceLimit - args->source;
  CompactShortArray *myFromUnicode = NULL;
  UChar targetUniChar = 0x0000;
  UChar mySourceChar = 0x0000;
  UBool isTargetUCharDBCS = (UBool)args->converter->fromUnicodeStatus;
  UBool oldIsTargetUCharDBCS = isTargetUCharDBCS;
  
  myFromUnicode = &args->converter->sharedData->table->dbcs.fromUnicode;
  /*writing the char to the output stream */
  while (mySourceIndex < sourceLength)
    {
      if (myTargetIndex < targetLength)
        {
          mySourceChar = (UChar) args->source[mySourceIndex++];
          targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
          oldIsTargetUCharDBCS = isTargetUCharDBCS;
          isTargetUCharDBCS =(UBool) (targetUniChar>0x00FF);
          
          if (targetUniChar != missingCharMarker)
            {
              if (oldIsTargetUCharDBCS != isTargetUCharDBCS)
                {
                  args->offsets[myTargetIndex] = mySourceIndex-1;
                  if (isTargetUCharDBCS) args->target[myTargetIndex++] = UCNV_SO;
                  else args->target[myTargetIndex++] = UCNV_SI;
                  
                  
                  if ((!isTargetUCharDBCS)&&(myTargetIndex+1 >= targetLength))
                    {
                      args->converter->charErrorBuffer[0] = (char) targetUniChar;
                      args->converter->charErrorBufferLength = 1;
                      *err = U_BUFFER_OVERFLOW_ERROR;
                      break;
                    }
                  else if (myTargetIndex+1 >= targetLength)
                    {
                      args->converter->charErrorBuffer[0] = (char) (targetUniChar >> 8);
                      args->converter->charErrorBuffer[1] = (char) (targetUniChar & 0x00FF);
                      args->converter->charErrorBufferLength = 2;
                      *err = U_BUFFER_OVERFLOW_ERROR;
                      break;
                    }
                }
              
              if (!isTargetUCharDBCS)
              {
                  args->offsets[myTargetIndex] = mySourceIndex-1;
                  args->target[myTargetIndex++] = (char) targetUniChar;
              }
              else
              {
                  args->offsets[myTargetIndex] = mySourceIndex-1;
                  args->target[myTargetIndex++] = (char) (targetUniChar >> 8);
                  if (myTargetIndex < targetLength)
                    {
                      args->offsets[myTargetIndex] = mySourceIndex-1;
                      args->target[myTargetIndex++] = (char) targetUniChar;
                    }
                  else
                    {
                      args->converter->charErrorBuffer[0] = (char) targetUniChar;
                      args->converter->charErrorBufferLength = 1;
                      *err = U_BUFFER_OVERFLOW_ERROR;
                      break;
                    }
                }
            }
          else
            {
              int32_t currentOffset = args->offsets[myTargetIndex-1]+1;
              char * saveTarget = args->target;
              const UChar* saveSource = args->source;
              int32_t *saveOffsets = args->offsets;
              *err = U_INVALID_CHAR_FOUND;
              args->converter->invalidUCharBuffer[0] = (UChar) mySourceChar;
              args->converter->invalidUCharLength = 1;

              /* Breaks out of the loop since behaviour was set to stop */
              args->converter->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
              args->target += myTargetIndex;
              args->source += mySourceIndex;
              args->offsets = args->offsets?args->offsets+myTargetIndex:0;
              FromU_CALLBACK_OFFSETS_LOGIC_MACRO(args->converter->fromUContext,
                                     args,
                                     args->converter->invalidUCharBuffer,
                                     1,
                                     (UChar32)mySourceChar,
                                     UCNV_UNASSIGNED,
                                     err);
              isTargetUCharDBCS  = (UBool)(args->converter->fromUnicodeStatus);
              args->source = saveSource;
              args->target = saveTarget;
              args->offsets = saveOffsets;
              isTargetUCharDBCS  = (UBool)(args->converter->fromUnicodeStatus);
              if (U_FAILURE (*err))     break;
              args->converter->invalidUCharLength = 0;
            }
        }
      else
        {
          *err = U_BUFFER_OVERFLOW_ERROR;
          break;
        }

    }


  args->target += myTargetIndex;
  args->source += mySourceIndex;
  
  args->converter->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;

  return;
}

U_CFUNC UChar32 T_UConverter_getNextUChar_EBCDIC_STATEFUL(UConverterToUnicodeArgs* args,
                                                UErrorCode* err)
{
  UChar myUChar;
  char const *sourceInitial = args->source;
  /*safe keeps a ptr to the beginning in case we need to step back*/
  
  /*Input boundary check*/
  if (args->source >= args->sourceLimit) 
    {
      *err = U_INDEX_OUTOFBOUNDS_ERROR;
      return 0xffff;
    }
  
  /*Checks to see if with have SI/SO shifters
   if we do we change the mode appropriately and we consume the byte*/
  while ((*(args->source) == UCNV_SI) || (*(args->source) == UCNV_SO)) 
    {
      args->converter->mode = *(args->source);
      args->source++;
      sourceInitial = args->source;
      
      /*Rechecks boundary after consuming the shift sequence*/
      if (args->source >= args->sourceLimit) 
        {
          *err = U_INDEX_OUTOFBOUNDS_ERROR;
          return 0xffff;
        }
    }
  
  if (args->converter->mode == UCNV_SI)
    {
      myUChar = ucmp16_getu( (&(args->converter->sharedData->table->dbcs.toUnicode)),
                             ((UChar)(uint8_t)(*(args->source))));
      args->source++;
    }
  else
    {
      /*Lead byte: we Build the codepoint and get the corresponding character
       * and update the source ptr*/
      if ((args->source + 2) > args->sourceLimit) 
        {
          *err = U_TRUNCATED_CHAR_FOUND;
          return 0xffff;
        }

      myUChar = ucmp16_getu( (&(args->converter->sharedData->table->dbcs.toUnicode)),
                             (((UChar)(uint8_t)((*(args->source))) << 8) |((uint8_t)*(args->source+1))) );

      args->source += 2;
    }
  
  if (myUChar < 0xfffe) return myUChar;
  else
    {      
      /* HSYS: Check logic here */
      UChar* myUCharPtr = &myUChar;
      UConverterCallbackReason reason;

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

      /*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,
                                    sourceInitial,
                                    args->source - sourceInitial,
                                    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 _EBCDICStatefulImpl={
    UCNV_EBCDIC_STATEFUL,

    _DBCSLoad,
    _DBCSUnload,

    NULL,
    NULL,
    NULL,

    T_UConverter_toUnicode_EBCDIC_STATEFUL,
    T_UConverter_toUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC,
    T_UConverter_fromUnicode_EBCDIC_STATEFUL,
    T_UConverter_fromUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC,
    T_UConverter_getNextUChar_EBCDIC_STATEFUL,

    NULL,
    NULL
};

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

const UConverterSharedData _EBCDICStatefulData={
    sizeof(UConverterSharedData), 1,
    NULL, NULL, NULL, FALSE, &_EBCDICStatefulImpl,
    0
};
