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