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