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