diff options
98 files changed, 2183 insertions, 1380 deletions
@@ -46,7 +46,26 @@ General Changes to classes. It also supports the use of compact type IDs for classes. +C++ Changes +=========== +- Added per process string converters for narrow and wide strings, + setProcessStringConverter and getProcessStringConverter in IceUtil + namespace can be used to establish and access the process narrow + string converter, likewise setProcessWstringConverter and + getProcessWstringConverter can be used to establish and access the + process wide string converter. + +- Added Ice.LogStdErr.Convert property which control whenever or not + the default StdErr logger convert messages from native narrow encoding + to the console code page, the default value is 1 meaning by default + messages are converted to the console code page encoding, the property + doesn't affect non Windows OS. + +- Added IceUtil::nativeToWnative and IceUtil::wnativeToNative functions + which allow to convert between narrow and wide strings, stringToWstring + and wstringToString have been deprecated. + Python Changes ============== diff --git a/config/PropertyNames.xml b/config/PropertyNames.xml index 9adb5eaa12d..86115b0ac40 100644 --- a/config/PropertyNames.xml +++ b/config/PropertyNames.xml @@ -334,6 +334,7 @@ generated from the section label. <property name="ImplicitContext" /> <property name="InitPlugins" /> <property name="LogFile" /> + <property name="LogStdErr.Convert"/> <property name="MessageSizeMax" /> <property name="MonitorConnections" /> <property name="Nohup" /> diff --git a/config/makeprops.py b/config/makeprops.py index fcbb9ef1bd5..74ad44ae15d 100755 --- a/config/makeprops.py +++ b/config/makeprops.py @@ -700,7 +700,8 @@ def main(): contentHandler = MultiHandler(infile, "") contentHandler.addHandlers([CppPropertyHandler(infile, className), JavaPropertyHandler(infile, className), - CSPropertyHandler(infile, className)]) + CSPropertyHandler(infile, className), + JSPropertyHandler(infile, className)]) else: if lang == "cpp": contentHandler = CppPropertyHandler(infile, className) diff --git a/cpp/config/Make.rules.msvc b/cpp/config/Make.rules.msvc index dc53ec96b69..13cb14a2cf6 100755 --- a/cpp/config/Make.rules.msvc +++ b/cpp/config/Make.rules.msvc @@ -103,7 +103,6 @@ ICEUTIL_OS_LIBS = $(ICE_OS_LIBS) DbgHelp.lib BZIP2_LIBS = libbz2$(LIBSUFFIX).lib DB_LIBS = libdb53$(LIBSUFFIX).lib MCPP_LIBS = mcpp$(LIBSUFFIX).lib -ICONV_LIB = libiconv.lib !endif !if "$(WINRT)" != "yes" diff --git a/cpp/demo/Glacier2/chat/config.client b/cpp/demo/Glacier2/chat/config.client index 3343510feab..0b3f70d0005 100644 --- a/cpp/demo/Glacier2/chat/config.client +++ b/cpp/demo/Glacier2/chat/config.client @@ -58,7 +58,7 @@ Ice.RetryIntervals=-1 # SSL Configuration # Ice.Plugin.IceSSL=IceSSL:createIceSSL -IceSSL.DefaultDir=../../../../certs/wss +IceSSL.DefaultDir=../../../../certs IceSSL.CertAuthFile=cacert.pem IceSSL.CertFile=c_rsa1024_pub.pem IceSSL.KeyFile=c_rsa1024_priv.pem diff --git a/cpp/demo/Ice/MFC/client/HelloClientDlg.cpp b/cpp/demo/Ice/MFC/client/HelloClientDlg.cpp index aaffc82453d..af3a92b9a5f 100644 --- a/cpp/demo/Ice/MFC/client/HelloClientDlg.cpp +++ b/cpp/demo/Ice/MFC/client/HelloClientDlg.cpp @@ -390,7 +390,7 @@ CHelloClientDlg::createProxy() { CString h; _host->GetWindowText(h); - string host = IceUtil::wstringToString(wstring(h)); + string host = IceUtil::wnativeToNative(getProcessStringConverter(), 0, wstring(h)); if(host.size() == 0) { _status->SetWindowText(CString(" No hostname")); diff --git a/cpp/demo/Ice/converter/Client.cpp b/cpp/demo/Ice/converter/Client.cpp index 7f7d39dca86..6b18da8277f 100644 --- a/cpp/demo/Ice/converter/Client.cpp +++ b/cpp/demo/Ice/converter/Client.cpp @@ -7,10 +7,8 @@ // // ********************************************************************** -#include <IceUtil/IceUtil.h> -#include <Ice/Ice.h> +#include <Client.h> #include <Greet.h> -#include <StringConverterI.h> using namespace std; using namespace Demo; @@ -20,14 +18,14 @@ menu() { cout << "usage:\n" - "t: send greeting with conversion\n" - "u: send greeting without conversion\n" + "t: send greeting\n" "s: shutdown server\n" "x: exit\n" "?: help\n"; } -string decodeString(const string& str) +string +decodeString(const string& str) { ostringstream result; for(string::const_iterator p = str.begin(); p != str.end(); ++p) @@ -46,7 +44,7 @@ string decodeString(const string& str) } int -run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator1, const Ice::CommunicatorPtr& communicator2) +Demo::Client::run(int argc, char* argv[]) { if(argc > 1) { @@ -55,15 +53,8 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator1, const Ice } const string proxyProperty = "Greet.Proxy"; - GreetPrx greet1 = GreetPrx::checkedCast(communicator1->propertyToProxy(proxyProperty)); - if(!greet1) - { - cerr << argv[0] << ": invalid proxy" << endl; - return EXIT_FAILURE; - } - - GreetPrx greet2 = GreetPrx::checkedCast(communicator2->propertyToProxy(proxyProperty)); - if(!greet2) + GreetPrx greet = GreetPrx::checkedCast(communicator()->propertyToProxy(proxyProperty)); + if(!greet) { cerr << argv[0] << ": invalid proxy" << endl; return EXIT_FAILURE; @@ -82,17 +73,12 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator1, const Ice cin >> c; if(c == 't') { - string ret = greet1->exchangeGreeting(greeting); - cout << "Received: \"" << decodeString(ret) << '\"' << endl; - } - else if(c == 'u') - { - string ret = greet2->exchangeGreeting(greeting); + string ret = greet->exchangeGreeting(greeting); cout << "Received: \"" << decodeString(ret) << '\"' << endl; } else if(c == 's') { - greet1->shutdown(); + greet->shutdown(); } else if(c == 'x') { @@ -117,64 +103,3 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator1, const Ice return EXIT_SUCCESS; } - -int -main(int argc, char* argv[]) -{ - int status; - Ice::CommunicatorPtr communicator1; - Ice::CommunicatorPtr communicator2; - - try - { - // - // Create two communicators, one with string converter configured - // and one without. - // - Ice::InitializationData initData; - initData.stringConverter = new StringConverterI(); - initData.properties = Ice::createProperties(initData.stringConverter); - initData.properties->load("config.client"); - communicator1 = Ice::initialize(argc, argv, initData); - - Ice::InitializationData initData2; - initData2.properties = Ice::createProperties(); - initData2.properties->load("config.client"); - communicator2 = Ice::initialize(argc, argv, initData2); - - status = run(argc, argv, communicator1, communicator2); - } - catch(const Ice::Exception& ex) - { - cerr << ex << endl; - status = EXIT_FAILURE; - } - - if(communicator1) - { - try - { - communicator1->destroy(); - } - catch(const Ice::Exception& ex) - { - cerr << ex << endl; - status = EXIT_FAILURE; - } - } - - if(communicator2) - { - try - { - communicator2->destroy(); - } - catch(const Ice::Exception& ex) - { - cerr << ex << endl; - status = EXIT_FAILURE; - } - } - - return status; -} diff --git a/cpp/demo/Ice/converter/Client.h b/cpp/demo/Ice/converter/Client.h new file mode 100644 index 00000000000..a8ed20f431c --- /dev/null +++ b/cpp/demo/Ice/converter/Client.h @@ -0,0 +1,25 @@ +// ********************************************************************** +// +// 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 DEMO_CLIENT_H +#define DEMO_CLIENT_H + +#include <Ice/Ice.h> + +namespace Demo +{ + +class Client : public Ice::Application +{ + virtual int run(int, char*[]); +}; + +} + +#endif
\ No newline at end of file diff --git a/cpp/demo/Ice/converter/ClientWithConverter.cpp b/cpp/demo/Ice/converter/ClientWithConverter.cpp new file mode 100644 index 00000000000..567bea9f203 --- /dev/null +++ b/cpp/demo/Ice/converter/ClientWithConverter.cpp @@ -0,0 +1,36 @@ +// ********************************************************************** +// +// 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 <Client.h> +#include <StringConverterI.h> + +using namespace std; +using namespace Demo; + +int +main(int argc, char* argv[]) +{ + int status = EXIT_SUCCESS; + try + { + // + // Set the process string converter and then initialize the + // aplication. + // + IceUtil::setProcessStringConverter(new StringConverterI()); + Client app; + status = app.main(argc, argv, "config.client"); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + return status; +} diff --git a/cpp/demo/Ice/converter/ClientWithoutConverter.cpp b/cpp/demo/Ice/converter/ClientWithoutConverter.cpp new file mode 100644 index 00000000000..1e04cc4a934 --- /dev/null +++ b/cpp/demo/Ice/converter/ClientWithoutConverter.cpp @@ -0,0 +1,30 @@ +// ********************************************************************** +// +// 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 <Client.h> + +using namespace std; +using namespace Demo; + +int +main(int argc, char* argv[]) +{ + int status = EXIT_SUCCESS; + try + { + Client app; + status = app.main(argc, argv, "config.client"); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + return status; +} diff --git a/cpp/demo/Ice/converter/Makefile b/cpp/demo/Ice/converter/Makefile index 0bb6cb8def0..3b724a84445 100644 --- a/cpp/demo/Ice/converter/Makefile +++ b/cpp/demo/Ice/converter/Makefile @@ -9,15 +9,20 @@ top_srcdir = ../../.. -CLIENT = client +CLIENT1 = client1 +CLIENT2 = client2 SERVER = server -TARGETS = $(CLIENT) $(SERVER) +TARGETS = $(CLIENT1) $(CLIENT2) $(SERVER) OBJS = Greet.o -COBJS = Client.o \ - StringConverterI.o +C1OBJS = Client.o \ + StringConverterI.o \ + ClientWithConverter.o + +C2OBJS = Client.o \ + ClientWithoutConverter.o SOBJS = GreetI.o \ Server.o @@ -32,9 +37,13 @@ include $(top_srcdir)/config/Make.rules CPPFLAGS := -I. $(CPPFLAGS) -$(CLIENT): $(OBJS) $(COBJS) +$(CLIENT1): $(OBJS) $(C1OBJS) rm -f $@ - $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(COBJS) $(LIBS) + $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(C1OBJS) $(LIBS) + +$(CLIENT2): $(OBJS) $(C2OBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(C2OBJS) $(LIBS) $(SERVER): $(OBJS) $(SOBJS) rm -f $@ diff --git a/cpp/demo/Ice/converter/Makefile.mak b/cpp/demo/Ice/converter/Makefile.mak index d47a8b8b54c..101bd807310 100644 --- a/cpp/demo/Ice/converter/Makefile.mak +++ b/cpp/demo/Ice/converter/Makefile.mak @@ -9,16 +9,21 @@ top_srcdir = ..\..\.. -CLIENT = client.exe +CLIENT1 = client1.exe +CLIENT2 = client2.exe SERVER = server.exe -TARGETS = $(CLIENT) $(SERVER) +TARGETS = $(CLIENT1) $(CLIENT2) $(SERVER) -OBJS = Greet.obj \ - StringConverterI.obj +OBJS = Greet.obj -COBJS = Client.obj +C1OBJS = Client.obj \ + StringConverterI.obj \ + ClientWithConverter.obj +C2OBJS = Client.obj \ + ClientWithoutConverter.obj + SOBJS = GreetI.obj \ Server.obj @@ -31,12 +36,18 @@ SRCS = $(OBJS:.obj=.cpp) \ CPPFLAGS = -I. $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN !if "$(GENERATE_PDB)" == "yes" -CPDBFLAGS = /pdb:$(CLIENT:.exe=.pdb) +C1PDBFLAGS = /pdb:$(CLIENT1:.exe=.pdb) +C2PDBFLAGS = /pdb:$(CLIENT2:.exe=.pdb) SPDBFLAGS = /pdb:$(SERVER:.exe=.pdb) !endif -$(CLIENT): $(OBJS) $(COBJS) - $(LINK) $(LD_EXEFLAGS) $(CPDBFLAGS) $(SETARGV) $(OBJS) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS) +$(CLIENT1): $(OBJS) $(C1OBJS) + $(LINK) $(LD_EXEFLAGS) $(C1PDBFLAGS) $(SETARGV) $(OBJS) $(C1OBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS) + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest + +$(CLIENT2): $(OBJS) $(C2OBJS) + $(LINK) $(LD_EXEFLAGS) $(C2PDBFLAGS) $(SETARGV) $(OBJS) $(C2OBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS) @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest diff --git a/cpp/demo/Ice/converter/README b/cpp/demo/Ice/converter/README index 2cfbb59525d..87dbb6f8e92 100644 --- a/cpp/demo/Ice/converter/README +++ b/cpp/demo/Ice/converter/README @@ -1,18 +1,26 @@ This demo illustrates how to implement and use string converters -with Ice. In this demo, the client represents an application that -uses ISO-Latin-1 as its character set, while the server uses UTF-8. +with Ice. In this demo, the clients uses ISO-Latin-1 as its +character set, while the server uses UTF-8. -The demo sends and receives the greeting "Bonne journée" which in -Latin-1 encoding is "Bonne journ\351e" and in UTF-8 encoding is -"Bonne journ\303\251e". +The demo sends and receives the greeting "Bonne journée" which +in Latin-1 encoding is "Bonne journ\351e" and in UTF-8 encoding +is "Bonne journ\303\251e". -The demo prints the strings as they are received to show how, without -conversion, they are not in the format expected by the application. +The demo server prints the strings as they are received to show +how, without conversion, they are not in the format expected by +the application. + +There are two clients client1 uses an string converter and, client2 +doesn't use and string converter. To run the demo, first start the server: $ server -In a separate window, start the client: +In a separate window, start the client1: + +$ client1 + +In a separate window, start the client2: -$ client +$ client2 diff --git a/cpp/demo/Ice/converter/StringConverterI.cpp b/cpp/demo/Ice/converter/StringConverterI.cpp index 219d792f1a3..12d83cb39c7 100644 --- a/cpp/demo/Ice/converter/StringConverterI.cpp +++ b/cpp/demo/Ice/converter/StringConverterI.cpp @@ -7,10 +7,10 @@ // // ********************************************************************** -#include <Ice/Ice.h> #include <StringConverterI.h> using namespace std; +using namespace IceUtil; Demo::StringConverterI::StringConverterI() { @@ -20,14 +20,14 @@ Demo::StringConverterI::~StringConverterI() { } -Ice::Byte* -Demo::StringConverterI::toUTF8(const char* sourceStart, const char* sourceEnd, Ice::UTF8Buffer& buffer) const +Byte* +Demo::StringConverterI::toUTF8(const char* sourceStart, const char* sourceEnd, UTF8Buffer& buffer) const { size_t inputSize = static_cast<size_t>(sourceEnd - sourceStart); size_t chunkSize = std::max<size_t>(inputSize, 6); size_t outputBytesLeft = chunkSize; - Ice::Byte* targetStart = buffer.getMoreBytes(chunkSize, 0); + Byte* targetStart = buffer.getMoreBytes(chunkSize, 0); size_t offset = 0; for(unsigned int i = 0; i < inputSize; ++i) @@ -66,7 +66,7 @@ Demo::StringConverterI::toUTF8(const char* sourceStart, const char* sourceEnd, I } void -Demo::StringConverterI::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, +Demo::StringConverterI::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, string& target) const { size_t inSize = static_cast<size_t>(sourceEnd - sourceStart); @@ -80,7 +80,7 @@ Demo::StringConverterI::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* { if(i + 1 >= inSize) { - throw Ice::StringConversionException(__FILE__, __LINE__, "UTF-8 string source exhausted"); + throw IllegalConversionException(__FILE__, __LINE__, "UTF-8 string source exhausted"); } target[targetIndex] = (sourceStart[i] & 0x03) << 6; target[targetIndex] = target[targetIndex] | (sourceStart[i + 1] & 0x3F); diff --git a/cpp/demo/Ice/converter/StringConverterI.h b/cpp/demo/Ice/converter/StringConverterI.h index 2d6d0ded912..ce6602db47e 100644 --- a/cpp/demo/Ice/converter/StringConverterI.h +++ b/cpp/demo/Ice/converter/StringConverterI.h @@ -10,7 +10,7 @@ #ifndef STRING_CONVERTER_I_H #define STRING_CONVERTER_I_H -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> namespace Demo { @@ -18,15 +18,15 @@ namespace Demo // // UTF-8 converter for LATIN-1 // -class StringConverterI : public Ice::StringConverter +class StringConverterI : public IceUtil::StringConverter { public: StringConverterI(); ~StringConverterI(); - virtual Ice::Byte* toUTF8(const char*, const char*, Ice::UTF8Buffer&) const; - virtual void fromUTF8(const Ice::Byte*, const Ice::Byte*, std::string&) const; + virtual IceUtil::Byte* toUTF8(const char*, const char*, IceUtil::UTF8Buffer&) const; + virtual void fromUTF8(const IceUtil::Byte*, const IceUtil::Byte*, std::string&) const; }; } diff --git a/cpp/demo/Ice/converter/expect.py b/cpp/demo/Ice/converter/expect.py index 87ec5834e9a..fe508333226 100755 --- a/cpp/demo/Ice/converter/expect.py +++ b/cpp/demo/Ice/converter/expect.py @@ -23,20 +23,25 @@ from demoscript import Util server = Util.spawn('./server --Ice.PrintAdapterReady') server.expect('.* ready') -client = Util.spawn('./client') -client.expect('.*==>') + +client = Util.spawn('./client1') +client.expect('.*==>') sys.stdout.write("testing with conversion... ") -sys.stdout.flush() -client.sendline('u') -server.expect('Received \\(UTF-8\\): "Bonne journ\\\\351e"') -client.expect('Received: "Bonne journ\\\\303\\\\251e"') +client.sendline('t') +server.expect('Received \\(UTF-8\\): "Bonne journ\\\\303\\\\251e"') +client.expect('Received: "Bonne journ\\\\351e"') print("ok") +client.sendline('x') +client = Util.spawn('./client2') +client.expect('.*==>') + sys.stdout.write("testing without conversion... ") +sys.stdout.flush() client.sendline('t') -server.expect('Received \\(UTF-8\\): "Bonne journ\\\\303\\\\251e"') -client.expect('Received: "Bonne journ\\\\351e"') +server.expect('Received \\(UTF-8\\): "Bonne journ\\\\351e"') +client.expect('Received: "Bonne journ\\\\303\\\\251e"') print("ok") client.sendline('s') diff --git a/cpp/include/Ice/BasicStream.h b/cpp/include/Ice/BasicStream.h index 3f546fd52a8..bd18dbf7b8a 100644 --- a/cpp/include/Ice/BasicStream.h +++ b/cpp/include/Ice/BasicStream.h @@ -10,6 +10,7 @@ #ifndef ICE_BASIC_STREAM_H #define ICE_BASIC_STREAM_H +#include <IceUtil/StringConverter.h> #include <Ice/InstanceF.h> #include <Ice/Object.h> #include <Ice/ProxyF.h> @@ -27,14 +28,6 @@ namespace Ice class UserException; -template<typename charT> class BasicStringConverter; - -typedef BasicStringConverter<char> StringConverter; -typedef IceUtil::Handle<StringConverter> StringConverterPtr; - -typedef BasicStringConverter<wchar_t> WstringConverter; -typedef IceUtil::Handle<WstringConverter> WstringConverterPtr; - } namespace IceInternal @@ -1244,8 +1237,8 @@ private: const Container::size_type _messageSizeMax; bool _unlimited; - const Ice::StringConverterPtr& _stringConverter; - const Ice::WstringConverterPtr& _wstringConverter; + const IceUtil::StringConverterPtr _stringConverter; + const IceUtil::WstringConverterPtr _wstringConverter; int _startSeq; int _minSeqSize; diff --git a/cpp/include/Ice/DynamicLibrary.h b/cpp/include/Ice/DynamicLibrary.h index 093870759aa..09e5956d93c 100644 --- a/cpp/include/Ice/DynamicLibrary.h +++ b/cpp/include/Ice/DynamicLibrary.h @@ -11,7 +11,6 @@ #define ICE_DYNAMIC_LIBRARY_H #include <Ice/DynamicLibraryF.h> -#include <Ice/StringConverter.h> #include <IceUtil/Shared.h> namespace IceInternal @@ -21,7 +20,7 @@ class ICE_API DynamicLibrary : public ::IceUtil::Shared { public: - DynamicLibrary(const Ice::StringConverterPtr&); + DynamicLibrary(); ~DynamicLibrary(); #ifdef _WIN32 @@ -88,7 +87,6 @@ private: void* _hnd; #endif std::string _err; - const Ice::StringConverterPtr _stringConverter; }; class ICE_API DynamicLibraryList : public ::IceUtil::Shared diff --git a/cpp/include/Ice/Ice.h b/cpp/include/Ice/Ice.h index 2c66ed00022..ffb233b40de 100644 --- a/cpp/include/Ice/Ice.h +++ b/cpp/include/Ice/Ice.h @@ -47,8 +47,5 @@ #ifndef ICE_OS_WINRT # include <Ice/Service.h> #endif -#ifndef _WIN32 -# include <Ice/IconvStringConverter.h> -#endif #endif diff --git a/cpp/include/Ice/Initialize.h b/cpp/include/Ice/Initialize.h index 0424731bc37..1422e0552e5 100644 --- a/cpp/include/Ice/Initialize.h +++ b/cpp/include/Ice/Initialize.h @@ -18,10 +18,10 @@ #include <Ice/StatsF.h> #include <Ice/InstrumentationF.h> #include <Ice/Dispatcher.h> -#include <Ice/StringConverter.h> #include <Ice/FactoryTable.h> #include <Ice/BuiltinSequences.h> #include <Ice/Version.h> +#include <Ice/Plugin.h> namespace Ice { @@ -34,8 +34,6 @@ ICE_API StringSeq argsToStringSeq(int, char*[]); ICE_API StringSeq argsToStringSeq(int, wchar_t*[]); -ICE_API StringSeq argsToStringSeq(int, wchar_t*[], const StringConverterPtr&); - #endif // @@ -46,9 +44,9 @@ ICE_API StringSeq argsToStringSeq(int, wchar_t*[], const StringConverterPtr&); // ICE_API void stringSeqToArgs(const StringSeq&, int&, char*[]); -ICE_API PropertiesPtr createProperties(const StringConverterPtr& = 0); -ICE_API PropertiesPtr createProperties(StringSeq&, const PropertiesPtr& = 0, const StringConverterPtr& = 0); -ICE_API PropertiesPtr createProperties(int&, char*[], const PropertiesPtr& = 0, const StringConverterPtr& = 0); +ICE_API PropertiesPtr createProperties(); +ICE_API PropertiesPtr createProperties(StringSeq&, const PropertiesPtr& = 0); +ICE_API PropertiesPtr createProperties(int&, char*[], const PropertiesPtr& = 0); // // This class is used to notify user of when Ice threads are started @@ -88,8 +86,6 @@ struct InitializationData LoggerPtr logger; StatsPtr stats; Instrumentation::CommunicatorObserverPtr observer; - StringConverterPtr stringConverter; - WstringConverterPtr wstringConverter; ThreadNotificationPtr threadHook; DispatcherPtr dispatcher; CompactIdResolverPtr compactIdResolver; diff --git a/cpp/include/Ice/StringConverter.h b/cpp/include/Ice/StringConverter.h deleted file mode 100644 index 90b302cbad8..00000000000 --- a/cpp/include/Ice/StringConverter.h +++ /dev/null @@ -1,161 +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. -// -// ********************************************************************** - -#ifndef ICE_STRING_CONVERTER_H -#define ICE_STRING_CONVERTER_H - -#include <Ice/Config.h> -#include <Ice/CommunicatorF.h> -#include <Ice/Plugin.h> -#include <IceUtil/Exception.h> -#include <IceUtil/Shared.h> -#include <IceUtil/Handle.h> -#include <IceUtil/Unicode.h> - -#include <string> - -namespace Ice -{ - -// -// Provides bytes to toUTF8. Raises MemoryLimitException when too many -// bytes are requested. -// -class ICE_API UTF8Buffer -{ -public: - virtual Byte* getMoreBytes(size_t howMany, Byte* firstUnused) = 0; - - virtual ~UTF8Buffer() {} -}; - -// -// A StringConverter converts narrow or wide-strings to and from UTF-8 byte sequences. -// It's used by the communicator during marshaling (toUTF8) and unmarshaling (fromUTF8). -// It report errors by raising StringConversionFailed or MemoryLimitException. -// -template<typename charT> -class BasicStringConverter : public IceUtil::Shared -{ -public: - - // - // Returns a pointer to byte after the last written byte (which may be - // past the last byte returned by getMoreBytes). - // - virtual Byte* toUTF8(const charT* sourceStart, const charT* sourceEnd, - UTF8Buffer&) const = 0; - - // - // Unmarshals a UTF-8 sequence into a basic_string - // - virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, - std::basic_string<charT>& target) const = 0; -}; - -typedef BasicStringConverter<char> StringConverter; -typedef IceUtil::Handle<StringConverter> StringConverterPtr; - -typedef BasicStringConverter<wchar_t> WstringConverter; -typedef IceUtil::Handle<WstringConverter> WstringConverterPtr; - - -// -// Converts to and from UTF-16 or UTF-32 depending on sizeof(wchar_t) -// -class ICE_API UnicodeWstringConverter : public WstringConverter -{ -public: - - UnicodeWstringConverter(IceUtil::ConversionFlags = IceUtil::lenientConversion); - - virtual Byte* toUTF8(const wchar_t*, const wchar_t*, UTF8Buffer&) const; - - virtual void fromUTF8(const Byte*, const Byte*, std::wstring&) const; - -private: - const IceUtil::ConversionFlags _conversionFlags; -}; - -#ifdef _WIN32 - -// -// Converts to/from UTF-8 using MultiByteToWideChar and WideCharToMultiByte -// - -class ICE_API WindowsStringConverter : public StringConverter -{ -public: - - explicit WindowsStringConverter(unsigned int); - - virtual Byte* toUTF8(const char*, const char*, UTF8Buffer&) const; - - virtual void fromUTF8(const Byte*, const Byte*, std::string& target) const; - -private: - unsigned int _cp; - UnicodeWstringConverter _unicodeWstringConverter; -}; -#endif - - -// -// 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& communicator, - const StringConverterPtr&, const WstringConverterPtr& = 0); - - virtual void initialize(); - - virtual void destroy(); -}; - -// -// Converts the given string from the native narrow string encoding to -// UTF8 using the given converter. If the converter is null, returns -// the given string. -// -ICE_API std::string -nativeToUTF8(const Ice::StringConverterPtr&, const std::string&); - -// -// Converts the given string from the native narrow string encoding to -// UTF8 using the communicator's converter. If the converter is null, -// returns the given string. -// -ICE_API std::string -nativeToUTF8(const Ice::CommunicatorPtr&, const std::string&); - -// -// Converts the given string from UTF8 to the native narrow string -// encoding using the given converter. If the converter is null, -// returns the given string. -// -ICE_API std::string -UTF8ToNative(const Ice::StringConverterPtr&, const std::string&); - -// -// Converts the given string from UTF8 to the native narrow string -// encoding using the communicator's converter. If the converter is -// null, returns the given string. -// -ICE_API std::string -UTF8ToNative(const Ice::CommunicatorPtr&, const std::string&); - -} - -#endif diff --git a/cpp/include/IceUtil/Exception.h b/cpp/include/IceUtil/Exception.h index 2709b64ee31..b3dca7824d5 100644 --- a/cpp/include/IceUtil/Exception.h +++ b/cpp/include/IceUtil/Exception.h @@ -135,6 +135,27 @@ private: static const char* _name; }; +#ifndef _WIN32 +class ICE_UTIL_API IconvInitializationException : public Exception +{ +public: + + IconvInitializationException(const char*, int, const std::string&); + virtual ~IconvInitializationException() throw(); + virtual std::string ice_name() const; + virtual void ice_print(std::ostream&) const; + virtual IconvInitializationException* ice_clone() const; + virtual void ice_throw() const; + + std::string reason() const; + +private: + + static const char* _name; + std::string _reason; +}; +#endif + } #endif diff --git a/cpp/include/IceUtil/FileUtil.h b/cpp/include/IceUtil/FileUtil.h index 7cb2cd55407..7fabce927b9 100644 --- a/cpp/include/IceUtil/FileUtil.h +++ b/cpp/include/IceUtil/FileUtil.h @@ -70,6 +70,7 @@ ICE_UTIL_API int rmdir(const std::string&); ICE_UTIL_API int mkdir(const std::string&, int); ICE_UTIL_API FILE* fopen(const std::string&, const std::string&); +ICE_UTIL_API FILE* freopen(const std::string&, const std::string&, FILE*); ICE_UTIL_API int open(const std::string&, int); #ifndef ICE_OS_WINRT diff --git a/cpp/include/IceUtil/IceUtil.h b/cpp/include/IceUtil/IceUtil.h index cba2207c079..b5e126a34c2 100644 --- a/cpp/include/IceUtil/IceUtil.h +++ b/cpp/include/IceUtil/IceUtil.h @@ -41,4 +41,8 @@ #include <IceUtil/Unicode.h> #include <IceUtil/UniquePtr.h> +#ifndef _WIN32 +# include <IceUtil/IconvStringConverter.h> +#endif + #endif diff --git a/cpp/include/Ice/IconvStringConverter.h b/cpp/include/IceUtil/IconvStringConverter.h index 23c683bf78a..e6bef3c6d82 100644 --- a/cpp/include/Ice/IconvStringConverter.h +++ b/cpp/include/IceUtil/IconvStringConverter.h @@ -7,18 +7,16 @@ // // ********************************************************************** -#ifndef ICE_ICONV_STRING_CONVERTER -#define ICE_ICONV_STRING_CONVERTER +#ifndef ICE_UTIL_ICONV_STRING_CONVERTER +#define ICE_UTIL_ICONV_STRING_CONVERTER -#include <Ice/StringConverter.h> -#include <Ice/UndefSysMacros.h> +#include <IceUtil/StringConverter.h> +#include <IceUtil/UndefSysMacros.h> #include <algorithm> #include <iconv.h> - -#ifndef _WIN32 #include <langinfo.h> -#endif +#include <string.h> // For strerror #if (defined(__APPLE__) && _LIBICONV_VERSION < 0x010B) || defined(__FreeBSD__) // @@ -27,14 +25,7 @@ # define ICE_CONST_ICONV_INBUF 1 #endif -// -// On Windows, we need to be very careful with errno: if we use different C -// runtime libraries for the main program and the libiconv DLL, we end up with -// two different errnos ... a not-so-good work-around is to ignore errno -// altogether, by defining ICE_NO_ERRNO -// - -namespace Ice +namespace IceUtil { // @@ -45,21 +36,17 @@ namespace Ice // // template<typename charT> -class IconvStringConverter : public Ice::BasicStringConverter<charT> +class IconvStringConverter : public BasicStringConverter<charT> { public: -#ifdef _WIN32 - IconvStringConverter(const char*); -#else IconvStringConverter(const char* = nl_langinfo(CODESET)); -#endif virtual ~IconvStringConverter(); - virtual Ice::Byte* toUTF8(const charT*, const charT*, Ice::UTF8Buffer&) const; + virtual Byte* toUTF8(const charT*, const charT*, UTF8Buffer&) const; - virtual void fromUTF8(const Ice::Byte*, const Ice::Byte*, std::basic_string<charT>&) const; + virtual void fromUTF8(const Byte*, const Byte*, std::basic_string<charT>&) const; private: @@ -69,11 +56,7 @@ private: static void cleanupKey(void*); static void close(std::pair<iconv_t, iconv_t>); -#ifdef _WIN32 - DWORD _key; -#else mutable pthread_key_t _key; -#endif const std::string _internalCode; }; @@ -99,48 +82,29 @@ IconvStringConverter<charT>::IconvStringConverter(const char* internalCode) : { close(createDescriptors()); } - catch(const Ice::StringConversionException& sce) + catch(const IllegalConversionException& sce) { - throw Ice::InitializationException(__FILE__, __LINE__, sce.reason); + throw IconvInitializationException(__FILE__, __LINE__, sce.reason()); } // // Create thread-specific key // -#ifdef _WIN32 - _key = TlsAlloc(); - if(_key == TLS_OUT_OF_INDEXES) - { - throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); - } -#else - #ifdef __SUNPRO_CC +#ifdef __SUNPRO_CC int rs = pthread_key_create(&_key, reinterpret_cast<IcePthreadKeyDestructor>(&cleanupKey)); - #else +#else int rs = pthread_key_create(&_key, &cleanupKey); - #endif +#endif if(rs != 0) { - throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rs); + throw ThreadSyscallException(__FILE__, __LINE__, rs); } -#endif } template<typename charT> IconvStringConverter<charT>::~IconvStringConverter() { -#ifdef _WIN32 - void* val = TlsGetValue(_key); - if(val != 0) - { - cleanupKey(val); - } - if(TlsFree(_key) == 0) - { - assert(0); - } -#else void* val = pthread_getspecific(_key); if(val != 0) { @@ -150,7 +114,6 @@ IconvStringConverter<charT>::~IconvStringConverter() { assert(0); } -#endif } template<typename charT> std::pair<iconv_t, iconv_t> @@ -163,20 +126,18 @@ IconvStringConverter<charT>::createDescriptors() const cdp.first = iconv_open(_internalCode.c_str(), externalCode); if(cdp.first == iconv_t(-1)) { - throw Ice::StringConversionException( - __FILE__, __LINE__, - std::string("iconv cannot convert from ") - + externalCode + " to " + _internalCode); + std::ostringstream os; + os << "iconv cannot convert from " << externalCode << " to " << _internalCode; + throw IllegalConversionException(__FILE__, __LINE__, os.str()); } cdp.second = iconv_open(externalCode, _internalCode.c_str()); if(cdp.second == iconv_t(-1)) { iconv_close(cdp.first); - - throw Ice::StringConversionException( - __FILE__, __LINE__, - std::string("iconv cannot convert from ") + _internalCode + " to " + externalCode); + std::ostringstream os; + os << "iconv cannot convert from " << _internalCode << " to " << externalCode; + throw IllegalConversionException(__FILE__, __LINE__, os.str()); } return cdp; } @@ -184,11 +145,7 @@ IconvStringConverter<charT>::createDescriptors() const template<typename charT> std::pair<iconv_t, iconv_t> IconvStringConverter<charT>::getDescriptors() const { -#ifdef _WIN32 - void* val = TlsGetValue(_key); -#else void* val = pthread_getspecific(_key); -#endif if(val != 0) { return *static_cast<std::pair<iconv_t, iconv_t>*>(val); @@ -196,19 +153,11 @@ IconvStringConverter<charT>::getDescriptors() const else { std::pair<iconv_t, iconv_t> cdp = createDescriptors(); - -#ifdef _WIN32 - if(TlsSetValue(_key, new std::pair<iconv_t, iconv_t>(cdp)) == 0) - { - throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); - } -#else int rs = pthread_setspecific(_key, new std::pair<iconv_t, iconv_t>(cdp)); if(rs != 0) { - throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rs); + throw ThreadSyscallException(__FILE__, __LINE__, rs); } -#endif return cdp; } } @@ -237,8 +186,8 @@ IconvStringConverter<charT>::close(std::pair<iconv_t, iconv_t> cdp) #endif } -template<typename charT> Ice::Byte* -IconvStringConverter<charT>::toUTF8(const charT* sourceStart, const charT* sourceEnd, Ice::UTF8Buffer& buf) const +template<typename charT> Byte* +IconvStringConverter<charT>::toUTF8(const charT* sourceStart, const charT* sourceEnd, UTF8Buffer& buf) const { iconv_t cd = getDescriptors().second; @@ -267,30 +216,19 @@ IconvStringConverter<charT>::toUTF8(const charT* sourceStart, const charT* sourc do { size_t howMany = std::max(inbytesleft, size_t(4)); - outbuf = reinterpret_cast<char*>(buf.getMoreBytes(howMany, reinterpret_cast<Ice::Byte*>(outbuf))); + outbuf = reinterpret_cast<char*>(buf.getMoreBytes(howMany, reinterpret_cast<Byte*>(outbuf))); count = iconv(cd, &inbuf, &inbytesleft, &outbuf, &howMany); -#ifdef ICE_NO_ERRNO - } while(count == size_t(-1)); -#else } while(count == size_t(-1) && errno == E2BIG); -#endif if(count == size_t(-1)) { - std::string msg = "Unknown error"; -#ifndef ICE_NO_ERRNO - if(errno != 0) - { - msg = strerror(errno); - } -#endif - throw Ice::StringConversionException(__FILE__, __LINE__, msg); + throw IllegalConversionException(__FILE__, __LINE__, errno != 0 ? strerror(errno) : "Unknown error"); } - return reinterpret_cast<Ice::Byte*>(outbuf); + return reinterpret_cast<Byte*>(outbuf); } template<typename charT> void -IconvStringConverter<charT>::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, +IconvStringConverter<charT>::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, std::basic_string<charT>& target) const { iconv_t cd = getDescriptors().first; @@ -308,7 +246,7 @@ IconvStringConverter<charT>::fromUTF8(const Ice::Byte* sourceStart, const Ice::B #ifdef ICE_CONST_ICONV_INBUF const char* inbuf = reinterpret_cast<const char*>(sourceStart); #else - char* inbuf = reinterpret_cast<char*>(const_cast<Ice::Byte*>(sourceStart)); + char* inbuf = reinterpret_cast<char*>(const_cast<Byte*>(sourceStart)); #endif size_t inbytesleft = sourceEnd - sourceStart; @@ -329,15 +267,13 @@ IconvStringConverter<charT>::fromUTF8(const Ice::Byte* sourceStart, const Ice::B do { size_t increment = std::max(inbytesleft * sizeof(wchar_t), size_t(8)); - bufsize += increment; - + bufsize += increment; char* newbuf = static_cast<char*>(realloc(buf, bufsize)); if(newbuf == 0) { free(buf); - throw Ice::StringConversionException( - __FILE__, __LINE__, "Out of memory"); + throw IllegalConversionException(__FILE__, __LINE__, "Out of memory"); } outbuf = newbuf + (outbuf - buf); @@ -346,23 +282,12 @@ IconvStringConverter<charT>::fromUTF8(const Ice::Byte* sourceStart, const Ice::B buf = newbuf; count = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); -#ifdef ICE_NO_ERRNO - } while(count == size_t(-1)); -#else } while(count == size_t(-1) && errno == E2BIG); -#endif if(count == size_t(-1)) { - std::string msg = "Unknown error"; -#ifndef ICE_NO_ERRNO - if(errno != 0) - { - msg = strerror(errno); - } -#endif free(buf); - throw Ice::StringConversionException(__FILE__, __LINE__, msg); + throw IllegalConversionException(__FILE__, __LINE__, errno != 0 ? strerror(errno) : "Unknown error"); } size_t length = (bufsize - outbytesleft) / sizeof(charT); diff --git a/cpp/include/IceUtil/StringConverter.h b/cpp/include/IceUtil/StringConverter.h new file mode 100644 index 00000000000..b3e8d62f2b7 --- /dev/null +++ b/cpp/include/IceUtil/StringConverter.h @@ -0,0 +1,193 @@ +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_UTIL_STRING_CONVERTER_H +#define ICE_UTIL_STRING_CONVERTER_H + +#include <IceUtil/Config.h> +#include <IceUtil/Exception.h> +#include <IceUtil/Shared.h> +#include <IceUtil/Handle.h> +#include <IceUtil/Unicode.h> + +#include <string> + +namespace IceUtil +{ + +// +// Raised by string converters when an encoding converseion fails. +// +class ICE_UTIL_API IllegalConversionException : public ::IceUtil::Exception +{ +public: + + IllegalConversionException(const char*, int); + IllegalConversionException(const char*, int, const ::std::string&); + virtual ~IllegalConversionException() throw(); + + virtual ::std::string ice_name() const; + virtual void ice_print(::std::ostream&) const; + virtual IllegalConversionException* ice_clone() const; + virtual void ice_throw() const; + + std::string reason() const; + +private: + + std::string _reason; +}; + +// +// Provides bytes to toUTF8. Raises MemoryLimitException when too many +// bytes are requested. +// +class ICE_UTIL_API UTF8Buffer +{ +public: + virtual Byte* getMoreBytes(size_t howMany, Byte* firstUnused) = 0; + + virtual ~UTF8Buffer() {} +}; + +// +// A StringConverter converts narrow or wide-strings to and from UTF-8 byte sequences. +// It's used by the communicator during marshaling (toUTF8) and unmarshaling (fromUTF8). +// It report errors by raising IllegalConversionException or MemoryLimitException. +// +template<typename charT> +class BasicStringConverter : public IceUtil::Shared +{ +public: + // + // Returns a pointer to byte after the last written byte (which may be + // past the last byte returned by getMoreBytes). + // + virtual Byte* toUTF8(const charT* sourceStart, const charT* sourceEnd, + UTF8Buffer&) const = 0; + + // + // Unmarshals a UTF-8 sequence into a basic_string + // + virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, + std::basic_string<charT>& target) const = 0; +}; + +typedef BasicStringConverter<char> StringConverter; +typedef IceUtil::Handle<StringConverter> StringConverterPtr; + +typedef BasicStringConverter<wchar_t> WstringConverter; +typedef IceUtil::Handle<WstringConverter> WstringConverterPtr; + +// +// Converts to and from UTF-16 or UTF-32 depending on sizeof(wchar_t) +// +class ICE_UTIL_API UnicodeWstringConverter : public WstringConverter +{ +public: + + UnicodeWstringConverter(ConversionFlags = lenientConversion); + + virtual Byte* toUTF8(const wchar_t*, const wchar_t*, UTF8Buffer&) const; + + virtual void fromUTF8(const Byte*, const Byte*, std::wstring&) const; + +private: + const ConversionFlags _conversionFlags; +}; + +#ifdef _WIN32 + +// +// Converts to/from UTF-8 using MultiByteToWideChar and WideCharToMultiByte +// +class ICE_UTIL_API WindowsStringConverter : public StringConverter +{ +public: + + explicit WindowsStringConverter(unsigned int); + + virtual Byte* toUTF8(const char*, const char*, UTF8Buffer&) const; + + virtual void fromUTF8(const Byte*, const Byte*, std::string& target) const; + +private: + unsigned int _cp; + UnicodeWstringConverter _unicodeWstringConverter; +}; +#endif + +// +// Retrive the per process narrow string converter. Access to the +// converter is protected by a static mutex. +// +ICE_UTIL_API StringConverterPtr getProcessStringConverter(); + +// +// Set the per process narrow string converter. Access to the +// converter is protected by a static mutex. +// +ICE_UTIL_API void setProcessStringConverter(const StringConverterPtr&); + +// +// Retrive the per process wide string converter. Access to the +// converter is protected by a static mutex. +// +ICE_UTIL_API WstringConverterPtr getProcessWstringConverter(); + +// +// Set the per process wide string converter. Access to the +// converter is protected by a static mutex. +// +ICE_UTIL_API void setProcessWstringConverter(const WstringConverterPtr&); + +// +// Convert the given wide string from the native wide string encoding to a +// narrow string with the native narrow string encoding. +// +// The StringConverter param can be null in that case the default narrow +// string encoding is assumed to be UTF8. +// +// The WstringConverter param can be null in that case the default wide +// string encoding is assumed, that would be UTF16 or UTF32 depending of +// the platform. +// +ICE_UTIL_API std::string +wnativeToNative(const StringConverterPtr&, const WstringConverterPtr&, const std::wstring&); + +// +// Convert the given narrow string from the native narrow string encoding +// to a wide string with the native wide string encoding. +// +// The StringConverter param can be null in that case the default narrow +// string encoding is assumed to be UTF8. +// +// The WstringConverter param can be null in that case the default wide +// string encoding is assumed, that would be UTF16 or UTF32 depending of +// the platform. +// +ICE_UTIL_API std::wstring +nativeToWnative(const StringConverterPtr&, const WstringConverterPtr&, const std::string&); + +// +// Converts the given string from the native narrow string encoding to +// UTF8 using the given converter. If the converter is null, returns +// the given string. +// +ICE_UTIL_API std::string +nativeToUTF8(const StringConverterPtr&, const std::string&); + +// +// Converts the given string from UTF8 to the native narrow string +// encoding using the given converter. If the converter is null, +// returns the given string. +// +ICE_UTIL_API std::string +UTF8ToNative(const StringConverterPtr&, const std::string&); + +} + +#endif diff --git a/cpp/include/Ice/UndefSysMacros.h b/cpp/include/IceUtil/UndefSysMacros.h index d135180f1b7..2dc931daf08 100644 --- a/cpp/include/Ice/UndefSysMacros.h +++ b/cpp/include/IceUtil/UndefSysMacros.h @@ -7,8 +7,8 @@ // // ********************************************************************** -#ifndef ICE_UNDEF_SYS_MACROS_H -#define ICE_UNDEF_SYS_MACROS_H +#ifndef ICE_UTIL_UNDEF_SYS_MACROS_H +#define ICE_UTIL_UNDEF_SYS_MACROS_H // // This header includes macros that can end up being dragged into diff --git a/cpp/include/IceUtil/Unicode.h b/cpp/include/IceUtil/Unicode.h index 40f002fa545..71a52b3e62f 100644 --- a/cpp/include/IceUtil/Unicode.h +++ b/cpp/include/IceUtil/Unicode.h @@ -22,8 +22,11 @@ enum ConversionFlags lenientConversion }; -ICE_UTIL_API std::string wstringToString(const std::wstring&, ConversionFlags = lenientConversion); -ICE_UTIL_API std::wstring stringToWstring(const std::string&, ConversionFlags = lenientConversion); +ICE_DEPRECATED_API std::string +wstringToString(const std::wstring&, ConversionFlags = lenientConversion); + +ICE_DEPRECATED_API std::wstring +stringToWstring(const std::string&, ConversionFlags = lenientConversion); typedef unsigned char Byte; 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 <IceUtil/IceUtil.h> -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> #include <typeinfo> 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 <Freeze/ObjectStore.h> #include <Freeze/EvictorI.h> -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> 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 <Freeze/CatalogIndexList.h> #include <algorithm> -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> 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 <Freeze/Catalog.h> #include <Freeze/CatalogIndexList.h> #include <IceUtil/UUID.h> +#include <IceUtil/StringConverter.h> #include <stdlib.h> -#include <Ice/StringConverter.h> - 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<MapDb> 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 <Freeze/TransactionI.h> #include <Freeze/IndexI.h> -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> 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 <IceUtil/StringUtil.h> #include <IceUtil/IceUtil.h> -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> #include <cstdlib> @@ -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 <Ice/TraceLevels.h> #include <Ice/LoggerUtil.h> #include <Ice/SlicedData.h> -#include <Ice/StringConverter.h> -#include <IceUtil/Unicode.h> +#include <IceUtil/StringConverter.h> #include <iterator> 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<Int>(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<Int>(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<Int>(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<Int>(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<Int>(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<Int>(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<Int>(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<Int>(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 <Ice/DynamicLibrary.h> #include <IceUtil/StringUtil.h> -#include <IceUtil/Unicode.h> +#include <IceUtil/StringConverter.h> #ifndef _WIN32 # include <dlfcn.h> @@ -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<Windows::Networking::Sockets::SocketErrorStatus>(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 <Ice/Instance.h> #include <IceUtil/Mutex.h> #include <IceUtil/MutexPtrLock.h> +#include <IceUtil/StringConverter.h> 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 <IceUtil/Mutex.h> #include <IceUtil/RecMutex.h> #include <IceUtil/Timer.h> +#include <IceUtil/StringConverter.h> #include <Ice/InstanceF.h> #include <Ice/CommunicatorF.h> #include <Ice/StatsF.h> @@ -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 <Ice/LoggerI.h> #include <IceUtil/Mutex.h> #include <IceUtil/MutexPtrLock.h> -#include <Ice/StringConverter.h> + +#ifdef _WIN32 +# include <IceUtil/StringUtil.h> +# include <IceUtil/ScopedArray.h> +# include <IceUtil/StringConverter.h> +#endif + #include <Ice/LocalException.h> 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<wchar_t> 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<char> 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 <Ice/Logger.h> #include <IceUtil/FileUtil.h> +#include <IceUtil/StringConverter.h> 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<string> 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<int>(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 <Ice/Logger.h> #include <Ice/LoggerUtil.h> #include <Ice/Communicator.h> -#include <Ice/StringConverter.h> 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<wchar_t*>(&nameBuf[0]), nameBufSize)); - name = Ice::UTF8ToNative(_converter, name); + string name = IceUtil::wnativeToNative(_converter, 0, + wstring(reinterpret_cast<wchar_t*>(&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<wchar_t*>(&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 <IceUtil/Mutex.h> #include <Ice/Properties.h> -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> #include <set> @@ -41,15 +41,15 @@ public: std::set<std::string> 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<std::string, PropertyValue> _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 <IceUtil/Mutex.h> #include <IceUtil/ArgVector.h> #include <IceUtil/FileUtil.h> +#include <IceUtil/StringConverter.h> #include <Ice/Service.h> #include <Ice/LoggerI.h> #include <Ice/Initialize.h> -#include <Ice/StringConverter.h> #include <Ice/Communicator.h> #include <Ice/LocalException.h> #include <Ice/Properties.h> @@ -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<wchar_t*>(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<wchar_t*>(IceUtil::stringToWstring(nativeToUTF8(_initData.stringConverter, _name)).c_str()), Ice_Service_ServiceMain }, + { const_cast<wchar_t*>( + 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<char*>(UTF8ToNative(_initData.stringConverter, IceUtil::wstringToString(argv[0])).c_str()); + args[0] = const_cast<char*>(IceUtil::wnativeToNative(converter, 0, argv[0]).c_str()); int i = 1; for(vector<string>::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<char*>(UTF8ToNative(_initData.stringConverter, IceUtil::wstringToString(argv[j])).c_str()); + args[i++] = const_cast<char*>(IceUtil::wnativeToNative(converter, 0, argv[j]).c_str()); } argc += static_cast<int>(_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 <Ice/StringConverter.h> -#include <IceUtil/IceUtil.h> -#include <IceUtil/StringUtil.h> -#include <IceUtil/ScopedArray.h> -#include <Ice/Initialize.h> -#include <Ice/Instance.h> -#include <Ice/LocalException.h> -#include <Ice/LoggerUtil.h> -#include <Ice/Communicator.h> - -#ifndef _WIN32 -#include <Ice/IconvStringConverter.h> -#endif - -#ifdef __MINGW32__ -# include <limits.h> -#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<size_t>(static_cast<size_t>(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<int>(sourceEnd - sourceStart); - if(sourceSize == 0) - { - return buffer.getMoreBytes(1, 0); - } - - int size = 0; - int writtenWchar = 0; - ScopedArray<wchar_t> 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<char> buffer; - do - { - size = size == 0 ? static_cast<int>(sourceEnd - sourceStart) + 2 : 2 * size; - buffer.reset(new char[size]); - writtenChar = WideCharToMultiByte(_cp, 0, wtarget.data(), static_cast<int>(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=<code page> 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<unsigned int>(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<char>; - break; - } - case 1: - { - stringConverter = new IconvStringConverter<char>(iconvArgs[0].c_str()); - break; - } - case 2: - { - stringConverter = new IconvStringConverter<char>(iconvArgs[0].c_str()); - wstringConverter = new IconvStringConverter<wchar_t>(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<const char*>(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<const Ice::Byte*>(str.data()), - reinterpret_cast<const Ice::Byte*>(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 <Ice/StringConverterPlugin.h> +#include <IceUtil/IceUtil.h> +#include <IceUtil/StringUtil.h> + +#include <Ice/Initialize.h> +#include <Ice/Instance.h> +#include <Ice/LocalException.h> +#include <Ice/LoggerUtil.h> +#include <Ice/Communicator.h> + +#ifndef _WIN32 +# include <IceUtil/IconvStringConverter.h> +#endif + +#ifdef __MINGW32__ +# include <limits.h> +#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=<code page> 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<unsigned int>(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<char>; + break; + } + case 1: + { + stringConverter = new IconvStringConverter<char>(iconvArgs[0].c_str()); + break; + } + case 2: + { + stringConverter = new IconvStringConverter<char>(iconvArgs[0].c_str()); + wstringConverter = new IconvStringConverter<wchar_t>(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 <Ice/Config.h> +#include <Ice/CommunicatorF.h> +#include <Ice/Plugin.h> +#include <IceUtil/StringConverter.h> + +#include <string> + +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<wchar_t*>(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<string, string> 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<DWORD>(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 <IceUtil/Unicode.h> #include <IceUtil/StringUtil.h> #include <IceUtil/FileUtil.h> -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> #define ICE_PATCH2_API_EXPORTS #include <IcePatch2/ClientUtil.h> #include <IcePatch2/Util.h> @@ -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<string&>(_dataDir) = simplify(nativeToUTF8(communicator, _dataDir)); + const_cast<string&>(_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 <Ice/Logger.h> #include <Ice/LoggerUtil.h> #include <Ice/Properties.h> -#include <Ice/StringConverter.h> #include <IceUtil/Mutex.h> #include <IceUtil/MutexPtrLock.h> @@ -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 <IceUtil/Unicode.h> +# include <IceUtil/StringConverter.h> # endif # include <DbgHelp.h> # include <tchar.h> @@ -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<DWORD64>(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 <IceUtil/DisableWarnings.h> #include <IceUtil/FileUtil.h> -#include <IceUtil/Unicode.h> #include <IceUtil/Exception.h> +#include <IceUtil/StringConverter.h> #include <climits> #include <string.h> @@ -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 <IceUtil/StringConverter.h> +#include <IceUtil/MutexPtrLock.h> +#include <IceUtil/Mutex.h> +#include <IceUtil/ScopedArray.h> +#include <IceUtil/StringUtil.h> + +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<IceUtil::Mutex> lock(processStringConverterMutex); + return processStringConverter; +} + +void +IceUtil::setProcessStringConverter(const StringConverterPtr& converter) +{ + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(processStringConverterMutex); + processStringConverter = converter; +} + +WstringConverterPtr +IceUtil::getProcessWstringConverter() +{ + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(processStringConverterMutex); + return processWstringConverter; +} + +void +IceUtil::setProcessWstringConverter(const WstringConverterPtr& converter) +{ + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> 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<const char*>(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<const Byte*>(str.data()), + reinterpret_cast<const Byte*>(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<const char*>(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<char*>(outBuf), static_cast<size_t>(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<const Byte*>(target.data()), + reinterpret_cast<const Byte*>(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<const char*>(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<const Byte*>(tmp.data()), + reinterpret_cast<const Byte*>(tmp.data() + tmp.size()), target); + } + else + { + const Byte* sourceStart = reinterpret_cast<const Byte*>(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<size_t>(static_cast<size_t>(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<int>(sourceEnd - sourceStart); + if(sourceSize == 0) + { + return buffer.getMoreBytes(1, 0); + } + + int size = 0; + int writtenWchar = 0; + ScopedArray<wchar_t> 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<char> buffer; + do + { + size = size == 0 ? static_cast<int>(sourceEnd - sourceStart) + 2 : 2 * size; + buffer.reset(new char[size]); + writtenChar = WideCharToMultiByte(_cp, flags, wtarget.data(), static_cast<int>(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 <IceUtil/StringUtil.h> -#include <IceUtil/Unicode.h> +#include <IceUtil/StringConverter.h> #include <cstring> #ifdef ICE_OS_WINRT -#include <IceUtil/ScopedArray.h> +# include <IceUtil/ScopedArray.h> #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 <Slice/Preprocessor.h> #include <Slice/Util.h> #include <IceUtil/StringUtil.h> +#include <IceUtil/StringConverter.h> #include <IceUtil/FileUtil.h> #include <IceUtil/UUID.h> #include <IceUtil/Unicode.h> @@ -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<wchar_t*>(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<wchar_t> 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<wchar_t*>(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<wchar_t*>(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<wchar_t*>(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<wchar_t*>(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<const BYTE*>(IceUtil::stringToWstring(resourceFile).c_str()), + reinterpret_cast<const BYTE*>(IceUtil::nativeToWnative(0, 0, resourceFile).c_str()), static_cast<DWORD>(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 <Ice/UndefSysMacros.h>"; + H << "\n#include <IceUtil/UndefSysMacros.h>"; if(_ice) { diff --git a/cpp/test/Ice/custom/Client.cpp b/cpp/test/Ice/custom/Client.cpp index d46b41e0860..6c5e737c5f7 100644 --- a/cpp/test/Ice/custom/Client.cpp +++ b/cpp/test/Ice/custom/Client.cpp @@ -34,9 +34,10 @@ main(int argc, char** argv) try { + IceUtil::setProcessStringConverter(new Test::StringConverterI()); + IceUtil::setProcessWstringConverter(new Test::WstringConverterI()); + Ice::InitializationData initData; - initData.stringConverter = new Test::StringConverterI(); - initData.wstringConverter = new Test::WstringConverterI(); communicator = Ice::initialize(argc, argv, initData); status = run(argc, argv, communicator); } diff --git a/cpp/test/Ice/custom/Collocated.cpp b/cpp/test/Ice/custom/Collocated.cpp index 08f4319a9f6..0dfc28feb4f 100644 --- a/cpp/test/Ice/custom/Collocated.cpp +++ b/cpp/test/Ice/custom/Collocated.cpp @@ -40,11 +40,12 @@ main(int argc, char** argv) try { + IceUtil::setProcessStringConverter(new Test::StringConverterI()); + IceUtil::setProcessWstringConverter(new Test::WstringConverterI()); + Ice::InitializationData initData; initData.properties = Ice::createProperties(argc, argv); initData.properties->setProperty("TestAdapter.Endpoints", "default -p 12010"); - initData.stringConverter = new Test::StringConverterI(); - initData.wstringConverter = new Test::WstringConverterI(); communicator = Ice::initialize(argc, argv, initData); status = run(argc, argv, communicator); } diff --git a/cpp/test/Ice/custom/Server.cpp b/cpp/test/Ice/custom/Server.cpp index e3705d15cfc..09d64eb0f2d 100644 --- a/cpp/test/Ice/custom/Server.cpp +++ b/cpp/test/Ice/custom/Server.cpp @@ -40,11 +40,13 @@ main(int argc, char** argv) try { + IceUtil::setProcessStringConverter(new Test::StringConverterI()); + IceUtil::setProcessWstringConverter(new Test::WstringConverterI()); + Ice::InitializationData initData; initData.properties = Ice::createProperties(argc, argv); initData.properties->setProperty("TestAdapter.Endpoints", "default -p 12010"); - initData.stringConverter = new Test::StringConverterI(); - initData.wstringConverter = new Test::WstringConverterI(); + communicator = Ice::initialize(argc, argv, initData); status = run(argc, argv, communicator); } diff --git a/cpp/test/Ice/custom/ServerAMD.cpp b/cpp/test/Ice/custom/ServerAMD.cpp index 46f240a0402..28f1e764a5c 100644 --- a/cpp/test/Ice/custom/ServerAMD.cpp +++ b/cpp/test/Ice/custom/ServerAMD.cpp @@ -40,12 +40,13 @@ main(int argc, char** argv) try { + IceUtil::setProcessStringConverter(new Test::StringConverterI()); + IceUtil::setProcessWstringConverter(new Test::WstringConverterI()); + Ice::InitializationData initData; initData.properties = Ice::createProperties(argc, argv); initData.properties->setProperty("TestAdapter.Endpoints", "default -p 12010"); - initData.stringConverter = new Test::StringConverterI(); - initData.wstringConverter = new Test::WstringConverterI(); communicator = Ice::initialize(argc, argv, initData); status = run(argc, argv, communicator); } diff --git a/cpp/test/Ice/custom/StringConverterI.cpp b/cpp/test/Ice/custom/StringConverterI.cpp index e7469d4d755..dc1e2cfdbba 100644 --- a/cpp/test/Ice/custom/StringConverterI.cpp +++ b/cpp/test/Ice/custom/StringConverterI.cpp @@ -11,13 +11,14 @@ #include <IceUtil/Unicode.h> using namespace std; +using namespace IceUtil; -Ice::Byte* -Test::StringConverterI::toUTF8(const char* sourceStart, const char* sourceEnd, Ice::UTF8Buffer& buffer) const +Byte* +Test::StringConverterI::toUTF8(const char* sourceStart, const char* sourceEnd, IceUtil::UTF8Buffer& buffer) const { size_t size = static_cast<size_t>(sourceEnd - sourceStart); - Ice::Byte* targetStart = buffer.getMoreBytes(size, 0); - Ice::Byte* targetEnd = targetStart + size; + Byte* targetStart = buffer.getMoreBytes(size, 0); + Byte* targetEnd = targetStart + size; size_t j = size; for(size_t i = 0; i < size; ++i) @@ -29,7 +30,7 @@ Test::StringConverterI::toUTF8(const char* sourceStart, const char* sourceEnd, I } void -Test::StringConverterI::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, +Test::StringConverterI::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, string& target) const { size_t size = static_cast<size_t>(sourceEnd - sourceStart); @@ -43,26 +44,26 @@ Test::StringConverterI::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* } -Ice::Byte* -Test::WstringConverterI::toUTF8(const wchar_t* sourceStart, const wchar_t* sourceEnd, Ice::UTF8Buffer& buffer) const +Byte* +Test::WstringConverterI::toUTF8(const wchar_t* sourceStart, const wchar_t* sourceEnd, IceUtil::UTF8Buffer& buffer) const { wstring ws(sourceStart, sourceEnd); - string s = IceUtil::wstringToString(ws); + string s = IceUtil::wnativeToNative(0, 0, ws); size_t size = s.size(); - Ice::Byte* targetStart = buffer.getMoreBytes(size, 0); - Ice::Byte* targetEnd = targetStart + size; + Byte* targetStart = buffer.getMoreBytes(size, 0); + Byte* targetEnd = targetStart + size; size_t j = size; for(size_t i = 0; i < size; ++i) { - targetStart[i] = static_cast<Ice::Byte>(s[--j]); + targetStart[i] = static_cast<Byte>(s[--j]); } return targetEnd; } void -Test::WstringConverterI::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, +Test::WstringConverterI::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, wstring& target) const { size_t size = static_cast<size_t>(sourceEnd - sourceStart); @@ -75,6 +76,6 @@ Test::WstringConverterI::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* s[i] = sourceStart[--j]; } - target = IceUtil::stringToWstring(s); + target = IceUtil::nativeToWnative(0, 0, s); } diff --git a/cpp/test/Ice/custom/StringConverterI.h b/cpp/test/Ice/custom/StringConverterI.h index 42d2ff6fa36..67ace8d90cd 100644 --- a/cpp/test/Ice/custom/StringConverterI.h +++ b/cpp/test/Ice/custom/StringConverterI.h @@ -10,7 +10,7 @@ #ifndef STRING_CONVERTER_I_H #define STRING_CONVERTER_I_H -#include <Ice/StringConverter.h> +#include <IceUtil/StringConverter.h> // // Simple contrived string converters which simply reverse the order of the @@ -20,21 +20,21 @@ namespace Test { -class StringConverterI : public Ice::StringConverter +class StringConverterI : public IceUtil::StringConverter { public: - virtual Ice::Byte* toUTF8(const char*, const char*, Ice::UTF8Buffer&) const; - virtual void fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, + virtual IceUtil::Byte* toUTF8(const char*, const char*, IceUtil::UTF8Buffer&) const; + virtual void fromUTF8(const IceUtil::Byte* sourceStart, const IceUtil::Byte* sourceEnd, std::string& target) const; }; -class WstringConverterI : public Ice::WstringConverter +class WstringConverterI : public IceUtil::WstringConverter { public: - virtual Ice::Byte* toUTF8(const wchar_t*, const wchar_t*, Ice::UTF8Buffer&) const; - virtual void fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, + virtual IceUtil::Byte* toUTF8(const wchar_t*, const wchar_t*, IceUtil::UTF8Buffer&) const; + virtual void fromUTF8(const IceUtil::Byte* sourceStart, const IceUtil::Byte* sourceEnd, std::wstring& target) const; }; diff --git a/cpp/test/Ice/stringConverter/Client.cpp b/cpp/test/Ice/stringConverter/Client.cpp index f653055adac..eb59598691d 100644 --- a/cpp/test/Ice/stringConverter/Client.cpp +++ b/cpp/test/Ice/stringConverter/Client.cpp @@ -11,13 +11,6 @@ #include <TestCommon.h> #include <Test.h> -#if defined(ICONV_ON_WINDOWS) -// -// On Windows, Ice/IcongStringConverter.h is not included by Ice/Ice.h -// -#include <Ice/IconvStringConverter.h> -#endif - #include <iostream> #include <locale.h> @@ -30,31 +23,6 @@ public: virtual int run(int, char*[]); }; -// -// Server side is pure unicode -// -class MyObjectI : public Test::MyObject -{ -public: - - virtual wstring widen(const string& msg, const Ice::Current&) - { - const Ice::Byte* cmsg = reinterpret_cast<const Ice::Byte*>(msg.c_str()); - - if(!IceUtil::isLegalUTF8Sequence(cmsg, cmsg + msg.size())) - { - throw Test::BadEncodingException(); - } - - return IceUtil::stringToWstring(msg); - } - - virtual string narrow(const wstring& wmsg, const Ice::Current&) - { - return IceUtil::wstringToString(wmsg); - } -}; - static bool useLocale = false; static bool useIconv = true; @@ -67,87 +35,68 @@ main(int argc, char* argv[]) // // Switch to French locale // (we just used the codeset for as default internal code for - // initData.stringConverter below) + // stringConverter below) // useLocale = (setlocale(LC_ALL, "fr_FR.ISO8859-15") != 0 || setlocale(LC_ALL, "fr_FR.iso885915@euro") != 0); #endif - - Ice::InitializationData initData; -#if defined(_WIN32) && !defined(ICONV_ON_WINDOWS) +#if defined(_WIN32) // // 28605 == ISO 8859-15 codepage // - initData.stringConverter = new Ice::WindowsStringConverter(28605); + IceUtil::setProcessStringConverter(new IceUtil::WindowsStringConverter(28605)); useIconv = false; #elif defined(__hpux) if(useLocale) { - initData.stringConverter = new Ice::IconvStringConverter<char>; + IceUtil::setProcessStringConverter(new IceUtil::IconvStringConverter<char>); } else { - initData.stringConverter = new Ice::IconvStringConverter<char>("iso815"); + IceUtil::setProcessStringConverter(new IceUtil::IconvStringConverter<char>("iso815")); } - initData.wstringConverter = new Ice::IconvStringConverter<wchar_t>("ucs4"); + IceUtil::setProcessWstringConverter(new IceUtil::IconvStringConverter<wchar_t>("ucs4")); #else if(useLocale) { -#ifndef _WIN32 - initData.stringConverter = new Ice::IconvStringConverter<char>; -#endif + IceUtil::setProcessStringConverter(new IceUtil::IconvStringConverter<char>()); } else { - initData.stringConverter = new Ice::IconvStringConverter<char>("ISO8859-15"); + IceUtil::setProcessStringConverter(new IceUtil::IconvStringConverter<char>("ISO8859-15")); } if(sizeof(wchar_t) == 4) { -#ifdef ICE_BIG_ENDIAN - initData.wstringConverter = new Ice::IconvStringConverter<wchar_t>("UTF-32BE"); -#else - initData.wstringConverter = new Ice::IconvStringConverter<wchar_t>("UTF-32LE"); -#endif +# ifdef ICE_BIG_ENDIAN + IceUtil::setProcessWstringConverter(new IceUtil::IconvStringConverter<wchar_t>("UTF-32BE")); +# else + IceUtil::setProcessWstringConverter(new IceUtil::IconvStringConverter<wchar_t>("UTF-32LE")); +# endif } else { -#ifdef ICE_BIG_ENDIAN - initData.wstringConverter = new Ice::IconvStringConverter<wchar_t>("UTF-16BE"); -#else - initData.wstringConverter = new Ice::IconvStringConverter<wchar_t>("UTF-16LE"); -#endif +# ifdef ICE_BIG_ENDIAN + IceUtil::setProcessWstringConverter(new IceUtil::IconvStringConverter<wchar_t>("UTF-16BE")); +# else + IceUtil::setProcessWstringConverter(new IceUtil::IconvStringConverter<wchar_t>("UTF-16LE")); +# endif } #endif - return app.main(argc, argv, initData); + return app.main(argc, argv); } int Client::run(int, char*[]) { - // - // Create server communicator and OA - // - Ice::InitializationData initData; - initData.properties = communicator()->getProperties()->clone(); - Ice::CommunicatorPtr serverCommunicator = Ice::initialize(initData); - Ice::ObjectAdapterPtr oa = serverCommunicator->createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost"); - - Ice::ObjectPtr servant = new MyObjectI; - Test::MyObjectPrx serverPrx = Test::MyObjectPrx::uncheckedCast(oa->addWithUUID(servant)); - oa->activate(); - - // - // Get a prx in the client's communicator - // - Test::MyObjectPrx clientPrx = - Test::MyObjectPrx::uncheckedCast(communicator()->stringToProxy(serverPrx->ice_toString())); + Test::MyObjectPrx proxy = + Test::MyObjectPrx::uncheckedCast(communicator()->stringToProxy("test:default -h localhost -p 12010")); - char oe = char(0xBD); // A single character in ISO Latin 9 + char oe = char(0xBD); // A single character in ISO Latin 9 string msg = string("tu me fends le c") + oe + "ur!"; cout << "testing string converter"; if(useLocale) @@ -159,14 +108,10 @@ Client::run(int, char*[]) cout << " (using iconv)"; } cout << "... " << flush; - wstring wmsg = clientPrx->widen(msg); - test(clientPrx->narrow(wmsg) == msg); + wstring wmsg = proxy->widen(msg); + test(proxy->narrow(wmsg) == msg); test(wmsg.size() == msg.size()); cout << "ok" << endl; - - // - // destroy server communicator - // - serverCommunicator->destroy(); + proxy->shutdown(); return EXIT_SUCCESS; } diff --git a/cpp/test/Ice/stringConverter/Makefile b/cpp/test/Ice/stringConverter/Makefile index 0a484407695..c86cfb4a3b5 100644 --- a/cpp/test/Ice/stringConverter/Makefile +++ b/cpp/test/Ice/stringConverter/Makefile @@ -10,22 +10,32 @@ top_srcdir = ../../.. CLIENT = $(call mktestname,client) +SERVER = $(call mktestname,server) -TARGETS = $(CLIENT) +TARGETS = $(CLIENT) $(SERVER) -OBJS = Test.o \ - Client.o +COBJS = Test.o \ + Client.o -SRCS = $(OBJS:.o=.cpp) +SOBJS = Test.o \ + Server.o + +SRCS = $(COBJS:.o=.cpp) \ + $(SOBJS:.o=.cpp) SLICE_SRCS = Test.ice + include $(top_srcdir)/config/Make.rules CPPFLAGS := -I. -I../../include $(CPPFLAGS) -$(CLIENT): $(OBJS) +$(CLIENT): $(COBJS) + rm -f $@ + $(call mktest,$@,$(COBJS),$(OPENSSL_RPATH_LINK) $(ICESSL_LIBS) $(ICEWS_LIBS)) + +$(SERVER): $(SOBJS) rm -f $@ - $(call mktest,$@,$(OBJS),$(LIBS) $(ICONV_LIBS)) + $(call mktest,$@,$(SOBJS),$(ICESSL_LIBS) $(ICEWS_LIBS)) include .depend diff --git a/cpp/test/Ice/stringConverter/Makefile.mak b/cpp/test/Ice/stringConverter/Makefile.mak index b03a42eedb5..619bb89ad5c 100644 --- a/cpp/test/Ice/stringConverter/Makefile.mak +++ b/cpp/test/Ice/stringConverter/Makefile.mak @@ -10,32 +10,38 @@ top_srcdir = ..\..\.. CLIENT = client.exe +SERVER = server.exe -TARGETS = $(CLIENT) +TARGETS = $(CLIENT) $(SERVER) -OBJS = Client.obj \ - Test.obj +OBJS = Test.obj + +COBJS = Client.obj + +SOBJS = Server.obj SRCS = $(OBJS:.obj=.cpp) !include $(top_srcdir)/config/Make.rules.mak CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN -!if "$(ICONV_HOME)" != "" -CPPFLAGS = $(CPPFLAGS) -I$(ICONV_HOME)\include -DICONV_ON_WINDOWS -DICE_NO_ERRNO -LIBS = $(LIBS) -LIBPATH:$(ICONV_HOME)\lib $(ICONV_LIB) -!endif !if "$(GENERATE_PDB)" == "yes" -PDBFLAGS = /pdb:$(CLIENT:.exe=.pdb) +CPDBFLAGS = /pdb:$(CLIENT).pdb +SPDBFLAGS = /pdb:$(SERVER).pdb !endif -$(CLIENT): $(OBJS) - $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(SETARGV) $(OBJS) $(PREOUT)$@ $(PRELIBS)$(LIBNAME) $(LIBS) +$(CLIENT): $(COBJS) $(OBJS) + $(LINK) $(LD_EXEFLAGS) $(CPDBFLAGS) $(SETARGV) $(COBJS) $(OBJS) $(PREOUT)$@ $(PRELIBS)$(LIBNAME) $(LIBS) + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest + +$(SERVER): $(SOBJS) $(OBJS) + $(LINK) $(LD_EXEFLAGS) $(SPDBFLAGS) $(SETARGV) $(SOBJS) $(OBJS) $(PREOUT)$@ $(PRELIBS)$(LIBNAME) $(LIBS) @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest -all:: $(CLIENT) +all:: $(TARGETS) clean:: del /q Test.cpp Test.h diff --git a/cpp/test/Ice/stringConverter/Server.cpp b/cpp/test/Ice/stringConverter/Server.cpp new file mode 100644 index 00000000000..4b9c6a78c20 --- /dev/null +++ b/cpp/test/Ice/stringConverter/Server.cpp @@ -0,0 +1,96 @@ +// ********************************************************************** +// +// 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 <Ice/Ice.h> +#include <TestCommon.h> +#include <Test.h> + +DEFINE_TEST("server"); + +using namespace std; + +// +// Server side is pure unicode +// +class MyObjectI : public Test::MyObject +{ +public: + + virtual wstring widen(const string& msg, const Ice::Current&) + { + const Ice::Byte* cmsg = reinterpret_cast<const Ice::Byte*>(msg.c_str()); + + if(!IceUtil::isLegalUTF8Sequence(cmsg, cmsg + msg.size())) + { + throw Test::BadEncodingException(); + } + + return IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), + IceUtil::getProcessWstringConverter(), msg); + } + + virtual string narrow(const wstring& wmsg, const Ice::Current&) + { + return IceUtil::wnativeToNative(IceUtil::getProcessStringConverter(), + IceUtil::getProcessWstringConverter(), wmsg); + } + + virtual void shutdown(const Ice::Current& current) + { + current.adapter->getCommunicator()->shutdown(); + } +}; + +int +run(int, char**, const Ice::CommunicatorPtr& communicator) +{ + communicator->getProperties()->setProperty("TestAdapter.Endpoints", "default -p 12010:udp -p 12010"); + Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("TestAdapter"); + adapter->add(new MyObjectI, communicator->stringToIdentity("test")); + adapter->activate(); + + TEST_READY + communicator->waitForShutdown(); + return EXIT_SUCCESS; +} + +int +main(int argc, char* argv[]) +{ + int status; + Ice::CommunicatorPtr communicator; + + try + { + Ice::InitializationData initData; + initData.properties = Ice::createProperties(argc, argv); + communicator = Ice::initialize(argc, argv, initData); + status = run(argc, argv, communicator); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + + if(communicator) + { + try + { + communicator->destroy(); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + } + + return status; +} diff --git a/cpp/test/Ice/stringConverter/Test.ice b/cpp/test/Ice/stringConverter/Test.ice index 3c8d19d4342..2a9df0fe395 100644 --- a/cpp/test/Ice/stringConverter/Test.ice +++ b/cpp/test/Ice/stringConverter/Test.ice @@ -18,6 +18,8 @@ interface MyObject { ["cpp:type:wstring"] string widen(string msg) throws BadEncodingException; string narrow(["cpp:type:wstring"] string wmsg); + + void shutdown(); }; }; diff --git a/cpp/test/Ice/stringConverter/run.py b/cpp/test/Ice/stringConverter/run.py index eed9bface4f..33fc2e8f3ac 100755 --- a/cpp/test/Ice/stringConverter/run.py +++ b/cpp/test/Ice/stringConverter/run.py @@ -20,6 +20,4 @@ if len(path) == 0: sys.path.append(os.path.join(path[0], "scripts")) import TestUtil -client = os.path.join(os.getcwd(), "client") - -TestUtil.simpleTest(client) +TestUtil.clientServerTest() diff --git a/cpp/test/IceGrid/Makefile.mak b/cpp/test/IceGrid/Makefile.mak index ecea19801a9..a33cdafc4be 100644 --- a/cpp/test/IceGrid/Makefile.mak +++ b/cpp/test/IceGrid/Makefile.mak @@ -17,7 +17,6 @@ SUBDIRS = activation \ allocation \ deployer \ distribution \ - fileLock \ noRestartUpdate \ replicaGroup \ replication \ diff --git a/cpp/test/IceGrid/deployer/Server.cpp b/cpp/test/IceGrid/deployer/Server.cpp index 7673e082a6e..3d576116fa4 100644 --- a/cpp/test/IceGrid/deployer/Server.cpp +++ b/cpp/test/IceGrid/deployer/Server.cpp @@ -80,13 +80,13 @@ main(int argc, char* argv[]) #if defined(_WIN32) wchar_t* value2 = _wgetenv(L"MY_ENV_UNICODE_VARIABLE"); - test(value2 != 0 && wstring(value2) == IceUtil::stringToWstring(unicodeVar)); + test(value2 != 0 && wstring(value2) == IceUtil::nativeToWnative(0, 0, unicodeVar)); - wchar_t* value3 = _wgetenv(IceUtil::stringToWstring(varname1).c_str()); + wchar_t* value3 = _wgetenv(IceUtil::nativeToWnative(0, 0, varname1).c_str()); test(value3 != 0 && wstring(value3) == L"2"); // Environment variables are case insensitive on Windows. - wchar_t* value4 = _wgetenv(IceUtil::stringToWstring(varname1).c_str()); + wchar_t* value4 = _wgetenv(IceUtil::nativeToWnative(0, 0, varname1).c_str()); test(value4 != 0 && wstring(value4) == L"2"); char* value5 = getenv("MY_WINDOWS_COMPOSED_VARIABLE"); diff --git a/cpp/test/IceGrid/replicaGroup/Makefile b/cpp/test/IceGrid/replicaGroup/Makefile index fc64b7f3c1f..aa9d9238ee9 100644 --- a/cpp/test/IceGrid/replicaGroup/Makefile +++ b/cpp/test/IceGrid/replicaGroup/Makefile @@ -18,7 +18,7 @@ SVCSONAME = $(call mksoname,TestService) PLUGINFILENAME = $(call mklibfilename,RegistryPlugin,$(VERSION)) PLUGINSONAME = $(call mksoname,RegistryPlugin,$(SOVERSION)) -TARGETS = $(CLIENT) $(SERVER) $(SVCFILENAME ) $(call mklibtargets,$(PLUGINFILENAME),$(PLUGINSONAME)) +TARGETS = $(CLIENT) $(SERVER) $(SVCFILENAME) $(call mklibtargets,$(PLUGINFILENAME),$(PLUGINSONAME)) OBJS = Test.o diff --git a/cpp/test/IceUtil/unicode/Client.cpp b/cpp/test/IceUtil/unicode/Client.cpp index db569292aa5..94f568ff334 100644 --- a/cpp/test/IceUtil/unicode/Client.cpp +++ b/cpp/test/IceUtil/unicode/Client.cpp @@ -9,6 +9,7 @@ #include <IceUtil/Unicode.h> #include <IceUtil/FileUtil.h> +#include <IceUtil/StringConverter.h> #include <TestCommon.h> #ifdef _WIN32 @@ -21,7 +22,7 @@ using namespace IceUtil; using namespace std; // -// Note that each file starts with a BOM; stringToWstring and wstringToString +// Note that each file starts with a BOM; nativeToWnative and wnativeToNative // converts these BOMs back and forth. // @@ -47,7 +48,7 @@ main(int argc, char* argv[]) # ifdef __MINGW32__ dir = argv[1]; # else - dir = IceUtil::wstringToString(argv[1]); + dir = IceUtil::wnativeToNative(0, 0, argv[1]); # endif dir += "\\"; #else @@ -83,7 +84,7 @@ main(int argc, char* argv[]) test(isLegalUTF8Sequence(reinterpret_cast<const Byte*>(line.data()), reinterpret_cast<const Byte*>(line.data() + line.size()))); lineNumber++; - wstring wline = stringToWstring(line); + wstring wline = nativeToWnative(0, 0, line); for(size_t i = 0; i < wline.length(); ++i) { @@ -156,7 +157,7 @@ main(int argc, char* argv[]) } } while(bis.good()); - string s = wstringToString(ws); + string s = wnativeToNative(0, 0, ws); IceUtilInternal::ifstream nbis((dir + "coeur.utf8"), ios_base::binary); test(nbis.good()); diff --git a/cs/src/Ice/PropertyNames.cs b/cs/src/Ice/PropertyNames.cs index 5826c53b686..1982ea9ffd1 100644 --- a/cs/src/Ice/PropertyNames.cs +++ b/cs/src/Ice/PropertyNames.cs @@ -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! @@ -97,6 +97,7 @@ namespace IceInternal new Property(@"^Ice\.ImplicitContext$", false, null), new Property(@"^Ice\.InitPlugins$", false, null), new Property(@"^Ice\.LogFile$", false, null), + new Property(@"^Ice\.LogStdErr\.Convert$", false, null), new Property(@"^Ice\.MessageSizeMax$", false, null), new Property(@"^Ice\.MonitorConnections$", false, null), new Property(@"^Ice\.Nohup$", false, null), diff --git a/java/src/IceInternal/PropertyNames.java b/java/src/IceInternal/PropertyNames.java index eee2fcac14a..5e48464bced 100644 --- a/java/src/IceInternal/PropertyNames.java +++ b/java/src/IceInternal/PropertyNames.java @@ -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! @@ -97,6 +97,7 @@ public final class PropertyNames new Property("Ice\\.ImplicitContext", false, null), new Property("Ice\\.InitPlugins", false, null), new Property("Ice\\.LogFile", false, null), + new Property("Ice\\.LogStdErr\\.Convert", false, null), new Property("Ice\\.MessageSizeMax", false, null), new Property("Ice\\.MonitorConnections", false, null), new Property("Ice\\.Nohup", false, null), diff --git a/js/src/Ice/PropertyNames.js b/js/src/Ice/PropertyNames.js index 5537b8c9d14..e21a4faae64 100644 --- a/js/src/Ice/PropertyNames.js +++ b/js/src/Ice/PropertyNames.js @@ -8,7 +8,7 @@ // ********************************************************************** ///* jshint -W044*/ -// Generated by makeprops.py from file PropertyNames.xml, Tue Feb 4 16:00:18 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! @@ -33,6 +33,7 @@ new Property("/^Ice\.Admin\.Locator\.Locator/", false, null), new Property("/^Ice\.Admin\.Locator\.Router/", false, null), new Property("/^Ice\.Admin\.Locator\.CollocationOptimized/", false, null), + new Property("/^Ice\.Admin\.Locator\.Context\../", false, null), new Property("/^Ice\.Admin\.Locator/", false, null), new Property("/^Ice\.Admin\.PublishedEndpoints/", false, null), new Property("/^Ice\.Admin\.ReplicaGroupId/", false, null), @@ -43,6 +44,7 @@ new Property("/^Ice\.Admin\.Router\.Locator/", false, null), new Property("/^Ice\.Admin\.Router\.Router/", false, null), new Property("/^Ice\.Admin\.Router\.CollocationOptimized/", false, null), + new Property("/^Ice\.Admin\.Router\.Context\../", false, null), new Property("/^Ice\.Admin\.Router/", false, null), new Property("/^Ice\.Admin\.ProxyOptions/", false, null), new Property("/^Ice\.Admin\.ThreadPool\.Size/", false, null), @@ -74,6 +76,7 @@ new Property("/^Ice\.Default\.Locator\.Locator/", false, null), new Property("/^Ice\.Default\.Locator\.Router/", false, null), new Property("/^Ice\.Default\.Locator\.CollocationOptimized/", false, null), + new Property("/^Ice\.Default\.Locator\.Context\../", false, null), new Property("/^Ice\.Default\.Locator/", false, null), new Property("/^Ice\.Default\.LocatorCacheTimeout/", false, null), new Property("/^Ice\.Default\.Package/", false, null), @@ -86,6 +89,7 @@ new Property("/^Ice\.Default\.Router\.Locator/", false, null), new Property("/^Ice\.Default\.Router\.Router/", false, null), new Property("/^Ice\.Default\.Router\.CollocationOptimized/", false, null), + new Property("/^Ice\.Default\.Router\.Context\../", false, null), new Property("/^Ice\.Default\.Router/", false, null), new Property("/^Ice\.Default\.SlicedFormat/", false, null), new Property("/^Ice\.IPv4/", false, null), @@ -96,6 +100,7 @@ new Property("/^Ice\.ImplicitContext/", false, null), new Property("/^Ice\.InitPlugins/", false, null), new Property("/^Ice\.LogFile/", false, null), + new Property("/^Ice\.LogStdErr\.Convert/", false, null), new Property("/^Ice\.MessageSizeMax/", false, null), new Property("/^Ice\.MonitorConnections/", false, null), new Property("/^Ice\.Nohup/", false, null), |