| |
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 */ |
| |
34 UnicodeNameTransliterator::UnicodeNameTransliterator(UnicodeFilter* adoptedFilter) : |
| |
35 Transliterator(UNICODE_STRING("Any-Name", 8), adoptedFilter) { |
| |
36 } |
| |
37 |
| |
38 /** |
| |
39 * Destructor. |
| |
40 */ |
| |
41 UnicodeNameTransliterator::~UnicodeNameTransliterator() {} |
| |
42 |
| |
43 /** |
| |
44 * Copy constructor. |
| |
45 */ |
| |
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 */ |
| |
61 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 */ |
| |
70 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 */ |