]> git.saurik.com Git - apple/icu.git/blame - icuSources/io/ufmt_cmn.c
ICU-491.11.3.tar.gz
[apple/icu.git] / icuSources / io / ufmt_cmn.c
CommitLineData
b75a7d8f
A
1/*
2******************************************************************************
3*
73c04bcf 4* Copyright (C) 1998-2006, International Business Machines
b75a7d8f
A
5* Corporation and others. All Rights Reserved.
6*
7******************************************************************************
8*
9* File ufmt_cmn.c
10*
11* Modification History:
12*
13* Date Name Description
14* 12/02/98 stephen Creation.
15* 03/12/99 stephen Modified for new C API.
16* 03/15/99 stephen Added defaultCPToUnicode, unicodeToDefaultCP
17* 07/19/99 stephen Fixed bug in defaultCPToUnicode
18******************************************************************************
19*/
20
21#include "cstring.h"
22#include "cmemory.h"
23#include "ufmt_cmn.h"
24#include "unicode/uchar.h"
25#include "unicode/ucnv.h"
374ca955 26#include "ustr_cnv.h"
b75a7d8f
A
27
28#define DIGIT_0 0x0030
29#define DIGIT_9 0x0039
30#define LOWERCASE_A 0x0061
31#define UPPERCASE_A 0x0041
32#define LOWERCASE_Z 0x007A
33#define UPPERCASE_Z 0x005A
34
35int
36ufmt_digitvalue(UChar c)
37{
38 if( ((c>=DIGIT_0)&&(c<=DIGIT_9)) ||
39 ((c>=LOWERCASE_A)&&(c<=LOWERCASE_Z)) ||
40 ((c>=UPPERCASE_A)&&(c<=UPPERCASE_Z)) )
41 {
73c04bcf 42 return c - DIGIT_0 - (c >= 0x0041 ? (c >= 0x0061 ? 39 : 7) : 0);
b75a7d8f
A
43 }
44 else
45 {
46 return -1;
47 }
48}
49
50UBool
51ufmt_isdigit(UChar c,
52 int32_t radix)
53{
54 int digitVal = ufmt_digitvalue(c);
55
56 return (UBool)(digitVal < radix && digitVal >= 0);
57}
58
73c04bcf
A
59#define TO_UC_DIGIT(a) a <= 9 ? (DIGIT_0 + a) : (0x0037 + a)
60#define TO_LC_DIGIT(a) a <= 9 ? (DIGIT_0 + a) : (0x0057 + a)
b75a7d8f
A
61
62void
374ca955 63ufmt_64tou(UChar *buffer,
b75a7d8f 64 int32_t *len,
374ca955
A
65 uint64_t value,
66 uint8_t radix,
b75a7d8f
A
67 UBool uselower,
68 int32_t minDigits)
69{
70 int32_t length = 0;
71 uint32_t digit;
72 UChar *left, *right, temp;
73
74 do {
374ca955 75 digit = (uint32_t)(value % radix);
b75a7d8f
A
76 value = value / radix;
77 buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(digit)
78 : TO_UC_DIGIT(digit));
79 } while(value);
80
81 /* pad with zeroes to make it minDigits long */
82 if(minDigits != -1 && length < minDigits) {
83 while(length < minDigits && length < *len)
73c04bcf 84 buffer[length++] = DIGIT_0; /*zero padding */
b75a7d8f
A
85 }
86
87 /* reverse the buffer */
88 left = buffer;
89 right = buffer + length;
90 while(left < --right) {
91 temp = *left;
92 *left++ = *right;
93 *right = temp;
94 }
95
96 *len = length;
97}
98
374ca955
A
99void
100ufmt_ptou(UChar *buffer,
101 int32_t *len,
102 void *value,
103 UBool uselower)
104{
105 int32_t i;
106 int32_t length = 0;
107 uint8_t *ptrIdx = (uint8_t *)&value;
108
109#if U_IS_BIG_ENDIAN
110 for (i = 0; i < (int32_t)sizeof(void *); i++)
111#else
112 for (i = (int32_t)sizeof(void *)-1; i >= 0 ; i--)
113#endif
114 {
115 uint8_t byteVal = ptrIdx[i];
116 uint16_t firstNibble = (uint16_t)(byteVal>>4);
117 uint16_t secondNibble = (uint16_t)(byteVal&0xF);
118 if (uselower) {
119 buffer[length++]=TO_LC_DIGIT(firstNibble);
120 buffer[length++]=TO_LC_DIGIT(secondNibble);
121 }
122 else {
123 buffer[length++]=TO_UC_DIGIT(firstNibble);
124 buffer[length++]=TO_UC_DIGIT(secondNibble);
125 }
126 }
127
128 *len = length;
129}
130
131int64_t
132ufmt_uto64(const UChar *buffer,
b75a7d8f 133 int32_t *len,
374ca955 134 int8_t radix)
b75a7d8f
A
135{
136 const UChar *limit;
137 int32_t count;
374ca955 138 int64_t result;
b75a7d8f
A
139
140
141 /* intialize parameters */
142 limit = buffer + *len;
143 count = 0;
374ca955 144 result = 0;
b75a7d8f
A
145
146 /* iterate through buffer */
147 while(ufmt_isdigit(*buffer, radix) && buffer < limit) {
148
149 /* read the next digit */
150 result *= radix;
151 result += ufmt_digitvalue(*buffer++);
152
153 /* increment our count */
154 ++count;
155 }
156
157 *len = count;
158 return result;
159}
160
73c04bcf 161#define NIBBLE_PER_BYTE 2
374ca955
A
162void *
163ufmt_utop(const UChar *buffer,
164 int32_t *len)
165{
73c04bcf
A
166 int32_t count, resultIdx, incVal, offset;
167 /* This union allows the pointer to be written as an array. */
168 union {
169 void *ptr;
170 uint8_t bytes[sizeof(void*)];
171 } result;
374ca955 172
73c04bcf
A
173 /* intialize variables */
174 count = 0;
175 offset = 0;
176 result.ptr = NULL;
177
178 /* Skip the leading zeros */
179 while(buffer[count] == DIGIT_0 || u_isspace(buffer[count])) {
180 count++;
181 offset++;
182 }
183
184 /* iterate through buffer, stop when you hit the end */
185 while(ufmt_isdigit(buffer[count], 16) && count < *len) {
186 /* increment the count consumed */
374ca955
A
187 ++count;
188 }
73c04bcf
A
189
190 /* detect overflow */
191 if (count - offset > (int32_t)(sizeof(void*)*NIBBLE_PER_BYTE)) {
192 offset = count - (int32_t)(sizeof(void*)*NIBBLE_PER_BYTE);
193 }
374ca955 194
73c04bcf
A
195 /* Initialize the direction of the input */
196#if U_IS_BIG_ENDIAN
197 incVal = -1;
198 resultIdx = (int32_t)(sizeof(void*) - 1);
199#else
200 incVal = 1;
201 resultIdx = 0;
202#endif
203 /* Write how much was consumed. */
374ca955 204 *len = count;
73c04bcf
A
205 while(--count >= offset) {
206 /* Get the first nibble of the byte */
207 uint8_t byte = (uint8_t)ufmt_digitvalue(buffer[count]);
208
209 if (count > offset) {
210 /* Get the second nibble of the byte when available */
211 byte = (uint8_t)(byte + (ufmt_digitvalue(buffer[--count]) << 4));
212 }
213 /* Write the byte into the array */
214 result.bytes[resultIdx] = byte;
215 resultIdx += incVal;
216 }
217
218 return result.ptr;
374ca955
A
219}
220
b75a7d8f
A
221UChar*
222ufmt_defaultCPToUnicode(const char *s, int32_t sSize,
223 UChar *target, int32_t tSize)
224{
225 UChar *alias;
226 UErrorCode status = U_ZERO_ERROR;
227 UConverter *defConverter = u_getDefaultConverter(&status);
228
229 if(U_FAILURE(status) || defConverter == 0)
230 return 0;
231
232 if(sSize <= 0) {
233 sSize = uprv_strlen(s) + 1;
234 }
235
236 /* perform the conversion in one swoop */
237 if(target != 0) {
238
239 alias = target;
240 ucnv_toUnicode(defConverter, &alias, alias + tSize, &s, s + sSize - 1,
241 NULL, TRUE, &status);
242
243
244 /* add the null terminator */
245 *alias = 0x0000;
246 }
247
248 u_releaseDefaultConverter(defConverter);
249
250 return target;
251}
252
b75a7d8f 253