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 */ 122