/*  
**********************************************************************
*   Copyright (C) 2000, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   file name:  ucnv_utf.cpp
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2000feb03
*   created by: Markus W. Scherer
*
*   Change history:
*
*   06/29/2000  helena      Major rewrite of the callback APIs.
*   07/20/2000  george      Change the coding style to conform to the coding guidelines,
*                           and a few miscellaneous bug fixes.
*/

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

/* UTF-8 -------------------------------------------------------------------- */

/* UTF-8 Conversion DATA
 *   for more information see Unicode Strandard 2.0 , Transformation Formats Appendix A-9
 */
/*static const uint32_t REPLACEMENT_CHARACTER = 0x0000FFFD;*/
static const uint32_t MAXIMUM_UCS2 = 0x0000FFFF;
static const uint32_t MAXIMUM_UTF16 = 0x0010FFFF;
static const uint32_t MAXIMUM_UCS4 = 0x7FFFFFFF;
static const int8_t HALF_SHIFT = 10;
static const uint32_t HALF_BASE = 0x0010000;
static const uint32_t HALF_MASK = 0x3FF;
static const uint32_t SURROGATE_HIGH_START = 0xD800;
static const uint32_t SURROGATE_HIGH_END = 0xDBFF;
static const uint32_t SURROGATE_LOW_START = 0xDC00;
static const uint32_t SURROGATE_LOW_END = 0xDFFF;
static const uint32_t SURROGATE_LOW_BASE = 9216; /* -SURROGATE_LOW_START + HALF_BASE */

static const uint32_t offsetsFromUTF8[7] = {0,
  (uint32_t) 0x00000000, (uint32_t) 0x00003080, (uint32_t) 0x000E2080,
  (uint32_t) 0x03C82080, (uint32_t) 0xFA082080, (uint32_t) 0x82082080
};

/* END OF UTF-8 Conversion DATA */

static const int8_t bytesFromUTF8[256] = {
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0
};

/* static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};*/

#define INVALID_UTF8_TAIL(utf8) (((utf8) & 0xC0) != 0x80)

/**
 * Calls invalid char callback when an invalid character sequence is encountered.
 * It presumes that the converter has a callback to call.
 *
 * @returns true when callback fails
 */
UBool T_UConverter_toUnicode_InvalidChar_Callback(UConverterToUnicodeArgs * args,
                                                  UErrorCode *err)
{
    UConverter *converter = args->converter;

    if (U_SUCCESS(*err))
    {
        *err = U_ILLEGAL_CHAR_FOUND;
    }

    /* Make the toUBytes invalid */
    uprv_memcpy(converter->invalidCharBuffer,
                converter->toUBytes,
                converter->invalidCharLength);

    /* Call the ErrorFunction */
    args->converter->fromCharErrorBehaviour(converter->toUContext,
                                            args,
                                            converter->invalidCharBuffer,
                                            converter->invalidCharLength,
                                            UCNV_ILLEGAL,
                                            err);

    return (UBool)U_FAILURE(*err);
}

UBool T_UConverter_toUnicode_InvalidChar_OffsetCallback(UConverterToUnicodeArgs * args,
                                                        int32_t currentOffset,
                                                        UErrorCode *err)
{
    int32_t *saveOffsets = args->offsets;
    UBool result;
    
    result = T_UConverter_toUnicode_InvalidChar_Callback(args, err);

    while (saveOffsets < args->offsets)
    {
        *(saveOffsets++) = currentOffset;
    }
    return result;
}

