From 1161c5817059464ab511632c0ce5d14593ced1a3 Mon Sep 17 00:00:00 2001 From: Jose Date: Fri, 2 May 2014 19:56:38 +0200 Subject: ICE-4851 - Use wstrings for input and output data that contain non-ASCII characters? --- cpp/src/Freeze/EvictorI.cpp | 9 +- cpp/src/Freeze/IndexI.cpp | 11 +- cpp/src/Freeze/MapDb.cpp | 16 +- cpp/src/Freeze/MapI.cpp | 19 +- cpp/src/Freeze/ObjectStore.cpp | 10 +- cpp/src/Freeze/SharedDbEnv.cpp | 7 +- cpp/src/FreezeScript/DumpDB.cpp | 8 - cpp/src/FreezeScript/transformdb.cpp | 7 - cpp/src/Glacier2/Glacier2Router.cpp | 4 - cpp/src/Ice/Application.cpp | 18 +- cpp/src/Ice/BasicStream.cpp | 213 ++++++----- cpp/src/Ice/DynamicLibrary.cpp | 15 +- cpp/src/Ice/Exception.cpp | 7 +- cpp/src/Ice/Initialize.cpp | 34 +- cpp/src/Ice/Instance.cpp | 74 ++-- cpp/src/Ice/Instance.h | 11 +- cpp/src/Ice/LoggerI.cpp | 117 +++++- cpp/src/Ice/LoggerI.h | 7 +- cpp/src/Ice/Makefile | 4 +- cpp/src/Ice/Makefile.mak | 2 +- cpp/src/Ice/Network.cpp | 60 +++- cpp/src/Ice/PluginManagerI.cpp | 2 +- cpp/src/Ice/PropertiesI.cpp | 27 +- cpp/src/Ice/PropertiesI.h | 16 +- cpp/src/Ice/PropertyNames.cpp | 3 +- cpp/src/Ice/PropertyNames.h | 2 +- cpp/src/Ice/Reference.cpp | 4 +- cpp/src/Ice/ReferenceFactory.cpp | 4 +- cpp/src/Ice/ServantManager.cpp | 4 +- cpp/src/Ice/Service.cpp | 92 +++-- cpp/src/Ice/StringConverter.cpp | 452 ----------------------- cpp/src/Ice/StringConverterPlugin.cpp | 179 +++++++++ cpp/src/Ice/StringConverterPlugin.h | 44 +++ cpp/src/Ice/ThreadPool.cpp | 7 +- cpp/src/IceBox/ServiceManagerI.cpp | 3 +- cpp/src/IceGrid/Activator.cpp | 31 +- cpp/src/IceGrid/IceGridNode.cpp | 6 +- cpp/src/IceGrid/RegistryI.cpp | 4 - cpp/src/IceGrid/ServerI.cpp | 4 +- cpp/src/IcePatch2Lib/ClientUtil.cpp | 11 +- cpp/src/IcePatch2Lib/Util.cpp | 8 +- cpp/src/IceSSL/Instance.cpp | 6 +- cpp/src/IceUtil/Exception.cpp | 60 +++- cpp/src/IceUtil/FileUtil.cpp | 115 +++++- cpp/src/IceUtil/Makefile | 5 +- cpp/src/IceUtil/Makefile.mak | 3 +- cpp/src/IceUtil/StringConverter.cpp | 478 +++++++++++++++++++++++++ cpp/src/IceUtil/StringUtil.cpp | 6 +- cpp/src/Slice/Preprocessor.cpp | 7 +- cpp/src/iceserviceinstall/ServiceInstaller.cpp | 86 +++-- cpp/src/slice2cpp/Gen.cpp | 2 +- 51 files changed, 1509 insertions(+), 815 deletions(-) delete mode 100644 cpp/src/Ice/StringConverter.cpp create mode 100644 cpp/src/Ice/StringConverterPlugin.cpp create mode 100644 cpp/src/Ice/StringConverterPlugin.h create mode 100644 cpp/src/IceUtil/StringConverter.cpp (limited to 'cpp/src') diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp index 0a5a5918515..c7caa0b9f1d 100644 --- a/cpp/src/Freeze/EvictorI.cpp +++ b/cpp/src/Freeze/EvictorI.cpp @@ -15,13 +15,14 @@ #include -#include +#include #include using namespace std; using namespace Freeze; using namespace Ice; +using namespace IceUtil; // // Static members @@ -317,7 +318,11 @@ Freeze::EvictorIBase::allDbs() const { Db db(_dbEnv->getEnv(), 0); - db.open(0, Ice::nativeToUTF8(_communicator, _filename).c_str(), 0, DB_UNKNOWN, DB_RDONLY, 0); + // + // Berkeley DB expects file paths to be UTF8 encoded. + // + db.open(0, nativeToUTF8(IceUtil::getProcessStringConverter(), _filename).c_str(), 0, DB_UNKNOWN, + DB_RDONLY, 0); Dbc* dbc = 0; db.cursor(0, &dbc, 0); diff --git a/cpp/src/Freeze/IndexI.cpp b/cpp/src/Freeze/IndexI.cpp index 3c05f862ee2..21231e707ca 100644 --- a/cpp/src/Freeze/IndexI.cpp +++ b/cpp/src/Freeze/IndexI.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include using namespace Freeze; using namespace Ice; @@ -379,13 +379,16 @@ Freeze::IndexI::associate(ObjectStoreBase* store, DbTxn* txn, } // - // We keep _dbName as a native string here, while it might have + // + // Berkeley DB expects file paths to be UTF8 encoded. We keep + // _dbName as a native string here, while it might have // been better to convert it to UTF-8, changing this isn't // possible without potentially breaking backward compatibility // with deployed databases. // - _db->open(txn, Ice::nativeToUTF8(store->communicator(), store->evictor()->filename()).c_str(), _dbName.c_str(), - DB_BTREE, flags, FREEZE_DB_MODE); + _db->open(txn, + IceUtil::nativeToUTF8(IceUtil::getProcessStringConverter(), store->evictor()->filename()).c_str(), + _dbName.c_str(), DB_BTREE, flags, FREEZE_DB_MODE); flags = 0; if(populateIndex) diff --git a/cpp/src/Freeze/MapDb.cpp b/cpp/src/Freeze/MapDb.cpp index 48ccb6ec75b..cb06a456596 100644 --- a/cpp/src/Freeze/MapDb.cpp +++ b/cpp/src/Freeze/MapDb.cpp @@ -14,10 +14,11 @@ #include #include -#include +#include using namespace std; using namespace Ice; +using namespace IceUtil; using namespace Freeze; namespace @@ -184,8 +185,11 @@ Freeze::MapDb::MapDb(const ConnectionIPtr& connection, flags |= DB_CREATE; } - open(txn, Ice::nativeToUTF8(_communicator, _dbName).c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); - + // + // Berkeley DB expects file paths to be UTF8 encoded. + // + open(txn, nativeToUTF8(getProcessStringConverter(), _dbName).c_str(), 0, DB_BTREE, + flags, FREEZE_DB_MODE); StringSeq oldIndices; StringSeq newIndices; @@ -435,7 +439,11 @@ Freeze::MapDb::MapDb(const Ice::CommunicatorPtr& communicator, u_int32_t flags = DB_THREAD | DB_CREATE | DB_AUTO_COMMIT; - open(0, Ice::nativeToUTF8(_communicator, _dbName).c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); + // + // Berkeley DB expects file paths to be UTF8 encoded. + // + open(0, nativeToUTF8(getProcessStringConverter(), _dbName).c_str(), 0, DB_BTREE, flags, + FREEZE_DB_MODE); } catch(const ::DbException& dx) { diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp index 3b2f20389b9..15e24028837 100644 --- a/cpp/src/Freeze/MapI.cpp +++ b/cpp/src/Freeze/MapI.cpp @@ -15,10 +15,9 @@ #include #include #include +#include #include -#include - using namespace std; using namespace Ice; using namespace Freeze; @@ -202,8 +201,12 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, Db oldDb(connectionI->dbEnv()->getEnv(), 0); - oldDb.open(txn, Ice::nativeToUTF8(connectionI->communicator(), oldDbName).c_str(), 0, DB_BTREE, - DB_THREAD, FREEZE_DB_MODE); + // + // Berkeley DB expects file paths to be UTF8 encoded. + // + oldDb.open(txn, + IceUtil::nativeToUTF8(IceUtil::getProcessStringConverter(), oldDbName).c_str(), + 0, DB_BTREE, DB_THREAD, FREEZE_DB_MODE); IceUtil::UniquePtr newDb(new MapDb(connectionI, dbName, key, value, keyCompare, indices, true)); @@ -1773,8 +1776,12 @@ Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db, out << "Opening index \"" << _dbName << "\""; } - _db->open(txn, Ice::nativeToUTF8(connection->communicator(), _dbName).c_str(), 0, DB_BTREE, flags, - FREEZE_DB_MODE); + // + // Berkeley DB expects file paths to be UTF8 encoded. + // + _db->open(txn, + IceUtil::nativeToUTF8(IceUtil::getProcessStringConverter(), _dbName).c_str(), + 0, DB_BTREE, flags, FREEZE_DB_MODE); // // To populate empty indices diff --git a/cpp/src/Freeze/ObjectStore.cpp b/cpp/src/Freeze/ObjectStore.cpp index 87aebc64f16..90756adba5e 100644 --- a/cpp/src/Freeze/ObjectStore.cpp +++ b/cpp/src/Freeze/ObjectStore.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include using namespace std; using namespace Ice; @@ -132,13 +132,15 @@ Freeze::ObjectStoreBase::ObjectStoreBase(const string& facet, const string& face } // - // We keep _dbName as a native string here, while it might have + // Berkeley DB expects file paths to be UTF8 encoded. We keep + // _dbName as a native string here, while it might have // been better to convert it to UTF-8, changing this isn't // possible without potentially breaking backward compatibility // with deployed databases. // - _db->open(txn, Ice::nativeToUTF8(evictor->communicator(), evictor->filename()).c_str(), _dbName.c_str(), - DB_BTREE, flags, FREEZE_DB_MODE); + _db->open(txn, + IceUtil::nativeToUTF8(IceUtil::getProcessStringConverter(), evictor->filename()).c_str(), + _dbName.c_str(), DB_BTREE, flags, FREEZE_DB_MODE); for(size_t i = 0; i < _indices.size(); ++i) { diff --git a/cpp/src/Freeze/SharedDbEnv.cpp b/cpp/src/Freeze/SharedDbEnv.cpp index 597682a6221..394d03b850d 100644 --- a/cpp/src/Freeze/SharedDbEnv.cpp +++ b/cpp/src/Freeze/SharedDbEnv.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include @@ -591,7 +591,10 @@ Freeze::SharedDbEnv::SharedDbEnv(const std::string& envName, // flags |= DB_THREAD; - _env->open(Ice::nativeToUTF8(_communicator, dbHome).c_str(), flags, FREEZE_DB_MODE); + // + // Berkeley DB expects file paths to be UTF8 encoded. + // + _env->open(nativeToUTF8(getProcessStringConverter(), dbHome).c_str(), flags, FREEZE_DB_MODE); // // Default checkpoint period is every 120 seconds diff --git a/cpp/src/FreezeScript/DumpDB.cpp b/cpp/src/FreezeScript/DumpDB.cpp index f1eb24508c0..736f22e0d9d 100644 --- a/cpp/src/FreezeScript/DumpDB.cpp +++ b/cpp/src/FreezeScript/DumpDB.cpp @@ -452,10 +452,6 @@ run(const Ice::StringSeq& originalArgs, const Ice::CommunicatorPtr& communicator if(!outputFile.empty()) { - // - // No nativeToUTF8 conversion necessary here, no string converter is installed - // by wmain() on Windows and args are assumbed to be UTF8 on Unix platforms. - // IceUtilInternal::ofstream of(outputFile); if(!of.good()) { @@ -469,10 +465,6 @@ run(const Ice::StringSeq& originalArgs, const Ice::CommunicatorPtr& communicator } else { - // - // No nativeToUTF8 conversion necessary here, no string converter is installed - // by wmain() on Windows and args are assumbed to be UTF8 on Unix platforms. - // IceUtilInternal::ifstream in(inputFile); char buff[1024]; while(true) diff --git a/cpp/src/FreezeScript/transformdb.cpp b/cpp/src/FreezeScript/transformdb.cpp index 065fb73e307..7021e125e91 100644 --- a/cpp/src/FreezeScript/transformdb.cpp +++ b/cpp/src/FreezeScript/transformdb.cpp @@ -724,10 +724,6 @@ run(const Ice::StringSeq& originalArgs, const Ice::CommunicatorPtr& communicator if(!outputFile.empty()) { - // - // No nativeToUTF8 conversion necessary here, no string converter is installed - // by wmain() on Windows and args are assumbed to be UTF8 on Unix platforms. - // IceUtilInternal::ofstream of(outputFile); if(!of.good()) { @@ -744,9 +740,6 @@ run(const Ice::StringSeq& originalArgs, const Ice::CommunicatorPtr& communicator // // Read the input file. // - // No nativeToUTF8 conversion necessary here, no string converter is installed - // by wmain() on Windows and args are assumbed to be UTF8 on Unix platforms. - // IceUtilInternal::ifstream in(inputFile); char buff[1024]; while(true) diff --git a/cpp/src/Glacier2/Glacier2Router.cpp b/cpp/src/Glacier2/Glacier2Router.cpp index 4a1d69da9eb..81db7b84407 100644 --- a/cpp/src/Glacier2/Glacier2Router.cpp +++ b/cpp/src/Glacier2/Glacier2Router.cpp @@ -236,10 +236,6 @@ Glacier2::RouterService::start(int argc, char* argv[], int& status) } else if(!passwordsProperty.empty()) { - // - // No nativeToUTF8 conversion necessary here, since no string - // converter is installed by Glacier2 the string is UTF-8. - // IceUtilInternal::ifstream passwordFile(passwordsProperty); if(!passwordFile) diff --git a/cpp/src/Ice/Application.cpp b/cpp/src/Ice/Application.cpp index 39175648f73..1519683d440 100644 --- a/cpp/src/Ice/Application.cpp +++ b/cpp/src/Ice/Application.cpp @@ -316,7 +316,7 @@ Ice::Application::main(int argc, char* argv[], const char* configFile) if(argc > 0 && argv[0] && LoggerIPtr::dynamicCast(getProcessLogger())) { - setProcessLogger(new LoggerI(argv[0], "")); + setProcessLogger(new LoggerI(argv[0], "", true, IceUtil::getProcessStringConverter())); } InitializationData initData; @@ -358,7 +358,7 @@ Ice::Application::main(int argc, wchar_t* argv[], const Ice::InitializationData& // On Windows the given wchar_t* strings are UTF16 and therefore // needs to be converted to native narow string encoding. // - return main(argsToStringSeq(argc, argv, initData.stringConverter), initData); + return main(argsToStringSeq(argc, argv), initData); } #endif @@ -368,7 +368,10 @@ Ice::Application::main(int argc, char* argv[], const InitializationData& initial { if(argc > 0 && argv[0] && LoggerIPtr::dynamicCast(getProcessLogger())) { - setProcessLogger(new LoggerI(argv[0], "")); + const bool convert = initializationData.properties ? + initializationData.properties->getPropertyAsIntWithDefault("Ice.LogStdErr.Convert", 1) == 1 && + initializationData.properties->getProperty("Ice.StdErr").empty() : true; + setProcessLogger(new LoggerI(argv[0], "", convert, IceUtil::getProcessStringConverter())); } if(IceInternal::Application::_communicator != 0) @@ -385,7 +388,7 @@ Ice::Application::main(int argc, char* argv[], const InitializationData& initial InitializationData initData = initializationData; try { - initData.properties = createProperties(argc, argv, initData.properties, initData.stringConverter); + initData.properties = createProperties(argc, argv, initData.properties); } catch(const std::exception& ex) { @@ -656,7 +659,12 @@ Ice::Application::doMain(int argc, char* argv[], const InitializationData& initD // if(initData.properties->getProperty("Ice.ProgramName") != "" && LoggerIPtr::dynamicCast(getProcessLogger())) { - setProcessLogger(new LoggerI(initData.properties->getProperty("Ice.ProgramName"), "")); + const bool convert = + initData.properties->getPropertyAsIntWithDefault("Ice.LogStdErr.Convert", 1) == 1 && + initData.properties->getProperty("Ice.StdErr").empty(); + + setProcessLogger(new LoggerI(initData.properties->getProperty("Ice.ProgramName"), "", convert, + IceUtil::getProcessStringConverter())); } IceInternal::Application::_communicator = initialize(argc, argv, initData); diff --git a/cpp/src/Ice/BasicStream.cpp b/cpp/src/Ice/BasicStream.cpp index 543ccb3144d..580cd342839 100644 --- a/cpp/src/Ice/BasicStream.cpp +++ b/cpp/src/Ice/BasicStream.cpp @@ -24,8 +24,7 @@ #include #include #include -#include -#include +#include #include using namespace std; @@ -35,7 +34,7 @@ using namespace IceInternal; namespace { -class StreamUTF8BufferI : public Ice::UTF8Buffer +class StreamUTF8BufferI : public IceUtil::UTF8Buffer { public: @@ -99,8 +98,8 @@ IceInternal::BasicStream::BasicStream(Instance* instance, const EncodingVersion& _sliceObjects(true), _messageSizeMax(_instance->messageSizeMax()), // Cached for efficiency. _unlimited(unlimited), - _stringConverter(instance->initializationData().stringConverter), - _wstringConverter(instance->initializationData().wstringConverter), + _stringConverter(instance->getStringConverter()), + _wstringConverter(instance->getWstringConverter()), _startSeq(-1), _sizePos(-1) { @@ -123,8 +122,8 @@ IceInternal::BasicStream::BasicStream(Instance* instance, const EncodingVersion& _sliceObjects(true), _messageSizeMax(_instance->messageSizeMax()), // Cached for efficiency. _unlimited(false), - _stringConverter(instance->initializationData().stringConverter), - _wstringConverter(instance->initializationData().wstringConverter), + _stringConverter(instance->getStringConverter()), + _wstringConverter(instance->getWstringConverter()), _startSeq(-1), _sizePos(-1) { @@ -1358,54 +1357,60 @@ IceInternal::BasicStream::writeConverted(const string& v) // Impossible to tell, so we guess. If we don't guess correctly, // we'll have to fix the mistake afterwards // - - Int guessedSize = static_cast(v.size()); - writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space. - - size_t firstIndex = b.size(); - StreamUTF8BufferI buffer(*this); - - Byte* lastByte = _stringConverter->toUTF8(v.data(), v.data() + v.size(), buffer); - if(lastByte != b.end()) - { - b.resize(lastByte - b.begin()); - } - size_t lastIndex = b.size(); - - Int actualSize = static_cast(lastIndex - firstIndex); - - // - // Check against the guess - // - if(guessedSize != actualSize) + try { - if(guessedSize <= 254 && actualSize > 254) - { - // - // Move the UTF-8 sequence 4 bytes further - // Use memmove instead of memcpy since the source and destination typically overlap. - // - resize(b.size() + 4); - memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, actualSize); - } - else if(guessedSize > 254 && actualSize <= 254) - { - // - // Move the UTF-8 sequence 4 bytes back - // - memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, actualSize); - resize(b.size() - 4); - } - - if(guessedSize <= 254) + Int guessedSize = static_cast(v.size()); + writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space. + + size_t firstIndex = b.size(); + StreamUTF8BufferI buffer(*this); + + Byte* lastByte = _stringConverter->toUTF8(v.data(), v.data() + v.size(), buffer); + if(lastByte != b.end()) { - rewriteSize(actualSize, b.begin() + firstIndex - 1); + b.resize(lastByte - b.begin()); } - else + size_t lastIndex = b.size(); + + Int actualSize = static_cast(lastIndex - firstIndex); + + // + // Check against the guess + // + if(guessedSize != actualSize) { - rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4); + if(guessedSize <= 254 && actualSize > 254) + { + // + // Move the UTF-8 sequence 4 bytes further + // Use memmove instead of memcpy since the source and destination typically overlap. + // + resize(b.size() + 4); + memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, actualSize); + } + else if(guessedSize > 254 && actualSize <= 254) + { + // + // Move the UTF-8 sequence 4 bytes back + // + memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, actualSize); + resize(b.size() - 4); + } + + if(guessedSize <= 254) + { + rewriteSize(actualSize, b.begin() + firstIndex - 1); + } + else + { + rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4); + } } } + catch(const IceUtil::IllegalConversionException& ex) + { + throw StringConversionException(__FILE__, __LINE__, ex.reason()); + } } void @@ -1425,7 +1430,14 @@ IceInternal::BasicStream::write(const string* begin, const string* end, bool con void IceInternal::BasicStream::readConverted(string& v, int sz) { - _stringConverter->fromUTF8(i, i + sz, v); + try + { + _stringConverter->fromUTF8(i, i + sz, v); + } + catch(const IceUtil::IllegalConversionException& ex) + { + throw StringConversionException(__FILE__, __LINE__, ex.reason()); + } } void @@ -1460,54 +1472,60 @@ IceInternal::BasicStream::write(const wstring& v) // Impossible to tell, so we guess. If we don't guess correctly, // we'll have to fix the mistake afterwards // - - Int guessedSize = static_cast(v.size()); - writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space. - - size_t firstIndex = b.size(); - StreamUTF8BufferI buffer(*this); - - Byte* lastByte = _wstringConverter->toUTF8(v.data(), v.data() + v.size(), buffer); - if(lastByte != b.end()) - { - b.resize(lastByte - b.begin()); - } - size_t lastIndex = b.size(); - - Int actualSize = static_cast(lastIndex - firstIndex); - - // - // Check against the guess - // - if(guessedSize != actualSize) + try { - if(guessedSize <= 254 && actualSize > 254) - { - // - // Move the UTF-8 sequence 4 bytes further - // Use memmove instead of memcpy since the source and destination typically overlap. - // - resize(b.size() + 4); - memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, actualSize); - } - else if(guessedSize > 254 && actualSize <= 254) - { - // - // Move the UTF-8 sequence 4 bytes back - // - memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, actualSize); - resize(b.size() - 4); - } - - if(guessedSize <= 254) + Int guessedSize = static_cast(v.size()); + writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space. + + size_t firstIndex = b.size(); + StreamUTF8BufferI buffer(*this); + + Byte* lastByte = _wstringConverter->toUTF8(v.data(), v.data() + v.size(), buffer); + if(lastByte != b.end()) { - rewriteSize(actualSize, b.begin() + firstIndex - 1); + b.resize(lastByte - b.begin()); } - else + size_t lastIndex = b.size(); + + Int actualSize = static_cast(lastIndex - firstIndex); + + // + // Check against the guess + // + if(guessedSize != actualSize) { - rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4); + if(guessedSize <= 254 && actualSize > 254) + { + // + // Move the UTF-8 sequence 4 bytes further + // Use memmove instead of memcpy since the source and destination typically overlap. + // + resize(b.size() + 4); + memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, actualSize); + } + else if(guessedSize > 254 && actualSize <= 254) + { + // + // Move the UTF-8 sequence 4 bytes back + // + memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, actualSize); + resize(b.size() - 4); + } + + if(guessedSize <= 254) + { + rewriteSize(actualSize, b.begin() + firstIndex - 1); + } + else + { + rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4); + } } } + catch(const IceUtil::IllegalConversionException& ex) + { + throw StringConversionException(__FILE__, __LINE__, ex.reason()); + } } void @@ -1535,8 +1553,15 @@ IceInternal::BasicStream::read(wstring& v) throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); } - _wstringConverter->fromUTF8(i, i + sz, v); - i += sz; + try + { + _wstringConverter->fromUTF8(i, i + sz, v); + i += sz; + } + catch(const IceUtil::IllegalConversionException& ex) + { + throw StringConversionException(__FILE__, __LINE__, ex.reason()); + } } else { diff --git a/cpp/src/Ice/DynamicLibrary.cpp b/cpp/src/Ice/DynamicLibrary.cpp index de114ba985b..1fa6c86ad73 100644 --- a/cpp/src/Ice/DynamicLibrary.cpp +++ b/cpp/src/Ice/DynamicLibrary.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #ifndef _WIN32 # include @@ -22,9 +22,8 @@ using namespace std; IceUtil::Shared* IceInternal::upCast(DynamicLibrary* p) { return p; } IceUtil::Shared* IceInternal::upCast(DynamicLibraryList* p) { return p; } -IceInternal::DynamicLibrary::DynamicLibrary(const Ice::StringConverterPtr& stringConverter) : - _hnd(0), - _stringConverter(stringConverter) +IceInternal::DynamicLibrary::DynamicLibrary() : + _hnd(0) { } @@ -198,10 +197,14 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc bool IceInternal::DynamicLibrary::load(const string& lib) { + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // #ifdef ICE_OS_WINRT - _hnd = LoadPackagedLibrary(IceUtil::stringToWstring(nativeToUTF8(_stringConverter, lib)).c_str(), 0); + _hnd = LoadPackagedLibrary(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, lib).c_str(), 0); #elif defined(_WIN32) - _hnd = LoadLibraryW(IceUtil::stringToWstring(nativeToUTF8(_stringConverter, lib)).c_str()); + _hnd = LoadLibraryW(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, lib).c_str()); #else int flags = RTLD_NOW | RTLD_GLOBAL; diff --git a/cpp/src/Ice/Exception.cpp b/cpp/src/Ice/Exception.cpp index 267a83e34b8..d503e480eb2 100644 --- a/cpp/src/Ice/Exception.cpp +++ b/cpp/src/Ice/Exception.cpp @@ -44,7 +44,12 @@ socketErrorToString(int error) } else { - return IceUtil::wstringToString( + // + // Don't need to use a wide string converter as the wide string come + // from Windows API. + // + return IceUtil::wnativeToNative( + IceUtil::getProcessStringConverter(), 0, static_cast(error).ToString()->Data()); } #else diff --git a/cpp/src/Ice/Initialize.cpp b/cpp/src/Ice/Initialize.cpp index 1b2710c525d..bb54e11c537 100644 --- a/cpp/src/Ice/Initialize.cpp +++ b/cpp/src/Ice/Initialize.cpp @@ -27,6 +27,7 @@ #include #include #include +#include using namespace std; using namespace Ice; @@ -80,20 +81,17 @@ Ice::argsToStringSeq(int argc, char* argv[]) #ifdef _WIN32 StringSeq -Ice::argsToStringSeq(int argc, wchar_t* argv[]) -{ - return argsToStringSeq(argc, argv, 0); -} - -StringSeq -Ice::argsToStringSeq(int /*argc*/, wchar_t* argv[], const StringConverterPtr& converter) +Ice::argsToStringSeq(int /*argc*/, wchar_t* argv[]) { + // + // Don't need to use a wide string converter argv is expected to + // come from Windows API. + // + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); StringSeq args; for(int i=0; argv[i] != 0; i++) { - string value = IceUtil::wstringToString(argv[i]); - value = Ice::UTF8ToNative(converter, value); - args.push_back(value); + args.push_back(IceUtil::wnativeToNative(converter, 0, argv[i])); } return args; } @@ -138,22 +136,22 @@ Ice::stringSeqToArgs(const StringSeq& args, int& argc, char* argv[]) } PropertiesPtr -Ice::createProperties(const StringConverterPtr& converter) +Ice::createProperties() { - return new PropertiesI(converter); + return new PropertiesI(IceUtil::getProcessStringConverter()); } PropertiesPtr -Ice::createProperties(StringSeq& args, const PropertiesPtr& defaults, const StringConverterPtr& converter) +Ice::createProperties(StringSeq& args, const PropertiesPtr& defaults) { - return new PropertiesI(args, defaults, converter); + return new PropertiesI(args, defaults, IceUtil::getProcessStringConverter()); } PropertiesPtr -Ice::createProperties(int& argc, char* argv[], const PropertiesPtr& defaults, const StringConverterPtr& converter) +Ice::createProperties(int& argc, char* argv[], const PropertiesPtr& defaults) { StringSeq args = argsToStringSeq(argc, argv); - PropertiesPtr properties = createProperties(args, defaults, converter); + PropertiesPtr properties = createProperties(args, defaults); stringSeqToArgs(args, argc, argv); return properties; } @@ -233,7 +231,7 @@ Ice::initialize(int& argc, char* argv[], const InitializationData& initializatio checkIceVersion(version); InitializationData initData = initializationData; - initData.properties = createProperties(argc, argv, initData.properties, initData.stringConverter); + initData.properties = createProperties(argc, argv, initData.properties); CommunicatorI* communicatorI = new CommunicatorI(initData); CommunicatorPtr result = communicatorI; // For exception safety. @@ -366,7 +364,7 @@ Ice::getProcessLogger() // // TODO: Would be nice to be able to use process name as prefix by default. // - processLogger = new Ice::LoggerI("", ""); + processLogger = new Ice::LoggerI("", "", true, IceUtil::getProcessStringConverter()); } return processLogger; } diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index b407284e2a9..9550e536180 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -513,8 +513,8 @@ IceInternal::Instance::stringToIdentity(const string& s) const } } - ident.name = Ice::UTF8ToNative(_initData.stringConverter, ident.name); - ident.category = Ice::UTF8ToNative(_initData.stringConverter, ident.category); + ident.name = UTF8ToNative(_stringConverter, ident.name); + ident.category = UTF8ToNative(_stringConverter, ident.category); return ident; } @@ -526,8 +526,8 @@ IceInternal::Instance::identityToString(const Identity& ident) const // This method returns the stringified identity. The returned string only // contains printable ascii. It can contain UTF8 in the escaped form. // - string name = Ice::nativeToUTF8(_initData.stringConverter, ident.name); - string category = Ice::nativeToUTF8(_initData.stringConverter, ident.category); + string name = nativeToUTF8(_stringConverter, ident.name); + string category = nativeToUTF8(_stringConverter, ident.category); if(category.empty()) { @@ -788,21 +788,28 @@ IceInternal::Instance::setDefaultRouter(const Ice::RouterPrx& defaultRouter) } void -IceInternal::Instance::setStringConverter(const Ice::StringConverterPtr& stringConverter) +IceInternal::Instance::setStringConverter(const IceUtil::StringConverterPtr& stringConverter) { // // No locking, as it can only be called during plug-in loading // - _initData.stringConverter = stringConverter; + _stringConverter = stringConverter; } void -IceInternal::Instance::setWstringConverter(const Ice::WstringConverterPtr& wstringConverter) +IceInternal::Instance::setWstringConverter(const IceUtil::WstringConverterPtr& wstringConverter) { // // No locking, as it can only be called during plug-in loading // - _initData.wstringConverter = wstringConverter; + if(wstringConverter == 0) + { + _wstringConverter = new IceUtil::UnicodeWstringConverter; + } + else + { + _wstringConverter = wstringConverter; + } } void @@ -823,13 +830,22 @@ IceInternal::Instance::setThreadHook(const Ice::ThreadNotificationPtr& threadHoo _initData.threadHook = threadHook; } +namespace +{ + +bool logStdErrConvert = true; + +} + IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const InitializationData& initData) : _state(StateActive), _initData(initData), _messageSizeMax(0), _clientACM(0), _serverACM(0), - _implicitContext(0) + _implicitContext(0), + _stringConverter(IceUtil::getProcessStringConverter()), + _wstringConverter(IceUtil::getProcessWstringConverter()) { try { @@ -853,17 +869,7 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi if(stdOutFilename != "") { -#ifdef _LARGEFILE64_SOURCE - FILE* file = freopen64(stdOutFilename.c_str(), "a", stdout); -#else -#ifdef _WIN32 - FILE* file = _wfreopen(IceUtil::stringToWstring(nativeToUTF8(_initData.stringConverter, - stdOutFilename)).c_str(), - L"a", stdout); -#else - FILE* file = freopen(stdOutFilename.c_str(), "a", stdout); -#endif -#endif + FILE* file = IceUtilInternal::freopen(stdOutFilename, "a", stdout); if(file == 0) { FileException ex(__FILE__, __LINE__); @@ -875,17 +881,7 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi if(stdErrFilename != "") { -#ifdef _LARGEFILE64_SOURCE - FILE* file = freopen64(stdErrFilename.c_str(), "a", stderr); -#else -#ifdef _WIN32 - FILE* file = _wfreopen(IceUtil::stringToWstring(nativeToUTF8(_initData.stringConverter, - stdErrFilename)).c_str(), - L"a", stderr); -#else - FILE* file = freopen(stdErrFilename.c_str(), "a", stderr); -#endif -#endif + FILE* file = IceUtilInternal::freopen(stdErrFilename, "a", stderr); if(file == 0) { FileException ex(__FILE__, __LINE__); @@ -957,7 +953,6 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi if(instanceCount == 1) { - #if defined(_WIN32) && !defined(ICE_OS_WINRT) WORD version = MAKEWORD(1, 1); WSADATA data; @@ -984,6 +979,10 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi } openlog(identForOpenlog.c_str(), LOG_PID, LOG_USER); } +#else + logStdErrConvert = + initData.properties->getPropertyAsIntWithDefault("Ice.LogStdErr.Convert", 1) == 1 && + initData.properties->getProperty("Ice.StdErr").empty(); #endif } } @@ -1008,12 +1007,15 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi #endif if(!logfile.empty()) { - _initData.logger = new LoggerI(_initData.properties->getProperty("Ice.ProgramName"), - nativeToUTF8(_initData.stringConverter, logfile)); + _initData.logger = new LoggerI(_initData.properties->getProperty("Ice.ProgramName"), logfile); } else { _initData.logger = getProcessLogger(); + if(LoggerIPtr::dynamicCast(_initData.logger)) + { + _initData.logger = new LoggerI("", "", logStdErrConvert, _stringConverter); + } } } @@ -1123,9 +1125,9 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi _retryQueue = new RetryQueue(this); - if(_initData.wstringConverter == 0) + if(_wstringConverter == 0) { - _initData.wstringConverter = new UnicodeWstringConverter(); + _wstringConverter = new IceUtil::UnicodeWstringConverter(); } // diff --git a/cpp/src/Ice/Instance.h b/cpp/src/Ice/Instance.h index 118fd88a339..7ed6b917100 100644 --- a/cpp/src/Ice/Instance.h +++ b/cpp/src/Ice/Instance.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -108,8 +109,12 @@ public: void setDefaultLocator(const Ice::LocatorPrx&); void setDefaultRouter(const Ice::RouterPrx&); - void setStringConverter(const Ice::StringConverterPtr&); - void setWstringConverter(const Ice::WstringConverterPtr&); + IceUtil::StringConverterPtr getStringConverter() const { return _stringConverter; } + void setStringConverter(const IceUtil::StringConverterPtr&); + + IceUtil::WstringConverterPtr getWstringConverter() const { return _wstringConverter; } + void setWstringConverter(const IceUtil::WstringConverterPtr&); + void setLogger(const Ice::LoggerPtr&); void setThreadHook(const Ice::ThreadNotificationPtr&); @@ -158,6 +163,8 @@ private: DynamicLibraryListPtr _dynamicLibraryList; Ice::PluginManagerPtr _pluginManager; const Ice::ImplicitContextIPtr _implicitContext; + IceUtil::StringConverterPtr _stringConverter; + IceUtil::WstringConverterPtr _wstringConverter; Ice::ObjectAdapterPtr _adminAdapter; Ice::FacetMap _adminFacets; Ice::Identity _adminIdentity; diff --git a/cpp/src/Ice/LoggerI.cpp b/cpp/src/Ice/LoggerI.cpp index 3375a2704e5..b5e599cc638 100644 --- a/cpp/src/Ice/LoggerI.cpp +++ b/cpp/src/Ice/LoggerI.cpp @@ -11,7 +11,13 @@ #include #include #include -#include + +#ifdef _WIN32 +# include +# include +# include +#endif + #include using namespace std; @@ -41,9 +47,70 @@ public: Init init; +#ifdef _WIN32 +string +UTF8ToCodePage(const string& in, int codePage) +{ + string out; + if(!in.empty()) + { + if(CP_UTF8 == codePage) + { + out = in; + } + else + { + IceUtil::ScopedArray wbuffer; + int size = 0; + int wlength = 0; + do + { + size == 0 ? 2 * in.size() : 2 * size; + wbuffer.reset(new wchar_t[size]); + wlength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, in.c_str(), -1, wbuffer.get(), size); + } + while(wlength == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + if(wlength == 0) + { + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString()); + } + + // + // WC_ERR_INVALID_CHARS conversion flag is only supported with 65001 (UTF-8) and + // 54936 (GB18030 Simplified Chinese) + // + DWORD conversionFlags = (codePage == 65001 || codePage == 54936) ? WC_ERR_INVALID_CHARS : 0; + + IceUtil::ScopedArray buffer; + + size = 0; + int length = 0; + do + { + size == 0 ? wlength + 2 : 2 * size; + buffer.reset(new char[length]); + length = WideCharToMultiByte(codePage, conversionFlags, wbuffer.get(), wlength, buffer.get(), size, 0, 0); + } + while(length == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + if(!length) + { + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString());; + } + out.assign(buffer.get(), length); + } + } + return out; } +#endif -Ice::LoggerI::LoggerI(const string& prefix, const string& file) +} + +Ice::LoggerI::LoggerI(const string& prefix, const string& file, + bool convert, const IceUtil::StringConverterPtr& converter) : + _convert(convert), + _converter(converter) { if(!prefix.empty()) { @@ -52,10 +119,6 @@ Ice::LoggerI::LoggerI(const string& prefix, const string& file) if(!file.empty()) { - // - // The given file string is execpted to be encoded as UTF8 by - // the caller, so no need to convert it here. - // _file = file; _out.open(file, fstream::out | fstream::app); if(!_out.is_open()) @@ -108,7 +171,7 @@ Ice::LoggerI::error(const string& message) LoggerPtr Ice::LoggerI::cloneWithPrefix(const std::string& prefix) { - return new LoggerI(prefix, _file); + return new LoggerI(prefix, _file, _convert, _converter); } void @@ -134,6 +197,46 @@ Ice::LoggerI::write(const string& message, bool indent) } else { +#ifndef _WIN32 cerr << s << endl; +#else + // + // Convert the message from the native narrow string encoding to the console + // code page encoding for printing. If the _convert member is set to false + // we don't do any conversion. + // + if(!_convert) + { + cerr << s << endl; + } + else + { + try + { + // + // First we convert the message to UTF8 using nativeToUTF8 + // then we convert the message to the console code page + // using UTF8ToCodePage. + // + // nativeToUTF8 doesn't do any conversion if the converter is + // null likewise UTF8ToCodePage doesn't do any conversion if + // the code page is UTF8. + // + // We cannot use cerr here as writing to console using cerr + // will do its own conversion and will corrupt the messages. + // + fprintf_s(stderr, "%s\n", UTF8ToCodePage(IceUtil::nativeToUTF8(_converter, s), + GetConsoleOutputCP()).c_str()); + } + catch(const IceUtil::IllegalConversionException&) + { + // + // If there is a problem with the encoding conversions we just + // write the original message without encoding conversions. + // + fprintf_s(stderr, "%s\n", s.c_str()); + } + } +#endif } } diff --git a/cpp/src/Ice/LoggerI.h b/cpp/src/Ice/LoggerI.h index ab05bc887a1..36b451b1b21 100644 --- a/cpp/src/Ice/LoggerI.h +++ b/cpp/src/Ice/LoggerI.h @@ -12,6 +12,7 @@ #include #include +#include namespace Ice { @@ -20,7 +21,8 @@ class LoggerI : public Logger { public: - LoggerI(const std::string&, const std::string&); + LoggerI(const std::string&, const std::string&, bool convert = true, + const IceUtil::StringConverterPtr& converter = 0); ~LoggerI(); virtual void print(const std::string&); @@ -34,7 +36,10 @@ private: void write(const std::string&, bool); std::string _prefix; + const bool _convert; + const IceUtil::StringConverterPtr _converter; IceUtilInternal::ofstream _out; + std::string _file; }; diff --git a/cpp/src/Ice/Makefile b/cpp/src/Ice/Makefile index 06ca628cfec..b84170ed094 100644 --- a/cpp/src/Ice/Makefile +++ b/cpp/src/Ice/Makefile @@ -105,7 +105,7 @@ OBJS = Acceptor.o \ Stats.o \ StreamI.o \ Stream.o \ - StringConverter.o \ + StringConverterPlugin.o \ TcpAcceptor.o \ TcpConnector.o \ TcpEndpointI.o \ @@ -179,7 +179,7 @@ CPPFLAGS := $(CPPFLAGS) -DCOMPSUFFIX=\"$(COMPSUFFIX)\" endif SLICE2CPPFLAGS := --ice --include-dir Ice --dll-export ICE_API $(SLICE2CPPFLAGS) -LINKWITH := -lIceUtil $(BZIP2_LIBS) $(ICONV_LIBS) $(ICE_OS_LIBS) +LINKWITH := -lIceUtil $(BZIP2_LIBS) $(ICE_OS_LIBS) ifeq ($(STATICLIBS),yes) $(libdir)/$(LIBNAME): $(OBJS) diff --git a/cpp/src/Ice/Makefile.mak b/cpp/src/Ice/Makefile.mak index 4c2bc1ab574..d920c044baa 100644 --- a/cpp/src/Ice/Makefile.mak +++ b/cpp/src/Ice/Makefile.mak @@ -106,7 +106,7 @@ OBJS = Acceptor.obj \ Stats.obj \ StreamI.obj \ Stream.obj \ - StringConverter.obj \ + StringConverterPlugin.obj \ TcpAcceptor.obj \ TcpConnector.obj \ TcpEndpointI.obj \ diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 9f7aae2debd..564c9c20b62 100644 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -516,7 +516,11 @@ getInterfaceIndex(const string& name) } else { - if(IceUtil::wstringToString(paddrs->FriendlyName) == name) + // + // Don't need to pass a wide string converter as the wide string + // come from Windows API. + // + if(IceUtil::wnativeToNative(IceUtil::getProcessStringConverter(), 0, paddrs->FriendlyName) == name) { index = paddrs->Ipv6IfIndex; break; @@ -656,7 +660,11 @@ getInterfaceAddress(const string& name) { while(paddrs) { - if(IceUtil::wstringToString(paddrs->FriendlyName) == name) + // + // Don't need to pass a wide string converter as the wide string come + // from Windows API. + // + if(IceUtil::wnativeToNative(IceUtil::getProcessStringConverter(), 0, paddrs->FriendlyName) == name) { struct sockaddr_in addrin; memcpy(&addrin, paddrs->FirstUnicastAddress->Address.lpSockaddr, @@ -872,11 +880,20 @@ IceInternal::getAddresses(const string& host, int port, ProtocolSupport, Ice::En } else { - addr.host = ref new HostName(ref new String(IceUtil::stringToWstring(host).c_str())); + // + // Don't need to pass a wide string converter as the wide string is passed + // to Windows API. + // + addr.host = ref new HostName(ref new String( + IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, host).c_str())); } stringstream os; os << port; - addr.port = ref new String(IceUtil::stringToWstring(os.str()).c_str()); + // + // Don't need to use any string converter here as the port number use just + // ACII characters. + // + addr.port = ref new String(IceUtil::nativeToWnative(0, 0, os.str()).c_str()); result.push_back(addr); return result; } @@ -1040,7 +1057,11 @@ IceInternal::getAddressForServer(const string& host, int port, ProtocolSupport p #ifdef ICE_OS_WINRT ostringstream os; os << port; - addr.port = ref new String(IceUtil::stringToWstring(os.str()).c_str()); + // + // Don't need to use any string converter here as the port number use just + // ACII characters. + // + addr.port = ref new String(IceUtil::nativeToWnative(0, 0, os.str()).c_str()); addr.host = nullptr; // Equivalent of inaddr_any, see doBind implementation. #else memset(&addr.saStorage, 0, sizeof(sockaddr_storage)); @@ -1516,7 +1537,11 @@ IceInternal::inetAddrToString(const Address& ss) } else { - return IceUtil::wstringToString(ss.host->RawName->Data()); + // + // Don't need to pass a wide string converter as the wide string come + // from Windows API. + // + return IceUtil::wnativeToNative(IceUtil::getProcessStringConverter(), 0, ss.host->RawName->Data()); } #endif } @@ -1539,7 +1564,10 @@ IceInternal::getPort(const Address& addr) } #else IceUtil::Int64 port; - if(addr.port == nullptr || !IceUtilInternal::stringToInt64(IceUtil::wstringToString(addr.port->Data()), port)) + // + // Don't need to use any string converter here as the port number use just ACII characters. + // + if(addr.port == nullptr || !IceUtilInternal::stringToInt64(IceUtil::wnativeToNative(0, 0, addr.port->Data()), port)) { return -1; } @@ -1563,7 +1591,11 @@ IceInternal::setPort(Address& addr, int port) #else ostringstream os; os << port; - addr.port = ref new String(IceUtil::stringToWstring(os.str()).c_str()); + // + // Don't need to use any string converter here as the port number use just + // ACII characters. + // + addr.port = ref new String(IceUtil::nativeToWnative(0, 0, os.str()).c_str()); #endif } @@ -1584,7 +1616,11 @@ IceInternal::isMulticast(const Address& addr) { return false; } - string host = IceUtil::wstringToString(addr.host->RawName->Data()); + // + // Don't need to use string converters here, this is just to do a local + // comparison to find if the address is multicast. + // + string host = IceUtil::wnativeToNative(0, 0, addr.host->RawName->Data()); string ip = IceUtilInternal::toUpper(host); vector tokens; IceUtilInternal::splitString(ip, ".", tokens); @@ -2486,7 +2522,11 @@ IceInternal::checkConnectErrorCode(const char* file, int line, HRESULT herr, Hos { DNSException ex(file, line); ex.error = static_cast(error); - ex.host = IceUtil::wstringToString(host->RawName->Data()); + // + // Don't need to pass a wide string converter as the wide string come from + // Windows API. + // + ex.host = IceUtil::wnativeToNative(IceUtil::getProcessStringConverter(), 0, host->RawName->Data()); throw ex; } else diff --git a/cpp/src/Ice/PluginManagerI.cpp b/cpp/src/Ice/PluginManagerI.cpp index d8e4bc7e293..81fbd6a922a 100644 --- a/cpp/src/Ice/PluginManagerI.cpp +++ b/cpp/src/Ice/PluginManagerI.cpp @@ -342,7 +342,7 @@ Ice::PluginManagerI::loadPlugin(const string& name, const string& pluginSpec, St // Load the entry point symbol. // PluginPtr plugin; - DynamicLibraryPtr library = new DynamicLibrary(IceInternal::getInstance(_communicator)->initializationData().stringConverter); + DynamicLibraryPtr library = new DynamicLibrary(); DynamicLibrary::symbol_type sym = library->loadEntryPoint(entryPoint); if(sym == 0) { diff --git a/cpp/src/Ice/PropertiesI.cpp b/cpp/src/Ice/PropertiesI.cpp index 4f6f7616de8..05c98890614 100644 --- a/cpp/src/Ice/PropertiesI.cpp +++ b/cpp/src/Ice/PropertiesI.cpp @@ -17,7 +17,6 @@ #include #include #include -#include using namespace std; using namespace Ice; @@ -304,7 +303,7 @@ Ice::PropertiesI::load(const std::string& file) if(file.find("HKLM\\") == 0) { HKEY iceKey; - const wstring keyName = IceUtil::stringToWstring(Ice::nativeToUTF8(_converter, file).substr(5)).c_str(); + const wstring keyName = IceUtil::nativeToWnative(_converter, 0, file).substr(5).c_str(); LONG err; if((err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_QUERY_VALUE, &iceKey)) != ERROR_SUCCESS) { @@ -351,8 +350,8 @@ Ice::PropertiesI::load(const std::string& file) getProcessLogger()->warning(os.str()); continue; } - string name = IceUtil::wstringToString(wstring(reinterpret_cast(&nameBuf[0]), nameBufSize)); - name = Ice::UTF8ToNative(_converter, name); + string name = IceUtil::wnativeToNative(_converter, 0, + wstring(reinterpret_cast(&nameBuf[0]), nameBufSize)); if(keyType != REG_SZ && keyType != REG_EXPAND_SZ) { ostringstream os; @@ -365,7 +364,7 @@ Ice::PropertiesI::load(const std::string& file) wstring valueW = wstring(reinterpret_cast(&dataBuf[0]), (dataBufSize / sizeof(wchar_t)) - 1); if(keyType == REG_SZ) { - value = IceUtil::wstringToString(valueW); + value = IceUtil::wnativeToNative(_converter, 0, valueW); } else // keyType == REG_EXPAND_SZ { @@ -385,9 +384,8 @@ Ice::PropertiesI::load(const std::string& file) continue; } } - value = IceUtil::wstringToString(wstring(&expandedValue[0], sz -1)); + value = IceUtil::wnativeToNative(_converter, 0, wstring(&expandedValue[0], sz -1)); } - value = Ice::UTF8ToNative(_converter, value); setProperty(name, value); } } @@ -401,7 +399,7 @@ Ice::PropertiesI::load(const std::string& file) else #endif { - IceUtilInternal::ifstream in(Ice::nativeToUTF8(_converter, file)); + IceUtilInternal::ifstream in(file); if(!in) { FileException ex(__FILE__, __LINE__); @@ -462,12 +460,12 @@ Ice::PropertiesI::PropertiesI(const PropertiesI* p) : { } -Ice::PropertiesI::PropertiesI(const StringConverterPtr& converter) : +Ice::PropertiesI::PropertiesI(const IceUtil::StringConverterPtr& converter) : _converter(converter) { } -Ice::PropertiesI::PropertiesI(StringSeq& args, const PropertiesPtr& defaults, const StringConverterPtr& converter) : +Ice::PropertiesI::PropertiesI(StringSeq& args, const PropertiesPtr& defaults, const IceUtil::StringConverterPtr& converter) : _converter(converter) { if(defaults != 0) @@ -539,7 +537,7 @@ Ice::PropertiesI::PropertiesI(StringSeq& args, const PropertiesPtr& defaults, co } void -Ice::PropertiesI::parseLine(const string& line, const StringConverterPtr& converter) +Ice::PropertiesI::parseLine(const string& line, const IceUtil::StringConverterPtr& converter) { string key; string value; @@ -705,8 +703,8 @@ Ice::PropertiesI::parseLine(const string& line, const StringConverterPtr& conver return; } - key = Ice::UTF8ToNative(converter, key); - value = Ice::UTF8ToNative(converter, value); + key = IceUtil::UTF8ToNative(converter, key); + value = IceUtil::UTF8ToNative(converter, value); setProperty(key, value); } @@ -718,6 +716,7 @@ Ice::PropertiesI::loadConfig() #ifndef ICE_OS_WINRT // // WinRT cannot access environment variables + // if(value.empty() || value == "1") { # ifdef _WIN32 @@ -730,7 +729,7 @@ Ice::PropertiesI::loadConfig() } if(ret > 0) { - value = Ice::UTF8ToNative(_converter, IceUtil::wstringToString(wstring(&v[0], ret))); + value = IceUtil::wnativeToNative(_converter, 0, wstring(&v[0], ret)); } else { diff --git a/cpp/src/Ice/PropertiesI.h b/cpp/src/Ice/PropertiesI.h index 997d2f10fc4..e802ef397a8 100644 --- a/cpp/src/Ice/PropertiesI.h +++ b/cpp/src/Ice/PropertiesI.h @@ -12,7 +12,7 @@ #include #include -#include +#include #include @@ -41,15 +41,15 @@ public: std::set getUnusedProperties(); private: - PropertiesI(const StringConverterPtr&); - PropertiesI(StringSeq&, const PropertiesPtr&, const StringConverterPtr&); + PropertiesI(const IceUtil::StringConverterPtr&); + PropertiesI(StringSeq&, const PropertiesPtr&, const IceUtil::StringConverterPtr&); PropertiesI(const PropertiesI*); - friend ICE_API PropertiesPtr createProperties(const StringConverterPtr&); - friend ICE_API PropertiesPtr createProperties(StringSeq&, const PropertiesPtr&, const StringConverterPtr&); - friend ICE_API PropertiesPtr createProperties(int&, char*[], const PropertiesPtr&, const StringConverterPtr&); + friend ICE_API PropertiesPtr createProperties(); + friend ICE_API PropertiesPtr createProperties(StringSeq&, const PropertiesPtr&); + friend ICE_API PropertiesPtr createProperties(int&, char*[], const PropertiesPtr&); - void parseLine(const std::string&, const StringConverterPtr&); + void parseLine(const std::string&, const IceUtil::StringConverterPtr&); void loadConfig(); @@ -70,7 +70,7 @@ private: bool used; }; std::map _properties; - const StringConverterPtr _converter; + const IceUtil::StringConverterPtr _converter; }; } diff --git a/cpp/src/Ice/PropertyNames.cpp b/cpp/src/Ice/PropertyNames.cpp index fbfdb94d092..97aa60d71dc 100644 --- a/cpp/src/Ice/PropertyNames.cpp +++ b/cpp/src/Ice/PropertyNames.cpp @@ -8,7 +8,7 @@ // ********************************************************************** ///* jshint -W044*/ -// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Apr 22 17:39:32 2014 +// Generated by makeprops.py from file ../config/PropertyNames.xml, Mon Apr 28 19:03:05 2014 // IMPORTANT: Do not edit this file -- any edits made here will be lost! @@ -95,6 +95,7 @@ const IceInternal::Property IcePropsData[] = IceInternal::Property("Ice.ImplicitContext", false, 0), IceInternal::Property("Ice.InitPlugins", false, 0), IceInternal::Property("Ice.LogFile", false, 0), + IceInternal::Property("Ice.LogStdErr.Convert", false, 0), IceInternal::Property("Ice.MessageSizeMax", false, 0), IceInternal::Property("Ice.MonitorConnections", false, 0), IceInternal::Property("Ice.Nohup", false, 0), diff --git a/cpp/src/Ice/PropertyNames.h b/cpp/src/Ice/PropertyNames.h index 64a7655b887..10eb9dc87f5 100644 --- a/cpp/src/Ice/PropertyNames.h +++ b/cpp/src/Ice/PropertyNames.h @@ -8,7 +8,7 @@ // ********************************************************************** ///* jshint -W044*/ -// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Apr 22 17:39:32 2014 +// Generated by makeprops.py from file ../config/PropertyNames.xml, Mon Apr 28 19:03:05 2014 // IMPORTANT: Do not edit this file -- any edits made here will be lost! diff --git a/cpp/src/Ice/Reference.cpp b/cpp/src/Ice/Reference.cpp index 36769c179b9..be40f3f0df9 100644 --- a/cpp/src/Ice/Reference.cpp +++ b/cpp/src/Ice/Reference.cpp @@ -238,7 +238,7 @@ IceInternal::Reference::toString() const // the reference parser uses as separators, then we enclose // the facet string in quotes. // - string fs = Ice::nativeToUTF8(_instance->initializationData().stringConverter, _facet); + string fs = nativeToUTF8(_instance->getStringConverter(), _facet); fs = IceUtilInternal::escapeString(fs, ""); if(fs.find_first_of(" :@") != string::npos) { @@ -1207,7 +1207,7 @@ IceInternal::RoutableReference::toString() const // reference parser uses as separators, then we enclose the // adapter id string in quotes. // - string a = Ice::nativeToUTF8(getInstance()->initializationData().stringConverter, _adapterId); + string a = nativeToUTF8(getInstance()->getStringConverter(), _adapterId); a = IceUtilInternal::escapeString(a, ""); if(a.find_first_of(" :@") != string::npos) { diff --git a/cpp/src/Ice/ReferenceFactory.cpp b/cpp/src/Ice/ReferenceFactory.cpp index d63bfc3a4e6..a96fd7630cd 100644 --- a/cpp/src/Ice/ReferenceFactory.cpp +++ b/cpp/src/Ice/ReferenceFactory.cpp @@ -288,7 +288,7 @@ IceInternal::ReferenceFactory::create(const string& str, const string& propertyP throw ex; } - facet = Ice::UTF8ToNative(_instance->initializationData().stringConverter, facet); + facet = UTF8ToNative(_instance->getStringConverter(), facet); break; } @@ -569,7 +569,7 @@ IceInternal::ReferenceFactory::create(const string& str, const string& propertyP throw ex; } - adapter = Ice::UTF8ToNative(_instance->initializationData().stringConverter, adapter); + adapter = UTF8ToNative(_instance->getStringConverter(), adapter); return create(ident, facet, mode, secure, protocol, encoding, endpoints, adapter, propertyPrefix); break; diff --git a/cpp/src/Ice/ServantManager.cpp b/cpp/src/Ice/ServantManager.cpp index 4c661eb1934..45f9e8dbb76 100644 --- a/cpp/src/Ice/ServantManager.cpp +++ b/cpp/src/Ice/ServantManager.cpp @@ -47,7 +47,7 @@ IceInternal::ServantManager::addServant(const ObjectPtr& object, const Identity& ex.id = _instance->identityToString(ident); if(!facet.empty()) { - string fs = nativeToUTF8(_instance->initializationData().stringConverter, facet); + string fs = nativeToUTF8(_instance->getStringConverter(), facet); ex.id += " -f " + IceUtilInternal::escapeString(fs, ""); } throw ex; @@ -107,7 +107,7 @@ IceInternal::ServantManager::removeServant(const Identity& ident, const string& ex.id = _instance->identityToString(ident); if(!facet.empty()) { - string fs = nativeToUTF8(_instance->initializationData().stringConverter, facet); + string fs = nativeToUTF8(_instance->getStringConverter(), facet); ex.id += " -f " + IceUtilInternal::escapeString(fs, ""); } throw ex; diff --git a/cpp/src/Ice/Service.cpp b/cpp/src/Ice/Service.cpp index bcc93beaa5e..13631d3209b 100644 --- a/cpp/src/Ice/Service.cpp +++ b/cpp/src/Ice/Service.cpp @@ -15,10 +15,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -204,11 +204,14 @@ class SMEventLoggerI : public Ice::Logger, public SMEventLogger { public: - SMEventLoggerI(const string& source, const StringConverterPtr& stringConverter) : + SMEventLoggerI(const string& source, const IceUtil::StringConverterPtr& stringConverter) : _stringConverter(stringConverter) { - _source = RegisterEventSourceW(0, IceUtil::stringToWstring( - nativeToUTF8(_stringConverter, mangleSource(source))).c_str()); + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + _source = RegisterEventSourceW(0, IceUtil::nativeToWnative(_stringConverter, 0, mangleSource(source)).c_str()); if(_source == 0) { SyscallException ex(__FILE__, __LINE__); @@ -224,12 +227,16 @@ public: } static void - addKeys(const string& source, const StringConverterPtr& stringConverter) + addKeys(const string& source, const IceUtil::StringConverterPtr& stringConverter) { HKEY hKey; DWORD d; + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // LONG err = RegCreateKeyExW(HKEY_LOCAL_MACHINE, - IceUtil::stringToWstring(nativeToUTF8(stringConverter, createKey(source))).c_str(), + IceUtil::nativeToWnative(stringConverter, 0, createKey(source)).c_str(), 0, const_cast(L"REG_SZ"), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &d); if(err != ERROR_SUCCESS) @@ -282,10 +289,14 @@ public: } static void - removeKeys(const string& source, const StringConverterPtr& stringConverter) + removeKeys(const string& source, const IceUtil::StringConverterPtr& stringConverter) { + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // LONG err = RegDeleteKeyW(HKEY_LOCAL_MACHINE, - IceUtil::stringToWstring(nativeToUTF8(stringConverter, createKey(source))).c_str()); + IceUtil::nativeToWnative(stringConverter, 0, createKey(source)).c_str()); if(err != ERROR_SUCCESS) { SyscallException ex(__FILE__, __LINE__); @@ -310,7 +321,11 @@ public: virtual void print(const string& message) { - wstring msg = IceUtil::stringToWstring(nativeToUTF8(_stringConverter, message)); + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + wstring msg = IceUtil::nativeToWnative(_stringConverter, 0, message); const wchar_t* messages[1]; messages[0] = msg.c_str(); // @@ -344,7 +359,11 @@ public: } s.append(message); - wstring msg = IceUtil::stringToWstring(nativeToUTF8(_stringConverter, s)); + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + wstring msg = IceUtil::nativeToWnative(_stringConverter, 0, s); const wchar_t* messages[1]; messages[0] = msg.c_str(); // @@ -370,7 +389,11 @@ public: virtual void warning(const string& message) { - wstring msg = IceUtil::stringToWstring(nativeToUTF8(_stringConverter, message)); + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + wstring msg = IceUtil::nativeToWnative(_stringConverter, 0, message); const wchar_t* messages[1]; messages[0] = msg.c_str(); // @@ -396,7 +419,11 @@ public: virtual void error(const string& message) { - wstring msg = IceUtil::stringToWstring(nativeToUTF8(_stringConverter, message)); + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + wstring msg = IceUtil::nativeToWnative(_stringConverter, 0, message); const wchar_t* messages[1]; messages[0] = msg.c_str(); // @@ -445,7 +472,7 @@ private: return "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" + mangleSource(name); } - StringConverterPtr _stringConverter; + IceUtil::StringConverterPtr _stringConverter; HANDLE _source; static HMODULE _module; }; @@ -462,7 +489,6 @@ Ice::Service::Service() _nohup = true; _service = false; _instance = this; - #ifndef _WIN32 _changeDirectory = true; _closeFiles = true; @@ -525,7 +551,7 @@ Ice::Service::main(int& argc, char* argv[], const InitializationData& initializa InitializationData initData = initializationData; try { - initData.properties = createProperties(argc, argv, initData.properties, initData.stringConverter); + initData.properties = createProperties(argc, argv, initData.properties); } catch(const Ice::Exception& ex) { @@ -542,6 +568,7 @@ Ice::Service::main(int& argc, char* argv[], const InitializationData& initializa string name; string eventLogSource; int idx = 1; + const IceUtil::StringConverterPtr stringConverter = IceUtil::getProcessStringConverter(); while(idx < argc) { if(strcmp(argv[idx], "--service") == 0) @@ -562,7 +589,7 @@ Ice::Service::main(int& argc, char* argv[], const InitializationData& initializa if(LoggerIPtr::dynamicCast(_logger)) { string eventLogSource = initData.properties->getPropertyWithDefault("Ice.EventLog.Source", name); - _logger = new SMEventLoggerIWrapper(new SMEventLoggerI(eventLogSource, initData.stringConverter), ""); + _logger = new SMEventLoggerIWrapper(new SMEventLoggerI(eventLogSource, stringConverter), ""); setProcessLogger(_logger); } @@ -688,7 +715,12 @@ Ice::Service::main(int& argc, char* argv[], const InitializationData& initializa _logger = getProcessLogger(); if(LoggerIPtr::dynamicCast(_logger)) { - _logger = new LoggerI(initData.properties->getProperty("Ice.ProgramName"), ""); + const bool convert = + initData.properties->getPropertyAsIntWithDefault("Ice.LogStdErr.Convert", 1) == 1 && + initData.properties->getProperty("Ice.StdErr").empty(); + + _logger = new LoggerI(initData.properties->getProperty("Ice.ProgramName"), "", convert, + IceUtil::getProcessStringConverter()); setProcessLogger(_logger); } } @@ -713,10 +745,10 @@ Ice::Service::main(int& argc, wchar_t* argv[], const InitializationData& initial // // MinGW doesn't see the main overload if we don't create the temp args object here. // - Ice::StringSeq args = Ice::argsToStringSeq(argc, argv, initializationData.stringConverter); + Ice::StringSeq args = Ice::argsToStringSeq(argc, argv); return main(args, initializationData); # else - return main(Ice::argsToStringSeq(argc, argv, initializationData.stringConverter), initializationData); + return main(Ice::argsToStringSeq(argc, argv), initializationData); # endif } @@ -773,7 +805,7 @@ Ice::Service::checkSystem() const int Ice::Service::run(int& argc, wchar_t* argv[], const InitializationData& initData) { - StringSeq args = Ice::argsToStringSeq(argc, argv, initData.stringConverter); + StringSeq args = Ice::argsToStringSeq(argc, argv); IceUtilInternal::ArgVector av(args); return run(av.argc, av.argv, initData); } @@ -1078,9 +1110,15 @@ Ice::Service::runService(int argc, char* argv[], const InitializationData& initD _initData = initData; + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // SERVICE_TABLE_ENTRYW ste[] = { - { const_cast(IceUtil::stringToWstring(nativeToUTF8(_initData.stringConverter, _name)).c_str()), Ice_Service_ServiceMain }, + { const_cast( + IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, _name).c_str()), + Ice_Service_ServiceMain }, { 0, 0 }, }; @@ -1260,8 +1298,14 @@ Ice::Service::serviceMain(int argc, wchar_t* argv[]) // // Merge the executable's arguments with the service's arguments. // + const IceUtil::StringConverterPtr converter(IceUtil::getProcessStringConverter()); + + // + // Don't need to pass a wide string converter in the bellow argv conversions + // as argv come from Windows API. + // char** args = new char*[_serviceArgs.size() + argc]; - args[0] = const_cast(UTF8ToNative(_initData.stringConverter, IceUtil::wstringToString(argv[0])).c_str()); + args[0] = const_cast(IceUtil::wnativeToNative(converter, 0, argv[0]).c_str()); int i = 1; for(vector::iterator p = _serviceArgs.begin(); p != _serviceArgs.end(); ++p) { @@ -1269,7 +1313,7 @@ Ice::Service::serviceMain(int argc, wchar_t* argv[]) } for(int j = 1; j < argc; ++j) { - args[i++] = const_cast(UTF8ToNative(_initData.stringConverter, IceUtil::wstringToString(argv[j])).c_str()); + args[i++] = const_cast(IceUtil::wnativeToNative(converter, 0, argv[j]).c_str()); } argc += static_cast(_serviceArgs.size()); @@ -1743,7 +1787,7 @@ Ice::Service::runDaemon(int argc, char* argv[], const InitializationData& initDa // if(_pidFile.size() > 0) { - IceUtilInternal::ofstream of(Ice::nativeToUTF8(_communicator, _pidFile)); + IceUtilInternal::ofstream of(_pidFile); of << getpid() << endl; if(!of) diff --git a/cpp/src/Ice/StringConverter.cpp b/cpp/src/Ice/StringConverter.cpp deleted file mode 100644 index 4c6696b5434..00000000000 --- a/cpp/src/Ice/StringConverter.cpp +++ /dev/null @@ -1,452 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#endif - -#ifdef __MINGW32__ -# include -#endif - -using namespace IceUtil; -using namespace IceUtilInternal; -using namespace std; - -namespace -{ - -class UTF8BufferI : public Ice::UTF8Buffer -{ -public: - - UTF8BufferI() : - _buffer(0), - _offset(0) - { - } - - ~UTF8BufferI() - { - free(_buffer); - } - - Ice::Byte* getMoreBytes(size_t howMany, Byte* firstUnused) - { - if(_buffer == 0) - { - _buffer = (Byte*)malloc(howMany); - } - else - { - assert(firstUnused != 0); - _offset = firstUnused - _buffer; - _buffer = (Byte*)realloc(_buffer, _offset + howMany); - } - - if(!_buffer) - { - throw std::bad_alloc(); - } - return _buffer + _offset; - } - - Ice::Byte* getBuffer() - { - return _buffer; - } - - void reset() - { - free(_buffer); - _buffer = 0; - _offset = 0; - } - -private: - - Ice::Byte* _buffer; - size_t _offset; -}; -} - - - -namespace Ice -{ - -UnicodeWstringConverter::UnicodeWstringConverter(ConversionFlags flags) : - _conversionFlags(flags) -{ -} - -Byte* -UnicodeWstringConverter::toUTF8(const wchar_t* sourceStart, - const wchar_t* sourceEnd, - UTF8Buffer& buffer) const -{ - // - // The "chunk size" is the maximum of the number of characters in the - // source and 6 (== max bytes necessary to encode one Unicode character). - // - size_t chunkSize = std::max(static_cast(sourceEnd - sourceStart), 6); - - Byte* targetStart = buffer.getMoreBytes(chunkSize, 0); - Byte* targetEnd = targetStart + chunkSize; - - ConversionResult result; - - while((result = - convertUTFWstringToUTF8(sourceStart, sourceEnd, - targetStart, targetEnd, _conversionFlags)) - == targetExhausted) - { - targetStart = buffer.getMoreBytes(chunkSize, targetStart); - targetEnd = targetStart + chunkSize; - } - - switch(result) - { - case conversionOK: - break; - case sourceExhausted: - throw StringConversionException(__FILE__, __LINE__, "wide string source exhausted"); - case sourceIllegal: - throw StringConversionException(__FILE__, __LINE__, "wide string source illegal"); - default: - { - assert(0); - throw StringConversionException(__FILE__, __LINE__); - } - } - return targetStart; -} - - -void -UnicodeWstringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, - wstring& target) const -{ - if(sourceStart == sourceEnd) - { - target = L""; - return; - } - - ConversionResult result = - convertUTF8ToUTFWstring(sourceStart, sourceEnd, target, _conversionFlags); - - switch(result) - { - case conversionOK: - break; - case sourceExhausted: - throw StringConversionException(__FILE__, __LINE__, "UTF-8 string source exhausted"); - case sourceIllegal: - throw StringConversionException(__FILE__, __LINE__, "UTF-8 string source illegal"); - default: - { - assert(0); - throw StringConversionException(__FILE__, __LINE__); - } - } -} - -#ifdef _WIN32 -WindowsStringConverter::WindowsStringConverter(unsigned int cp) : - _cp(cp) -{ -} - -Byte* -WindowsStringConverter::toUTF8(const char* sourceStart, - const char* sourceEnd, - UTF8Buffer& buffer) const -{ - // - // First convert to UTF-16 - // - int sourceSize = static_cast(sourceEnd - sourceStart); - if(sourceSize == 0) - { - return buffer.getMoreBytes(1, 0); - } - - int size = 0; - int writtenWchar = 0; - ScopedArray wbuffer; - do - { - size = size == 0 ? sourceSize + 2 : 2 * size; - wbuffer.reset(new wchar_t[size]); - - writtenWchar = MultiByteToWideChar(_cp, MB_ERR_INVALID_CHARS, sourceStart, - sourceSize, wbuffer.get(), size); - } while(writtenWchar == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); - - if(writtenWchar == 0) - { - throw StringConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString()); - } - - // - // Then convert this UTF-16 wbuffer into UTF-8 - // - return _unicodeWstringConverter.toUTF8(wbuffer.get(), wbuffer.get() + writtenWchar, buffer); -} - -void -WindowsStringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, - string& target) const -{ - if(sourceStart == sourceEnd) - { - target = ""; - return; - } - - // - // First convert to wstring (UTF-16) - // - wstring wtarget; - _unicodeWstringConverter.fromUTF8(sourceStart, sourceEnd, wtarget); - - // - // And then to a multi-byte narrow string - // - int size = 0; - int writtenChar = 0; - ScopedArray buffer; - do - { - size = size == 0 ? static_cast(sourceEnd - sourceStart) + 2 : 2 * size; - buffer.reset(new char[size]); - writtenChar = WideCharToMultiByte(_cp, 0, wtarget.data(), static_cast(wtarget.size()), - buffer.get(), size, 0, 0); - } while(writtenChar == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); - - if(writtenChar == 0) - { - throw StringConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString()); - } - - target.assign(buffer.get(), writtenChar); -} - -#endif - -StringConverterPlugin::StringConverterPlugin(const CommunicatorPtr& communicator, - const StringConverterPtr& stringConverter, - const WstringConverterPtr& wstringConverter) -{ - if(communicator == 0) - { - throw PluginInitializationException(__FILE__, __LINE__, "Communicator cannot be null"); - } - - IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); - - if(stringConverter != 0) - { - instance->setStringConverter(stringConverter); - } - if(wstringConverter != 0) - { - instance->setWstringConverter(wstringConverter); - } -} - -void -StringConverterPlugin::initialize() -{ -} - -void -StringConverterPlugin::destroy() -{ -} - -} - -// -// The entry point for the "string converter" plug-in built-in the Ice library -// -extern "C" -{ - -using namespace Ice; - -ICE_DECLSPEC_EXPORT Plugin* -createStringConverter(const CommunicatorPtr& communicator, const string& name, const StringSeq& args) -{ - StringConverterPtr stringConverter; - WstringConverterPtr wstringConverter; - - if(args.size() > 2) - { - Error out(communicator->getLogger()); - out << "Plugin " << name << ": too many arguments"; - return 0; - } - - try - { - -#ifdef _WIN32 - - int cp = -1; - - for(size_t i = 0; i < args.size(); ++i) - { - if(args[i].find("windows=") == 0) - { - cp = atoi(args[i].substr(strlen("windows=")).c_str()); - } - else if(args[i].find("iconv=") != 0) - { - Error out(communicator->getLogger()); - out << "Plugin " << name << ": invalid \"" << args[i] << "\" argument"; - return 0; - } - } - - if(cp == -1) - { - Error out(communicator->getLogger()); - out << "Plugin " << name << ": missing windows= argument"; - return 0; - } - - if(cp == 0 || cp == INT_MAX || cp < 0) - { - Error out(communicator->getLogger()); - out << "Plugin " << name << ": invalid Windows code page"; - return 0; - } - - stringConverter = new WindowsStringConverter(static_cast(cp)); -#else - StringSeq iconvArgs; - - for(size_t i = 0; i < args.size(); ++i) - { - if(args[i].find("iconv=") == 0) - { - if(!IceUtilInternal::splitString(args[i].substr(strlen("iconv=")), ", \t\r\n", iconvArgs)) - { - Error out(communicator->getLogger()); - out << "Plugin " << name << ": invalid iconv argument"; - return 0; - } - } - else if(args[i].find("windows=") != 0) - { - Error out(communicator->getLogger()); - out << "Plugin " << name << ": invalid \"" << args[i] << "\" argument"; - return 0; - } - } - - switch(iconvArgs.size()) - { - case 0: - { - stringConverter = new IconvStringConverter; - break; - } - case 1: - { - stringConverter = new IconvStringConverter(iconvArgs[0].c_str()); - break; - } - case 2: - { - stringConverter = new IconvStringConverter(iconvArgs[0].c_str()); - wstringConverter = new IconvStringConverter(iconvArgs[1].c_str()); - break; - } - default: - { - assert(0); - } - } - -#endif - - return new StringConverterPlugin(communicator, stringConverter, wstringConverter); - } - catch(const std::exception& ex) - { - Error out(communicator->getLogger()); - out << "Plugin " << name << ": creation failed with " << ex.what(); - return 0; - } - catch(...) - { - Error out(communicator->getLogger()); - out << "Plugin " << name << ": creation failed with unknown exception"; - return 0; - } -} -} - -string -Ice::nativeToUTF8(const Ice::StringConverterPtr& converter, const string& str) -{ - if(!converter) - { - return str; - } - if(str.empty()) - { - return str; - } - UTF8BufferI buffer; - Ice::Byte* last = converter->toUTF8(str.data(), str.data() + str.size(), buffer); - return string(reinterpret_cast(buffer.getBuffer()), last - buffer.getBuffer()); -} - -string -Ice::nativeToUTF8(const Ice::CommunicatorPtr& ic, const string& str) -{ - return nativeToUTF8(IceInternal::getInstance(ic)->initializationData().stringConverter, str); -} - -string -Ice::UTF8ToNative(const Ice::StringConverterPtr& converter, const string& str) -{ - if(!converter) - { - return str; - } - if(str.empty()) - { - return str; - } - string tmp; - converter->fromUTF8(reinterpret_cast(str.data()), - reinterpret_cast(str.data() + str.size()), tmp); - return tmp; -} - -string -Ice::UTF8ToNative(const Ice::CommunicatorPtr& ic, const std::string& str) -{ - return UTF8ToNative(IceInternal::getInstance(ic)->initializationData().stringConverter, str); -} diff --git a/cpp/src/Ice/StringConverterPlugin.cpp b/cpp/src/Ice/StringConverterPlugin.cpp new file mode 100644 index 00000000000..5cd4526688b --- /dev/null +++ b/cpp/src/Ice/StringConverterPlugin.cpp @@ -0,0 +1,179 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifndef _WIN32 +# include +#endif + +#ifdef __MINGW32__ +# include +#endif + +using namespace IceUtil; +using namespace IceUtilInternal; +using namespace std; + + +Ice::StringConverterPlugin::StringConverterPlugin(const CommunicatorPtr& communicator, + const StringConverterPtr& stringConverter, + const WstringConverterPtr& wstringConverter) +{ + if(communicator == 0) + { + throw PluginInitializationException(__FILE__, __LINE__, "Communicator cannot be null"); + } + + IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); + + IceUtil::setProcessStringConverter(stringConverter); + instance->setStringConverter(stringConverter); + IceUtil::setProcessWstringConverter(wstringConverter); + instance->setWstringConverter(wstringConverter); +} + +void +Ice::StringConverterPlugin::initialize() +{ +} + +void +Ice::StringConverterPlugin::destroy() +{ +} + +// +// The entry point for the "string converter" plug-in built-in the Ice library +// +extern "C" +{ + +using namespace Ice; + +ICE_DECLSPEC_EXPORT Plugin* +createStringConverter(const CommunicatorPtr& communicator, const string& name, const StringSeq& args) +{ + StringConverterPtr stringConverter; + WstringConverterPtr wstringConverter; + + if(args.size() > 2) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": too many arguments"; + return 0; + } + + try + { + +#ifdef _WIN32 + int cp = -1; + + for(size_t i = 0; i < args.size(); ++i) + { + if(args[i].find("windows=") == 0) + { + cp = atoi(args[i].substr(strlen("windows=")).c_str()); + } + else if(args[i].find("iconv=") != 0) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": invalid \"" << args[i] << "\" argument"; + return 0; + } + } + + if(cp == -1) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": missing windows= argument"; + return 0; + } + + if(cp == 0 || cp == INT_MAX || cp < 0) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": invalid Windows code page"; + return 0; + } + + stringConverter = new WindowsStringConverter(static_cast(cp)); +#else + StringSeq iconvArgs; + + for(size_t i = 0; i < args.size(); ++i) + { + if(args[i].find("iconv=") == 0) + { + if(!IceUtilInternal::splitString(args[i].substr(strlen("iconv=")), ", \t\r\n", iconvArgs)) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": invalid iconv argument"; + return 0; + } + } + else if(args[i].find("windows=") != 0) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": invalid \"" << args[i] << "\" argument"; + return 0; + } + } + + switch(iconvArgs.size()) + { + case 0: + { + stringConverter = new IconvStringConverter; + break; + } + case 1: + { + stringConverter = new IconvStringConverter(iconvArgs[0].c_str()); + break; + } + case 2: + { + stringConverter = new IconvStringConverter(iconvArgs[0].c_str()); + wstringConverter = new IconvStringConverter(iconvArgs[1].c_str()); + break; + } + default: + { + assert(0); + } + } + +#endif + + return new StringConverterPlugin(communicator, stringConverter, wstringConverter); + } + catch(const std::exception& ex) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": creation failed with " << ex.what(); + return 0; + } + catch(...) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": creation failed with unknown exception"; + return 0; + } +} +} diff --git a/cpp/src/Ice/StringConverterPlugin.h b/cpp/src/Ice/StringConverterPlugin.h new file mode 100644 index 00000000000..13963a9ce14 --- /dev/null +++ b/cpp/src/Ice/StringConverterPlugin.h @@ -0,0 +1,44 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_STRING_CONVERTER_PLUGIN_H +#define ICE_STRING_CONVERTER_PLUGIN_H + +#include +#include +#include +#include + +#include + +namespace Ice +{ + +// +// A special plug-in that sets stringConverter and wstringConverter during +// construction (when the provided stringConverter resp. wstringConverter +// are not null). Both initialize and destroy are no-op. See Ice::InitializationData. +// + +class ICE_API StringConverterPlugin : public Ice::Plugin +{ +public: + + StringConverterPlugin(const CommunicatorPtr&, + const IceUtil::StringConverterPtr&, + const IceUtil::WstringConverterPtr& = 0); + + virtual void initialize(); + + virtual void destroy(); +}; + +} + +#endif diff --git a/cpp/src/Ice/ThreadPool.cpp b/cpp/src/Ice/ThreadPool.cpp index bdfe1a095ac..61415da250a 100644 --- a/cpp/src/Ice/ThreadPool.cpp +++ b/cpp/src/Ice/ThreadPool.cpp @@ -950,8 +950,13 @@ IceInternal::ThreadPool::run(const EventHandlerThreadPtr& thread) #ifdef ICE_OS_WINRT catch(Platform::Exception^ ex) { + // + // We don't need to pass the wide string converter in the call to wnativeToNative + // because the wide string is using the platform default encoding. + // Error out(_instance->initializationData().logger); - out << "exception in `" << _prefix << "':\n" << IceUtil::wstringToString(ex->Message->Data()) + out << "exception in `" << _prefix << "':\n" + << IceUtil::wnativeToNative(_instance->getStringConverter(), 0, ex->Message->Data()) << "\nevent handler: " << current._handler->toString(); } #endif diff --git a/cpp/src/IceBox/ServiceManagerI.cpp b/cpp/src/IceBox/ServiceManagerI.cpp index 2448f543ed7..d1883c77537 100644 --- a/cpp/src/IceBox/ServiceManagerI.cpp +++ b/cpp/src/IceBox/ServiceManagerI.cpp @@ -523,8 +523,7 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint, // // Load the entry point. // - IceInternal::DynamicLibraryPtr library = - new IceInternal::DynamicLibrary(IceInternal::getInstance(_communicator)->initializationData().stringConverter); + IceInternal::DynamicLibraryPtr library = new IceInternal::DynamicLibrary(); IceInternal::DynamicLibrary::symbol_type sym = library->loadEntryPoint(entryPoint, false); if(sym == 0) { diff --git a/cpp/src/IceGrid/Activator.cpp b/cpp/src/IceGrid/Activator.cpp index eb85bb964e6..1b1bb3f6d04 100644 --- a/cpp/src/IceGrid/Activator.cpp +++ b/cpp/src/IceGrid/Activator.cpp @@ -377,7 +377,12 @@ Activator::activate(const string& name, wchar_t absbuf[_MAX_PATH]; wchar_t* fPart; wstring ext = path.size() <= 4 || path[path.size() - 4] != '.' ? L".exe" : L""; - if(SearchPathW(NULL, IceUtil::stringToWstring(path).c_str(), ext.c_str(), _MAX_PATH, absbuf, &fPart) == 0) + + // + // IceGrid doesn't support to use string converters, so don't need to use + // any string converter in wnativeToNative conversions. + // + if(SearchPathW(NULL, IceUtil::nativeToWnative(0, 0, path).c_str(), ext.c_str(), _MAX_PATH, absbuf, &fPart) == 0) { if(_traceLevels->activator > 0) { @@ -386,7 +391,7 @@ Activator::activate(const string& name, } throw string("Couldn't find `" + path + "' executable."); } - path = IceUtil::wstringToString(absbuf); + path = IceUtil::wnativeToNative(0, 0, absbuf); } else if(!pwd.empty()) { @@ -397,10 +402,14 @@ Activator::activate(const string& name, // // Get the absolute pathname of the working directory. // + // IceGrid doesn't support to use string converters, so + // don't need to use any string converter in nativeToWnative + // conversions. + // if(!pwd.empty()) { wchar_t absbuf[_MAX_PATH]; - if(_wfullpath(absbuf, IceUtil::stringToWstring(pwd).c_str(), _MAX_PATH) == NULL) + if(_wfullpath(absbuf, IceUtil::nativeToWnative(0, 0, pwd).c_str(), _MAX_PATH) == NULL) { if(_traceLevels->activator > 0) { @@ -409,7 +418,7 @@ Activator::activate(const string& name, } throw string("The server working directory path `" + pwd + "' can't be converted into an absolute path."); } - pwd = IceUtil::wstringToString(absbuf); + pwd = IceUtil::wnativeToNative(0, 0, absbuf); } #endif @@ -484,13 +493,17 @@ Activator::activate(const string& name, } } - wstring wpwd = IceUtil::stringToWstring(pwd); + // + // IceGrid doesn't support to use string converters, so don't need to use + // any string converter in nativeToWnative conversions. + // + wstring wpwd = IceUtil::nativeToWnative(0, 0, pwd); const wchar_t* dir = !wpwd.empty() ? wpwd.c_str() : NULL; // // Make a copy of the command line. // - wchar_t* cmdbuf = _wcsdup(IceUtil::stringToWstring(cmd).c_str()); + wchar_t* cmdbuf = _wcsdup(IceUtil::nativeToWnative(0, 0, cmd).c_str()); // // Create the environment block for the child process. We start with the environment @@ -530,7 +543,11 @@ Activator::activate(const string& name, FreeEnvironmentStringsW(static_cast(parentEnv)); for(StringSeq::const_iterator p = envs.begin(); p != envs.end(); ++p) { - wstring s = IceUtil::stringToWstring(*p); + // + // IceGrid doesn't support to use string converters, so don't need to use + // any string converter in nativeToWnative conversions. + // + wstring s = IceUtil::nativeToWnative(0, 0, *p); wstring::size_type pos = s.find(L'='); if(pos != wstring::npos) { diff --git a/cpp/src/IceGrid/IceGridNode.cpp b/cpp/src/IceGrid/IceGridNode.cpp index bc7683bb6af..68ef989fb45 100644 --- a/cpp/src/IceGrid/IceGridNode.cpp +++ b/cpp/src/IceGrid/IceGridNode.cpp @@ -126,7 +126,11 @@ private: void setNoIndexingAttribute(const string& pa) { - wstring path = IceUtil::stringToWstring(pa); + // + // We don't need to pass a wide string converter the wide + // string is passed to Windows API. + // + wstring path = IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, pa); DWORD attrs = GetFileAttributesW(path.c_str()); if(attrs == INVALID_FILE_ATTRIBUTES) { diff --git a/cpp/src/IceGrid/RegistryI.cpp b/cpp/src/IceGrid/RegistryI.cpp index b058f935a1e..74138f91de0 100644 --- a/cpp/src/IceGrid/RegistryI.cpp +++ b/cpp/src/IceGrid/RegistryI.cpp @@ -1186,10 +1186,6 @@ RegistryI::getPermissionsVerifier(const ObjectAdapterPtr& adapter, } else if(!passwordsProperty.empty()) { - // - // No nativeToUTF8 conversion necessary here, since no string - // converter is installed by IceGrid the string is UTF-8. - // IceUtilInternal::ifstream passwordFile(passwordsProperty); if(!passwordFile) { diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp index 283496dce8c..7adbb72bb6a 100644 --- a/cpp/src/IceGrid/ServerI.cpp +++ b/cpp/src/IceGrid/ServerI.cpp @@ -405,9 +405,9 @@ struct EnvironmentEval : std::unary_function break; } string variable = v.substr(beg + 1, end - beg - 1); - DWORD ret = GetEnvironmentVariableW(IceUtil::stringToWstring(variable).c_str(), &buf[0], + DWORD ret = GetEnvironmentVariableW(IceUtil::nativeToWnative(0, 0, variable).c_str(), &buf[0], static_cast(buf.size())); - string valstr = (ret > 0 && ret < buf.size()) ? IceUtil::wstringToString(&buf[0]) : string(""); + string valstr = (ret > 0 && ret < buf.size()) ? IceUtil::wnativeToNative(0, 0, &buf[0]) : string(""); v.replace(beg, end - beg + 1, valstr); beg += valstr.size(); } diff --git a/cpp/src/IcePatch2Lib/ClientUtil.cpp b/cpp/src/IcePatch2Lib/ClientUtil.cpp index 2fe5675e4ed..82d0dce208d 100644 --- a/cpp/src/IcePatch2Lib/ClientUtil.cpp +++ b/cpp/src/IcePatch2Lib/ClientUtil.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #define ICE_PATCH2_API_EXPORTS #include #include @@ -19,6 +19,7 @@ using namespace std; using namespace Ice; +using namespace IceUtil; using namespace IcePatch2; namespace IcePatch2 @@ -526,7 +527,7 @@ IcePatch2::Patcher::prepare() bool IcePatch2::Patcher::patch(const string& d) { - string dir = simplify(nativeToUTF8(_serverNoCompress->ice_getCommunicator(), d)); + string dir = simplify(d); if(dir.empty() || dir == ".") { @@ -649,11 +650,7 @@ IcePatch2::Patcher::init(const FileServerPrx& server) Ice::CommunicatorPtr communicator = server->ice_getCommunicator(); - // - // Transform dataDir to a UTF8 string (it's either read from the properties or - // provided by the user application directly). - // - const_cast(_dataDir) = simplify(nativeToUTF8(communicator, _dataDir)); + const_cast(_dataDir) = simplify(_dataDir); // // Make sure that _chunkSize doesn't exceed MessageSizeMax, otherwise diff --git a/cpp/src/IcePatch2Lib/Util.cpp b/cpp/src/IcePatch2Lib/Util.cpp index 7e49a32d2bf..2fc00be9d7c 100644 --- a/cpp/src/IcePatch2Lib/Util.cpp +++ b/cpp/src/IcePatch2Lib/Util.cpp @@ -422,8 +422,12 @@ IcePatch2::readDirectory(const string& pa) #ifdef _WIN32 + // + // IcePatch2 doesn't support to use string converters, so don't need to use + // any string converter in nativeToWnative or wnativeToNative conversions. + // StringSeq result; - const wstring fs = IceUtil::stringToWstring(simplify(path + "/*")); + const wstring fs = IceUtil::nativeToWnative(0, 0, simplify(path + "/*")); struct _wfinddata_t data; intptr_t h = _wfindfirst(fs.c_str(), &data); @@ -434,7 +438,7 @@ IcePatch2::readDirectory(const string& pa) while(true) { - string name = IceUtil::wstringToString(data.name); + string name = IceUtil::wnativeToNative(0, 0, data.name); assert(!name.empty()); if(name != ".." && name != ".") diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp index d630e8cbbf7..44c4704b2bc 100644 --- a/cpp/src/IceSSL/Instance.cpp +++ b/cpp/src/IceSSL/Instance.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -236,7 +235,8 @@ IceSSL::SharedInstance::SharedInstance(const CommunicatorPtr& communicator) : { RAND_load_file(randFile, 1024); } - string randFiles = Ice::nativeToUTF8(communicator, properties->getProperty("IceSSL.Random")); + + string randFiles = properties->getProperty("IceSSL.Random"); if(!randFiles.empty()) { @@ -246,7 +246,7 @@ IceSSL::SharedInstance::SharedInstance(const CommunicatorPtr& communicator) : #else const string sep = ":"; #endif - string defaultDir = Ice::nativeToUTF8(communicator, properties->getProperty("IceSSL.DefaultDir")); + string defaultDir = properties->getProperty("IceSSL.DefaultDir"); if(!IceUtilInternal::splitString(randFiles, sep, files)) { diff --git a/cpp/src/IceUtil/Exception.cpp b/cpp/src/IceUtil/Exception.cpp index a6c9ba96ceb..8498a6a5f55 100644 --- a/cpp/src/IceUtil/Exception.cpp +++ b/cpp/src/IceUtil/Exception.cpp @@ -39,7 +39,7 @@ #ifdef ICE_WIN32_STACK_TRACES # if defined(_MSC_VER) && _MSC_VER >= 1700 # define DBGHELP_TRANSLATE_TCHAR -# include +# include # endif # include # include @@ -207,6 +207,9 @@ getStackTrace() // TODO: call SymRefreshModuleList here? (not available on XP) +#ifdef DBGHELP_TRANSLATE_TCHAR + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); +#endif for(int i = 0; i < frames; i++) { if(!stackTrace.empty()) @@ -219,11 +222,16 @@ getStackTrace() DWORD64 address = reinterpret_cast(stack[i]); + // + // Don't need to use pass a wide string converter in the bellow + // calls to wnativeToNative as the wide strings come from + // Windows API. + // BOOL ok = SymFromAddr(process, address, 0, symbol); if(ok) { #ifdef DBGHELP_TRANSLATE_TCHAR - s << IceUtil::wstringToString(symbol->Name); + s << IceUtil::wnativeToNative(converter, 0, symbol->Name); #else s << symbol->Name; #endif @@ -231,8 +239,8 @@ getStackTrace() if(ok) { s << " at line " << line.LineNumber << " in " -#ifdef DBGHELP_TRANSLATE_TCHAR - << IceUtil::wstringToString(line.FileName); +#ifdef DBGHELP_TRANSLATE_TCHAR + << IceUtil::wnativeToNative(converter, 0, line.FileName); #else << line.FileName; #endif @@ -668,3 +676,47 @@ IceUtil::OptionalNotSetException::ice_throw() const throw *this; } +#ifndef _WIN32 +IceUtil::IconvInitializationException::IconvInitializationException(const char* file, int line, const string& reason) : + Exception(file, line), + _reason(reason) +{ +} + +IceUtil::IconvInitializationException::~IconvInitializationException() throw() +{ +} + +const char* IceUtil::IconvInitializationException::_name = "IceUtil::IconvInitializationException"; + +string +IceUtil::IconvInitializationException::ice_name() const +{ + return _name; +} + +void +IceUtil::IconvInitializationException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ": " << _reason; +} + +IceUtil::IconvInitializationException* +IceUtil::IconvInitializationException::ice_clone() const +{ + return new IconvInitializationException(*this); +} + +void +IceUtil::IconvInitializationException::ice_throw() const +{ + throw *this; +} + +string +IceUtil::IconvInitializationException::reason() const +{ + return _reason; +} +#endif diff --git a/cpp/src/IceUtil/FileUtil.cpp b/cpp/src/IceUtil/FileUtil.cpp index af8fcd66b60..d9080a3c62d 100644 --- a/cpp/src/IceUtil/FileUtil.cpp +++ b/cpp/src/IceUtil/FileUtil.cpp @@ -9,8 +9,8 @@ #include #include -#include #include +#include #include #include @@ -92,6 +92,26 @@ IceUtilInternal::fileExists(const string& path) return true; } +FILE* +IceUtilInternal::freopen(const std::string& path, const std::string& mode, FILE* stream) +{ +#ifdef _LARGEFILE64_SOURCE + return freopen64(path.c_str(), mode.c_str(), stream); +#else +# ifdef _WIN32 + // + // Don't need to use a wide string converter, the wide strings are directly passed + // to Windows API. + // + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); + return _wfreopen(IceUtil::nativeToWnative(converter, 0, path).c_str(), + IceUtil::nativeToWnative(converter, 0, mode).c_str(), stderr); +# else + return freopen(path.c_str(), mode.c_str(), stderr); +# endif +#endif +} + #ifdef _WIN32 // @@ -100,49 +120,78 @@ IceUtilInternal::fileExists(const string& path) int IceUtilInternal::stat(const string& path, structstat* buffer) { - return _wstat(IceUtil::stringToWstring(path).c_str(), buffer); + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + return _wstat(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), buffer); } int IceUtilInternal::remove(const string& path) { - return ::_wremove(IceUtil::stringToWstring(path).c_str()); + return ::_wremove(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str()); } int IceUtilInternal::rename(const string& from, const string& to) { - return ::_wrename(IceUtil::stringToWstring(from).c_str(), IceUtil::stringToWstring(to).c_str()); + // + // Don't need to use a wide string converter, the wide strings are directly passed + // to Windows API. + // + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); + return ::_wrename(IceUtil::nativeToWnative(converter, 0, from).c_str(), + IceUtil::nativeToWnative(converter, 0, to).c_str()); } int IceUtilInternal::rmdir(const string& path) { - return ::_wrmdir(IceUtil::stringToWstring(path).c_str()); + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + return ::_wrmdir(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str()); } int IceUtilInternal::mkdir(const string& path, int) { - return ::_wmkdir(IceUtil::stringToWstring(path).c_str()); + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + return ::_wmkdir(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str()); } FILE* IceUtilInternal::fopen(const string& path, const string& mode) { - return ::_wfopen(IceUtil::stringToWstring(path).c_str(), IceUtil::stringToWstring(mode).c_str()); + // + // Don't need to use a wide string converter, the wide strings are directly passed + // to Windows API. + // + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); + return ::_wfopen(IceUtil::nativeToWnative(converter, 0, path).c_str(), + IceUtil::nativeToWnative(converter, 0, mode).c_str()); } int IceUtilInternal::open(const string& path, int flags) { + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // if(flags & _O_CREAT) { - return ::_wopen(IceUtil::stringToWstring(path).c_str(), flags, _S_IREAD | _S_IWRITE); + return ::_wopen(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), + flags, _S_IREAD | _S_IWRITE); } else { - return ::_wopen(IceUtil::stringToWstring(path).c_str(), flags); + return ::_wopen(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), flags); } } @@ -150,12 +199,16 @@ IceUtilInternal::open(const string& path, int flags) int IceUtilInternal::getcwd(string& cwd) { + // + // Don't need to use a wide string converter, the wide string come + // from Windows API. + // wchar_t cwdbuf[_MAX_PATH]; if(_wgetcwd(cwdbuf, _MAX_PATH) == NULL) { return -1; } - cwd = IceUtil::wstringToString(cwdbuf); + cwd = IceUtil::wnativeToNative(IceUtil::getProcessStringConverter(), 0, cwdbuf); return 0; } #endif @@ -163,7 +216,11 @@ IceUtilInternal::getcwd(string& cwd) int IceUtilInternal::unlink(const string& path) { - return _wunlink(IceUtil::stringToWstring(path).c_str()); + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + return _wunlink(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str()); } int @@ -180,14 +237,18 @@ IceUtilInternal::FileLock::FileLock(const std::string& path) : _fd(INVALID_HANDLE_VALUE), _path(path) { + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // #ifndef ICE_OS_WINRT - _fd = ::CreateFileW(IceUtil::stringToWstring(path).c_str(), GENERIC_WRITE, 0, NULL, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + _fd = ::CreateFileW(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), + GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); #else CREATEFILE2_EXTENDED_PARAMETERS params; params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; - _fd = ::CreateFile2(IceUtil::stringToWstring(path).c_str(), GENERIC_WRITE, 0, - OPEN_ALWAYS, ¶ms); + _fd = ::CreateFile2(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), + GENERIC_WRITE, 0, OPEN_ALWAYS, ¶ms); #endif _path = path; @@ -241,7 +302,11 @@ IceUtilInternal::ifstream::ifstream(const string& path, ios_base::openmode mode) #ifdef __MINGW32__ std::ifstream(path.c_str(), mode) #else - std::ifstream(IceUtil::stringToWstring(path).c_str(), mode) + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + std::ifstream(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), mode) #endif { } @@ -252,7 +317,11 @@ IceUtilInternal::ifstream::open(const string& path, ios_base::openmode mode) #ifdef __MINGW32__ std::ifstream::open(path.c_str(), mode); #else - std::ifstream::open(IceUtil::stringToWstring(path).c_str(), mode); + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + std::ifstream::open(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), mode); #endif } @@ -264,7 +333,11 @@ IceUtilInternal::ofstream::ofstream(const string& path, ios_base::openmode mode) #ifdef __MINGW32__ std::ofstream(path.c_str(), mode) #else - std::ofstream(IceUtil::stringToWstring(path).c_str(), mode) + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + std::ofstream(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), mode) #endif { } @@ -275,7 +348,11 @@ IceUtilInternal::ofstream::open(const string& path, ios_base::openmode mode) #ifdef __MINGW32__ std::ofstream::open(path.c_str(), mode); #else - std::ofstream::open(IceUtil::stringToWstring(path).c_str(), mode); + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + std::ofstream::open(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(), mode); #endif } diff --git a/cpp/src/IceUtil/Makefile b/cpp/src/IceUtil/Makefile index 1b02c312713..d5814dc8e49 100644 --- a/cpp/src/IceUtil/Makefile +++ b/cpp/src/IceUtil/Makefile @@ -34,14 +34,15 @@ OBJS = ArgVector.o \ UUID.o \ Unicode.o \ MutexProtocol.o \ - FileUtil.o + FileUtil.o \ + StringConverter.o SRCS = $(OBJS:.o=.cpp) include $(top_srcdir)/config/Make.rules CPPFLAGS := $(CPPFLAGS) $(ICEUTIL_FLAGS) -DICE_UTIL_API_EXPORTS -I.. -LINKWITH := $(ICEUTIL_OS_LIBS) +LINKWITH := $(ICEUTIL_OS_LIBS) $(ICONV_LIBS) ifeq ($(STATICLIBS),yes) $(libdir)/$(LIBNAME): $(OBJS) diff --git a/cpp/src/IceUtil/Makefile.mak b/cpp/src/IceUtil/Makefile.mak index 2ff65bcb1a6..799d2091f28 100644 --- a/cpp/src/IceUtil/Makefile.mak +++ b/cpp/src/IceUtil/Makefile.mak @@ -34,7 +34,8 @@ OBJS = ArgVector.obj \ Timer.obj \ UUID.obj \ Unicode.obj \ - MutexProtocol.obj + MutexProtocol.obj \ + StringConverter.obj SRCS = $(OBJS:.obj=.cpp) diff --git a/cpp/src/IceUtil/StringConverter.cpp b/cpp/src/IceUtil/StringConverter.cpp new file mode 100644 index 00000000000..2a57b719695 --- /dev/null +++ b/cpp/src/IceUtil/StringConverter.cpp @@ -0,0 +1,478 @@ + +#include +#include +#include +#include +#include + +using namespace IceUtil; +using namespace IceUtilInternal; +using namespace std; + +namespace +{ + +IceUtil::Mutex* processStringConverterMutex = 0; +IceUtil::StringConverterPtr processStringConverter; +IceUtil::WstringConverterPtr processWstringConverter; + +class Init +{ +public: + + Init() + { + processStringConverterMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete processStringConverterMutex; + processStringConverterMutex = 0; + } +}; + +Init init; + +const char* __IceUtil__IllegalConversionException_name = "IceUtil::IllegalConversionException"; + +} + +IllegalConversionException::IllegalConversionException(const char* file, int line) : + ::IceUtil::Exception(file, line) +{ +} + +IllegalConversionException::IllegalConversionException(const char* file, int line, const string& reason) : + ::IceUtil::Exception(file, line), + _reason(reason) +{ +} + +IllegalConversionException::~IllegalConversionException() throw() +{ +} + +string +IllegalConversionException::ice_name() const +{ + return __IceUtil__IllegalConversionException_name; +} + +void +IllegalConversionException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ": " << _reason; +} + +IceUtil::IllegalConversionException* +IllegalConversionException::ice_clone() const +{ + return new IllegalConversionException(*this); +} + +void +IllegalConversionException::ice_throw() const +{ + throw *this; +} + +string +IllegalConversionException::reason() const +{ + return _reason; +} + + +namespace +{ + +class UTF8BufferI : public UTF8Buffer +{ +public: + + UTF8BufferI() : + _buffer(0), + _offset(0) + { + } + + ~UTF8BufferI() + { + free(_buffer); + } + + Byte* getMoreBytes(size_t howMany, Byte* firstUnused) + { + if(_buffer == 0) + { + _buffer = (Byte*)malloc(howMany); + } + else + { + assert(firstUnused != 0); + _offset = firstUnused - _buffer; + _buffer = (Byte*)realloc(_buffer, _offset + howMany); + } + + if(!_buffer) + { + throw std::bad_alloc(); + } + return _buffer + _offset; + } + + Byte* getBuffer() + { + return _buffer; + } + + void reset() + { + free(_buffer); + _buffer = 0; + _offset = 0; + } + +private: + + IceUtil::Byte* _buffer; + size_t _offset; +}; + +} + +StringConverterPtr +IceUtil::getProcessStringConverter() +{ + IceUtilInternal::MutexPtrLock lock(processStringConverterMutex); + return processStringConverter; +} + +void +IceUtil::setProcessStringConverter(const StringConverterPtr& converter) +{ + IceUtilInternal::MutexPtrLock lock(processStringConverterMutex); + processStringConverter = converter; +} + +WstringConverterPtr +IceUtil::getProcessWstringConverter() +{ + IceUtilInternal::MutexPtrLock lock(processStringConverterMutex); + return processWstringConverter; +} + +void +IceUtil::setProcessWstringConverter(const WstringConverterPtr& converter) +{ + IceUtilInternal::MutexPtrLock lock(processStringConverterMutex); + processWstringConverter = converter; +} + +string +IceUtil::nativeToUTF8(const IceUtil::StringConverterPtr& converter, const string& str) +{ + if(!converter || str.empty()) + { + return str; + } + UTF8BufferI buffer; + Byte* last = converter->toUTF8(str.data(), str.data() + str.size(), buffer); + return string(reinterpret_cast(buffer.getBuffer()), last - buffer.getBuffer()); +} + +string +IceUtil::UTF8ToNative(const IceUtil::StringConverterPtr& converter, const string& str) +{ + if(!converter || str.empty()) + { + return str; + } + string tmp; + converter->fromUTF8(reinterpret_cast(str.data()), + reinterpret_cast(str.data() + str.size()), tmp); + return tmp; +} + +string +IceUtil::wnativeToNative(const StringConverterPtr& converter, const WstringConverterPtr& wConverter, const wstring& v) +{ + string target; + if(!v.empty()) + { + // + // First convert to UTF8 narrow string. + // + if(wConverter) + { + UTF8BufferI buffer; + Byte* last = wConverter->toUTF8(v.data(), v.data() + v.size(), buffer); + target = string(reinterpret_cast(buffer.getBuffer()), last - buffer.getBuffer()); + } + else + { + size_t size = v.size() * 4 * sizeof(char); + + Byte* outBuf = new Byte[size]; + Byte* targetStart = outBuf; + Byte* targetEnd = outBuf + size; + + const wchar_t* sourceStart = v.data(); + + ConversionResult cr = + convertUTFWstringToUTF8( + sourceStart, sourceStart + v.size(), + targetStart, targetEnd, lenientConversion); + + if(cr != conversionOK) + { + delete[] outBuf; + assert(cr == sourceExhausted || cr == sourceIllegal); + throw UTFConversionException(__FILE__, __LINE__, + cr == sourceExhausted ? partialCharacter : badEncoding); + } + + target = string(reinterpret_cast(outBuf), static_cast(targetStart - outBuf)); + delete[] outBuf; + } + + // + // If narrow string converter is present convert to the native narrow string encoding, otherwise + // native narrow string encoding is UTF8 and we are done. + // + if(converter) + { + string tmp; + converter->fromUTF8(reinterpret_cast(target.data()), + reinterpret_cast(target.data() + target.size()), tmp); + tmp.swap(target); + } + } + return target; +} + +wstring +IceUtil::nativeToWnative(const StringConverterPtr& converter, const WstringConverterPtr& wConverter, const string& v) +{ + wstring target; + if(!v.empty()) + { + // + // If there is a narrow string converter use it to convert to UTF8, otherwise the narrow + // string is already UTF8 encoded. + // + string tmp; + if(converter) + { + UTF8BufferI buffer; + Byte* last = converter->toUTF8(v.data(), v.data() + v.size(), buffer); + tmp = string(reinterpret_cast(buffer.getBuffer()), last - buffer.getBuffer()); + } + else + { + tmp = v; + } + + // + // If there is a wide string converter use fromUTF8 to convert to the wide string native encoding. + // + if(wConverter) + { + wConverter->fromUTF8(reinterpret_cast(tmp.data()), + reinterpret_cast(tmp.data() + tmp.size()), target); + } + else + { + const Byte* sourceStart = reinterpret_cast(tmp.data()); + + ConversionResult cr = + convertUTF8ToUTFWstring(sourceStart, sourceStart + tmp.size(), target, lenientConversion); + + if(cr != conversionOK) + { + assert(cr == sourceExhausted || cr == sourceIllegal); + + throw UTFConversionException(__FILE__, __LINE__, + cr == sourceExhausted ? partialCharacter : badEncoding); + } + } + } + return target; +} + +UnicodeWstringConverter::UnicodeWstringConverter(ConversionFlags flags) : + _conversionFlags(flags) +{ +} + +Byte* +UnicodeWstringConverter::toUTF8(const wchar_t* sourceStart, + const wchar_t* sourceEnd, + UTF8Buffer& buffer) const +{ + // + // The "chunk size" is the maximum of the number of characters in the + // source and 6 (== max bytes necessary to encode one Unicode character). + // + size_t chunkSize = std::max(static_cast(sourceEnd - sourceStart), 6); + + Byte* targetStart = buffer.getMoreBytes(chunkSize, 0); + Byte* targetEnd = targetStart + chunkSize; + + ConversionResult result; + + while((result = + convertUTFWstringToUTF8(sourceStart, sourceEnd, + targetStart, targetEnd, _conversionFlags)) + == targetExhausted) + { + targetStart = buffer.getMoreBytes(chunkSize, targetStart); + targetEnd = targetStart + chunkSize; + } + + switch(result) + { + case conversionOK: + break; + case sourceExhausted: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "wide string source exhausted"); + case sourceIllegal: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "wide string source illegal"); + default: + { + assert(0); + throw IceUtil::IllegalConversionException(__FILE__, __LINE__); + } + } + return targetStart; +} + + +void +UnicodeWstringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, + wstring& target) const +{ + if(sourceStart == sourceEnd) + { + target = L""; + return; + } + + ConversionResult result = + convertUTF8ToUTFWstring(sourceStart, sourceEnd, target, _conversionFlags); + + switch(result) + { + case conversionOK: + break; + case sourceExhausted: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "UTF-8 string source exhausted"); + case sourceIllegal: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "UTF-8 string source illegal"); + default: + { + assert(0); + throw IceUtil::IllegalConversionException(__FILE__, __LINE__); + } + } +} + +#ifdef _WIN32 +WindowsStringConverter::WindowsStringConverter(unsigned int cp) : + _cp(cp) +{ +} + +Byte* +WindowsStringConverter::toUTF8(const char* sourceStart, + const char* sourceEnd, + UTF8Buffer& buffer) const +{ + // + // First convert to UTF-16 + // + int sourceSize = static_cast(sourceEnd - sourceStart); + if(sourceSize == 0) + { + return buffer.getMoreBytes(1, 0); + } + + int size = 0; + int writtenWchar = 0; + ScopedArray wbuffer; + + // + // The following code pages doesn't support MB_ERR_INVALID_CHARS flag + // see http://msdn.microsoft.com/en-us/library/windows/desktop/dd319072(v=vs.85).aspx + // + DWORD flags = + (_cp == 50220 || _cp == 50221 || _cp == 50222 || + _cp == 50225 || _cp == 50227 || _cp == 50229 || + _cp == 65000 || _cp == 42 || (_cp >= 57002 && _cp <= 57011)) ? 0 : MB_ERR_INVALID_CHARS; + + do + { + size = size == 0 ? sourceSize + 2 : 2 * size; + wbuffer.reset(new wchar_t[size]); + + writtenWchar = MultiByteToWideChar(_cp, flags, sourceStart, + sourceSize, wbuffer.get(), size); + } while(writtenWchar == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + if(writtenWchar == 0) + { + throw IllegalConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString()); + } + + // + // Then convert this UTF-16 wbuffer into UTF-8 + // + return _unicodeWstringConverter.toUTF8(wbuffer.get(), wbuffer.get() + writtenWchar, buffer); +} + +void +WindowsStringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, + string& target) const +{ + if(sourceStart == sourceEnd) + { + target = ""; + return; + } + + // + // First convert to wstring (UTF-16) + // + wstring wtarget; + _unicodeWstringConverter.fromUTF8(sourceStart, sourceEnd, wtarget); + + // + // WC_ERR_INVALID_CHARS conversion flag is only supported with 65001 (UTF-8) and + // 54936 (GB18030 Simplified Chinese) + // + DWORD flags = (_cp == 65001 || _cp == 54936) ? WC_ERR_INVALID_CHARS : 0; + // + // And then to a multi-byte narrow string + // + int size = 0; + int writtenChar = 0; + ScopedArray buffer; + do + { + size = size == 0 ? static_cast(sourceEnd - sourceStart) + 2 : 2 * size; + buffer.reset(new char[size]); + writtenChar = WideCharToMultiByte(_cp, flags, wtarget.data(), static_cast(wtarget.size()), + buffer.get(), size, 0, 0); + } while(writtenChar == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + if(writtenChar == 0) + { + throw IllegalConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString()); + } + + target.assign(buffer.get(), writtenChar); +} + +#endif diff --git a/cpp/src/IceUtil/StringUtil.cpp b/cpp/src/IceUtil/StringUtil.cpp index 55ce5c65d25..16d7c9f18bf 100644 --- a/cpp/src/IceUtil/StringUtil.cpp +++ b/cpp/src/IceUtil/StringUtil.cpp @@ -8,11 +8,11 @@ // ********************************************************************** #include -#include +#include #include #ifdef ICE_OS_WINRT -#include +# include #endif using namespace std; @@ -575,7 +575,7 @@ IceUtilInternal::errorToString(int error, LPCVOID source) LocalFree(msg); } #endif - return IceUtil::wstringToString(result); + return wnativeToNative(getProcessStringConverter(), getProcessWstringConverter(), result); } else { diff --git a/cpp/src/Slice/Preprocessor.cpp b/cpp/src/Slice/Preprocessor.cpp index a4981328ed7..da37e868ef9 100644 --- a/cpp/src/Slice/Preprocessor.cpp +++ b/cpp/src/Slice/Preprocessor.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -232,7 +233,11 @@ Slice::Preprocessor::preprocess(bool keepComments, const string& extraArgs) wchar_t* name = _wtempnam(NULL, L".preprocess"); if(name) { - _cppFile = IceUtil::wstringToString(name); + // + // Don't need to pass a wide string converter the wide string + // come from Windows API. + // + _cppFile = IceUtil::wnativeToNative(IceUtil::getProcessStringConverter(), 0, name); free(name); _cppHandle = IceUtilInternal::fopen(_cppFile, "w+"); } diff --git a/cpp/src/iceserviceinstall/ServiceInstaller.cpp b/cpp/src/iceserviceinstall/ServiceInstaller.cpp index 3e51e782638..527484d1f26 100644 --- a/cpp/src/iceserviceinstall/ServiceInstaller.cpp +++ b/cpp/src/iceserviceinstall/ServiceInstaller.cpp @@ -55,7 +55,6 @@ IceServiceInstaller::IceServiceInstaller(int serviceType, const string& configFi // // Compute _serviceName // - if(_serviceType == icegridregistry) { @@ -268,20 +267,24 @@ IceServiceInstaller::install(const PropertiesPtr& properties) bool autoStart = properties->getPropertyAsIntWithDefault("AutoStart", 1) != 0; string password = properties->getProperty("Password"); + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // SC_HANDLE service = CreateServiceW( scm, - IceUtil::stringToWstring(_serviceName).c_str(), - IceUtil::stringToWstring(displayName).c_str(), + IceUtil::nativeToWnative(0, 0, _serviceName).c_str(), + IceUtil::nativeToWnative(0, 0, displayName).c_str(), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, autoStart ? SERVICE_AUTO_START : SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, - IceUtil::stringToWstring(command).c_str(), + IceUtil::nativeToWnative(0, 0, command).c_str(), 0, 0, - IceUtil::stringToWstring(deps).c_str(), - IceUtil::stringToWstring(_sidName).c_str(), - IceUtil::stringToWstring(password).c_str()); + IceUtil::nativeToWnative(0, 0, deps).c_str(), + IceUtil::nativeToWnative(0, 0, _sidName).c_str(), + IceUtil::nativeToWnative(0, 0, password).c_str()); if(service == 0) { @@ -293,7 +296,7 @@ IceServiceInstaller::install(const PropertiesPtr& properties) // // Set description // - wstring uDescription = IceUtil::stringToWstring(description); + wstring uDescription = IceUtil::nativeToWnative(0, 0, description); SERVICE_DESCRIPTIONW sd = { const_cast(uDescription.c_str()) }; if(!ChangeServiceConfig2W(service, SERVICE_CONFIG_DESCRIPTION, &sd)) @@ -318,7 +321,11 @@ IceServiceInstaller::uninstall() throw "Cannot open SCM: " + IceUtilInternal::errorToString(res); } - SC_HANDLE service = OpenServiceW(scm, IceUtil::stringToWstring(_serviceName).c_str(), SERVICE_ALL_ACCESS); + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // + SC_HANDLE service = OpenServiceW(scm, IceUtil::nativeToWnative(0, 0, _serviceName).c_str(), SERVICE_ALL_ACCESS); if(service == 0) { DWORD res = GetLastError(); @@ -412,8 +419,12 @@ IceServiceInstaller::initializeSid(const string& name) DWORD domainNameSize = 32; IceUtil::ScopedArray domainName(new wchar_t[domainNameSize]); + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // SID_NAME_USE nameUse; - while(LookupAccountNameW(0, IceUtil::stringToWstring(name).c_str(), _sidBuffer.get(), &sidSize, domainName.get(), + while(LookupAccountNameW(0, IceUtil::nativeToWnative(0, 0, name).c_str(), _sidBuffer.get(), &sidSize, domainName.get(), &domainNameSize, &nameUse) == false) { DWORD res = GetLastError(); @@ -458,7 +469,7 @@ IceServiceInstaller::initializeSid(const string& name) throw "Could not retrieve full account name for " + name + ": " + IceUtilInternal::errorToString(res); } - _sidName = IceUtil::wstringToString(domainName) + "\\" + IceUtil::wstringToString(accountName); + _sidName = IceUtil::wnativeToNative(0, 0, domainName) + "\\" + IceUtil::wnativeToNative(0, 0, accountName); } if(_debug) @@ -466,7 +477,7 @@ IceServiceInstaller::initializeSid(const string& name) Trace trace(_communicator->getLogger(), "IceServiceInstaller"); wchar_t* sidString = 0; ConvertSidToStringSidW(_sid, &sidString); - trace << "SID: " << IceUtil::wstringToString(sidString) << "; "; + trace << "SID: " << IceUtil::wnativeToNative(0, 0, sidString) << "; "; LocalFree(sidString); trace << "Full name: " << _sidName; } @@ -509,8 +520,12 @@ IceServiceInstaller::grantPermissions(const string& path, SE_OBJECT_TYPE type, b PACL acl = 0; PACL newAcl = 0; PSECURITY_DESCRIPTOR sd = 0; - DWORD res = GetNamedSecurityInfoW(const_cast(IceUtil::stringToWstring(path).c_str()), type, - DACL_SECURITY_INFORMATION, 0, 0, &acl, 0, &sd); + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // + DWORD res = GetNamedSecurityInfoW(const_cast(IceUtil::nativeToWnative(0, 0, path).c_str()), type, + DACL_SECURITY_INFORMATION, 0, 0, &acl, 0, &sd); if(res != ERROR_SUCCESS) { throw "Could not retrieve securify info for " + path + ": " + IceUtilInternal::errorToString(res); @@ -591,8 +606,12 @@ IceServiceInstaller::grantPermissions(const string& path, SE_OBJECT_TYPE type, b throw "Could not modify ACL for " + path + ": " + IceUtilInternal::errorToString(res); } - res = SetNamedSecurityInfoW(const_cast(IceUtil::stringToWstring(path).c_str()), type, - DACL_SECURITY_INFORMATION, 0, 0, newAcl, 0); + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // + res = SetNamedSecurityInfoW(const_cast(IceUtil::nativeToWnative(0, 0, path).c_str()), type, + DACL_SECURITY_INFORMATION, 0, 0, newAcl, 0); if(res != ERROR_SUCCESS) { throw "Could not grant access to " + _sidName + " on " + path + ": " + @@ -620,7 +639,11 @@ IceServiceInstaller::grantPermissions(const string& path, SE_OBJECT_TYPE type, b bool IceServiceInstaller::mkdir(const string& path) const { - if(CreateDirectoryW(IceUtil::stringToWstring(path).c_str(), 0) == 0) + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // + if(CreateDirectoryW(IceUtil::nativeToWnative(0, 0, path).c_str(), 0) == 0) { DWORD res = GetLastError(); if(res == ERROR_ALREADY_EXISTS) @@ -655,7 +678,11 @@ IceServiceInstaller::addLog(const string& log) const HKEY key = 0; DWORD disposition = 0; - LONG res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, IceUtil::stringToWstring(createLog(log)).c_str(), 0, L"REG_SZ", + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // + LONG res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, IceUtil::nativeToWnative(0, 0, createLog(log)).c_str(), 0, L"REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &key, &disposition); if(res != ERROR_SUCCESS) @@ -673,7 +700,11 @@ IceServiceInstaller::addLog(const string& log) const void IceServiceInstaller::removeLog(const string& log) const { - LONG res = RegDeleteKeyW(HKEY_LOCAL_MACHINE, IceUtil::stringToWstring(createLog(log)).c_str()); + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // + LONG res = RegDeleteKeyW(HKEY_LOCAL_MACHINE, IceUtil::nativeToWnative(0, 0, createLog(log)).c_str()); // // We get ERROR_ACCESS_DENIED when the log is shared by several sources @@ -687,9 +718,13 @@ IceServiceInstaller::removeLog(const string& log) const void IceServiceInstaller::addSource(const string& source, const string& log, const string& resourceFile) const { + // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // HKEY key = 0; DWORD disposition = 0; - LONG res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, IceUtil::stringToWstring(createSource(source, log)).c_str(), + LONG res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, IceUtil::nativeToWnative(0, 0, createSource(source, log)).c_str(), 0, L"REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &key, &disposition); if(res != ERROR_SUCCESS) { @@ -702,7 +737,7 @@ IceServiceInstaller::addSource(const string& source, const string& log, const st // DLL. // res = RegSetValueExW(key, L"EventMessageFile", 0, REG_EXPAND_SZ, - reinterpret_cast(IceUtil::stringToWstring(resourceFile).c_str()), + reinterpret_cast(IceUtil::nativeToWnative(0, 0, resourceFile).c_str()), static_cast(resourceFile.length() + 1) * sizeof(wchar_t)); if(res == ERROR_SUCCESS) @@ -759,9 +794,12 @@ IceServiceInstaller::removeSource(const string& source) const // // Check if we can delete the source sub-key // + // We don't support to use a string converter with this tool, so don't need to + // use string converters in calls to nativeToWnative. + // LONG delRes = RegDeleteKeyW(HKEY_LOCAL_MACHINE, - IceUtil::stringToWstring(createSource(source, - IceUtil::wstringToString(subkey))).c_str()); + IceUtil::nativeToWnative(0, 0, createSource(source, + IceUtil::wnativeToNative(0, 0, subkey))).c_str()); if(delRes == ERROR_SUCCESS) { res = RegCloseKey(key); @@ -769,7 +807,7 @@ IceServiceInstaller::removeSource(const string& source) const { throw "Could not close registry key handle: " + IceUtilInternal::errorToString(res); } - return IceUtil::wstringToString(subkey); + return IceUtil::wnativeToNative(0, 0, subkey); } ++index; diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 40edd85266c..babb4fcceb3 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -444,7 +444,7 @@ Slice::Gen::generate(const UnitPtr& p) H << "\n#include <" << changeInclude(*q, _includePaths) << "." << extension << ">"; } - H << "\n#include "; + H << "\n#include "; if(_ice) { -- cgit v1.2.3