/*
 *****************************************************************************
 *
 *   Copyright (C) 1998-2001, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *****************************************************************************
 *
 *  ucnv_err.c
 *  Implements error behaviour functions called by T_UConverter_{from,to}Unicode
 *
 *
*   Change history:
*
*   06/29/2000  helena      Major rewrite of the callback APIs.
*/

#include "unicode/ucnv_err.h"
#include "unicode/ucnv_cb.h"
#include "ucnv_cnv.h"
#include "cmemory.h"
#include "unicode/ucnv.h"
#include "ustrfmt.h"

#define VALUE_STRING_LENGTH 32
/*Magic # 32 = 4(number of char in value string) * 8(max number of bytes per char for any converter) */
#define UNICODE_PERCENT_SIGN_CODEPOINT  0x0025
#define UNICODE_U_CODEPOINT             0x0055
#define UNICODE_X_CODEPOINT             0x0058
#define UNICODE_RS_CODEPOINT            0x005C
#define UNICODE_U_LOW_CODEPOINT         0x0075
#define UNICODE_X_LOW_CODEPOINT         0x0078
#define UNICODE_AMP_CODEPOINT           0x0026
#define UNICODE_HASH_CODEPOINT          0x0023
#define UNICODE_SEMICOLON_CODEPOINT     0x003B
#define UCNV_PRV_ESCAPE_ICU      0
#define UCNV_PRV_ESCAPE_C       'C'
#define UCNV_PRV_ESCAPE_XML_DEC 'D'
#define UCNV_PRV_ESCAPE_XML_HEX 'X'
#define UCNV_PRV_ESCAPE_JAVA    'J'


/*Function Pointer STOPS at the ILLEGAL_SEQUENCE */
U_CAPI void    U_EXPORT2
UCNV_FROM_U_CALLBACK_STOP (
                  const void *context,
                  UConverterFromUnicodeArgs *fromUArgs,
                  const UChar* codeUnits,
                  int32_t length,
                  UChar32 codePoint,
                  UConverterCallbackReason reason,
                  UErrorCode * err)
{
  /* the caller must have set the error code accordingly */
  return;
}


/*Function Pointer STOPS at the ILLEGAL_SEQUENCE */
U_CAPI void    U_EXPORT2
UCNV_TO_U_CALLBACK_STOP (
                   const void *context,
                   UConverterToUnicodeArgs *toUArgs,
                   const char* codePoints,
                   int32_t length,
                   UConverterCallbackReason reason,
                   UErrorCode * err)
{
  /* the caller must have set the error code accordingly */
  return;
}

U_CAPI void    U_EXPORT2
UCNV_FROM_U_CALLBACK_SKIP (                  
                  const void *context,
                  UConverterFromUnicodeArgs *fromUArgs,
                  const UChar* codeUnits,
                  int32_t length,
                  UChar32 codePoint,
                  UConverterCallbackReason reason,
                  UErrorCode * err)
{
    if(context==NULL)
    {
        if (reason <= UCNV_IRREGULAR)
        {
            *err = U_ZERO_ERROR;
            return;
        }

    }
    else if(*(char*)context=='i')
    {
        if(reason != UCNV_UNASSIGNED)
        {
            /* the caller must have set 
             * the error code accordingly
             */
            return;
        }
        else
        {
            *err = U_ZERO_ERROR;
            return;
        }
    }
}

U_CAPI void    U_EXPORT2
UCNV_FROM_U_CALLBACK_SUBSTITUTE (
                  const void *context,
                  UConverterFromUnicodeArgs *fromArgs,
                  const UChar* codeUnits,
                  int32_t length,
                  UChar32 codePoint,
                  UConverterCallbackReason reason,
                  UErrorCode * err)
{
    if(context == NULL)
    {
        if (reason > UCNV_IRREGULAR)
        {
            return;
        }
    
        *err = U_ZERO_ERROR;
        ucnv_cbFromUWriteSub(fromArgs, 0, err);
        return;
    }
    else if(*((char*)context)=='i')
    {
        if(reason != UCNV_UNASSIGNED)
        {
            /* the caller must have set 
             * the error code accordingly
             */
            return;
        }
        else
        {
            *err = U_ZERO_ERROR;
            ucnv_cbFromUWriteSub(fromArgs, 0, err);
            return;
        }
    }
}

/*uses uprv_itou to get a unicode escape sequence of the offensive sequence,
 *uses a clean copy (resetted) of the converter, to convert that unicode
 *escape sequence to the target codepage (if conversion failure happens then
 *we revert to substituting with subchar)
 */
