/*
******************************************************************************
*
*   Copyright (C) 1998-2001, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
******************************************************************************
*
* File ufmt_cmn.c
*
* Modification History:
*
*   Date        Name        Description
*   12/02/98    stephen     Creation.
*   03/12/99    stephen     Modified for new C API.
*   03/15/99    stephen     Added defaultCPToUnicode, unicodeToDefaultCP
*   07/19/99    stephen     Fixed bug in defaultCPToUnicode
******************************************************************************
*/

#include "cmemory.h"
#include "ufmt_cmn.h"
#include "unicode/uchar.h"
#include "unicode/ucnv.h"
#include "ustr_imp.h"

#define DIGIT_0     0x0030
#define DIGIT_9     0x0039
#define LOWERCASE_A 0x0061
#define UPPERCASE_A 0x0041
#define LOWERCASE_Z 0x007A
#define UPPERCASE_Z 0x005A

int
ufmt_digitvalue(UChar c)
{
    if( ((c>=DIGIT_0)&&(c<=DIGIT_9)) ||
        ((c>=LOWERCASE_A)&&(c<=LOWERCASE_Z)) ||
        ((c>=UPPERCASE_A)&&(c<=UPPERCASE_Z))  )
    {
      return c - 0x0030 - (c >= 0x0041 ? (c >= 0x0061 ? 39 : 7) : 0);
    }
    else
    {
      return -1;
    }
}

UBool
ufmt_isdigit(UChar     c,
             int32_t     radix)
{
    int digitVal = ufmt_digitvalue(c);

    return (UBool)(digitVal < radix && digitVal >= 0);
}

#define TO_UC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0030 + a + 7)
#define TO_LC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0030 + a + 39)

void 
ufmt_ltou(UChar     *buffer, 
          int32_t   *len,
          uint32_t  value, 
          uint32_t  radix,
          UBool     uselower,
          int32_t   minDigits)
{
    int32_t  length = 0;
    uint32_t digit;
    UChar    *left, *right, temp;
    
    do {
        digit = value % radix;
        value = value / radix;
        buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(digit) 
            : TO_UC_DIGIT(digit));
    } while(value);

    /* pad with zeroes to make it minDigits long */
    if(minDigits != -1 && length < minDigits) {
        while(length < minDigits && length < *len)
            buffer[length++] = 0x0030;  /*zero padding */
    }

    /* reverse the buffer */
    left     = buffer;
    right = buffer + length;
    while(left < --right) {
        temp     = *left;
        *left++     = *right;
        *right     = temp;
    }
    
    *len = length;
}

long
ufmt_utol(const UChar     *buffer, 
          int32_t     *len,
          int32_t     radix)
{
    const UChar     *limit;
    int32_t         count;
    long        result;
    
    
    /* intialize parameters */
    limit     = buffer + *len;
    count     = 0;
    result     = 0;
    
    /* iterate through buffer */
    while(ufmt_isdigit(*buffer, radix) && buffer < limit) {
        
        /* read the next digit */
        result *= radix;
        result += ufmt_digitvalue(*buffer++);
        
        /* increment our count */
        ++count;
    }
    
    *len = count;
    return result;
}

UChar*
ufmt_defaultCPToUnicode(const char *s,
                        int32_t len)
{
    int32_t size;
    UChar *target, *alias;
    UErrorCode status = U_ZERO_ERROR;
    UConverter *defConverter = u_getDefaultConverter(&status);
    
    if(U_FAILURE(status) || defConverter == 0)
        return 0;
    
    /* perform the conversion in one swoop */
    size = (len + 1) / ucnv_getMinCharSize(defConverter);
    target = (UChar*) uprv_malloc(size * sizeof(UChar));
    if(target != 0) {
        
        alias = target;
        ucnv_toUnicode(defConverter, &alias, alias + size, &s, s + len, 
            NULL, TRUE, &status);
        
        
        /* add the null terminator */
        *alias = 0x0000;
    }
    
    u_releaseDefaultConverter(defConverter);
    
    return target;
}

char*
ufmt_unicodeToDefaultCP(const UChar *s,
                        int32_t len)
{
    int32_t size;
    char *target, *alias;
    UErrorCode status = U_ZERO_ERROR;
    UConverter *defConverter = u_getDefaultConverter(&status);
    
    if(U_FAILURE(status) || defConverter == 0)
        return 0;
    
    /* perform the conversion in one swoop */
    target = (char*) 
        uprv_malloc((len + 1) * ucnv_getMaxCharSize(defConverter) * sizeof(char));
    size = (len) * ucnv_getMaxCharSize(defConverter) * sizeof(char);
    if(target != 0) {
        
        alias = target;
        ucnv_fromUnicode(defConverter, &alias, alias + size, &s, s + len, 
            NULL, TRUE, &status);
        
        
        /* add the null terminator */
        *alias = 0x00;
    }
    
    u_releaseDefaultConverter(defConverter);
    
    return target;
}



