| /* |
| ****************************************************************************** |
| * |
| * 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; |
| } |
| |
| |
| |