U_CAPI void    U_EXPORT2
UCNV_FROM_U_CALLBACK_ESCAPE (
                         const void *context,
                         UConverterFromUnicodeArgs *fromArgs,
                         const UChar *codeUnits,
                         int32_t length,
                         UChar32 codePoint,
                         UConverterCallbackReason reason,
                         UErrorCode * err)
{

  UChar valueString[VALUE_STRING_LENGTH];
  int32_t valueStringLength = 0;
  int32_t i = 0;

  const UChar *myValueSource = NULL;
  UErrorCode err2 = U_ZERO_ERROR;
  UConverterFromUCallback original = NULL;
  const void *originalContext;

  UConverterFromUCallback ignoredCallback = NULL;
  const void *ignoredContext;
  
  if (reason > UCNV_IRREGULAR)
  {
    return;
  }

  ucnv_setFromUCallBack (fromArgs->converter,
                     (UConverterFromUCallback) UCNV_FROM_U_CALLBACK_SUBSTITUTE,
                     NULL,
                     &original,
                     &originalContext,
                     &err2);
  
  if (U_FAILURE (err2))
  {
    *err = err2;
    return;
  } 
  if(context==NULL)
  { 
      while (i < length)
      {
        valueString[valueStringLength++] = (UChar) UNICODE_PERCENT_SIGN_CODEPOINT;  /* adding % */
        valueString[valueStringLength++] = (UChar) UNICODE_U_CODEPOINT; /* adding U */
        uprv_itou (valueString + valueStringLength, codeUnits[i++], 16, 4);
        valueStringLength += 4;
      }
  }
  else
  {
      switch(*((char*)context))
      {
        case UCNV_PRV_ESCAPE_JAVA:
          while (i < length)
          {
            valueString[valueStringLength++] = (UChar) UNICODE_RS_CODEPOINT;    /* adding \ */
            valueString[valueStringLength++] = (UChar) UNICODE_U_LOW_CODEPOINT; /* adding u */
            uprv_itou (valueString + valueStringLength, codeUnits[i++], 16, 4);
            valueStringLength += 4;
          }
          break;

        case UCNV_PRV_ESCAPE_C:
            valueString[valueStringLength++] = (UChar) UNICODE_RS_CODEPOINT;    /* adding \ */

            if(length==2){
                valueString[valueStringLength++] = (UChar) UNICODE_U_CODEPOINT; /* adding U */
                valueStringLength += uprv_itou (valueString + valueStringLength, codePoint, 16, 8);
                
            }
            else{
                valueString[valueStringLength++] = (UChar) UNICODE_U_LOW_CODEPOINT; /* adding u */
                valueStringLength += uprv_itou (valueString + valueStringLength, codeUnits[0], 16, 4);
            }
          break;

        case UCNV_PRV_ESCAPE_XML_DEC:
    
            valueString[valueStringLength++] = (UChar) UNICODE_AMP_CODEPOINT;   /* adding & */
            valueString[valueStringLength++] = (UChar) UNICODE_HASH_CODEPOINT;  /* adding # */
            if(length==2){
                valueStringLength += uprv_itou (valueString + valueStringLength, codePoint, 10, 0);
            }
            else{
                valueStringLength += uprv_itou (valueString + valueStringLength, codeUnits[0], 10, 0);
            }
            valueString[valueStringLength++] = (UChar) UNICODE_SEMICOLON_CODEPOINT; /* adding ; */
          break;

        case UCNV_PRV_ESCAPE_XML_HEX:

            valueString[valueStringLength++] = (UChar) UNICODE_AMP_CODEPOINT;   /* adding & */
            valueString[valueStringLength++] = (UChar) UNICODE_HASH_CODEPOINT;  /* adding # */
            valueString[valueStringLength++] = (UChar) UNICODE_X_LOW_CODEPOINT; /* adding x */
            if(length==2){
                valueStringLength += uprv_itou (valueString + valueStringLength, codePoint, 16, 0);
            }
            else{
                valueStringLength += uprv_itou (valueString + valueStringLength, codeUnits[0], 16, 0);
            }
            valueString[valueStringLength++] = (UChar) UNICODE_SEMICOLON_CODEPOINT; /* adding ; */
          break;
       default:
          while (i < length)
          {
            valueString[valueStringLength++] = (UChar) UNICODE_PERCENT_SIGN_CODEPOINT;  /* adding % */
            valueString[valueStringLength++] = (UChar) UNICODE_U_CODEPOINT;             /* adding U */
            uprv_itou (valueString + valueStringLength, codeUnits[i++], 16, 4);
            valueStringLength += 4;
          }
      }

  }  
  myValueSource = valueString;

  /* reset the error */
  *err = U_ZERO_ERROR;

  ucnv_cbFromUWriteUChars(fromArgs, &myValueSource, myValueSource+valueStringLength, 0, err);

  ucnv_setFromUCallBack (fromArgs->converter,
                         original,
                         originalContext,
                         &ignoredCallback,
                         &ignoredContext,
                         &err2);
  if (U_FAILURE (err2))
    {
      *err = err2;
      return;
    }

  return;
}



