// Collator.startswith {{{ static PyObject * icu_Collator_collation_order(icu_Collator *self, PyObject *args, PyObject *kwargs) { PyObject *a_; int32_t asz; int32_t actual_a; UChar *a; wchar_t *aw; UErrorCode status = U_ZERO_ERROR; UCollationElements *iter = NULL; int order = 0, len = -1; if (!PyArg_ParseTuple(args, "U", &a_)) return NULL; asz = (int32_t)PyUnicode_GetSize(a_); a = (UChar*)calloc(asz*4 + 2, sizeof(UChar)); aw = (wchar_t*)calloc(asz*4 + 2, sizeof(wchar_t)); if (a == NULL || aw == NULL ) return PyErr_NoMemory(); actual_a = (int32_t)PyUnicode_AsWideChar((PyUnicodeObject*)a_, aw, asz*4+1); if (actual_a > -1) { u_strFromWCS(a, asz*4 + 1, &actual_a, aw, -1, &status); iter = ucol_openElements(self->collator, a, actual_a, &status); if (iter != NULL && U_SUCCESS(status)) { order = ucol_next(iter, &status); len = ucol_getOffset(iter); ucol_closeElements(iter); iter = NULL; } } free(a); free(aw); return Py_BuildValue("ii", order, len); } // }}}
// Collator.find {{{ static PyObject * icu_Collator_find(icu_Collator *self, PyObject *args, PyObject *kwargs) { PyObject *a_, *b_; int32_t asz, bsz; UChar *a, *b; wchar_t *aw, *bw; UErrorCode status = U_ZERO_ERROR; UStringSearch *search = NULL; int32_t pos = -1, length = -1; if (!PyArg_ParseTuple(args, "UU", &a_, &b_)) return NULL; asz = (int32_t)PyUnicode_GetSize(a_); bsz = (int32_t)PyUnicode_GetSize(b_); a = (UChar*)calloc(asz*4 + 2, sizeof(UChar)); b = (UChar*)calloc(bsz*4 + 2, sizeof(UChar)); aw = (wchar_t*)calloc(asz*4 + 2, sizeof(wchar_t)); bw = (wchar_t*)calloc(bsz*4 + 2, sizeof(wchar_t)); if (a == NULL || b == NULL || aw == NULL || bw == NULL) return PyErr_NoMemory(); PyUnicode_AsWideChar((PyUnicodeObject*)a_, aw, asz*4+1); PyUnicode_AsWideChar((PyUnicodeObject*)b_, bw, bsz*4+1); u_strFromWCS(a, asz*4 + 1, NULL, aw, -1, &status); u_strFromWCS(b, bsz*4 + 1, NULL, bw, -1, &status); if (U_SUCCESS(status)) { search = usearch_openFromCollator(a, -1, b, -1, self->collator, NULL, &status); if (U_SUCCESS(status)) { pos = usearch_first(search, &status); if (pos != USEARCH_DONE) length = usearch_getMatchedLength(search); else pos = -1; } if (search != NULL) usearch_close(search); } free(a); free(b); free(aw); free(bw); return Py_BuildValue("ii", pos, length); } // }}}
/*---------------------------------------------------------------------------------------------- This method uses an ICU function to convert a string from UTF-32 to UTF-16. Assumptions: If sourceLen is -1, it will be computed (by ICU) Exit conditions: <text> Parameters: <text> Return value: The number of characters needed to store the fully-converted result (which may be greater than targetLen) ----------------------------------------------------------------------------------------------*/ int UnicodeConverter::Convert(const wchar_t* source, int sourceLen, UChar* target, int targetLen) { UErrorCode status = U_ZERO_ERROR; int32_t spaceRequiredForData; u_strFromWCS(target, targetLen, &spaceRequiredForData, source, sourceLen, &status); if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) throw std::runtime_error("Unable to convert from UTF-32 to UTF-16"); return spaceRequiredForData; }
// Collator.startswith {{{ static PyObject * icu_Collator_startswith(icu_Collator *self, PyObject *args, PyObject *kwargs) { PyObject *a_, *b_; int32_t asz, bsz; int32_t actual_a, actual_b; UChar *a, *b; wchar_t *aw, *bw; UErrorCode status = U_ZERO_ERROR; int ans = 0; if (!PyArg_ParseTuple(args, "UU", &a_, &b_)) return NULL; asz = (int32_t)PyUnicode_GetSize(a_); bsz = (int32_t)PyUnicode_GetSize(b_); if (asz < bsz) Py_RETURN_FALSE; if (bsz == 0) Py_RETURN_TRUE; a = (UChar*)calloc(asz*4 + 2, sizeof(UChar)); b = (UChar*)calloc(bsz*4 + 2, sizeof(UChar)); aw = (wchar_t*)calloc(asz*4 + 2, sizeof(wchar_t)); bw = (wchar_t*)calloc(bsz*4 + 2, sizeof(wchar_t)); if (a == NULL || b == NULL || aw == NULL || bw == NULL) return PyErr_NoMemory(); actual_a = (int32_t)PyUnicode_AsWideChar((PyUnicodeObject*)a_, aw, asz*4+1); actual_b = (int32_t)PyUnicode_AsWideChar((PyUnicodeObject*)b_, bw, bsz*4+1); if (actual_a > -1 && actual_b > -1) { u_strFromWCS(a, asz*4 + 1, &actual_a, aw, -1, &status); u_strFromWCS(b, bsz*4 + 1, &actual_b, bw, -1, &status); if (U_SUCCESS(status) && ucol_equal(self->collator, a, actual_b, b, actual_b)) ans = 1; } free(a); free(b); free(aw); free(bw); if (ans) Py_RETURN_TRUE; Py_RETURN_FALSE; } // }}}
/** * Main Windows time zone detection function. Returns the Windows * time zone, translated to an ICU time zone, or NULL upon failure. */ U_CFUNC const char* U_EXPORT2 uprv_detectWindowsTimeZone() { UErrorCode status = U_ZERO_ERROR; UResourceBundle* bundle = NULL; char* icuid = NULL; UChar apiStd[MAX_LENGTH_ID]; char apiStdName[MAX_LENGTH_ID]; char regStdName[MAX_LENGTH_ID]; char tmpid[MAX_LENGTH_ID]; int32_t len; int id; int errorCode; char ISOcode[3]; /* 2 letter iso code */ LONG result; TZI tziKey; TZI tziReg; TIME_ZONE_INFORMATION apiTZI; /* Obtain TIME_ZONE_INFORMATION from the API, and then convert it to TZI. We could also interrogate the registry directly; we do this below if needed. */ uprv_memset(&apiTZI, 0, sizeof(apiTZI)); uprv_memset(&tziKey, 0, sizeof(tziKey)); uprv_memset(&tziReg, 0, sizeof(tziReg)); GetTimeZoneInformation(&apiTZI); tziKey.bias = apiTZI.Bias; uprv_memcpy((char *)&tziKey.standardDate, (char*)&apiTZI.StandardDate, sizeof(apiTZI.StandardDate)); uprv_memcpy((char *)&tziKey.daylightDate, (char*)&apiTZI.DaylightDate, sizeof(apiTZI.DaylightDate)); /* Convert the wchar_t* standard name to char* */ uprv_memset(apiStdName, 0, sizeof(apiStdName)); u_strFromWCS(apiStd, MAX_LENGTH_ID, NULL, apiTZI.StandardName, -1, &status); u_austrncpy(apiStdName, apiStd, sizeof(apiStdName) - 1); tmpid[0] = 0; id = GetUserGeoID(GEOCLASS_NATION); errorCode = GetGeoInfoA(id,GEO_ISO2,ISOcode,3,0); bundle = ures_openDirect(NULL, "windowsZones", &status); ures_getByKey(bundle, "mapTimezones", bundle, &status); /* Note: We get the winid not from static tables but from resource bundle. */ while (U_SUCCESS(status) && ures_hasNext(bundle)) { UBool idFound = FALSE; const char* winid; UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status); if (U_FAILURE(status)) { break; } winid = ures_getKey(winTZ); result = getTZI(winid, &tziReg); if (result == ERROR_SUCCESS) { /* Windows alters the DaylightBias in some situations. Using the bias and the rules suffices, so overwrite these unreliable fields. */ tziKey.standardBias = tziReg.standardBias; tziKey.daylightBias = tziReg.daylightBias; if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) { const UChar* icuTZ = NULL; if (errorCode != 0) { icuTZ = ures_getStringByKey(winTZ, ISOcode, &len, &status); } if (errorCode==0 || icuTZ==NULL) { /* fallback to default "001" and reset status */ status = U_ZERO_ERROR; icuTZ = ures_getStringByKey(winTZ, "001", &len, &status); } if (U_SUCCESS(status)) { /* Get the standard name from the registry key to compare with the one from Windows API call. */ uprv_memset(regStdName, 0, sizeof(regStdName)); result = getSTDName(winid, regStdName, sizeof(regStdName)); if (result == ERROR_SUCCESS) { if (uprv_strcmp(apiStdName, regStdName) == 0) { idFound = TRUE; } } /* tmpid buffer holds the ICU timezone ID corresponding to the timezone ID from Windows. * If none is found, tmpid buffer will contain a fallback ID (i.e. the time zone ID matching * the current time zone information) */ if (idFound || tmpid[0] == 0) { /* if icuTZ has more than one city, take only the first (i.e. terminate icuTZ at first space) */ int index=0; while (! (*icuTZ == '\0' || *icuTZ ==' ')) { tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'char' is ASCII compatible on windows */ } tmpid[index]='\0'; } } } } ures_close(winTZ); if (idFound) { break; } } /* * Copy the timezone ID to icuid to be returned. */ if (tmpid[0] != 0) { len = uprv_strlen(tmpid); icuid = (char*)uprv_calloc(len + 1, sizeof(char)); if (icuid != NULL) { uprv_strcpy(icuid, tmpid); } } ures_close(bundle); return icuid; }