From: Markus Scherer Date: Tue, 28 Feb 2017 22:07:03 +0000 (+0000) Subject: ICU-12992 return pointer-wrapper class from UnicodeString::getBuffer() and siblings... X-Git-Tag: release-59-rc~119^2~15 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d924dda84bca1bdba455225ee0d5210e122f2725;p=icu ICU-12992 return pointer-wrapper class from UnicodeString::getBuffer() and siblings, add wrapper class overloads to make this mostly work as is, fix a few call sites X-SVN-Rev: 39715 --- diff --git a/icu4c/source/common/ucurr.cpp b/icu4c/source/common/ucurr.cpp index c63e6ca593f..8cc817ade9e 100644 --- a/icu4c/source/common/ucurr.cpp +++ b/icu4c/source/common/ucurr.cpp @@ -1030,7 +1030,8 @@ collectCurrencyNames(const char* locale, const UnicodeString *symbol; while ((symbol = iter.next()) != NULL) { (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso; - (*currencySymbols)[*total_currency_symbol_count].currencyName = (UChar*) symbol->getBuffer(); + (*currencySymbols)[*total_currency_symbol_count].currencyName = + const_cast(symbol->getBuffer().get()); (*currencySymbols)[*total_currency_symbol_count].flag = 0; (*currencySymbols)[(*total_currency_symbol_count)++].currencyNameLen = symbol->length(); } diff --git a/icu4c/source/common/unicode/unistr.h b/icu4c/source/common/unicode/unistr.h index 7b325f2df0f..3ed6b7f41cc 100644 --- a/icu4c/source/common/unicode/unistr.h +++ b/icu4c/source/common/unicode/unistr.h @@ -79,6 +79,7 @@ class U_COMMON_API Char16Ptr final { public: /** * Copies the pointer. + * TODO: @param p ... * @draft ICU 59 */ inline Char16Ptr(char16_t *p); @@ -106,22 +107,71 @@ public: * @draft ICU 59 */ Char16Ptr(int null); + /** + * Destructor. + * @draft ICU 59 + */ + inline ~Char16Ptr(); + /** * Pointer access. + * TODO @return ... + * @draft ICU 59 + */ + inline char16_t *get() const; + /** + * char16_t pointer access via type conversion (e.g., static_cast). + * @draft ICU 59 + */ + operator char16_t *() const { return get(); } + /** + * uint16_t pointer access via type conversion (e.g., static_cast). + * @draft ICU 59 + */ + inline operator uint16_t *() const; +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + /** + * wchar_t pointer access via type conversion (e.g., static_cast). + * @draft ICU 59 + */ + inline operator wchar_t *() const; +#endif + operator void *() const { return get(); } + + char16_t operator[](size_t offset) const { return get()[offset]; } + + UBool operator==(const Char16Ptr &other) const { return get() == other.get(); } + UBool operator!=(const Char16Ptr &other) const { return !operator==(other); } + UBool operator==(const char16_t *other) const { return get() == other; } + UBool operator!=(const char16_t *other) const { return !operator==(other); } + UBool operator==(const uint16_t *other) const { return static_cast(*this) == other; } + UBool operator!=(const uint16_t *other) const { return !operator==(other); } +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + UBool operator==(const wchar_t *other) const { return static_cast(*this) == other; } + UBool operator!=(const wchar_t *other) const { return !operator==(other); } +#endif + UBool operator==(const std::nullptr_t null) const { return get() == null; } + UBool operator!=(const std::nullptr_t null) const { return !operator==(null); } + /** + * Comparison with NULL. + * @return TRUE if the pointer is nullptr and null==0 * @draft ICU 59 */ - inline char16_t *get(); + UBool operator==(int null) const { return get() == nullptr && null == 0; } /** - * Pointer access via type conversion (e.g., static_cast). + * Comparison with NULL. + * @return TRUE if the pointer is not nullptr and null==0 * @draft ICU 59 */ - operator char16_t *() { return get(); } + UBool operator!=(int null) const { return get() != nullptr && null == 0; } + + Char16Ptr operator+(size_t offset) const { return Char16Ptr(get() + offset); } private: Char16Ptr() = delete; #ifdef U_ALIASING_BARRIER - template char16_t *cast(T *t) { + template static char16_t *cast(T *t) { U_ALIASING_BARRIER(t); return reinterpret_cast(t); } @@ -144,8 +194,22 @@ Char16Ptr::Char16Ptr(uint16_t *p) : p(cast(p)) {} Char16Ptr::Char16Ptr(wchar_t *p) : p(cast(p)) {} #endif Char16Ptr::Char16Ptr(std::nullptr_t p) : p(p) {} +Char16Ptr::~Char16Ptr() { + U_ALIASING_BARRIER(p); +} -char16_t *Char16Ptr::get() { return p; } +char16_t *Char16Ptr::get() const { return p; } + +Char16Ptr::operator uint16_t *() const { + U_ALIASING_BARRIER(p); + return reinterpret_cast(p); +} +#if U_SIZEOF_WCHAR_T==2 +Char16Ptr::operator wchar_t *() const { + U_ALIASING_BARRIER(p); + return reinterpret_cast(p); +} +#endif #else @@ -155,8 +219,18 @@ Char16Ptr::Char16Ptr(uint16_t *p) { u.up = p; } Char16Ptr::Char16Ptr(wchar_t *p) { u.wp = p; } #endif Char16Ptr::Char16Ptr(std::nullptr_t p) { u.cp = p; } +Char16Ptr::~Char16Ptr() {} -char16_t *Char16Ptr::get() { return u.cp; } +char16_t *Char16Ptr::get() const { return u.cp; } + +Char16Ptr::operator uint16_t *() const { + return u.up; +} +#if U_SIZEOF_WCHAR_T==2 +Char16Ptr::operator wchar_t *() const { + return u.wp; +} +#endif #endif @@ -196,22 +270,60 @@ public: * @draft ICU 59 */ ConstChar16Ptr(int null); + /** + * Destructor. + * @draft ICU 59 + */ + inline ~ConstChar16Ptr(); + /** * Pointer access. * @draft ICU 59 */ inline const char16_t *get() const; /** - * Pointer access via type conversion (e.g., static_cast). + * char16_t pointer access via type conversion (e.g., static_cast). + * @draft ICU 59 + */ + operator const char16_t *() const { return get(); } + /** + * uint16_t pointer access via type conversion (e.g., static_cast). + * @draft ICU 59 + */ + inline operator const uint16_t *() const; +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + /** + * wchar_t pointer access via type conversion (e.g., static_cast). * @draft ICU 59 */ - operator const char16_t *() { return get(); } + inline operator const wchar_t *() const; +#endif + operator const void *() const { return get(); } + + char16_t operator[](size_t offset) const { return get()[offset]; } + + UBool operator==(const ConstChar16Ptr &other) const { return get() == other.get(); } + UBool operator!=(const ConstChar16Ptr &other) const { return !operator==(other); } + UBool operator==(const char16_t *other) const { return get() == other; } + UBool operator!=(const char16_t *other) const { return !operator==(other); } + UBool operator==(const uint16_t *other) const { return static_cast(*this) == other; } + UBool operator!=(const uint16_t *other) const { return !operator==(other); } +#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN) + UBool operator==(const wchar_t *other) const { return static_cast(*this) == other; } + UBool operator!=(const wchar_t *other) const { return !operator==(other); } +#endif + UBool operator==(const std::nullptr_t null) const { return get() == null; } + UBool operator!=(const std::nullptr_t null) const { return !operator==(null); } + UBool operator==(int null) const { return get() == nullptr && null == 0; } + UBool operator!=(int null) const { return get() != nullptr && null == 0; } + + ConstChar16Ptr operator+(size_t offset) { return ConstChar16Ptr(get() + offset); } private: ConstChar16Ptr() = delete; #ifdef U_ALIASING_BARRIER - template const char16_t *cast(const T *t) { + template static const char16_t *cast(const T *t) { U_ALIASING_BARRIER(t); return reinterpret_cast(t); } @@ -234,9 +346,23 @@ ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) : p(cast(p)) {} ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) : p(cast(p)) {} #endif ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) : p(p) {} +ConstChar16Ptr::~ConstChar16Ptr() { + U_ALIASING_BARRIER(p); +} const char16_t *ConstChar16Ptr::get() const { return p; } +ConstChar16Ptr::operator const uint16_t *() const { + U_ALIASING_BARRIER(p); + return reinterpret_cast(p); +} +#if U_SIZEOF_WCHAR_T==2 +ConstChar16Ptr::operator const wchar_t *() const { + U_ALIASING_BARRIER(p); + return reinterpret_cast(p); +} +#endif + #else ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) { u.cp = p; } @@ -245,9 +371,19 @@ ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) { u.up = p; } ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) { u.wp = p; } #endif ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) { u.cp = p; } +ConstChar16Ptr::~ConstChar16Ptr() {} const char16_t *ConstChar16Ptr::get() const { return u.cp; } +ConstChar16Ptr::operator const uint16_t *() const { + return u.up; +} +#if U_SIZEOF_WCHAR_T==2 +ConstChar16Ptr::operator const wchar_t *() const { + return u.wp; +} +#endif + #endif // TODO end experiment ----------------- @@ -3047,13 +3183,13 @@ public: * in the buffer, starting at the returned pointer; * default to the current string capacity if minCapacity==-1 * @return a writable pointer to the internal string buffer, - * or 0 if an error occurs (nested calls, out of memory) + * or nullptr if an error occurs (nested calls, out of memory) * * @see releaseBuffer * @see getTerminatedBuffer() * @stable ICU 2.0 */ - UChar *getBuffer(int32_t minCapacity); + Char16Ptr getBuffer(int32_t minCapacity); /** * Release a read/write buffer on a UnicodeString object with an @@ -3101,13 +3237,13 @@ public: * be modified. * * @return a read-only pointer to the internal string buffer, - * or 0 if the string is empty or bogus + * or nullptr if the string is empty or bogus * * @see getBuffer(int32_t minCapacity) * @see getTerminatedBuffer() * @stable ICU 2.0 */ - inline const UChar *getBuffer() const; + inline ConstChar16Ptr getBuffer() const; /** * Get a read-only pointer to the internal buffer, @@ -3142,7 +3278,7 @@ public: * @see getBuffer() * @stable ICU 2.2 */ - const UChar *getTerminatedBuffer(); + ConstChar16Ptr getTerminatedBuffer(); //======================================== // Constructors @@ -4134,7 +4270,7 @@ UnicodeString::isBufferWritable() const (!(fUnion.fFields.fLengthAndFlags&kRefCounted) || refCount()==1)); } -inline const UChar * +inline ConstChar16Ptr UnicodeString::getBuffer() const { if(fUnion.fFields.fLengthAndFlags&(kIsBogus|kOpenGetBuffer)) { return 0; diff --git a/icu4c/source/common/unistr.cpp b/icu4c/source/common/unistr.cpp index c24d8b7f0a9..a891dec799b 100644 --- a/icu4c/source/common/unistr.cpp +++ b/icu4c/source/common/unistr.cpp @@ -260,9 +260,10 @@ UnicodeString::UnicodeString(const UChar *text, } UnicodeString::UnicodeString(UBool isTerminated, - ConstChar16Ptr text, + ConstChar16Ptr textPtr, int32_t textLength) { fUnion.fFields.fLengthAndFlags = kReadonlyAlias; + const UChar *text = textPtr; if(text == NULL) { // treat as an empty string, do not alias setToEmpty(); @@ -276,7 +277,7 @@ UnicodeString::UnicodeString(UBool isTerminated, // text is terminated, or else it would have failed the above test textLength = u_strlen(text); } - setArray(const_cast(text.get()), textLength, + setArray(const_cast(text), textLength, isTerminated ? textLength + 1 : textLength); } } @@ -916,10 +917,11 @@ UnicodeString::doExtract(int32_t start, } int32_t -UnicodeString::extract(Char16Ptr dest, int32_t destCapacity, +UnicodeString::extract(Char16Ptr destPtr, int32_t destCapacity, UErrorCode &errorCode) const { int32_t len = length(); if(U_SUCCESS(errorCode)) { + UChar *dest = destPtr; if(isBogus() || destCapacity<0 || (destCapacity>0 && dest==0)) { errorCode=U_ILLEGAL_ARGUMENT_ERROR; } else { @@ -1258,7 +1260,7 @@ UnicodeString::unBogus() { } } -const UChar * +ConstChar16Ptr UnicodeString::getTerminatedBuffer() { if(!isWritable()) { return 0; @@ -1292,7 +1294,7 @@ UnicodeString::getTerminatedBuffer() { array[len] = 0; return array; } else { - return NULL; + return nullptr; } } @@ -1756,7 +1758,7 @@ UnicodeString::doHashCode() const // External Buffer //======================================== -UChar * +Char16Ptr UnicodeString::getBuffer(int32_t minCapacity) { if(minCapacity>=-1 && cloneArrayIfNeeded(minCapacity)) { fUnion.fFields.fLengthAndFlags|=kOpenGetBuffer; diff --git a/icu4c/source/extra/uconv/uconv.cpp b/icu4c/source/extra/uconv/uconv.cpp index 3bc807c819d..6aad36b5a9c 100644 --- a/icu4c/source/extra/uconv/uconv.cpp +++ b/icu4c/source/extra/uconv/uconv.cpp @@ -290,7 +290,7 @@ static int printConverters(const char *pname, const char *lookfor, UnicodeString str(name, ""); putchar('\t'); - u_wmsg(stderr, "cantGetAliases", str.getTerminatedBuffer(), + u_wmsg(stderr, "cantGetAliases", str.getTerminatedBuffer().get(), u_wmsg_errorName(err)); goto error_cleanup; } else { @@ -304,7 +304,7 @@ static int printConverters(const char *pname, const char *lookfor, if (U_FAILURE(err)) { UnicodeString str(name, ""); putchar('\t'); - u_wmsg(stderr, "cantGetAliases", str.getTerminatedBuffer(), + u_wmsg(stderr, "cantGetAliases", str.getTerminatedBuffer().get(), u_wmsg_errorName(err)); goto error_cleanup; } @@ -627,7 +627,7 @@ ConvertFile::convertFile(const char *pname, UnicodeString str2(strerror(errno), ""); str2.append((UChar32) 0); initMsg(pname); - u_wmsg(stderr, "cantOpenInputF", str1.getBuffer(), str2.getBuffer()); + u_wmsg(stderr, "cantOpenInputF", str1.getBuffer().get(), str2.getBuffer().get()); return FALSE; } closeFile = TRUE; @@ -672,10 +672,10 @@ ConvertFile::convertFile(const char *pname, UChar linebuf[20], offsetbuf[20]; uprv_itou(linebuf, 20, parse.line, 10, 0); uprv_itou(offsetbuf, 20, parse.offset, 10, 0); - u_wmsg(stderr, "cantCreateTranslitParseErr", str.getTerminatedBuffer(), + u_wmsg(stderr, "cantCreateTranslitParseErr", str.getTerminatedBuffer().get(), u_wmsg_errorName(err), linebuf, offsetbuf); } else { - u_wmsg(stderr, "cantCreateTranslit", str.getTerminatedBuffer(), + u_wmsg(stderr, "cantCreateTranslit", str.getTerminatedBuffer().get(), u_wmsg_errorName(err)); } @@ -698,7 +698,7 @@ ConvertFile::convertFile(const char *pname, if (U_FAILURE(err)) { UnicodeString str(fromcpage, ""); initMsg(pname); - u_wmsg(stderr, "cantOpenFromCodeset", str.getTerminatedBuffer(), + u_wmsg(stderr, "cantOpenFromCodeset", str.getTerminatedBuffer().get(), u_wmsg_errorName(err)); goto error_exit; } @@ -713,7 +713,7 @@ ConvertFile::convertFile(const char *pname, if (U_FAILURE(err)) { UnicodeString str(tocpage, ""); initMsg(pname); - u_wmsg(stderr, "cantOpenToCodeset", str.getTerminatedBuffer(), + u_wmsg(stderr, "cantOpenToCodeset", str.getTerminatedBuffer().get(), u_wmsg_errorName(err)); goto error_exit; } @@ -742,7 +742,7 @@ ConvertFile::convertFile(const char *pname, if (ferror(infile) != 0) { UnicodeString str(strerror(errno)); initMsg(pname); - u_wmsg(stderr, "cantRead", str.getTerminatedBuffer()); + u_wmsg(stderr, "cantRead", str.getTerminatedBuffer().get()); goto error_exit; } @@ -819,8 +819,8 @@ ConvertFile::convertFile(const char *pname, initMsg(pname); u_wmsg(stderr, "problemCvtToU", - UnicodeString(pos, length, "").getTerminatedBuffer(), - str.getTerminatedBuffer(), + UnicodeString(pos, length, "").getTerminatedBuffer().get(), + str.getTerminatedBuffer().get(), u_wmsg_errorName(err)); willexit = TRUE; @@ -1008,10 +1008,10 @@ ConvertFile::convertFile(const char *pname, initMsg(pname); u_wmsg(stderr, errtag, - UnicodeString(pos, length, "").getTerminatedBuffer(), - str.getTerminatedBuffer(), + UnicodeString(pos, length, "").getTerminatedBuffer().get(), + str.getTerminatedBuffer().get(), u_wmsg_errorName(err)); - u_wmsg(stderr, "errorUnicode", str.getTerminatedBuffer()); + u_wmsg(stderr, "errorUnicode", str.getTerminatedBuffer().get()); willexit = TRUE; err = U_ZERO_ERROR; /* reset the error for the rest of the conversion. */ @@ -1026,7 +1026,7 @@ ConvertFile::convertFile(const char *pname, if (wr != outlen) { UnicodeString str(strerror(errno)); initMsg(pname); - u_wmsg(stderr, "cantWrite", str.getTerminatedBuffer()); + u_wmsg(stderr, "cantWrite", str.getTerminatedBuffer().get()); willexit = TRUE; } @@ -1075,7 +1075,7 @@ static void usage(const char *pname, int ecode) { UnicodeString upname(pname, (int32_t)(uprv_strlen(pname) + 1)); UnicodeString mname(msg, msgLen + 1); - res = u_wmsg(fp, "usage", mname.getBuffer(), upname.getBuffer()); + res = u_wmsg(fp, "usage", mname.getBuffer().get(), upname.getBuffer().get()); if (!ecode) { if (!res) { fputc('\n', fp); @@ -1184,7 +1184,7 @@ main(int argc, char **argv) initMsg(pname); UnicodeString str(*iter); initMsg(pname); - u_wmsg(stderr, "badBlockSize", str.getTerminatedBuffer()); + u_wmsg(stderr, "badBlockSize", str.getTerminatedBuffer().get()); return 3; } } else { @@ -1212,7 +1212,7 @@ main(int argc, char **argv) if (U_FAILURE(e) || !printName) { UnicodeString str(*iter); initMsg(pname); - u_wmsg(stderr, "noSuchCodeset", str.getTerminatedBuffer()); + u_wmsg(stderr, "noSuchCodeset", str.getTerminatedBuffer().get()); return 2; } } else @@ -1240,7 +1240,7 @@ main(int argc, char **argv) } else { UnicodeString str(*iter); initMsg(pname); - u_wmsg(stderr, "unknownCallback", str.getTerminatedBuffer()); + u_wmsg(stderr, "unknownCallback", str.getTerminatedBuffer().get()); return 4; } } else { @@ -1256,7 +1256,7 @@ main(int argc, char **argv) } else { UnicodeString str(*iter); initMsg(pname); - u_wmsg(stderr, "unknownCallback", str.getTerminatedBuffer()); + u_wmsg(stderr, "unknownCallback", str.getTerminatedBuffer().get()); return 4; } } else { @@ -1276,7 +1276,7 @@ main(int argc, char **argv) } else { UnicodeString str(*iter); initMsg(pname); - u_wmsg(stderr, "unknownCallback", str.getTerminatedBuffer()); + u_wmsg(stderr, "unknownCallback", str.getTerminatedBuffer().get()); return 4; } } else { @@ -1329,7 +1329,7 @@ main(int argc, char **argv) UnicodeString str2(strerror(errno), ""); initMsg(pname); u_wmsg(stderr, "cantCreateOutputF", - str1.getBuffer(), str2.getBuffer()); + str1.getBuffer().get(), str2.getBuffer().get()); return 1; } } else { diff --git a/icu4c/source/i18n/collationfastlatinbuilder.h b/icu4c/source/i18n/collationfastlatinbuilder.h index 8b63b86815f..ad64d03b75f 100644 --- a/icu4c/source/i18n/collationfastlatinbuilder.h +++ b/icu4c/source/i18n/collationfastlatinbuilder.h @@ -37,7 +37,7 @@ public: UBool forData(const CollationData &data, UErrorCode &errorCode); const uint16_t *getTable() const { - return reinterpret_cast(result.getBuffer()); + return result.getBuffer(); } int32_t lengthOfTable() const { return result.length(); } diff --git a/icu4c/source/test/intltest/dtfmtrtts.cpp b/icu4c/source/test/intltest/dtfmtrtts.cpp index 5bac60ed7db..32f4715df37 100644 --- a/icu4c/source/test/intltest/dtfmtrtts.cpp +++ b/icu4c/source/test/intltest/dtfmtrtts.cpp @@ -121,7 +121,9 @@ void DateFormatRoundTripTest::TestCentury() */ //if (date[1] != date[2] || result[0] != result[1]) { if (date[1] != date[2]) { - errln("Round trip failure: \"%S\" (%f), \"%S\" (%f)", result[0].getBuffer(), date[1], result[1].getBuffer(), date[2]); + errln("Round trip failure: \"%S\" (%f), \"%S\" (%f)", + static_cast(result[0].getBuffer()), date[1], + static_cast(result[1].getBuffer()), date[2]); } } diff --git a/icu4c/source/test/intltest/ustrtest.cpp b/icu4c/source/test/intltest/ustrtest.cpp index afa503bcbf3..429ae325b0c 100644 --- a/icu4c/source/test/intltest/ustrtest.cpp +++ b/icu4c/source/test/intltest/ustrtest.cpp @@ -1087,7 +1087,7 @@ UnicodeStringTest::TestMiscellaneous() } // test releaseBuffer() with a NUL-terminated buffer - test1.getBuffer(20)[2]=0; + test1.getBuffer(20).get()[2]=0; test1.releaseBuffer(); // implicit -1 if(test1.length()!=2 || test1.charAt(0)!=1 || test1.charAt(1) !=2) { errln("UnicodeString::releaseBuffer(-1) does not properly set the length of the UnicodeString"); @@ -1558,7 +1558,10 @@ UnicodeStringTest::TestBogus() { // writable alias to another string's buffer: very bad idea, just convenient for this test test3.setToBogus(); - if(!test3.isBogus() || test3.setTo((UChar *)test1.getBuffer(), test1.length(), test1.getCapacity()).isBogus() || test3!=test1) { + if(!test3.isBogus() || + test3.setTo(const_cast(test1.getBuffer().get()), + test1.length(), test1.getCapacity()).isBogus() || + test3!=test1) { errln("bogus.setTo(writable alias) failed"); } diff --git a/icu4c/source/tools/genrb/reslist.cpp b/icu4c/source/tools/genrb/reslist.cpp index 86c577654f8..8c8ed4162da 100644 --- a/icu4c/source/tools/genrb/reslist.cpp +++ b/icu4c/source/tools/genrb/reslist.cpp @@ -1031,7 +1031,7 @@ void SRBRoot::write(const char *outputDir, const char *outputPkg, if (f16BitUnits.length() <= 1) { // no pool strings to checksum } else if (U_IS_BIG_ENDIAN) { - checksum = computeCRC((const char *)f16BitUnits.getBuffer(), + checksum = computeCRC(reinterpret_cast(f16BitUnits.getBuffer().get()), (uint32_t)f16BitUnits.length() * 2, checksum); } else { // Swap to big-endian so we get the same checksum on all platforms @@ -1039,7 +1039,7 @@ void SRBRoot::write(const char *outputDir, const char *outputPkg, UnicodeString s(f16BitUnits); s.append((UChar)1); // Ensure that we own this buffer. assert(!s.isBogus()); - uint16_t *p = (uint16_t *)s.getBuffer(); + uint16_t *p = const_cast(static_cast(s.getBuffer())); for (int32_t count = f16BitUnits.length(); count > 0; --count) { uint16_t x = *p; *p++ = (uint16_t)((x << 8) | (x >> 8));