]>
git.saurik.com Git - apple/icu.git/blob - icuSources/io/ufmt_cmn.cpp
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 ******************************************************************************
6 * Copyright (C) 1998-2014, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 ******************************************************************************
13 * Modification History:
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 ******************************************************************************
26 #include "unicode/uchar.h"
27 #include "unicode/ucnv.h"
30 #if !UCONFIG_NO_CONVERSION
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
41 ufmt_digitvalue(UChar c
)
43 if( ((c
>=DIGIT_0
)&&(c
<=DIGIT_9
)) ||
44 ((c
>=LOWERCASE_A
)&&(c
<=LOWERCASE_Z
)) ||
45 ((c
>=UPPERCASE_A
)&&(c
<=UPPERCASE_Z
)) )
47 return c
- DIGIT_0
- (c
>= 0x0041 ? (c
>= 0x0061 ? 39 : 7) : 0);
59 int digitVal
= ufmt_digitvalue(c
);
61 return (UBool
)(digitVal
< radix
&& digitVal
>= 0);
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)
68 ufmt_64tou(UChar
*buffer
,
77 UChar
*left
, *right
, temp
;
80 digit
= (uint32_t)(value
% radix
);
81 value
= value
/ radix
;
82 buffer
[length
++] = (UChar
)(uselower
? TO_LC_DIGIT(digit
)
83 : TO_UC_DIGIT(digit
));
86 /* pad with zeroes to make it minDigits long */
87 if(minDigits
!= -1 && length
< minDigits
) {
88 while(length
< minDigits
&& length
< *len
)
89 buffer
[length
++] = DIGIT_0
; /*zero padding */
92 /* reverse the buffer */
94 right
= buffer
+ length
;
95 while(left
< --right
) {
105 ufmt_ptou(UChar
*buffer
,
112 uint8_t *ptrIdx
= (uint8_t *)&value
;
115 for (i
= 0; i
< (int32_t)sizeof(void *); i
++)
117 for (i
= (int32_t)sizeof(void *)-1; i
>= 0 ; i
--)
120 uint8_t byteVal
= ptrIdx
[i
];
121 uint16_t firstNibble
= (uint16_t)(byteVal
>>4);
122 uint16_t secondNibble
= (uint16_t)(byteVal
&0xF);
124 buffer
[length
++]=TO_LC_DIGIT(firstNibble
);
125 buffer
[length
++]=TO_LC_DIGIT(secondNibble
);
128 buffer
[length
++]=TO_UC_DIGIT(firstNibble
);
129 buffer
[length
++]=TO_UC_DIGIT(secondNibble
);
137 ufmt_uto64(const UChar
*buffer
,
146 /* intialize parameters */
147 limit
= buffer
+ *len
;
151 /* iterate through buffer */
152 while(ufmt_isdigit(*buffer
, radix
) && buffer
< limit
) {
154 /* read the next digit */
156 result
+= ufmt_digitvalue(*buffer
++);
158 /* increment our count */
166 #define NIBBLE_PER_BYTE 2
168 ufmt_utop(const UChar
*buffer
,
171 int32_t count
, resultIdx
, incVal
, offset
;
172 /* This union allows the pointer to be written as an array. */
175 uint8_t bytes
[sizeof(void*)];
178 /* intialize variables */
183 /* Skip the leading zeros */
184 while(buffer
[count
] == DIGIT_0
|| u_isspace(buffer
[count
])) {
189 /* iterate through buffer, stop when you hit the end */
190 while(count
< *len
&& ufmt_isdigit(buffer
[count
], 16)) {
191 /* increment the count consumed */
195 /* detect overflow */
196 if (count
- offset
> (int32_t)(sizeof(void*)*NIBBLE_PER_BYTE
)) {
197 offset
= count
- (int32_t)(sizeof(void*)*NIBBLE_PER_BYTE
);
200 /* Initialize the direction of the input */
203 resultIdx
= (int32_t)(sizeof(void*) - 1);
208 /* Write how much was consumed. */
210 while(--count
>= offset
) {
211 /* Get the first nibble of the byte */
212 uint8_t byte
= (uint8_t)ufmt_digitvalue(buffer
[count
]);
214 if (count
> offset
) {
215 /* Get the second nibble of the byte when available */
216 byte
= (uint8_t)(byte
+ (ufmt_digitvalue(buffer
[--count
]) << 4));
218 /* Write the byte into the array */
219 result
.bytes
[resultIdx
] = byte
;
227 ufmt_defaultCPToUnicode(const char *s
, int32_t sSize
,
228 UChar
*target
, int32_t tSize
)
231 UErrorCode status
= U_ZERO_ERROR
;
232 UConverter
*defConverter
= u_getDefaultConverter(&status
);
234 if(U_FAILURE(status
) || defConverter
== 0)
238 sSize
= uprv_strlen(s
) + 1;
241 /* perform the conversion in one swoop */
245 ucnv_toUnicode(defConverter
, &alias
, alias
+ tSize
, &s
, s
+ sSize
- 1,
246 NULL
, TRUE
, &status
);
249 /* add the null terminator */
253 u_releaseDefaultConverter(defConverter
);