summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2009-02-09 19:20:38 +0100
committerBenoit Foucher <benoit@zeroc.com>2009-02-09 19:20:38 +0100
commit124b43c7bd718655556bd3cba2a554293bf63d16 (patch)
tree5c3138e3c96e9f3a4763e1b6eea92018d892b241 /cpp
parentBug 3519 - fix use of tolower in slice2freeze (diff)
downloadice-124b43c7bd718655556bd3cba2a554293bf63d16.tar.bz2
ice-124b43c7bd718655556bd3cba2a554293bf63d16.tar.xz
ice-124b43c7bd718655556bd3cba2a554293bf63d16.zip
Support for serializable and protobuf metadata (from cs_serial branch)
Diffstat (limited to 'cpp')
-rw-r--r--cpp/demo/Ice/protobuf/.depend8
-rw-r--r--cpp/demo/Ice/protobuf/.gitignore9
-rw-r--r--cpp/demo/Ice/protobuf/Client.cpp116
-rw-r--r--cpp/demo/Ice/protobuf/Hello.ice29
-rw-r--r--cpp/demo/Ice/protobuf/HelloI.cpp27
-rw-r--r--cpp/demo/Ice/protobuf/HelloI.h23
-rw-r--r--cpp/demo/Ice/protobuf/Makefile66
-rw-r--r--cpp/demo/Ice/protobuf/Makefile.mak73
-rw-r--r--cpp/demo/Ice/protobuf/Person.proto16
-rw-r--r--cpp/demo/Ice/protobuf/README63
-rw-r--r--cpp/demo/Ice/protobuf/Server.cpp44
-rw-r--r--cpp/demo/Ice/protobuf/config.client23
-rw-r--r--cpp/demo/Ice/protobuf/config.server24
-rw-r--r--cpp/include/Slice/CPlusPlusUtil.h1
-rw-r--r--cpp/include/Slice/JavaUtil.h3
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.cpp142
-rw-r--r--cpp/src/Slice/CsUtil.cpp38
-rw-r--r--cpp/src/Slice/JavaUtil.cpp200
-rw-r--r--cpp/src/Slice/PythonUtil.cpp64
-rw-r--r--cpp/src/slice2cpp/Gen.cpp235
-rw-r--r--cpp/src/slice2cs/Gen.cpp23
-rw-r--r--cpp/src/slice2java/Gen.cpp17
-rw-r--r--cpp/test/Ice/protobuf/.depend8
-rw-r--r--cpp/test/Ice/protobuf/.gitignore10
-rw-r--r--cpp/test/Ice/protobuf/AllTests.cpp148
-rw-r--r--cpp/test/Ice/protobuf/Client.cpp70
-rw-r--r--cpp/test/Ice/protobuf/Makefile67
-rw-r--r--cpp/test/Ice/protobuf/Makefile.mak74
-rw-r--r--cpp/test/Ice/protobuf/Server.cpp66
-rw-r--r--cpp/test/Ice/protobuf/Test.ice61
-rw-r--r--cpp/test/Ice/protobuf/Test.proto16
-rw-r--r--cpp/test/Ice/protobuf/TestI.cpp33
-rw-r--r--cpp/test/Ice/protobuf/TestI.h26
-rwxr-xr-xcpp/test/Ice/protobuf/run.py24
34 files changed, 1743 insertions, 104 deletions
diff --git a/cpp/demo/Ice/protobuf/.depend b/cpp/demo/Ice/protobuf/.depend
new file mode 100644
index 00000000000..894f66bd977
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/.depend
@@ -0,0 +1,8 @@
+Hello$(OBJEXT): Hello.cpp Hello.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/LoggerF.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h Person.pb.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/Stream.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/ScopedArray.h
+Person.pb$(OBJEXT): Person.pb.cpp Person.pb.h
+Client$(OBJEXT): Client.cpp $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Functional.h $(includedir)/IceUtil/Functional.h $(includedir)/Ice/Stream.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h Hello.h Person.pb.h
+HelloI$(OBJEXT): HelloI.cpp $(includedir)/IceUtil/IceUtil.h $(includedir)/IceUtil/Config.h $(includedir)/IceUtil/AbstractMutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Exception.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/Cache.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/CountDownLatch.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/CtrlCHandler.h $(includedir)/IceUtil/Functional.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/RWRecMutex.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/RecMutex.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/UUID.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/Handle.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Functional.h $(includedir)/Ice/Stream.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h HelloI.h Hello.h Person.pb.h
+Server$(OBJEXT): Server.cpp $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Functional.h $(includedir)/IceUtil/Functional.h $(includedir)/Ice/Stream.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h HelloI.h Hello.h Person.pb.h
+Hello.cpp: Hello.ice
+Hello.ice: $(SLICE2CPP) $(SLICEPARSERLIB)
+Person.pb.cpp: Person.proto
diff --git a/cpp/demo/Ice/protobuf/.gitignore b/cpp/demo/Ice/protobuf/.gitignore
new file mode 100644
index 00000000000..0c7a711fcec
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/.gitignore
@@ -0,0 +1,9 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+Hello.cpp
+Hello.h
+Person.pb.cpp
+Person.pb.h
diff --git a/cpp/demo/Ice/protobuf/Client.cpp b/cpp/demo/Ice/protobuf/Client.cpp
new file mode 100644
index 00000000000..0baae8f5248
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/Client.cpp
@@ -0,0 +1,116 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 <Hello.h>
+
+using namespace std;
+using namespace Demo;
+
+class HelloClient : public Ice::Application
+{
+public:
+
+ HelloClient();
+
+ virtual int run(int, char*[]);
+
+private:
+
+ void menu();
+};
+
+int
+main(int argc, char* argv[])
+{
+ HelloClient app;
+ return app.main(argc, argv, "config.client");
+}
+
+HelloClient::HelloClient() :
+ //
+ // Since this is an interactive demo we don't want any signal
+ // handling.
+ //
+ Ice::Application(Ice::NoSignalHandling)
+{
+}
+
+int
+HelloClient::run(int argc, char* argv[])
+{
+ if(argc > 1)
+ {
+ cerr << appName() << ": too many arguments" << endl;
+ return EXIT_FAILURE;
+ }
+
+ HelloPrx hello = HelloPrx::checkedCast(communicator()->propertyToProxy("Hello.Proxy"));
+ if(!hello)
+ {
+ cerr << argv[0] << ": invalid proxy" << endl;
+ return EXIT_FAILURE;
+ }
+
+ tutorial::Person p;
+ p.set_id(1);
+ p.set_name("Fred Jones");
+ p.set_email("fred@jones.com");
+
+ menu();
+
+ char c;
+ do
+ {
+ try
+ {
+ cout << "==> ";
+ cin >> c;
+ if(c == 't')
+ {
+ hello->sayHello(p);
+ }
+ else if(c == 's')
+ {
+ hello->shutdown();
+ }
+ else if(c == 'x')
+ {
+ // Nothing to do
+ }
+ else if(c == '?')
+ {
+ menu();
+ }
+ else
+ {
+ cout << "unknown command `" << c << "'" << endl;
+ menu();
+ }
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ }
+ }
+ while(cin.good() && c != 'x');
+
+ return EXIT_SUCCESS;
+}
+
+void
+HelloClient::menu()
+{
+ cout <<
+ "usage:\n"
+ "t: send greeting\n"
+ "s: shutdown server\n"
+ "x: exit\n"
+ "?: help\n";
+}
diff --git a/cpp/demo/Ice/protobuf/Hello.ice b/cpp/demo/Ice/protobuf/Hello.ice
new file mode 100644
index 00000000000..3453d0a9fa9
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/Hello.ice
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 HELLO_ICE
+#define HELLO_ICE
+
+[["cpp:include:Person.pb.h"]]
+
+module Demo
+{
+
+["cpp:protobuf:tutorial::Person", "java:protobuf:tutorial.PersonPB.Person", "python:protobuf:Person_pb2.Person"]
+sequence<byte> Person;
+
+interface Hello
+{
+ idempotent void sayHello(Person p);
+ void shutdown();
+};
+
+};
+
+#endif
diff --git a/cpp/demo/Ice/protobuf/HelloI.cpp b/cpp/demo/Ice/protobuf/HelloI.cpp
new file mode 100644
index 00000000000..7ea465805f6
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/HelloI.cpp
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 <IceUtil/IceUtil.h>
+#include <Ice/Ice.h>
+#include <HelloI.h>
+
+using namespace std;
+
+void
+HelloI::sayHello(const tutorial::Person& p, const Ice::Current&)
+{
+ cout << "Hello World from " << p.DebugString() << endl;
+}
+
+void
+HelloI::shutdown(const Ice::Current& c)
+{
+ cout << "Shutting down..." << endl;
+ c.adapter->getCommunicator()->shutdown();
+}
diff --git a/cpp/demo/Ice/protobuf/HelloI.h b/cpp/demo/Ice/protobuf/HelloI.h
new file mode 100644
index 00000000000..e82667964ab
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/HelloI.h
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 HELLO_I_H
+#define HELLO_I_H
+
+#include <Hello.h>
+
+class HelloI : public Demo::Hello
+{
+public:
+
+ virtual void sayHello(const tutorial::Person& p, const Ice::Current&);
+ virtual void shutdown(const Ice::Current&);
+};
+
+#endif
diff --git a/cpp/demo/Ice/protobuf/Makefile b/cpp/demo/Ice/protobuf/Makefile
new file mode 100644
index 00000000000..33f02dcecb5
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/Makefile
@@ -0,0 +1,66 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2008 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.
+#
+# **********************************************************************
+
+#
+# If protobuf is not installed in a standard location where the
+# compiler can find it, set PROTOBUF_HOME to the protobuf installation
+# directory.
+#
+PROTOBUF_HOME ?= /usr/local
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+OBJS = Hello.o \
+ Person.pb.o
+
+COBJS = Client.o
+
+SOBJS = HelloI.o \
+ Server.o
+
+SRCS = $(OBJS:.o=.cpp) \
+ $(COBJS:.o=.cpp) \
+ $(SOBJS:.o=.cpp)
+
+SLICE_SRCS = Hello.ice
+PROTO_SRCS = Person.proto
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I$(PROTOBUF_HOME)/include -I. $(CPPFLAGS)
+LIBS := $(LIBS) -L$(PROTOBUF_HOME)/lib -lprotobuf
+
+$(CLIENT): $(OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(COBJS) $(LIBS)
+
+$(SERVER): $(OBJS) $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(SOBJS) $(LIBS)
+
+%..pb.h %.pb.cpp: %.proto
+ rm -f $(*F).pb.h $(*F).pb.cpp
+ $(PROTOBUF_HOME)/bin/protoc --cpp_out=. $(*F).proto
+ mv $(*F).pb.cc $(*F).pb.cpp
+
+depend::
+ for i in $(PROTO_SRCS); do \
+ echo "$${i%.proto}.pb.cpp: $$i" >> .depend; \
+ done
+
+clean::
+ rm -f $(addsuffix .pb.cpp, $(basename $(notdir $(PROTO_SRCS))))
+ rm -f $(addsuffix .pb.h, $(basename $(notdir $(PROTO_SRCS))))
+
+include .depend
diff --git a/cpp/demo/Ice/protobuf/Makefile.mak b/cpp/demo/Ice/protobuf/Makefile.mak
new file mode 100644
index 00000000000..a9b69331a5d
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/Makefile.mak
@@ -0,0 +1,73 @@
+#**********************************************************************
+#
+# Copyright (c) 2003-2008 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.
+#
+# **********************************************************************
+
+#
+# If protobuf is not installed in a standard location where the
+# compiler can find it, set PROTOBUF_HOME to the protobuf installation
+# directory.
+#
+!if "$(PROTOBUF_HOME)" == ""
+PROTOBUF_HOME = c:\protobuf
+!endif
+
+top_srcdir = ..\..\..
+
+CLIENT = client.exe
+SERVER = server.exe
+
+TARGETS = $(CLIENT) $(SERVER)
+
+OBJS = Hello.obj \
+ Person.pb.obj
+
+COBJS = Client.obj
+
+SOBJS = HelloI.obj \
+ Server.obj
+
+SRCS = $(OBJS:.obj=.cpp) \
+ $(COBJS:.obj=.cpp) \
+ $(SOBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+# Need to use -W0 to gid rid of ugly warnings from generated protobuf file as
+# well as prevent compile failure on x64 due to warnings from protobuf headers
+CPPFLAGS = -I$(PROTOBUF_HOME)\include -I. $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN -W0
+LIBS = $(LIBS) /libpath:$(PROTOBUF_HOME)\lib libprotobuf.lib
+
+!if "$(GENERATE_PDB)" == "yes"
+CPDBFLAGS = /pdb:$(CLIENT:.exe=.pdb)
+SPDBFLAGS = /pdb:$(SERVER:.exe=.pdb)
+!endif
+
+$(CLIENT): $(OBJS) $(COBJS)
+ $(LINK) $(LD_EXEFLAGS) $(CPDBFLAGS) $(SETARGV) $(OBJS) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+$(SERVER): $(OBJS) $(SOBJS)
+ $(LINK) $(LD_EXEFLAGS) $(SPDBFLAGS) $(SETARGV) $(OBJS) $(SOBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+# A generic rule would be nicer, but since protoc generates .pb.cpp
+# it is not possible with nmake.
+Person.pb.cpp: Person.proto
+ del /q Person.pb.h Person.pb.cpp
+ $(PROTOBUF_HOME)\bin\protoc --cpp_out=. Person.proto
+ move Person.pb.cc Person.pb.cpp
+
+Person.pb.h: Person.pb.cpp
+
+clean::
+ del /q Hello.cpp Hello.h
+ del /q Person.pb.h Person.pb.cpp
+
+!include .depend
diff --git a/cpp/demo/Ice/protobuf/Person.proto b/cpp/demo/Ice/protobuf/Person.proto
new file mode 100644
index 00000000000..b68990dbc48
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/Person.proto
@@ -0,0 +1,16 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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.
+//
+// **********************************************************************
+
+package tutorial;
+
+message Person {
+ required int32 id = 1;
+ required string name = 2;
+ optional string email = 3;
+}
diff --git a/cpp/demo/Ice/protobuf/README b/cpp/demo/Ice/protobuf/README
new file mode 100644
index 00000000000..e8573ab5d40
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/README
@@ -0,0 +1,63 @@
+This demo shows how to integrate Google Protocol Buffers with Ice.
+
+The Protocol Buffers distribution and documentation can be found at
+
+ http://code.google.com/apis/protocolbuffers/
+
+This demo was tested with Protocol Buffers version 2.0.2.
+
+We have added new metadata that makes it possible for you to specify
+protocol buffers message types in your Slice definitions, with Ice
+handling the serialization chores for you automatically. The metadata,
+which may only be used on a sequence<byte> type, has the following
+syntax in C++:
+
+ cpp:protobuf[:protoc-generated-class]
+
+For example:
+
+ ["cpp:protobuf:tutorial::Person"] sequence<byte> Person;
+
+The type name specified in this example, tutorial::Person, corresponds
+to the C++ class generated by the Protocol Buffers compiler (protoc)
+for the definition shown below:
+
+ package tutorial;
+ message Person { ... };
+
+If the metadata omits the type name, the Slice compiler assumes that
+the message type resides in the same namespace as the Slice type. For
+example, consider this Slice definition:
+
+ module Demo
+ {
+
+ ["cpp:protobuf"] sequence<byte> Person;
+
+ };
+
+In this case the Slice compiler assumes that the message type
+corresponds to the C++ type Demo::Person, as shown in the following
+definition:
+
+ package Demo;
+ message Person { ... };
+
+C++ users must also add another metadata directive so that the header
+file generated by the protocol buffers compiler is included properly.
+This metadata directive must appear before any other Slice definitions
+and has the following syntax:
+
+ [["cpp:include:Person.pb.h"]]
+
+Prior to building the demo, please review Makefile or Makefile.mak in
+this directory and adjust the value of PROTOBUF_HOME to reflect the
+installation directory of Protocol Buffers on your system.
+
+To run the demo, first start the server:
+
+ $ server
+
+In a separate window, start the client:
+
+ $ client
diff --git a/cpp/demo/Ice/protobuf/Server.cpp b/cpp/demo/Ice/protobuf/Server.cpp
new file mode 100644
index 00000000000..e39445cd890
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/Server.cpp
@@ -0,0 +1,44 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 <HelloI.h>
+
+using namespace std;
+
+class HelloServer : public Ice::Application
+{
+public:
+
+ virtual int run(int, char*[]);
+};
+
+int
+main(int argc, char* argv[])
+{
+ HelloServer app;
+ return app.main(argc, argv, "config.server");
+}
+
+int
+HelloServer::run(int argc, char* argv[])
+{
+ if(argc > 1)
+ {
+ cerr << appName() << ": too many arguments" << endl;
+ return EXIT_FAILURE;
+ }
+
+ Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Hello");
+ Demo::HelloPtr hello = new HelloI;
+ adapter->add(hello, communicator()->stringToIdentity("hello"));
+ adapter->activate();
+ communicator()->waitForShutdown();
+ return EXIT_SUCCESS;
+}
diff --git a/cpp/demo/Ice/protobuf/config.client b/cpp/demo/Ice/protobuf/config.client
new file mode 100644
index 00000000000..a02cab0f4cb
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/config.client
@@ -0,0 +1,23 @@
+#
+# The client reads this property to create the reference to the
+# "hello" object in the server.
+#
+Hello.Proxy=hello:tcp -p 10000
+
+#
+# Network Tracing
+#
+# 0 = no network tracing
+# 1 = trace connection establishment and closure
+# 2 = like 1, but more detailed
+# 3 = like 2, but also trace data transfer
+#
+#Ice.Trace.Network=1
+
+#
+# Protocol Tracing
+#
+# 0 = no protocol tracing
+# 1 = trace protocol messages
+#
+#Ice.Trace.Protocol=1
diff --git a/cpp/demo/Ice/protobuf/config.server b/cpp/demo/Ice/protobuf/config.server
new file mode 100644
index 00000000000..309db9731b2
--- /dev/null
+++ b/cpp/demo/Ice/protobuf/config.server
@@ -0,0 +1,24 @@
+#
+# The server creates one single object adapter with the name
+# "Hello". The following line sets the endpoints for this
+# adapter.
+#
+Hello.Endpoints=tcp -p 10000
+
+#
+# Network Tracing
+#
+# 0 = no network tracing
+# 1 = trace connection establishment and closure
+# 2 = like 1, but more detailed
+# 3 = like 2, but also trace data transfer
+#
+#Ice.Trace.Network=1
+
+#
+# Protocol Tracing
+#
+# 0 = no protocol tracing
+# 1 = trace protocol messages
+#
+#Ice.Trace.Protocol=1
diff --git a/cpp/include/Slice/CPlusPlusUtil.h b/cpp/include/Slice/CPlusPlusUtil.h
index 4fc6ea5e822..0f121bcda98 100644
--- a/cpp/include/Slice/CPlusPlusUtil.h
+++ b/cpp/include/Slice/CPlusPlusUtil.h
@@ -48,6 +48,7 @@ SLICE_API void writeAllocateCode(::IceUtilInternal::Output&, const ParamDeclList
const StringList&, bool = false, bool = false);
SLICE_API void writeStreamMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, const std::string&, bool,
const std::string& = "", bool = false, const StringList& = StringList());
+SLICE_API std::string findMetaData(const SequencePtr&, const StringList&, bool, bool&);
SLICE_API std::string findMetaData(const StringList&, bool);
SLICE_API bool inWstringModule(const SequencePtr&);
diff --git a/cpp/include/Slice/JavaUtil.h b/cpp/include/Slice/JavaUtil.h
index d85ae3cf2bb..31cbd963f78 100644
--- a/cpp/include/Slice/JavaUtil.h
+++ b/cpp/include/Slice/JavaUtil.h
@@ -181,8 +181,7 @@ protected:
//
bool getDictionaryTypes(const DictionaryPtr&, const std::string&, const StringList&,
std::string&, std::string&) const;
- bool getSequenceTypes(const SequencePtr&, const std::string&, const StringList&,
- std::string&, std::string&) const;
+ bool getSequenceTypes(const SequencePtr&, const std::string&, const StringList&, std::string&, std::string&) const;
virtual JavaOutput* createOutput();
diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp
index 6997b9b436c..e09e622ea41 100644
--- a/cpp/src/Slice/CPlusPlusUtil.cpp
+++ b/cpp/src/Slice/CPlusPlusUtil.cpp
@@ -215,6 +215,13 @@ Slice::typeToString(const TypePtr& type, bool useWstring, const StringList& meta
}
else
{
+ // Get the metadata associated at the point of definition.
+ bool protobuf;
+ seqType = findMetaData(seq, seq->getMetaData(), true, protobuf);
+ if(protobuf && !seqType.empty())
+ {
+ return seqType;
+ }
return fixKwd(seq->scoped());
}
}
@@ -348,6 +355,13 @@ Slice::inputTypeToString(const TypePtr& type, bool useWstring, const StringList&
}
else
{
+ // Get the metadata associated at the point of definition.
+ bool protobuf;
+ seqType = findMetaData(seq, seq->getMetaData(), true, protobuf);
+ if(protobuf && !seqType.empty())
+ {
+ return "const " + seqType + "&";
+ }
return "const " + fixKwd(seq->scoped()) + "&";
}
}
@@ -432,6 +446,12 @@ Slice::outputTypeToString(const TypePtr& type, bool useWstring, const StringList
}
else
{
+ bool protobuf;
+ seqType = findMetaData(seq, seq->getMetaData(), true, protobuf);
+ if(protobuf && !seqType.empty())
+ {
+ return seqType + "&";
+ }
return fixKwd(seq->scoped()) + "&";
}
}
@@ -679,6 +699,7 @@ Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, const string&
if(marshal)
{
string scope = fixKwd(seq->scope());
+
if(seqType == "array" || seqType == "range:array")
{
//
@@ -758,11 +779,13 @@ Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, const string&
else
{
//
- // No modifying metadata specified. Use appropriate write methods for type.
+ // No modifying metadata specified. Use appropriate
+ // write methods for type.
//
StringList l = seq->getMetaData();
- seqType = findMetaData(l, false);
- if(!seqType.empty())
+ bool protobuf;
+ seqType = findMetaData(seq, l, false, protobuf);
+ if(protobuf || !seqType.empty())
{
out << nl << scope << "__" << funcSeq << (pointer ? "" : "&") << stream << ", " << fixedParam
<< ");";
@@ -911,12 +934,14 @@ Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, const string&
else
{
//
- // No modifying metadata supplied. Just use appropriate read function.
+ // No modifying metadata supplied. Just use
+ // appropriate read function.
//
StringList l = seq->getMetaData();
- seqType = findMetaData(l, false);
- if(!seqType.empty() || !builtin || builtin->kind() == Builtin::KindObject ||
- builtin->kind() == Builtin::KindObjectProxy)
+ bool protobuf;
+ seqType = findMetaData(seq, l, false, protobuf);
+ if(protobuf || !seqType.empty() || !builtin || builtin->kind() == Builtin::KindObject ||
+ builtin->kind() == Builtin::KindObjectProxy)
{
out << nl << scope << "__" << funcSeq << (pointer ? "" : "&") << stream << ", "
<< fixedParam << ");";
@@ -1019,8 +1044,13 @@ writeRangeAllocateCode(Output& out, const TypePtr& type, const string& fixedName
SequencePtr seq = SequencePtr::dynamicCast(type);
if(seq)
{
- string seqType = findMetaData(metaData, true);
- if(seqType.find("range") == 0 && seqType != "range:array")
+ bool protobuf;
+ string seqType = findMetaData(seq, metaData, true, protobuf);
+ if(!protobuf && seqType.empty())
+ {
+ seqType = findMetaData(seq, seq->getMetaData(), true, protobuf);
+ }
+ if(!protobuf && seqType.find("range") == 0 && seqType != "range:array")
{
StringList md;
if(seqType.find("range:") == 0)
@@ -1305,9 +1335,10 @@ Slice::writeStreamMarshalUnmarshalCode(Output& out, const TypePtr& type, const s
}
else
{
- seqType = findMetaData(seq->getMetaData(), false);
+ bool protobuf;
+ seqType = findMetaData(seq, seq->getMetaData(), false, protobuf);
builtin = BuiltinPtr::dynamicCast(seq->type());
- if(!seqType.empty() || !builtin || (builtin->kind() == Builtin::KindObject ||
+ if(protobuf || !seqType.empty() || !builtin || (builtin->kind() == Builtin::KindObject ||
builtin->kind() == Builtin::KindObjectProxy))
{
string scope = fixKwd(seq->scope());
@@ -1501,6 +1532,95 @@ Slice::writeStreamMarshalUnmarshalCode(Output& out, const TypePtr& type, const s
assert(false);
}
+// Accepted metadata.
+//
+// cpp:type:<typename>
+// cpp:const
+// cpp:array
+// cpp:range:<typename>
+// cpp:protobuf<:typename>
+//
+
+// This form is for sequences definitions only.
+string
+Slice::findMetaData(const SequencePtr& seq, const StringList& metaData, bool inParam, bool& isProtobuf)
+{
+ isProtobuf = false;
+ static const string prefix = "cpp:";
+ for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
+ {
+ string str = *q;
+ if(str.find(prefix) == 0)
+ {
+ string::size_type pos = str.find(':', prefix.size());
+ string ss;
+ if(pos == string::npos)
+ {
+ ss = str.substr(prefix.size());
+ }
+ else
+ {
+ ss = str.substr(prefix.size(), pos - prefix.size());
+ }
+ //
+ // If the form is cpp:type:<...> the data after cpp:type:
+ // is returned. If the form is cpp:range:<...> (and this
+ // is an inParam) the data after cpp: is returned.
+ //
+ if(ss == "protobuf" || pos != string::npos)
+ {
+ string ss = str.substr(prefix.size(), pos - prefix.size());
+ if(ss == "type")
+ {
+ return str.substr(pos + 1);
+ }
+ else if(ss == "protobuf")
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(!builtin || builtin->kind() != Builtin::KindByte)
+ {
+ continue;
+ }
+ isProtobuf = true;
+ if(pos != string::npos)
+ {
+ return str.substr(pos + 1);
+ }
+ return "";
+ }
+ else if(inParam && ss == "range")
+ {
+ return str.substr(prefix.size());
+ }
+ }
+ //
+ // If the data is an inParam and the metadata is cpp:array
+ // or cpp:range then array or range is returned.
+ //
+ else if(inParam)
+ {
+ if(ss == "array" || ss == "range")
+ {
+ return ss;
+ }
+ }
+ //
+ // Otherwise if the data is "class" it is returned.
+ //
+ else
+ {
+ if(ss == "class")
+ {
+ return ss;
+ }
+ }
+ }
+ }
+
+ return "";
+}
+
+// Does not handle cpp:protobuf
string
Slice::findMetaData(const StringList& metaData, bool inParam)
{
diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp
index a2f722b2dcb..58b41e7045c 100644
--- a/cpp/src/Slice/CsUtil.cpp
+++ b/cpp/src/Slice/CsUtil.cpp
@@ -214,6 +214,13 @@ Slice::CsGenerator::typeToString(const TypePtr& type)
}
}
+ prefix = "clr:serializable:";
+ if(seq->findMetaData(prefix, meta))
+ {
+ string type = meta.substr(prefix.size());
+ return global() + type;
+ }
+
return typeToString(seq->type()) + "[]";
}
@@ -888,6 +895,21 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
}
default:
{
+ string prefix = "clr:serializable:";
+ string meta;
+ if(seq->findMetaData(prefix, meta))
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeSerializable(" << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = (" << typeToString(seq) << ")" << stream << ".readSerializable();";
+ }
+ break;
+ }
+
typeS[0] = toupper(static_cast<unsigned char>(typeS[0]));
if(marshal)
{
@@ -1688,6 +1710,22 @@ Slice::CsGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
continue; // Custom type or List<T>
}
}
+ if(s.substr(prefix.size(), 13) == "serializable:")
+ {
+ string meta;
+ if(cont->findMetaData(prefix + "collection", meta)
+ || cont->findMetaData(prefix + "generic:", meta))
+ {
+ emitWarning(file, cont->line(), msg + " `" + meta + "':\n" +
+ "serialization can only be used with the array mapping for byte sequences");
+ }
+ string type = s.substr(prefix.size() + 13);
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(!type.empty() && builtin && builtin->kind() == Builtin::KindByte)
+ {
+ continue;
+ }
+ }
}
else if(StructPtr::dynamicCast(cont))
{
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp
index 99b617e2146..5c4b2420f90 100644
--- a/cpp/src/Slice/JavaUtil.cpp
+++ b/cpp/src/Slice/JavaUtil.cpp
@@ -551,6 +551,22 @@ Slice::JavaGenerator::typeToString(const TypePtr& type,
}
else
{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(builtin && builtin->kind() == Builtin::KindByte)
+ {
+ string prefix = "java:serializable:";
+ string meta;
+ if(seq->findMetaData(prefix, meta))
+ {
+ return string("Ice.Holder<") + meta.substr(prefix.size()) + " >";
+ }
+ prefix = "java:protobuf:";
+ if(seq->findMetaData(prefix, meta))
+ {
+ return string("Ice.Holder<") + meta.substr(prefix.size()) + " >";
+ }
+ }
+
//
// Only use the type's generated holder if the instance and
// formal types match.
@@ -595,6 +611,22 @@ Slice::JavaGenerator::typeToString(const TypePtr& type,
}
else
{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(builtin && builtin->kind() == Builtin::KindByte)
+ {
+ string prefix = "java:serializable:";
+ string meta;
+ if(seq->findMetaData(prefix, meta))
+ {
+ return meta.substr(prefix.size());
+ }
+ prefix = "java:protobuf:";
+ if(seq->findMetaData(prefix, meta))
+ {
+ return meta.substr(prefix.size());
+ }
+ }
+
string instanceType, formalType;
getSequenceTypes(seq, package, metaData, instanceType, formalType);
return formal ? formalType : instanceType;
@@ -1241,15 +1273,64 @@ Slice::JavaGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
{
string stream = marshal ? "__os" : "__is";
string v = param;
+ bool java2 = seq->definitionContext()->findMetaData(_java2MetaData) == _java2MetaData;
+
+ //
+ // If the sequence is a byte sequence, check if there's the serializable or protobuf metadata to
+ // get rid of these two easy cases first.
+ //
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(builtin && builtin->kind() == Builtin::KindByte)
+ {
+ string meta;
+ static const string protobuf = "java:protobuf:";
+ static const string serializable = "java:serializable:";
+ if(seq->findMetaData(serializable, meta))
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeSerializable(" << v << ");";
+ }
+ else
+ {
+ string type = typeToString(seq, TypeModeIn, package);
+ out << nl << v << " = (" << type << ")" << stream << ".readSerializable();";
+ }
+ return;
+ }
+ else if(seq->findMetaData(protobuf, meta))
+ {
+ if(marshal)
+ {
+ out << nl << "if(!" << v << ".isInitialized())";
+ out << sb;
+ out << nl << "throw new Ice.MarshalException(\"type not fully initialized\");";
+ out << eb;
+ out << nl << stream << ".writeByteSeq(" << v << ".toByteArray());";
+ }
+ else
+ {
+ string type = typeToString(seq, TypeModeIn, package);
+ out << nl << "try";
+ out << sb;
+ out << nl << v << " = " << type << ".parseFrom(" << stream << ".readByteSeq());";
+ out << eb;
+ out << nl << "catch(com.google.protobuf.InvalidProtocolBufferException __ex)";
+ out << sb;
+ out << nl << "Ice.MarshalException __mex = new Ice.MarshalException();";
+ out << nl << "__mex.initCause(__ex);";
+ out << nl << "throw __mex;";
+ out << eb;
+ }
+ return;
+ }
+ }
- bool java2 = false;
bool customType = false;
string instanceType;
if(_featureProfile != Slice::IceE)
{
- java2 = seq->definitionContext()->findMetaData(_java2MetaData) == _java2MetaData;
-
//
// We have to determine whether it's possible to use the
// type's generated helper class for this marshal/unmarshal
@@ -1300,7 +1381,7 @@ Slice::JavaGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
while(s)
{
//
- // Stop if the inner sequence type has a custom type.
+ // Stop if the inner sequence type has a custom, serializable or protobuf type.
//
if(hasTypeMetaData(s) && _featureProfile != Slice::IceE)
{
@@ -2496,10 +2577,60 @@ Slice::JavaGenerator::writeStreamSequenceMarshalUnmarshalCode(Output& out,
{
string stream = marshal ? "__outS" : "__inS";
string v = param;
-
bool java2 = seq->definitionContext()->findMetaData(_java2MetaData) == _java2MetaData;
//
+ // If the sequence is a byte sequence, check if there's the serializable or protobuf metadata to
+ // get rid of these two easy cases first.
+ //
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(builtin && builtin->kind() == Builtin::KindByte)
+ {
+ string meta;
+ static const string protobuf = "java:protobuf:";
+ static const string serializable = "java:serializable:";
+ if(seq->findMetaData(serializable, meta))
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeSerializable(" << v << ");";
+ }
+ else
+ {
+ string type = typeToString(seq, TypeModeIn, package);
+ out << nl << v << " = (" << type << ")" << stream << ".readSerializable();";
+ }
+ return;
+ }
+ else if(seq->findMetaData(protobuf, meta))
+ {
+ if(marshal)
+ {
+ out << nl << "if(!" << v << ".isInitialized())";
+ out << sb;
+ out << nl << "throw new Ice.MarshalException(\"type not fully initialized\");";
+ out << eb;
+ out << nl << stream << ".writeByteSeq(" << v << ".toByteArray());";
+ }
+ else
+ {
+ string type = meta.substr(protobuf.size());
+ out << nl << "try";
+ out << sb;
+ out << nl << v << " = " << type << ".parseFrom(" << stream << ".readByteSeq());";
+ out << eb;
+ out << nl << "catch(com.google.protobuf.InvalidProtocolBufferException __ex)";
+ out << sb;
+ out << nl << "Ice.MarshalException __mex = new Ice.MarshalException();";
+ out << nl << "__mex.initCause(__ex);";
+ out << nl << "throw __mex;";
+ out << eb;
+ }
+ return;
+ }
+ }
+
+ //
// We have to determine whether it's possible to use the
// type's generated helper class for this marshal/unmarshal
// task. Since the user may have specified a custom type in
@@ -2548,7 +2679,7 @@ Slice::JavaGenerator::writeStreamSequenceMarshalUnmarshalCode(Output& out,
while(s)
{
//
- // Stop if the inner sequence type has a custom type.
+ // Stop if the inner sequence type has a custom, serializable or protobuf type.
//
if(hasTypeMetaData(s))
{
@@ -3145,6 +3276,18 @@ Slice::JavaGenerator::hasTypeMetaData(const TypePtr& type, const StringList& loc
{
return true;
}
+ else if(str.find("java:protobuf:") == 0 || str.find("java:serializable:") == 0)
+ {
+ SequencePtr seq = SequencePtr::dynamicCast(cont);
+ if(seq)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(builtin && builtin->kind() == Builtin::KindByte)
+ {
+ return true;
+ }
+ }
+ }
}
}
@@ -3533,9 +3676,33 @@ Slice::JavaGenerator::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
void
Slice::JavaGenerator::MetaDataVisitor::visitSequence(const SequencePtr& p)
{
+ static const string protobuf = "java:protobuf:";
+ static const string serializable = "java:serializable:";
StringList metaData = getMetaData(p);
- validateType(p, metaData, p->definitionContext()->filename(), p->line());
- validateGetSet(p, metaData, p->definitionContext()->filename(), p->line());
+ const string file = p->definitionContext()->filename();
+ const string line = p->line();
+ for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); )
+ {
+ string s = *q++;
+ if(s.find(protobuf) == 0 || s.find(serializable) == 0)
+ {
+ //
+ // Remove from list so validateType does not try to handle as well.
+ //
+ metaData.remove(s);
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(!builtin || builtin->kind() != Builtin::KindByte)
+ {
+ _history.insert(s);
+ emitWarning(file, line, "ignoring invalid metadata `" + s + "':\n" +
+ "this metadata can only be used with a byte sequence");
+ }
+ }
+ }
+
+ validateType(p, metaData, file, line);
+ validateGetSet(p, metaData, file, line);
}
void
@@ -3598,6 +3765,16 @@ Slice::JavaGenerator::MetaDataVisitor::getMetaData(const ContainedPtr& cont)
result.push_back(s);
continue;
}
+ else if(s.substr(prefix.size(), pos - prefix.size()) == "serializable")
+ {
+ result.push_back(s);
+ continue;
+ }
+ else if(s.substr(prefix.size(), pos - prefix.size()) == "protobuf")
+ {
+ result.push_back(s);
+ continue;
+ }
emitWarning(file, cont->line(), "ignoring invalid metadata `" + s + "'");
}
@@ -3634,6 +3811,13 @@ Slice::JavaGenerator::MetaDataVisitor::validateType(const SyntaxTreeBasePtr& p,
}
emitWarning(file, line, "invalid metadata for " + str);
}
+ else if(i->find("java:protobuf:") == 0 || i->find("java:serializable:") == 0)
+ {
+ //
+ // Only valid in sequence defintion which is checked in visitSequence
+ //
+ emitWarning(file, line, "ignoring invalid metadata `" + *i + "'");
+ }
}
}
diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp
index c1c91b3f289..7dc251b25df 100644
--- a/cpp/src/Slice/PythonUtil.cpp
+++ b/cpp/src/Slice/PythonUtil.cpp
@@ -1204,17 +1204,46 @@ Slice::Python::CodeVisitor::visitStructStart(const StructPtr& p)
void
Slice::Python::CodeVisitor::visitSequence(const SequencePtr& p)
{
+ static const string protobuf = "python:protobuf:";
+ StringList metaData = p->getMetaData();
+ bool isCustom = false;
+ string customType;
+ for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
+ {
+ if(q->find(protobuf) == 0)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(!builtin || builtin->kind() != Builtin::KindByte)
+ {
+ continue;
+ }
+ isCustom = true;
+ customType = q->substr(protobuf.size());
+ break;
+ }
+ }
+
//
// Emit the type information.
//
string scoped = p->scoped();
_out << sp << nl << "if not " << getDictLookup(p, "_t_") << ':';
_out.inc();
- _out << nl << "_M_" << getAbsolute(p, "_t_") << " = IcePy.defineSequence('" << scoped << "', ";
- writeMetaData(p->getMetaData());
- _out << ", ";
- writeType(p->type());
- _out << ")";
+ if(isCustom)
+ {
+ string package = customType.substr(0, customType.find('.'));
+ _out << nl << "import " << package;
+ _out << nl << "_M_" << getAbsolute(p, "_t_")
+ << " = IcePy.defineCustom('" << scoped << "', " << customType << ")";
+ }
+ else
+ {
+ _out << nl << "_M_" << getAbsolute(p, "_t_") << " = IcePy.defineSequence('" << scoped << "', ";
+ writeMetaData(metaData);
+ _out << ", ";
+ writeType(p->type());
+ _out << ")";
+ }
_out.dec();
}
@@ -2032,7 +2061,30 @@ Slice::Python::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
void
Slice::Python::MetaDataVisitor::visitSequence(const SequencePtr& p)
{
- validateSequence(p->definitionContext(), p->line(), p, p->getMetaData());
+ static const string protobuf = "python:protobuf:";
+ StringList metaData = p->getMetaData();
+ const string file = p->definitionContext()->filename();
+ const string line = p->line();
+ for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); )
+ {
+ string s = *q++;
+ if(s.find(protobuf) == 0)
+ {
+ //
+ // Remove from list so validateSequence does not try to handle as well.
+ //
+ metaData.remove(s);
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(!builtin || builtin->kind() != Builtin::KindByte)
+ {
+ emitWarning(file, line, "ignoring invalid metadata `" + s + ":\n" +
+ "`protobuf' encoding must be a byte sequence");
+ }
+ }
+ }
+
+ validateSequence(p->definitionContext(), line, p, metaData);
}
void
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 3ab5e21fcd4..513b9f684ee 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -1151,14 +1151,20 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
TypePtr type = p->type();
string s = typeToString(type, _useWstring, p->typeMetaData());
StringList metaData = p->getMetaData();
- string seqType = findMetaData(metaData, false);
- if(!seqType.empty())
- {
- H << sp << nl << "typedef " << seqType << ' ' << name << ';';
- }
- else
+
+ bool protobuf;
+ string seqType = findMetaData(p, metaData, false, protobuf);
+ H << sp;
+ if(!protobuf)
{
- H << sp << nl << "typedef ::std::vector<" << (s[0] == ':' ? " " : "") << s << "> " << name << ';';
+ if(!seqType.empty())
+ {
+ H << nl << "typedef " << seqType << ' ' << name << ';';
+ }
+ else
+ {
+ H << nl << "typedef ::std::vector<" << (s[0] == ':' ? " " : "") << s << "> " << name << ';';
+ }
}
BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
@@ -1167,100 +1173,163 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
string scoped = fixKwd(p->scoped());
string scope = fixKwd(p->scope());
- if(!seqType.empty())
+ if(protobuf || !seqType.empty())
{
- H << nl << _dllExport << "void __write" << name << "(::IceInternal::BasicStream*, const " << name << "&);";
- H << nl << _dllExport << "void __read" << name << "(::IceInternal::BasicStream*, " << name << "&);";
+ string typeName = name;
+ string scopedName = scoped;
+ if(protobuf && !seqType.empty())
+ {
+ typeName = seqType;
+ scopedName = seqType;
+ }
+ H << nl << _dllExport << "void __write" << name << "(::IceInternal::BasicStream*, const "
+ << typeName << "&);";
+ H << nl << _dllExport << "void __read" << name << "(::IceInternal::BasicStream*, "
+ << typeName << "&);";
if(_stream)
{
H << nl << _dllExport << "void ice_write" << p->name() << "(const ::Ice::OutputStreamPtr&, const "
- << name << "&);";
- H << nl << _dllExport << "void ice_read" << p->name() << "(const ::Ice::InputStreamPtr&, " << name
+ << typeName << "&);";
+ H << nl << _dllExport << "void ice_read" << p->name() << "(const ::Ice::InputStreamPtr&, " << typeName
<< "&);";
}
C << sp << nl << "void" << nl << scope.substr(2) << "__write" << name <<
- "(::IceInternal::BasicStream* __os, const " << scoped << "& v)";
- C << sb;
- C << nl << "::Ice::Int size = static_cast< ::Ice::Int>(v.size());";
- C << nl << "__os->writeSize(size);";
- C << nl << "for(" << name << "::const_iterator p = v.begin(); p != v.end(); ++p)";
+ "(::IceInternal::BasicStream* __os, const " << scopedName << "& v)";
C << sb;
- writeMarshalUnmarshalCode(C, type, "(*p)", true);
- C << eb;
+ if(protobuf)
+ {
+ C << nl << "std::vector< ::Ice::Byte> data(v.ByteSize());";
+ C << nl << "if(!v.IsInitialized())";
+ C << sb;
+ C << nl << "throw ::Ice::MarshalException(__FILE__, __LINE__, \"type not fully initialized: \" + v.InitializationErrorString());";
+ C << eb;
+ C << nl << "if(!v.SerializeToArray(&data[0], data.size()))";
+ C << sb;
+ C << nl << "throw ::Ice::MarshalException(__FILE__, __LINE__, \"SerializeToArray failed\");";
+ C << eb;
+ C << nl << "__os->write(&data[0], &data[0] + data.size());";
+ }
+ else
+ {
+ C << nl << "::Ice::Int size = static_cast< ::Ice::Int>(v.size());";
+ C << nl << "__os->writeSize(size);";
+ C << nl << "for(" << name << "::const_iterator p = v.begin(); p != v.end(); ++p)";
+ C << sb;
+ writeMarshalUnmarshalCode(C, type, "(*p)", true);
+ C << eb;
+ }
C << eb;
C << sp << nl << "void" << nl << scope.substr(2) << "__read" << name
- << "(::IceInternal::BasicStream* __is, " << scoped << "& v)";
+ << "(::IceInternal::BasicStream* __is, " << scopedName << "& v)";
C << sb;
- C << nl << "::Ice::Int sz;";
- C << nl << "__is->readSize(sz);";
- C << nl << name << "(sz).swap(v);";
- if(type->isVariableLength())
+ if(protobuf)
{
- // Protect against bogus sequence sizes.
- C << nl << "__is->startSeq(sz, " << type->minWireSize() << ");";
+ C << nl << "::std::pair<const ::Ice::Byte*, const ::Ice::Byte*> data;";
+ C << nl << "__is->read(data);";
+ C << nl << "if(!v.ParseFromArray(data.first, data.second - data.first))";
+ C << sb;
+ C << nl << "throw ::Ice::MarshalException(__FILE__, __LINE__, \"ParseFromArray failed\");";
+ C << eb;
}
else
{
- C << nl << "__is->checkFixedSeq(sz, " << type->minWireSize() << ");";
- }
- C << nl << "for(" << name << "::iterator p = v.begin(); p != v.end(); ++p)";
- C << sb;
- writeMarshalUnmarshalCode(C, type, "(*p)", false);
+ C << nl << "::Ice::Int sz;";
+ C << nl << "__is->readSize(sz);";
+ C << nl << name << "(sz).swap(v);";
+ if(type->isVariableLength())
+ {
+ // Protect against bogus sequence sizes.
+ C << nl << "__is->startSeq(sz, " << type->minWireSize() << ");";
+ }
+ else
+ {
+ C << nl << "__is->checkFixedSeq(sz, " << type->minWireSize() << ");";
+ }
+ C << nl << "for(" << name << "::iterator p = v.begin(); p != v.end(); ++p)";
+ C << sb;
+ writeMarshalUnmarshalCode(C, type, "(*p)", false);
- //
- // After unmarshaling each element, check that there are still enough bytes left in the stream
- // to unmarshal the remainder of the sequence, and decrement the count of elements
- // yet to be unmarshaled for sequences with variable-length element type (that is, for sequences
- // of classes, structs, dictionaries, sequences, strings, or proxies). This allows us to
- // abort unmarshaling for bogus sequence sizes at the earliest possible moment.
- // (For fixed-length sequences, we don't need to do this because the prediction of how many
- // bytes will be taken up by the sequence is accurate.)
- //
- if(type->isVariableLength())
- {
- if(!SequencePtr::dynamicCast(type))
+ //
+ // After unmarshaling each element, check that there are still enough bytes left in the stream
+ // to unmarshal the remainder of the sequence, and decrement the count of elements
+ // yet to be unmarshaled for sequences with variable-length element type (that is, for sequences
+ // of classes, structs, dictionaries, sequences, strings, or proxies). This allows us to
+ // abort unmarshaling for bogus sequence sizes at the earliest possible moment.
+ // (For fixed-length sequences, we don't need to do this because the prediction of how many
+ // bytes will be taken up by the sequence is accurate.)
+ //
+ if(type->isVariableLength())
{
- //
- // No need to check for directly nested sequences because, at the start of each
- // sequence, we check anyway.
- //
- C << nl << "__is->checkSeq();";
+ if(!SequencePtr::dynamicCast(type))
+ {
+ //
+ // No need to check for directly nested sequences because, at the start of each
+ // sequence, we check anyway.
+ //
+ C << nl << "__is->checkSeq();";
+ }
+ C << nl << "__is->endElement();";
+ }
+ C << eb;
+ if(type->isVariableLength())
+ {
+ C << nl << "__is->endSeq(sz);";
}
- C << nl << "__is->endElement();";
- }
- C << eb;
- if(type->isVariableLength())
- {
- C << nl << "__is->endSeq(sz);";
}
C << eb;
if(_stream)
{
C << sp << nl << "void" << nl << scope.substr(2) << "ice_write" << p->name()
- << "(const ::Ice::OutputStreamPtr& __outS, const " << scoped << "& v)";
- C << sb;
- C << nl << "__outS->writeSize(::Ice::Int(v.size()));";
- C << nl << scoped << "::const_iterator p;";
- C << nl << "for(p = v.begin(); p != v.end(); ++p)";
+ << "(const ::Ice::OutputStreamPtr& __outS, const " << scopedName << "& v)";
C << sb;
- writeStreamMarshalUnmarshalCode(C, type, "(*p)", true, "", _useWstring);
- C << eb;
+ if(protobuf)
+ {
+ C << nl << "std::vector< ::Ice::Byte> data(v.ByteSize());";
+ C << nl << "if(!v.IsInitialized())";
+ C << sb;
+ C << nl << "throw ::Ice::MarshalException(__FILE__, __LINE__, \"type not fully initialized: \" + v.InitializationErrorString());";
+ C << eb;
+ C << nl << "v.SerializeToArray(&data[0], data.size());";
+
+ C << nl << "__outS->writeByteSeq(data);";
+ }
+ else
+ {
+ C << nl << "__outS->writeSize(::Ice::Int(v.size()));";
+ C << nl << scopedName << "::const_iterator p;";
+ C << nl << "for(p = v.begin(); p != v.end(); ++p)";
+ C << sb;
+ writeStreamMarshalUnmarshalCode(C, type, "(*p)", true, "", _useWstring);
+ C << eb;
+ }
C << eb;
C << sp << nl << "void" << nl << scope.substr(2) << "ice_read" << p->name()
- << "(const ::Ice::InputStreamPtr& __inS, " << scoped << "& v)";
- C << sb;
- C << nl << "::Ice::Int sz = __inS->readSize();";
- C << nl << scoped << "(sz).swap(v);";
- C << nl << scoped << "::iterator p;";
- C << nl << "for(p = v.begin(); p != v.end(); ++p)";
+ << "(const ::Ice::InputStreamPtr& __inS, " << scopedName << "& v)";
C << sb;
- writeStreamMarshalUnmarshalCode(C, type, "(*p)", false, "", _useWstring);
- C << eb;
+ if(protobuf)
+ {
+ C << nl << "std::pair<const ::Ice::Byte*, const ::Ice::Byte*> data;";
+ C << nl << "__inS->readByteSeq(data);";
+ C << nl << "if(!v.ParseFromArray(data.first, data.second - data.first))";
+ C << sb;
+ C << nl << "throw ::Ice::MarshalException(__FILE__, __LINE__, \"ParseFromArray failed\");";
+ C << eb;
+ }
+ else
+ {
+ C << nl << "::Ice::Int sz = __inS->readSize();";
+ C << nl << scopedName << "(sz).swap(v);";
+ C << nl << scopedName << "::iterator p;";
+ C << nl << "for(p = v.begin(); p != v.end(); ++p)";
+ C << sb;
+ writeStreamMarshalUnmarshalCode(C, type, "(*p)", false, "", _useWstring);
+ C << eb;
+ }
C << eb;
}
}
@@ -5749,6 +5818,7 @@ Slice::Gen::MetaDataVisitor::visitStructEnd(const StructPtr&)
void
Slice::Gen::MetaDataVisitor::visitOperation(const OperationPtr& p)
{
+
bool ami = false;
ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
if(cl->hasMetaData("ami") || p->hasMetaData("ami") || cl->hasMetaData("amd") || p->hasMetaData("amd"))
@@ -5814,7 +5884,31 @@ Slice::Gen::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
void
Slice::Gen::MetaDataVisitor::visitSequence(const SequencePtr& p)
{
- validate(p, p->getMetaData(), p->definitionContext()->filename(), p->line());
+ StringList metaData = p->getMetaData();
+ const string file = p->definitionContext()->filename();
+ const string line = p->line();
+ static const string prefix = "cpp:protobuf";
+ for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); )
+ {
+ string s = *q++;
+ if(s.find(prefix) == 0)
+ {
+ //
+ // Remove from list so validate does not try to handle as well.
+ //
+ metaData.remove(s);
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(!builtin || builtin->kind() != Builtin::KindByte)
+ {
+ _history.insert(s);
+ emitWarning(file, line, "ignoring invalid metadata `" + s + "':\n"+
+ "`protobuf' encoding must be a byte sequence.");
+ }
+ }
+ }
+
+ validate(p, metaData, file, line);
}
void
@@ -5871,7 +5965,6 @@ Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const Strin
{
continue;
}
-
emitWarning(file, line, "ignoring invalid metadata `" + s + "'");
}
_history.insert(s);
diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp
index 9a2a4ae2f08..a2420094869 100644
--- a/cpp/src/slice2cs/Gen.cpp
+++ b/cpp/src/slice2cs/Gen.cpp
@@ -1666,6 +1666,15 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
return;
}
+ //
+ // No need to generate anything for serializable sequences.
+ //
+ prefix = "clr:serializable:";
+ if(p->findMetaData(prefix, meta))
+ {
+ return;
+ }
+
string name = fixId(p->name());
string s = typeToString(p->type());
@@ -2732,9 +2741,10 @@ Slice::Gen::TypesVisitor::writeMemberHashCode(const DataMemberList& dataMembers,
SequencePtr seq = SequencePtr::dynamicCast(memberType);
if(seq)
{
- string genericType;
- bool isGeneric = seq->findMetaData("clr:generic:", genericType);
- bool isArray = !isGeneric && !seq->hasMetaData("clr:collection");
+ string meta;
+ bool isSerializable = seq->findMetaData("clr:serializable", meta);
+ bool isGeneric = seq->findMetaData("clr:generic:", meta);
+ bool isArray = !isSerializable && !isGeneric && !seq->hasMetaData("clr:collection");
if(isArray)
{
//
@@ -2811,9 +2821,10 @@ Slice::Gen::TypesVisitor::writeMemberEquals(const DataMemberList& dataMembers, i
SequencePtr seq = SequencePtr::dynamicCast(memberType);
if(seq)
{
- string genericType;
- bool isGeneric = seq->findMetaData("clr:generic:", genericType);
- bool isArray = !isGeneric && !seq->hasMetaData("clr:collection");
+ string meta;
+ bool isSerializable = seq->findMetaData("clr:serializable:", meta);
+ bool isGeneric = seq->findMetaData("clr:generic:", meta);
+ bool isArray = !isSerializable && !isGeneric && !seq->hasMetaData("clr:collection");
if(isArray)
{
//
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index 9142e4b6e05..4289a6ae5a9 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -3185,6 +3185,23 @@ Slice::Gen::HolderVisitor::visitStructStart(const StructPtr& p)
void
Slice::Gen::HolderVisitor::visitSequence(const SequencePtr& p)
{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(builtin && builtin->kind() == Builtin::KindByte)
+ {
+ string prefix = "java:serializable:";
+ string meta;
+ if(p->findMetaData(prefix, meta))
+ {
+ return; // No holders for serializable types.
+ }
+ prefix = "java:protobuf:";
+ if(p->findMetaData(prefix, meta))
+ {
+ return; // No holders for protobuf types.
+
+ }
+ }
+
writeHolder(p);
}
diff --git a/cpp/test/Ice/protobuf/.depend b/cpp/test/Ice/protobuf/.depend
new file mode 100644
index 00000000000..9483597c566
--- /dev/null
+++ b/cpp/test/Ice/protobuf/.depend
@@ -0,0 +1,8 @@
+Test$(OBJEXT): Test.cpp ./Test.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/LoggerF.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Direct.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/ObjectFactory.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/ScopedArray.h
+Client$(OBJEXT): Client.cpp $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Functional.h $(includedir)/IceUtil/Functional.h $(includedir)/Ice/Stream.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h ../../include/TestCommon.h ./Test.h
+AllTests$(OBJEXT): AllTests.cpp $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Functional.h $(includedir)/IceUtil/Functional.h $(includedir)/Ice/Stream.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h ../../include/TestCommon.h ./Test.h
+Test$(OBJEXT): Test.cpp ./Test.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/LoggerF.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Direct.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/ObjectFactory.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/ScopedArray.h
+TestI$(OBJEXT): TestI.cpp ./TestI.h ./Test.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/LoggerF.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Direct.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Functional.h $(includedir)/IceUtil/Functional.h $(includedir)/Ice/Stream.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h
+Server$(OBJEXT): Server.cpp $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Functional.h $(includedir)/IceUtil/Functional.h $(includedir)/Ice/Stream.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/FactoryTableDef.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/Ice/UserExceptionFactoryF.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h ./TestI.h ./Test.h
+Test.cpp: Test.ice
+Test.ice: $(SLICE2CPP) $(SLICEPARSERLIB)
diff --git a/cpp/test/Ice/protobuf/.gitignore b/cpp/test/Ice/protobuf/.gitignore
new file mode 100644
index 00000000000..0a8a5d76820
--- /dev/null
+++ b/cpp/test/Ice/protobuf/.gitignore
@@ -0,0 +1,10 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+Test.cpp
+Test.h
+Test.pb.cpp
+Test.pb.h
+
diff --git a/cpp/test/Ice/protobuf/AllTests.cpp b/cpp/test/Ice/protobuf/AllTests.cpp
new file mode 100644
index 00000000000..b17f2d13405
--- /dev/null
+++ b/cpp/test/Ice/protobuf/AllTests.cpp
@@ -0,0 +1,148 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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>
+#include <Test.pb.h>
+
+using namespace std;
+using namespace Test;
+
+class CallbackBase : public IceUtil::Monitor<IceUtil::Mutex>
+{
+public:
+
+ CallbackBase() :
+ _called(false)
+ {
+ }
+
+ virtual ~CallbackBase()
+ {
+ }
+
+ bool check()
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ while(!_called)
+ {
+ if(!timedWait(IceUtil::Time::seconds(5)))
+ {
+ return false;
+ }
+ }
+ _called = false;
+ return true;
+ }
+
+protected:
+
+ void called()
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ assert(!_called);
+ _called = true;
+ notify();
+ }
+
+private:
+
+ bool _called;
+};
+
+class AMI_MyClass_opMessageI : public Test::AMI_MyClass_opMessage, public CallbackBase
+{
+public:
+
+ virtual void ice_response(const test::Message& r, const test::Message& o)
+ {
+ test(o.i() == 99);
+ test(r.i() == 99);
+ called();
+ }
+
+ virtual void ice_exception(const ::Ice::Exception&)
+ {
+ test(false);
+ }
+};
+typedef IceUtil::Handle<AMI_MyClass_opMessageI> AMI_MyClass_opMessageIPtr;
+
+class AMI_MyClass_opMessageAMDI : public Test::AMI_MyClass_opMessageAMD, public CallbackBase
+{
+public:
+
+ virtual void ice_response(const test::Message& r, const test::Message& o)
+ {
+ test(o.i() == 99);
+ test(r.i() == 99);
+ called();
+ }
+
+ virtual void ice_exception(const ::Ice::Exception&)
+ {
+ test(false);
+ }
+};
+typedef IceUtil::Handle<AMI_MyClass_opMessageAMDI> AMI_MyClass_opMessageAMDIPtr;
+
+
+MyClassPrx
+allTests(const Ice::CommunicatorPtr& communicator)
+{
+ string ref = "test:default -p 12010 -t 10000";
+ Ice::ObjectPrx baseProxy = communicator->stringToProxy(ref);
+ MyClassPrx cl = MyClassPrx::checkedCast(baseProxy);
+ test(cl);
+
+ cout << "testing twoway operations... " << flush;
+ {
+ test::Message i;
+ i.set_i(99);
+ test::Message o;
+
+ test::Message r = cl->opMessage(i, o);
+
+ test(o.i() == 99);
+ test(r.i() == 99);
+ }
+ {
+ test::Message i;
+ i.set_i(99);
+ test::Message o;
+
+ test::Message r = cl->opMessageAMD(i, o);
+
+ test(o.i() == 99);
+ test(r.i() == 99);
+ }
+ cout << "ok" << endl;
+
+ cout << "testing twoway AMI operations... " << flush;
+ {
+ test::Message i;
+ i.set_i(99);
+
+ AMI_MyClass_opMessageIPtr cb = new AMI_MyClass_opMessageI();
+ cl->opMessage_async(cb, i);
+ test(cb->check());
+ }
+ {
+ test::Message i;
+ i.set_i(99);
+
+ AMI_MyClass_opMessageAMDIPtr cb = new AMI_MyClass_opMessageAMDI();
+ cl->opMessageAMD_async(cb, i);
+ test(cb->check());
+ }
+ cout << "ok" << endl;
+
+ return cl;
+}
diff --git a/cpp/test/Ice/protobuf/Client.cpp b/cpp/test/Ice/protobuf/Client.cpp
new file mode 100644
index 00000000000..b704aa5da04
--- /dev/null
+++ b/cpp/test/Ice/protobuf/Client.cpp
@@ -0,0 +1,70 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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>
+
+using namespace std;
+using namespace Test;
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ MyClassPrx allTests(const Ice::CommunicatorPtr&);
+ MyClassPrx myClass = allTests(communicator);
+ myClass->shutdown();
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ Ice::CommunicatorPtr communicator;
+
+ try
+ {
+ Ice::InitializationData initData;
+ initData.properties = Ice::createProperties(argc, argv);
+
+ //
+ // For this test, we want to disable retries.
+ //
+ initData.properties->setProperty("Ice.RetryIntervals", "-1");
+
+ //
+ // This test kills connections, so we don't want warnings.
+ //
+ initData.properties->setProperty("Ice.Warn.Connections", "0");
+
+ 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/protobuf/Makefile b/cpp/test/Ice/protobuf/Makefile
new file mode 100644
index 00000000000..d1df993bf18
--- /dev/null
+++ b/cpp/test/Ice/protobuf/Makefile
@@ -0,0 +1,67 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2008 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.
+#
+# **********************************************************************
+
+#
+# If protobuf is not installed in a standard location where the
+# compiler can find it, set PROTOBUF_HOME to the protobuf installation
+# directory.
+#
+PROTOBUF_HOME ?= /usr/local
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+COBJS = Test.o \
+ Client.o \
+ AllTests.o \
+ Test.pb.o
+
+SOBJS = Test.o \
+ TestI.o \
+ Server.o \
+ Test.pb.o
+
+SRCS = $(COBJS:.o=.cpp) \
+ $(SOBJS:.o=.cpp)
+
+SLICE_SRCS = Test.ice
+PROTO_SRCS = Test.proto
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../../include -I$(PROTOBUF_HOME)/include $(CPPFLAGS)
+LIBS := $(LIBS) -L$(PROTOBUF_HOME)/lib -lprotobuf
+
+$(CLIENT): $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(COBJS) $(LIBS)
+
+$(SERVER): $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(SOBJS) $(LIBS)
+
+%..pb.h %.pb.cpp: %.proto
+ rm -f $(*F).pb.h $(*F).pb.cpp
+ $(PROTOBUF_HOME)/bin/protoc --cpp_out=. $(*F).proto
+ mv $(*F).pb.cc $(*F).pb.cpp
+
+depend::
+ for i in $(PROTO_SRCS); do \
+ echo "$${i%.proto}.pb.cpp: $$i" >> .depend; \
+ done
+
+clean::
+ rm -f $(addsuffix .pb.cpp, $(basename $(notdir $(PROTO_SRCS))))
+ rm -f $(addsuffix .pb.h, $(basename $(notdir $(PROTO_SRCS))))
+
+include .depend
diff --git a/cpp/test/Ice/protobuf/Makefile.mak b/cpp/test/Ice/protobuf/Makefile.mak
new file mode 100644
index 00000000000..0948f926785
--- /dev/null
+++ b/cpp/test/Ice/protobuf/Makefile.mak
@@ -0,0 +1,74 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2008 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.
+#
+# **********************************************************************
+
+#
+# If protobuf is not installed in a standard location where the
+# compiler can find it, set PROTOBUF_HOME to the protobuf installation
+# directory.
+#
+!if "$(PROTOBUF_HOME)" == ""
+PROTOBUF_HOME = c:\protobuf
+!endif
+
+top_srcdir = ..\..\..
+
+CLIENT = client.exe
+SERVER = server.exe
+
+TARGETS = $(CLIENT) $(SERVER)
+
+COBJS = Test.obj \
+ Client.obj \
+ AllTests.obj \
+ Test.pb.obj
+
+SOBJS = Test.obj \
+ TestI.obj \
+ Server.obj \
+ Test.pb.obj
+
+SRCS = $(COBJS:.obj=.cpp) \
+ $(SOBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+# Need to use -W0 to gid rid of ugly warnings from generated protobuf file as
+# well as prevent compile failure on x64 due to warnings from protobuf headers
+CPPFLAGS = -I$(PROTOBUF_HOME)\include -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN -W0
+LIBS = $(LIBS) /libpath:$(PROTOBUF_HOME)\lib libprotobuf.lib
+
+!if "$(GENERATE_PDB)" == "yes"
+CPDBFLAGS = /pdb:$(CLIENT:.exe=.pdb)
+SPDBFLAGS = /pdb:$(SERVER:.exe=.pdb)
+!endif
+
+$(CLIENT): $(COBJS)
+ $(LINK) $(LD_EXEFLAGS) $(CPDBFLAGS) $(SETARGV) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+$(SERVER): $(SOBJS)
+ $(LINK) $(LD_EXEFLAGS) $(SPDBFLAGS) $(SETARGV) $(SOBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+# A generic rule would be nicer, but since protoc generates .pb.cpp
+# it is not possible with nmake.
+Test.pb.cpp: Test.proto
+ del /q Test.pb.h Test.pb.cpp
+ $(PROTOBUF_HOME)\bin\protoc --cpp_out=. Test.proto
+ move Test.pb.cc Test.pb.cpp
+
+Test.pb.h: Test.pb.cpp
+
+clean::
+ del /q Test.pb.h Test.pb.cpp
+ del /q Test.cpp Test.h
+
+!include .depend
diff --git a/cpp/test/Ice/protobuf/Server.cpp b/cpp/test/Ice/protobuf/Server.cpp
new file mode 100644
index 00000000000..a62c326f266
--- /dev/null
+++ b/cpp/test/Ice/protobuf/Server.cpp
@@ -0,0 +1,66 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 <TestI.h>
+
+using namespace std;
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ communicator->getProperties()->setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000:udp");
+ Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("TestAdapter");
+ Ice::ObjectPtr object = new MyClassI;
+ adapter->add(object, communicator->stringToIdentity("test"));
+ adapter->activate();
+ 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);
+
+ //
+ // This test kills connections, so we don't want warnings.
+ //
+ initData.properties->setProperty("Ice.Warn.Connections", "0");
+
+ 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/protobuf/Test.ice b/cpp/test/Ice/protobuf/Test.ice
new file mode 100644
index 00000000000..58190d47ade
--- /dev/null
+++ b/cpp/test/Ice/protobuf/Test.ice
@@ -0,0 +1,61 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 TEST_ICE
+#define TEST_ICE
+
+[["cpp:include:Test.pb.h"]]
+
+module Test
+{
+
+["cpp:protobuf:test::Message"] sequence<byte> Message;
+
+["ami"] class MyClass
+{
+ void shutdown();
+
+ Message opMessage(Message i, out Message o);
+
+ ["amd"] Message opMessageAMD(Message i, out Message o);
+};
+
+// Remaining type definitions are there to verify that the generated
+// code compiles correctly.
+
+sequence<Message> SLS;
+sequence<SLS> SLSS;
+dictionary<int, Message> SLD;
+dictionary<int, SLS> SLSD;
+
+//
+// The following doesn't compile since the generated protobuf type
+// doesn't define operator== or operator<
+//
+// struct Foo
+// {
+// Message SLmem;
+// SLS SLSmem;
+// };
+
+exception Bar
+{
+ Message SLmem;
+ SLS SLSmem;
+};
+
+class Baz
+{
+ Message SLmem;
+ SLS SLSmem;
+};
+
+};
+
+#endif
diff --git a/cpp/test/Ice/protobuf/Test.proto b/cpp/test/Ice/protobuf/Test.proto
new file mode 100644
index 00000000000..fea4c801ddd
--- /dev/null
+++ b/cpp/test/Ice/protobuf/Test.proto
@@ -0,0 +1,16 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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.
+//
+// **********************************************************************
+
+package test;
+
+option java_outer_classname = "TestPB";
+
+message Message {
+ required int32 i = 1;
+}
diff --git a/cpp/test/Ice/protobuf/TestI.cpp b/cpp/test/Ice/protobuf/TestI.cpp
new file mode 100644
index 00000000000..668e2f761b5
--- /dev/null
+++ b/cpp/test/Ice/protobuf/TestI.cpp
@@ -0,0 +1,33 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 <TestI.h>
+#include <Ice/Ice.h>
+
+using namespace std;
+using namespace Ice;
+
+test::Message
+MyClassI::opMessage(const test::Message& i, test::Message& o, const Ice::Current&)
+{
+ o = i;
+ return i;
+}
+
+void
+MyClassI::opMessageAMD_async(const Test::AMD_MyClass_opMessageAMDPtr& cb, const test::Message& i, const Ice::Current&)
+{
+ cb->ice_response(i, i);
+}
+
+void
+MyClassI::shutdown(const Ice::Current& current)
+{
+ current.adapter->getCommunicator()->shutdown();
+}
diff --git a/cpp/test/Ice/protobuf/TestI.h b/cpp/test/Ice/protobuf/TestI.h
new file mode 100644
index 00000000000..19a42d95129
--- /dev/null
+++ b/cpp/test/Ice/protobuf/TestI.h
@@ -0,0 +1,26 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2008 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 TEST_I_H
+#define TEST_I_H
+
+#include <Test.h>
+
+class MyClassI : virtual public Test::MyClass
+{
+public:
+
+ virtual void shutdown(const Ice::Current&);
+
+ virtual test::Message opMessage(const test::Message&, test::Message&, const Ice::Current&);
+ virtual void opMessageAMD_async(const Test::AMD_MyClass_opMessageAMDPtr&, const test::Message&,
+ const Ice::Current&);
+};
+
+#endif
diff --git a/cpp/test/Ice/protobuf/run.py b/cpp/test/Ice/protobuf/run.py
new file mode 100755
index 00000000000..70bca77e564
--- /dev/null
+++ b/cpp/test/Ice/protobuf/run.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2008 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.
+#
+# **********************************************************************
+
+import os, sys
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+TestUtil.clientServerTest()
+