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 void U_EXPORT2
ulistfmt_close(UListFormatter * listfmt)38 ulistfmt_close(UListFormatter *listfmt)
39 {
40 delete (ListFormatter*)listfmt;
41 }
42
43
44 // Magic number: FLST in ASCII
45 UPRV_FORMATTED_VALUE_CAPI_AUTO_IMPL(
46 FormattedList,
47 UFormattedList,
48 UFormattedListImpl,
49 UFormattedListApiHelper,
50 ulistfmt,
51 0x464C5354)
52
53
getUnicodeStrings(const UChar * const strings[],const int32_t * stringLengths,int32_t stringCount,UnicodeString * length4StackBuffer,LocalArray<UnicodeString> & maybeOwner,UErrorCode & status)54 static UnicodeString* getUnicodeStrings(
55 const UChar* const strings[],
56 const int32_t* stringLengths,
57 int32_t stringCount,
58 UnicodeString* length4StackBuffer,
59 LocalArray<UnicodeString>& maybeOwner,
60 UErrorCode& status) {
61 U_ASSERT(U_SUCCESS(status));
62 if (stringCount < 0 || (strings == NULL && stringCount > 0)) {
63 status = U_ILLEGAL_ARGUMENT_ERROR;
64 return nullptr;
65 }
66 UnicodeString* ustrings = length4StackBuffer;
67 if (stringCount > 4) {
68 maybeOwner.adoptInsteadAndCheckErrorCode(new UnicodeString[stringCount], status);
69 if (U_FAILURE(status)) {
70 return nullptr;
71 }
72 ustrings = maybeOwner.getAlias();
73 }
74 if (stringLengths == NULL) {
75 for (int32_t stringIndex = 0; stringIndex < stringCount; stringIndex++) {
76 ustrings[stringIndex].setTo(TRUE, strings[stringIndex], -1);
77 }
78 } else {
79 for (int32_t stringIndex = 0; stringIndex < stringCount; stringIndex++) {
80 ustrings[stringIndex].setTo(stringLengths[stringIndex] < 0, strings[stringIndex], stringLengths[stringIndex]);
81 }
82 }
83 return ustrings;
84 }
85
86
87 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)88 ulistfmt_format(const UListFormatter* listfmt,
89 const UChar* const strings[],
90 const int32_t * stringLengths,
91 int32_t stringCount,
92 UChar* result,
93 int32_t resultCapacity,
94 UErrorCode* status)
95 {
96 if (U_FAILURE(*status)) {
97 return -1;
98 }
99 if ((result == NULL) ? resultCapacity != 0 : resultCapacity < 0) {
100 *status = U_ILLEGAL_ARGUMENT_ERROR;
101 return -1;
102 }
103 UnicodeString length4StackBuffer[4];
104 LocalArray<UnicodeString> maybeOwner;
105 UnicodeString* ustrings = getUnicodeStrings(
106 strings, stringLengths, stringCount, length4StackBuffer, maybeOwner, *status);
107 if (U_FAILURE(*status)) {
108 return -1;
109 }
110 UnicodeString res;
111 if (result != NULL) {
112 // NULL destination for pure preflighting: empty dummy string
113 // otherwise, alias the destination buffer (copied from udat_format)
114 res.setTo(result, 0, resultCapacity);
115 }
116 reinterpret_cast<const ListFormatter*>(listfmt)->format( ustrings, stringCount, res, *status );
117 return res.extract(result, resultCapacity, *status);
118 }
119
120
121 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)122 ulistfmt_formatStringsToResult(
123 const UListFormatter* listfmt,
124 const UChar* const strings[],
125 const int32_t * stringLengths,
126 int32_t stringCount,
127 UFormattedList* uresult,
128 UErrorCode* status) {
129 auto* result = UFormattedListApiHelper::validate(uresult, *status);
130 if (U_FAILURE(*status)) {
131 return;
132 }
133 UnicodeString length4StackBuffer[4];
134 LocalArray<UnicodeString> maybeOwner;
135 UnicodeString* ustrings = getUnicodeStrings(
136 strings, stringLengths, stringCount, length4StackBuffer, maybeOwner, *status);
137 if (U_FAILURE(*status)) {
138 return;
139 }
140 result->fImpl = reinterpret_cast<const ListFormatter*>(listfmt)
141 ->formatStringsToValue(ustrings, stringCount, *status);
142 }
143
144
145 #endif /* #if !UCONFIG_NO_FORMATTING */
146