diff options
author | Benoit Foucher <benoit@zeroc.com> | 2009-02-09 19:20:38 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2009-02-09 19:20:38 +0100 |
commit | 124b43c7bd718655556bd3cba2a554293bf63d16 (patch) | |
tree | 5c3138e3c96e9f3a4763e1b6eea92018d892b241 /cpp | |
parent | Bug 3519 - fix use of tolower in slice2freeze (diff) | |
download | ice-124b43c7bd718655556bd3cba2a554293bf63d16.tar.bz2 ice-124b43c7bd718655556bd3cba2a554293bf63d16.tar.xz ice-124b43c7bd718655556bd3cba2a554293bf63d16.zip |
Support for serializable and protobuf metadata (from cs_serial branch)
Diffstat (limited to 'cpp')
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() + |