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