U_CFUNC void T_UConverter_toUnicode_UTF8 (UConverterToUnicodeArgs * args,
                                  UErrorCode * err)
{
    const unsigned char *mySource = (unsigned char *) args->source;
    UChar *myTarget = args->target;
    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
    const UChar *targetLimit = args->targetLimit;
    unsigned char *toUBytes = args->converter->toUBytes;
    UBool invalidTailChar = FALSE;
    uint32_t ch, ch2 = 0, i;
    uint32_t inBytes;  /* Total number of bytes in the current UTF8 sequence */
  
    if (U_FAILURE(*err))
    {
        return;
    }

    /* Restore size of current sequence */
    if (args->converter->toUnicodeStatus && myTarget < targetLimit)
    {
        inBytes = args->converter->toULength;       /* restore # of bytes to consume */
        i = args->converter->invalidCharLength;     /* restore # of bytes consumed */

        ch = args->converter->toUnicodeStatus;/*Stores the previously calculated ch from a previous call*/
        args->converter->toUnicodeStatus = 0;
        goto morebytes;
    }


    while (mySource < sourceLimit && myTarget < targetLimit)
    {
        ch = *(mySource++);
        if (ch < 0x80)        /* Simple case */
        {
            *(myTarget++) = (UChar) ch;
        }
        else
        {
            /* store the first char */
            toUBytes[0] = (char)ch;
            inBytes = bytesFromUTF8[ch]; /* lookup current sequence length */
            i = 1;

morebytes:
            while (i < inBytes)
            {
                if (mySource < sourceLimit)
                {
                    toUBytes[i] = (char) (ch2 = *(mySource++));
                    if (INVALID_UTF8_TAIL(ch2))
                    {
                        *err = U_TRUNCATED_CHAR_FOUND;
                        invalidTailChar = TRUE;
                        break;
                    }
                    ch = (ch << 6) + ch2;
                    i++;
                }
                else
                {
                    if (args->flush)
                    {
                        if (U_SUCCESS(*err))
                        {
                            *err = U_TRUNCATED_CHAR_FOUND;
                        }
                    }
                    else
                    {    /* stores a partially calculated target*/
                        args->converter->toUnicodeStatus = ch;
                        args->converter->toULength = (int8_t) inBytes;
                        args->converter->invalidCharLength = (int8_t) i;
                    }
                    goto donefornow;
                }
            }

            /* Remove the acummulated high bits */
            ch -= offsetsFromUTF8[inBytes];

            if (i == inBytes && ch <= MAXIMUM_UTF16)
            {
                /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
                if (ch <= MAXIMUM_UCS2) 
                {
                    /* fits in 16 bits */
                    *(myTarget++) = (UChar) ch;
                }
                else
                {
                    /* write out the surrogates */
                    ch -= HALF_BASE;
                    *(myTarget++) = (UChar) ((ch >> HALF_SHIFT) + SURROGATE_HIGH_START);
                    ch = (ch & HALF_MASK) + SURROGATE_LOW_START;
                    if (myTarget < targetLimit)
                    {
                        *(myTarget++) = (UChar)ch;
                    }
                    else
                    {
                        /* Put in overflow buffer (not handled here) */
                        args->converter->UCharErrorBuffer[0] = (UChar) ch;
                        args->converter->UCharErrorBufferLength = 1;
                        *err = U_INDEX_OUTOFBOUNDS_ERROR;
                        break;
                    }
                }
            }
            else
            {
                args->source = (const char *) mySource;
                args->target = myTarget;
                args->converter->invalidCharLength = (int8_t)i;
                if (T_UConverter_toUnicode_InvalidChar_Callback(args, err))
                {
                    /* Stop if the error wasn't handled */
                    break;
                }
                args->converter->invalidCharLength = 0;
                mySource = (unsigned char *) args->source;
                myTarget = args->target;
                if (invalidTailChar)
                {
                    /* Treat the tail as ASCII*/
                    if (myTarget < targetLimit)
                    {
                        *(myTarget++) = (UChar) ch2;
                        invalidTailChar = FALSE;
                    }
                    else
                    {
                        /* Put in overflow buffer (not handled here) */
                        args->converter->UCharErrorBuffer[0] = (UChar) ch2;
                        args->converter->UCharErrorBufferLength = 1;
                        *err = U_INDEX_OUTOFBOUNDS_ERROR;
                        break;
                    }
                }
            }
        }
    }

donefornow:
    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
    {
        /* End of target buffer */
        *err = U_INDEX_OUTOFBOUNDS_ERROR;
    }

    args->target = myTarget;
    args->source = (const char *) mySource;
}

