beecrypt's c++ api uses jchar arrays for strings, while ICU 59 expects char16_t type In practice these both seem to be defined as short int on amd64 so it might be okay to just reinterpret_cast them? There's probably no easy way out on a platform where char16_t won't match jchar Patch by Valeriy Malov https://bugs.gentoo.org/618676 --- a/c++/io/DataInputStream.cxx +++ b/c++/io/DataInputStream.cxx @@ -201,7 +201,7 @@ String DataInputStream::readUTF() throw (IOException) jchar* buffer = new jchar[ulen+1]; status = U_ZERO_ERROR; - ucnv_toUChars(_utf, buffer, ulen+1, (const char*) data, (jint) utflen, &status); + ucnv_toUChars(_utf, reinterpret_cast(buffer), ulen+1, (const char*) data, (jint) utflen, &status); delete[] data; @@ -232,7 +232,7 @@ String DataInputStream::readLine() throw (IOException) array target_buffer(80); jint target_offset = 0; - UChar* target = target_buffer.data(); + UChar* target = reinterpret_cast(target_buffer.data()); const UChar* target_limit = target+1; char source_buffer[MAX_BYTES_PER_CHARACTER]; const char* source = source_buffer; --- a/c++/io/DataOutputStream.cxx +++ b/c++/io/DataOutputStream.cxx @@ -187,7 +187,7 @@ void DataOutputStream::writeUTF(const String& str) throw (IOException) const array& src = str.toCharArray(); // the expected status code here is U_BUFFER_OVERFLOW_ERROR - jint need = ucnv_fromUChars(_utf, 0, 0, src.data(), src.size(), &status); + jint need = ucnv_fromUChars(_utf, 0, 0, reinterpret_cast(src.data()), src.size(), &status); if (U_FAILURE(status)) if (status != U_BUFFER_OVERFLOW_ERROR) throw IOException("ucnv_fromUChars failed"); @@ -200,7 +200,7 @@ void DataOutputStream::writeUTF(const String& str) throw (IOException) status = U_ZERO_ERROR; // the expected status code here is U_STRING_NOT_TERMINATED_WARNING - ucnv_fromUChars(_utf, (char*) buffer, need, src.data(), src.size(), &status); + ucnv_fromUChars(_utf, (char*) buffer, need, reinterpret_cast(src.data()), src.size(), &status); if (status != U_STRING_NOT_TERMINATED_WARNING) { delete[] buffer; --- a/c++/io/PrintStream.cxx +++ b/c++/io/PrintStream.cxx @@ -191,7 +191,7 @@ void PrintStream::print(jchar ch) throw () UErrorCode status = U_ZERO_ERROR; // do conversion of one character - size_t used = ucnv_fromUChars(_loc, buffer, 8, &ch, 1, &status); + size_t used = ucnv_fromUChars(_loc, buffer, 8, reinterpret_cast(&ch), 1, &status); if (U_FAILURE(status)) throw IOException("failure in ucnv_fromUChars"); @@ -268,14 +268,14 @@ void PrintStream::print(jlong x) throw () void PrintStream::print(const array& chars) throw () { - print(chars.data(), chars.size()); + print(reinterpret_cast(chars.data()), chars.size()); } void PrintStream::print(const String& str) throw () { const array& tmp = str.toCharArray(); - print(tmp.data(), tmp.size()); + print(reinterpret_cast(tmp.data()), tmp.size()); } void PrintStream::println() throw () --- a/c++/lang/String.cxx +++ b/c++/lang/String.cxx @@ -33,6 +33,8 @@ using namespace beecrypt::lang; #include #include +static_assert(sizeof(jchar) == sizeof(UChar), "jchar and UChar sizes mismatch"); + String::String(array& swapWith) { assert(swapWith.size() <= Integer::MAX_VALUE); @@ -56,7 +58,7 @@ String::String() String::String(char c) : _value(1) { - u_charsToUChars(&c, _value.data(), 1); + u_charsToUChars(&c, reinterpret_cast(_value.data()), 1); } String::String(jchar c) : _value(&c, 1) @@ -67,7 +69,7 @@ String::String(const char* value) : _value(::strlen(value)) { assert(_value.size() <= Integer::MAX_VALUE); - u_charsToUChars(value, _value.data(), _value.size()); + u_charsToUChars(value, reinterpret_cast(_value.data()), _value.size()); } String::String(const jchar* value, int offset, int length) : _value(value+offset, length) @@ -449,7 +451,7 @@ std::ostream& beecrypt::lang::operator<<(std::ostream& stream, const String& str if (U_FAILURE(status)) throw RuntimeException("ucnv_open failed"); - int need = ucnv_fromUChars(loc, 0, 0, src.data(), src.size(), &status); + int need = ucnv_fromUChars(loc, 0, 0, reinterpret_cast(src.data()), src.size(), &status); if (U_FAILURE(status)) if (status != U_BUFFER_OVERFLOW_ERROR) throw RuntimeException("ucnv_fromUChars failed"); @@ -458,7 +460,7 @@ std::ostream& beecrypt::lang::operator<<(std::ostream& stream, const String& str status = U_ZERO_ERROR; - ucnv_fromUChars(loc, out, need+1, src.data(), src.size(), &status); + ucnv_fromUChars(loc, out, need+1, reinterpret_cast(src.data()), src.size(), &status); if (U_FAILURE(status)) throw RuntimeException("ucnv_fromUChars failed"); --- a/c++/lang/StringBuffer.cxx +++ b/c++/lang/StringBuffer.cxx @@ -35,7 +35,7 @@ StringBuffer::StringBuffer() : _buffer(16) StringBuffer::StringBuffer(const char* s) : _buffer(16 + strlen(s)) { - u_charsToUChars(s, _buffer.data(), _used = strlen(s)); + u_charsToUChars(s, reinterpret_cast(_buffer.data()), _used = strlen(s)); } StringBuffer::StringBuffer(const String& s) : _buffer(16 + s._value.size()) @@ -53,7 +53,7 @@ StringBuffer& StringBuffer::append(char c) synchronized (this) { core_ensureCapacity(_used+1); - u_charsToUChars(&c, _buffer.data() + _used++, 1); + u_charsToUChars(&c, reinterpret_cast(_buffer.data() + _used++), 1); } return *this; } @@ -88,7 +88,7 @@ StringBuffer& StringBuffer::append(const char* s) jint need = strlen(s); core_ensureCapacity(_used + need); - u_charsToUChars(s, _buffer.data() + _used, need); + u_charsToUChars(s, reinterpret_cast(_buffer.data() + _used), need); _used += need; } --- a/c++/lang/StringBuilder.cxx +++ b/c++/lang/StringBuilder.cxx @@ -38,7 +38,7 @@ StringBuilder::StringBuilder() : _buffer(16) StringBuilder::StringBuilder(const char* s) : _buffer(16 + strlen(s)) { - u_charsToUChars(s, _buffer.data(), _used = strlen(s)); + u_charsToUChars(s, reinterpret_cast(_buffer.data()), _used = strlen(s)); } StringBuilder::StringBuilder(const String& s) : _buffer(16 + s._value.size()) @@ -55,7 +55,7 @@ StringBuilder& StringBuilder::append(char c) { ensureCapacity(_used+1); - u_charsToUChars(&c, _buffer.data() + _used++, 1); + u_charsToUChars(&c, reinterpret_cast(_buffer.data() + _used++), 1); return *this; } @@ -97,7 +97,7 @@ StringBuilder& StringBuilder::append(const char* s) ensureCapacity(_used + need); - u_charsToUChars(s, _buffer.data() + _used, need); + u_charsToUChars(s, reinterpret_cast(_buffer.data() + _used), need); _used += need; --- a/c++/security/Provider.cxx +++ b/c++/security/Provider.cxx @@ -90,7 +90,7 @@ Object* Provider::setProperty(const String& key, const String& value) UErrorCode status = U_ZERO_ERROR; - ucnv_fromUChars(_conv, symname, 1024, src.data(), src.size(), &status); + ucnv_fromUChars(_conv, symname, 1024, reinterpret_cast(src.data()), src.size(), &status); if (status != U_ZERO_ERROR) throw RuntimeException("error in ucnv_fromUChars"); --- a/c++/security/Security.cxx +++ b/c++/security/Security.cxx @@ -104,7 +104,7 @@ void Security::initialize() const array& src = value->toCharArray(); - int need = ucnv_fromUChars(_loc, 0, 0, src.data(), src.size(), &status); + int need = ucnv_fromUChars(_loc, 0, 0, reinterpret_cast(src.data()), src.size(), &status); if (U_FAILURE(status)) if (status != U_BUFFER_OVERFLOW_ERROR) throw RuntimeException("ucnv_fromUChars failed"); @@ -112,7 +112,7 @@ void Security::initialize() char* shared_library = new char[need+1]; status = U_ZERO_ERROR; - ucnv_fromUChars(_loc, shared_library, need+1, src.data(), src.size(), &status); + ucnv_fromUChars(_loc, shared_library, need+1, reinterpret_cast(src.data()), src.size(), &status); if (U_FAILURE(status)) throw RuntimeException("ucnv_fromUChars failed");