1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
5 * Copyright (C) 2010-2015, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: charstr.cpp
10 * tab size: 8 (not used)
13 * created on: 2010may19
14 * created by: Markus W. Scherer
17 #include "unicode/utypes.h"
18 #include "unicode/putil.h"
26 CharString
&CharString::copyFrom(const CharString
&s
, UErrorCode
&errorCode
) {
27 if(U_SUCCESS(errorCode
) && this!=&s
&& ensureCapacity(s
.len
+1, 0, errorCode
)) {
29 uprv_memcpy(buffer
.getAlias(), s
.buffer
.getAlias(), len
+1);
34 int32_t CharString::lastIndexOf(char c
) const {
35 for(int32_t i
=len
; i
>0;) {
43 CharString
&CharString::truncate(int32_t newLength
) {
48 buffer
[len
=newLength
]=0;
53 CharString
&CharString::append(char c
, UErrorCode
&errorCode
) {
54 if(ensureCapacity(len
+2, 0, errorCode
)) {
61 CharString
&CharString::append(const char *s
, int32_t sLength
, UErrorCode
&errorCode
) {
62 if(U_FAILURE(errorCode
)) {
65 if(sLength
<-1 || (s
==NULL
&& sLength
!=0)) {
66 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
70 sLength
=uprv_strlen(s
);
73 if(s
==(buffer
.getAlias()+len
)) {
74 // The caller wrote into the getAppendBuffer().
75 if(sLength
>=(buffer
.getCapacity()-len
)) {
76 // The caller wrote too much.
77 errorCode
=U_INTERNAL_PROGRAM_ERROR
;
79 buffer
[len
+=sLength
]=0;
81 } else if(buffer
.getAlias()<=s
&& s
<(buffer
.getAlias()+len
) &&
82 sLength
>=(buffer
.getCapacity()-len
)
84 // (Part of) this string is appended to itself which requires reallocation,
85 // so we have to make a copy of the substring and append that.
86 return append(CharString(s
, sLength
, errorCode
), errorCode
);
87 } else if(ensureCapacity(len
+sLength
+1, 0, errorCode
)) {
88 uprv_memcpy(buffer
.getAlias()+len
, s
, sLength
);
89 buffer
[len
+=sLength
]=0;
95 char *CharString::getAppendBuffer(int32_t minCapacity
,
96 int32_t desiredCapacityHint
,
97 int32_t &resultCapacity
,
98 UErrorCode
&errorCode
) {
99 if(U_FAILURE(errorCode
)) {
103 int32_t appendCapacity
=buffer
.getCapacity()-len
-1; // -1 for NUL
104 if(appendCapacity
>=minCapacity
) {
105 resultCapacity
=appendCapacity
;
106 return buffer
.getAlias()+len
;
108 if(ensureCapacity(len
+minCapacity
+1, len
+desiredCapacityHint
+1, errorCode
)) {
109 resultCapacity
=buffer
.getCapacity()-len
-1;
110 return buffer
.getAlias()+len
;
116 CharString
&CharString::appendInvariantChars(const UnicodeString
&s
, UErrorCode
&errorCode
) {
117 if(U_FAILURE(errorCode
)) {
120 if (!uprv_isInvariantUnicodeString(s
)) {
121 errorCode
= U_INVARIANT_CONVERSION_ERROR
;
124 if(ensureCapacity(len
+s
.length()+1, 0, errorCode
)) {
125 len
+=s
.extract(0, 0x7fffffff, buffer
.getAlias()+len
, buffer
.getCapacity()-len
, US_INV
);
130 UBool
CharString::ensureCapacity(int32_t capacity
,
131 int32_t desiredCapacityHint
,
132 UErrorCode
&errorCode
) {
133 if(U_FAILURE(errorCode
)) {
136 if(capacity
>buffer
.getCapacity()) {
137 if(desiredCapacityHint
==0) {
138 desiredCapacityHint
=capacity
+buffer
.getCapacity();
140 if( (desiredCapacityHint
<=capacity
|| buffer
.resize(desiredCapacityHint
, len
+1)==NULL
) &&
141 buffer
.resize(capacity
, len
+1)==NULL
143 errorCode
=U_MEMORY_ALLOCATION_ERROR
;
150 CharString
&CharString::appendPathPart(StringPiece s
, UErrorCode
&errorCode
) {
151 if(U_FAILURE(errorCode
)) {
158 if(len
>0 && (c
=buffer
[len
-1])!=U_FILE_SEP_CHAR
&& c
!=U_FILE_ALT_SEP_CHAR
) {
159 append(U_FILE_SEP_CHAR
, errorCode
);
161 append(s
, errorCode
);
165 CharString
&CharString::ensureEndsWithFileSeparator(UErrorCode
&errorCode
) {
167 if(U_SUCCESS(errorCode
) && len
>0 &&
168 (c
=buffer
[len
-1])!=U_FILE_SEP_CHAR
&& c
!=U_FILE_ALT_SEP_CHAR
) {
169 append(U_FILE_SEP_CHAR
, errorCode
);