mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 22:44:49 +00:00
ICU-432 more leak fixes
X-SVN-Rev: 1824
This commit is contained in:
parent
09f92d4480
commit
8349610248
9 changed files with 104 additions and 40 deletions
|
@ -502,7 +502,7 @@ ResourceBundle::getStringArray( const char *resourceTag,
|
|||
|
||||
if(sldata == 0) {
|
||||
UResourceBundle array;
|
||||
ures_initStackObject(&array);
|
||||
ures_setIsStackObject(&array, TRUE);
|
||||
UErrorCode fallbackInfo = U_ZERO_ERROR;
|
||||
ures_getByKey(resource, resourceTag, &array, &fallbackInfo);
|
||||
if(U_SUCCESS(fallbackInfo)) {
|
||||
|
@ -566,7 +566,7 @@ ResourceBundle::get2dArray(const char *resourceTag,
|
|||
|
||||
if(sldata == 0) {
|
||||
UResourceBundle array;
|
||||
ures_initStackObject(&array);
|
||||
ures_setIsStackObject(&array, TRUE);
|
||||
UErrorCode fallbackInfo = U_ZERO_ERROR;
|
||||
ures_getByKey(resource, resourceTag, &array, &fallbackInfo);
|
||||
if(U_SUCCESS(fallbackInfo)) {
|
||||
|
@ -574,7 +574,7 @@ ResourceBundle::get2dArray(const char *resourceTag,
|
|||
if(rowCount > 0) {
|
||||
result = new UnicodeString*[rowCount];
|
||||
UResourceBundle row;
|
||||
ures_initStackObject(&row);
|
||||
ures_setIsStackObject(&row, TRUE);
|
||||
ures_getByIndex(&array, 0, &row, &err);
|
||||
columnCount = ures_getSize(&row);
|
||||
const UChar* string = 0;
|
||||
|
@ -653,7 +653,7 @@ ResourceBundle::getTaggedArrayItem( const char *resourceTag,
|
|||
|
||||
if(sldata == 0) {
|
||||
UResourceBundle table;
|
||||
ures_initStackObject(&table);
|
||||
ures_setIsStackObject(&table, TRUE);
|
||||
UErrorCode fallbackInfo = U_ZERO_ERROR;
|
||||
ures_getByKey(resource, resourceTag, &table, &fallbackInfo);
|
||||
if(U_SUCCESS(fallbackInfo)) {
|
||||
|
|
|
@ -393,7 +393,7 @@ U_CFUNC UResourceBundle* ures_openNoFallback(const char* path, const char* local
|
|||
|
||||
r->fHasFallback = FALSE;
|
||||
r->fIsTopLevel = TRUE;
|
||||
r->fIsStackObject = FALSE;
|
||||
ures_setIsStackObject(r, FALSE);
|
||||
r->fIndex = -1;
|
||||
r->fData = entryOpen(path, localeID, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
|
@ -417,13 +417,16 @@ U_CFUNC UResourceBundle* ures_openNoFallback(const char* path, const char* local
|
|||
return r;
|
||||
}
|
||||
|
||||
UResourceBundle *init_resb_result(const ResourceData *rdata, const Resource r, const char *key, UResourceDataEntry *realData, UResourceBundle *resB) {
|
||||
UResourceBundle *init_resb_result(const ResourceData *rdata, const Resource r, const char *key, UResourceDataEntry *realData, UResourceBundle *resB, UErrorCode *status) {
|
||||
if(status == NULL || U_FAILURE(*status)) {
|
||||
return resB;
|
||||
}
|
||||
if(resB == NULL) {
|
||||
resB = (UResourceBundle *)uprv_malloc(sizeof(UResourceBundle));
|
||||
resB->fIsStackObject = FALSE;
|
||||
ures_setIsStackObject(resB, FALSE);
|
||||
} else {
|
||||
if(resB->fIsStackObject != FALSE) {
|
||||
resB->fIsStackObject = TRUE;
|
||||
if(ures_isStackObject(resB, status) != FALSE) {
|
||||
ures_setIsStackObject(resB, TRUE);
|
||||
}
|
||||
}
|
||||
resB->fData = realData;
|
||||
|
@ -451,10 +454,17 @@ UResourceBundle *copyResb(UResourceBundle *r, const UResourceBundle *original, U
|
|||
isStackObject = FALSE;
|
||||
r = (UResourceBundle *)uprv_malloc(sizeof(UResourceBundle));
|
||||
} else {
|
||||
isStackObject = TRUE;
|
||||
isStackObject = ures_isStackObject(r, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return r;
|
||||
}
|
||||
if(isStackObject == FALSE) {
|
||||
ures_close(r);
|
||||
r = (UResourceBundle *)uprv_malloc(sizeof(UResourceBundle));
|
||||
}
|
||||
}
|
||||
uprv_memcpy(r, original, sizeof(UResourceBundle));
|
||||
r->fIsStackObject = isStackObject;
|
||||
ures_setIsStackObject(r, isStackObject);
|
||||
if(r->fData != NULL) {
|
||||
entryIncrease(r->fData);
|
||||
}
|
||||
|
@ -469,7 +479,7 @@ void copyResbFillIn(UResourceBundle *r, const UResourceBundle *original) {
|
|||
return;
|
||||
}
|
||||
uprv_memcpy(r, original, sizeof(UResourceBundle));
|
||||
r->fIsStackObject = TRUE;
|
||||
ures_setIsStackObject(r, TRUE);
|
||||
if(original->fData != NULL) {
|
||||
entryIncrease(r->fData);
|
||||
}
|
||||
|
@ -664,14 +674,14 @@ U_CAPI UResourceBundle* U_EXPORT2 ures_getNextResource(UResourceBundle *resB, UR
|
|||
if(r == RES_BOGUS && resB->fHasFallback) {
|
||||
/* TODO: do the fallback */
|
||||
}
|
||||
return init_resb_result(&(resB->fResData), r, key, resB->fData, fillIn);
|
||||
return init_resb_result(&(resB->fResData), r, key, resB->fData, fillIn, status);
|
||||
break;
|
||||
case RES_ARRAY:
|
||||
r = res_getArrayItem(&(resB->fResData), resB->fRes, resB->fIndex);
|
||||
if(r == RES_BOGUS && resB->fHasFallback) {
|
||||
/* TODO: do the fallback */
|
||||
}
|
||||
return init_resb_result(&(resB->fResData), r, key, resB->fData, fillIn);
|
||||
return init_resb_result(&(resB->fResData), r, key, resB->fData, fillIn, status);
|
||||
break;
|
||||
case RES_INT_VECTOR:
|
||||
default:
|
||||
|
@ -710,14 +720,14 @@ U_CAPI UResourceBundle* U_EXPORT2 ures_getByIndex(const UResourceBundle *resB, i
|
|||
if(r == RES_BOGUS && resB->fHasFallback) {
|
||||
/* TODO: do the fallback */
|
||||
}
|
||||
return init_resb_result(&(resB->fResData), r, key, resB->fData, fillIn);
|
||||
return init_resb_result(&(resB->fResData), r, key, resB->fData, fillIn, status);
|
||||
break;
|
||||
case RES_ARRAY:
|
||||
r = res_getArrayItem(&(resB->fResData), resB->fRes, indexR);
|
||||
if(r == RES_BOGUS && resB->fHasFallback) {
|
||||
/* TODO: do the fallback */
|
||||
}
|
||||
return init_resb_result(&(resB->fResData), r, key, resB->fData, fillIn);
|
||||
return init_resb_result(&(resB->fResData), r, key, resB->fData, fillIn, status);
|
||||
break;
|
||||
case RES_INT_VECTOR:
|
||||
default:
|
||||
|
@ -805,7 +815,7 @@ U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, con
|
|||
/*return NULL;*/
|
||||
return fillIn;
|
||||
} else {
|
||||
return init_resb_result(rd, res, key, realData, fillIn);
|
||||
return init_resb_result(rd, res, key, realData, fillIn, status);
|
||||
}
|
||||
} else {
|
||||
*status = U_MISSING_RESOURCE_ERROR;
|
||||
|
@ -813,7 +823,7 @@ U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, con
|
|||
return fillIn;
|
||||
}
|
||||
} else {
|
||||
return init_resb_result(&(resB->fResData), res, key, resB->fData, fillIn);
|
||||
return init_resb_result(&(resB->fResData), res, key, resB->fData, fillIn, status);
|
||||
}
|
||||
} else if(RES_GET_TYPE(resB->fRes) == RES_ARRAY && resB->fHasFallback == TRUE) {
|
||||
/* here should go a first attempt to locate the key using index table */
|
||||
|
@ -822,7 +832,7 @@ U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, con
|
|||
/*return NULL;*/
|
||||
return fillIn;
|
||||
} else {
|
||||
return init_resb_result(rd, res, key, realData, fillIn);
|
||||
return init_resb_result(rd, res, key, realData, fillIn, status);
|
||||
}
|
||||
} else {
|
||||
*status = U_RESOURCE_TYPE_MISMATCH;
|
||||
|
@ -980,7 +990,6 @@ U_CAPI void ures_openFillIn(UResourceBundle *r, const char* path,
|
|||
UResourceDataEntry *firstData;
|
||||
r->fHasFallback = TRUE;
|
||||
r->fIsTopLevel = TRUE;
|
||||
r->fIsStackObject = TRUE;
|
||||
r->fKey = NULL;
|
||||
r->fVersion = NULL;
|
||||
r->fIndex = -1;
|
||||
|
@ -1010,7 +1019,7 @@ U_CAPI UResourceBundle* ures_open(const char* path,
|
|||
|
||||
r->fHasFallback = TRUE;
|
||||
r->fIsTopLevel = TRUE;
|
||||
r->fIsStackObject = FALSE;
|
||||
ures_setIsStackObject(r, FALSE);
|
||||
r->fKey = NULL;
|
||||
r->fVersion = NULL;
|
||||
r->fIndex = -1;
|
||||
|
@ -1085,10 +1094,32 @@ U_CAPI UResourceBundle* U_EXPORT2 ures_openU(const UChar* myPath,
|
|||
return r;
|
||||
}
|
||||
|
||||
U_CAPI void ures_initStackObject( UResourceBundle* resB) {
|
||||
resB->fIsStackObject = TRUE;
|
||||
U_CAPI void ures_setIsStackObject( UResourceBundle* resB, UBool state) {
|
||||
if(state == TRUE) {
|
||||
resB->fMagic1 = 0;
|
||||
resB->fMagic2 = 0;
|
||||
} else {
|
||||
resB->fMagic1 = MAGIC1;
|
||||
resB->fMagic2 = MAGIC2;
|
||||
}
|
||||
}
|
||||
|
||||
U_CAPI UBool ures_isStackObject( UResourceBundle* resB, UErrorCode *status) {
|
||||
if(status == NULL || U_FAILURE(*status)) {
|
||||
return FALSE;
|
||||
}
|
||||
if(resB == NULL) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return TRUE;
|
||||
}
|
||||
if(resB->fMagic1 == MAGIC1 && resB->fMagic2 == MAGIC2) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U_CAPI const UChar* ures_get( const UResourceBundle* resB,
|
||||
const char* resourceTag,
|
||||
UErrorCode* status)
|
||||
|
@ -1107,7 +1138,7 @@ U_CAPI const UChar* ures_getArrayItem(const UResourceBundle* resB,
|
|||
UErrorCode* status)
|
||||
{
|
||||
UResourceBundle res;
|
||||
ures_initStackObject(&res);
|
||||
ures_setIsStackObject(&res, TRUE);
|
||||
if (status==NULL || U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1133,7 +1164,7 @@ U_CAPI const UChar* ures_get2dArrayItem(const UResourceBundle* resB,
|
|||
UErrorCode* status)
|
||||
{
|
||||
UResourceBundle res;
|
||||
ures_initStackObject(&res);
|
||||
ures_setIsStackObject(&res, TRUE);
|
||||
if (status==NULL || U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1144,7 +1175,7 @@ U_CAPI const UChar* ures_get2dArrayItem(const UResourceBundle* resB,
|
|||
ures_getByKey(resB, resourceTag, &res, status);
|
||||
if(U_SUCCESS(*status)) {
|
||||
UResourceBundle res2;
|
||||
ures_initStackObject(&res2);
|
||||
ures_setIsStackObject(&res2, TRUE);
|
||||
ures_getByIndex(&res, rowIndex, &res2, status);
|
||||
ures_close(&res);
|
||||
if(U_SUCCESS(*status)) {
|
||||
|
@ -1166,7 +1197,7 @@ U_CAPI const UChar* ures_getTaggedArrayItem(const UResourceBundle* resB,
|
|||
UErrorCode* status)
|
||||
{
|
||||
UResourceBundle res;
|
||||
ures_initStackObject(&res);
|
||||
ures_setIsStackObject(&res, TRUE);
|
||||
if (status==NULL || U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1196,7 +1227,7 @@ U_CAPI int32_t ures_countArrayItems(const UResourceBundle* resourceBundle,
|
|||
Resource res = RES_BOGUS;
|
||||
|
||||
UResourceBundle resData;
|
||||
ures_initStackObject(&resData);
|
||||
ures_setIsStackObject(&resData, TRUE);
|
||||
if (status==NULL || U_FAILURE(*status)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1219,6 +1250,7 @@ U_CAPI int32_t ures_countArrayItems(const UResourceBundle* resourceBundle,
|
|||
|
||||
U_CAPI void ures_close(UResourceBundle* resB)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
if(resB != NULL) {
|
||||
if(resB->fData != NULL) {
|
||||
entryClose(resB->fData);
|
||||
|
@ -1232,7 +1264,7 @@ U_CAPI void ures_close(UResourceBundle* resB)
|
|||
uprv_free(resB->fVersion);
|
||||
}
|
||||
|
||||
if(resB->fIsStackObject == FALSE) {
|
||||
if(ures_isStackObject(resB, &status) == FALSE) {
|
||||
uprv_free(resB);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#define kVersionSeparator "."
|
||||
#define kVersionTag "Version"
|
||||
|
||||
#define MAGIC1 19700503
|
||||
#define MAGIC2 19641227
|
||||
|
||||
|
||||
enum UResEntryType {
|
||||
ENTRY_OK = 0,
|
||||
|
@ -53,7 +56,9 @@ struct UResourceBundle {
|
|||
char *fVersion;
|
||||
UBool fHasFallback;
|
||||
UBool fIsTopLevel;
|
||||
UBool fIsStackObject;
|
||||
uint32_t fMagic1;
|
||||
uint32_t fMagic2;
|
||||
/*UBool fIsStackObject;*/
|
||||
UResourceDataEntry *fData; /*for low-level access*/
|
||||
int32_t fIndex;
|
||||
int32_t fSize;
|
||||
|
@ -64,7 +69,9 @@ struct UResourceBundle {
|
|||
/*U_CFUNC UResourceBundle* ures_openNoFallback(UResourceBundle *r, const char* path, const char* localeID, UErrorCode* status);*/
|
||||
U_CFUNC UResourceBundle* ures_openNoFallback(const char* path, const char* localeID, UErrorCode* status);
|
||||
U_CFUNC const char* ures_getRealLocale(const UResourceBundle* resourceBundle, UErrorCode* status);
|
||||
U_CAPI void ures_initStackObject( UResourceBundle* resB);
|
||||
U_CAPI void ures_setIsStackObject( UResourceBundle* resB, UBool state);
|
||||
U_CAPI UBool ures_isStackObject( UResourceBundle* resB, UErrorCode *status);
|
||||
|
||||
/*U_CFUNC UChar** ures_listInstalledLocales(const char *path, int32_t* count);*/
|
||||
U_CFUNC const ResourceData *getFallbackData(const UResourceBundle* resBundle, const char* * resTag, UResourceDataEntry* *realData, Resource *res, UErrorCode *status);
|
||||
U_CFUNC int32_t hashBundle(const void *parm);
|
||||
|
|
|
@ -545,7 +545,7 @@ void TransliterationRuleParser::parseRules(void) {
|
|||
|
||||
// Convert the set vector to an array
|
||||
data->setVariablesLength = setVariablesVector.size();
|
||||
data->setVariables = new UnicodeSet*[data->setVariablesLength];
|
||||
data->setVariables = data->setVariablesLength == 0 ? 0 : new UnicodeSet*[data->setVariablesLength];
|
||||
// orphanElement removes the given element and shifts all other
|
||||
// elements down. For performance (and code clarity) we work from
|
||||
// the end back to index 0.
|
||||
|
|
|
@ -29,9 +29,15 @@
|
|||
/**
|
||||
* Construct a new empty rule set.
|
||||
*/
|
||||
void deleteRule(void *rule) {
|
||||
delete (TransliterationRule *)rule;
|
||||
}
|
||||
|
||||
TransliterationRuleSet::TransliterationRuleSet() {
|
||||
maxContextLength = 0;
|
||||
ruleVector = new UVector();
|
||||
ruleVector->setDeleter(&deleteRule);
|
||||
isFrozen = FALSE;
|
||||
rules = NULL;
|
||||
}
|
||||
|
||||
|
@ -40,7 +46,8 @@ TransliterationRuleSet::TransliterationRuleSet() {
|
|||
* has already been frozen.
|
||||
*/
|
||||
TransliterationRuleSet::TransliterationRuleSet(const TransliterationRuleSet& other) :
|
||||
ruleVector(0),
|
||||
ruleVector(NULL),
|
||||
isFrozen(TRUE),
|
||||
maxContextLength(other.maxContextLength) {
|
||||
|
||||
uprv_memcpy(index, other.index, sizeof(index));
|
||||
|
@ -55,6 +62,9 @@ TransliterationRuleSet::TransliterationRuleSet(const TransliterationRuleSet& oth
|
|||
* Destructor.
|
||||
*/
|
||||
TransliterationRuleSet::~TransliterationRuleSet() {
|
||||
if(ruleVector != NULL) {
|
||||
ruleVector->removeAllElements();
|
||||
}
|
||||
delete ruleVector;
|
||||
delete[] rules;
|
||||
}
|
||||
|
@ -80,7 +90,8 @@ void TransliterationRuleSet::addRule(TransliterationRule* adoptedRule,
|
|||
delete adoptedRule;
|
||||
return;
|
||||
}
|
||||
if (ruleVector == NULL) {
|
||||
//if (ruleVector == NULL) {
|
||||
if (isFrozen == TRUE) {
|
||||
// throw new IllegalArgumentException("Cannot add rules after freezing");
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
delete adoptedRule;
|
||||
|
@ -162,8 +173,9 @@ void TransliterationRuleSet::freeze(const TransliterationRuleData& data,
|
|||
for (j=0; j<v.size(); ++j) {
|
||||
rules[j] = (TransliterationRule*) v.elementAt(j);
|
||||
}
|
||||
delete ruleVector;
|
||||
ruleVector = NULL;
|
||||
//delete ruleVector;
|
||||
//ruleVector = NULL;
|
||||
isFrozen = TRUE;
|
||||
|
||||
// TODO Add error reporting that indicates the rules that
|
||||
// are being masked.
|
||||
|
|
|
@ -37,6 +37,11 @@ class TransliterationRuleSet {
|
|||
*/
|
||||
UVector* ruleVector;
|
||||
|
||||
/**
|
||||
* freeing vector after freeze leaks rules. It should not be freed until destruction time
|
||||
*/
|
||||
UBool isFrozen;
|
||||
|
||||
/**
|
||||
* Length of the longest preceding context
|
||||
*/
|
||||
|
|
|
@ -725,9 +725,6 @@ SimpleDateFormat::parse(const UnicodeString& text, ParsePosition& pos) const
|
|||
int32_t oldStart = start;
|
||||
UBool ambiguousYear[] = { FALSE };
|
||||
|
||||
char s[100];
|
||||
s[text.extract(0, text.length(), s)]=0;
|
||||
|
||||
fCalendar->clear();
|
||||
|
||||
UBool inQuote = FALSE;
|
||||
|
|
|
@ -310,6 +310,9 @@ void TestBinaryCollationData(){
|
|||
log_err("ERROR: ures_getByKey(locale(te), CollationElements) failed");
|
||||
return;
|
||||
}
|
||||
ures_close(binColl);
|
||||
ures_close(coll);
|
||||
ures_close(teRes);
|
||||
|
||||
}
|
||||
void TestAPI(){
|
||||
|
@ -374,7 +377,7 @@ void TestAPI(){
|
|||
log_err("ERROR: ures_getByIndex on string resource fetched the key=%s, expected \"TE\" \n", austrdup(ures_getString(teFillin2, &len, &status)));
|
||||
}
|
||||
|
||||
ures_close(teRes);
|
||||
/*ures_close(teRes);*/
|
||||
|
||||
/*Test ures_openFillIn*/
|
||||
log_verbose("Testing ures_openFillIn......\n");
|
||||
|
@ -398,6 +401,8 @@ void TestAPI(){
|
|||
myErrorName(status));
|
||||
}
|
||||
|
||||
ures_close(teFillin);
|
||||
ures_close(teFillin2);
|
||||
ures_close(teRes);
|
||||
|
||||
|
||||
|
@ -603,6 +608,10 @@ void TestErrorConditions(){
|
|||
log_err("ERROR: ures_getInt() with errorCode != U_ZERO_ERROR should fail\n");
|
||||
}
|
||||
|
||||
ures_close(teFillin);
|
||||
ures_close(teFillin2);
|
||||
ures_close(coll);
|
||||
ures_close(binColl);
|
||||
ures_close(teRes);
|
||||
|
||||
|
||||
|
|
|
@ -184,6 +184,8 @@ void CharIterTest::TestConstructionAndEqualityUChariter() {
|
|||
errln("operator= failed");
|
||||
|
||||
|
||||
free(testText);
|
||||
free(testText2);
|
||||
|
||||
delete test1;
|
||||
delete test2;
|
||||
|
|
Loading…
Add table
Reference in a new issue