U_CFUNC void T_UConverter_toUnicode_UTF8_OFFSETS_LOGIC (UConverterToUnicodeArgs * args,
                                                UErrorCode * err)
{
    const unsigned char *mySource = (unsigned char *) args->source;
    UChar *myTarget = args->target;
    int32_t *myOffsets = args->offsets;
    int32_t offsetNum = 0;
    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
    const UChar *targetLimit = args->targetLimit;
    unsigned char *toUBytes = args->converter->toUBytes;
    UBool invalidTailChar = FALSE;
    uint32_t ch, ch2 = 0, i;
    uint32_t inBytes;

    /* Restore size of current sequence */
    if (args->converter->toUnicodeStatus && myTarget < targetLimit)
    {
        inBytes = args->converter->toULength;       /* restore # of bytes to consume */
        i = args->converter->invalidCharLength;     /* restore # of bytes consumed */

        ch = args->converter->toUnicodeStatus;/*Stores the previously calculated ch from a previous call*/
        args->converter->toUnicodeStatus = 0;
        goto morebytes;
    }

    while (mySource < sourceLimit && myTarget < targetLimit)
    {
        ch = *(mySource++);
        if (ch < 0x80)        /* Simple case */
        {
            *(myTarget++) = (UChar) ch;
            *(myOffsets++) = offsetNum++;
        }
        else
        {
            toUBytes[0] = (char)ch;
            inBytes = bytesFromUTF8[ch];
            i = 1;

morebytes:
            while (i < inBytes)
            {
                if (mySource < sourceLimit)
                {
                    toUBytes[i] = (char) (ch2 = *(mySource++));
                    if (INVALID_UTF8_TAIL(ch2))
                    {
                        *err = U_TRUNCATED_CHAR_FOUND;
                        invalidTailChar = TRUE;
                        break;
                    }
                    ch = (ch << 6) + ch2;
                    i++;
                }
                else
                {
                    if (args->flush)
                    {
                        if (U_SUCCESS(*err)) 
                        {
                            *err = U_TRUNCATED_CHAR_FOUND;
                            args->converter->toUnicodeStatus = 0;
                        }
                    }
                    else
                    {
                        args->converter->toUnicodeStatus = ch;
                        args->converter->toULength = (int8_t)inBytes;
                        args->converter->invalidCharLength = (int8_t)i;
                    }
                    goto donefornow;
                }
            }

            /* Remove the acummulated high bits */
            ch -= offsetsFromUTF8[inBytes];

            if (i == inBytes && ch <= MAXIMUM_UTF16)
            {
                /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
                if (ch <= MAXIMUM_UCS2) 
                {
                    /* fits in 16 bits */
                    *(myTarget++) = (UChar) ch;
                    *(myOffsets++) = offsetNum;
                }
                else
                {
                    /* write out the surrogates */
                    *(myOffsets++) = offsetNum;
                    ch -= HALF_BASE;
                    *(myTarget++) = (UChar) ((ch >> HALF_SHIFT) + SURROGATE_HIGH_START);
                    ch = (ch & HALF_MASK) + SURROGATE_LOW_START;
                    if (myTarget < targetLimit)
                    {
                        *(myTarget++) = (UChar)ch;
                        *(myOffsets++) = offsetNum;
                    }
                    else
                    {
                        args->converter->UCharErrorBuffer[0] = (UChar) ch;
                        args->converter->UCharErrorBufferLength = 1;
                        *err = U_INDEX_OUTOFBOUNDS_ERROR;
                    }
                }
                offsetNum += i;
            }
            else
            {
                UBool useOffset;

                args->source = (const char *) mySource;
                args->target = myTarget;
                args->offsets = myOffsets;
                args->converter->invalidCharLength = (int8_t)i;
                if (T_UConverter_toUnicode_InvalidChar_OffsetCallback(args,
                 offsetNum, err))
                {
                    /* Stop if the error wasn't handled */
                    break;
                }

                args->converter->invalidCharLength = 0;
                mySource = (unsigned char *) args->source;
                myTarget = args->target;

                useOffset = (UBool)(myOffsets != args->offsets);
                myOffsets = args->offsets;
                offsetNum += i;

                if (invalidTailChar)
                {
                    /* Treat the tail as ASCII*/
                    if (myTarget < targetLimit)
                    {
                        *(myTarget++) = (UChar) ch2;
                        *myOffsets = offsetNum++;
                        if (useOffset)
                        {
                            /* Increment when the target was consumed */
                            myOffsets++;
                        }
                        invalidTailChar = FALSE;
                    }
                    else
                    {
                        /* Put in overflow buffer (not handled here) */
                        args->converter->UCharErrorBuffer[0] = (UChar) ch2;
                        args->converter->UCharErrorBufferLength = 1;
                        *err = U_INDEX_OUTOFBOUNDS_ERROR;
                        break;
                    }
                }
            }
        }
    }

donefornow:
    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
    {   /* End of target buffer */
        *err = U_INDEX_OUTOFBOUNDS_ERROR;
    }

    args->target = myTarget;
    args->source = (const char *) mySource;
    args->offsets = myOffsets;
}

