ICU-5092 Replace the temporary pointer parsing hack with a permanent platform independent parsing function.
X-SVN-Rev: 19451
This commit is contained in:
parent
406830baf5
commit
722f647186
@ -1,7 +1,7 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2004, International Business Machines
|
||||
* Copyright (C) 1998-2006, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
@ -39,7 +39,7 @@ ufmt_digitvalue(UChar c)
|
||||
((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
|
||||
{
|
||||
@ -56,8 +56,8 @@ ufmt_isdigit(UChar c,
|
||||
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,
|
||||
@ -81,7 +81,7 @@ 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 */
|
||||
@ -158,37 +158,64 @@ ufmt_uto64(const UChar *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*
|
||||
|
@ -1031,37 +1031,6 @@ u_scanf_pointer_handler(UFILE *input,
|
||||
len = ufmt_min(len, info->fWidth);
|
||||
}
|
||||
|
||||
#ifdef OS400
|
||||
/* TODO: Fix this code so that it will work on all platforms */
|
||||
{
|
||||
int64_t result[2];
|
||||
int32_t lenOrig = len;
|
||||
|
||||
/* Make sure that we don't consume too much */
|
||||
if (len > (int32_t)(sizeof(int64_t)*2)) {
|
||||
len = (int32_t)(sizeof(int64_t)*2);
|
||||
}
|
||||
|
||||
/* parse the pointer - set first half of big endian pointer */
|
||||
result[0] = (int64_t)ufmt_utop(input->str.fPos, &len);
|
||||
|
||||
/* update the input's position to reflect consumed data */
|
||||
input->str.fPos += len;
|
||||
len = lenOrig - len;
|
||||
|
||||
/* Make sure that we don't consume too much */
|
||||
if (len > (int32_t)(sizeof(int64_t)*2)) {
|
||||
len = (int32_t)(sizeof(int64_t)*2);
|
||||
}
|
||||
|
||||
/* parse the pointer - set second half of big endian pointer */
|
||||
result[1] = (int64_t)ufmt_utop(input->str.fPos, &len);
|
||||
|
||||
if (!info->fSkipArg) {
|
||||
p = *((void **)result);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Make sure that we don't consume too much */
|
||||
if (len > (int32_t)(sizeof(void*)*2)) {
|
||||
len = (int32_t)(sizeof(void*)*2);
|
||||
@ -1074,8 +1043,6 @@ u_scanf_pointer_handler(UFILE *input,
|
||||
*p = result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* update the input's position to reflect consumed data */
|
||||
input->str.fPos += len;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user