16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org**********************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Copyright (C) 2001-2011, International Business Machines
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Corporation and others.  All Rights Reserved.
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org**********************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Date        Name        Description
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   06/06/01    aliu        Creation.
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org**********************************************************************
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_TRANSLITERATION
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/unifilt.h"
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uchar.h"
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf16.h"
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uni2name.h"
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h"
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uprops.h"
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeNameTransliterator)
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar OPEN_DELIM[] = {92,78,123,0}; // "\N{"
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar CLOSE_DELIM  = 125; // "}"
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define OPEN_DELIM_LEN 3
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Constructs a transliterator.
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeNameTransliterator::UnicodeNameTransliterator(UnicodeFilter* adoptedFilter) :
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(UNICODE_STRING("Any-Name", 8), adoptedFilter) {
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Destructor.
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeNameTransliterator::~UnicodeNameTransliterator() {}
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copy constructor.
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeNameTransliterator::UnicodeNameTransliterator(const UnicodeNameTransliterator& o) :
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(o) {}
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Assignment operator.
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*UnicodeNameTransliterator& UnicodeNameTransliterator::operator=(
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             const UnicodeNameTransliterator& o) {
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator::operator=(o);
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *this;
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}*/
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transliterator API.
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator* UnicodeNameTransliterator::clone(void) const {
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return new UnicodeNameTransliterator(*this);
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Implements {@link Transliterator#handleTransliterate}.
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Ignore isIncremental since we don't need the context, and
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * we work on codepoints.
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid UnicodeNameTransliterator::handleTransliterate(Replaceable& text, UTransPosition& offsets,
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                                    UBool /*isIncremental*/) const {
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // The failure mode, here and below, is to behave like Any-Null,
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // if either there is no name data (max len == 0) or there is no
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // memory (malloc() => NULL).
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t maxLen = uprv_getMaxCharNameLength();
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (maxLen == 0) {
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offsets.start = offsets.limit;
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Accomodate the longest possible name plus padding
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    char* buf = (char*) uprv_malloc(maxLen);
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (buf == NULL) {
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offsets.start = offsets.limit;
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t cursor = offsets.start;
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t limit = offsets.limit;
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString str(FALSE, OPEN_DELIM, OPEN_DELIM_LEN);
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode status;
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t len;
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (cursor < limit) {
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar32 c = text.char32At(cursor);
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t clen = U16_LENGTH(c);
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_ZERO_ERROR;
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if ((len = u_charName(c, U_EXTENDED_CHAR_NAME, buf, maxLen, &status)) >0 && !U_FAILURE(status)) {
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            str.truncate(OPEN_DELIM_LEN);
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            str.append(UnicodeString(buf, len, US_INV)).append(CLOSE_DELIM);
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            text.handleReplaceBetween(cursor, cursor+clen, str);
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            len += OPEN_DELIM_LEN + 1; // adjust for delimiters
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            cursor += len; // advance cursor and adjust for new text
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            limit += len-clen; // change in length
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            cursor += clen;
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsets.contextLimit += limit - offsets.limit;
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsets.limit = limit;
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsets.start = cursor;
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uprv_free(buf);
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_TRANSLITERATION */
122