U_CFUNC void T_UConverter_fromUnicode_UTF8 (UConverterFromUnicodeArgs * args,
                                    UErrorCode * err)
{
    const UChar *mySource = args->source;
    unsigned char *myTarget = (unsigned char *) args->target;
    const UChar *sourceLimit = args->sourceLimit;
    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
    uint32_t ch, ch2;
    int16_t indexToWrite;
    char temp[4];

    if (args->converter->fromUnicodeStatus && myTarget < targetLimit)
    {
        ch = args->converter->fromUnicodeStatus;
        args->converter->fromUnicodeStatus = 0;
        goto lowsurogate;
    }

    while (mySource < sourceLimit && myTarget < targetLimit)
    {
        ch = *(mySource++);

        if (ch < 0x80)        /* Single byte */
        {
            *(myTarget++) = (char) ch;
        }
        else if (ch < 0x800)  /* Double byte */
        {
            *(myTarget++) = (char) ((ch >> 6) | 0xc0);
            if (myTarget < targetLimit)
            {
                *(myTarget++) = (char) ((ch & 0x3f) | 0x80);
            }
            else
            {
                args->converter->charErrorBuffer[0] = (char) ((ch & 0x3f) | 0x80);
                args->converter->charErrorBufferLength = 1;
                *err = U_INDEX_OUTOFBOUNDS_ERROR;
            }
        }
        else
        /* Check for surogates */
        {
            if ((ch >= SURROGATE_HIGH_START) && (ch <= SURROGATE_HIGH_END))
            {
lowsurogate:
                if (mySource < sourceLimit)
                {
                    ch2 = *mySource;
                    if ((ch2 >= SURROGATE_LOW_START) && (ch2 <= SURROGATE_LOW_END))
                    {
                        /* If there were two surrogates, combine them otherwise treat them normally */
                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
                        mySource++;
                    }
                }
                else if (!args->flush)
                {
                    args->converter->fromUnicodeStatus = ch;
                    break;
                }
            }

            if (ch < 0x10000)
            {
                indexToWrite = 2;
                temp[2] = (char) ((ch >> 12) | 0xe0);
            }
            else
            {
                indexToWrite = 3;
                temp[3] = (char) ((ch >> 18) | 0xf0);
                temp[2] = (char) ((ch >> 12) & 0x3f | 0x80);
            }
            temp[1] = (char) ((ch >> 6) & 0x3f | 0x80);
            temp[0] = (char) (ch & 0x3f | 0x80);

            for (; indexToWrite >= 0; indexToWrite--)
            {
                if (myTarget < targetLimit)
                {
                    *(myTarget++) = temp[indexToWrite];
                }
                else
                {
                    args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
                    *err = U_INDEX_OUTOFBOUNDS_ERROR;
                }
            }
        }
    }

    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
    {
        *err = U_INDEX_OUTOFBOUNDS_ERROR;
    }

    args->target = (char *) myTarget;
    args->source = mySource;
}

