2 *******************************************************************************
3 * Copyright (C) 2010-2015, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 *******************************************************************************
6 * file name: charstr.cpp
8 * tab size: 8 (not used)
11 * created on: 2010may19
12 * created by: Markus W. Scherer
15 #include "unicode/utypes.h"
23 CharString
&CharString::copyFrom(const CharString
&s
, UErrorCode
&errorCode
) {
24 if(U_SUCCESS(errorCode
) && this!=&s
&& ensureCapacity(s
.len
+1, 0, errorCode
)) {
26 uprv_memcpy(buffer
.getAlias(), s
.buffer
.getAlias(), len
+1);
31 int32_t CharString::lastIndexOf(char c
) const {
32 for(int32_t i
=len
; i
>0;) {
40 CharString
&CharString::truncate(int32_t newLength
) {
45 buffer
[len
=newLength
]=0;
50 CharString
&CharString::append(char c
, UErrorCode
&errorCode
) {
51 if(ensureCapacity(len
+2, 0, errorCode
)) {
58 CharString
&CharString::append(const char *s
, int32_t sLength
, UErrorCode
&errorCode
) {
59 if(U_FAILURE(errorCode
)) {
62 if(sLength
<-1 || (s
==NULL
&& sLength
!=0)) {
63 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
67 sLength
=uprv_strlen(s
);
70 if(s
==(buffer
.getAlias()+len
)) {
71 // The caller wrote into the getAppendBuffer().
72 if(sLength
>=(buffer
.getCapacity()-len
)) {
73 // The caller wrote too much.
74 errorCode
=U_INTERNAL_PROGRAM_ERROR
;
76 buffer
[len
+=sLength
]=0;
78 } else if(buffer
.getAlias()<=s
&& s
<(buffer
.getAlias()+len
) &&
79 sLength
>=(buffer
.getCapacity()-len
)
81 // (Part of) this string is appended to itself which requires reallocation,
82 // so we have to make a copy of the substring and append that.
83 return append(CharString(s
, sLength
, errorCode
), errorCode
);
84 } else if(ensureCapacity(len
+sLength
+1, 0, errorCode
)) {
85 uprv_memcpy(buffer
.getAlias()+len
, s
, sLength
);
86 buffer
[len
+=sLength
]=0;
92 char *CharString::getAppendBuffer(int32_t minCapacity
,
93 int32_t desiredCapacityHint
,
94 int32_t &resultCapacity
,
95 UErrorCode
&errorCode
) {
96 if(U_FAILURE(errorCode
)) {
100 int32_t appendCapacity
=buffer
.getCapacity()-len
-1; // -1 for NUL
101 if(appendCapacity
>=minCapacity
) {
102 resultCapacity
=appendCapacity
;
103 return buffer
.getAlias()+len
;
105 if(ensureCapacity(len
+minCapacity
+1, len
+desiredCapacityHint
+1, errorCode
)) {
106 resultCapacity
=buffer
.getCapacity()-len
-1;
107 return buffer
.getAlias()+len
;
113 CharString
&CharString::appendInvariantChars(const UnicodeString
&s
, UErrorCode
&errorCode
) {
114 if(U_FAILURE(errorCode
)) {
117 if (!uprv_isInvariantUnicodeString(s
)) {
118 errorCode
= U_INVARIANT_CONVERSION_ERROR
;
121 if(ensureCapacity(len
+s
.length()+1, 0, errorCode
)) {
122 len
+=s
.extract(0, 0x7fffffff, buffer
.getAlias()+len
, buffer
.getCapacity()-len
, US_INV
);
127 UBool
CharString::ensureCapacity(int32_t capacity
,
128 int32_t desiredCapacityHint
,
129 UErrorCode
&errorCode
) {
130 if(U_FAILURE(errorCode
)) {
133 if(capacity
>buffer
.getCapacity()) {
134 if(desiredCapacityHint
==0) {
135 desiredCapacityHint
=capacity
+buffer
.getCapacity();
137 if( (desiredCapacityHint
<=capacity
|| buffer
.resize(desiredCapacityHint
, len
+1)==NULL
) &&
138 buffer
.resize(capacity
, len
+1)==NULL
140 errorCode
=U_MEMORY_ALLOCATION_ERROR
;
147 CharString
&CharString::appendPathPart(const StringPiece
&s
, UErrorCode
&errorCode
) {
148 if(U_FAILURE(errorCode
)) {
155 if(len
>0 && (c
=buffer
[len
-1])!=U_FILE_SEP_CHAR
&& c
!=U_FILE_ALT_SEP_CHAR
) {
156 append(U_FILE_SEP_CHAR
, errorCode
);
158 append(s
, errorCode
);
162 CharString
&CharString::ensureEndsWithFileSeparator(UErrorCode
&errorCode
) {
164 if(U_SUCCESS(errorCode
) && len
>0 &&
165 (c
=buffer
[len
-1])!=U_FILE_SEP_CHAR
&& c
!=U_FILE_ALT_SEP_CHAR
) {
166 append(U_FILE_SEP_CHAR
, errorCode
);