tor-browser

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

ulistformatter.cpp (5097B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 *****************************************************************************************
      5 * Copyright (C) 2015, International Business Machines
      6 * Corporation and others. All Rights Reserved.
      7 *****************************************************************************************
      8 */
      9 
     10 #include "unicode/utypes.h"
     11 
     12 #if !UCONFIG_NO_FORMATTING
     13 
     14 #include "unicode/ulistformatter.h"
     15 #include "unicode/listformatter.h"
     16 #include "unicode/localpointer.h"
     17 #include "cmemory.h"
     18 #include "formattedval_impl.h"
     19 
     20 U_NAMESPACE_USE
     21 
     22 U_CAPI UListFormatter* U_EXPORT2
     23 ulistfmt_open(const char*  locale,
     24              UErrorCode*  status)
     25 {
     26    if (U_FAILURE(*status)) {
     27        return nullptr;
     28    }
     29    LocalPointer<ListFormatter> listfmt(ListFormatter::createInstance(Locale(locale), *status));
     30    if (U_FAILURE(*status)) {
     31        return nullptr;
     32    }
     33    return (UListFormatter*)listfmt.orphan();
     34 }
     35 
     36 
     37 U_CAPI UListFormatter* U_EXPORT2
     38 ulistfmt_openForType(const char*  locale, UListFormatterType type,
     39                    UListFormatterWidth width, UErrorCode* status)
     40 {
     41    if (U_FAILURE(*status)) {
     42        return nullptr;
     43    }
     44    LocalPointer<ListFormatter> listfmt(ListFormatter::createInstance(Locale(locale), type, width, *status));
     45    if (U_FAILURE(*status)) {
     46        return nullptr;
     47    }
     48    return (UListFormatter*)listfmt.orphan();
     49 }
     50 
     51 
     52 U_CAPI void U_EXPORT2
     53 ulistfmt_close(UListFormatter *listfmt)
     54 {
     55    delete (ListFormatter*)listfmt;
     56 }
     57 
     58 
     59 // Magic number: FLST in ASCII
     60 UPRV_FORMATTED_VALUE_CAPI_AUTO_IMPL(
     61    FormattedList,
     62    UFormattedList,
     63    UFormattedListImpl,
     64    UFormattedListApiHelper,
     65    ulistfmt,
     66    0x464C5354)
     67 
     68 
     69 static UnicodeString* getUnicodeStrings(
     70        const char16_t* const strings[],
     71        const int32_t* stringLengths,
     72        int32_t stringCount,
     73        UnicodeString* length4StackBuffer,
     74        LocalArray<UnicodeString>& maybeOwner,
     75        UErrorCode& status) {
     76    U_ASSERT(U_SUCCESS(status));
     77    if (stringCount < 0 || (strings == nullptr && stringCount > 0)) {
     78        status = U_ILLEGAL_ARGUMENT_ERROR;
     79        return nullptr;
     80    }
     81    UnicodeString* ustrings = length4StackBuffer;
     82    if (stringCount > 4) {
     83        maybeOwner.adoptInsteadAndCheckErrorCode(new UnicodeString[stringCount], status);
     84        if (U_FAILURE(status)) {
     85            return nullptr;
     86        }
     87        ustrings = maybeOwner.getAlias();
     88    }
     89    if (stringLengths == nullptr) {
     90        for (int32_t stringIndex = 0; stringIndex < stringCount; stringIndex++) {
     91            ustrings[stringIndex].setTo(true, strings[stringIndex], -1);
     92        }
     93    } else {
     94        for (int32_t stringIndex = 0; stringIndex < stringCount; stringIndex++) {
     95            ustrings[stringIndex].setTo(stringLengths[stringIndex] < 0, strings[stringIndex], stringLengths[stringIndex]);
     96        }
     97    }
     98    return ustrings;
     99 }
    100 
    101 
    102 U_CAPI int32_t U_EXPORT2
    103 ulistfmt_format(const UListFormatter* listfmt,
    104                const char16_t* const strings[],
    105                const int32_t *    stringLengths,
    106                int32_t            stringCount,
    107                char16_t*             result,
    108                int32_t            resultCapacity,
    109                UErrorCode*        status)
    110 {
    111    if (U_FAILURE(*status)) {
    112        return -1;
    113    }
    114    if ((result == nullptr) ? resultCapacity != 0 : resultCapacity < 0) {
    115        *status = U_ILLEGAL_ARGUMENT_ERROR;
    116        return -1;
    117    }
    118    UnicodeString length4StackBuffer[4];
    119    LocalArray<UnicodeString> maybeOwner;
    120    UnicodeString* ustrings = getUnicodeStrings(
    121        strings, stringLengths, stringCount, length4StackBuffer, maybeOwner, *status);
    122    if (U_FAILURE(*status)) {
    123        return -1;
    124    }
    125    UnicodeString res;
    126    if (result != nullptr) {
    127        // nullptr destination for pure preflighting: empty dummy string
    128        // otherwise, alias the destination buffer (copied from udat_format)
    129        res.setTo(result, 0, resultCapacity);
    130    }
    131    reinterpret_cast<const ListFormatter*>(listfmt)->format( ustrings, stringCount, res, *status );
    132    return res.extract(result, resultCapacity, *status);
    133 }
    134 
    135 
    136 U_CAPI void U_EXPORT2
    137 ulistfmt_formatStringsToResult(
    138                const UListFormatter* listfmt,
    139                const char16_t* const strings[],
    140                const int32_t *    stringLengths,
    141                int32_t            stringCount,
    142                UFormattedList*    uresult,
    143                UErrorCode*        status) {
    144    auto* result = UFormattedListApiHelper::validate(uresult, *status);
    145    if (U_FAILURE(*status)) {
    146        return;
    147    }
    148    UnicodeString length4StackBuffer[4];
    149    LocalArray<UnicodeString> maybeOwner;
    150    UnicodeString* ustrings = getUnicodeStrings(
    151        strings, stringLengths, stringCount, length4StackBuffer, maybeOwner, *status);
    152    if (U_FAILURE(*status)) {
    153        return;
    154    }
    155    result->fImpl = reinterpret_cast<const ListFormatter*>(listfmt)
    156        ->formatStringsToValue(ustrings, stringCount, *status);
    157 }
    158 
    159 
    160 #endif /* #if !UCONFIG_NO_FORMATTING */