// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 *
 *   Copyright (C) 2003-2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  idnaref.cpp
 *   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
 *   created on: 2003feb1
 *   created by: Ram Viswanadha
 */

#include "unicode/utypes.h"

#if !UCONFIG_NO_IDNA && !UCONFIG_NO_TRANSLITERATION
#include "idnaref.h"
#include "punyref.h"
#include "ustr_imp.h"
#include "cmemory.h"
#include "sprpimpl.h"
#include "nptrans.h"
#include "testidna.h"
#include "punycode.h"
#include "unicode/ustring.h"

/* it is official IDNA ACE Prefix is "xn--" */
static const UChar ACE_PREFIX[] ={ 0x0078,0x006E,0x002d,0x002d } ;
#define ACE_PREFIX_LENGTH 4

#define MAX_LABEL_LENGTH 63
#define HYPHEN      0x002D
/* The Max length of the labels should not be more than 64 */
#define MAX_LABEL_BUFFER_SIZE 100
#define MAX_IDN_BUFFER_SIZE   300

#define CAPITAL_A        0x0041
#define CAPITAL_Z        0x005A
#define LOWER_CASE_DELTA 0x0020
#define FULL_STOP        0x002E


inline static UBool
startsWithPrefix(const UChar* src , int32_t srcLength){
    UBool startsWithPrefix = TRUE;

    if(srcLength < ACE_PREFIX_LENGTH){
        return FALSE;
    }

    for(int8_t i=0; i< ACE_PREFIX_LENGTH; i++){
        if(u_tolower(src[i]) != ACE_PREFIX[i]){
            startsWithPrefix = FALSE;
        }
    }
    return startsWithPrefix;
}

inline static UChar
toASCIILower(UChar ch){
    if(CAPITAL_A <= ch && ch <= CAPITAL_Z){
        return ch + LOWER_CASE_DELTA;
    }
    return ch;
}

inline static int32_t
compareCaseInsensitiveASCII(const UChar* s1, int32_t s1Len,
                            const UChar* s2, int32_t s2Len){
    if(s1Len != s2Len){
        return (s1Len > s2Len) ? s1Len : s2Len;
    }
    UChar c1,c2;
    int32_t rc;

    for(int32_t i =0;/* no condition */;i++) {
        /* If we reach the ends of both strings then they match */
        if(i == s1Len) {
            return 0;
        }

        c1 = s1[i];
        c2 = s2[i];

        /* Case-insensitive comparison */
        if(c1!=c2) {
            rc=(int32_t)toASCIILower(c1)-(int32_t)toASCIILower(c2);
            if(rc!=0) {
                return rc;
            }
        }
    }

}

static UErrorCode getError(enum punycode_status status){
    switch(status){
    case punycode_success:
        return U_ZERO_ERROR;
    case punycode_bad_input:   /* Input is invalid.                         */
        return U_INVALID_CHAR_FOUND;
    case punycode_big_output:  /* Output would exceed the space provided.   */
        return U_BUFFER_OVERFLOW_ERROR;
    case punycode_overflow :    /* Input requires wider integers to process. */
        return U_INDEX_OUTOFBOUNDS_ERROR;
    default:
        return U_INTERNAL_PROGRAM_ERROR;
    }
}

