]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
51004dcb | 4 | * Copyright (C) 1998-2012, International Business Machines |
b75a7d8f A |
5 | * Corporation and others. All Rights Reserved. |
6 | * | |
7 | ******************************************************************************* | |
8 | * | |
9 | * File ustr.c | |
10 | * | |
11 | * Modification History: | |
12 | * | |
13 | * Date Name Description | |
14 | * 05/28/99 stephen Creation. | |
15 | ******************************************************************************* | |
16 | */ | |
17 | ||
18 | #include "ustr.h" | |
19 | #include "cmemory.h" | |
20 | #include "cstring.h" | |
21 | #include "unicode/ustring.h" | |
374ca955 | 22 | #include "unicode/putil.h" |
51004dcb | 23 | #include "unicode/utf16.h" |
b75a7d8f A |
24 | |
25 | /* Protos */ | |
26 | static void ustr_resize(struct UString *s, int32_t len, UErrorCode *status); | |
27 | ||
28 | /* Macros */ | |
29 | #define ALLOCATION(minSize) (minSize < 0x80 ? 0x80 : (2 * minSize + 0x80) & ~(0x80 - 1)) | |
30 | ||
4388f060 | 31 | U_CFUNC void |
b75a7d8f A |
32 | ustr_init(struct UString *s) |
33 | { | |
34 | s->fChars = 0; | |
35 | s->fLength = s->fCapacity = 0; | |
36 | } | |
37 | ||
4388f060 | 38 | U_CFUNC void |
b75a7d8f A |
39 | ustr_initChars(struct UString *s, const char* source, int32_t length, UErrorCode *status) |
40 | { | |
41 | int i = 0; | |
42 | if (U_FAILURE(*status)) return; | |
43 | s->fChars = 0; | |
44 | s->fLength = s->fCapacity = 0; | |
45 | if (length == -1) { | |
46 | length = (int32_t)uprv_strlen(source); | |
47 | } | |
48 | if(s->fCapacity < length) { | |
49 | ustr_resize(s, ALLOCATION(length), status); | |
50 | if(U_FAILURE(*status)) return; | |
51 | } | |
52 | for (; i < length; i++) | |
53 | { | |
54 | UChar charToAppend; | |
55 | u_charsToUChars(source+i, &charToAppend, 1); | |
56 | ustr_ucat(s, charToAppend, status); | |
57 | /* | |
58 | #if U_CHARSET_FAMILY==U_ASCII_FAMILY | |
59 | ustr_ucat(s, (UChar)(uint8_t)(source[i]), status); | |
60 | #elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY | |
61 | ustr_ucat(s, (UChar)asciiFromEbcdic[(uint8_t)(*cs++)], status); | |
62 | #else | |
63 | # error U_CHARSET_FAMILY is not valid | |
64 | #endif | |
65 | */ | |
66 | } | |
67 | } | |
68 | ||
4388f060 | 69 | U_CFUNC void |
b75a7d8f A |
70 | ustr_deinit(struct UString *s) |
71 | { | |
46f4442e A |
72 | if (s) { |
73 | uprv_free(s->fChars); | |
74 | s->fChars = 0; | |
75 | s->fLength = s->fCapacity = 0; | |
76 | } | |
b75a7d8f A |
77 | } |
78 | ||
4388f060 | 79 | U_CFUNC void |
b75a7d8f A |
80 | ustr_cpy(struct UString *dst, |
81 | const struct UString *src, | |
82 | UErrorCode *status) | |
83 | { | |
84 | if(U_FAILURE(*status) || dst == src) | |
85 | return; | |
86 | ||
87 | if(dst->fCapacity < src->fLength) { | |
88 | ustr_resize(dst, ALLOCATION(src->fLength), status); | |
89 | if(U_FAILURE(*status)) | |
90 | return; | |
91 | } | |
374ca955 A |
92 | if(src->fChars == NULL || dst->fChars == NULL){ |
93 | return; | |
94 | } | |
b75a7d8f A |
95 | uprv_memcpy(dst->fChars, src->fChars, sizeof(UChar) * src->fLength); |
96 | dst->fLength = src->fLength; | |
97 | dst->fChars[dst->fLength] = 0x0000; | |
98 | } | |
99 | ||
4388f060 | 100 | U_CFUNC void |
b75a7d8f A |
101 | ustr_setlen(struct UString *s, |
102 | int32_t len, | |
103 | UErrorCode *status) | |
104 | { | |
105 | if(U_FAILURE(*status)) | |
106 | return; | |
107 | ||
108 | if(s->fCapacity < (len + 1)) { | |
109 | ustr_resize(s, ALLOCATION(len), status); | |
110 | if(U_FAILURE(*status)) | |
111 | return; | |
112 | } | |
113 | ||
114 | s->fLength = len; | |
115 | s->fChars[len] = 0x0000; | |
116 | } | |
117 | ||
4388f060 | 118 | U_CFUNC void |
b75a7d8f A |
119 | ustr_cat(struct UString *dst, |
120 | const struct UString *src, | |
121 | UErrorCode *status) | |
122 | { | |
123 | ustr_ncat(dst, src, src->fLength, status); | |
124 | } | |
125 | ||
4388f060 | 126 | U_CFUNC void |
b75a7d8f A |
127 | ustr_ncat(struct UString *dst, |
128 | const struct UString *src, | |
129 | int32_t n, | |
130 | UErrorCode *status) | |
131 | { | |
132 | if(U_FAILURE(*status) || dst == src) | |
133 | return; | |
134 | ||
135 | if(dst->fCapacity < (dst->fLength + n)) { | |
136 | ustr_resize(dst, ALLOCATION(dst->fLength + n), status); | |
137 | if(U_FAILURE(*status)) | |
138 | return; | |
139 | } | |
140 | ||
141 | uprv_memcpy(dst->fChars + dst->fLength, src->fChars, | |
142 | sizeof(UChar) * n); | |
143 | dst->fLength += src->fLength; | |
144 | dst->fChars[dst->fLength] = 0x0000; | |
145 | } | |
146 | ||
4388f060 | 147 | U_CFUNC void |
b75a7d8f A |
148 | ustr_ucat(struct UString *dst, |
149 | UChar c, | |
150 | UErrorCode *status) | |
151 | { | |
152 | if(U_FAILURE(*status)) | |
153 | return; | |
154 | ||
155 | if(dst->fCapacity < (dst->fLength + 1)) { | |
156 | ustr_resize(dst, ALLOCATION(dst->fLength + 1), status); | |
157 | if(U_FAILURE(*status)) | |
158 | return; | |
159 | } | |
160 | ||
161 | uprv_memcpy(dst->fChars + dst->fLength, &c, | |
162 | sizeof(UChar) * 1); | |
163 | dst->fLength += 1; | |
164 | dst->fChars[dst->fLength] = 0x0000; | |
165 | } | |
4388f060 | 166 | U_CFUNC void |
374ca955 A |
167 | ustr_u32cat(struct UString *dst, UChar32 c, UErrorCode *status){ |
168 | if(c > 0x10FFFF){ | |
169 | *status = U_ILLEGAL_CHAR_FOUND; | |
170 | return; | |
171 | } | |
172 | if(c >0xFFFF){ | |
173 | ustr_ucat(dst, U16_LEAD(c), status); | |
174 | ustr_ucat(dst, U16_TRAIL(c), status); | |
175 | }else{ | |
176 | ustr_ucat(dst, (UChar) c, status); | |
177 | } | |
178 | } | |
4388f060 | 179 | U_CFUNC void |
b75a7d8f A |
180 | ustr_uscat(struct UString *dst, |
181 | const UChar* src,int len, | |
182 | UErrorCode *status) | |
183 | { | |
184 | if(U_FAILURE(*status)) | |
185 | return; | |
186 | ||
187 | if(dst->fCapacity < (dst->fLength + len)) { | |
188 | ustr_resize(dst, ALLOCATION(dst->fLength + len), status); | |
189 | if(U_FAILURE(*status)) | |
190 | return; | |
191 | } | |
192 | ||
193 | uprv_memcpy(dst->fChars + dst->fLength, src, | |
194 | sizeof(UChar) * len); | |
195 | dst->fLength += len; | |
196 | dst->fChars[dst->fLength] = 0x0000; | |
197 | } | |
198 | ||
199 | /* Destroys data in the string */ | |
200 | static void | |
201 | ustr_resize(struct UString *s, | |
202 | int32_t len, | |
203 | UErrorCode *status) | |
204 | { | |
205 | if(U_FAILURE(*status)) | |
206 | return; | |
207 | ||
208 | /* +1 for trailing 0x0000 */ | |
209 | s->fChars = (UChar*) uprv_realloc(s->fChars, sizeof(UChar) * (len + 1)); | |
210 | if(s->fChars == 0) { | |
211 | *status = U_MEMORY_ALLOCATION_ERROR; | |
b75a7d8f A |
212 | s->fLength = s->fCapacity = 0; |
213 | return; | |
214 | } | |
215 | ||
216 | s->fCapacity = len; | |
217 | } |