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