static inline int32_t convertASCIIToUChars(const char* src,UChar* dest, int32_t length){
    int i;
    for(i=0;i<length;i++){
        dest[i] = src[i];
    }
    return i;
}
static inline int32_t convertUCharsToASCII(const UChar* src,char* dest, int32_t length){
    int i;
    for(i=0;i<length;i++){
        dest[i] = (char)src[i];
    }
    return i;
}
// wrapper around the reference Punycode implementation
static int32_t convertToPuny(const UChar* src, int32_t srcLength,
                             UChar* dest, int32_t destCapacity,
                             UErrorCode& status){
    uint32_t b1Stack[MAX_LABEL_BUFFER_SIZE];
    int32_t b1Len = 0, b1Capacity = MAX_LABEL_BUFFER_SIZE;
    uint32_t* b1 = b1Stack;
    char b2Stack[MAX_LABEL_BUFFER_SIZE];
    char* b2 = b2Stack;
    int32_t b2Len =MAX_LABEL_BUFFER_SIZE ;
    punycode_status error;
    unsigned char* caseFlags = NULL;

    u_strToUTF32((UChar32*)b1,b1Capacity,&b1Len,src,srcLength,&status);
    if(status == U_BUFFER_OVERFLOW_ERROR){
        // redo processing of string
        /* we do not have enough room so grow the buffer*/
        b1 =  (uint32_t*) uprv_malloc(b1Len * sizeof(uint32_t));
        if(b1==NULL){
            status = U_MEMORY_ALLOCATION_ERROR;
            goto CLEANUP;
        }

        status = U_ZERO_ERROR; // reset error

        u_strToUTF32((UChar32*)b1,b1Len,&b1Len,src,srcLength,&status);
    }
    if(U_FAILURE(status)){
        goto CLEANUP;
    }

    //caseFlags = (unsigned char*) uprv_malloc(b1Len *sizeof(unsigned char));

    error = punycode_encode(b1Len,b1,caseFlags, (uint32_t*)&b2Len, b2);
    status = getError(error);

    if(status == U_BUFFER_OVERFLOW_ERROR){
        /* we do not have enough room so grow the buffer*/
        b2 = (char*) uprv_malloc( b2Len * sizeof(char));
        if(b2==NULL){
            status = U_MEMORY_ALLOCATION_ERROR;
            goto CLEANUP;
        }

        status = U_ZERO_ERROR; // reset error

        punycode_status error = punycode_encode(b1Len,b1,caseFlags, (uint32_t*)&b2Len, b2);
        status = getError(error);
    }
    if(U_FAILURE(status)){
        goto CLEANUP;
    }

    if(b2Len < destCapacity){
          convertASCIIToUChars(b2,dest,b2Len);
    }else{
        status =U_BUFFER_OVERFLOW_ERROR;
    }

CLEANUP:
    if(b1Stack != b1){
        uprv_free(b1);
    }
    if(b2Stack != b2){
        uprv_free(b2);
    }
    uprv_free(caseFlags);

    return b2Len;
}


static NamePrepTransform* getInstance(UErrorCode& status){
    TestIDNA *thisTest = dynamic_cast<TestIDNA *>(IntlTest::gTest);
    if (thisTest == nullptr && U_SUCCESS(status)) {
        status = U_INTERNAL_PROGRAM_ERROR;
    }
    if (U_FAILURE(status)) return nullptr;
    return thisTest->getInstance(status);
}


static int32_t convertFromPuny(  const UChar* src, int32_t srcLength,
                                 UChar* dest, int32_t destCapacity,
                                 UErrorCode& status){
    char b1Stack[MAX_LABEL_BUFFER_SIZE];
    char* b1 = b1Stack;
    int32_t destLen =0;

    convertUCharsToASCII(src, b1,srcLength);

    uint32_t b2Stack[MAX_LABEL_BUFFER_SIZE];
    uint32_t* b2 = b2Stack;
    int32_t b2Len =MAX_LABEL_BUFFER_SIZE;
    unsigned char* caseFlags = NULL; //(unsigned char*) uprv_malloc(srcLength * sizeof(unsigned char*));
    punycode_status error = punycode_decode(srcLength,b1,(uint32_t*)&b2Len,b2,caseFlags);
    status = getError(error);
    if(status == U_BUFFER_OVERFLOW_ERROR){
        b2 =  (uint32_t*) uprv_malloc(b2Len * sizeof(uint32_t));
        if(b2 == NULL){
            status = U_MEMORY_ALLOCATION_ERROR;
            goto CLEANUP;
        }
        error = punycode_decode(srcLength,b1,(uint32_t*)&b2Len,b2,caseFlags);
        status = getError(error);
    }

    if(U_FAILURE(status)){
        goto CLEANUP;
    }

    u_strFromUTF32(dest,destCapacity,&destLen,(UChar32*)b2,b2Len,&status);

CLEANUP:
    if(b1Stack != b1){
        uprv_free(b1);
    }
    if(b2Stack != b2){
        uprv_free(b2);
    }
    uprv_free(caseFlags);

    return destLen;
}


