]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
73c04bcf | 4 | * Copyright (C) 1998-2006, 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 | { | |
71 | uprv_free(s->fChars); | |
72 | s->fChars = 0; | |
73 | s->fLength = s->fCapacity = 0; | |
74 | } | |
75 | ||
76 | void | |
77 | ustr_cpy(struct UString *dst, | |
78 | const struct UString *src, | |
79 | UErrorCode *status) | |
80 | { | |
81 | if(U_FAILURE(*status) || dst == src) | |
82 | return; | |
83 | ||
84 | if(dst->fCapacity < src->fLength) { | |
85 | ustr_resize(dst, ALLOCATION(src->fLength), status); | |
86 | if(U_FAILURE(*status)) | |
87 | return; | |
88 | } | |
374ca955 A |
89 | if(src->fChars == NULL || dst->fChars == NULL){ |
90 | return; | |
91 | } | |
b75a7d8f A |
92 | uprv_memcpy(dst->fChars, src->fChars, sizeof(UChar) * src->fLength); |
93 | dst->fLength = src->fLength; | |
94 | dst->fChars[dst->fLength] = 0x0000; | |
95 | } | |
96 | ||
97 | void | |
98 | ustr_setlen(struct UString *s, | |
99 | int32_t len, | |
100 | UErrorCode *status) | |
101 | { | |
102 | if(U_FAILURE(*status)) | |
103 | return; | |
104 | ||
105 | if(s->fCapacity < (len + 1)) { | |
106 | ustr_resize(s, ALLOCATION(len), status); | |
107 | if(U_FAILURE(*status)) | |
108 | return; | |
109 | } | |
110 | ||
111 | s->fLength = len; | |
112 | s->fChars[len] = 0x0000; | |
113 | } | |
114 | ||
115 | void | |
116 | ustr_cat(struct UString *dst, | |
117 | const struct UString *src, | |
118 | UErrorCode *status) | |
119 | { | |
120 | ustr_ncat(dst, src, src->fLength, status); | |
121 | } | |
122 | ||
123 | void | |
124 | ustr_ncat(struct UString *dst, | |
125 | const struct UString *src, | |
126 | int32_t n, | |
127 | UErrorCode *status) | |
128 | { | |
129 | if(U_FAILURE(*status) || dst == src) | |
130 | return; | |
131 | ||
132 | if(dst->fCapacity < (dst->fLength + n)) { | |
133 | ustr_resize(dst, ALLOCATION(dst->fLength + n), status); | |
134 | if(U_FAILURE(*status)) | |
135 | return; | |
136 | } | |
137 | ||
138 | uprv_memcpy(dst->fChars + dst->fLength, src->fChars, | |
139 | sizeof(UChar) * n); | |
140 | dst->fLength += src->fLength; | |
141 | dst->fChars[dst->fLength] = 0x0000; | |
142 | } | |
143 | ||
144 | void | |
145 | ustr_ucat(struct UString *dst, | |
146 | UChar c, | |
147 | UErrorCode *status) | |
148 | { | |
149 | if(U_FAILURE(*status)) | |
150 | return; | |
151 | ||
152 | if(dst->fCapacity < (dst->fLength + 1)) { | |
153 | ustr_resize(dst, ALLOCATION(dst->fLength + 1), status); | |
154 | if(U_FAILURE(*status)) | |
155 | return; | |
156 | } | |
157 | ||
158 | uprv_memcpy(dst->fChars + dst->fLength, &c, | |
159 | sizeof(UChar) * 1); | |
160 | dst->fLength += 1; | |
161 | dst->fChars[dst->fLength] = 0x0000; | |
162 | } | |
374ca955 A |
163 | void |
164 | ustr_u32cat(struct UString *dst, UChar32 c, UErrorCode *status){ | |
165 | if(c > 0x10FFFF){ | |
166 | *status = U_ILLEGAL_CHAR_FOUND; | |
167 | return; | |
168 | } | |
169 | if(c >0xFFFF){ | |
170 | ustr_ucat(dst, U16_LEAD(c), status); | |
171 | ustr_ucat(dst, U16_TRAIL(c), status); | |
172 | }else{ | |
173 | ustr_ucat(dst, (UChar) c, status); | |
174 | } | |
175 | } | |
b75a7d8f A |
176 | void |
177 | ustr_uscat(struct UString *dst, | |
178 | const UChar* src,int len, | |
179 | UErrorCode *status) | |
180 | { | |
181 | if(U_FAILURE(*status)) | |
182 | return; | |
183 | ||
184 | if(dst->fCapacity < (dst->fLength + len)) { | |
185 | ustr_resize(dst, ALLOCATION(dst->fLength + len), status); | |
186 | if(U_FAILURE(*status)) | |
187 | return; | |
188 | } | |
189 | ||
190 | uprv_memcpy(dst->fChars + dst->fLength, src, | |
191 | sizeof(UChar) * len); | |
192 | dst->fLength += len; | |
193 | dst->fChars[dst->fLength] = 0x0000; | |
194 | } | |
195 | ||
196 | /* Destroys data in the string */ | |
197 | static void | |
198 | ustr_resize(struct UString *s, | |
199 | int32_t len, | |
200 | UErrorCode *status) | |
201 | { | |
202 | if(U_FAILURE(*status)) | |
203 | return; | |
204 | ||
205 | /* +1 for trailing 0x0000 */ | |
206 | s->fChars = (UChar*) uprv_realloc(s->fChars, sizeof(UChar) * (len + 1)); | |
207 | if(s->fChars == 0) { | |
208 | *status = U_MEMORY_ALLOCATION_ERROR; | |
b75a7d8f A |
209 | s->fLength = s->fCapacity = 0; |
210 | return; | |
211 | } | |
212 | ||
213 | s->fCapacity = len; | |
214 | } |