ulistformatter.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. #include "unicode/utypes.h"
  10. #if !UCONFIG_NO_FORMATTING
  11. #include "unicode/ulistformatter.h"
  12. #include "unicode/listformatter.h"
  13. #include "unicode/localpointer.h"
  14. #include "cmemory.h"
  15. #include "formattedval_impl.h"
  16. U_NAMESPACE_USE
  17. U_CAPI UListFormatter* U_EXPORT2
  18. ulistfmt_open(const char* locale,
  19. UErrorCode* status)
  20. {
  21. if (U_FAILURE(*status)) {
  22. return nullptr;
  23. }
  24. LocalPointer<ListFormatter> listfmt(ListFormatter::createInstance(Locale(locale), *status));
  25. if (U_FAILURE(*status)) {
  26. return nullptr;
  27. }
  28. return (UListFormatter*)listfmt.orphan();
  29. }
  30. U_CAPI UListFormatter* U_EXPORT2
  31. ulistfmt_openForType(const char* locale, UListFormatterType type,
  32. UListFormatterWidth width, UErrorCode* status)
  33. {
  34. if (U_FAILURE(*status)) {
  35. return nullptr;
  36. }
  37. LocalPointer<ListFormatter> listfmt(ListFormatter::createInstance(Locale(locale), type, width, *status));
  38. if (U_FAILURE(*status)) {
  39. return nullptr;
  40. }
  41. return (UListFormatter*)listfmt.orphan();
  42. }
  43. U_CAPI void U_EXPORT2
  44. ulistfmt_close(UListFormatter *listfmt)
  45. {
  46. delete (ListFormatter*)listfmt;
  47. }
  48. // Magic number: FLST in ASCII
  49. UPRV_FORMATTED_VALUE_CAPI_AUTO_IMPL(
  50. FormattedList,
  51. UFormattedList,
  52. UFormattedListImpl,
  53. UFormattedListApiHelper,
  54. ulistfmt,
  55. 0x464C5354)
  56. static UnicodeString* getUnicodeStrings(
  57. const char16_t* const strings[],
  58. const int32_t* stringLengths,
  59. int32_t stringCount,
  60. UnicodeString* length4StackBuffer,
  61. LocalArray<UnicodeString>& maybeOwner,
  62. UErrorCode& status) {
  63. U_ASSERT(U_SUCCESS(status));
  64. if (stringCount < 0 || (strings == nullptr && stringCount > 0)) {
  65. status = U_ILLEGAL_ARGUMENT_ERROR;
  66. return nullptr;
  67. }
  68. UnicodeString* ustrings = length4StackBuffer;
  69. if (stringCount > 4) {
  70. maybeOwner.adoptInsteadAndCheckErrorCode(new UnicodeString[stringCount], status);
  71. if (U_FAILURE(status)) {
  72. return nullptr;
  73. }
  74. ustrings = maybeOwner.getAlias();
  75. }
  76. if (stringLengths == nullptr) {
  77. for (int32_t stringIndex = 0; stringIndex < stringCount; stringIndex++) {
  78. ustrings[stringIndex].setTo(true, strings[stringIndex], -1);
  79. }
  80. } else {
  81. for (int32_t stringIndex = 0; stringIndex < stringCount; stringIndex++) {
  82. ustrings[stringIndex].setTo(stringLengths[stringIndex] < 0, strings[stringIndex], stringLengths[stringIndex]);
  83. }
  84. }
  85. return ustrings;
  86. }
  87. U_CAPI int32_t U_EXPORT2
  88. ulistfmt_format(const UListFormatter* listfmt,
  89. const char16_t* const strings[],
  90. const int32_t * stringLengths,
  91. int32_t stringCount,
  92. char16_t* result,
  93. int32_t resultCapacity,
  94. UErrorCode* status)
  95. {
  96. if (U_FAILURE(*status)) {
  97. return -1;
  98. }
  99. if ((result == nullptr) ? 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 != nullptr) {
  112. // nullptr 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. U_CAPI void U_EXPORT2
  120. ulistfmt_formatStringsToResult(
  121. const UListFormatter* listfmt,
  122. const char16_t* const strings[],
  123. const int32_t * stringLengths,
  124. int32_t stringCount,
  125. UFormattedList* uresult,
  126. UErrorCode* status) {
  127. auto* result = UFormattedListApiHelper::validate(uresult, *status);
  128. if (U_FAILURE(*status)) {
  129. return;
  130. }
  131. UnicodeString length4StackBuffer[4];
  132. LocalArray<UnicodeString> maybeOwner;
  133. UnicodeString* ustrings = getUnicodeStrings(
  134. strings, stringLengths, stringCount, length4StackBuffer, maybeOwner, *status);
  135. if (U_FAILURE(*status)) {
  136. return;
  137. }
  138. result->fImpl = reinterpret_cast<const ListFormatter*>(listfmt)
  139. ->formatStringsToValue(ustrings, stringCount, *status);
  140. }
  141. #endif /* #if !UCONFIG_NO_FORMATTING */