U_CFUNC int32_t U_EXPORT2
idnaref_toASCII(const UChar* src, int32_t srcLength,
              UChar* dest, int32_t destCapacity,
              int32_t options,
              UParseError* parseError,
              UErrorCode* status){

    if(status == NULL || U_FAILURE(*status)){
        return 0;
    }
    if((src == NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    UChar b1Stack[MAX_LABEL_BUFFER_SIZE], b2Stack[MAX_LABEL_BUFFER_SIZE];
    //initialize pointers to stack buffers
    UChar  *b1 = b1Stack, *b2 = b2Stack;
    int32_t b1Len=0, b2Len=0,
            b1Capacity = MAX_LABEL_BUFFER_SIZE,
            b2Capacity = MAX_LABEL_BUFFER_SIZE ,
            reqLength=0;

    //get the options
    UBool allowUnassigned   = (UBool)((options & IDNAREF_ALLOW_UNASSIGNED) != 0);
    UBool useSTD3ASCIIRules = (UBool)((options & IDNAREF_USE_STD3_RULES) != 0);

    UBool* caseFlags = NULL;

    // assume the source contains all ascii codepoints
    UBool srcIsASCII  = TRUE;
    // assume the source contains all LDH codepoints
    UBool srcIsLDH = TRUE;
    int32_t j=0;

    if(srcLength == -1){
        srcLength = u_strlen(src);
    }

    // step 1
    for( j=0;j<srcLength;j++){
        if(src[j] > 0x7F){
            srcIsASCII = FALSE;
        }
        b1[b1Len++] = src[j];
    }

    NamePrepTransform* prep = getInstance(*status);
    if(U_FAILURE(*status)){
        goto CLEANUP;
    }

    // step 2 is performed only if the source contains non ASCII
    if (!srcIsASCII) {
        b1Len = prep->process(src,srcLength,b1, b1Capacity,allowUnassigned,parseError,*status);

        if(*status == U_BUFFER_OVERFLOW_ERROR){
            // redo processing of string
            /* we do not have enough room so grow the buffer*/
            b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR);
            if(b1==NULL){
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto CLEANUP;
            }

            *status = U_ZERO_ERROR; // reset error

            b1Len = prep->process(src,srcLength,b1, b1Len,allowUnassigned, parseError, *status);
        }
        // error bail out
        if(U_FAILURE(*status)){
            goto CLEANUP;
        }
    }

    if(b1Len == 0){
        *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR;
        goto CLEANUP;
    }

    srcIsASCII = TRUE;
    // step 3 & 4
    for( j=0;j<b1Len;j++){
        if(b1[j] > 0x7F){// check if output of usprep_prepare is all ASCII
            srcIsASCII = FALSE;
        }else if(prep->isLDHChar(b1[j])==FALSE){  // if the char is in ASCII range verify that it is an LDH character{
            srcIsLDH = FALSE;
        }
    }

    if(useSTD3ASCIIRules == TRUE){
        // verify 3a and 3b
        if( srcIsLDH == FALSE /* source contains some non-LDH characters */
            || b1[0] ==  HYPHEN || b1[b1Len-1] == HYPHEN){
            *status = U_IDNA_STD3_ASCII_RULES_ERROR;
            goto CLEANUP;
        }
    }
    if(srcIsASCII){
        if(b1Len <= destCapacity){
            u_memmove(dest, b1, b1Len);
            reqLength = b1Len;
        }else{
            reqLength = b1Len;
            goto CLEANUP;
        }
    }else{
        // step 5 : verify the sequence does not begin with ACE prefix
        if(!startsWithPrefix(b1,b1Len)){

            //step 6: encode the sequence with punycode
            //caseFlags = (UBool*) uprv_malloc(b1Len * sizeof(UBool));

            b2Len = convertToPuny(b1,b1Len, b2,b2Capacity,*status);
            //b2Len = u_strToPunycode(b2,b2Capacity,b1,b1Len, caseFlags, status);
            if(*status == U_BUFFER_OVERFLOW_ERROR){
                // redo processing of string
                /* we do not have enough room so grow the buffer*/
                b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR);
                if(b2 == NULL){
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    goto CLEANUP;
                }

                *status = U_ZERO_ERROR; // reset error

                b2Len = convertToPuny(b1, b1Len, b2, b2Len, *status);
                //b2Len = u_strToPunycode(b2,b2Len,b1,b1Len, caseFlags, status);

            }
            //error bail out
            if(U_FAILURE(*status)){
                goto CLEANUP;
            }
            reqLength = b2Len+ACE_PREFIX_LENGTH;

            if(reqLength > destCapacity){
                *status = U_BUFFER_OVERFLOW_ERROR;
                goto CLEANUP;
            }
            //Step 7: prepend the ACE prefix
            u_memcpy(dest, ACE_PREFIX, ACE_PREFIX_LENGTH);
            //Step 6: copy the contents in b2 into dest
            u_memcpy(dest+ACE_PREFIX_LENGTH, b2, b2Len);

        }else{
            *status = U_IDNA_ACE_PREFIX_ERROR;
            goto CLEANUP;
        }
    }

    if(reqLength > MAX_LABEL_LENGTH){
        *status = U_IDNA_LABEL_TOO_LONG_ERROR;
    }

CLEANUP:
    if(b1 != b1Stack){
        uprv_free(b1);
    }
    if(b2 != b2Stack){
        uprv_free(b2);
    }
    uprv_free(caseFlags);

//    delete prep;

    return u_terminateUChars(dest, destCapacity, reqLength, status);
}