U_CFUNC void T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args,
                                                  UErrorCode * err)
{
    const UChar *mySource = args->source;
    unsigned char *myTarget = (unsigned char *) args->target;
    int32_t *myOffsets = args->offsets;
    const UChar *sourceLimit = args->sourceLimit;
    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
    uint32_t ch, ch2;
    int32_t offsetNum = 0;
    int16_t indexToWrite;
    char temp[4];

    if (args->converter->fromUnicodeStatus && myTarget < targetLimit)
    {
        ch = args->converter->fromUnicodeStatus;
        args->converter->fromUnicodeStatus = 0;
        goto lowsurogate;
    }

    while (mySource < sourceLimit && myTarget < targetLimit)
    {
        ch = *(mySource++);

        if (ch < 0x80)        /* Single byte */
        {
            *(myOffsets++) = offsetNum++;
            *(myTarget++) = (char) ch;
        }
        else if (ch < 0x800)  /* Double byte */
        {
            *(myOffsets++) = offsetNum;
            *(myTarget++) = (char) ((ch >> 6) | 0xc0);
            if (myTarget < targetLimit)
            {
                *(myOffsets++) = offsetNum++;
                *(myTarget++) = (char) ((ch & 0x3f) | 0x80);
            }
            else
            {
                args->converter->charErrorBuffer[0] = (char) ((ch & 0x3f) | 0x80);
                args->converter->charErrorBufferLength = 1;
                *err = U_INDEX_OUTOFBOUNDS_ERROR;
            }
        }
        else
        /* Check for surogates */
        {
            if ((ch >= SURROGATE_HIGH_START) && (ch <= SURROGATE_HIGH_END))
            {
lowsurogate:
                if (mySource < sourceLimit)
                {
                    ch2 = *mySource;
                    if ((ch2 >= SURROGATE_LOW_START) && (ch2 <= SURROGATE_LOW_END))
                    {
                        /* If there were two surrogates, combine them otherwise treat them normally */
                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
                        mySource++;
                    }
                }
                else if (!args->flush)
                {
                    args->converter->fromUnicodeStatus = ch;
                    break;
                }
            }

            if (ch < 0x10000)
            {
                indexToWrite = 2;
                temp[2] = (char) ((ch >> 12) | 0xe0);
            }
            else
            {
                indexToWrite = 3;
                temp[3] = (char) ((ch >> 18) | 0xf0);
                temp[2] = (char) ((ch >> 12) & 0x3f | 0x80);
            }
            temp[1] = (char) ((ch >> 6) & 0x3f | 0x80);
            temp[0] = (char) (ch & 0x3f | 0x80);

            for (; indexToWrite >= 0; indexToWrite--)
            {
                if (myTarget < targetLimit)
                {
                    *(myOffsets++) = offsetNum;
                    *(myTarget++) = temp[indexToWrite];
                }
                else
                {
                    args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
                    *err = U_INDEX_OUTOFBOUNDS_ERROR;
                }
            }
            offsetNum += (ch >= 0x10000) + 1;
        }
    }

    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
    {
        *err = U_INDEX_OUTOFBOUNDS_ERROR;
    }

    args->target = (char *) myTarget;
    args->source = mySource;
}

