tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

uni2name.cpp (3662B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 **********************************************************************
      5 *   Copyright (C) 2001-2011, International Business Machines
      6 *   Corporation and others.  All Rights Reserved.
      7 **********************************************************************
      8 *   Date        Name        Description
      9 *   06/06/01    aliu        Creation.
     10 **********************************************************************
     11 */
     12 
     13 #include "unicode/utypes.h"
     14 
     15 #if !UCONFIG_NO_TRANSLITERATION
     16 
     17 #include "unicode/unifilt.h"
     18 #include "unicode/uchar.h"
     19 #include "unicode/utf16.h"
     20 #include "uni2name.h"
     21 #include "cstring.h"
     22 #include "cmemory.h"
     23 #include "uprops.h"
     24 
     25 U_NAMESPACE_BEGIN
     26 
     27 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeNameTransliterator)
     28 
     29 static const char16_t OPEN_DELIM[] = {92,78,123,0}; // "\N{"
     30 static const char16_t CLOSE_DELIM  = 125; // "}"
     31 #define OPEN_DELIM_LEN 3
     32 
     33 /**
     34 * Constructs a transliterator.
     35 */
     36 UnicodeNameTransliterator::UnicodeNameTransliterator(UnicodeFilter* adoptedFilter) :
     37    Transliterator(UNICODE_STRING("Any-Name", 8), adoptedFilter) {
     38 }
     39 
     40 /**
     41 * Destructor.
     42 */
     43 UnicodeNameTransliterator::~UnicodeNameTransliterator() {}
     44 
     45 /**
     46 * Copy constructor.
     47 */
     48 UnicodeNameTransliterator::UnicodeNameTransliterator(const UnicodeNameTransliterator& o) :
     49    Transliterator(o) {}
     50 
     51 /**
     52 * Assignment operator.
     53 */
     54 /*UnicodeNameTransliterator& UnicodeNameTransliterator::operator=(
     55                             const UnicodeNameTransliterator& o) {
     56    Transliterator::operator=(o);
     57    return *this;
     58 }*/
     59 
     60 /**
     61 * Transliterator API.
     62 */
     63 UnicodeNameTransliterator* UnicodeNameTransliterator::clone() const {
     64    return new UnicodeNameTransliterator(*this);
     65 }
     66 
     67 /**
     68 * Implements {@link Transliterator#handleTransliterate}.
     69 * Ignore isIncremental since we don't need the context, and
     70 * we work on codepoints.
     71 */
     72 void UnicodeNameTransliterator::handleTransliterate(Replaceable& text, UTransPosition& offsets,
     73                                                    UBool /*isIncremental*/) const {
     74    // The failure mode, here and below, is to behave like Any-Null,
     75    // if either there is no name data (max len == 0) or there is no
     76    // memory (malloc() => nullptr).
     77 
     78    int32_t maxLen = uprv_getMaxCharNameLength();
     79    if (maxLen == 0) {
     80        offsets.start = offsets.limit;
     81        return;
     82    }
     83 
     84    // Accommodate the longest possible name plus padding
     85    char* buf = static_cast<char*>(uprv_malloc(maxLen));
     86    if (buf == nullptr) {
     87        offsets.start = offsets.limit;
     88        return;
     89    }
     90    
     91    int32_t cursor = offsets.start;
     92    int32_t limit = offsets.limit;
     93 
     94    UnicodeString str(false, OPEN_DELIM, OPEN_DELIM_LEN);
     95    UErrorCode status;
     96    int32_t len;
     97 
     98    while (cursor < limit) {
     99        UChar32 c = text.char32At(cursor);
    100        int32_t clen = U16_LENGTH(c);
    101        status = U_ZERO_ERROR;
    102        if ((len = u_charName(c, U_EXTENDED_CHAR_NAME, buf, maxLen, &status)) >0 && !U_FAILURE(status)) {
    103            str.truncate(OPEN_DELIM_LEN);
    104            str.append(UnicodeString(buf, len, US_INV)).append(CLOSE_DELIM);
    105            text.handleReplaceBetween(cursor, cursor+clen, str);
    106            len += OPEN_DELIM_LEN + 1; // adjust for delimiters
    107            cursor += len; // advance cursor and adjust for new text
    108            limit += len-clen; // change in length
    109        } else {
    110            cursor += clen;
    111        }
    112    }
    113 
    114    offsets.contextLimit += limit - offsets.limit;
    115    offsets.limit = limit;
    116    offsets.start = cursor;
    117 
    118    uprv_free(buf);
    119 }
    120 
    121 U_NAMESPACE_END
    122 
    123 #endif /* #if !UCONFIG_NO_TRANSLITERATION */