U_CFUNC int32_t U_EXPORT2
idnaref_toUnicode(const UChar* src, int32_t srcLength,
                UChar* dest, int32_t destCapacity,
                int32_t options,
                UParseError* parseError,
                UErrorCode* status){

    if(status == NULL || U_FAILURE(*status)){
        return 0;
    }
    if((src == NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }



    UChar b1Stack[MAX_LABEL_BUFFER_SIZE], b2Stack[MAX_LABEL_BUFFER_SIZE], b3Stack[MAX_LABEL_BUFFER_SIZE];

    //initialize pointers to stack buffers
    UChar  *b1 = b1Stack, *b2 = b2Stack, *b1Prime=NULL, *b3=b3Stack;
    int32_t b1Len, b2Len, b1PrimeLen, b3Len,
            b1Capacity = MAX_LABEL_BUFFER_SIZE,
            b2Capacity = MAX_LABEL_BUFFER_SIZE,
            b3Capacity = MAX_LABEL_BUFFER_SIZE,
            reqLength=0;
//    UParseError parseError;

    NamePrepTransform* prep = getInstance(*status);
    b1Len = 0;
    UBool* caseFlags = NULL;

    //get the options
    UBool allowUnassigned   = (UBool)((options & IDNAREF_ALLOW_UNASSIGNED) != 0);
    UBool useSTD3ASCIIRules = (UBool)((options & IDNAREF_USE_STD3_RULES) != 0);

    UBool srcIsASCII = TRUE;
    UBool srcIsLDH = TRUE;
    int32_t failPos =0;

    if(U_FAILURE(*status)){
        goto CLEANUP;
    }
    // step 1: find out if all the codepoints in src are ASCII
    if(srcLength==-1){
        srcLength = 0;
        for(;src[srcLength]!=0;){
            if(src[srcLength]> 0x7f){
                srcIsASCII = FALSE;
            }if(prep->isLDHChar(src[srcLength])==FALSE){
                // here we do not assemble surrogates
                // since we know that LDH code points
                // are in the ASCII range only
                srcIsLDH = FALSE;
                failPos = srcLength;
            }
            srcLength++;
        }
    }else{
        for(int32_t j=0; j<srcLength; j++){
            if(src[j]> 0x7f){
                srcIsASCII = FALSE;
            }else if(prep->isLDHChar(src[j])==FALSE){
                // here we do not assemble surrogates
                // since we know that LDH code points
                // are in the ASCII range only
                srcIsLDH = FALSE;
                failPos = j;
            }
        }
    }

    if(srcIsASCII == FALSE){
        // step 2: process the string
        b1Len = prep->process(src,srcLength,b1,b1Capacity,allowUnassigned, parseError, *status);
        if(*status == U_BUFFER_OVERFLOW_ERROR){
            // redo processing of string
            /* we do not have enough room so grow the buffer*/
            b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR);
            if(b1==NULL){
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto CLEANUP;
            }

            *status = U_ZERO_ERROR; // reset error

            b1Len = prep->process(src,srcLength,b1, b1Len,allowUnassigned, parseError, *status);
        }
        //bail out on error
        if(U_FAILURE(*status)){
            goto CLEANUP;
        }
    }else{

        // copy everything to b1
        if(srcLength < b1Capacity){
            u_memmove(b1, src, srcLength);
        }else{
            /* we do not have enough room so grow the buffer*/
            b1 = (UChar*) uprv_malloc(srcLength * U_SIZEOF_UCHAR);
            if(b1==NULL){
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto CLEANUP;
            }
            u_memmove(b1, src, srcLength);
        }
        b1Len = srcLength;
    }
    //step 3: verify ACE Prefix
    if(startsWithPrefix(src,srcLength)){

        //step 4: Remove the ACE Prefix
        b1Prime = b1 + ACE_PREFIX_LENGTH;
        b1PrimeLen  = b1Len - ACE_PREFIX_LENGTH;

        //step 5: Decode using punycode
        b2Len = convertFromPuny(b1Prime,b1PrimeLen, b2, b2Capacity, *status);
        //b2Len = u_strFromPunycode(b2, b2Capacity,b1Prime,b1PrimeLen, caseFlags, status);

        if(*status == U_BUFFER_OVERFLOW_ERROR){
            // redo processing of string
            /* we do not have enough room so grow the buffer*/
            b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR);
            if(b2==NULL){
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto CLEANUP;
            }

            *status = U_ZERO_ERROR; // reset error

            b2Len =  convertFromPuny(b1Prime,b1PrimeLen, b2, b2Len, *status);
            //b2Len = u_strFromPunycode(b2, b2Len,b1Prime,b1PrimeLen,caseFlags, status);
        }


        //step 6:Apply toASCII
        b3Len = idnaref_toASCII(b2,b2Len,b3,b3Capacity,options,parseError, status);

        if(*status == U_BUFFER_OVERFLOW_ERROR){
            // redo processing of string
            /* we do not have enough room so grow the buffer*/
            b3 = (UChar*) uprv_malloc(b3Len * U_SIZEOF_UCHAR);
            if(b3==NULL){
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto CLEANUP;
            }

            *status = U_ZERO_ERROR; // reset error

            b3Len =  idnaref_toASCII(b2,b2Len,b3,b3Len, options, parseError, status);

        }
        //bail out on error
        if(U_FAILURE(*status)){
            goto CLEANUP;
        }

        //step 7: verify
        if(compareCaseInsensitiveASCII(b1, b1Len, b3, b3Len) !=0){
            *status = U_IDNA_VERIFICATION_ERROR;
            goto CLEANUP;
        }

        //step 8: return output of step 5
        reqLength = b2Len;
        if(b2Len <= destCapacity) {
            u_memmove(dest, b2, b2Len);
        }
    }else{
        // verify that STD3 ASCII rules are satisfied
        if(useSTD3ASCIIRules == TRUE){
            if( srcIsLDH == FALSE /* source contains some non-LDH characters */
                || src[0] ==  HYPHEN || src[srcLength-1] == HYPHEN){
                *status = U_IDNA_STD3_ASCII_RULES_ERROR;

                /* populate the parseError struct */
                if(srcIsLDH==FALSE){
                    // failPos is always set the index of failure
                    uprv_syntaxError(src,failPos, srcLength,parseError);
                }else if(src[0] == HYPHEN){
                    // fail position is 0
                    uprv_syntaxError(src,0,srcLength,parseError);
                }else{
                    // the last index in the source is always length-1
                    uprv_syntaxError(src, (srcLength>0) ? srcLength-1 : srcLength, srcLength,parseError);
                }

                goto CLEANUP;
            }
        }
        //copy the source to destination
        if(srcLength <= destCapacity){
            u_memmove(dest, src, srcLength);
        }
        reqLength = srcLength;
    }

