ICU-432 more leak fixes

X-SVN-Rev: 1824
This commit is contained in:
Vladimir Weinstein 2000-07-12 22:59:57 +00:00
parent 09f92d4480
commit 8349610248
9 changed files with 104 additions and 40 deletions

View file

@ -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)) {

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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.

View file

@ -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.

View file

@ -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
*/

View file

@ -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;

View file

@ -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);

View file

@ -184,6 +184,8 @@ void CharIterTest::TestConstructionAndEqualityUChariter() {
errln("operator= failed");
free(testText);
free(testText2);
delete test1;
delete test2;