ICU-7829 reset the default converter if the default converter name changes

X-SVN-Rev: 28310
This commit is contained in:
Steven R. Loomis 2010-07-14 23:01:37 +00:00
parent 82bdfe0afd
commit a8575b74fa
5 changed files with 101 additions and 5 deletions

View File

@ -1,7 +1,7 @@
/*
********************************************************************
* COPYRIGHT:
* Copyright (c) 1996-2009, International Business Machines Corporation and
* Copyright (c) 1996-2010, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************
*
@ -1043,7 +1043,7 @@ ucnv_flushCache ()
UTRACE_ENTRY_OC(UTRACE_UCNV_FLUSH_CACHE);
/* Close the default converter without creating a new one so that everything will be flushed. */
ucnv_close(u_getDefaultConverter(&status));
u_flushDefaultConverter();
/*if shared data hasn't even been lazy evaluated yet
* return 0
@ -1317,6 +1317,9 @@ ucnv_setDefaultName(const char *converterName) {
/* The close may make the current name go away. */
ucnv_close(cnv);
/* reset the converter cache */
u_flushDefaultConverter();
}
#endif
}

View File

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1998-2004, International Business Machines
* Copyright (C) 1998-2010, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -80,6 +80,29 @@ u_releaseDefaultConverter(UConverter *converter)
}
}
U_CAPI void U_EXPORT2
u_flushDefaultConverter()
{
UConverter *converter = NULL;
if (gDefaultConverter != NULL) {
umtx_lock(NULL);
/* need to check to make sure it wasn't taken out from under us */
if (gDefaultConverter != NULL) {
converter = gDefaultConverter;
gDefaultConverter = NULL;
}
umtx_unlock(NULL);
}
/* if the cache was populated, flush it */
if(converter != NULL) {
ucnv_close(converter);
}
}
/* conversions between char* and UChar* ------------------------------------- */
/* maximum string length for u_uastrcpy() and u_austrcpy() implementations */

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 1999-2004, International Business Machines
* Copyright (C) 1999-2010, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* file name: ustr_cnv.h
@ -37,6 +37,13 @@ u_getDefaultConverter(UErrorCode *status);
U_CAPI void U_EXPORT2
u_releaseDefaultConverter(UConverter *converter);
/**
* Flush the default converter, if cached.
* @internal
*/
U_CAPI void U_EXPORT2
u_flushDefaultConverter(void);
#endif
#endif

View File

@ -113,6 +113,7 @@ static void TestConvertExFromUTF8(void);
static void TestConvertExFromUTF8_C5F0(void);
static void TestConvertAlgorithmic(void);
void TestDefaultConverterError(void); /* defined in cctest.c */
void TestDefaultConverterSet(void); /* defined in cctest.c */
static void TestToUCountPending(void);
static void TestFromUCountPending(void);
static void TestDefaultName(void);
@ -147,6 +148,7 @@ void addTestConvert(TestNode** root)
addTest(root, &TestConvertExFromUTF8_C5F0, "tsconv/ccapitst/TestConvertExFromUTF8_C5F0");
addTest(root, &TestConvertAlgorithmic, "tsconv/ccapitst/TestConvertAlgorithmic");
addTest(root, &TestDefaultConverterError, "tsconv/ccapitst/TestDefaultConverterError");
addTest(root, &TestDefaultConverterSet, "tsconv/ccapitst/TestDefaultConverterSet");
#if !UCONFIG_NO_FILE_IO
addTest(root, &TestToUCountPending, "tsconv/ccapitst/TestToUCountPending");
addTest(root, &TestFromUCountPending, "tsconv/ccapitst/TestFromUCountPending");

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2004, International Business Machines Corporation and
* Copyright (c) 1997-2010, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@ -9,7 +9,9 @@
#include "cintltst.h"
#include "ustr_cnv.h"
#include <string.h>
void TestDefaultConverterError(void); /* keep gcc happy */
void TestDefaultConverterSet(void); /* keep gcc happy */
/* This makes sure that a converter isn't leaked when an error is passed to
@ -32,5 +34,64 @@ void TestDefaultConverterError(void) {
}
}
/* Get the default converter. Copy its name. Put it back. */
static void copyDefaultConverterName(char *out, UErrorCode *status) {
UConverter *defConv;
const char *itsName;
out[0]=0;
if(U_FAILURE(*status)) return;
defConv = u_getDefaultConverter(status);
/* get its name */
itsName = ucnv_getName(defConv, status);
if(U_FAILURE(*status)) return;
strcpy(out, itsName);
/* put it back. */
u_releaseDefaultConverter(defConv);
}
/*
Changing the default name may not affect the actual name from u_getDefaultConverter
( for example, if UTF-8 is the fixed converter ).
But, if it does cause a change, that change should be reflected when the converter is
set back.
*/
void TestDefaultConverterSet(void) {
UErrorCode status = U_ZERO_ERROR;
static char defaultName[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
static char nameBeforeSet[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
static char nameAfterSet[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
static char nameAfterRestore[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
static const char SET_TO[]="iso-8859-3";
strcpy(defaultName, ucnv_getDefaultName());
log_verbose("getDefaultName returned %s\n", defaultName);
/* first, flush any extant converter */
u_flushDefaultConverter();
copyDefaultConverterName(nameBeforeSet, &status);
log_verbose("name from u_getDefaultConverter() = %s\n", nameBeforeSet);
u_flushDefaultConverter();
ucnv_setDefaultName(SET_TO);
copyDefaultConverterName(nameAfterSet, &status);
log_verbose("name from u_getDefaultConverter() after set to %s (%s) = %s\n", SET_TO, ucnv_getDefaultName(), nameAfterSet);
ucnv_setDefaultName(defaultName);
copyDefaultConverterName(nameAfterRestore, &status);
log_verbose("name from u_getDefaultConverter() after restore = %s\n", nameAfterRestore);
u_flushDefaultConverter();
if(U_FAILURE(status)) {
log_err("Error in test: %s\n", u_errorName(status));
} else {
if(!strcmp(nameBeforeSet, nameAfterSet)) { /* changing the default didn't affect. */
log_info("Skipping test: ucnv_setDefaultName() did not affect actual name of %s\n", nameBeforeSet);
} else {
if(strcmp(nameBeforeSet, nameAfterRestore)) {
log_err("Error: u_getDefaultConverter() is still returning %s (expected %s) even though default converter was set back to %s (was %s)\n", nameAfterRestore, nameBeforeSet, defaultName , SET_TO);
} else {
log_verbose("Test passed. \n");
}
}
}
}