CLEANUP:

    if(b1 != b1Stack){
        uprv_free(b1);
    }
    if(b2 != b2Stack){
        uprv_free(b2);
    }
    uprv_free(caseFlags);

    // The RFC states that 
    // <quote>
    // ToUnicode never fails. If any step fails, then the original input
    // is returned immediately in that step.
    // </quote>
    // So if any step fails lets copy source to destination
    if(U_FAILURE(*status)){
        //copy the source to destination
        if(dest && srcLength <= destCapacity){
          if(srcLength == -1) {
            u_memmove(dest, src, u_strlen(src));
          } else {
            u_memmove(dest, src, srcLength);
          }
        }
        reqLength = srcLength;
        *status = U_ZERO_ERROR;
    }
    return u_terminateUChars(dest, destCapacity, reqLength, status);
}


static int32_t
getNextSeparator(UChar *src,int32_t srcLength,NamePrepTransform* prep,
                 UChar **limit,
                 UBool *done,
                 UErrorCode *status){
    if(srcLength == -1){
        int32_t i;
        for(i=0 ; ;i++){
            if(src[i] == 0){
                *limit = src + i; // point to null
                *done = TRUE;
                return i;
            }
            if(prep->isLabelSeparator(src[i],*status)){
                *limit = src + (i+1); // go past the delimiter
                return i;

            }
        }
    }else{
        int32_t i;
        for(i=0;i<srcLength;i++){
            if(prep->isLabelSeparator(src[i],*status)){
                *limit = src + (i+1); // go past the delimiter
                return i;
            }
        }
        // we have not found the delimiter
        if(i==srcLength){
            *limit = src+srcLength;
            *done = TRUE;
        }
        return i;
    }
}

