1/* 2******************************************************************************* 3* Copyright (C) 2010-2011, 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 130CharString &CharString::appendPathPart(const StringPiece &s, UErrorCode &errorCode) { 131 if(U_FAILURE(errorCode)) { 132 return *this; 133 } 134 if(s.length()==0) { 135 return *this; 136 } 137 char c; 138 if(len>0 && (c=buffer[len-1])!=U_FILE_SEP_CHAR && c!=U_FILE_ALT_SEP_CHAR) { 139 append(U_FILE_SEP_CHAR, errorCode); 140 } 141 append(s, errorCode); 142 return *this; 143} 144 145U_NAMESPACE_END 146