mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 04:29:31 +00:00
ICU-4639 Improve the thread safety and simplify the UEnumeration
X-SVN-Rev: 19078
This commit is contained in:
parent
e404ee2694
commit
a93842f01e
3 changed files with 85 additions and 138 deletions
|
@ -6,11 +6,14 @@
|
|||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/ucsdet.h"
|
||||
|
||||
#include "csdetect.h"
|
||||
#include "csmatch.h"
|
||||
#include "uenumimp.h"
|
||||
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "umutex.h"
|
||||
#include "ucln_in.h"
|
||||
#include "inputext.h"
|
||||
|
@ -20,23 +23,34 @@
|
|||
#include "csrucode.h"
|
||||
#include "csr2022.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
|
||||
|
||||
#define NEW_ARRAY(type,count) (type *) uprv_malloc((count) * sizeof(type))
|
||||
#define DELETE_ARRAY(array) uprv_free((void *) (array))
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static CharsetRecognizer **fCSRecognizers = NULL;
|
||||
|
||||
static int32_t fCSRecognizers_size = 0;
|
||||
|
||||
static UBool U_CALLCONV csdet_cleanup(void)
|
||||
{
|
||||
return CharsetDetector::cleanup();
|
||||
if (fCSRecognizers != NULL) {
|
||||
for(int32_t r = 0; r < fCSRecognizers_size; r += 1) {
|
||||
delete fCSRecognizers[r];
|
||||
fCSRecognizers[r] = NULL;
|
||||
}
|
||||
|
||||
DELETE_ARRAY(fCSRecognizers);
|
||||
fCSRecognizers = NULL;
|
||||
fCSRecognizers_size = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
CharsetRecognizer **CharsetDetector::fCSRecognizers = NULL;
|
||||
|
||||
int32_t CharsetDetector::fCSRecognizers_size = 0;
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void CharsetDetector::setRecognizers()
|
||||
{
|
||||
|
@ -117,22 +131,6 @@ void CharsetDetector::setRecognizers()
|
|||
}
|
||||
}
|
||||
|
||||
UBool CharsetDetector::cleanup()
|
||||
{
|
||||
if (fCSRecognizers != NULL) {
|
||||
for(int32_t r = 0; r < fCSRecognizers_size; r += 1) {
|
||||
delete fCSRecognizers[r];
|
||||
fCSRecognizers[r] = NULL;
|
||||
}
|
||||
|
||||
DELETE_ARRAY(fCSRecognizers);
|
||||
fCSRecognizers = NULL;
|
||||
fCSRecognizers_size = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CharsetDetector::CharsetDetector()
|
||||
: textIn(new InputText()), fStripTags(FALSE), fFreshTextSet(FALSE)
|
||||
{
|
||||
|
@ -278,3 +276,68 @@ const char *CharsetDetector::getCharsetName(int32_t index, UErrorCode &status) c
|
|||
|
||||
U_NAMESPACE_END
|
||||
|
||||
U_CDECL_BEGIN
|
||||
typedef struct {
|
||||
int32_t currIndex;
|
||||
} Context;
|
||||
|
||||
|
||||
|
||||
static void U_CALLCONV
|
||||
enumClose(UEnumeration *en) {
|
||||
if(en->context != NULL) {
|
||||
DELETE_ARRAY(en->context);
|
||||
}
|
||||
|
||||
DELETE_ARRAY(en);
|
||||
}
|
||||
|
||||
static int32_t U_CALLCONV
|
||||
enumCount(UEnumeration *en, UErrorCode *status) {
|
||||
return fCSRecognizers_size;
|
||||
}
|
||||
|
||||
static const char* U_CALLCONV
|
||||
enumNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
|
||||
if(((Context *)en->context)->currIndex >= fCSRecognizers_size) {
|
||||
return NULL;
|
||||
}
|
||||
const char *currName = fCSRecognizers[((Context *)en->context)->currIndex]->getName();
|
||||
*resultLength = (int32_t)uprv_strlen(currName);
|
||||
((Context *)en->context)->currIndex++;
|
||||
|
||||
return currName;
|
||||
}
|
||||
|
||||
static void U_CALLCONV
|
||||
enumReset(UEnumeration *en, UErrorCode *status) {
|
||||
((Context *)en->context)->currIndex = 0;
|
||||
}
|
||||
|
||||
UEnumeration enumeration = {
|
||||
NULL,
|
||||
NULL,
|
||||
enumClose,
|
||||
enumCount,
|
||||
uenum_unextDefault,
|
||||
enumNext,
|
||||
enumReset
|
||||
};
|
||||
|
||||
U_DRAFT UEnumeration * U_EXPORT2
|
||||
ucsdet_getAllDetectableCharsets(const UCharsetDetector *ucsd, UErrorCode *status)
|
||||
{
|
||||
if(U_FAILURE(*status)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize recognized charsets. */
|
||||
CharsetDetector::getDetectableCount();
|
||||
|
||||
UEnumeration *en = NEW_ARRAY(UEnumeration, 1);
|
||||
memcpy(en, &enumeration, sizeof(UEnumeration));
|
||||
en->context = (void*)NEW_ARRAY(Context, 1);
|
||||
uprv_memset(en->context, 0, sizeof(Context));
|
||||
return en;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
|
|
@ -24,8 +24,6 @@ private:
|
|||
CharsetMatch **resultArray;
|
||||
UBool fStripTags; // If true, setText() will strip tags from input text.
|
||||
UBool fFreshTextSet;
|
||||
static CharsetRecognizer **fCSRecognizers;
|
||||
static int32_t fCSRecognizers_size;
|
||||
static void setRecognizers();
|
||||
|
||||
public:
|
||||
|
@ -48,8 +46,6 @@ public:
|
|||
const char *getCharsetName(int32_t index, UErrorCode& status) const;
|
||||
|
||||
static int32_t getDetectableCount();
|
||||
|
||||
static UBool cleanup();
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -11,12 +11,7 @@
|
|||
#include "csdetect.h"
|
||||
#include "csmatch.h"
|
||||
|
||||
#include "unicode/putil.h"
|
||||
|
||||
#include "cmemory.h"
|
||||
#include "uenumimp.h"
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
|
||||
|
||||
|
@ -144,113 +139,6 @@ ucsdet_detectAll(UCharsetDetector *ucsd,
|
|||
// }
|
||||
// return UCharsetDetector::getDetectableCount();
|
||||
// }
|
||||
U_CDECL_END
|
||||
|
||||
typedef struct {
|
||||
int32_t currIndex;
|
||||
int32_t maxIndex;
|
||||
char *currChar;
|
||||
UChar *currUChar;
|
||||
char **array;
|
||||
} Context;
|
||||
|
||||
#define cont ((Context *)en->context)
|
||||
|
||||
static void U_CALLCONV
|
||||
enumClose(UEnumeration *en) {
|
||||
if(cont->currUChar != NULL) {
|
||||
DELETE_ARRAY(cont->currUChar);
|
||||
cont->currUChar = NULL;
|
||||
}
|
||||
|
||||
delete en;
|
||||
}
|
||||
|
||||
static int32_t U_CALLCONV
|
||||
enumCount(UEnumeration *en, UErrorCode *status) {
|
||||
return cont->maxIndex;
|
||||
}
|
||||
|
||||
static const UChar* U_CALLCONV
|
||||
enumUNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
|
||||
if(cont->currIndex >= cont->maxIndex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(cont->currUChar == NULL) {
|
||||
cont->currUChar = NEW_ARRAY(UChar, 1024);
|
||||
}
|
||||
|
||||
cont->currChar = (cont->array)[cont->currIndex];
|
||||
*resultLength = (int32_t)strlen(cont->currChar);
|
||||
u_charsToUChars(cont->currChar, cont->currUChar, *resultLength);
|
||||
cont->currIndex++;
|
||||
|
||||
return cont->currUChar;
|
||||
}
|
||||
|
||||
static const char* U_CALLCONV
|
||||
enumNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
|
||||
if(cont->currIndex >= cont->maxIndex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cont->currChar = (cont->array)[cont->currIndex];
|
||||
*resultLength = (int32_t)strlen(cont->currChar);
|
||||
cont->currIndex++;
|
||||
|
||||
return cont->currChar;
|
||||
}
|
||||
|
||||
static void U_CALLCONV
|
||||
enumReset(UEnumeration *en, UErrorCode *status) {
|
||||
cont->currIndex = 0;
|
||||
}
|
||||
|
||||
Context enumContext = {
|
||||
0, 0,
|
||||
NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
UEnumeration enumeration = {
|
||||
NULL,
|
||||
&enumContext,
|
||||
enumClose,
|
||||
enumCount,
|
||||
enumUNext,
|
||||
enumNext,
|
||||
enumReset
|
||||
};
|
||||
|
||||
|
||||
static UEnumeration *getEnum(const char** source, int32_t size) {
|
||||
UEnumeration *en = new UEnumeration;
|
||||
memcpy(en, &enumeration, sizeof(UEnumeration));
|
||||
cont->array = (char **)source;
|
||||
cont->maxIndex = size;
|
||||
return en;
|
||||
}
|
||||
|
||||
static const char** charsets = NEW_ARRAY(const char *, CharsetDetector::getDetectableCount());
|
||||
|
||||
U_CDECL_BEGIN
|
||||
U_DRAFT UEnumeration * U_EXPORT2
|
||||
ucsdet_getAllDetectableCharsets(const UCharsetDetector *ucsd, UErrorCode *status)
|
||||
{
|
||||
if(U_FAILURE(*status)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CharsetDetector *csd = (CharsetDetector *) ucsd;
|
||||
int32_t size = CharsetDetector::getDetectableCount();
|
||||
|
||||
for(int32_t index=0; index<size; index += 1) {
|
||||
charsets[index] = csd->getCharsetName(index, *status);
|
||||
}
|
||||
|
||||
return getEnum(charsets, size);
|
||||
}
|
||||
|
||||
U_DRAFT UBool U_EXPORT2
|
||||
ucsdet_isInputFilterEnabled(const UCharsetDetector *ucsd)
|
||||
|
|
Loading…
Add table
Reference in a new issue