U_CFUNC UChar32 T_UConverter_getNextUChar_UTF8(UConverterToUnicodeArgs *args,
                                               UErrorCode* err)
{
    /*safe keeps a ptr to the beginning in case we need to step back*/
    char const *sourceInitial = args->source;
    uint16_t extraBytesToWrite;
    uint8_t myByte;
    UChar32 ch;
    int8_t isLegalSequence = 1;

    /*Input boundary check*/
    if (args->source >= args->sourceLimit) 
    {
        *err = U_INDEX_OUTOFBOUNDS_ERROR;
        return 0xffff;
    }

    myByte = (uint8_t)*(args->source++);
    if (myByte < 0x80)
    {
        return (UChar32)myByte;
    }
    extraBytesToWrite = (uint16_t)bytesFromUTF8[myByte];
    if (extraBytesToWrite == 0) {
        goto CALL_ERROR_FUNCTION;
    }

    /*The byte sequence is longer than the buffer area passed*/

    if ((args->source + extraBytesToWrite - 1) > args->sourceLimit)
    {
        *err = U_TRUNCATED_CHAR_FOUND;
        return 0xffff;
    }
    else
    {
        ch = myByte << 6;
        switch(extraBytesToWrite)
        {     
          /* note: code falls through cases! (sic)*/ 
        case 6:
            ch += (myByte = (uint8_t)*(args->source++));
            ch <<= 6;
            if ((myByte & 0xC0) != 0x80) 
            {
                isLegalSequence = 0;
                break;
            }
        case 5:
            ch += (myByte = *(args->source++));
            ch <<= 6;
            if ((myByte & 0xC0) != 0x80) 
            {
                isLegalSequence = 0;
                break;
            }
        case 4:
            ch += (myByte = *(args->source++));
            ch <<= 6;
            if ((myByte & 0xC0) != 0x80) 
            {
                isLegalSequence = 0;
                break;
            }
        case 3:
            ch += (myByte = *(args->source++));
            ch <<= 6;
            if ((myByte & 0xC0) != 0x80) 
            {
                isLegalSequence = 0;
                break;
            }
        case 2:
            ch += (myByte = *(args->source++));
            if ((myByte & 0xC0) != 0x80) 
            {
                isLegalSequence = 0;
            }
        };
    }
    ch -= offsetsFromUTF8[extraBytesToWrite];

    if (isLegalSequence)
        return ch; /* return the code point */

CALL_ERROR_FUNCTION:
    {
    UChar myUChar = (UChar)0xffff; /* ### TODO: this is a hack until we prepare the callbacks for code points */
    UChar* myUCharPtr = &myUChar;
    
    *err = U_ILLEGAL_CHAR_FOUND;
    
    /*It 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,
                                    UCNV_ILLEGAL,
                                    err);

    /*makes the internal caching transparent to the user*/
    if (*err == U_INDEX_OUTOFBOUNDS_ERROR)
        *err = U_ZERO_ERROR;

    return (UChar32)myUChar;
    }
} 

static const UConverterImpl _UTF8Impl={
    UCNV_UTF8,

    NULL,
    NULL,

    NULL,
    NULL,
    NULL,

    T_UConverter_toUnicode_UTF8,
    T_UConverter_toUnicode_UTF8_OFFSETS_LOGIC,
    T_UConverter_fromUnicode_UTF8,
    T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC,
    T_UConverter_getNextUChar_UTF8,

    NULL
};

/* Todo: verify that UTF-8 == (ccsid (ibm-codepage) 1208) for unicode version 2.0 and 3.0 */
const UConverterStaticData _UTF8StaticData={
  sizeof(UConverterStaticData),
"UTF8",
    1208, UCNV_IBM, UCNV_UTF8, 1, 4,
    3, { 0xef, 0xbf, 0xbd, 0 }
};


const UConverterSharedData _UTF8Data={
    sizeof(UConverterSharedData), ~((uint32_t) 0),
    NULL, NULL, &_UTF8StaticData, FALSE, &_UTF8Impl, 
    0
};

/* UTF-16BE ----------------------------------------------------------------- */

