Index: icu46/source/io/ufmt_cmn.c |
=================================================================== |
--- icu46/source/io/ufmt_cmn.c (revision 0) |
+++ icu46/source/io/ufmt_cmn.c (revision 0) |
@@ -0,0 +1,253 @@ |
+/* |
+****************************************************************************** |
+* |
+* Copyright (C) 1998-2006, 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 "cstring.h" |
+#include "cmemory.h" |
+#include "ufmt_cmn.h" |
+#include "unicode/uchar.h" |
+#include "unicode/ucnv.h" |
+#include "ustr_cnv.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 - DIGIT_0 - (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 ? (DIGIT_0 + a) : (0x0037 + a) |
+#define TO_LC_DIGIT(a) a <= 9 ? (DIGIT_0 + a) : (0x0057 + a) |
+ |
+void |
+ufmt_64tou(UChar *buffer, |
+ int32_t *len, |
+ uint64_t value, |
+ uint8_t radix, |
+ UBool uselower, |
+ int32_t minDigits) |
+{ |
+ int32_t length = 0; |
+ uint32_t digit; |
+ UChar *left, *right, temp; |
+ |
+ do { |
+ digit = (uint32_t)(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++] = DIGIT_0; /*zero padding */ |
+ } |
+ |
+ /* reverse the buffer */ |
+ left = buffer; |
+ right = buffer + length; |
+ while(left < --right) { |
+ temp = *left; |
+ *left++ = *right; |
+ *right = temp; |
+ } |
+ |
+ *len = length; |
+} |
+ |
+void |
+ufmt_ptou(UChar *buffer, |
+ int32_t *len, |
+ void *value, |
+ UBool uselower) |
+{ |
+ int32_t i; |
+ int32_t length = 0; |
+ uint8_t *ptrIdx = (uint8_t *)&value; |
+ |
+#if U_IS_BIG_ENDIAN |
+ for (i = 0; i < (int32_t)sizeof(void *); i++) |
+#else |
+ for (i = (int32_t)sizeof(void *)-1; i >= 0 ; i--) |
+#endif |
+ { |
+ uint8_t byteVal = ptrIdx[i]; |
+ uint16_t firstNibble = (uint16_t)(byteVal>>4); |
+ uint16_t secondNibble = (uint16_t)(byteVal&0xF); |
+ if (uselower) { |
+ buffer[length++]=TO_LC_DIGIT(firstNibble); |
+ buffer[length++]=TO_LC_DIGIT(secondNibble); |
+ } |
+ else { |
+ buffer[length++]=TO_UC_DIGIT(firstNibble); |
+ buffer[length++]=TO_UC_DIGIT(secondNibble); |
+ } |
+ } |
+ |
+ *len = length; |
+} |
+ |
+int64_t |
+ufmt_uto64(const UChar *buffer, |
+ int32_t *len, |
+ int8_t radix) |
+{ |
+ const UChar *limit; |
+ int32_t count; |
+ int64_t 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; |
+} |
+ |
+#define NIBBLE_PER_BYTE 2 |
+void * |
+ufmt_utop(const UChar *buffer, |
+ int32_t *len) |
+{ |
+ int32_t count, resultIdx, incVal, offset; |
+ /* This union allows the pointer to be written as an array. */ |
+ union { |
+ void *ptr; |
+ uint8_t bytes[sizeof(void*)]; |
+ } result; |
+ |
+ /* intialize variables */ |
+ count = 0; |
+ offset = 0; |
+ result.ptr = NULL; |
+ |
+ /* Skip the leading zeros */ |
+ while(buffer[count] == DIGIT_0 || u_isspace(buffer[count])) { |
+ count++; |
+ offset++; |
+ } |
+ |
+ /* iterate through buffer, stop when you hit the end */ |
+ while(ufmt_isdigit(buffer[count], 16) && count < *len) { |
+ /* increment the count consumed */ |
+ ++count; |
+ } |
+ |
+ /* detect overflow */ |
+ if (count - offset > (int32_t)(sizeof(void*)*NIBBLE_PER_BYTE)) { |
+ offset = count - (int32_t)(sizeof(void*)*NIBBLE_PER_BYTE); |
+ } |
+ |
+ /* Initialize the direction of the input */ |
+#if U_IS_BIG_ENDIAN |
+ incVal = -1; |
+ resultIdx = (int32_t)(sizeof(void*) - 1); |
+#else |
+ incVal = 1; |
+ resultIdx = 0; |
+#endif |
+ /* Write how much was consumed. */ |
+ *len = count; |
+ while(--count >= offset) { |
+ /* Get the first nibble of the byte */ |
+ uint8_t byte = (uint8_t)ufmt_digitvalue(buffer[count]); |
+ |
+ if (count > offset) { |
+ /* Get the second nibble of the byte when available */ |
+ byte = (uint8_t)(byte + (ufmt_digitvalue(buffer[--count]) << 4)); |
+ } |
+ /* Write the byte into the array */ |
+ result.bytes[resultIdx] = byte; |
+ resultIdx += incVal; |
+ } |
+ |
+ return result.ptr; |
+} |
+ |
+UChar* |
+ufmt_defaultCPToUnicode(const char *s, int32_t sSize, |
+ UChar *target, int32_t tSize) |
+{ |
+ UChar *alias; |
+ UErrorCode status = U_ZERO_ERROR; |
+ UConverter *defConverter = u_getDefaultConverter(&status); |
+ |
+ if(U_FAILURE(status) || defConverter == 0) |
+ return 0; |
+ |
+ if(sSize <= 0) { |
+ sSize = uprv_strlen(s) + 1; |
+ } |
+ |
+ /* perform the conversion in one swoop */ |
+ if(target != 0) { |
+ |
+ alias = target; |
+ ucnv_toUnicode(defConverter, &alias, alias + tSize, &s, s + sSize - 1, |
+ NULL, TRUE, &status); |
+ |
+ |
+ /* add the null terminator */ |
+ *alias = 0x0000; |
+ } |
+ |
+ u_releaseDefaultConverter(defConverter); |
+ |
+ return target; |
+} |
+ |
+ |
Property changes on: icu46/source/io/ufmt_cmn.c |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |