diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp index fe10efa0406..eb4eddfd9a0 100644 --- a/icu4c/source/common/locid.cpp +++ b/icu4c/source/common/locid.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1997-2008, International Business Machines + * Copyright (C) 1997-2009, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -320,9 +320,7 @@ Locale::Locale( const char * newLanguage, } else { - char togo_stack[ULOC_FULLNAME_CAPACITY]; - char *togo; - char *togo_heap = NULL; + MaybeStackArray togo; int32_t size = 0; int32_t lsize = 0; int32_t csize = 0; @@ -389,24 +387,18 @@ Locale::Locale( const char * newLanguage, /*if the whole string is longer than our internal limit, we need to go to the heap for temporary buffers*/ - if (size >= ULOC_FULLNAME_CAPACITY) + if (size >= togo.getCapacity()) { - togo_heap = (char *)uprv_malloc(sizeof(char)*(size+1)); // If togo_heap could not be created, initialize with default settings. - if (togo_heap == NULL) { + if (togo.resize(size+1) == NULL) { init(NULL, FALSE); } - togo = togo_heap; - } - else - { - togo = togo_stack; } togo[0] = 0; // Now, copy it back. - p = togo; + p = togo.getAlias(); if ( lsize != 0 ) { uprv_strcpy(p, newLanguage); @@ -450,11 +442,7 @@ Locale::Locale( const char * newLanguage, // Parse it, because for example 'language' might really be a complete // string. - init(togo, FALSE); - - if (togo_heap) { - uprv_free(togo_heap); - } + init(togo.getAlias(), FALSE); } } diff --git a/icu4c/source/common/propname.cpp b/icu4c/source/common/propname.cpp index 55e354044f3..1721f83ebd4 100644 --- a/icu4c/source/common/propname.cpp +++ b/icu4c/source/common/propname.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (c) 2002-2006, International Business Machines +* Copyright (c) 2002-2009, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Author: Alan Liu @@ -598,8 +598,6 @@ PropertyAliases::swap(const UDataSwapper *ds, ValueMap *outValueMaps; ValueMap valueMap; - uint8_t *temp; - int32_t i; inAliases=(const PropertyAliases *)inBytes; @@ -647,26 +645,25 @@ PropertyAliases::swap(const UDataSwapper *ds, * resort strings in name->enum maps * swap value maps */ - temp=(uint8_t *)uprv_malloc(aliases.total_size); - if(temp==NULL) { + LocalMemory temp; + if(temp.allocateInsteadAndReset(aliases.total_size)==NULL) { udata_printError(ds, "upname_swap(): unable to allocate temp memory (%d bytes)\n", aliases.total_size); *pErrorCode=U_MEMORY_ALLOCATION_ERROR; return 0; } - uprv_memset(temp, 0, aliases.total_size); /* swap properties->name groups map */ NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes, - temp, aliases.enumToName_offset, pErrorCode); + temp.getAlias(), aliases.enumToName_offset, pErrorCode); /* swap name->properties map */ NameToEnum::swap(ds, inBytes, length, outBytes, - temp, aliases.nameToEnum_offset, pErrorCode); + temp.getAlias(), aliases.nameToEnum_offset, pErrorCode); /* swap properties->value maps map */ NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes, - temp, aliases.enumToValue_offset, pErrorCode); + temp.getAlias(), aliases.enumToValue_offset, pErrorCode); /* enumerate all ValueMaps and swap them */ inValueMaps=(const ValueMap *)(inBytes+aliases.valueMap_offset); @@ -679,16 +676,16 @@ PropertyAliases::swap(const UDataSwapper *ds, if(valueMap.enumToName_offset!=0) { EnumToOffset::swap(ds, inBytes, length, outBytes, - temp, valueMap.enumToName_offset, + temp.getAlias(), valueMap.enumToName_offset, pErrorCode); } else if(valueMap.ncEnumToName_offset!=0) { NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes, - temp, valueMap.ncEnumToName_offset, + temp.getAlias(), valueMap.ncEnumToName_offset, pErrorCode); } if(valueMap.nameToEnum_offset!=0) { NameToEnum::swap(ds, inBytes, length, outBytes, - temp, valueMap.nameToEnum_offset, + temp.getAlias(), valueMap.nameToEnum_offset, pErrorCode); } } @@ -698,9 +695,6 @@ PropertyAliases::swap(const UDataSwapper *ds, outValueMaps, pErrorCode); /* name groups and strings were swapped above */ - - /* release temp */ - uprv_free(temp); } return aliases.total_size; diff --git a/icu4c/source/common/rbbitblb.cpp b/icu4c/source/common/rbbitblb.cpp index 44c8e9fdd98..2ce82dfed18 100644 --- a/icu4c/source/common/rbbitblb.cpp +++ b/icu4c/source/common/rbbitblb.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (c) 2002-2008, International Business Machines +* Copyright (c) 2002-2009, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -955,74 +955,56 @@ void RBBITableBuilder::setAdd(UVector *dest, UVector *source) { int32_t destOriginalSize = dest->size(); int32_t sourceSize = source->size(); int32_t di = 0; - void *(destS[16]), *(sourceS[16]); // Handle small cases without malloc - void **destH = 0, **sourceH = 0; - void **destBuff, **sourceBuff; + MaybeStackArray destArray, sourceArray; // Handle small cases without malloc + void **destPtr, **sourcePtr; void **destLim, **sourceLim; - if (destOriginalSize > (int32_t)(sizeof(destS)/sizeof(destS[0]))) { - destH = (void **)uprv_malloc(sizeof(void *) * destOriginalSize); - destBuff = destH; - } - else { - destBuff = destS; - } - if (destBuff == 0) { - return; - } - destLim = destBuff + destOriginalSize; - - if (sourceSize > (int32_t)(sizeof(sourceS)/sizeof(sourceS[0]))) { - sourceH = (void **)uprv_malloc(sizeof(void *) * sourceSize); - sourceBuff = sourceH; - } - else { - sourceBuff = sourceS; - } - if (sourceBuff == 0) { - if (destH) { - uprv_free(destH); + if (destOriginalSize > destArray.getCapacity()) { + if (destArray.resize(destOriginalSize) == NULL) { + return; } - return; } - sourceLim = sourceBuff + sourceSize; + destPtr = destArray.getAlias(); + destLim = destPtr + destOriginalSize; // destArray.getArrayLimit()? + + if (sourceSize > sourceArray.getCapacity()) { + if (sourceArray.resize(sourceSize) == NULL) { + return; + } + } + sourcePtr = sourceArray.getAlias(); + sourceLim = sourcePtr + sourceSize; // sourceArray.getArrayLimit()? // Avoid multiple "get element" calls by getting the contents into arrays - (void) dest->toArray(destBuff); - (void) source->toArray(sourceBuff); + (void) dest->toArray(destPtr); + (void) source->toArray(sourcePtr); dest->setSize(sourceSize+destOriginalSize, *fStatus); - while (sourceBuff < sourceLim && destBuff < destLim) { - if (*destBuff == *sourceBuff) { - dest->setElementAt(*sourceBuff++, di++); - destBuff++; + while (sourcePtr < sourceLim && destPtr < destLim) { + if (*destPtr == *sourcePtr) { + dest->setElementAt(*sourcePtr++, di++); + destPtr++; } // This check is required for machines with segmented memory, like i5/OS. // Direct pointer comparison is not recommended. - else if (uprv_memcmp(destBuff, sourceBuff, sizeof(void *)) < 0) { - dest->setElementAt(*destBuff++, di++); + else if (uprv_memcmp(destPtr, sourcePtr, sizeof(void *)) < 0) { + dest->setElementAt(*destPtr++, di++); } - else { /* *sourceBuff < *destBuff */ - dest->setElementAt(*sourceBuff++, di++); + else { /* *sourcePtr < *destPtr */ + dest->setElementAt(*sourcePtr++, di++); } } // At most one of these two cleanup loops will execute - while (destBuff < destLim) { - dest->setElementAt(*destBuff++, di++); + while (destPtr < destLim) { + dest->setElementAt(*destPtr++, di++); } - while (sourceBuff < sourceLim) { - dest->setElementAt(*sourceBuff++, di++); + while (sourcePtr < sourceLim) { + dest->setElementAt(*sourcePtr++, di++); } dest->setSize(di, *fStatus); - if (destH) { - uprv_free(destH); - } - if (sourceH) { - uprv_free(sourceH); - } } diff --git a/icu4c/source/common/unormcmp.cpp b/icu4c/source/common/unormcmp.cpp index 7b3903d898c..83ce3c2ba79 100644 --- a/icu4c/source/common/unormcmp.cpp +++ b/icu4c/source/common/unormcmp.cpp @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 2001-2006, International Business Machines +* Copyright (C) 2001-2009, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -534,8 +534,7 @@ unorm_compare(const UChar *s1, int32_t length1, const UChar *s2, int32_t length2, uint32_t options, UErrorCode *pErrorCode) { - UChar fcd1[300], fcd2[300]; - UChar *d1, *d2; + MaybeStackArray fcd1, fcd2; const UnicodeSet *nx; UNormalizationMode mode; int32_t normOptions; @@ -563,7 +562,6 @@ unorm_compare(const UChar *s1, int32_t length1, return 0; } - d1=d2=0; options|=_COMPARE_EQUIV; result=0; @@ -616,58 +614,50 @@ unorm_compare(const UChar *s1, int32_t length1, */ if(!isFCD1) { - _len1=unorm_internalNormalizeWithNX(fcd1, LENGTHOF(fcd1), + _len1=unorm_internalNormalizeWithNX(fcd1.getAlias(), fcd1.getCapacity(), s1, length1, mode, normOptions, nx, pErrorCode); - if(*pErrorCode!=U_BUFFER_OVERFLOW_ERROR) { - s1=fcd1; - } else { - d1=(UChar *)uprv_malloc(_len1*U_SIZEOF_UCHAR); - if(d1==0) { + if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { + if(fcd1.resize(_len1)==NULL) { *pErrorCode=U_MEMORY_ALLOCATION_ERROR; - goto cleanup; + return result; } *pErrorCode=U_ZERO_ERROR; - _len1=unorm_internalNormalizeWithNX(d1, _len1, + _len1=unorm_internalNormalizeWithNX(fcd1.getAlias(), fcd1.getCapacity(), s1, length1, mode, normOptions, nx, pErrorCode); if(U_FAILURE(*pErrorCode)) { - goto cleanup; + return result; } - - s1=d1; } + s1=fcd1.getAlias(); length1=_len1; } if(!isFCD2) { - _len2=unorm_internalNormalizeWithNX(fcd2, LENGTHOF(fcd2), + _len2=unorm_internalNormalizeWithNX(fcd2.getAlias(), fcd2.getCapacity(), s2, length2, mode, normOptions, nx, pErrorCode); - if(*pErrorCode!=U_BUFFER_OVERFLOW_ERROR) { - s2=fcd2; - } else { - d2=(UChar *)uprv_malloc(_len2*U_SIZEOF_UCHAR); - if(d2==0) { + if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { + if(fcd2.resize(_len2)==NULL) { *pErrorCode=U_MEMORY_ALLOCATION_ERROR; - goto cleanup; + return result; } *pErrorCode=U_ZERO_ERROR; - _len2=unorm_internalNormalizeWithNX(d2, _len2, + _len2=unorm_internalNormalizeWithNX(fcd2.getAlias(), fcd2.getCapacity(), s2, length2, mode, normOptions, nx, pErrorCode); if(U_FAILURE(*pErrorCode)) { - goto cleanup; + return result; } - - s2=d2; } + s2=fcd2.getAlias(); length2=_len2; } } @@ -675,15 +665,6 @@ unorm_compare(const UChar *s1, int32_t length1, if(U_SUCCESS(*pErrorCode)) { result=unorm_cmpEquivFold(s1, length1, s2, length2, options, pErrorCode); } - -cleanup: - if(d1!=0) { - uprv_free(d1); - } - if(d2!=0) { - uprv_free(d2); - } - return result; } diff --git a/icu4c/source/common/usprep.cpp b/icu4c/source/common/usprep.cpp index 4a723289b3c..a8f1a007237 100644 --- a/icu4c/source/common/usprep.cpp +++ b/icu4c/source/common/usprep.cpp @@ -330,89 +330,64 @@ usprep_getProfile(const char* path, /* fetch the data from the cache */ umtx_lock(&usprepMutex); profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey)); + if(profile != NULL) { + profile->refCount++; + } umtx_unlock(&usprepMutex); - if(profile == NULL){ - UStringPrepKey* key = (UStringPrepKey*) uprv_malloc(sizeof(UStringPrepKey)); - if(key == NULL){ - *status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } + if(profile == NULL) { /* else load the data and put the data in the cache */ - profile = (UStringPrepProfile*) uprv_malloc(sizeof(UStringPrepProfile)); - if(profile == NULL){ + LocalMemory newProfile; + if(newProfile.allocateInsteadAndReset() == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; - uprv_free(key); return NULL; } - /* initialize the data struct members */ - uprv_memset(profile->indexes,0,sizeof(profile->indexes)); - profile->mappingData = NULL; - profile->sprepData = NULL; - profile->refCount = 0; - - /* initialize the key memebers */ - key->name = (char*) uprv_malloc(uprv_strlen(name)+1); - if(key->name == NULL){ - *status = U_MEMORY_ALLOCATION_ERROR; - uprv_free(key); - uprv_free(profile); - return NULL; - } - - uprv_strcpy(key->name, name); - - key->path=NULL; - - if(path != NULL){ - key->path = (char*) uprv_malloc(uprv_strlen(path)+1); - if(key->path == NULL){ - *status = U_MEMORY_ALLOCATION_ERROR; - uprv_free(key->name); - uprv_free(key); - uprv_free(profile); - return NULL; - } - uprv_strcpy(key->path, path); - } - /* load the data */ - if(!loadData(profile, path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status) ){ - uprv_free(key->path); - uprv_free(key->name); - uprv_free(key); - uprv_free(profile); + if(!loadData(newProfile.getAlias(), path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status) ){ return NULL; } /* get the options */ - profile->doNFKC = (UBool)((profile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0); - profile->checkBiDi = (UBool)((profile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0); + newProfile->doNFKC = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0); + newProfile->checkBiDi = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0); - if(profile->checkBiDi) { - profile->bdp = ubidi_getSingleton(status); + if(newProfile->checkBiDi) { + newProfile->bdp = ubidi_getSingleton(status); if(U_FAILURE(*status)) { - usprep_unload(profile); - uprv_free(key->path); - uprv_free(key->name); - uprv_free(key); - uprv_free(profile); + usprep_unload(newProfile.getAlias()); return NULL; } - } else { - profile->bdp = NULL; } - + + LocalMemory key; + LocalMemory keyName; + LocalMemory keyPath; + if( key.allocateInsteadAndReset() == NULL || + keyName.allocateInsteadAndCopy(uprv_strlen(name)+1) == NULL || + (path != NULL && + keyPath.allocateInsteadAndCopy(uprv_strlen(path)+1) == NULL) + ) { + *status = U_MEMORY_ALLOCATION_ERROR; + usprep_unload(newProfile.getAlias()); + return NULL; + } + + /* initialize the key members */ + key->name = keyName.orphan(); + uprv_strcpy(key->name, name); + if(path != NULL){ + key->path = keyPath.orphan(); + uprv_strcpy(key->path, path); + } + + profile = newProfile.orphan(); umtx_lock(&usprepMutex); /* add the data object to the cache */ - uhash_put(SHARED_DATA_HASHTABLE, key, profile, status); + profile->refCount = 1; + uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status); umtx_unlock(&usprepMutex); } - umtx_lock(&usprepMutex); - /* increment the refcount */ - profile->refCount++; - umtx_unlock(&usprepMutex); return profile; }