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 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 |
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 |
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 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 |
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 |
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 | |