U_CAPI void  U_EXPORT2
UCNV_TO_U_CALLBACK_SKIP (
                 const void *context,
                 UConverterToUnicodeArgs *toArgs,
                 const char* codeUnits,
                 int32_t length,
                 UConverterCallbackReason reason,
                 UErrorCode * err)
{
    if(context==NULL)
    {
        if (reason <= UCNV_IRREGULAR)
        {
            *err = U_ZERO_ERROR;
            return;
        }

    }
    else if(*((char*)context)=='i')
    {
        if(reason != UCNV_UNASSIGNED)
        {
            /* the caller must have set 
             * the error code accordingly
             */
            return;
        }
        else
        {
            *err = U_ZERO_ERROR;
            return;
        }
    }
}

U_CAPI void    U_EXPORT2
UCNV_TO_U_CALLBACK_SUBSTITUTE (
                 const void *context,
                 UConverterToUnicodeArgs *toArgs,
                 const char* codeUnits,
                 int32_t length,
                 UConverterCallbackReason reason,
                 UErrorCode * err)
{
    if(context == NULL)
    {
        if (reason > UCNV_IRREGULAR)
        {
            return;
        }
    
        *err = U_ZERO_ERROR;
        ucnv_cbToUWriteSub(toArgs,0,err);
        return;
    }
    else if(*((char*)context)=='i')
    {
        if(reason != UCNV_UNASSIGNED)
        {
            /* the caller must have set 
             * the error code accordingly
             */
            return;
        }
        else
        {
            *err = U_ZERO_ERROR;
            ucnv_cbToUWriteSub(toArgs,0,err);
            return;
        }
    }

}

/*uses uprv_itou to get a unicode escape sequence of the offensive sequence,
 *and uses that as the substitution sequence
 */
U_CAPI void   U_EXPORT2
UCNV_TO_U_CALLBACK_ESCAPE (
                 const void *context,
                 UConverterToUnicodeArgs *toArgs,
                 const char* codeUnits,
                 int32_t length,
                 UConverterCallbackReason reason,
                 UErrorCode * err)
{
    UChar uniValueString[VALUE_STRING_LENGTH];
    int32_t valueStringLength = 0;
    int32_t i = 0;

    if (reason > UCNV_IRREGULAR)
    {
        return;
    }

  if(context==NULL)
  {    
    while (i < length)
    {
        uniValueString[valueStringLength++] = (UChar) UNICODE_PERCENT_SIGN_CODEPOINT; /* adding % */
        uniValueString[valueStringLength++] = (UChar) UNICODE_X_CODEPOINT;    /* adding X */
        uprv_itou (uniValueString + valueStringLength, (uint8_t) codeUnits[i++], 16, 2);
        valueStringLength += 2;
    }
  }
  else
  {
      switch(*((char*)context))
      {
        case UCNV_PRV_ESCAPE_XML_DEC:
           while (i < length)
           {
                uniValueString[valueStringLength++] = (UChar) UNICODE_AMP_CODEPOINT;   /* adding & */
                uniValueString[valueStringLength++] = (UChar) UNICODE_HASH_CODEPOINT;  /* adding # */
                valueStringLength += uprv_itou (uniValueString + valueStringLength, codeUnits[i++], 10, 0);
                uniValueString[valueStringLength++] = (UChar) UNICODE_SEMICOLON_CODEPOINT; /* adding ; */
           }
          break;

        case UCNV_PRV_ESCAPE_XML_HEX:
          while (i < length)
          {
                uniValueString[valueStringLength++] = (UChar) UNICODE_AMP_CODEPOINT;   /* adding & */
                uniValueString[valueStringLength++] = (UChar) UNICODE_HASH_CODEPOINT;  /* adding # */
                uniValueString[valueStringLength++] = (UChar) UNICODE_X_LOW_CODEPOINT; /* adding x */
                valueStringLength += uprv_itou (uniValueString + valueStringLength, codeUnits[i++], 16, 0);
                uniValueString[valueStringLength++] = (UChar) UNICODE_SEMICOLON_CODEPOINT; /* adding ; */
          }
          break;
        case UCNV_PRV_ESCAPE_C:
          while (i < length)
          {
                uniValueString[valueStringLength++] = (UChar) UNICODE_RS_CODEPOINT;    /* adding \ */
                uniValueString[valueStringLength++] = (UChar) UNICODE_X_LOW_CODEPOINT; /* adding x */
                valueStringLength += uprv_itou (uniValueString + valueStringLength, codeUnits[i++], 16, 2);
          }
          break;
        default:
          while (i < length)
          {
                uniValueString[valueStringLength++] = (UChar) UNICODE_PERCENT_SIGN_CODEPOINT; /* adding % */
                uniValueString[valueStringLength++] = (UChar) UNICODE_X_CODEPOINT;    /* adding X */
                uprv_itou (uniValueString + valueStringLength, (uint8_t) codeUnits[i++], 16, 2);
                valueStringLength += 2;
          }
      }
  }
    /* reset the error */
    *err = U_ZERO_ERROR;

    ucnv_cbToUWriteUChars(toArgs, uniValueString, valueStringLength, 0, err);
}
