| 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
|
|
|
|
|