michael@0: /* michael@0: ******************************************************************************* michael@0: * Copyright (C) 2010-2011, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: ******************************************************************************* michael@0: * file name: charstr.cpp michael@0: * encoding: US-ASCII michael@0: * tab size: 8 (not used) michael@0: * indentation:4 michael@0: * michael@0: * created on: 2010may19 michael@0: * created by: Markus W. Scherer michael@0: */ michael@0: michael@0: #include "unicode/utypes.h" michael@0: #include "charstr.h" michael@0: #include "cmemory.h" michael@0: #include "cstring.h" michael@0: michael@0: U_NAMESPACE_BEGIN michael@0: michael@0: CharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) { michael@0: if(U_SUCCESS(errorCode) && this!=&s && ensureCapacity(s.len+1, 0, errorCode)) { michael@0: len=s.len; michael@0: uprv_memcpy(buffer.getAlias(), s.buffer.getAlias(), len+1); michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: CharString &CharString::truncate(int32_t newLength) { michael@0: if(newLength<0) { michael@0: newLength=0; michael@0: } michael@0: if(newLength0) { michael@0: if(s==(buffer.getAlias()+len)) { michael@0: // The caller wrote into the getAppendBuffer(). michael@0: if(sLength>=(buffer.getCapacity()-len)) { michael@0: // The caller wrote too much. michael@0: errorCode=U_INTERNAL_PROGRAM_ERROR; michael@0: } else { michael@0: buffer[len+=sLength]=0; michael@0: } michael@0: } else if(buffer.getAlias()<=s && s<(buffer.getAlias()+len) && michael@0: sLength>=(buffer.getCapacity()-len) michael@0: ) { michael@0: // (Part of) this string is appended to itself which requires reallocation, michael@0: // so we have to make a copy of the substring and append that. michael@0: return append(CharString(s, sLength, errorCode), errorCode); michael@0: } else if(ensureCapacity(len+sLength+1, 0, errorCode)) { michael@0: uprv_memcpy(buffer.getAlias()+len, s, sLength); michael@0: buffer[len+=sLength]=0; michael@0: } michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: char *CharString::getAppendBuffer(int32_t minCapacity, michael@0: int32_t desiredCapacityHint, michael@0: int32_t &resultCapacity, michael@0: UErrorCode &errorCode) { michael@0: if(U_FAILURE(errorCode)) { michael@0: resultCapacity=0; michael@0: return NULL; michael@0: } michael@0: int32_t appendCapacity=buffer.getCapacity()-len-1; // -1 for NUL michael@0: if(appendCapacity>=minCapacity) { michael@0: resultCapacity=appendCapacity; michael@0: return buffer.getAlias()+len; michael@0: } michael@0: if(ensureCapacity(len+minCapacity+1, len+desiredCapacityHint+1, errorCode)) { michael@0: resultCapacity=buffer.getCapacity()-len-1; michael@0: return buffer.getAlias()+len; michael@0: } michael@0: resultCapacity=0; michael@0: return NULL; michael@0: } michael@0: michael@0: CharString &CharString::appendInvariantChars(const UnicodeString &s, UErrorCode &errorCode) { michael@0: if(ensureCapacity(len+s.length()+1, 0, errorCode)) { michael@0: len+=s.extract(0, 0x7fffffff, buffer.getAlias()+len, buffer.getCapacity()-len, US_INV); michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: UBool CharString::ensureCapacity(int32_t capacity, michael@0: int32_t desiredCapacityHint, michael@0: UErrorCode &errorCode) { michael@0: if(U_FAILURE(errorCode)) { michael@0: return FALSE; michael@0: } michael@0: if(capacity>buffer.getCapacity()) { michael@0: if(desiredCapacityHint==0) { michael@0: desiredCapacityHint=capacity+buffer.getCapacity(); michael@0: } michael@0: if( (desiredCapacityHint<=capacity || buffer.resize(desiredCapacityHint, len+1)==NULL) && michael@0: buffer.resize(capacity, len+1)==NULL michael@0: ) { michael@0: errorCode=U_MEMORY_ALLOCATION_ERROR; michael@0: return FALSE; michael@0: } michael@0: } michael@0: return TRUE; michael@0: } michael@0: michael@0: CharString &CharString::appendPathPart(const StringPiece &s, UErrorCode &errorCode) { michael@0: if(U_FAILURE(errorCode)) { michael@0: return *this; michael@0: } michael@0: if(s.length()==0) { michael@0: return *this; michael@0: } michael@0: char c; michael@0: if(len>0 && (c=buffer[len-1])!=U_FILE_SEP_CHAR && c!=U_FILE_ALT_SEP_CHAR) { michael@0: append(U_FILE_SEP_CHAR, errorCode); michael@0: } michael@0: append(s, errorCode); michael@0: return *this; michael@0: } michael@0: michael@0: U_NAMESPACE_END