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