1 // Copyright (C) 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;