1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
6 * Copyright (C) 1998-2012, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 *******************************************************************************
13 * Modification History:
15 * Date Name Description
16 * 05/28/99 stephen Creation.
17 *******************************************************************************
23 #include "unicode/ustring.h"
24 #include "unicode/putil.h"
25 #include "unicode/utf16.h"
28 static void ustr_resize(struct UString
*s
, int32_t len
, UErrorCode
*status
);
31 #define ALLOCATION(minSize) (minSize < 0x80 ? 0x80 : (2 * minSize + 0x80) & ~(0x80 - 1))
34 ustr_init(struct UString
*s
)
37 s
->fLength
= s
->fCapacity
= 0;
41 ustr_initChars(struct UString
*s
, const char* source
, int32_t length
, UErrorCode
*status
)
44 if (U_FAILURE(*status
)) return;
46 s
->fLength
= s
->fCapacity
= 0;
48 length
= (int32_t)uprv_strlen(source
);
50 if(s
->fCapacity
< length
) {
51 ustr_resize(s
, ALLOCATION(length
), status
);
52 if(U_FAILURE(*status
)) return;
54 for (; i
< length
; i
++)
57 u_charsToUChars(source
+i
, &charToAppend
, 1);
58 ustr_ucat(s
, charToAppend
, status
);
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);
65 # error U_CHARSET_FAMILY is not valid
72 ustr_deinit(struct UString
*s
)
77 s
->fLength
= s
->fCapacity
= 0;
82 ustr_cpy(struct UString
*dst
,
83 const struct UString
*src
,
86 if(U_FAILURE(*status
) || dst
== src
)
89 if(dst
->fCapacity
< src
->fLength
) {
90 ustr_resize(dst
, ALLOCATION(src
->fLength
), status
);
91 if(U_FAILURE(*status
))
94 if(src
->fChars
== NULL
|| dst
->fChars
== NULL
){
97 u_memcpy(dst
->fChars
, src
->fChars
, src
->fLength
);
98 dst
->fLength
= src
->fLength
;
99 dst
->fChars
[dst
->fLength
] = 0x0000;
103 ustr_setlen(struct UString
*s
,
107 if(U_FAILURE(*status
))
110 if(s
->fCapacity
< (len
+ 1)) {
111 ustr_resize(s
, ALLOCATION(len
), status
);
112 if(U_FAILURE(*status
))
117 s
->fChars
[len
] = 0x0000;
121 ustr_cat(struct UString
*dst
,
122 const struct UString
*src
,
125 ustr_ncat(dst
, src
, src
->fLength
, status
);
129 ustr_ncat(struct UString
*dst
,
130 const struct UString
*src
,
134 if(U_FAILURE(*status
) || dst
== src
)
137 if(dst
->fCapacity
< (dst
->fLength
+ n
)) {
138 ustr_resize(dst
, ALLOCATION(dst
->fLength
+ n
), status
);
139 if(U_FAILURE(*status
))
143 uprv_memcpy(dst
->fChars
+ dst
->fLength
, src
->fChars
,
145 dst
->fLength
+= src
->fLength
;
146 dst
->fChars
[dst
->fLength
] = 0x0000;
150 ustr_ucat(struct UString
*dst
,
154 if(U_FAILURE(*status
))
157 if(dst
->fCapacity
< (dst
->fLength
+ 1)) {
158 ustr_resize(dst
, ALLOCATION(dst
->fLength
+ 1), status
);
159 if(U_FAILURE(*status
))
163 uprv_memcpy(dst
->fChars
+ dst
->fLength
, &c
,
166 dst
->fChars
[dst
->fLength
] = 0x0000;
169 ustr_u32cat(struct UString
*dst
, UChar32 c
, UErrorCode
*status
){
171 *status
= U_ILLEGAL_CHAR_FOUND
;
175 ustr_ucat(dst
, U16_LEAD(c
), status
);
176 ustr_ucat(dst
, U16_TRAIL(c
), status
);
178 ustr_ucat(dst
, (UChar
) c
, status
);
182 ustr_uscat(struct UString
*dst
,
183 const UChar
* src
,int len
,
186 if(U_FAILURE(*status
))
189 if(dst
->fCapacity
< (dst
->fLength
+ len
)) {
190 ustr_resize(dst
, ALLOCATION(dst
->fLength
+ len
), status
);
191 if(U_FAILURE(*status
))
195 uprv_memcpy(dst
->fChars
+ dst
->fLength
, src
,
196 sizeof(UChar
) * len
);
198 dst
->fChars
[dst
->fLength
] = 0x0000;
201 /* Destroys data in the string */
203 ustr_resize(struct UString
*s
,
207 if(U_FAILURE(*status
))
210 /* +1 for trailing 0x0000 */
211 s
->fChars
= (UChar
*) uprv_realloc(s
->fChars
, sizeof(UChar
) * (len
+ 1));
213 *status
= U_MEMORY_ALLOCATION_ERROR
;
214 s
->fLength
= s
->fCapacity
= 0;