1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/uni2name.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,121 @@ 1.4 +/* 1.5 +********************************************************************** 1.6 +* Copyright (C) 2001-2011, International Business Machines 1.7 +* Corporation and others. All Rights Reserved. 1.8 +********************************************************************** 1.9 +* Date Name Description 1.10 +* 06/06/01 aliu Creation. 1.11 +********************************************************************** 1.12 +*/ 1.13 + 1.14 +#include "unicode/utypes.h" 1.15 + 1.16 +#if !UCONFIG_NO_TRANSLITERATION 1.17 + 1.18 +#include "unicode/unifilt.h" 1.19 +#include "unicode/uchar.h" 1.20 +#include "unicode/utf16.h" 1.21 +#include "uni2name.h" 1.22 +#include "cstring.h" 1.23 +#include "cmemory.h" 1.24 +#include "uprops.h" 1.25 + 1.26 +U_NAMESPACE_BEGIN 1.27 + 1.28 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeNameTransliterator) 1.29 + 1.30 +static const UChar OPEN_DELIM[] = {92,78,123,0}; // "\N{" 1.31 +static const UChar CLOSE_DELIM = 125; // "}" 1.32 +#define OPEN_DELIM_LEN 3 1.33 + 1.34 +/** 1.35 + * Constructs a transliterator. 1.36 + */ 1.37 +UnicodeNameTransliterator::UnicodeNameTransliterator(UnicodeFilter* adoptedFilter) : 1.38 + Transliterator(UNICODE_STRING("Any-Name", 8), adoptedFilter) { 1.39 +} 1.40 + 1.41 +/** 1.42 + * Destructor. 1.43 + */ 1.44 +UnicodeNameTransliterator::~UnicodeNameTransliterator() {} 1.45 + 1.46 +/** 1.47 + * Copy constructor. 1.48 + */ 1.49 +UnicodeNameTransliterator::UnicodeNameTransliterator(const UnicodeNameTransliterator& o) : 1.50 + Transliterator(o) {} 1.51 + 1.52 +/** 1.53 + * Assignment operator. 1.54 + */ 1.55 +/*UnicodeNameTransliterator& UnicodeNameTransliterator::operator=( 1.56 + const UnicodeNameTransliterator& o) { 1.57 + Transliterator::operator=(o); 1.58 + return *this; 1.59 +}*/ 1.60 + 1.61 +/** 1.62 + * Transliterator API. 1.63 + */ 1.64 +Transliterator* UnicodeNameTransliterator::clone(void) const { 1.65 + return new UnicodeNameTransliterator(*this); 1.66 +} 1.67 + 1.68 +/** 1.69 + * Implements {@link Transliterator#handleTransliterate}. 1.70 + * Ignore isIncremental since we don't need the context, and 1.71 + * we work on codepoints. 1.72 + */ 1.73 +void UnicodeNameTransliterator::handleTransliterate(Replaceable& text, UTransPosition& offsets, 1.74 + UBool /*isIncremental*/) const { 1.75 + // The failure mode, here and below, is to behave like Any-Null, 1.76 + // if either there is no name data (max len == 0) or there is no 1.77 + // memory (malloc() => NULL). 1.78 + 1.79 + int32_t maxLen = uprv_getMaxCharNameLength(); 1.80 + if (maxLen == 0) { 1.81 + offsets.start = offsets.limit; 1.82 + return; 1.83 + } 1.84 + 1.85 + // Accomodate the longest possible name plus padding 1.86 + char* buf = (char*) uprv_malloc(maxLen); 1.87 + if (buf == NULL) { 1.88 + offsets.start = offsets.limit; 1.89 + return; 1.90 + } 1.91 + 1.92 + int32_t cursor = offsets.start; 1.93 + int32_t limit = offsets.limit; 1.94 + 1.95 + UnicodeString str(FALSE, OPEN_DELIM, OPEN_DELIM_LEN); 1.96 + UErrorCode status; 1.97 + int32_t len; 1.98 + 1.99 + while (cursor < limit) { 1.100 + UChar32 c = text.char32At(cursor); 1.101 + int32_t clen = U16_LENGTH(c); 1.102 + status = U_ZERO_ERROR; 1.103 + if ((len = u_charName(c, U_EXTENDED_CHAR_NAME, buf, maxLen, &status)) >0 && !U_FAILURE(status)) { 1.104 + str.truncate(OPEN_DELIM_LEN); 1.105 + str.append(UnicodeString(buf, len, US_INV)).append(CLOSE_DELIM); 1.106 + text.handleReplaceBetween(cursor, cursor+clen, str); 1.107 + len += OPEN_DELIM_LEN + 1; // adjust for delimiters 1.108 + cursor += len; // advance cursor and adjust for new text 1.109 + limit += len-clen; // change in length 1.110 + } else { 1.111 + cursor += clen; 1.112 + } 1.113 + } 1.114 + 1.115 + offsets.contextLimit += limit - offsets.limit; 1.116 + offsets.limit = limit; 1.117 + offsets.start = cursor; 1.118 + 1.119 + uprv_free(buf); 1.120 +} 1.121 + 1.122 +U_NAMESPACE_END 1.123 + 1.124 +#endif /* #if !UCONFIG_NO_TRANSLITERATION */