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