diff --git a/icu4c/source/i18n/name2uni.cpp b/icu4c/source/i18n/name2uni.cpp index 515ae9b1cd..feb759819f 100644 --- a/icu4c/source/i18n/name2uni.cpp +++ b/icu4c/source/i18n/name2uni.cpp @@ -135,10 +135,33 @@ void NameUnicodeTransliterator::handleTransliterate(Replaceable& text, UTransPos buf[ibuf] = 0; // Add terminating zero UErrorCode status = U_ZERO_ERROR; - // Convert UChar to char - u_UCharsToChars(buf, cbuf, ibuf+1); + UChar32 ch = 0xFFFF; - UChar32 ch = u_charFromName(U_UNICODE_CHAR_NAME, cbuf, &status); + // Try in this order: U+XXXX (and bail out if we cannot + // decode it), or Unicode name then Unicode 1.0 name. + + if (ibuf >= 6 && buf[0] == 0x0055 && buf[1] == 0x002B) { + // We've found a U+ prefix, compute the value. + ch = 0; + int32_t jbuf = 2; + for (; jbuf < ibuf; ++jbuf) { + if (buf[jbuf] >= 0x0030 && buf[jbuf] <= 0x0039) { + ch = (ch << 4) + buf[jbuf] - 0x0030; + } else if (buf[jbuf] >= 0x0041 && buf[jbuf] <= 0x0045) { + ch = (ch << 4) + buf[jbuf] - 0x0041 + 10; + } else { + ch = 0xFFFF; + break; + } + } + } else { + u_UCharsToChars(buf, cbuf, ibuf+1); + ch = u_charFromName(U_UNICODE_CHAR_NAME, cbuf, &status); + if (ch == (UChar32) 0xFFFF || U_FAILURE(status)) { + status = U_ZERO_ERROR; + ch = u_charFromName(U_UNICODE_10_CHAR_NAME, cbuf, &status); + } + } if (ch != (UChar32) 0xFFFF && U_SUCCESS(status)) { // Lookup succeeded str.truncate(0); diff --git a/icu4c/source/i18n/uni2name.cpp b/icu4c/source/i18n/uni2name.cpp index fa665e7c4a..e8e83094e4 100644 --- a/icu4c/source/i18n/uni2name.cpp +++ b/icu4c/source/i18n/uni2name.cpp @@ -80,6 +80,7 @@ void UnicodeNameTransliterator::handleTransliterate(Replaceable& text, UTransPos UBool /*isIncremental*/) const { // As of Unicode 3.0.0, the longest name is 83 characters long. // Adjust this buffer size as needed. + char buf[128]; int32_t cursor = offsets.start; @@ -90,12 +91,15 @@ void UnicodeNameTransliterator::handleTransliterate(Replaceable& text, UTransPos UTextOffset len; while (cursor < limit) { - status = U_ZERO_ERROR; UChar32 c = text.char32At(cursor); - if ((len=u_charName(c, U_UNICODE_CHAR_NAME, buf, sizeof(buf), &status)) <= 0 || U_FAILURE(status)) { + status = U_ZERO_ERROR; + if ((len = u_charName(c, U_UNICODE_CHAR_NAME, buf, sizeof(buf), &status)) <= 0 || U_FAILURE(status)) { + status = U_ZERO_ERROR; + if ((len = u_charName(c, U_UNICODE_10_CHAR_NAME, buf, sizeof(buf), &status)) <= 0 || U_FAILURE(status)) { sprintf(buf, "U+%04lX", c); len = uprv_strlen(buf); - } + } + } str.truncate(1); str.append(UnicodeString(buf, len, "")).append(closeDelimiter);