202 lines
4.7 KiB
C
202 lines
4.7 KiB
C
|
/*
|
||
|
*******************************************************************************
|
||
|
* *
|
||
|
* COPYRIGHT: *
|
||
|
* (C) Copyright International Business Machines Corporation, 1998 *
|
||
|
* Licensed Material - Program-Property of IBM - All Rights Reserved. *
|
||
|
* US Government Users Restricted Rights - Use, duplication, or disclosure *
|
||
|
* restricted by GSA ADP Schedule Contract with IBM Corp. *
|
||
|
* *
|
||
|
*******************************************************************************
|
||
|
*
|
||
|
* 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 "ufmt_cmn.h"
|
||
|
#include "uchar.h"
|
||
|
#include "ucnv.h"
|
||
|
|
||
|
int
|
||
|
ufmt_digitvalue(UChar c)
|
||
|
{
|
||
|
return c - 0x0030 - (c >= 0x0041 ? (c >= 0x0061 ? 39 : 7) : 0);
|
||
|
}
|
||
|
|
||
|
bool_t
|
||
|
ufmt_isdigit(UChar c,
|
||
|
int32_t radix)
|
||
|
{
|
||
|
int digitVal = ufmt_digitvalue(c);
|
||
|
|
||
|
return (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,
|
||
|
long value,
|
||
|
int32_t radix,
|
||
|
bool_t uselower,
|
||
|
int32_t minDigits)
|
||
|
{
|
||
|
int32_t length = 0;
|
||
|
long q;
|
||
|
int8_t digit;
|
||
|
UChar *left, *right, temp;
|
||
|
|
||
|
while(value > radix && length < *len) {
|
||
|
q = value / radix;
|
||
|
digit = (int8_t)(value - q * radix);
|
||
|
buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(digit)
|
||
|
: TO_UC_DIGIT(digit));
|
||
|
value = q;
|
||
|
}
|
||
|
|
||
|
if(length < *len) {
|
||
|
buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(value)
|
||
|
: TO_UC_DIGIT(value));
|
||
|
}
|
||
|
|
||
|
/* pad with zeroes to make it minDigits long */
|
||
|
if(minDigits != -1 && length < minDigits) {
|
||
|
while(length < minDigits && length < *len)
|
||
|
buffer[length++] = 0x0030;
|
||
|
}
|
||
|
|
||
|
/* 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;
|
||
|
}
|
||
|
|
||
|
bool_t
|
||
|
ufmt_isws(UChar c)
|
||
|
{
|
||
|
return (c == 0x0020 || /* space */
|
||
|
c == 0x0009 || /* tab */
|
||
|
c == 0x000D || /* CR */
|
||
|
c == 0x000A || /* LF */
|
||
|
c == 0x000B || /* vertical tab */
|
||
|
c == 0x000C || /* form feed */
|
||
|
u_isspace(c));
|
||
|
}
|
||
|
|
||
|
UChar*
|
||
|
ufmt_defaultCPToUnicode(const char *s,
|
||
|
int32_t len)
|
||
|
{
|
||
|
int32_t size;
|
||
|
UChar *target, *alias;
|
||
|
UConverter *defConverter;
|
||
|
UErrorCode status = ZERO_ERROR;
|
||
|
|
||
|
defConverter = ucnv_open(ucnv_getDefaultName(), &status);
|
||
|
if(FAILURE(status) || defConverter == 0)
|
||
|
return 0;
|
||
|
|
||
|
/* perform the conversion in one swoop */
|
||
|
size = (len + 1) / ucnv_getMinCharSize(defConverter);
|
||
|
target = (UChar*) malloc(size * sizeof(UChar));
|
||
|
if(target == 0) {
|
||
|
ucnv_close(defConverter);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
alias = target;
|
||
|
ucnv_toUnicode(defConverter, &alias, alias + size, &s, s + len,
|
||
|
NULL, TRUE, &status);
|
||
|
|
||
|
ucnv_close(defConverter);
|
||
|
|
||
|
/* add the null terminator */
|
||
|
*alias = 0x0000;
|
||
|
|
||
|
return target;
|
||
|
}
|
||
|
|
||
|
char*
|
||
|
ufmt_unicodeToDefaultCP(const UChar *s,
|
||
|
int32_t len)
|
||
|
{
|
||
|
int32_t size;
|
||
|
char *target, *alias;
|
||
|
const UChar *consumed = 0;
|
||
|
UConverter *defConverter;
|
||
|
UErrorCode status = ZERO_ERROR;
|
||
|
|
||
|
defConverter = ucnv_open(ucnv_getDefaultName(), &status);
|
||
|
if(FAILURE(status) || defConverter == 0)
|
||
|
return 0;
|
||
|
|
||
|
/* perform the conversion in one swoop */
|
||
|
target = (char*)
|
||
|
malloc((len + 1) * ucnv_getMaxCharSize(defConverter) * sizeof(char));
|
||
|
if(target == 0) {
|
||
|
ucnv_close(defConverter);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
alias = target;
|
||
|
ucnv_fromUnicode(defConverter, &alias, alias + size, &s, s + len,
|
||
|
NULL, TRUE, &status);
|
||
|
|
||
|
ucnv_close(defConverter);
|
||
|
|
||
|
/* add the null terminator */
|
||
|
*alias = 0x00;
|
||
|
|
||
|
return target;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|