/*
******************************************************************************
*
-* Copyright (C) 1998-2004, International Business Machines
+* Copyright (C) 1998-2006, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
((c>=LOWERCASE_A)&&(c<=LOWERCASE_Z)) ||
((c>=UPPERCASE_A)&&(c<=UPPERCASE_Z)) )
{
- return c - 0x0030 - (c >= 0x0041 ? (c >= 0x0061 ? 39 : 7) : 0);
+ return c - DIGIT_0 - (c >= 0x0041 ? (c >= 0x0061 ? 39 : 7) : 0);
}
else
{
return (UBool)(digitVal < radix && digitVal >= 0);
}
-#define TO_UC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0037 + a)
-#define TO_LC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0057 + a)
+#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,
/* pad with zeroes to make it minDigits long */
if(minDigits != -1 && length < minDigits) {
while(length < minDigits && length < *len)
- buffer[length++] = 0x0030; /*zero padding */
+ buffer[length++] = DIGIT_0; /*zero padding */
}
/* reverse the buffer */
return result;
}
+#define NIBBLE_PER_BYTE 2
void *
ufmt_utop(const UChar *buffer,
int32_t *len)
{
- /*
- TODO: Fix this code so that it will work with pointers that are 2<=sizeof(void*)<=16
- */
- const UChar *limit;
- int32_t count;
- int64_t result;
+ 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 parameters */
- limit = buffer + *len;
- count = 0;
- result = 0;
-
- /* iterate through buffer */
- /* limit to sixteen iterations since that is the max that an int64_t can contain for pointer work */
- while(ufmt_isdigit(*buffer, 16) && buffer < limit) {
-
- /* read the next digit */
- result *= 16;
- result += ufmt_digitvalue(*buffer++);
-
- /* increment our count */
+ /* 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;
- return (void *)result;
+ 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*