127f654740f2a26ad62a5c155af9199af9e69b889claireho/*
227f654740f2a26ad62a5c155af9199af9e69b889claireho*******************************************************************************
327f654740f2a26ad62a5c155af9199af9e69b889claireho*   Copyright (C) 2010, International Business Machines
427f654740f2a26ad62a5c155af9199af9e69b889claireho*   Corporation and others.  All Rights Reserved.
527f654740f2a26ad62a5c155af9199af9e69b889claireho*******************************************************************************
627f654740f2a26ad62a5c155af9199af9e69b889claireho*   file name:  charstr.cpp
727f654740f2a26ad62a5c155af9199af9e69b889claireho*   encoding:   US-ASCII
827f654740f2a26ad62a5c155af9199af9e69b889claireho*   tab size:   8 (not used)
927f654740f2a26ad62a5c155af9199af9e69b889claireho*   indentation:4
1027f654740f2a26ad62a5c155af9199af9e69b889claireho*
1127f654740f2a26ad62a5c155af9199af9e69b889claireho*   created on: 2010may19
1227f654740f2a26ad62a5c155af9199af9e69b889claireho*   created by: Markus W. Scherer
1327f654740f2a26ad62a5c155af9199af9e69b889claireho*/
1427f654740f2a26ad62a5c155af9199af9e69b889claireho
1527f654740f2a26ad62a5c155af9199af9e69b889claireho#include "unicode/utypes.h"
1627f654740f2a26ad62a5c155af9199af9e69b889claireho#include "charstr.h"
1727f654740f2a26ad62a5c155af9199af9e69b889claireho#include "cmemory.h"
1827f654740f2a26ad62a5c155af9199af9e69b889claireho#include "cstring.h"
1927f654740f2a26ad62a5c155af9199af9e69b889claireho
2027f654740f2a26ad62a5c155af9199af9e69b889clairehoU_NAMESPACE_BEGIN
2127f654740f2a26ad62a5c155af9199af9e69b889claireho
2227f654740f2a26ad62a5c155af9199af9e69b889clairehoCharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) {
2327f654740f2a26ad62a5c155af9199af9e69b889claireho    if(U_SUCCESS(errorCode) && this!=&s && ensureCapacity(s.len+1, 0, errorCode)) {
2427f654740f2a26ad62a5c155af9199af9e69b889claireho        len=s.len;
2527f654740f2a26ad62a5c155af9199af9e69b889claireho        uprv_memcpy(buffer.getAlias(), s.buffer.getAlias(), len+1);
2627f654740f2a26ad62a5c155af9199af9e69b889claireho    }
2727f654740f2a26ad62a5c155af9199af9e69b889claireho    return *this;
2827f654740f2a26ad62a5c155af9199af9e69b889claireho}
2927f654740f2a26ad62a5c155af9199af9e69b889claireho
3027f654740f2a26ad62a5c155af9199af9e69b889clairehoCharString &CharString::truncate(int32_t newLength) {
3127f654740f2a26ad62a5c155af9199af9e69b889claireho    if(newLength<0) {
3227f654740f2a26ad62a5c155af9199af9e69b889claireho        newLength=0;
3327f654740f2a26ad62a5c155af9199af9e69b889claireho    }
3427f654740f2a26ad62a5c155af9199af9e69b889claireho    if(newLength<len) {
3527f654740f2a26ad62a5c155af9199af9e69b889claireho        buffer[len=newLength]=0;
3627f654740f2a26ad62a5c155af9199af9e69b889claireho    }
3727f654740f2a26ad62a5c155af9199af9e69b889claireho    return *this;
3827f654740f2a26ad62a5c155af9199af9e69b889claireho}
3927f654740f2a26ad62a5c155af9199af9e69b889claireho
4027f654740f2a26ad62a5c155af9199af9e69b889clairehoCharString &CharString::append(char c, UErrorCode &errorCode) {
4127f654740f2a26ad62a5c155af9199af9e69b889claireho    if(ensureCapacity(len+2, 0, errorCode)) {
4227f654740f2a26ad62a5c155af9199af9e69b889claireho        buffer[len++]=c;
4327f654740f2a26ad62a5c155af9199af9e69b889claireho        buffer[len]=0;
4427f654740f2a26ad62a5c155af9199af9e69b889claireho    }
4527f654740f2a26ad62a5c155af9199af9e69b889claireho    return *this;
4627f654740f2a26ad62a5c155af9199af9e69b889claireho}
4727f654740f2a26ad62a5c155af9199af9e69b889claireho
4827f654740f2a26ad62a5c155af9199af9e69b889clairehoCharString &CharString::append(const char *s, int32_t sLength, UErrorCode &errorCode) {
4927f654740f2a26ad62a5c155af9199af9e69b889claireho    if(U_FAILURE(errorCode)) {
5027f654740f2a26ad62a5c155af9199af9e69b889claireho        return *this;
5127f654740f2a26ad62a5c155af9199af9e69b889claireho    }
5227f654740f2a26ad62a5c155af9199af9e69b889claireho    if(sLength<-1 || (s==NULL && sLength!=0)) {
5327f654740f2a26ad62a5c155af9199af9e69b889claireho        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
5427f654740f2a26ad62a5c155af9199af9e69b889claireho        return *this;
5527f654740f2a26ad62a5c155af9199af9e69b889claireho    }
5627f654740f2a26ad62a5c155af9199af9e69b889claireho    if(sLength<0) {
5727f654740f2a26ad62a5c155af9199af9e69b889claireho        sLength=uprv_strlen(s);
5827f654740f2a26ad62a5c155af9199af9e69b889claireho    }
5927f654740f2a26ad62a5c155af9199af9e69b889claireho    if(sLength>0) {
6027f654740f2a26ad62a5c155af9199af9e69b889claireho        if(s==(buffer.getAlias()+len)) {
6127f654740f2a26ad62a5c155af9199af9e69b889claireho            // The caller wrote into the getAppendBuffer().
6227f654740f2a26ad62a5c155af9199af9e69b889claireho            if(sLength>=(buffer.getCapacity()-len)) {
6327f654740f2a26ad62a5c155af9199af9e69b889claireho                // The caller wrote too much.
6427f654740f2a26ad62a5c155af9199af9e69b889claireho                errorCode=U_INTERNAL_PROGRAM_ERROR;
6527f654740f2a26ad62a5c155af9199af9e69b889claireho            } else {
6627f654740f2a26ad62a5c155af9199af9e69b889claireho                buffer[len+=sLength]=0;
6727f654740f2a26ad62a5c155af9199af9e69b889claireho            }
6827f654740f2a26ad62a5c155af9199af9e69b889claireho        } else if(buffer.getAlias()<=s && s<(buffer.getAlias()+len) &&
6927f654740f2a26ad62a5c155af9199af9e69b889claireho                  sLength>=(buffer.getCapacity()-len)
7027f654740f2a26ad62a5c155af9199af9e69b889claireho        ) {
7127f654740f2a26ad62a5c155af9199af9e69b889claireho            // (Part of) this string is appended to itself which requires reallocation,
7227f654740f2a26ad62a5c155af9199af9e69b889claireho            // so we have to make a copy of the substring and append that.
7327f654740f2a26ad62a5c155af9199af9e69b889claireho            return append(CharString(s, sLength, errorCode), errorCode);
7427f654740f2a26ad62a5c155af9199af9e69b889claireho        } else if(ensureCapacity(len+sLength+1, 0, errorCode)) {
7527f654740f2a26ad62a5c155af9199af9e69b889claireho            uprv_memcpy(buffer.getAlias()+len, s, sLength);
7627f654740f2a26ad62a5c155af9199af9e69b889claireho            buffer[len+=sLength]=0;
7727f654740f2a26ad62a5c155af9199af9e69b889claireho        }
7827f654740f2a26ad62a5c155af9199af9e69b889claireho    }
7927f654740f2a26ad62a5c155af9199af9e69b889claireho    return *this;
8027f654740f2a26ad62a5c155af9199af9e69b889claireho}
8127f654740f2a26ad62a5c155af9199af9e69b889claireho
8227f654740f2a26ad62a5c155af9199af9e69b889clairehochar *CharString::getAppendBuffer(int32_t minCapacity,
8327f654740f2a26ad62a5c155af9199af9e69b889claireho                                  int32_t desiredCapacityHint,
8427f654740f2a26ad62a5c155af9199af9e69b889claireho                                  int32_t &resultCapacity,
8527f654740f2a26ad62a5c155af9199af9e69b889claireho                                  UErrorCode &errorCode) {
8627f654740f2a26ad62a5c155af9199af9e69b889claireho    if(U_FAILURE(errorCode)) {
8727f654740f2a26ad62a5c155af9199af9e69b889claireho        resultCapacity=0;
8827f654740f2a26ad62a5c155af9199af9e69b889claireho        return NULL;
8927f654740f2a26ad62a5c155af9199af9e69b889claireho    }
9027f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t appendCapacity=buffer.getCapacity()-len-1;  // -1 for NUL
9127f654740f2a26ad62a5c155af9199af9e69b889claireho    if(appendCapacity>=minCapacity) {
9227f654740f2a26ad62a5c155af9199af9e69b889claireho        resultCapacity=appendCapacity;
9327f654740f2a26ad62a5c155af9199af9e69b889claireho        return buffer.getAlias()+len;
9427f654740f2a26ad62a5c155af9199af9e69b889claireho    }
9527f654740f2a26ad62a5c155af9199af9e69b889claireho    if(ensureCapacity(len+minCapacity+1, len+desiredCapacityHint+1, errorCode)) {
9627f654740f2a26ad62a5c155af9199af9e69b889claireho        resultCapacity=buffer.getCapacity()-len-1;
9727f654740f2a26ad62a5c155af9199af9e69b889claireho        return buffer.getAlias()+len;
9827f654740f2a26ad62a5c155af9199af9e69b889claireho    }
9927f654740f2a26ad62a5c155af9199af9e69b889claireho    resultCapacity=0;
10027f654740f2a26ad62a5c155af9199af9e69b889claireho    return NULL;
10127f654740f2a26ad62a5c155af9199af9e69b889claireho}
10227f654740f2a26ad62a5c155af9199af9e69b889claireho
10327f654740f2a26ad62a5c155af9199af9e69b889clairehoCharString &CharString::appendInvariantChars(const UnicodeString &s, UErrorCode &errorCode) {
10427f654740f2a26ad62a5c155af9199af9e69b889claireho    if(ensureCapacity(len+s.length()+1, 0, errorCode)) {
10527f654740f2a26ad62a5c155af9199af9e69b889claireho        len+=s.extract(0, 0x7fffffff, buffer.getAlias()+len, buffer.getCapacity()-len, US_INV);
10627f654740f2a26ad62a5c155af9199af9e69b889claireho    }
10727f654740f2a26ad62a5c155af9199af9e69b889claireho    return *this;
10827f654740f2a26ad62a5c155af9199af9e69b889claireho}
10927f654740f2a26ad62a5c155af9199af9e69b889claireho
11027f654740f2a26ad62a5c155af9199af9e69b889clairehoUBool CharString::ensureCapacity(int32_t capacity,
11127f654740f2a26ad62a5c155af9199af9e69b889claireho                                 int32_t desiredCapacityHint,
11227f654740f2a26ad62a5c155af9199af9e69b889claireho                                 UErrorCode &errorCode) {
11327f654740f2a26ad62a5c155af9199af9e69b889claireho    if(U_FAILURE(errorCode)) {
11427f654740f2a26ad62a5c155af9199af9e69b889claireho        return FALSE;
11527f654740f2a26ad62a5c155af9199af9e69b889claireho    }
11627f654740f2a26ad62a5c155af9199af9e69b889claireho    if(capacity>buffer.getCapacity()) {
11727f654740f2a26ad62a5c155af9199af9e69b889claireho        if(desiredCapacityHint==0) {
11827f654740f2a26ad62a5c155af9199af9e69b889claireho            desiredCapacityHint=capacity+buffer.getCapacity();
11927f654740f2a26ad62a5c155af9199af9e69b889claireho        }
12027f654740f2a26ad62a5c155af9199af9e69b889claireho        if( (desiredCapacityHint<=capacity || buffer.resize(desiredCapacityHint, len+1)==NULL) &&
12127f654740f2a26ad62a5c155af9199af9e69b889claireho            buffer.resize(capacity, len+1)==NULL
12227f654740f2a26ad62a5c155af9199af9e69b889claireho        ) {
12327f654740f2a26ad62a5c155af9199af9e69b889claireho            errorCode=U_MEMORY_ALLOCATION_ERROR;
12427f654740f2a26ad62a5c155af9199af9e69b889claireho            return FALSE;
12527f654740f2a26ad62a5c155af9199af9e69b889claireho        }
12627f654740f2a26ad62a5c155af9199af9e69b889claireho    }
12727f654740f2a26ad62a5c155af9199af9e69b889claireho    return TRUE;
12827f654740f2a26ad62a5c155af9199af9e69b889claireho}
12927f654740f2a26ad62a5c155af9199af9e69b889claireho
13027f654740f2a26ad62a5c155af9199af9e69b889clairehoU_NAMESPACE_END
131