+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
*
*******************************************************************************
* file name: loclikely.cpp
-* encoding: US-ASCII
+* encoding: UTF-8
* tab size: 8 (not used)
* indentation:4
*
* that then do not depend on resource bundle code and likely-subtags data.
*/
+#include "unicode/bytestream.h"
#include "unicode/utypes.h"
#include "unicode/locid.h"
#include "unicode/putil.h"
+#include "unicode/uchar.h"
#include "unicode/uloc.h"
#include "unicode/ures.h"
#include "unicode/uscript.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "ulocimp.h"
#include "ustr_imp.h"
+/**
+ * These are the canonical strings for unknown languages, scripts and regions.
+ **/
+static const char* const unknownLanguage = "und";
+static const char* const unknownScript = "Zzzz";
+static const char* const unknownRegion = "ZZ";
+
/**
* This function looks for the localeID in the likelySubtags resource.
*
int32_t resLen = 0;
const UChar* s = NULL;
UErrorCode tmpErr = U_ZERO_ERROR;
- UResourceBundle* subtags = ures_openDirect(NULL, "likelySubtags", &tmpErr);
+ icu::LocalUResourceBundlePointer subtags(ures_openDirect(NULL, "likelySubtags", &tmpErr));
if (U_SUCCESS(tmpErr)) {
- s = ures_getStringByKey(subtags, localeID, &resLen, &tmpErr);
+ icu::CharString und;
+ if (localeID != NULL) {
+ if (*localeID == '\0') {
+ localeID = unknownLanguage;
+ } else if (*localeID == '_') {
+ und.append(unknownLanguage, *err);
+ und.append(localeID, *err);
+ if (U_FAILURE(*err)) {
+ return NULL;
+ }
+ localeID = und.data();
+ }
+ }
+ s = ures_getStringByKey(subtags.getAlias(), localeID, &resLen, &tmpErr);
if (U_FAILURE(tmpErr)) {
/*
u_UCharsToChars(s, buffer, resLen + 1);
result = buffer;
}
-
- ures_close(subtags);
} else {
*err = tmpErr;
}
*bufferLength += tagLength;
}
-/**
- * These are the canonical strings for unknown languages, scripts and regions.
- **/
-static const char* const unknownLanguage = "und";
-static const char* const unknownScript = "Zzzz";
-static const char* const unknownRegion = "ZZ";
-
/**
* Create a tag string from the supplied parameters. The lang, script and region
* parameters may be NULL pointers. If they are, their corresponding length parameters
* @param trailing Any trailing data to append to the new tag.
* @param trailingLength The length of the trailing data.
* @param alternateTags A string containing any alternate tags.
- * @param tag The output buffer.
- * @param tagCapacity The capacity of the output buffer.
+ * @param sink The output sink receiving the tag string.
* @param err A pointer to a UErrorCode for error reporting.
- * @return The length of the tag string, which may be greater than tagCapacity, or -1 on error.
**/
-static int32_t U_CALLCONV
+static void U_CALLCONV
createTagStringWithAlternates(
const char* lang,
int32_t langLength,
const char* trailing,
int32_t trailingLength,
const char* alternateTags,
- char* tag,
- int32_t tagCapacity,
+ icu::ByteSink& sink,
UErrorCode* err) {
if (U_FAILURE(*err)) {
goto error;
}
- else if (tag == NULL ||
- tagCapacity <= 0 ||
- langLength >= ULOC_LANG_CAPACITY ||
+ else if (langLength >= ULOC_LANG_CAPACITY ||
scriptLength >= ULOC_SCRIPT_CAPACITY ||
regionLength >= ULOC_COUNTRY_CAPACITY) {
goto error;
**/
char tagBuffer[ULOC_FULLNAME_CAPACITY];
int32_t tagLength = 0;
- int32_t capacityRemaining = tagCapacity;
UBool regionAppended = FALSE;
if (langLength > 0) {
}
}
- {
- const int32_t toCopy =
- tagLength >= tagCapacity ? tagCapacity : tagLength;
-
- /**
- * Copy the partial tag from our internal buffer to the supplied
- * target.
- **/
- uprv_memcpy(
- tag,
- tagBuffer,
- toCopy);
-
- capacityRemaining -= toCopy;
- }
+ /**
+ * Copy the partial tag from our internal buffer to the supplied
+ * target.
+ **/
+ sink.Append(tagBuffer, tagLength);
if (trailingLength > 0) {
- if (*trailing != '@' && capacityRemaining > 0) {
- tag[tagLength++] = '_';
- --capacityRemaining;
- if (capacityRemaining > 0 && !regionAppended) {
+ if (*trailing != '@') {
+ sink.Append("_", 1);
+ if (!regionAppended) {
/* extra separator is required */
- tag[tagLength++] = '_';
- --capacityRemaining;
+ sink.Append("_", 1);
}
}
- if (capacityRemaining > 0) {
- /*
- * Copy the trailing data into the supplied buffer. Use uprv_memmove, since we
- * don't know if the user-supplied buffers overlap.
- */
- const int32_t toCopy =
- trailingLength >= capacityRemaining ? capacityRemaining : trailingLength;
-
- uprv_memmove(
- &tag[tagLength],
- trailing,
- toCopy);
- }
+ /*
+ * Copy the trailing data into the supplied buffer.
+ */
+ sink.Append(trailing, trailingLength);
}
- tagLength += trailingLength;
-
- return u_terminateChars(
- tag,
- tagCapacity,
- tagLength,
- err);
+ return;
}
error:
U_SUCCESS(*err)) {
*err = U_ILLEGAL_ARGUMENT_ERROR;
}
-
- return -1;
}
/**
* @param regionLength The length of the region tag.
* @param trailing Any trailing data to append to the new tag.
* @param trailingLength The length of the trailing data.
- * @param tag The output buffer.
- * @param tagCapacity The capacity of the output buffer.
+ * @param sink The output sink receiving the tag string.
* @param err A pointer to a UErrorCode for error reporting.
- * @return The length of the tag string, which may be greater than tagCapacity.
**/
-static int32_t U_CALLCONV
+static void U_CALLCONV
createTagString(
const char* lang,
int32_t langLength,
int32_t regionLength,
const char* trailing,
int32_t trailingLength,
- char* tag,
- int32_t tagCapacity,
+ icu::ByteSink& sink,
UErrorCode* err)
{
- return createTagStringWithAlternates(
+ createTagStringWithAlternates(
lang,
langLength,
script,
trailing,
trailingLength,
NULL,
- tag,
- tagCapacity,
+ sink,
err);
}
unknownLanguage);
*langLength = (int32_t)uprv_strlen(lang);
}
- else if (_isIDSeparator(*position)) {
+ if (_isIDSeparator(*position)) {
++position;
}
goto exit;
}
-static int32_t U_CALLCONV
+static UBool U_CALLCONV
createLikelySubtagsString(
const char* lang,
int32_t langLength,
int32_t regionLength,
const char* variants,
int32_t variantsLength,
- char* tag,
- int32_t tagCapacity,
- UErrorCode* err)
-{
+ icu::ByteSink& sink,
+ UErrorCode* err) {
/**
* ULOC_FULLNAME_CAPACITY will provide enough capacity
* that we can build a string that contains the language,
* script and region code without worrying about overrunning
* the user-supplied buffer.
**/
- char tagBuffer[ULOC_FULLNAME_CAPACITY];
char likelySubtagsBuffer[ULOC_FULLNAME_CAPACITY];
if(U_FAILURE(*err)) {
const char* likelySubtags = NULL;
- createTagString(
- lang,
- langLength,
- script,
- scriptLength,
- region,
- regionLength,
- NULL,
- 0,
- tagBuffer,
- sizeof(tagBuffer),
- err);
+ icu::CharString tagBuffer;
+ {
+ icu::CharStringByteSink sink(&tagBuffer);
+ createTagString(
+ lang,
+ langLength,
+ script,
+ scriptLength,
+ region,
+ regionLength,
+ NULL,
+ 0,
+ sink,
+ err);
+ }
if(U_FAILURE(*err)) {
goto error;
}
likelySubtags =
findLikelySubtags(
- tagBuffer,
+ tagBuffer.data(),
likelySubtagsBuffer,
sizeof(likelySubtagsBuffer),
err);
/* Always use the language tag from the
maximal string, since it may be more
specific than the one provided. */
- return createTagStringWithAlternates(
+ createTagStringWithAlternates(
NULL,
0,
NULL,
variants,
variantsLength,
likelySubtags,
- tag,
- tagCapacity,
+ sink,
err);
+ return TRUE;
}
}
const char* likelySubtags = NULL;
- createTagString(
- lang,
- langLength,
- script,
- scriptLength,
- NULL,
- 0,
- NULL,
- 0,
- tagBuffer,
- sizeof(tagBuffer),
- err);
+ icu::CharString tagBuffer;
+ {
+ icu::CharStringByteSink sink(&tagBuffer);
+ createTagString(
+ lang,
+ langLength,
+ script,
+ scriptLength,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ sink,
+ err);
+ }
if(U_FAILURE(*err)) {
goto error;
}
likelySubtags =
findLikelySubtags(
- tagBuffer,
+ tagBuffer.data(),
likelySubtagsBuffer,
sizeof(likelySubtagsBuffer),
err);
/* Always use the language tag from the
maximal string, since it may be more
specific than the one provided. */
- return createTagStringWithAlternates(
+ createTagStringWithAlternates(
NULL,
0,
NULL,
variants,
variantsLength,
likelySubtags,
- tag,
- tagCapacity,
+ sink,
err);
+ return TRUE;
}
}
const char* likelySubtags = NULL;
- createTagString(
- lang,
- langLength,
- NULL,
- 0,
- region,
- regionLength,
- NULL,
- 0,
- tagBuffer,
- sizeof(tagBuffer),
- err);
+ icu::CharString tagBuffer;
+ {
+ icu::CharStringByteSink sink(&tagBuffer);
+ createTagString(
+ lang,
+ langLength,
+ NULL,
+ 0,
+ region,
+ regionLength,
+ NULL,
+ 0,
+ sink,
+ err);
+ }
if(U_FAILURE(*err)) {
goto error;
}
likelySubtags =
findLikelySubtags(
- tagBuffer,
+ tagBuffer.data(),
likelySubtagsBuffer,
sizeof(likelySubtagsBuffer),
err);
/* Always use the language tag from the
maximal string, since it may be more
specific than the one provided. */
- return createTagStringWithAlternates(
+ createTagStringWithAlternates(
NULL,
0,
script,
variants,
variantsLength,
likelySubtags,
- tag,
- tagCapacity,
+ sink,
err);
+ return TRUE;
}
}
{
const char* likelySubtags = NULL;
- createTagString(
- lang,
- langLength,
- NULL,
- 0,
- NULL,
- 0,
- NULL,
- 0,
- tagBuffer,
- sizeof(tagBuffer),
- err);
+ icu::CharString tagBuffer;
+ {
+ icu::CharStringByteSink sink(&tagBuffer);
+ createTagString(
+ lang,
+ langLength,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ sink,
+ err);
+ }
if(U_FAILURE(*err)) {
goto error;
}
likelySubtags =
findLikelySubtags(
- tagBuffer,
+ tagBuffer.data(),
likelySubtagsBuffer,
sizeof(likelySubtagsBuffer),
err);
/* Always use the language tag from the
maximal string, since it may be more
specific than the one provided. */
- return createTagStringWithAlternates(
+ createTagStringWithAlternates(
NULL,
0,
script,
variants,
variantsLength,
likelySubtags,
- tag,
- tagCapacity,
+ sink,
err);
+ return TRUE;
}
}
- return u_terminateChars(
- tag,
- tagCapacity,
- 0,
- err);
+ return FALSE;
error:
*err = U_ILLEGAL_ARGUMENT_ERROR;
}
- return -1;
+ return FALSE;
}
#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) \
} \
}
-static int32_t
-_uloc_addLikelySubtags(const char* localeID,
- char* maximizedLocaleID,
- int32_t maximizedLocaleIDCapacity,
- UErrorCode* err)
-{
+static void
+_uloc_addLikelySubtags(const char* localeID,
+ icu::ByteSink& sink,
+ UErrorCode* err) {
char lang[ULOC_LANG_CAPACITY];
int32_t langLength = sizeof(lang);
char script[ULOC_SCRIPT_CAPACITY];
const char* trailing = "";
int32_t trailingLength = 0;
int32_t trailingIndex = 0;
- int32_t resultLength = 0;
+ UBool success = FALSE;
if(U_FAILURE(*err)) {
goto error;
}
- else if (localeID == NULL ||
- maximizedLocaleID == NULL ||
- maximizedLocaleIDCapacity <= 0) {
+ if (localeID == NULL) {
goto error;
}
CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
- resultLength =
+ success =
createLikelySubtagsString(
lang,
langLength,
regionLength,
trailing,
trailingLength,
- maximizedLocaleID,
- maximizedLocaleIDCapacity,
+ sink,
err);
- if (resultLength == 0) {
+ if (!success) {
const int32_t localIDLength = (int32_t)uprv_strlen(localeID);
/*
* If we get here, we need to return localeID.
*/
- uprv_memcpy(
- maximizedLocaleID,
- localeID,
- localIDLength <= maximizedLocaleIDCapacity ?
- localIDLength : maximizedLocaleIDCapacity);
-
- resultLength =
- u_terminateChars(
- maximizedLocaleID,
- maximizedLocaleIDCapacity,
- localIDLength,
- err);
+ sink.Append(localeID, localIDLength);
}
- return resultLength;
+ return;
error:
if (!U_FAILURE(*err)) {
*err = U_ILLEGAL_ARGUMENT_ERROR;
}
-
- return -1;
}
-static int32_t
-_uloc_minimizeSubtags(const char* localeID,
- char* minimizedLocaleID,
- int32_t minimizedLocaleIDCapacity,
- UErrorCode* err)
-{
- /**
- * ULOC_FULLNAME_CAPACITY will provide enough capacity
- * that we can build a string that contains the language,
- * script and region code without worrying about overrunning
- * the user-supplied buffer.
- **/
- char maximizedTagBuffer[ULOC_FULLNAME_CAPACITY];
- int32_t maximizedTagBufferLength = sizeof(maximizedTagBuffer);
+static void
+_uloc_minimizeSubtags(const char* localeID,
+ icu::ByteSink& sink,
+ UErrorCode* err) {
+ icu::CharString maximizedTagBuffer;
char lang[ULOC_LANG_CAPACITY];
int32_t langLength = sizeof(lang);
if(U_FAILURE(*err)) {
goto error;
}
- else if (localeID == NULL ||
- minimizedLocaleID == NULL ||
- minimizedLocaleIDCapacity <= 0) {
+ else if (localeID == NULL) {
goto error;
}
CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
- createTagString(
- lang,
- langLength,
- script,
- scriptLength,
- region,
- regionLength,
- NULL,
- 0,
- maximizedTagBuffer,
- maximizedTagBufferLength,
- err);
- if(U_FAILURE(*err)) {
- goto error;
- }
+ {
+ icu::CharString base;
+ {
+ icu::CharStringByteSink sink(&base);
+ createTagString(
+ lang,
+ langLength,
+ script,
+ scriptLength,
+ region,
+ regionLength,
+ NULL,
+ 0,
+ sink,
+ err);
+ }
- /**
- * First, we need to first get the maximization
- * from AddLikelySubtags.
- **/
- maximizedTagBufferLength =
- uloc_addLikelySubtags(
- maximizedTagBuffer,
- maximizedTagBuffer,
- maximizedTagBufferLength,
- err);
+ /**
+ * First, we need to first get the maximization
+ * from AddLikelySubtags.
+ **/
+ {
+ icu::CharStringByteSink sink(&maximizedTagBuffer);
+ ulocimp_addLikelySubtags(base.data(), sink, err);
+ }
+ }
if(U_FAILURE(*err)) {
goto error;
* Start first with just the language.
**/
{
- char tagBuffer[ULOC_FULLNAME_CAPACITY];
-
- const int32_t tagBufferLength =
+ icu::CharString tagBuffer;
+ {
+ icu::CharStringByteSink sink(&tagBuffer);
createLikelySubtagsString(
lang,
langLength,
0,
NULL,
0,
- tagBuffer,
- sizeof(tagBuffer),
+ sink,
err);
+ }
if(U_FAILURE(*err)) {
goto error;
}
else if (uprv_strnicmp(
- maximizedTagBuffer,
- tagBuffer,
- tagBufferLength) == 0) {
+ maximizedTagBuffer.data(),
+ tagBuffer.data(),
+ tagBuffer.length()) == 0) {
- return createTagString(
+ createTagString(
lang,
langLength,
NULL,
0,
trailing,
trailingLength,
- minimizedLocaleID,
- minimizedLocaleIDCapacity,
+ sink,
err);
+ return;
}
}
**/
if (regionLength > 0) {
- char tagBuffer[ULOC_FULLNAME_CAPACITY];
-
- const int32_t tagBufferLength =
+ icu::CharString tagBuffer;
+ {
+ icu::CharStringByteSink sink(&tagBuffer);
createLikelySubtagsString(
lang,
langLength,
regionLength,
NULL,
0,
- tagBuffer,
- sizeof(tagBuffer),
+ sink,
err);
+ }
if(U_FAILURE(*err)) {
goto error;
}
else if (uprv_strnicmp(
- maximizedTagBuffer,
- tagBuffer,
- tagBufferLength) == 0) {
+ maximizedTagBuffer.data(),
+ tagBuffer.data(),
+ tagBuffer.length()) == 0) {
- return createTagString(
+ createTagString(
lang,
langLength,
NULL,
regionLength,
trailing,
trailingLength,
- minimizedLocaleID,
- minimizedLocaleIDCapacity,
+ sink,
err);
+ return;
}
}
* maximal version that we already have.
**/
if (scriptLength > 0 && regionLength > 0) {
- char tagBuffer[ULOC_FULLNAME_CAPACITY];
-
- const int32_t tagBufferLength =
+ icu::CharString tagBuffer;
+ {
+ icu::CharStringByteSink sink(&tagBuffer);
createLikelySubtagsString(
lang,
langLength,
0,
NULL,
0,
- tagBuffer,
- sizeof(tagBuffer),
+ sink,
err);
+ }
if(U_FAILURE(*err)) {
goto error;
}
else if (uprv_strnicmp(
- maximizedTagBuffer,
- tagBuffer,
- tagBufferLength) == 0) {
+ maximizedTagBuffer.data(),
+ tagBuffer.data(),
+ tagBuffer.length()) == 0) {
- return createTagString(
+ createTagString(
lang,
langLength,
script,
0,
trailing,
trailingLength,
- minimizedLocaleID,
- minimizedLocaleIDCapacity,
+ sink,
err);
+ return;
}
}
* If we got here, return the locale ID parameter.
**/
const int32_t localeIDLength = (int32_t)uprv_strlen(localeID);
-
- uprv_memcpy(
- minimizedLocaleID,
- localeID,
- localeIDLength <= minimizedLocaleIDCapacity ?
- localeIDLength : minimizedLocaleIDCapacity);
-
- return u_terminateChars(
- minimizedLocaleID,
- minimizedLocaleIDCapacity,
- localeIDLength,
- err);
+ sink.Append(localeID, localeIDLength);
+ return;
}
error:
if (!U_FAILURE(*err)) {
*err = U_ILLEGAL_ARGUMENT_ERROR;
}
-
- return -1;
-
-
}
static UBool
}
U_CAPI int32_t U_EXPORT2
-uloc_addLikelySubtags(const char* localeID,
- char* maximizedLocaleID,
- int32_t maximizedLocaleIDCapacity,
- UErrorCode* err)
-{
+uloc_addLikelySubtags(const char* localeID,
+ char* maximizedLocaleID,
+ int32_t maximizedLocaleIDCapacity,
+ UErrorCode* status) {
+ if (U_FAILURE(*status)) {
+ return 0;
+ }
+
+ icu::CheckedArrayByteSink sink(
+ maximizedLocaleID, maximizedLocaleIDCapacity);
+
+ ulocimp_addLikelySubtags(localeID, sink, status);
+ int32_t reslen = sink.NumberOfBytesAppended();
+
+ if (U_FAILURE(*status)) {
+ return sink.Overflowed() ? reslen : -1;
+ }
+
+ if (sink.Overflowed()) {
+ *status = U_BUFFER_OVERFLOW_ERROR;
+ } else {
+ u_terminateChars(
+ maximizedLocaleID, maximizedLocaleIDCapacity, reslen, status);
+ }
+
+ return reslen;
+}
+
+U_CAPI void U_EXPORT2
+ulocimp_addLikelySubtags(const char* localeID,
+ icu::ByteSink& sink,
+ UErrorCode* status) {
char localeBuffer[ULOC_FULLNAME_CAPACITY];
- if (!do_canonicalize(
- localeID,
- localeBuffer,
- sizeof(localeBuffer),
- err)) {
- return -1;
+ if (do_canonicalize(localeID, localeBuffer, sizeof localeBuffer, status)) {
+ _uloc_addLikelySubtags(localeBuffer, sink, status);
}
- else {
- return _uloc_addLikelySubtags(
- localeBuffer,
- maximizedLocaleID,
- maximizedLocaleIDCapacity,
- err);
- }
}
U_CAPI int32_t U_EXPORT2
-uloc_minimizeSubtags(const char* localeID,
- char* minimizedLocaleID,
- int32_t minimizedLocaleIDCapacity,
- UErrorCode* err)
-{
+uloc_minimizeSubtags(const char* localeID,
+ char* minimizedLocaleID,
+ int32_t minimizedLocaleIDCapacity,
+ UErrorCode* status) {
+ if (U_FAILURE(*status)) {
+ return 0;
+ }
+
+ icu::CheckedArrayByteSink sink(
+ minimizedLocaleID, minimizedLocaleIDCapacity);
+
+ ulocimp_minimizeSubtags(localeID, sink, status);
+ int32_t reslen = sink.NumberOfBytesAppended();
+
+ if (U_FAILURE(*status)) {
+ return sink.Overflowed() ? reslen : -1;
+ }
+
+ if (sink.Overflowed()) {
+ *status = U_BUFFER_OVERFLOW_ERROR;
+ } else {
+ u_terminateChars(
+ minimizedLocaleID, minimizedLocaleIDCapacity, reslen, status);
+ }
+
+ return reslen;
+}
+
+U_CAPI void U_EXPORT2
+ulocimp_minimizeSubtags(const char* localeID,
+ icu::ByteSink& sink,
+ UErrorCode* status) {
char localeBuffer[ULOC_FULLNAME_CAPACITY];
- if (!do_canonicalize(
- localeID,
- localeBuffer,
- sizeof(localeBuffer),
- err)) {
- return -1;
+ if (do_canonicalize(localeID, localeBuffer, sizeof localeBuffer, status)) {
+ _uloc_minimizeSubtags(localeBuffer, sink, status);
}
- else {
- return _uloc_minimizeSubtags(
- localeBuffer,
- minimizedLocaleID,
- minimizedLocaleIDCapacity,
- err);
- }
}
// Pairs of (language subtag, + or -) for finding out fast if common languages
// are LTR (minus) or RTL (plus).
-static const char* LANG_DIR_STRING =
+static const char LANG_DIR_STRING[] =
"root-en-es-pt-zh-ja-ko-de-fr-it-ar+he+fa+ru-nl-pl-th-tr-";
-// Implemented here because this calls uloc_addLikelySubtags().
+// Implemented here because this calls ulocimp_addLikelySubtags().
U_CAPI UBool U_EXPORT2
uloc_isRightToLeft(const char *locale) {
UErrorCode errorCode = U_ZERO_ERROR;
errorCode = U_ZERO_ERROR;
char lang[8];
int32_t langLength = uloc_getLanguage(locale, lang, UPRV_LENGTHOF(lang), &errorCode);
- if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING ||
- langLength == 0) {
+ if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) {
return FALSE;
}
- const char* langPtr = uprv_strstr(LANG_DIR_STRING, lang);
- if (langPtr != NULL) {
- switch (langPtr[langLength]) {
- case '-': return FALSE;
- case '+': return TRUE;
- default: break; // partial match of a longer code
+ if (langLength > 0) {
+ const char* langPtr = uprv_strstr(LANG_DIR_STRING, lang);
+ if (langPtr != NULL) {
+ switch (langPtr[langLength]) {
+ case '-': return FALSE;
+ case '+': return TRUE;
+ default: break; // partial match of a longer code
+ }
}
}
// Otherwise, find the likely script.
errorCode = U_ZERO_ERROR;
- char likely[ULOC_FULLNAME_CAPACITY];
- (void)uloc_addLikelySubtags(locale, likely, UPRV_LENGTHOF(likely), &errorCode);
+ icu::CharString likely;
+ {
+ icu::CharStringByteSink sink(&likely);
+ ulocimp_addLikelySubtags(locale, sink, &errorCode);
+ }
if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) {
return FALSE;
}
- scriptLength = uloc_getScript(likely, script, UPRV_LENGTHOF(script), &errorCode);
+ scriptLength = uloc_getScript(likely.data(), script, UPRV_LENGTHOF(script), &errorCode);
if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING ||
scriptLength == 0) {
return FALSE;
}
}
+ if (uprv_strcmp(script,"Aran")==0) {
+ uprv_strcpy(script,"Arab"); // The properties functions do not understand Aran
+ }
UScriptCode scriptCode = (UScriptCode)u_getPropertyValueEnum(UCHAR_SCRIPT, script);
return uscript_isRightToLeft(scriptCode);
}
return uloc_isRightToLeft(getBaseName());
}
+U_NAMESPACE_END
+
// The following must at least allow for rg key value (6) plus terminator (1).
#define ULOC_RG_BUFLEN 8
rgLen = 0;
} else if (rgLen == 0 && inferRegion) {
// no unicode_region_subtag but inferRegion TRUE, try likely subtags
- char locBuf[ULOC_FULLNAME_CAPACITY];
rgStatus = U_ZERO_ERROR;
- (void)uloc_addLikelySubtags(localeID, locBuf, ULOC_FULLNAME_CAPACITY, &rgStatus);
+ icu::CharString locBuf;
+ {
+ icu::CharStringByteSink sink(&locBuf);
+ ulocimp_addLikelySubtags(localeID, sink, &rgStatus);
+ }
if (U_SUCCESS(rgStatus)) {
- rgLen = uloc_getCountry(locBuf, rgBuf, ULOC_RG_BUFLEN, status);
+ rgLen = uloc_getCountry(locBuf.data(), rgBuf, ULOC_RG_BUFLEN, status);
if (U_FAILURE(*status)) {
rgLen = 0;
}
return u_terminateChars(region, regionCapacity, rgLen, status);
}
-U_NAMESPACE_END