U_CFUNC int32_t U_EXPORT2
idnaref_IDNToASCII(  const UChar* src, int32_t srcLength,
                   UChar* dest, int32_t destCapacity,
                   int32_t options,
                   UParseError* parseError,
                   UErrorCode* status){

    if(status == NULL || U_FAILURE(*status)){
        return 0;
    }
    if((src == NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }

    int32_t reqLength = 0;
//    UParseError parseError;

    NamePrepTransform* prep = getInstance(*status);

    //initialize pointers to stack buffers
    UChar b1Stack[MAX_LABEL_BUFFER_SIZE];
    UChar  *b1 = b1Stack;
    int32_t b1Len, labelLen;
    UChar* delimiter = (UChar*)src;
    UChar* labelStart = (UChar*)src;
    int32_t remainingLen = srcLength;
    int32_t b1Capacity = MAX_LABEL_BUFFER_SIZE;

    //get the options
//    UBool allowUnassigned   = (UBool)((options & IDNAREF_ALLOW_UNASSIGNED) != 0);
//    UBool useSTD3ASCIIRules = (UBool)((options & IDNAREF_USE_STD3_RULES) != 0);
    UBool done = FALSE;

    if(U_FAILURE(*status)){
        goto CLEANUP;
    }


    if(srcLength == -1){
        for(;;){

            if(*delimiter == 0){
                break;
            }

            labelLen = getNextSeparator(labelStart, -1, prep, &delimiter, &done, status);
            b1Len = 0;
            if(!(labelLen==0 && done)){// make sure this is not a root label separator.

                b1Len = idnaref_toASCII(labelStart, labelLen, b1, b1Capacity,
                                        options, parseError, status);

                if(*status == U_BUFFER_OVERFLOW_ERROR){
                    // redo processing of string
                    /* we do not have enough room so grow the buffer*/
                    b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR);
                    if(b1==NULL){
                        *status = U_MEMORY_ALLOCATION_ERROR;
                        goto CLEANUP;
                    }

                    *status = U_ZERO_ERROR; // reset error

                    b1Len = idnaref_toASCII(labelStart, labelLen, b1, b1Len,
                                            options, parseError, status);

                }
            }

            if(U_FAILURE(*status)){
                goto CLEANUP;
            }
            int32_t tempLen = (reqLength + b1Len );
            // copy to dest
            if( tempLen< destCapacity){
                u_memmove(dest+reqLength, b1, b1Len);
            }

            reqLength = tempLen;

            // add the label separator
            if(done == FALSE){
                if(reqLength < destCapacity){
                    dest[reqLength] = FULL_STOP;
                }
                reqLength++;
            }

            labelStart = delimiter;
        }
    }else{
        for(;;){

            if(delimiter == src+srcLength){
                break;
            }

            labelLen = getNextSeparator(labelStart, remainingLen, prep, &delimiter, &done, status);

            b1Len = idnaref_toASCII(labelStart, labelLen, b1, b1Capacity,
                                    options,parseError, status);

            if(*status == U_BUFFER_OVERFLOW_ERROR){
                // redo processing of string
                /* we do not have enough room so grow the buffer*/
                b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR);
                if(b1==NULL){
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    goto CLEANUP;
                }

                *status = U_ZERO_ERROR; // reset error

                b1Len = idnaref_toASCII(labelStart, labelLen, b1, b1Len,
                                        options, parseError, status);

            }

            if(U_FAILURE(*status)){
                goto CLEANUP;
            }
            int32_t tempLen = (reqLength + b1Len );
            // copy to dest
            if( tempLen< destCapacity){
                u_memmove(dest+reqLength, b1, b1Len);
            }

            reqLength = tempLen;

            // add the label separator
            if(done == FALSE){
                if(reqLength < destCapacity){
                    dest[reqLength] = FULL_STOP;
                }
                reqLength++;
            }

            labelStart = delimiter;
            remainingLen = static_cast<int32_t>(srcLength - (delimiter - src));
        }
    }


