• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
ulistfmt_open(const char * locale,UErrorCode * status)23 ulistfmt_open(const char*  locale,
24               UErrorCode*  status)
25 {
26     if (U_FAILURE(*status)) {
27         return NULL;
28     }
29     LocalPointer<ListFormatter> listfmt(ListFormatter::createInstance(Locale(locale), *status));
30     if (U_FAILURE(*status)) {
31         return NULL;
32     }
33     return (UListFormatter*)listfmt.orphan();
34 }
35 
36 
37 U_CAPI UListFormatter* U_EXPORT2
ulistfmt_openForType(const char * locale,UListFormatterType type,UListFormatterWidth width,UErrorCode * status)38 ulistfmt_openForType(const char*  locale, UListFormatterType type,
39                     UListFormatterWidth width, UErrorCode* status)
40 {
41     if (U_FAILURE(*status)) {
42         return NULL;
43     }
44     LocalPointer<ListFormatter> listfmt(ListFormatter::createInstance(Locale(locale), type, width, *status));
45     if (U_FAILURE(*status)) {
46         return NULL;
47     }
48     return (UListFormatter*)listfmt.orphan();
49 }
50 
51 
52 U_CAPI void U_EXPORT2
ulistfmt_close(UListFormatter * listfmt)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 
getUnicodeStrings(const UChar * const strings[],const int32_t * stringLengths,int32_t stringCount,UnicodeString * length4StackBuffer,LocalArray<UnicodeString> & maybeOwner,UErrorCode & status)69 static UnicodeString* getUnicodeStrings(
70         const UChar* 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 == NULL && 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 == NULL) {
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
ulistfmt_format(const UListFormatter * listfmt,const UChar * const strings[],const int32_t * stringLengths,int32_t stringCount,UChar * result,int32_t resultCapacity,UErrorCode * status)103 ulistfmt_format(const UListFormatter* listfmt,
104                 const UChar* const strings[],
105                 const int32_t *    stringLengths,
106                 int32_t            stringCount,
107                 UChar*             result,
108                 int32_t            resultCapacity,
109                 UErrorCode*        status)
110 {
111     if (U_FAILURE(*status)) {
112         return -1;
113     }
114     if ((result == NULL) ? 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 != NULL) {
127         // NULL 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
ulistfmt_formatStringsToResult(const UListFormatter * listfmt,const UChar * const strings[],const int32_t * stringLengths,int32_t stringCount,UFormattedList * uresult,UErrorCode * status)137 ulistfmt_formatStringsToResult(
138                 const UListFormatter* listfmt,
139                 const UChar* 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 */
161