summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2014-05-02 19:56:38 +0200
committerJose <jose@zeroc.com>2014-05-02 19:56:38 +0200
commit1161c5817059464ab511632c0ce5d14593ced1a3 (patch)
tree51bbcdf2a4ea43c430312157350bb4271bc3f40d
parentUpdate .gitignore files (diff)
downloadice-1161c5817059464ab511632c0ce5d14593ced1a3.tar.bz2
ice-1161c5817059464ab511632c0ce5d14593ced1a3.tar.xz
ice-1161c5817059464ab511632c0ce5d14593ced1a3.zip
ICE-4851 - Use wstrings for input and output data that contain non-ASCII characters?
-rw-r--r--CHANGES19
-rw-r--r--config/PropertyNames.xml1
-rwxr-xr-xconfig/makeprops.py3
-rwxr-xr-xcpp/config/Make.rules.msvc1
-rw-r--r--cpp/demo/Glacier2/chat/config.client2
-rw-r--r--cpp/demo/Ice/MFC/client/HelloClientDlg.cpp2
-rw-r--r--cpp/demo/Ice/converter/Client.cpp93
-rw-r--r--cpp/demo/Ice/converter/Client.h25
-rw-r--r--cpp/demo/Ice/converter/ClientWithConverter.cpp36
-rw-r--r--cpp/demo/Ice/converter/ClientWithoutConverter.cpp30
-rw-r--r--cpp/demo/Ice/converter/Makefile21
-rw-r--r--cpp/demo/Ice/converter/Makefile.mak27
-rw-r--r--cpp/demo/Ice/converter/README26
-rw-r--r--cpp/demo/Ice/converter/StringConverterI.cpp12
-rw-r--r--cpp/demo/Ice/converter/StringConverterI.h8
-rwxr-xr-xcpp/demo/Ice/converter/expect.py21
-rw-r--r--cpp/include/Ice/BasicStream.h13
-rw-r--r--cpp/include/Ice/DynamicLibrary.h4
-rw-r--r--cpp/include/Ice/Ice.h3
-rw-r--r--cpp/include/Ice/Initialize.h12
-rw-r--r--cpp/include/Ice/StringConverter.h161
-rw-r--r--cpp/include/IceUtil/Exception.h21
-rw-r--r--cpp/include/IceUtil/FileUtil.h1
-rw-r--r--cpp/include/IceUtil/IceUtil.h4
-rw-r--r--cpp/include/IceUtil/IconvStringConverter.h (renamed from cpp/include/Ice/IconvStringConverter.h)139
-rw-r--r--cpp/include/IceUtil/StringConverter.h193
-rw-r--r--cpp/include/IceUtil/UndefSysMacros.h (renamed from cpp/include/Ice/UndefSysMacros.h)4
-rw-r--r--cpp/include/IceUtil/Unicode.h7
-rw-r--r--cpp/src/Freeze/EvictorI.cpp9
-rw-r--r--cpp/src/Freeze/IndexI.cpp11
-rw-r--r--cpp/src/Freeze/MapDb.cpp16
-rw-r--r--cpp/src/Freeze/MapI.cpp19
-rw-r--r--cpp/src/Freeze/ObjectStore.cpp10
-rw-r--r--cpp/src/Freeze/SharedDbEnv.cpp7
-rw-r--r--cpp/src/FreezeScript/DumpDB.cpp8
-rw-r--r--cpp/src/FreezeScript/transformdb.cpp7
-rw-r--r--cpp/src/Glacier2/Glacier2Router.cpp4
-rw-r--r--cpp/src/Ice/Application.cpp18
-rw-r--r--cpp/src/Ice/BasicStream.cpp213
-rw-r--r--cpp/src/Ice/DynamicLibrary.cpp15
-rw-r--r--cpp/src/Ice/Exception.cpp7
-rw-r--r--cpp/src/Ice/Initialize.cpp34
-rw-r--r--cpp/src/Ice/Instance.cpp74
-rw-r--r--cpp/src/Ice/Instance.h11
-rw-r--r--cpp/src/Ice/LoggerI.cpp117
-rw-r--r--cpp/src/Ice/LoggerI.h7
-rw-r--r--cpp/src/Ice/Makefile4
-rw-r--r--cpp/src/Ice/Makefile.mak2
-rw-r--r--cpp/src/Ice/Network.cpp60
-rw-r--r--cpp/src/Ice/PluginManagerI.cpp2
-rw-r--r--cpp/src/Ice/PropertiesI.cpp27
-rw-r--r--cpp/src/Ice/PropertiesI.h16
-rw-r--r--cpp/src/Ice/PropertyNames.cpp3
-rw-r--r--cpp/src/Ice/PropertyNames.h2
-rw-r--r--cpp/src/Ice/Reference.cpp4
-rw-r--r--cpp/src/Ice/ReferenceFactory.cpp4
-rw-r--r--cpp/src/Ice/ServantManager.cpp4
-rw-r--r--cpp/src/Ice/Service.cpp92
-rw-r--r--cpp/src/Ice/StringConverter.cpp452
-rw-r--r--cpp/src/Ice/StringConverterPlugin.cpp179
-rw-r--r--cpp/src/Ice/StringConverterPlugin.h44
-rw-r--r--cpp/src/Ice/ThreadPool.cpp7
-rw-r--r--cpp/src/IceBox/ServiceManagerI.cpp3
-rw-r--r--cpp/src/IceGrid/Activator.cpp31
-rw-r--r--cpp/src/IceGrid/IceGridNode.cpp6
-rw-r--r--cpp/src/IceGrid/RegistryI.cpp4
-rw-r--r--cpp/src/IceGrid/ServerI.cpp4
-rw-r--r--cpp/src/IcePatch2Lib/ClientUtil.cpp11
-rw-r--r--cpp/src/IcePatch2Lib/Util.cpp8
-rw-r--r--cpp/src/IceSSL/Instance.cpp6
-rw-r--r--cpp/src/IceUtil/Exception.cpp60
-rw-r--r--cpp/src/IceUtil/FileUtil.cpp115
-rw-r--r--cpp/src/IceUtil/Makefile5
-rw-r--r--cpp/src/IceUtil/Makefile.mak3
-rw-r--r--cpp/src/IceUtil/StringConverter.cpp478
-rw-r--r--cpp/src/IceUtil/StringUtil.cpp6
-rw-r--r--cpp/src/Slice/Preprocessor.cpp7
-rw-r--r--cpp/src/iceserviceinstall/ServiceInstaller.cpp86
-rw-r--r--cpp/src/slice2cpp/Gen.cpp2
-rw-r--r--cpp/test/Ice/custom/Client.cpp5
-rw-r--r--cpp/test/Ice/custom/Collocated.cpp5
-rw-r--r--cpp/test/Ice/custom/Server.cpp6
-rw-r--r--cpp/test/Ice/custom/ServerAMD.cpp5
-rw-r--r--cpp/test/Ice/custom/StringConverterI.cpp27
-rw-r--r--cpp/test/Ice/custom/StringConverterI.h14
-rw-r--r--cpp/test/Ice/stringConverter/Client.cpp105
-rw-r--r--cpp/test/Ice/stringConverter/Makefile22
-rw-r--r--cpp/test/Ice/stringConverter/Makefile.mak28
-rw-r--r--cpp/test/Ice/stringConverter/Server.cpp96
-rw-r--r--cpp/test/Ice/stringConverter/Test.ice2
-rwxr-xr-xcpp/test/Ice/stringConverter/run.py4
-rw-r--r--cpp/test/IceGrid/Makefile.mak1
-rw-r--r--cpp/test/IceGrid/deployer/Server.cpp6
-rw-r--r--cpp/test/IceGrid/replicaGroup/Makefile2
-rw-r--r--cpp/test/IceUtil/unicode/Client.cpp9
-rw-r--r--cs/src/Ice/PropertyNames.cs3
-rw-r--r--java/src/IceInternal/PropertyNames.java3
-rw-r--r--js/src/Ice/PropertyNames.js7
98 files changed, 2183 insertions, 1380 deletions
diff --git a/CHANGES b/CHANGES
index fbf3953c89e..a3416b4ad66 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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, &params);
+ _fd = ::CreateFile2(IceUtil::nativeToWnative(IceUtil::getProcessStringConverter(), 0, path).c_str(),
+ GENERIC_WRITE, 0, OPEN_ALWAYS, &params);
#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),