U_CFUNC void T_UConverter_toUnicode_UTF16_BE (UConverterToUnicodeArgs * args,
                                      UErrorCode * err)
{
    const unsigned char *mySource = (unsigned 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 mySourceChar = 0x0000;
    UChar oldmySourceChar = 0x0000;

    while (mySourceIndex < sourceLength)
    {
        if (myTargetIndex < targetLength)
        {
            /*gets the corresponding UChar */
            mySourceChar = (unsigned char) mySource[mySourceIndex++];
            oldmySourceChar = mySourceChar;
            if (args->converter->toUnicodeStatus == 0)
            {
                args->converter->toUnicodeStatus = 
                    (unsigned char) mySourceChar == 0 ? 0xFFFF : mySourceChar;
            }
            else
            {
                if (args->converter->toUnicodeStatus != 0xFFFF)
                    mySourceChar = (UChar) ((args->converter->toUnicodeStatus << 8) | mySourceChar);
                args->converter->toUnicodeStatus = 0;

                myTarget[myTargetIndex++] = mySourceChar;
            }
        }
        else
        {
            *err = U_INDEX_OUTOFBOUNDS_ERROR;
            break;
        }
    }

    if (U_SUCCESS(*err) && args->flush
      && (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;
}

U_CFUNC void  T_UConverter_fromUnicode_UTF16_BE (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;
    UChar mySourceChar;

    /*writing the char to the output stream */
    while (mySourceIndex < sourceLength)
    {
        if (myTargetIndex < targetLength)
        {
            mySourceChar = (UChar) mySource[mySourceIndex++];
            myTarget[myTargetIndex++] = (char) (mySourceChar >> 8);
            if (myTargetIndex < targetLength)
            {
                myTarget[myTargetIndex++] = (char) mySourceChar;
            }
            else
            {
                args->converter->charErrorBuffer[0] = (char) mySourceChar;
                args->converter->charErrorBufferLength = 1;
                *err = U_INDEX_OUTOFBOUNDS_ERROR;
            }
        }
        else
        {
            *err = U_INDEX_OUTOFBOUNDS_ERROR;
            break;
        }
    }

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

U_CFUNC UChar32 T_UConverter_getNextUChar_UTF16_BE(UConverterToUnicodeArgs* args,
                                                   UErrorCode* err)
{
    UChar32 myUChar;
    uint16_t first;
    /*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
        {
            /* a character was cut in half*/
            *err = U_TRUNCATED_CHAR_FOUND;
        }
        return 0xffff;
    }

    /*Gets the corresponding codepoint*/
    first = ((uint16_t)(*(args->source)) << 8) |((uint8_t)*((args->source)+1));
    myUChar = first;
    args->source += 2;

    if(UTF_IS_FIRST_SURROGATE(first)) {
        uint16_t second;

        if (args->source+2 > args->sourceLimit) {
            *err = U_TRUNCATED_CHAR_FOUND;
            return 0xffff;
        }

        /* get the second surrogate and assemble the code point */
        second = ((uint16_t)(*(args->source)) << 8) |((uint8_t)*(args->source+1));

        /* ignore unmatched surrogates and just deliver the first one in such a case */
        if(UTF_IS_SECOND_SURROGATE(second)) {
            /* matched pair, get pair value */
            myUChar = UTF16_GET_PAIR_VALUE(first, second);
            args->source += 2;
        }
    }

    return myUChar;
} 

static const UConverterImpl _UTF16BEImpl={
    UCNV_UTF16_BigEndian,

    NULL,
    NULL,

    NULL,
    NULL,
    NULL,

    T_UConverter_toUnicode_UTF16_BE,
    NULL,
    T_UConverter_fromUnicode_UTF16_BE,
    NULL,
    T_UConverter_getNextUChar_UTF16_BE,

    NULL
};

/* Todo: verify that UTF-16BE == (ccsid (ibm-codepage) 1200) for unicode version 2.0 and 3.0 */
const UConverterStaticData _UTF16BEStaticData={
  sizeof(UConverterStaticData),
"UTF16_BigEndian",
    1200, UCNV_IBM, UCNV_UTF16_BigEndian, 2, 2,
    2, { 0xff, 0xfd, 0, 0 }
};


const UConverterSharedData _UTF16BEData={
    sizeof(UConverterSharedData), ~((uint32_t) 0),
    NULL, NULL, &_UTF16BEStaticData, FALSE, &_UTF16BEImpl, 
    0
};

/* UTF-16LE ----------------------------------------------------------------- */

U_CFUNC void  T_UConverter_toUnicode_UTF16_LE (UConverterToUnicodeArgs * args,
                                       UErrorCode * err)
{
    const unsigned char *mySource = (unsigned 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 mySourceChar = 0x0000;

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

            if (args->converter->toUnicodeStatus == 0x00)
            {
                args->converter->toUnicodeStatus = (unsigned char) mySourceChar == 0x00 ? 0xFFFF : mySourceChar;
            }
            else
            {
                if (args->converter->toUnicodeStatus == 0xFFFF) {
                    mySourceChar = (UChar) (mySourceChar << 8);
                }
                else
                {
                    mySourceChar <<= 8;
                    mySourceChar |= (UChar) (args->converter->toUnicodeStatus);
                }
                args->converter->toUnicodeStatus = 0x00;
                myTarget[myTargetIndex++] = mySourceChar;
            }
        }
        else
        {
            *err = U_INDEX_OUTOFBOUNDS_ERROR;
            break;
        }
    }


    if (U_SUCCESS(*err) && args->flush
      && (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;
}

U_CFUNC void   T_UConverter_fromUnicode_UTF16_LE (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;
    UChar mySourceChar;

    /*writing the char to the output stream */
    while (mySourceIndex < sourceLength)
    {
        if (myTargetIndex < targetLength)
        {
            mySourceChar = (UChar) mySource[mySourceIndex++];
            myTarget[myTargetIndex++] = (char) mySourceChar;
            if (myTargetIndex < targetLength)
            {
                myTarget[myTargetIndex++] = (char) (mySourceChar >> 8);
            }
            else
            {
                args->converter->charErrorBuffer[0] = (char) (mySourceChar >> 8);
                args->converter->charErrorBufferLength = 1;
                *err = U_INDEX_OUTOFBOUNDS_ERROR;
            }
        }
        else
        {
            *err = U_INDEX_OUTOFBOUNDS_ERROR;
            break;
        }
    }

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

U_CFUNC UChar32 T_UConverter_getNextUChar_UTF16_LE(UConverterToUnicodeArgs* args,
                                                   UErrorCode* err)
{
    UChar32 myUChar;
    uint16_t first;
    /*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
        {
            /* a character was cut in half*/
            *err = U_TRUNCATED_CHAR_FOUND;
        }

        return 0xffff;
    }

    /*Gets the corresponding codepoint*/
    first =  ((uint16_t)*((args->source)+1) << 8) | ((uint8_t)(*(args->source)));
    myUChar=first;
    /*updates the source*/
    args->source += 2;  

    if (UTF_IS_FIRST_SURROGATE(first))
    {
        uint16_t second;

        if (args->source+2 > args->sourceLimit)
        {
           *err = U_TRUNCATED_CHAR_FOUND;
            return 0xffff;
        }

        /* get the second surrogate and assemble the code point */
        second = ((uint16_t)*(args->source+1) << 8) |((uint8_t)(*(args->source)));

        /* ignore unmatched surrogates and just deliver the first one in such a case */
        if(UTF_IS_SECOND_SURROGATE(second))
        {
            /* matched pair, get pair value */
            myUChar = UTF16_GET_PAIR_VALUE(first, second);
            args->source += 2;
        }
    }

    return myUChar;
} 

static const UConverterImpl _UTF16LEImpl={
    UCNV_UTF16_LittleEndian,

    NULL,
    NULL,

    NULL,
    NULL,
    NULL,

    T_UConverter_toUnicode_UTF16_LE,
    NULL,
    T_UConverter_fromUnicode_UTF16_LE,
    NULL,
    T_UConverter_getNextUChar_UTF16_LE,

    NULL
};


/* Todo: verify that UTF-16LE == (ccsid (ibm-codepage) 1200) for unicode version 2.0 and 3.0 */
const UConverterStaticData _UTF16LEStaticData={
    sizeof(UConverterStaticData),
    "UTF16_LittleEndian",
    1200, UCNV_IBM, UCNV_UTF16_LittleEndian, 2, 2,
    2, { 0xfd, 0xff, 0, 0 }
};


const UConverterSharedData _UTF16LEData={
    sizeof(UConverterSharedData), ~((uint32_t) 0),
    NULL, NULL, &_UTF16LEStaticData, FALSE, &_UTF16LEImpl, 
    0
};