CLEANUP:

    if(b1 != b1Stack){
        uprv_free(b1);
    }

//   delete prep;

    return u_terminateUChars(dest, destCapacity, reqLength, status);
}

U_CFUNC int32_t U_EXPORT2
idnaref_IDNToUnicode(  const UChar* src, int32_t srcLength,
                     UChar* dest, int32_t destCapacity,
                     int32_t options,
                     UParseError* parseError,
                     UErrorCode* status){

    if(status == NULL || U_FAILURE(*status)){
        return 0;
    }
    if((src == NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }

    int32_t reqLength = 0;

    UBool done = FALSE;

    NamePrepTransform* prep = getInstance(*status);

    //initialize pointers to stack buffers
    UChar b1Stack[MAX_LABEL_BUFFER_SIZE];
    UChar  *b1 = b1Stack;
    int32_t b1Len, labelLen;
    UChar* delimiter = (UChar*)src;
    UChar* labelStart = (UChar*)src;
    int32_t remainingLen = srcLength;
    int32_t b1Capacity = MAX_LABEL_BUFFER_SIZE;

    //get the options
//    UBool allowUnassigned   = (UBool)((options & IDNAREF_ALLOW_UNASSIGNED) != 0);
//    UBool useSTD3ASCIIRules = (UBool)((options & IDNAREF_USE_STD3_RULES) != 0);

    if(U_FAILURE(*status)){
        goto CLEANUP;
    }

    if(srcLength == -1){
        for(;;){

            if(*delimiter == 0){
                break;
            }

            labelLen = getNextSeparator(labelStart, -1, prep, &delimiter, &done, status);

           if(labelLen==0 && done==FALSE){
                *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR;
            }
            b1Len = idnaref_toUnicode(labelStart, labelLen, b1, b1Capacity,
                                      options, parseError, status);

            if(*status == U_BUFFER_OVERFLOW_ERROR){
                // redo processing of string
                /* we do not have enough room so grow the buffer*/
                b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR);
                if(b1==NULL){
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    goto CLEANUP;
                }

                *status = U_ZERO_ERROR; // reset error

                b1Len = idnaref_toUnicode( labelStart, labelLen, b1, b1Len,
                                           options, parseError, status);

            }

            if(U_FAILURE(*status)){
                goto CLEANUP;
            }
            int32_t tempLen = (reqLength + b1Len );
            // copy to dest
            if( tempLen< destCapacity){
                u_memmove(dest+reqLength, b1, b1Len);
            }

            reqLength = tempLen;
            // add the label separator
            if(done == FALSE){
                if(reqLength < destCapacity){
                    dest[reqLength] = FULL_STOP;
                }
                reqLength++;
            }

            labelStart = delimiter;
        }
    }else{
        for(;;){

            if(delimiter == src+srcLength){
                break;
            }

            labelLen = getNextSeparator(labelStart, remainingLen, prep, &delimiter, &done, status);

            if(labelLen==0 && done==FALSE){
                *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR;
            }

            b1Len = idnaref_toUnicode( labelStart,labelLen, b1, b1Capacity,
                                       options, parseError, status);

            if(*status == U_BUFFER_OVERFLOW_ERROR){
                // redo processing of string
                /* we do not have enough room so grow the buffer*/
                b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR);
                if(b1==NULL){
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    goto CLEANUP;
                }

                *status = U_ZERO_ERROR; // reset error

                b1Len = idnaref_toUnicode( labelStart, labelLen, b1, b1Len,
                                           options, parseError, status);

            }

            if(U_FAILURE(*status)){
                goto CLEANUP;
            }
            int32_t tempLen = (reqLength + b1Len );
            // copy to dest
            if( tempLen< destCapacity){
                u_memmove(dest+reqLength, b1, b1Len);
            }

            reqLength = tempLen;

            // add the label separator
            if(done == FALSE){
                if(reqLength < destCapacity){
                    dest[reqLength] = FULL_STOP;
                }
                reqLength++;
            }

            labelStart = delimiter;
            remainingLen = static_cast<int32_t>(srcLength - (delimiter - src));
        }
    }

