mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-06 22:15:31 +00:00
ICU-7247 use LocalMemory & MaybeStackArray in some places
X-SVN-Rev: 26964
This commit is contained in:
parent
786d5042dd
commit
d73228968d
5 changed files with 98 additions and 178 deletions
|
@ -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<char, ULOC_FULLNAME_CAPACITY> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<uint8_t> 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;
|
||||
|
|
|
@ -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<void *, 16> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<UChar, 300> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<UStringPrepProfile> 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<UStringPrepKey> key;
|
||||
LocalMemory<char> keyName;
|
||||
LocalMemory<char> 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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue