00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022 #include "ufmt_cmn.h"
00023 #include "unicode/uchar.h"
00024 #include "unicode/ucnv.h"
00025 #include "umutex.h"
00026
00027 int
00028 ufmt_digitvalue(UChar c)
00029 {
00030 return c - 0x0030 - (c >= 0x0041 ? (c >= 0x0061 ? 39 : 7) : 0);
00031 }
00032
00033 UBool
00034 ufmt_isdigit(UChar c,
00035 int32_t radix)
00036 {
00037 int digitVal = ufmt_digitvalue(c);
00038
00039 return (UBool)(digitVal < radix && digitVal >= 0);
00040 }
00041
00042 #define TO_UC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0030 + a + 7)
00043 #define TO_LC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0030 + a + 39)
00044
00045 void
00046 ufmt_ltou(UChar *buffer,
00047 int32_t *len,
00048 long value,
00049 int32_t radix,
00050 UBool uselower,
00051 int32_t minDigits)
00052 {
00053 int32_t length = 0;
00054 long q;
00055 int8_t digit;
00056 UChar *left, *right, temp;
00057
00058 while(value > radix && length < *len) {
00059 q = value / radix;
00060 digit = (int8_t)(value - q * radix);
00061 buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(digit)
00062 : TO_UC_DIGIT(digit));
00063 value = q;
00064 }
00065
00066 if(length < *len) {
00067 buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(value)
00068 : TO_UC_DIGIT(value));
00069 }
00070
00071
00072 if(minDigits != -1 && length < minDigits) {
00073 while(length < minDigits && length < *len)
00074 buffer[length++] = 0x0030;
00075 }
00076
00077
00078 left = buffer;
00079 right = buffer + length;
00080 while(left < --right) {
00081 temp = *left;
00082 *left++ = *right;
00083 *right = temp;
00084 }
00085
00086 *len = length;
00087 }
00088
00089 long
00090 ufmt_utol(const UChar *buffer,
00091 int32_t *len,
00092 int32_t radix)
00093 {
00094 const UChar *limit;
00095 int32_t count;
00096 long result;
00097
00098
00099
00100 limit = buffer + *len;
00101 count = 0;
00102 result = 0;
00103
00104
00105 while(ufmt_isdigit(*buffer, radix) && buffer < limit) {
00106
00107
00108 result *= radix;
00109 result += ufmt_digitvalue(*buffer++);
00110
00111
00112 ++count;
00113 }
00114
00115 *len = count;
00116 return result;
00117 }
00118
00119 UBool
00120 ufmt_isws(UChar c)
00121 {
00122 return (UBool)(c == 0x0020 ||
00123 c == 0x0009 ||
00124 c == 0x000D ||
00125 c == 0x000A ||
00126 c == 0x000B ||
00127 c == 0x000C ||
00128 u_isspace(c));
00129 }
00130
00131 UConverter *gDef = NULL;
00132
00133 UChar*
00134 ufmt_defaultCPToUnicode(const char *s,
00135 int32_t len)
00136 {
00137 int32_t size;
00138 UChar *target, *alias;
00139 UConverter *defConverter = NULL;
00140 UErrorCode status = U_ZERO_ERROR;
00141
00142 umtx_lock(NULL);
00143 if(gDef != NULL)
00144 {
00145 defConverter = gDef;
00146 gDef = NULL;
00147 }
00148 umtx_unlock(NULL);
00149
00150 if(defConverter == NULL)
00151 defConverter = ucnv_open(ucnv_getDefaultName(), &status);
00152
00153 if(U_FAILURE(status) || defConverter == 0)
00154 return 0;
00155
00156
00157 size = (len + 1) / ucnv_getMinCharSize(defConverter);
00158 target = (UChar*) malloc(size * sizeof(UChar));
00159 if(target != 0) {
00160
00161 alias = target;
00162 ucnv_toUnicode(defConverter, &alias, alias + size, &s, s + len,
00163 NULL, TRUE, &status);
00164
00165
00166
00167 *alias = 0x0000;
00168 }
00169
00170 umtx_lock(NULL);
00171 if(gDef == NULL)
00172 {
00173 gDef = defConverter;
00174 defConverter = NULL;
00175 }
00176 umtx_unlock(NULL);
00177
00178 if(defConverter != NULL) {
00179 ucnv_close(defConverter);
00180 }
00181
00182 return target;
00183 }
00184
00185 char*
00186 ufmt_unicodeToDefaultCP(const UChar *s,
00187 int32_t len)
00188 {
00189 int32_t size;
00190 char *target, *alias;
00191 UConverter *defConverter = NULL;
00192 UErrorCode status = U_ZERO_ERROR;
00193
00194 umtx_lock(NULL);
00195 if(gDef != NULL)
00196 {
00197 defConverter = gDef;
00198 gDef = NULL;
00199 }
00200 umtx_unlock(NULL);
00201
00202 if(defConverter == NULL)
00203 defConverter = ucnv_open(ucnv_getDefaultName(), &status);
00204
00205 if(U_FAILURE(status) || defConverter == 0)
00206 return 0;
00207
00208
00209 target = (char*)
00210 malloc((len + 1) * ucnv_getMaxCharSize(defConverter) * sizeof(char));
00211 size = (len) * ucnv_getMaxCharSize(defConverter) * sizeof(char);
00212 if(target != 0) {
00213
00214 alias = target;
00215 ucnv_fromUnicode(defConverter, &alias, alias + size, &s, s + len,
00216 NULL, TRUE, &status);
00217
00218
00219
00220 *alias = 0x00;
00221 }
00222
00223 umtx_lock(NULL);
00224 if(gDef == NULL)
00225 {
00226 gDef = defConverter;
00227 defConverter = NULL;
00228 }
00229 umtx_unlock(NULL);
00230
00231 if(defConverter != NULL) {
00232 ucnv_close(defConverter);
00233 }
00234
00235 return target;
00236 }
00237
00238
00239
00240