CLEANUP:

    if(b1 != b1Stack){
        uprv_free(b1);
    }

//    delete prep;

    return u_terminateUChars(dest, destCapacity, reqLength, status);
}

U_CFUNC int32_t U_EXPORT2
idnaref_compare(  const UChar *s1, int32_t length1,
                const UChar *s2, int32_t length2,
                int32_t options,
                UErrorCode* status){

    if(status == NULL || U_FAILURE(*status)){
        return -1;
    }

    UChar b1Stack[MAX_IDN_BUFFER_SIZE], b2Stack[MAX_IDN_BUFFER_SIZE];
    UChar *b1 = b1Stack, *b2 = b2Stack;
    int32_t b1Len, b2Len, b1Capacity = MAX_IDN_BUFFER_SIZE, b2Capacity = MAX_IDN_BUFFER_SIZE;
    int32_t result = -1;

    UParseError parseError;

    b1Len = idnaref_IDNToASCII(s1, length1, b1, b1Capacity, options, &parseError, status);
    if(*status == U_BUFFER_OVERFLOW_ERROR){
        // redo processing of string
        /* we do not have enough room so grow the buffer*/
        b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR);
        if(b1==NULL){
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto CLEANUP;
        }

        *status = U_ZERO_ERROR; // reset error

        b1Len = idnaref_IDNToASCII(s1,length1,b1,b1Len, options, &parseError, status);

    }

    b2Len = idnaref_IDNToASCII(s2,length2,b2,b2Capacity,options, &parseError, status);
    if(*status == U_BUFFER_OVERFLOW_ERROR){
        // redo processing of string
        /* we do not have enough room so grow the buffer*/
        b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR);
        if(b2==NULL){
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto CLEANUP;
        }

        *status = U_ZERO_ERROR; // reset error

        b2Len = idnaref_IDNToASCII(s2,length2,b2,b2Len,options, &parseError, status);

    }
    // when toASCII is applied all label separators are replaced with FULL_STOP
    result = compareCaseInsensitiveASCII(b1,b1Len,b2,b2Len);

CLEANUP:
    if(b1 != b1Stack){
        uprv_free(b1);
    }

    if(b2 != b2Stack){
        uprv_free(b2);
    }

    return result;
}
#endif /* #if !UCONFIG_NO_IDNA */
