summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu-xetex/common/ucase.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu-xetex/common/ucase.c')
-rw-r--r--Build/source/libs/icu-xetex/common/ucase.c128
1 files changed, 123 insertions, 5 deletions
diff --git a/Build/source/libs/icu-xetex/common/ucase.c b/Build/source/libs/icu-xetex/common/ucase.c
index de3f79a7ed4..c21045a06a4 100644
--- a/Build/source/libs/icu-xetex/common/ucase.c
+++ b/Build/source/libs/icu-xetex/common/ucase.c
@@ -1,7 +1,7 @@
/*
*******************************************************************************
*
-* Copyright (C) 2004-2005, International Business Machines
+* Copyright (C) 2004-2006, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@@ -196,7 +196,9 @@ ucase_openBinary(const uint8_t *bin, int32_t length, UErrorCode *pErrorCode) {
U_CAPI void U_EXPORT2
ucase_close(UCaseProps *csp) {
if(csp!=NULL) {
+#if !UCASE_HARDCODE_DATA
udata_close(csp->mem);
+#endif
uprv_free(csp);
}
}
@@ -204,16 +206,20 @@ ucase_close(UCaseProps *csp) {
/* UCaseProps singleton ----------------------------------------------------- */
static UCaseProps *gCsp=NULL, *gCspDummy=NULL;
+#if !UCASE_HARDCODE_DATA
static UErrorCode gErrorCode=U_ZERO_ERROR;
static int8_t gHaveData=0;
+#endif
static UBool U_CALLCONV ucase_cleanup(void) {
ucase_close(gCsp);
gCsp=NULL;
- gErrorCode=U_ZERO_ERROR;
- gHaveData=0;
ucase_close(gCspDummy);
gCspDummy=NULL;
+#if !UCASE_HARDCODE_DATA
+ gErrorCode=U_ZERO_ERROR;
+ gHaveData=0;
+#endif
return TRUE;
}
@@ -605,7 +611,7 @@ strcmpMax(const UChar *s, int32_t length, const UChar *t, int32_t max) {
U_CAPI UBool U_EXPORT2
ucase_addStringCaseClosure(const UCaseProps *csp, const UChar *s, int32_t length, const USetAdder *sa) {
const UChar *unfold, *p;
- int32_t i, start, limit, result, unfoldRows, unfoldRowWidth, unfoldStringWidth, unfoldCPWidth;
+ int32_t i, start, limit, result, unfoldRows, unfoldRowWidth, unfoldStringWidth;
if(csp->unfold==NULL || s==NULL) {
return FALSE; /* no reverse case folding data, or no string */
@@ -625,7 +631,6 @@ ucase_addStringCaseClosure(const UCaseProps *csp, const UChar *s, int32_t length
unfoldRows=unfold[UCASE_UNFOLD_ROWS];
unfoldRowWidth=unfold[UCASE_UNFOLD_ROW_WIDTH];
unfoldStringWidth=unfold[UCASE_UNFOLD_STRING_WIDTH];
- unfoldCPWidth=unfoldRowWidth-unfoldStringWidth;
unfold+=unfoldRowWidth;
if(length>unfoldStringWidth) {
@@ -1479,3 +1484,116 @@ ucase_toFullFolding(const UCaseProps *csp, UChar32 c,
return (result==c) ? ~result : result;
}
+
+/* case mapping properties API ---------------------------------------------- */
+
+/* get the UCaseProps singleton, or else its dummy, once and for all */
+static const UCaseProps *
+getCaseProps() {
+ /*
+ * This lazy intialization with double-checked locking (without mutex protection for
+ * the initial check) is transiently unsafe under certain circumstances.
+ * Check the readme and use u_init() if necessary.
+ */
+
+ /* the initial check is performed by the GET_CASE_PROPS() macro */
+ const UCaseProps *csp;
+ UErrorCode errorCode=U_ZERO_ERROR;
+
+ csp=ucase_getSingleton(&errorCode);
+ if(U_FAILURE(errorCode)) {
+ errorCode=U_ZERO_ERROR;
+ csp=ucase_getDummy(&errorCode);
+ if(U_FAILURE(errorCode)) {
+ return NULL;
+ }
+ }
+
+ return csp;
+}
+
+/*
+ * In ICU 3.0, most Unicode properties were loaded from uprops.icu.
+ * ICU 3.2 adds ucase.icu for case mapping properties.
+ * ICU 3.4 adds ubidi.icu for bidi/shaping properties and
+ * removes case/bidi/shaping properties from uprops.icu.
+ *
+ * Loading of uprops.icu was never mutex-protected and required u_init()
+ * for thread safety.
+ * In order to maintain performance for all such properties,
+ * ucase.icu and ubidi.icu are loaded lazily, without mutexing.
+ * u_init() will try to load them for thread safety,
+ * but u_init() will not fail if they are missing.
+ *
+ * uchar.c maintains a tri-state flag for (not loaded/loaded/failed to load)
+ * and an error code for load failure.
+ * Instead, here we try to load at most once.
+ * If it works, we use the resulting singleton object.
+ * If it fails, then we get a dummy object, which always works unless
+ * we are seriously out of memory.
+ * After the first try, we have a never-changing pointer to either the
+ * real singleton or the dummy.
+ *
+ * This method is used in Unicode properties APIs (uchar.h) that
+ * do not have a service object and also do not have an error code parameter.
+ * Other API implementations get the singleton themselves
+ * (with mutexing), store it in the service object, and report errors.
+ */
+#define GET_CASE_PROPS() (gCsp!=NULL ? gCsp : getCaseProps())
+
+/* public API (see uchar.h) */
+
+U_CAPI UBool U_EXPORT2
+u_isULowercase(UChar32 c) {
+ return (UBool)(UCASE_LOWER==ucase_getType(GET_CASE_PROPS(), c));
+}
+
+U_CAPI UBool U_EXPORT2
+u_isUUppercase(UChar32 c) {
+ return (UBool)(UCASE_UPPER==ucase_getType(GET_CASE_PROPS(), c));
+}
+
+/* Transforms the Unicode character to its lower case equivalent.*/
+U_CAPI UChar32 U_EXPORT2
+u_tolower(UChar32 c) {
+ return ucase_tolower(GET_CASE_PROPS(), c);
+}
+
+/* Transforms the Unicode character to its upper case equivalent.*/
+U_CAPI UChar32 U_EXPORT2
+u_toupper(UChar32 c) {
+ return ucase_toupper(GET_CASE_PROPS(), c);
+}
+
+/* Transforms the Unicode character to its title case equivalent.*/
+U_CAPI UChar32 U_EXPORT2
+u_totitle(UChar32 c) {
+ return ucase_totitle(GET_CASE_PROPS(), c);
+}
+
+/* return the simple case folding mapping for c */
+U_CAPI UChar32 U_EXPORT2
+u_foldCase(UChar32 c, uint32_t options) {
+ return ucase_fold(GET_CASE_PROPS(), c, options);
+}
+
+U_CFUNC int32_t U_EXPORT2
+ucase_hasBinaryProperty(UChar32 c, UProperty which) {
+ /* case mapping properties */
+ const UCaseProps *csp=GET_CASE_PROPS();
+ if(csp==NULL) {
+ return FALSE;
+ }
+ switch(which) {
+ case UCHAR_LOWERCASE:
+ return (UBool)(UCASE_LOWER==ucase_getType(csp, c));
+ case UCHAR_UPPERCASE:
+ return (UBool)(UCASE_UPPER==ucase_getType(csp, c));
+ case UCHAR_SOFT_DOTTED:
+ return ucase_isSoftDotted(csp, c);
+ case UCHAR_CASE_SENSITIVE:
+ return ucase_isCaseSensitive(csp, c);
+ default:
+ return FALSE;
+ }
+}