1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius*   Copyright (C) 2001-2011, International Business Machines
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Date        Name        Description
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   06/06/01    aliu        Creation.
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_TRANSLITERATION
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/unifilt.h"
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h"
1783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "unicode/utf16.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uni2name.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uprops.h"
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeNameTransliterator)
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar OPEN_DELIM[] = {92,78,123,0}; // "\N{"
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar CLOSE_DELIM  = 125; // "}"
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define OPEN_DELIM_LEN 3
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Constructs a transliterator.
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeNameTransliterator::UnicodeNameTransliterator(UnicodeFilter* adoptedFilter) :
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Transliterator(UNICODE_STRING("Any-Name", 8), adoptedFilter) {
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Destructor.
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeNameTransliterator::~UnicodeNameTransliterator() {}
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Copy constructor.
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeNameTransliterator::UnicodeNameTransliterator(const UnicodeNameTransliterator& o) :
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Transliterator(o) {}
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Assignment operator.
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*UnicodeNameTransliterator& UnicodeNameTransliterator::operator=(
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             const UnicodeNameTransliterator& o) {
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Transliterator::operator=(o);
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return *this;
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}*/
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Transliterator API.
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruTransliterator* UnicodeNameTransliterator::clone(void) const {
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return new UnicodeNameTransliterator(*this);
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Implements {@link Transliterator#handleTransliterate}.
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Ignore isIncremental since we don't need the context, and
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * we work on codepoints.
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid UnicodeNameTransliterator::handleTransliterate(Replaceable& text, UTransPosition& offsets,
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                    UBool /*isIncremental*/) const {
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // The failure mode, here and below, is to behave like Any-Null,
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // if either there is no name data (max len == 0) or there is no
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // memory (malloc() => NULL).
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t maxLen = uprv_getMaxCharNameLength();
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (maxLen == 0) {
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offsets.start = offsets.limit;
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Accomodate the longest possible name plus padding
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char* buf = (char*) uprv_malloc(maxLen);
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (buf == NULL) {
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offsets.start = offsets.limit;
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t cursor = offsets.start;
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t limit = offsets.limit;
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString str(FALSE, OPEN_DELIM, OPEN_DELIM_LEN);
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode status;
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t len;
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (cursor < limit) {
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32 c = text.char32At(cursor);
9883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        int32_t clen = U16_LENGTH(c);
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_ZERO_ERROR;
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ((len = u_charName(c, U_EXTENDED_CHAR_NAME, buf, maxLen, &status)) >0 && !U_FAILURE(status)) {
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            str.truncate(OPEN_DELIM_LEN);
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            str.append(UnicodeString(buf, len, US_INV)).append(CLOSE_DELIM);
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            text.handleReplaceBetween(cursor, cursor+clen, str);
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            len += OPEN_DELIM_LEN + 1; // adjust for delimiters
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            cursor += len; // advance cursor and adjust for new text
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            limit += len-clen; // change in length
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            cursor += clen;
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsets.contextLimit += limit - offsets.limit;
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsets.limit = limit;
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsets.start = cursor;
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_free(buf);
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_TRANSLITERATION */
122