]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/charstr.cpp
ICU-461.12.tar.gz
[apple/icu.git] / icuSources / common / charstr.cpp
CommitLineData
729e4ab9
A
1/*
2*******************************************************************************
3* Copyright (C) 2010, International Business Machines
4* Corporation and others. All Rights Reserved.
5*******************************************************************************
6* file name: charstr.cpp
7* encoding: US-ASCII
8* tab size: 8 (not used)
9* indentation:4
10*
11* created on: 2010may19
12* created by: Markus W. Scherer
13*/
14
15#include "unicode/utypes.h"
16#include "charstr.h"
17#include "cmemory.h"
18#include "cstring.h"
19
20U_NAMESPACE_BEGIN
21
22CharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) {
23 if(U_SUCCESS(errorCode) && this!=&s && ensureCapacity(s.len+1, 0, errorCode)) {
24 len=s.len;
25 uprv_memcpy(buffer.getAlias(), s.buffer.getAlias(), len+1);
26 }
27 return *this;
28}
29
30CharString &CharString::truncate(int32_t newLength) {
31 if(newLength<0) {
32 newLength=0;
33 }
34 if(newLength<len) {
35 buffer[len=newLength]=0;
36 }
37 return *this;
38}
39
40CharString &CharString::append(char c, UErrorCode &errorCode) {
41 if(ensureCapacity(len+2, 0, errorCode)) {
42 buffer[len++]=c;
43 buffer[len]=0;
44 }
45 return *this;
46}
47
48CharString &CharString::append(const char *s, int32_t sLength, UErrorCode &errorCode) {
49 if(U_FAILURE(errorCode)) {
50 return *this;
51 }
52 if(sLength<-1 || (s==NULL && sLength!=0)) {
53 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
54 return *this;
55 }
56 if(sLength<0) {
57 sLength=uprv_strlen(s);
58 }
59 if(sLength>0) {
60 if(s==(buffer.getAlias()+len)) {
61 // The caller wrote into the getAppendBuffer().
62 if(sLength>=(buffer.getCapacity()-len)) {
63 // The caller wrote too much.
64 errorCode=U_INTERNAL_PROGRAM_ERROR;
65 } else {
66 buffer[len+=sLength]=0;
67 }
68 } else if(buffer.getAlias()<=s && s<(buffer.getAlias()+len) &&
69 sLength>=(buffer.getCapacity()-len)
70 ) {
71 // (Part of) this string is appended to itself which requires reallocation,
72 // so we have to make a copy of the substring and append that.
73 return append(CharString(s, sLength, errorCode), errorCode);
74 } else if(ensureCapacity(len+sLength+1, 0, errorCode)) {
75 uprv_memcpy(buffer.getAlias()+len, s, sLength);
76 buffer[len+=sLength]=0;
77 }
78 }
79 return *this;
80}
81
82char *CharString::getAppendBuffer(int32_t minCapacity,
83 int32_t desiredCapacityHint,
84 int32_t &resultCapacity,
85 UErrorCode &errorCode) {
86 if(U_FAILURE(errorCode)) {
87 resultCapacity=0;
88 return NULL;
89 }
90 int32_t appendCapacity=buffer.getCapacity()-len-1; // -1 for NUL
91 if(appendCapacity>=minCapacity) {
92 resultCapacity=appendCapacity;
93 return buffer.getAlias()+len;
94 }
95 if(ensureCapacity(len+minCapacity+1, len+desiredCapacityHint+1, errorCode)) {
96 resultCapacity=buffer.getCapacity()-len-1;
97 return buffer.getAlias()+len;
98 }
99 resultCapacity=0;
100 return NULL;
101}
102
103CharString &CharString::appendInvariantChars(const UnicodeString &s, UErrorCode &errorCode) {
104 if(ensureCapacity(len+s.length()+1, 0, errorCode)) {
105 len+=s.extract(0, 0x7fffffff, buffer.getAlias()+len, buffer.getCapacity()-len, US_INV);
106 }
107 return *this;
108}
109
110UBool CharString::ensureCapacity(int32_t capacity,
111 int32_t desiredCapacityHint,
112 UErrorCode &errorCode) {
113 if(U_FAILURE(errorCode)) {
114 return FALSE;
115 }
116 if(capacity>buffer.getCapacity()) {
117 if(desiredCapacityHint==0) {
118 desiredCapacityHint=capacity+buffer.getCapacity();
119 }
120 if( (desiredCapacityHint<=capacity || buffer.resize(desiredCapacityHint, len+1)==NULL) &&
121 buffer.resize(capacity, len+1)==NULL
122 ) {
123 errorCode=U_MEMORY_ALLOCATION_ERROR;
124 return FALSE;
125 }
126 }
127 return TRUE;
128}
129
130U_NAMESPACE_END