summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile13
-rw-r--r--cpp/config/Make.rules6
-rw-r--r--cpp/include/Slice/ObjCUtil.h125
-rw-r--r--cpp/include/Slice/Preprocessor.h2
-rw-r--r--cpp/src/Ice/Makefile2
-rw-r--r--cpp/src/Makefile14
-rw-r--r--cpp/src/Slice/Makefile1
-rw-r--r--cpp/src/Slice/ObjCUtil.cpp1204
-rw-r--r--cpp/src/Slice/Preprocessor.cpp10
-rw-r--r--cpp/src/slice2objc/Gen.cpp3139
-rw-r--r--cpp/src/slice2objc/Gen.h186
-rw-r--r--cpp/src/slice2objc/Main.cpp290
-rw-r--r--cpp/src/slice2objc/Makefile31
-rw-r--r--demoscript/Util.py4
-rw-r--r--man/man1/slice2objc.1127
-rw-r--r--objc/Makefile53
-rwxr-xr-xobjc/allDemos.py33
-rwxr-xr-xobjc/allTests.py59
-rw-r--r--objc/config/Make.rules194
-rw-r--r--objc/config/Make.rules.Darwin101
-rwxr-xr-xobjc/config/makegitignore.py159
-rw-r--r--objc/demo/Database/Makefile21
-rw-r--r--objc/demo/Database/README5
-rw-r--r--objc/demo/Database/library/.gitignore14
-rw-r--r--objc/demo/Database/library/Client.m57
-rw-r--r--objc/demo/Database/library/Glacier2Session.ice47
-rw-r--r--objc/demo/Database/library/Grammar.y131
-rw-r--r--objc/demo/Database/library/Library.ice285
-rw-r--r--objc/demo/Database/library/Makefile47
-rw-r--r--objc/demo/Database/library/Parser.h80
-rw-r--r--objc/demo/Database/library/Parser.m486
-rw-r--r--objc/demo/Database/library/README14
-rw-r--r--objc/demo/Database/library/RunParser.m215
-rw-r--r--objc/demo/Database/library/Scanner.l257
-rw-r--r--objc/demo/Database/library/Session.ice79
-rw-r--r--objc/demo/Database/library/config.client68
-rw-r--r--objc/demo/Ice/Makefile21
-rw-r--r--objc/demo/Ice/README20
-rw-r--r--objc/demo/Ice/hello/.gitignore8
-rw-r--r--objc/demo/Ice/hello/Client.m246
-rw-r--r--objc/demo/Ice/hello/Hello.ice21
-rw-r--r--objc/demo/Ice/hello/HelloI.h14
-rw-r--r--objc/demo/Ice/hello/HelloI.m44
-rw-r--r--objc/demo/Ice/hello/Makefile36
-rw-r--r--objc/demo/Ice/hello/README43
-rw-r--r--objc/demo/Ice/hello/Server.m65
-rw-r--r--objc/demo/Ice/hello/config.client65
-rw-r--r--objc/demo/Ice/hello/config.server74
-rwxr-xr-xobjc/demo/Ice/hello/expect.py30
-rw-r--r--objc/demo/Ice/helloRouter/.gitignore9
-rw-r--r--objc/demo/Ice/helloRouter/Client.m133
-rw-r--r--objc/demo/Ice/helloRouter/Hello.ice21
-rw-r--r--objc/demo/Ice/helloRouter/Makefile29
-rw-r--r--objc/demo/Ice/helloRouter/README12
-rw-r--r--objc/demo/Ice/helloRouter/Router.ice70
-rw-r--r--objc/demo/Ice/helloRouter/config.client57
-rw-r--r--objc/demo/Ice/minimal/.gitignore8
-rw-r--r--objc/demo/Ice/minimal/Client.m59
-rw-r--r--objc/demo/Ice/minimal/Hello.ice20
-rw-r--r--objc/demo/Ice/minimal/HelloI.h14
-rw-r--r--objc/demo/Ice/minimal/HelloI.m29
-rw-r--r--objc/demo/Ice/minimal/Makefile36
-rw-r--r--objc/demo/Ice/minimal/README14
-rw-r--r--objc/demo/Ice/minimal/Server.m55
-rwxr-xr-xobjc/demo/Ice/minimal/expect.py35
-rw-r--r--objc/demo/Ice/optional/.gitignore8
-rw-r--r--objc/demo/Ice/optional/Client.m246
-rw-r--r--objc/demo/Ice/optional/Contact.ice43
-rw-r--r--objc/demo/Ice/optional/ContactDBI.h20
-rw-r--r--objc/demo/Ice/optional/ContactDBI.m114
-rw-r--r--objc/demo/Ice/optional/Makefile36
-rw-r--r--objc/demo/Ice/optional/README10
-rw-r--r--objc/demo/Ice/optional/Server.m65
-rw-r--r--objc/demo/Ice/optional/config.client10
-rw-r--r--objc/demo/Ice/optional/config.server11
-rwxr-xr-xobjc/demo/Ice/optional/expect.py29
-rw-r--r--objc/demo/Makefile21
-rw-r--r--objc/demo/Manual/Makefile21
-rw-r--r--objc/demo/Manual/README11
-rw-r--r--objc/demo/Manual/printer/.gitignore8
-rw-r--r--objc/demo/Manual/printer/Client.m49
-rw-r--r--objc/demo/Manual/printer/Makefile35
-rw-r--r--objc/demo/Manual/printer/Printer.ice20
-rw-r--r--objc/demo/Manual/printer/README8
-rw-r--r--objc/demo/Manual/printer/Server.m68
-rwxr-xr-xobjc/demo/Manual/printer/expect.py35
-rw-r--r--objc/demo/Manual/simple_filesystem/.gitignore8
-rw-r--r--objc/demo/Manual/simple_filesystem/Client.m99
-rw-r--r--objc/demo/Manual/simple_filesystem/DirectoryI.h28
-rw-r--r--objc/demo/Manual/simple_filesystem/DirectoryI.m68
-rw-r--r--objc/demo/Manual/simple_filesystem/FileI.h31
-rw-r--r--objc/demo/Manual/simple_filesystem/FileI.m68
-rw-r--r--objc/demo/Manual/simple_filesystem/Filesystem.ice32
-rw-r--r--objc/demo/Manual/simple_filesystem/Makefile37
-rw-r--r--objc/demo/Manual/simple_filesystem/README10
-rw-r--r--objc/demo/Manual/simple_filesystem/Server.m86
-rwxr-xr-xobjc/demo/Manual/simple_filesystem/expect.py36
-rw-r--r--objc/demo/README10
-rw-r--r--objc/include/Makefile21
-rw-r--r--objc/include/objc/Glacier2.h10
-rw-r--r--objc/include/objc/Glacier2/.gitignore10
-rw-r--r--objc/include/objc/Glacier2/Glacier2.h14
-rw-r--r--objc/include/objc/Glacier2/Makefile26
-rw-r--r--objc/include/objc/Ice.h10
-rw-r--r--objc/include/objc/Ice/.gitignore17
-rw-r--r--objc/include/objc/Ice/Communicator.h63
-rw-r--r--objc/include/objc/Ice/Config.h41
-rw-r--r--objc/include/objc/Ice/Connection.h89
-rw-r--r--objc/include/objc/Ice/Current.h85
-rw-r--r--objc/include/objc/Ice/DispatchInterceptor.h27
-rw-r--r--objc/include/objc/Ice/Endpoint.h90
-rw-r--r--objc/include/objc/Ice/Exception.h46
-rw-r--r--objc/include/objc/Ice/Format.h15
-rw-r--r--objc/include/objc/Ice/Ice.h30
-rw-r--r--objc/include/objc/Ice/ImplicitContext.h20
-rw-r--r--objc/include/objc/Ice/Initialize.h80
-rw-r--r--objc/include/objc/Ice/Logger.h18
-rw-r--r--objc/include/objc/Ice/Makefile26
-rw-r--r--objc/include/objc/Ice/Object.h78
-rw-r--r--objc/include/objc/Ice/ObjectAdapter.h53
-rw-r--r--objc/include/objc/Ice/ObjectFactory.h16
-rw-r--r--objc/include/objc/Ice/Properties.h44
-rw-r--r--objc/include/objc/Ice/Proxy.h182
-rw-r--r--objc/include/objc/Ice/SlicedData.h25
-rw-r--r--objc/include/objc/Ice/Stream.h369
-rw-r--r--objc/include/objc/IceGrid.h10
-rw-r--r--objc/include/objc/IceGrid/.gitignore15
-rw-r--r--objc/include/objc/IceGrid/IceGrid.h19
-rw-r--r--objc/include/objc/IceGrid/Makefile26
-rw-r--r--objc/include/objc/IceStorm.h10
-rw-r--r--objc/include/objc/IceStorm/.gitignore5
-rw-r--r--objc/include/objc/IceStorm/Makefile26
-rw-r--r--objc/include/objc/Makefile21
-rw-r--r--objc/lib/.gitignore1
-rw-r--r--objc/src/Glacier2/.gitignore18
-rw-r--r--objc/src/Glacier2/Makefile50
-rw-r--r--objc/src/Ice/.gitignore33
-rw-r--r--objc/src/Ice/Communicator.mm608
-rw-r--r--objc/src/Ice/CommunicatorI.h28
-rw-r--r--objc/src/Ice/Connection.mm424
-rw-r--r--objc/src/Ice/ConnectionI.h39
-rw-r--r--objc/src/Ice/Current.mm287
-rw-r--r--objc/src/Ice/CurrentI.h16
-rw-r--r--objc/src/Ice/DispatchInterceptor.m60
-rw-r--r--objc/src/Ice/Dispatcher.mm96
-rw-r--r--objc/src/Ice/DispatcherI.h27
-rw-r--r--objc/src/Ice/Endpoint.mm321
-rw-r--r--objc/src/Ice/EndpointI.h45
-rw-r--r--objc/src/Ice/Exception.mm919
-rw-r--r--objc/src/Ice/ExceptionI.h18
-rw-r--r--objc/src/Ice/IdentityI.h18
-rw-r--r--objc/src/Ice/IdentityI.mm40
-rw-r--r--objc/src/Ice/ImplicitContext.mm83
-rw-r--r--objc/src/Ice/ImplicitContextI.h22
-rw-r--r--objc/src/Ice/Initialize.mm623
-rw-r--r--objc/src/Ice/InitializeI.h16
-rw-r--r--objc/src/Ice/Logger.mm194
-rw-r--r--objc/src/Ice/LoggerI.h21
-rw-r--r--objc/src/Ice/Makefile140
-rw-r--r--objc/src/Ice/Object.mm567
-rw-r--r--objc/src/Ice/ObjectAdapter.mm565
-rw-r--r--objc/src/Ice/ObjectAdapterI.h21
-rw-r--r--objc/src/Ice/ObjectI.h37
-rw-r--r--objc/src/Ice/Properties.mm304
-rw-r--r--objc/src/Ice/PropertiesI.h30
-rw-r--r--objc/src/Ice/Proxy.mm1721
-rw-r--r--objc/src/Ice/ProxyI.h32
-rw-r--r--objc/src/Ice/Request.h23
-rw-r--r--objc/src/Ice/Request.m59
-rw-r--r--objc/src/Ice/SlicedData.mm89
-rw-r--r--objc/src/Ice/SlicedDataI.h21
-rw-r--r--objc/src/Ice/Stream.mm3440
-rw-r--r--objc/src/Ice/StreamI.h29
-rw-r--r--objc/src/Ice/Util.h242
-rw-r--r--objc/src/Ice/Util.mm477
-rw-r--r--objc/src/Ice/VersionI.h27
-rw-r--r--objc/src/Ice/VersionI.mm127
-rw-r--r--objc/src/Ice/Wrapper.h32
-rw-r--r--objc/src/Ice/Wrapper.mm258
-rw-r--r--objc/src/IceGrid/.gitignore28
-rw-r--r--objc/src/IceGrid/Makefile56
-rw-r--r--objc/src/IceStorm/.gitignore8
-rw-r--r--objc/src/IceStorm/Makefile45
-rw-r--r--objc/src/Makefile40
-rw-r--r--objc/test/Common/.gitignore4
-rw-r--r--objc/test/Common/Makefile50
-rw-r--r--objc/test/Common/TestCommon.m251
-rw-r--r--objc/test/Ice/Makefile47
-rw-r--r--objc/test/Ice/adapterDeactivation/.gitignore8
-rw-r--r--objc/test/Ice/adapterDeactivation/AdapterDeactivationTest.ice23
-rw-r--r--objc/test/Ice/adapterDeactivation/AllTests.m70
-rw-r--r--objc/test/Ice/adapterDeactivation/Client.m76
-rw-r--r--objc/test/Ice/adapterDeactivation/Makefile37
-rw-r--r--objc/test/Ice/adapterDeactivation/Server.m82
-rw-r--r--objc/test/Ice/adapterDeactivation/TestI.h15
-rw-r--r--objc/test/Ice/adapterDeactivation/TestI.m31
-rwxr-xr-xobjc/test/Ice/adapterDeactivation/run.py23
-rw-r--r--objc/test/Ice/ami/.gitignore8
-rw-r--r--objc/test/Ice/ami/AMITest.ice41
-rw-r--r--objc/test/Ice/ami/AllTests.m760
-rw-r--r--objc/test/Ice/ami/Client.m93
-rw-r--r--objc/test/Ice/ami/Makefile37
-rw-r--r--objc/test/Ice/ami/Server.m103
-rw-r--r--objc/test/Ice/ami/TestI.h29
-rw-r--r--objc/test/Ice/ami/TestI.m114
-rwxr-xr-xobjc/test/Ice/ami/run.py23
-rw-r--r--objc/test/Ice/binding/.gitignore8
-rw-r--r--objc/test/Ice/binding/AllTests.m886
-rw-r--r--objc/test/Ice/binding/BindingTest.ice37
-rw-r--r--objc/test/Ice/binding/Client.m75
-rw-r--r--objc/test/Ice/binding/Makefile37
-rw-r--r--objc/test/Ice/binding/Server.m86
-rw-r--r--objc/test/Ice/binding/TestI.h35
-rw-r--r--objc/test/Ice/binding/TestI.m105
-rwxr-xr-xobjc/test/Ice/binding/run.py23
-rw-r--r--objc/test/Ice/defaultServant/.gitignore7
-rw-r--r--objc/test/Ice/defaultServant/Client.m204
-rw-r--r--objc/test/Ice/defaultServant/DefaultServantTest.ice21
-rw-r--r--objc/test/Ice/defaultServant/Makefile29
-rw-r--r--objc/test/Ice/defaultServant/MyObjectI.h13
-rw-r--r--objc/test/Ice/defaultServant/MyObjectI.m46
-rwxr-xr-xobjc/test/Ice/defaultServant/run.py25
-rw-r--r--objc/test/Ice/defaultValue/.gitignore7
-rw-r--r--objc/test/Ice/defaultValue/AllTests.m110
-rw-r--r--objc/test/Ice/defaultValue/Client.m53
-rw-r--r--objc/test/Ice/defaultValue/DefaultValueTest.ice87
-rw-r--r--objc/test/Ice/defaultValue/Makefile29
-rwxr-xr-xobjc/test/Ice/defaultValue/run.py25
-rw-r--r--objc/test/Ice/dispatcher/.gitignore8
-rw-r--r--objc/test/Ice/dispatcher/AllTests.m156
-rw-r--r--objc/test/Ice/dispatcher/Client.m81
-rw-r--r--objc/test/Ice/dispatcher/DispatcherTest.ice31
-rw-r--r--objc/test/Ice/dispatcher/Makefile37
-rw-r--r--objc/test/Ice/dispatcher/Server.m96
-rw-r--r--objc/test/Ice/dispatcher/TestI.h25
-rw-r--r--objc/test/Ice/dispatcher/TestI.m45
-rwxr-xr-xobjc/test/Ice/dispatcher/run.py23
-rw-r--r--objc/test/Ice/enums/.gitignore8
-rw-r--r--objc/test/Ice/enums/AllTests.m388
-rw-r--r--objc/test/Ice/enums/Client.m79
-rw-r--r--objc/test/Ice/enums/EnumTest.ice98
-rw-r--r--objc/test/Ice/enums/Makefile37
-rw-r--r--objc/test/Ice/enums/Server.m83
-rw-r--r--objc/test/Ice/enums/TestI.h15
-rw-r--r--objc/test/Ice/enums/TestI.m69
-rwxr-xr-xobjc/test/Ice/enums/run.py28
-rw-r--r--objc/test/Ice/exceptions/.gitignore8
-rw-r--r--objc/test/Ice/exceptions/AllTests.m501
-rw-r--r--objc/test/Ice/exceptions/Client.m79
-rw-r--r--objc/test/Ice/exceptions/ExceptionsTest.ice88
-rw-r--r--objc/test/Ice/exceptions/Makefile37
-rw-r--r--objc/test/Ice/exceptions/Server.m90
-rw-r--r--objc/test/Ice/exceptions/TestI.h16
-rw-r--r--objc/test/Ice/exceptions/TestI.m153
-rwxr-xr-xobjc/test/Ice/exceptions/run.py32
-rw-r--r--objc/test/Ice/facets/.gitignore8
-rw-r--r--objc/test/Ice/facets/AllTests.m196
-rw-r--r--objc/test/Ice/facets/Client.m77
-rw-r--r--objc/test/Ice/facets/FacetsTest.ice61
-rw-r--r--objc/test/Ice/facets/Makefile37
-rw-r--r--objc/test/Ice/facets/Server.m91
-rw-r--r--objc/test/Ice/facets/TestI.h40
-rw-r--r--objc/test/Ice/facets/TestI.m103
-rwxr-xr-xobjc/test/Ice/facets/run.py23
-rw-r--r--objc/test/Ice/faultTolerance/.gitignore8
-rw-r--r--objc/test/Ice/faultTolerance/AllTests.m292
-rw-r--r--objc/test/Ice/faultTolerance/Client.m106
-rw-r--r--objc/test/Ice/faultTolerance/Makefile37
-rw-r--r--objc/test/Ice/faultTolerance/Server.m115
-rw-r--r--objc/test/Ice/faultTolerance/Test.ice23
-rw-r--r--objc/test/Ice/faultTolerance/TestI.h14
-rw-r--r--objc/test/Ice/faultTolerance/TestI.m36
-rwxr-xr-xobjc/test/Ice/faultTolerance/run.py46
-rw-r--r--objc/test/Ice/hash/.gitignore7
-rw-r--r--objc/test/Ice/hash/AllTests.m163
-rw-r--r--objc/test/Ice/hash/Client.m53
-rw-r--r--objc/test/Ice/hash/HashTest.ice93
-rw-r--r--objc/test/Ice/hash/Makefile29
-rwxr-xr-xobjc/test/Ice/hash/run.py25
-rw-r--r--objc/test/Ice/hold/.gitignore8
-rw-r--r--objc/test/Ice/hold/AllTests.m266
-rw-r--r--objc/test/Ice/hold/Client.m76
-rw-r--r--objc/test/Ice/hold/HoldTest.ice25
-rw-r--r--objc/test/Ice/hold/Makefile37
-rw-r--r--objc/test/Ice/hold/Server.m101
-rw-r--r--objc/test/Ice/hold/TestI.h28
-rw-r--r--objc/test/Ice/hold/TestI.m140
-rwxr-xr-xobjc/test/Ice/hold/run.py23
-rw-r--r--objc/test/Ice/info/.gitignore8
-rw-r--r--objc/test/Ice/info/AllTests.m173
-rw-r--r--objc/test/Ice/info/Client.m79
-rw-r--r--objc/test/Ice/info/InfoTest.ice27
-rw-r--r--objc/test/Ice/info/Makefile37
-rw-r--r--objc/test/Ice/info/Server.m83
-rw-r--r--objc/test/Ice/info/TestI.h19
-rw-r--r--objc/test/Ice/info/TestI.m60
-rwxr-xr-xobjc/test/Ice/info/run.py23
-rw-r--r--objc/test/Ice/inheritance/.gitignore8
-rw-r--r--objc/test/Ice/inheritance/AllTests.m222
-rw-r--r--objc/test/Ice/inheritance/Client.m77
-rw-r--r--objc/test/Ice/inheritance/InheritanceTest.ice87
-rw-r--r--objc/test/Ice/inheritance/Makefile37
-rw-r--r--objc/test/Ice/inheritance/Server.m83
-rw-r--r--objc/test/Ice/inheritance/TestI.h50
-rw-r--r--objc/test/Ice/inheritance/TestI.m198
-rwxr-xr-xobjc/test/Ice/inheritance/run.py23
-rw-r--r--objc/test/Ice/interceptor/.gitignore7
-rw-r--r--objc/test/Ice/interceptor/Client.m166
-rw-r--r--objc/test/Ice/interceptor/InterceptorI.h25
-rw-r--r--objc/test/Ice/interceptor/InterceptorI.m100
-rw-r--r--objc/test/Ice/interceptor/InterceptorTest.ice53
-rw-r--r--objc/test/Ice/interceptor/Makefile30
-rw-r--r--objc/test/Ice/interceptor/MyObjectI.h13
-rw-r--r--objc/test/Ice/interceptor/MyObjectI.m46
-rwxr-xr-xobjc/test/Ice/interceptor/run.py25
-rw-r--r--objc/test/Ice/invoke/.gitignore8
-rw-r--r--objc/test/Ice/invoke/AllTests.m278
-rw-r--r--objc/test/Ice/invoke/BlobjectI.h14
-rw-r--r--objc/test/Ice/invoke/BlobjectI.m76
-rw-r--r--objc/test/Ice/invoke/Client.m77
-rw-r--r--objc/test/Ice/invoke/InvokeTest.ice31
-rw-r--r--objc/test/Ice/invoke/Makefile37
-rw-r--r--objc/test/Ice/invoke/Server.m81
-rwxr-xr-xobjc/test/Ice/invoke/run.py23
-rw-r--r--objc/test/Ice/location/.gitignore8
-rw-r--r--objc/test/Ice/location/AllTests.m479
-rw-r--r--objc/test/Ice/location/Client.m78
-rw-r--r--objc/test/Ice/location/LocationTest.ice56
-rw-r--r--objc/test/Ice/location/Makefile38
-rw-r--r--objc/test/Ice/location/Server.m113
-rw-r--r--objc/test/Ice/location/ServerLocator.h29
-rw-r--r--objc/test/Ice/location/ServerLocator.m129
-rw-r--r--objc/test/Ice/location/TestI.h34
-rw-r--r--objc/test/Ice/location/TestI.m176
-rwxr-xr-xobjc/test/Ice/location/run.py23
-rw-r--r--objc/test/Ice/metrics/.gitignore8
-rw-r--r--objc/test/Ice/metrics/AllTests.m1192
-rw-r--r--objc/test/Ice/metrics/Client.m87
-rw-r--r--objc/test/Ice/metrics/Makefile37
-rw-r--r--objc/test/Ice/metrics/MetricsTest.ice51
-rw-r--r--objc/test/Ice/metrics/Server.m103
-rw-r--r--objc/test/Ice/metrics/TestI.h33
-rw-r--r--objc/test/Ice/metrics/TestI.m98
-rwxr-xr-xobjc/test/Ice/metrics/run.py23
-rw-r--r--objc/test/Ice/objects/.gitignore8
-rw-r--r--objc/test/Ice/objects/AllTests.m517
-rw-r--r--objc/test/Ice/objects/Client.m146
-rw-r--r--objc/test/Ice/objects/Makefile38
-rw-r--r--objc/test/Ice/objects/ObjectsTest.ice201
-rw-r--r--objc/test/Ice/objects/Server.m131
-rw-r--r--objc/test/Ice/objects/TestI.h79
-rw-r--r--objc/test/Ice/objects/TestI.m328
-rwxr-xr-xobjc/test/Ice/objects/run.py32
-rw-r--r--objc/test/Ice/objects/test.log1399
-rw-r--r--objc/test/Ice/operations/.gitignore8
-rw-r--r--objc/test/Ice/operations/AllTests.m52
-rw-r--r--objc/test/Ice/operations/BatchOneways.m58
-rw-r--r--objc/test/Ice/operations/Client.m102
-rw-r--r--objc/test/Ice/operations/Makefile42
-rw-r--r--objc/test/Ice/operations/Oneways.m37
-rw-r--r--objc/test/Ice/operations/OnewaysNewAMI.m125
-rw-r--r--objc/test/Ice/operations/OperationsTest.ice221
-rw-r--r--objc/test/Ice/operations/Server.m93
-rw-r--r--objc/test/Ice/operations/TestI.h16
-rw-r--r--objc/test/Ice/operations/TestI.m470
-rw-r--r--objc/test/Ice/operations/Twoways.m1094
-rw-r--r--objc/test/Ice/operations/TwowaysNewAMI.m1186
-rwxr-xr-xobjc/test/Ice/operations/run.py23
-rw-r--r--objc/test/Ice/optional/.gitignore8
-rw-r--r--objc/test/Ice/optional/AllTests.m1448
-rw-r--r--objc/test/Ice/optional/Client.m76
-rw-r--r--objc/test/Ice/optional/Makefile37
-rw-r--r--objc/test/Ice/optional/OptionalTest.ice279
-rw-r--r--objc/test/Ice/optional/Server.m82
-rw-r--r--objc/test/Ice/optional/TestI.h18
-rw-r--r--objc/test/Ice/optional/TestI.m239
-rwxr-xr-xobjc/test/Ice/optional/run.py26
-rw-r--r--objc/test/Ice/proxy/.gitignore8
-rw-r--r--objc/test/Ice/proxy/AllTests.m869
-rw-r--r--objc/test/Ice/proxy/Client.m79
-rw-r--r--objc/test/Ice/proxy/Makefile37
-rw-r--r--objc/test/Ice/proxy/ProxyTest.ice30
-rw-r--r--objc/test/Ice/proxy/Server.m84
-rw-r--r--objc/test/Ice/proxy/TestI.h21
-rw-r--r--objc/test/Ice/proxy/TestI.m53
-rwxr-xr-xobjc/test/Ice/proxy/run.py23
-rw-r--r--objc/test/Ice/retry/.gitignore8
-rw-r--r--objc/test/Ice/retry/AllTests.m147
-rw-r--r--objc/test/Ice/retry/Client.m89
-rw-r--r--objc/test/Ice/retry/Makefile37
-rw-r--r--objc/test/Ice/retry/RetryTest.ice22
-rw-r--r--objc/test/Ice/retry/Server.m83
-rw-r--r--objc/test/Ice/retry/TestI.h15
-rw-r--r--objc/test/Ice/retry/TestI.m26
-rwxr-xr-xobjc/test/Ice/retry/run.py23
-rw-r--r--objc/test/Ice/services/.gitignore7
-rw-r--r--objc/test/Ice/services/AllTests.m116
-rw-r--r--objc/test/Ice/services/Client.m76
-rw-r--r--objc/test/Ice/services/Makefile30
-rw-r--r--objc/test/Ice/services/ServicesTest.ice21
-rwxr-xr-xobjc/test/Ice/services/run.py25
-rw-r--r--objc/test/Ice/slicing/Makefile21
-rw-r--r--objc/test/Ice/slicing/exceptions/.gitignore10
-rw-r--r--objc/test/Ice/slicing/exceptions/AllTests.m826
-rw-r--r--objc/test/Ice/slicing/exceptions/Client.m76
-rw-r--r--objc/test/Ice/slicing/exceptions/Makefile40
-rw-r--r--objc/test/Ice/slicing/exceptions/Server.m84
-rw-r--r--objc/test/Ice/slicing/exceptions/SlicingExceptionsTestClient.ice113
-rw-r--r--objc/test/Ice/slicing/exceptions/SlicingExceptionsTestServer.ice134
-rw-r--r--objc/test/Ice/slicing/exceptions/TestI.h13
-rw-r--r--objc/test/Ice/slicing/exceptions/TestI.m156
-rwxr-xr-xobjc/test/Ice/slicing/exceptions/run.py28
-rw-r--r--objc/test/Ice/slicing/objects/.gitignore14
-rw-r--r--objc/test/Ice/slicing/objects/AllTests.m2232
-rw-r--r--objc/test/Ice/slicing/objects/Client.m77
-rw-r--r--objc/test/Ice/slicing/objects/Makefile45
-rw-r--r--objc/test/Ice/slicing/objects/Server.m85
-rw-r--r--objc/test/Ice/slicing/objects/SlicingObjectsForwardClient.ice28
-rw-r--r--objc/test/Ice/slicing/objects/SlicingObjectsForwardServer.ice28
-rw-r--r--objc/test/Ice/slicing/objects/SlicingObjectsTestClient.ice196
-rw-r--r--objc/test/Ice/slicing/objects/SlicingObjectsTestServer.ice215
-rw-r--r--objc/test/Ice/slicing/objects/TestI.h18
-rw-r--r--objc/test/Ice/slicing/objects/TestI.m539
-rwxr-xr-xobjc/test/Ice/slicing/objects/run.py28
-rw-r--r--objc/test/Ice/stream/.gitignore7
-rw-r--r--objc/test/Ice/stream/Client.m979
-rw-r--r--objc/test/Ice/stream/Makefile28
-rw-r--r--objc/test/Ice/stream/StreamTest.ice175
-rwxr-xr-xobjc/test/Ice/stream/run.py29
-rw-r--r--objc/test/Ice/timeout/.gitignore8
-rw-r--r--objc/test/Ice/timeout/AllTests.m277
-rw-r--r--objc/test/Ice/timeout/Client.m93
-rw-r--r--objc/test/Ice/timeout/Makefile37
-rw-r--r--objc/test/Ice/timeout/Server.m94
-rw-r--r--objc/test/Ice/timeout/TestI.h18
-rw-r--r--objc/test/Ice/timeout/TestI.m94
-rw-r--r--objc/test/Ice/timeout/TimeoutTest.ice29
-rwxr-xr-xobjc/test/Ice/timeout/run.py23
-rw-r--r--objc/test/Makefile21
-rw-r--r--objc/test/Slice/Makefile21
-rw-r--r--objc/test/Slice/keyword/.gitignore9
-rw-r--r--objc/test/Slice/keyword/Client.m223
-rw-r--r--objc/test/Slice/keyword/Inherit.ice95
-rw-r--r--objc/test/Slice/keyword/Key.ice86
-rw-r--r--objc/test/Slice/keyword/Makefile29
-rwxr-xr-xobjc/test/Slice/keyword/run.py25
-rw-r--r--objc/test/include/TestCommon.h35
-rw-r--r--py/config/Make.rules1
-rwxr-xr-xscripts/TestUtil.py16
-rw-r--r--slice/Freeze/BackgroundSaveEvictor.ice2
-rw-r--r--slice/Freeze/CatalogData.ice2
-rw-r--r--slice/Freeze/Connection.ice2
-rw-r--r--slice/Freeze/ConnectionF.ice2
-rw-r--r--slice/Freeze/DB.ice2
-rw-r--r--slice/Freeze/Evictor.ice2
-rw-r--r--slice/Freeze/EvictorF.ice2
-rw-r--r--slice/Freeze/EvictorStorage.ice2
-rw-r--r--slice/Freeze/Exception.ice2
-rw-r--r--slice/Freeze/Transaction.ice2
-rw-r--r--slice/Freeze/TransactionalEvictor.ice2
-rw-r--r--slice/Glacier2/Metrics.ice3
-rw-r--r--slice/Glacier2/PermissionsVerifier.ice3
-rw-r--r--slice/Glacier2/PermissionsVerifierF.ice3
-rw-r--r--slice/Glacier2/Router.ice3
-rw-r--r--slice/Glacier2/RouterF.ice3
-rw-r--r--slice/Glacier2/SSLInfo.ice3
-rw-r--r--slice/Glacier2/Session.ice3
-rw-r--r--slice/Ice/BuiltinSequences.ice3
-rw-r--r--slice/Ice/Communicator.ice3
-rw-r--r--slice/Ice/CommunicatorF.ice3
-rw-r--r--slice/Ice/Connection.ice3
-rw-r--r--slice/Ice/ConnectionF.ice3
-rw-r--r--slice/Ice/Current.ice3
-rw-r--r--slice/Ice/Endpoint.ice3
-rw-r--r--slice/Ice/EndpointF.ice3
-rw-r--r--slice/Ice/EndpointTypes.ice3
-rw-r--r--slice/Ice/FacetMap.ice3
-rw-r--r--slice/Ice/Identity.ice3
-rw-r--r--slice/Ice/ImplicitContext.ice3
-rw-r--r--slice/Ice/ImplicitContextF.ice3
-rw-r--r--slice/Ice/Instrumentation.ice3
-rw-r--r--slice/Ice/InstrumentationF.ice3
-rw-r--r--slice/Ice/LocalException.ice3
-rw-r--r--slice/Ice/Locator.ice4
-rw-r--r--slice/Ice/LocatorF.ice3
-rw-r--r--slice/Ice/Logger.ice3
-rw-r--r--slice/Ice/LoggerF.ice3
-rw-r--r--slice/Ice/Metrics.ice3
-rw-r--r--slice/Ice/ObjectAdapter.ice3
-rw-r--r--slice/Ice/ObjectAdapterF.ice3
-rw-r--r--slice/Ice/ObjectFactory.ice3
-rw-r--r--slice/Ice/ObjectFactoryF.ice3
-rw-r--r--slice/Ice/Plugin.ice3
-rw-r--r--slice/Ice/PluginF.ice3
-rw-r--r--slice/Ice/Process.ice3
-rw-r--r--slice/Ice/ProcessF.ice3
-rw-r--r--slice/Ice/Properties.ice3
-rw-r--r--slice/Ice/PropertiesAdmin.ice3
-rw-r--r--slice/Ice/PropertiesF.ice3
-rw-r--r--slice/Ice/RemoteLogger.ice3
-rw-r--r--slice/Ice/Router.ice3
-rw-r--r--slice/Ice/RouterF.ice3
-rw-r--r--slice/Ice/ServantLocator.ice3
-rw-r--r--slice/Ice/ServantLocatorF.ice3
-rw-r--r--slice/Ice/SliceChecksumDict.ice3
-rw-r--r--slice/Ice/Version.ice3
-rw-r--r--slice/IceBox/IceBox.ice2
-rw-r--r--slice/IceDiscovery/IceDiscovery.ice2
-rw-r--r--slice/IceGrid/Admin.ice3
-rw-r--r--slice/IceGrid/Descriptor.ice3
-rw-r--r--slice/IceGrid/Discovery.ice3
-rw-r--r--slice/IceGrid/Exception.ice3
-rw-r--r--slice/IceGrid/FileParser.ice3
-rw-r--r--slice/IceGrid/Locator.ice3
-rw-r--r--slice/IceGrid/Observer.ice3
-rw-r--r--slice/IceGrid/PluginFacade.ice3
-rw-r--r--slice/IceGrid/Query.ice3
-rw-r--r--slice/IceGrid/Registry.ice3
-rw-r--r--slice/IceGrid/Session.ice3
-rw-r--r--slice/IceGrid/UserAccountMapper.ice3
-rw-r--r--slice/IcePatch2/FileInfo.ice2
-rw-r--r--slice/IcePatch2/FileServer.ice2
-rw-r--r--slice/IceSSL/ConnectionInfo.ice2
-rw-r--r--slice/IceSSL/EndpointInfo.ice2
-rw-r--r--slice/IceStorm/IceStorm.ice3
-rw-r--r--slice/IceStorm/Metrics.ice3
526 files changed, 56161 insertions, 100 deletions
diff --git a/Makefile b/Makefile
index d807ccdb3b1..07636d831df 100644
--- a/Makefile
+++ b/Makefile
@@ -8,9 +8,16 @@
# **********************************************************************
SUBDIRS = cpp java js py rb php
-CLEAN_SUBDIRS = js java py rb php cpp
-DEPEND_SUBDIRS = cpp py rb php
-INSTALL_SUBDIRS = cpp java py rb php js
+CLEAN_SUBDIRS = js java py rb php cpp
+DEPEND_SUBDIRS = cpp py rb php
+INSTALL_SUBDIRS = cpp java py rb php js
+
+ifeq ($(shell uname),Darwin)
+SUBDIRS += objc
+CLEAN_SUBDIRS += objc
+DEPEND_SUBDIRS += objc
+INSTALL_SUBDIRS += objc
+endif
all::
@for subdir in $(SUBDIRS); \
diff --git a/cpp/config/Make.rules b/cpp/config/Make.rules
index 40dc1c522b8..84b126c37ab 100644
--- a/cpp/config/Make.rules
+++ b/cpp/config/Make.rules
@@ -358,9 +358,9 @@ ifneq ($(SLICE_OBJS),)
endif
#
-# If dependencies has non been created yet make all OBJS depend
-# on all SRCS, Slice generated files will be created before C++
-# compilation starts and avoid problems with parallel make
+# If dependencies haven't been created yet make all OBJS depend on all
+# SRCS, Slice generated files will be created before C++ compilation
+# starts. This prevents issues parallel make.
#
ifneq ($(OBJS),)
diff --git a/cpp/include/Slice/ObjCUtil.h b/cpp/include/Slice/ObjCUtil.h
new file mode 100644
index 00000000000..5432259a226
--- /dev/null
+++ b/cpp/include/Slice/ObjCUtil.h
@@ -0,0 +1,125 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef OBJC_UTIL_H
+#define OBJC_UTIL_H
+
+#include <Slice/Parser.h>
+#include <IceUtil/OutputUtil.h>
+
+namespace Slice
+{
+
+enum BaseType
+{
+ BaseTypeNone,
+ BaseTypeObject,
+ BaseTypeException
+};
+
+class SLICE_API ObjCGenerator : private ::IceUtil::noncopyable
+{
+public:
+
+ virtual ~ObjCGenerator() {};
+
+ //
+ // Validate all metadata in the unit with an "objc:" prefix.
+ //
+ static void validateMetaData(const UnitPtr&);
+
+protected:
+ struct ModulePrefix
+ {
+ ModulePtr m;
+ std::string name;
+ };
+
+ static bool addModule(const ModulePtr&, const std::string&);
+ static ModulePrefix modulePrefix(const ModulePtr&);
+ static std::string moduleName(const ModulePtr&);
+ static ModulePtr findModule(const ContainedPtr&, int = 0, bool = false);
+ static void modulePrefixError(const ModulePtr&, const std::string&);
+ static std::string fixId(const std::string&, int = 0, bool = false);
+ static std::string fixId(const ContainedPtr&, int = 0, bool = false);
+ static std::string fixName(const ContainedPtr&, int = 0, bool = false);
+ static std::string fixScoped(const ContainedPtr&, int = 0, bool = false);
+ static std::string typeToString(const TypePtr&);
+ static std::string inTypeToString(const TypePtr&, bool, bool = false, bool = false);
+ static std::string outTypeToString(const TypePtr&, bool, bool = false, bool = false);
+ static std::string typeToObjCTypeString(const TypePtr&);
+ static bool isValueType(const TypePtr&);
+ static bool isString(const TypePtr&);
+ static bool isClass(const TypePtr&);
+ static bool mapsToPointerType(const TypePtr&);
+ static std::string getBuiltinName(const BuiltinPtr&);
+ static std::string getBuiltinSelector(const BuiltinPtr&, bool);
+ static std::string getOptionalHelperGetter(const TypePtr&);
+ static std::string getOptionalStreamHelper(const TypePtr&);
+ static StringList splitScopedName(const std::string&);
+ static std::string getOptionalFormat(const TypePtr&);
+
+ //
+ // Generate code to marshal or unmarshal a type
+ //
+ void writeMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, const std::string&, bool, bool) const;
+ void writeOptMemberMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, const std::string&, bool) const;
+ void writeOptParamMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, const std::string&, int,
+ bool) const;
+
+private:
+
+ class MetaDataVisitor : public ParserVisitor
+ {
+ public:
+ MetaDataVisitor();
+
+ virtual bool visitUnitStart(const UnitPtr&);
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual void visitClassDecl(const ClassDeclPtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual void visitExceptionEnd(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitStructEnd(const StructPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ virtual void visitParamDecl(const ParamDeclPtr&);
+ virtual void visitDataMember(const DataMemberPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+
+ private:
+
+ void validate(const ContainedPtr&);
+
+ static Slice::StringList getMetaData(const ContainedPtr&);
+ static void modulePrefixError(const ModulePtr&, const std::string&);
+
+ static const std::string _objcPrefix; // "objc:"
+ static const std::string _msg; // "ignoring invalid metadata"
+
+ StringSet _history;
+ };
+
+
+ //
+ // Map of module scoped name to ModulePtr. Used to verify that objc:prefix metadata directives are consistent.
+ //
+
+ typedef std::map<std::string, ModulePrefix> ModuleMap;
+ static ModuleMap _modules;
+};
+
+}
+
+#endif
diff --git a/cpp/include/Slice/Preprocessor.h b/cpp/include/Slice/Preprocessor.h
index 3ae1225a9e0..6667189aec1 100644
--- a/cpp/include/Slice/Preprocessor.h
+++ b/cpp/include/Slice/Preprocessor.h
@@ -39,7 +39,7 @@ public:
FILE* preprocess(bool, const std::string& = "");
bool close();
- enum Language { CPlusPlus, Java, JavaXML, CSharp, Python, Ruby, PHP, JS };
+ enum Language { CPlusPlus, Java, JavaXML, CSharp, Python, Ruby, PHP, JS, ObjC };
bool printMakefileDependencies(Language, const std::vector<std::string>&, const std::string& = "", const std::string& = "cpp",
const std::string& = "");
diff --git a/cpp/src/Ice/Makefile b/cpp/src/Ice/Makefile
index 7001e0d7a44..2f87cf2123c 100644
--- a/cpp/src/Ice/Makefile
+++ b/cpp/src/Ice/Makefile
@@ -54,7 +54,7 @@ SLICE_OBJS = BuiltinSequences.o \
SliceChecksumDict.o \
Version.o
-OBJS = Acceptor.o \
+OBJS = Acceptor.o \
ACM.o \
Application.o \
AsyncResult.o \
diff --git a/cpp/src/Makefile b/cpp/src/Makefile
index 89e7e3c423b..d9cd4c797fa 100644
--- a/cpp/src/Makefile
+++ b/cpp/src/Makefile
@@ -12,7 +12,7 @@ top_srcdir = ..
include $(top_srcdir)/config/Make.rules
ifneq ($(findstring MINGW,$(UNAME)),)
- SUBDIRS = IceUtil \
+ SUBDIRS = IceUtil \
Slice \
slice2cpp \
slice2rb \
@@ -20,7 +20,7 @@ ifneq ($(findstring MINGW,$(UNAME)),)
IceSSL \
IceDiscovery
else
- SUBDIRS = IceUtil \
+ SUBDIRS = IceUtil \
Slice \
slice2cpp \
slice2cs \
@@ -31,7 +31,13 @@ else
slice2py \
slice2rb \
slice2html \
- slice2js \
+ slice2js
+
+ifeq ($(UNAME),Darwin)
+ SUBDIRS := $(SUBDIRS) slice2objc
+endif
+
+ SUBDIRS := $(SUBDIRS) \
Ice \
IceXML \
IceSSL \
@@ -59,7 +65,7 @@ endif
Slice: IceUtil
-slice2cpp slice2cs slice2freeze slice2freezej slice2java slice2js slice2php slice2py slice2rb slice2html: Slice
+slice2cpp slice2cs slice2freeze slice2freezej slice2java slice2js slice2php slice2py slice2rb slice2html slice2objc: Slice
Ice: slice2cpp
diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile
index d96009fad9e..4e816bc3ccb 100644
--- a/cpp/src/Slice/Makefile
+++ b/cpp/src/Slice/Makefile
@@ -22,6 +22,7 @@ OBJS = Checksum.o \
JavaUtil.o \
MD5.o \
MD5I.o \
+ ObjCUtil.o \
Parser.o \
PHPUtil.o \
Preprocessor.o \
diff --git a/cpp/src/Slice/ObjCUtil.cpp b/cpp/src/Slice/ObjCUtil.cpp
new file mode 100644
index 00000000000..cc3abd3b08b
--- /dev/null
+++ b/cpp/src/Slice/ObjCUtil.cpp
@@ -0,0 +1,1204 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Slice/ObjCUtil.h>
+#include <Slice/Util.h>
+#include <IceUtil/Functional.h>
+#include <IceUtil/StringUtil.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#include <direct.h>
+#endif
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+using namespace std;
+using namespace Slice;
+using namespace IceUtil;
+using namespace IceUtilInternal;
+
+Slice::ObjCGenerator::ModuleMap Slice::ObjCGenerator::_modules;
+
+static string
+lookupKwd(const string& name, int baseType, bool mangleCasts = false)
+{
+ //
+ // All lists in this method *must* be kept in case-insensitive
+ // alphabetical order.
+ //
+ static string keywordList[] =
+ {
+ "auto", "BOOL", "break", "bycopy", "byref", "case", "char", "const", "continue",
+ "default", "do", "double", "else", "enum", "extern", "float", "for", "goto",
+ "id", "if", "IMP", "in", "inline", "inout", "int", "long", "nil", "NO", "oneway", "out",
+ "register", "return", "SEL", "self", "short", "signed", "sizeof", "static", "struct", "super", "switch",
+ "typedef", "union", "unsigned", "void", "volatile", "while", "YES"
+ };
+
+ static string nsObjectList[] =
+ {
+ "autorelease", "class", "classForCoder", "copy", "dealloc", "description", "hash", "init", "isa",
+ "isProxy", "mutableCopy", "release", "retain", "retainCount", "superclass", "zone"
+ };
+ static string nsExceptionList[] =
+ {
+ "callStackReturnAddresses", "name", "raise", "reason", "reserved", "userInfo",
+ };
+
+ bool found = binary_search(&keywordList[0],
+ &keywordList[sizeof(keywordList) / sizeof(*keywordList)],
+ name,
+ Slice::CICompare());
+ if(!found)
+ {
+ switch(baseType)
+ {
+ case BaseTypeNone:
+ break;
+
+ case BaseTypeException:
+ found = binary_search(&nsExceptionList[0],
+ &nsExceptionList[sizeof(nsExceptionList) / sizeof(*nsExceptionList)],
+ name,
+ Slice::CICompare());
+ if(found)
+ {
+ break;
+ }
+
+ case BaseTypeObject:
+ found = binary_search(&nsObjectList[0],
+ &nsObjectList[sizeof(nsObjectList) / sizeof(*nsObjectList)],
+ name,
+ Slice::CICompare());
+ break;
+ }
+ }
+ if(found || (mangleCasts && (name == "checkedCast" || name == "uncheckedCast")))
+ {
+ return name + "_";
+ }
+ return name;
+}
+
+bool
+Slice::ObjCGenerator::addModule(const ModulePtr& m, const string& name)
+{
+ string scoped = m->scoped();
+ ModuleMap::const_iterator i = _modules.find(scoped);
+ if(i != _modules.end())
+ {
+ if(i->second.name != name)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ ModulePrefix mp;
+ mp.m = m;
+ mp.name = name;
+ _modules[scoped] = mp;
+ }
+ return true;
+}
+
+Slice::ObjCGenerator::ModulePrefix
+Slice::ObjCGenerator::modulePrefix(const ModulePtr& m)
+{
+ return _modules[m->scoped()];
+}
+
+string
+Slice::ObjCGenerator::moduleName(const ModulePtr& m)
+{
+ return _modules[m->scoped()].name;
+}
+
+ModulePtr
+Slice::ObjCGenerator::findModule(const ContainedPtr& cont, int baseTypes, bool mangleCasts)
+{
+ ModulePtr m = ModulePtr::dynamicCast(cont);
+ ContainerPtr container = cont->container();
+ while(container && !m)
+ {
+ ContainedPtr contained = ContainedPtr::dynamicCast(container);
+ container = contained->container();
+ m = ModulePtr::dynamicCast(contained);
+ }
+ assert(m);
+ return m;
+}
+
+//
+// If the passed name is a scoped name, return the identical scoped
+// name, but with all components that are Objective-C keywords
+// replaced by their prefixed version; otherwise, if the passed name
+// is not scoped, but an Objective-C keyword, return the prefixed
+// name; otherwise, check if the name is one of the method names of
+// baseTypes; if so, returned the prefixed name; otherwise, return the
+// name unchanged.
+//
+string
+Slice::ObjCGenerator::fixId(const string& name, int baseTypes, bool mangleCasts)
+{
+ if(name.empty())
+ {
+ return name;
+ }
+ return lookupKwd(name, baseTypes, mangleCasts);
+}
+
+string
+Slice::ObjCGenerator::fixId(const ContainedPtr& cont, int baseTypes, bool mangleCasts)
+{
+ return fixId(cont->name(), baseTypes, mangleCasts);
+}
+
+string
+Slice::ObjCGenerator::fixName(const ContainedPtr& cont, int baseTypes, bool mangleCasts)
+{
+ return moduleName(findModule(cont, baseTypes, mangleCasts)) + cont->name();
+}
+
+string
+Slice::ObjCGenerator::typeToString(const TypePtr& type)
+{
+ if(!type)
+ {
+ return "void";
+ }
+
+ static const char* builtinTable[] =
+ {
+ "ICEByte",
+ "BOOL",
+ "ICEShort",
+ "ICEInt",
+ "ICELong",
+ "ICEFloat",
+ "ICEDouble",
+ "NSString",
+ "ICEObject",
+ "id<ICEObjectPrx>",
+ "id" // Dummy--we don't support Slice local Object
+ };
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ return builtinTable[builtin->kind()];
+ }
+
+ ProxyPtr proxy = ProxyPtr::dynamicCast(type);
+ if(proxy)
+ {
+ string mName = moduleName(findModule(proxy->_class()));
+ return "id<" + mName + (proxy->_class()->name()) + "Prx>";
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return fixName(seq);
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ return fixName(d);
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl && cl->isInterface())
+ {
+ return "ICEObject";
+ }
+
+ ContainedPtr contained = ContainedPtr::dynamicCast(type);
+ if(contained)
+ {
+ return fixName(contained);
+ }
+
+ return "???";
+}
+
+string
+Slice::ObjCGenerator::inTypeToString(const TypePtr& type, bool optional, bool autoreleasing, bool reference)
+{
+ string s;
+ if(optional)
+ {
+ s = "id";
+ }
+ else
+ {
+ s = typeToString(type);
+ if(mapsToPointerType(type))
+ {
+ s += "*";
+ }
+ }
+ if(autoreleasing && !isValueType(type))
+ {
+ s += " ICE_AUTORELEASING_QUALIFIER";
+ }
+ if(reference)
+ {
+ s += "*";
+ }
+ return s;
+}
+
+string
+Slice::ObjCGenerator::outTypeToString(const TypePtr& type, bool optional, bool autoreleasing, bool reference)
+{
+ if(!type)
+ {
+ return "void";
+ }
+
+ string s;
+ if(optional)
+ {
+ s = "id";
+ }
+ else
+ {
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(isString(type))
+ {
+ s = "NSMutableString";
+ }
+ else if(seq)
+ {
+ string prefix = moduleName(findModule(seq));
+ s = prefix + "Mutable" + seq->name();
+ }
+ else if(d)
+ {
+ string prefix = moduleName(findModule(d));
+ s = prefix + "Mutable" + d->name();
+ }
+ else
+ {
+ s = typeToString(type);
+ }
+ if(mapsToPointerType(type))
+ {
+ s += "*";
+ }
+ }
+ if(autoreleasing && !isValueType(type))
+ {
+ s += " ICE_AUTORELEASING_QUALIFIER";
+ }
+ if(reference)
+ {
+ s += "*";
+ }
+ return s;
+}
+
+string
+Slice::ObjCGenerator::typeToObjCTypeString(const TypePtr& type)
+{
+ ProxyPtr proxy = ProxyPtr::dynamicCast(type);
+ if(proxy)
+ {
+ return moduleName(findModule(proxy->_class())) + (proxy->_class()->name()) + "Prx";
+ }
+ else
+ {
+ return typeToString(type);
+ }
+}
+
+bool
+Slice::ObjCGenerator::isValueType(const TypePtr& type)
+{
+ if(!type)
+ {
+ return true;
+ }
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindString:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ return false;
+ break;
+ }
+ default:
+ {
+ return true;
+ break;
+ }
+ }
+ }
+ if(EnumPtr::dynamicCast(type))
+ {
+ return true;
+ }
+ return false;
+}
+
+bool
+Slice::ObjCGenerator::isString(const TypePtr& type)
+{
+ if(!type)
+ {
+ return false;
+ }
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ return builtin && builtin->kind() == Builtin::KindString;
+}
+bool
+Slice::ObjCGenerator::isClass(const TypePtr& type)
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ return builtin->kind() == Builtin::KindObject;
+ }
+ return ClassDeclPtr::dynamicCast(type);
+}
+
+bool
+Slice::ObjCGenerator::mapsToPointerType(const TypePtr& type)
+{
+ if(isValueType(type))
+ {
+ return false;
+ }
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ return builtin->kind() != Builtin::KindObjectProxy;
+ }
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl && cl->isInterface())
+ {
+ return true;
+ }
+ return !ProxyPtr::dynamicCast(type);
+}
+
+string
+Slice::ObjCGenerator::getBuiltinName(const BuiltinPtr& builtin)
+{
+ switch(builtin->kind())
+ {
+ case Builtin::KindByte:
+ {
+ return "Byte";
+ }
+ case Builtin::KindBool:
+ {
+ return "Bool";
+ }
+ case Builtin::KindShort:
+ {
+ return "Short";
+ }
+ case Builtin::KindInt:
+ {
+ return "Int";
+ }
+ case Builtin::KindLong:
+ {
+ return "Long";
+ }
+ case Builtin::KindFloat:
+ {
+ return "Float";
+ }
+ case Builtin::KindDouble:
+ {
+ return "Double";
+ }
+ case Builtin::KindString:
+ {
+ return "String";
+ }
+ case Builtin::KindObject:
+ {
+ return "Object";
+ }
+ case Builtin::KindObjectProxy:
+ {
+ return "Proxy";
+ }
+ default:
+ {
+ assert(false);
+ }
+ }
+ return "NO__SUCH__TYPE";
+}
+
+string
+Slice::ObjCGenerator::getOptionalHelperGetter(const TypePtr& type)
+{
+ if(isValueType(type))
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ return "get" + getBuiltinName(builtin);
+ }
+ if(EnumPtr::dynamicCast(type))
+ {
+ return "getInt";
+ }
+ }
+ return "get";
+}
+
+//
+// Split a scoped name into its components and return the components as a list of (unscoped) identifiers.
+//
+StringList
+Slice::ObjCGenerator::splitScopedName(const string& scoped)
+{
+ assert(scoped[0] == ':');
+ StringList ids;
+ string::size_type next = 0;
+ string::size_type pos;
+ while((pos = scoped.find("::", next)) != string::npos)
+ {
+ pos += 2;
+ if(pos != scoped.size())
+ {
+ string::size_type endpos = scoped.find("::", pos);
+ if(endpos != string::npos)
+ {
+ ids.push_back(scoped.substr(pos, endpos - pos));
+ }
+ }
+ next = pos;
+ }
+ if(next != scoped.size())
+ {
+ ids.push_back(scoped.substr(next));
+ }
+ else
+ {
+ ids.push_back("");
+ }
+
+ return ids;
+}
+
+string
+Slice::ObjCGenerator::getOptionalFormat(const TypePtr& type)
+{
+ BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
+ if(bp)
+ {
+ switch(bp->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindBool:
+ {
+ return "ICEOptionalFormatF1";
+ }
+ case Builtin::KindShort:
+ {
+ return "ICEOptionalFormatF2";
+ }
+ case Builtin::KindInt:
+ case Builtin::KindFloat:
+ {
+ return "ICEOptionalFormatF4";
+ }
+ case Builtin::KindLong:
+ case Builtin::KindDouble:
+ {
+ return "ICEOptionalFormatF8";
+ }
+ case Builtin::KindString:
+ {
+ return "ICEOptionalFormatVSize";
+ }
+ case Builtin::KindObject:
+ {
+ return "ICEOptionalFormatClass";
+ }
+ case Builtin::KindObjectProxy:
+ {
+ return "ICEOptionalFormatFSize";
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ }
+
+ if(EnumPtr::dynamicCast(type))
+ {
+ return "ICEOptionalFormatSize";
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return seq->type()->isVariableLength() ? "ICEOptionalFormatFSize" : "ICEOptionalFormatVSize";
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ return (d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) ?
+ "ICEOptionalFormatFSize" : "ICEOptionalFormatVSize";
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ return st->isVariableLength() ? "ICEOptionalFormatFSize" : "ICEOptionalFormatVSize";
+ }
+
+ if(ProxyPtr::dynamicCast(type))
+ {
+ return "ICEOptionalFormatFSize";
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ assert(cl);
+ return "ICEOptionalFormatClass";
+}
+
+void
+Slice::ObjCGenerator::writeMarshalUnmarshalCode(Output &out, const TypePtr& type, const string& param,
+ bool marshal, bool autoreleased) const
+{
+ string stream = marshal ? "os_" : "is_";
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+
+ if(builtin)
+ {
+ string name;
+ if(builtin->kind() == Builtin::KindObject)
+ {
+ if(marshal)
+ {
+ out << nl << "[" << stream << " writeObject:" << param << "];";
+ }
+ else
+ {
+ if(autoreleased)
+ {
+ out << nl << "[" << stream << " readObject:&" << param << "];";
+ }
+ else
+ {
+ out << nl << "[" << stream << " newObject:&" << param << "];";
+ }
+ }
+ }
+ else if(builtin->kind() == Builtin::KindObjectProxy)
+ {
+ if(marshal)
+ {
+ out << nl << "[" << stream << " writeProxy:" << param << "];";
+ }
+ else
+ {
+ if(autoreleased)
+ {
+ out << nl << param << " = [" << stream << " readProxy:[ICEObjectPrx class]];";
+ }
+ else
+ {
+ out << nl << param << " = [" << stream << " newProxy:[ICEObjectPrx class]];";
+ }
+ }
+ }
+ else
+ {
+ if(marshal)
+ {
+ out << nl << "[" << stream << " write" << getBuiltinName(builtin) << ":" << param << "];";
+ }
+ else
+ {
+ if(autoreleased || isValueType(builtin))
+ {
+ out << nl << param << " = [" << stream << " read" << getBuiltinName(builtin) << "];";
+ }
+ else
+ {
+ out << nl << param << " = [" << stream << " new" << getBuiltinName(builtin) << "];";
+ }
+ }
+ }
+ return;
+ }
+
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+ if(prx)
+ {
+ if(marshal)
+ {
+ out << nl << "[" << stream << " writeProxy:(id<ICEObjectPrx>)" << param << "];";
+ }
+ else
+ {
+ string name = moduleName(findModule(prx->_class())) + prx->_class()->name() + "Prx";
+ out << nl << param << " = (id<" << name << ">)[" << stream;
+ if(autoreleased)
+ {
+ out << " readProxy:";
+ }
+ else
+ {
+ out << " newProxy:";
+ }
+ //
+ // We use objc_getClass to get the proxy class instead of [name class]. This is to avoid
+ // a warning if the proxy is forward declared.
+ //
+ if(prx->_class()->definition())
+ {
+ out << "[" << name << " class]];";
+ }
+ else
+ {
+ out << "objc_getClass(\"" << name << "\")];";
+ }
+ }
+ return;
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl)
+ {
+ if(marshal)
+ {
+ // Cast avoids warning for forward-declared classes.
+ out << nl << "[" << stream << " writeObject:(ICEObject*)" << param << "];";
+ }
+ else
+ {
+ if(autoreleased)
+ {
+ out << nl << "[" << stream << " " << "readObject:(ICEObject**)&" << param;
+ }
+ else
+ {
+ out << nl << "[" << stream << " " << "newObject:(ICEObject**)&" << param;
+ }
+
+ if(cl->isInterface())
+ {
+ out << "];";
+ }
+ else
+ {
+ string name = moduleName(findModule(cl)) + cl->name();
+ if(cl->definition())
+ {
+ out << " expectedType:[" << name << " class]];";
+ }
+ else
+ {
+ out << " expectedType:objc_getClass(\"" << name << "\")];";
+ }
+ }
+ }
+ return;
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ if(marshal)
+ {
+ out << nl << "[" << stream << " writeEnumerator:" << param << " min:" << en->minValue()
+ << " max:" << en->maxValue() << "];";
+ }
+ else
+ {
+ out << nl << param << " = " << "[" << stream << " readEnumerator:" << en->minValue()
+ << " max:" << en->maxValue() << "];";
+ }
+ return;
+ }
+
+ ContainedPtr c = ContainedPtr::dynamicCast(type);
+ assert(c);
+ string name = moduleName(findModule(c)) + c->name() + "Helper";
+ if(marshal)
+ {
+ out << nl << "[" + name << " write:" << param << " stream:" << stream << "];";
+ }
+ else
+ {
+ if(autoreleased)
+ {
+ out << nl << param << " = [" << name << " read:" << stream << "];";
+ }
+ else
+ {
+ out << nl << param << " = [" << name << " readRetained:" << stream << "];";
+ }
+ }
+}
+
+void
+Slice::ObjCGenerator::writeOptMemberMarshalUnmarshalCode(Output &out, const TypePtr& type, const string& param,
+ bool marshal) const
+{
+ string stream = marshal ? "os_" : "is_";
+ string optionalHelper;
+ string helper;
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ if(builtin->kind() == Builtin::KindObjectProxy)
+ {
+ optionalHelper = "ICEVarLengthOptionalHelper";
+ helper = "[ICEProxyHelper class]";
+ }
+ else
+ {
+ writeMarshalUnmarshalCode(out, type, param, marshal, false);
+ return;
+ }
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl)
+ {
+ writeMarshalUnmarshalCode(out, type, param, marshal, false);
+ return;
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ writeMarshalUnmarshalCode(out, type, param, marshal, false);
+ return;
+ }
+
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+ if(prx)
+ {
+ optionalHelper = "ICEVarLengthOptionalHelper";
+ helper = "objc_getClass(\"" + moduleName(findModule(prx->_class())) + prx->_class()->name() + "PrxHelper\")";
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ if(st->isVariableLength())
+ {
+ optionalHelper = "ICEVarLengthOptionalHelper";
+ }
+ else
+ {
+ optionalHelper = "ICEFixedLengthOptionalHelper";
+ }
+ helper = "[" + typeToString(st) + "Helper class]";
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ TypePtr element = seq->type();
+ if(element->isVariableLength())
+ {
+ optionalHelper = "ICEVarLengthOptionalHelper";
+ }
+ else if(element->minWireSize() == 1)
+ {
+ writeMarshalUnmarshalCode(out, type, param, marshal, false);
+ return;
+ }
+ else
+ {
+ optionalHelper = "ICEFixedSequenceOptionalHelper";
+ }
+ helper = "[" + moduleName(findModule(seq)) + seq->name() + "Helper class]";
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ if(d->keyType()->isVariableLength() || d->valueType()->isVariableLength())
+ {
+ optionalHelper = "ICEVarLengthOptionalHelper";
+ }
+ else
+ {
+ optionalHelper = "ICEFixedDictionaryOptionalHelper";
+ }
+ helper = "[" + moduleName(findModule(d)) + d->name() + "Helper class]";
+ }
+
+ out << nl;
+ if(marshal)
+ {
+ out << "[" << optionalHelper << " write:" << param << " stream:" << stream << " helper:" << helper << "];";
+ }
+ else
+ {
+ out << param << " = [" << optionalHelper << " readRetained:" << stream << " helper:" << helper << "];";
+ }
+
+}
+
+void
+Slice::ObjCGenerator::writeOptParamMarshalUnmarshalCode(Output &out, const TypePtr& type, const string& param,
+ int tag, bool marshal) const
+{
+ string helper;
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ ProxyPtr proxy = ProxyPtr::dynamicCast(type);
+ if(builtin)
+ {
+ helper = "ICE" + getBuiltinName(builtin) + "Helper";
+ }
+ else if(proxy)
+ {
+ helper = moduleName(findModule(proxy->_class())) + (proxy->_class()->name()) + "PrxHelper";
+ }
+ else
+ {
+ helper = typeToString(type) + "Helper";
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl)
+ {
+ out << nl;
+ if(marshal)
+ {
+ out << "[" << helper << " writeOpt:" << param << " stream:os_ tag:" << tag << "];";
+ }
+ else
+ {
+ out << "[" << helper << " readOpt:&" << param << " stream:is_ tag:" << tag << "];";
+ }
+ return;
+ }
+
+ out << nl;
+ if(marshal)
+ {
+ out << "[" << helper << " writeOpt:" << param << " stream:os_ tag:" << tag << "];";
+ }
+ else
+ {
+ out << param << " = [" << helper << " readOpt:is_ tag:" << tag << "];";
+ }
+}
+
+void
+Slice::ObjCGenerator::validateMetaData(const UnitPtr& u)
+{
+ MetaDataVisitor visitor;
+ u->visit(&visitor, true);
+}
+
+const string Slice::ObjCGenerator::MetaDataVisitor::_objcPrefix = "objc:";
+const string Slice::ObjCGenerator::MetaDataVisitor::_msg = "ignoring invalid metadata";
+
+Slice::ObjCGenerator::MetaDataVisitor::MetaDataVisitor()
+{
+}
+
+bool
+Slice::ObjCGenerator::MetaDataVisitor::visitUnitStart(const UnitPtr& p)
+{
+ //
+ // Validate global metadata in the top-level file and all included files.
+ //
+ StringList files = p->allFiles();
+
+ for(StringList::iterator q = files.begin(); q != files.end(); ++q)
+ {
+ string file = *q;
+ DefinitionContextPtr dc = p->findDefinitionContext(file);
+ assert(dc);
+ StringList globalMetaData = dc->getMetaData();
+ int headerDir = 0;
+ for(StringList::const_iterator r = globalMetaData.begin(); r != globalMetaData.end(); ++r)
+ {
+ string s = *r;
+ if(_history.count(s) == 0)
+ {
+ if(s.find(_objcPrefix) == 0)
+ {
+ static const string objcHeaderDirPrefix = "objc:header-dir:";
+ if(s.find(objcHeaderDirPrefix) == 0 && s.size() > objcHeaderDirPrefix.size())
+ {
+ headerDir++;
+ if(headerDir > 1)
+ {
+ ostringstream ostr;
+ ostr << "ignoring invalid global metadata `" << s
+ << "': directive can appear only once per file";
+ emitWarning(file, -1, ostr.str());
+ _history.insert(s);
+ }
+ continue;
+ }
+ ostringstream ostr;
+ ostr << "ignoring invalid global metadata `" << s << "'";
+ emitWarning(file, -1, ostr.str());
+ }
+ _history.insert(s);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool
+Slice::ObjCGenerator::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
+{
+ validate(p);
+ return true;
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitModuleEnd(const ModulePtr&)
+{
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ validate(p);
+}
+
+bool
+Slice::ObjCGenerator::MetaDataVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ validate(p);
+ return true;
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitClassDefEnd(const ClassDefPtr&)
+{
+}
+
+bool
+Slice::ObjCGenerator::MetaDataVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ validate(p);
+ return true;
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitExceptionEnd(const ExceptionPtr&)
+{
+}
+
+bool
+Slice::ObjCGenerator::MetaDataVisitor::visitStructStart(const StructPtr& p)
+{
+ validate(p);
+ return true;
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitStructEnd(const StructPtr&)
+{
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitOperation(const OperationPtr& p)
+{
+ if(p->hasMetaData("UserException"))
+ {
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
+ if(!cl->isLocal())
+ {
+ ostringstream os;
+ os << "ignoring invalid metadata `UserException': directive applies only to local operations "
+ << ": warning: metadata directive `UserException' applies only to local operations "
+ << "but enclosing " << (cl->isInterface() ? "interface" : "class") << "`" << cl->name()
+ << "' is not local";
+ emitWarning(p->file(), p->line(), os.str());
+ }
+ }
+ validate(p);
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitParamDecl(const ParamDeclPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitSequence(const SequencePtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitEnum(const EnumPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::visitConst(const ConstPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
+{
+ ModulePtr m = ModulePtr::dynamicCast(cont);
+ if(m)
+ {
+ bool error = false;
+ bool foundPrefix = false;
+
+ StringList meta = getMetaData(m);
+ StringList::const_iterator p;
+
+ for(p = meta.begin(); p != meta.end(); ++p)
+ {
+ const string prefix = "prefix:";
+ string name;
+ if(p->substr(_objcPrefix.size(), prefix.size()) == prefix)
+ {
+ foundPrefix = true;
+ name = trim(p->substr(_objcPrefix.size() + prefix.size()));
+ if(name.empty())
+ {
+ if(_history.count(*p) == 0)
+ {
+ string file = m->definitionContext()->filename();
+ ostringstream os;
+ os << _msg << " `" << *p << "'" << endl;
+ emitWarning(file, m->line(), os.str());
+ _history.insert(*p);
+ }
+ error = true;
+ }
+ else
+ {
+ if(!addModule(m, name))
+ {
+ modulePrefixError(m, *p);
+ }
+ }
+ }
+ else
+ {
+ if(_history.count(*p) == 0)
+ {
+ string file = m->definitionContext()->filename();
+ ostringstream os;
+ os << _msg << " `" << *p << "'" << endl;
+ emitWarning(file, m->line(), os.str());
+ _history.insert(*p);
+ }
+ error = true;
+ }
+ }
+
+ if(!error && !foundPrefix)
+ {
+ StringList names = splitScopedName(m->scoped());
+ string name;
+ for(StringList::const_iterator i = names.begin(); i != names.end(); ++i)
+ {
+ name += *i;
+ }
+ if(!addModule(m, name))
+ {
+ modulePrefixError(m, "");
+ }
+ }
+ }
+}
+
+StringList
+Slice::ObjCGenerator::MetaDataVisitor::getMetaData(const ContainedPtr& cont)
+{
+ StringList ret;
+ StringList localMetaData = cont->getMetaData();
+ StringList::const_iterator p;
+
+ for(p = localMetaData.begin(); p != localMetaData.end(); ++p)
+ {
+ if(p->find(_objcPrefix) != string::npos)
+ {
+ ret.push_back(*p);
+ }
+ }
+
+ return ret;
+}
+
+void
+Slice::ObjCGenerator::MetaDataVisitor::modulePrefixError(const ModulePtr& m, const string& metadata)
+{
+ string file = m->definitionContext()->filename();
+ string line = m->line();
+ ModulePrefix mp = modulePrefix(m);
+ string old_file = mp.m->definitionContext()->filename();
+ string old_line = mp.m->line();
+ ostringstream os;
+ if(!metadata.empty())
+ {
+ os << _msg << " `" << metadata << "': ";
+ }
+ os << "inconsistent module prefix previously defined ";
+ if(old_file != file)
+ {
+ os << "in " << old_file << ":";
+ }
+ else
+ {
+ os << "at line ";
+ }
+ os << line;
+ os << " as `" << mp.name << "'" << endl;
+ emitWarning(file, line, os.str());
+}
+
diff --git a/cpp/src/Slice/Preprocessor.cpp b/cpp/src/Slice/Preprocessor.cpp
index a5593065d1c..30b6d5c6948 100644
--- a/cpp/src/Slice/Preprocessor.cpp
+++ b/cpp/src/Slice/Preprocessor.cpp
@@ -622,6 +622,16 @@ Slice::Preprocessor::printMakefileDependencies(Language lang, const vector<strin
}
break;
}
+ case ObjC:
+ {
+ string::size_type pos = result.find(suffix);
+ if(pos != string::npos)
+ {
+ string name = result.substr(0, pos);
+ result.replace(0, pos + suffix.size() - 1, name + ".h " + name + ".m");
+ }
+ break;
+ }
default:
{
abort();
diff --git a/cpp/src/slice2objc/Gen.cpp b/cpp/src/slice2objc/Gen.cpp
new file mode 100644
index 00000000000..763f3f5661a
--- /dev/null
+++ b/cpp/src/slice2objc/Gen.cpp
@@ -0,0 +1,3139 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/DisableWarnings.h>
+#include <IceUtil/Functional.h>
+#include <Gen.h>
+#include <limits>
+#include <sys/stat.h>
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+#include <IceUtil/Iterator.h>
+#include <IceUtil/UUID.h>
+#include <Slice/Checksum.h>
+#include <Slice/FileTracker.h>
+#include <Slice/Util.h>
+#include <string.h>
+
+using namespace std;
+using namespace Slice;
+using namespace IceUtilInternal;
+
+namespace
+{
+
+string
+sliceModeToIceMode(Operation::Mode opMode)
+{
+ string mode;
+ switch(opMode)
+ {
+ case Operation::Normal:
+ {
+ mode = "ICENormal";
+ break;
+ }
+ case Operation::Nonmutating:
+ {
+ mode = "ICENonmutating";
+ break;
+ }
+ case Operation::Idempotent:
+ {
+ mode = "ICEIdempotent";
+ break;
+ }
+ default:
+ {
+ assert(false);
+ break;
+ }
+ }
+ return mode;
+}
+
+string
+opFormatTypeToString(const OperationPtr& op)
+{
+ switch(op->format())
+ {
+ case DefaultFormat:
+ {
+ return "ICEDefaultFormat";
+ break;
+ }
+ case CompactFormat:
+ {
+ return "ICECompactFormat";
+ break;
+ }
+ case SlicedFormat:
+ {
+ return "ICESlicedFormat";
+ break;
+ }
+ default:
+ {
+ assert(false);
+ }
+ }
+
+ return "???";
+}
+
+class SortParamDeclByTagFn
+{
+public:
+
+ static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs)
+ {
+ return lhs->tag() < rhs->tag();
+ }
+};
+
+}
+
+Slice::ObjCVisitor::ObjCVisitor(Output& h, Output& m) : _H(h), _M(m)
+{
+}
+
+Slice::ObjCVisitor::~ObjCVisitor()
+{
+}
+
+void
+Slice::ObjCVisitor::writeMarshalUnmarshalParams(const ParamDeclList& params, const OperationPtr& op, bool marshal,
+ bool reference)
+{
+ ParamDeclList optionals;
+ for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p)
+ {
+ if((*p)->optional())
+ {
+ optionals.push_back(*p);
+ }
+ else
+ {
+ string name = reference ? "*" + fixId((*p)->name()) : fixId((*p)->name());
+ writeMarshalUnmarshalCode(_M, (*p)->type(), name, marshal, true);
+ }
+ }
+ if(op && op->returnType())
+ {
+ if(!op->returnIsOptional())
+ {
+ writeMarshalUnmarshalCode(_M, op->returnType(), "ret_", marshal, true);
+ }
+ }
+
+ optionals.sort(SortParamDeclByTagFn::compare);
+ bool checkReturnType = op && op->returnIsOptional();
+ for(ParamDeclList::const_iterator p = optionals.begin(); p != optionals.end(); ++p)
+ {
+ if(checkReturnType && op->returnTag() < (*p)->tag())
+ {
+ writeOptParamMarshalUnmarshalCode(_M, op->returnType(), "ret_", op->returnTag(), marshal);
+ checkReturnType = false;
+ }
+ string name = reference ? "*" + fixId((*p)->name()) : fixId((*p)->name());
+ writeOptParamMarshalUnmarshalCode(_M, (*p)->type(), name, (*p)->tag(), marshal);
+ }
+ if(checkReturnType)
+ {
+ writeOptParamMarshalUnmarshalCode(_M, op->returnType(), "ret_", op->returnTag(), marshal);
+ }
+}
+
+void
+Slice::ObjCVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p)
+{
+ string name = fixName(p);
+ string scoped = p->scoped();
+ ClassList allBases = p->allBases();
+ StringList ids;
+
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped));
+
+ StringList other;
+ other.push_back(p->scoped());
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+
+ StringList::const_iterator firstIter = ids.begin();
+ StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), scoped);
+ assert(scopedIter != ids.end());
+ StringList::difference_type scopedPos = IceUtilInternal::distance(firstIter, scopedIter);
+
+ _M << sp << nl << "static NSString *" << name << "_ids__[] = ";
+ _M << sb;
+ {
+ StringList::const_iterator q = ids.begin();
+ while(q != ids.end())
+ {
+ _M << nl << "@\"" << *q << '"';
+ if(++q != ids.end())
+ {
+ _M << ',';
+ }
+ }
+ }
+ _M << eb << ";";
+
+ OperationList ops = p->operations();
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ assert(cl);
+
+ string opName = getName(op);
+ _M << sp << nl << "+(BOOL)" << op->name() << "___:(id<" << name << ">)target_ current:(ICECurrent *)current "
+ << "is:(id<ICEInputStream>)is_ os:(id<ICEOutputStream>)os_";
+ _M << sb;
+
+ _M << nl << "ICEInternalCheckModeAndSelector(target_, " << sliceModeToIceMode(op->mode()) << ", @selector(";
+ string selector = getSelector(op);
+ if(!selector.empty())
+ {
+ _M << selector << "current:";
+ }
+ else
+ {
+ _M << opName << ":";
+ }
+ _M << "), current);";
+
+ _M << nl << "ICEEncodingVersion* encoding = [is_ startEncapsulation];";
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if(!(*pli)->isOutParam())
+ {
+ inParams.push_back(*pli);
+ }
+ else
+ {
+ outParams.push_back(*pli);
+ }
+ }
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+ throws.sort(Slice::DerivedToBaseCompare());
+
+ for(ParamDeclList::const_iterator inp = inParams.begin(); inp != inParams.end(); ++inp)
+ {
+ TypePtr type = (*inp)->type();
+ string name = (*inp)->name();
+ _M << nl << outTypeToString(type, (*inp)->optional(), true) << " " << fixId(name);
+ if(!isValueType(type))
+ {
+ _M << " = nil";
+ }
+ _M << ";";
+ }
+ writeMarshalUnmarshalParams(inParams, 0, false);
+ if(op->sendsClasses(false))
+ {
+ _M << nl << "[is_ readPendingObjects];";
+ }
+ _M << nl << "[is_ endEncapsulation];";
+ if(!throws.empty())
+ {
+ _M << nl << "@try";
+ _M << sb;
+ }
+ for(ParamDeclList::const_iterator outp = outParams.begin(); outp != outParams.end(); ++outp)
+ {
+ TypePtr type = (*outp)->type();
+ string name = (*outp)->name();
+ _M << nl << inTypeToString(type, (*outp)->optional(), true) << " " << fixId(name);
+ if((*outp)->optional())
+ {
+ _M << " = ICENone";
+ }
+ _M << ";";
+ }
+ _M << nl << "[os_ startEncapsulation:encoding format:" << opFormatTypeToString(*r) << "];";
+ TypePtr returnType = op->returnType();
+ if(returnType)
+ {
+ _M << nl << inTypeToString(returnType, op->returnIsOptional(), true) << " ret_ = ";
+ }
+ else
+ {
+ _M << nl;
+ }
+ string args = getServerArgs(op);
+ _M << "[target_ " << opName << args;
+ if(!args.empty())
+ {
+ _M << " current";
+ }
+ _M << ":current];";
+ writeMarshalUnmarshalParams(outParams, op, true);
+ if(op->returnsClasses(false))
+ {
+ _M << nl << "[os_ writePendingObjects];";
+ }
+ if(!throws.empty())
+ {
+ _M << eb;
+ ExceptionList::const_iterator t;
+ for(t = throws.begin(); t != throws.end(); ++t)
+ {
+ string exS = fixName(*t);
+ _M << nl << "@catch(" << exS << " *ex)";
+ _M << sb;
+ _M << nl << "[os_ writeException:ex];";
+ _M << nl << "return NO;";
+ _M << eb;
+ }
+ _M << nl << "@finally";
+ _M << sb;
+ _M << nl << "[os_ endEncapsulation];";
+ _M << eb;
+ }
+ else
+ {
+ _M << nl << "[os_ endEncapsulation];";
+ }
+ _M << nl << "return YES;";
+ _M << eb;
+ }
+
+ OperationList allOps = p->allOperations();
+ if(!allOps.empty())
+ {
+ map<string, string> allOpNames;
+ for(OperationList::const_iterator p = allOps.begin(); p != allOps.end(); ++p)
+ {
+ allOpNames.insert(make_pair((*p)->name(), fixName(ClassDefPtr::dynamicCast((*p)->container()))));
+ }
+
+ allOpNames["ice_id"] = "ICEObject";
+ allOpNames["ice_ids"] = "ICEObject";
+ allOpNames["ice_isA"] = "ICEObject";
+ allOpNames["ice_ping"] = "ICEObject";
+
+ map<string, string>::const_iterator q;
+
+ _M << sp << nl << "static NSString *" << name << "_all__[] =";
+ _M << sb;
+ q = allOpNames.begin();
+ while(q != allOpNames.end())
+ {
+ _M << nl << "@\"" << q->first << '"';
+ if(++q != allOpNames.end())
+ {
+ _M << ',';
+ }
+ }
+ _M << eb << ';';
+
+ _M << sp << nl << "-(BOOL) dispatch__:(ICECurrent *)current is:(id<ICEInputStream>)is "
+ << "os:(id<ICEOutputStream>)os";
+ _M << sb;
+ _M << nl << "id target__ = [self target__];";
+ _M << nl << "switch(ICEInternalLookupString(" << name << "_all__, sizeof(" << name
+ << "_all__) / sizeof(NSString*), current.operation))";
+ _M << sb;
+ int i = 0;
+ for(q = allOpNames.begin(); q != allOpNames.end(); ++q)
+ {
+ _M << nl << "case " << i++ << ':';
+ _M.inc();
+ string target = (q->second == "ICEObject") ? "self" : "target__";
+ _M << nl << "return [" << q->second << " " << q->first << "___:(id<" << q->second
+ << ">)" << target << " current:current is:is os:os];";
+ _M.dec();
+ }
+ _M << nl << "default:";
+ _M.inc();
+ _M << nl << "@throw [ICEOperationNotExistException operationNotExistException:";
+ _M.useCurrentPosAsIndent();
+ _M << "__FILE__";
+ _M << nl << "line:__LINE__";
+ _M << nl << "id_:current.id_";
+ _M << nl << "facet:current.facet";
+ _M << nl << "operation:current.operation];";
+ _M.restoreIndent();
+ _M.dec();
+ _M << eb;
+ _M << eb;
+ }
+
+ _M << sp << nl << "+(NSString * const*) staticIds__:(int*)count idIndex:(int*)idx";
+ _M << sb;
+ _M << nl << "*count = sizeof(" << name << "_ids__) / sizeof(NSString *);";
+ _M << nl << "*idx = " << scopedPos << ";";
+ _M << nl << "return " << name << "_ids__;";
+ _M << eb;
+}
+
+string
+Slice::ObjCVisitor::getName(const OperationPtr& op) const
+{
+ if(!op->parameters().empty())
+ {
+ return fixId(op->name(), BaseTypeNone);
+ }
+ else
+ {
+ return fixId(op->name(), BaseTypeObject);
+ }
+}
+
+string
+Slice::ObjCVisitor::getSelector(const OperationPtr& op) const
+{
+ string result;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(q == paramList.begin())
+ {
+ result += getName(op) + ":";
+ }
+ else
+ {
+ result += fixId((*q)->name()) + ":";
+ }
+ }
+ return result;
+}
+
+string
+Slice::ObjCVisitor::getParams(const OperationPtr& op) const
+{
+ string result;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ typeString = outTypeToString(type, (*q)->optional(), false, true);
+ }
+ else
+ {
+ typeString = inTypeToString(type, (*q)->optional());
+ }
+ string name = fixId((*q)->name());
+ if(q != paramList.begin())
+ {
+ result += " " + name;
+ }
+ result += ":(" + typeString + ")" + name;
+ }
+ return result;
+}
+
+string
+Slice::ObjCVisitor::getMarshalParams(const OperationPtr& op) const
+{
+ ParamDeclList paramList = op->parameters();
+ string result;
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(!(*q)->isOutParam())
+ {
+ TypePtr type = (*q)->type();
+ string name = fixId((*q)->name());
+ if(!result.empty())
+ {
+ result += " " + name;
+ }
+ result += ":(" + inTypeToString(type, (*q)->optional()) + ")" + name;
+ }
+ }
+ return result;
+}
+
+string
+Slice::ObjCVisitor::getUnmarshalParams(const OperationPtr& op) const
+{
+ string result;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ TypePtr type = (*q)->type();
+ string name = fixId((*q)->name());
+ if(!result.empty())
+ {
+ result += " " + name;
+ }
+ result += ":(" + outTypeToString(type, (*q)->optional(), false, true) + ")" + name;
+ }
+ }
+ return result;
+}
+
+string
+Slice::ObjCVisitor::getServerParams(const OperationPtr& op) const
+{
+ string result;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ typeString = inTypeToString(type, (*q)->optional(), false, true);
+ }
+ else
+ {
+ typeString = outTypeToString(type, (*q)->optional());
+ }
+ string name = fixId((*q)->name());
+ if(q != paramList.begin())
+ {
+ result += " " + name;
+ }
+ result += ":(" + typeString + ")" + name;
+ }
+ return result;
+}
+
+string
+Slice::ObjCVisitor::getResponseCBSig(const OperationPtr& op) const
+{
+ string result;
+ TypePtr returnType = op->returnType();
+ if(returnType)
+ {
+ result = outTypeToString(returnType, op->returnIsOptional());
+ }
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ TypePtr type = (*q)->type();
+ string name = fixId((*q)->name());
+ if(!result.empty())
+ {
+ result += ", ";
+ }
+ result += outTypeToString(type, (*q)->optional());
+ }
+ }
+ return "void(^)(" + result + ")";
+}
+
+string
+Slice::ObjCVisitor::getArgs(const OperationPtr& op) const
+{
+ string result;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string name = fixId((*q)->name());
+ if(q != paramList.begin())
+ {
+ result += " " + name;
+ }
+ result += ":" + name;
+ }
+ return result;
+}
+
+string
+Slice::ObjCVisitor::getMarshalArgs(const OperationPtr& op) const
+{
+ string result;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(!(*q)->isOutParam())
+ {
+ string name = fixId((*q)->name());
+ if(!result.empty())
+ {
+ result += " " + name;
+ }
+ result += ":" + name;
+ }
+ }
+ return result;
+}
+
+string
+Slice::ObjCVisitor::getUnmarshalArgs(const OperationPtr& op) const
+{
+ string result;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ string name = fixId((*q)->name());
+ if(!result.empty())
+ {
+ result += " " + name;
+ }
+ result += ":" + name;
+ }
+ }
+ return result;
+}
+
+string
+Slice::ObjCVisitor::getServerArgs(const OperationPtr& op) const
+{
+ string result;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string name = fixId((*q)->name());
+ if(q != paramList.begin())
+ {
+ result += " " + name;
+ }
+ result += ":";
+ if((*q)->isOutParam())
+ {
+ result += "&";
+ }
+ result += name;
+ }
+ return result;
+}
+
+Slice::Gen::Gen(const string& name, const string& base, const string& include, const vector<string>& includePaths,
+ const string& dir)
+ : _base(base),
+ _include(include),
+ _includePaths(includePaths)
+{
+ for(vector<string>::iterator p = _includePaths.begin(); p != _includePaths.end(); ++p)
+ {
+ *p = fullPath(*p);
+ }
+
+ string::size_type pos = _base.find_last_of("/\\");
+ if(pos != string::npos)
+ {
+ _base.erase(0, pos + 1);
+ }
+
+ string fileH = _base + ".h";
+ string fileM = _base + ".m";
+ string fileImplH = _base + "I.h";
+ string fileImplM = _base + "I.m";
+
+ if(!dir.empty())
+ {
+ fileH = dir + '/' + fileH;
+ fileM = dir + '/' + fileM;
+ fileImplH = dir + '/' + fileImplH;
+ fileImplM = dir + '/' + fileImplM;
+ }
+
+ _H.open(fileH.c_str());
+ if(!_H)
+ {
+ ostringstream os;
+ os << "cannot open `" << fileH << "': " << strerror(errno);
+ throw FileException(__FILE__, __LINE__, os.str());
+ }
+ FileTracker::instance()->addFile(fileH);
+ printHeader(_H);
+ _H << nl << "// Generated from file `" << _base << ".ice'";
+
+ _H << sp << nl << "#import <objc/Ice/Config.h>";
+ _H << nl << "#import <objc/Ice/Proxy.h>";
+ _H << nl << "#import <objc/Ice/Object.h>";
+ _H << nl << "#import <objc/Ice/Current.h>";
+ _H << nl << "#import <objc/Ice/Exception.h>";
+ _H << nl << "#import <objc/Ice/Stream.h>";
+
+ _M.open(fileM.c_str());
+ if(!_M)
+ {
+ ostringstream os;
+ os << "cannot open `" << fileM << "': " << strerror(errno);
+ throw FileException(__FILE__, __LINE__, os.str());
+ }
+ FileTracker::instance()->addFile(fileM);
+ printHeader(_M);
+ _M << nl << "// Generated from file `" << _base << ".ice'";
+}
+
+Slice::Gen::~Gen()
+{
+ if(_H.isOpen())
+ {
+ _H << '\n';
+ _M << '\n';
+ }
+}
+
+bool
+Slice::Gen::operator!() const
+{
+ if(!_H || !_M)
+ {
+ return true;
+ }
+ return false;
+}
+
+void
+Slice::Gen::generate(const UnitPtr& p)
+{
+ ObjCGenerator::validateMetaData(p);
+
+ _M << nl << "\n#import <objc/Ice/LocalException.h>";
+ _M << nl << "#import <objc/Ice/Stream.h>";
+ if(p->hasContentsWithMetaData("preserve-slice"))
+ {
+ _H << "\n#import <objc/Ice/SlicedData.h>";
+ }
+ _M << nl << "#import <";
+ if(!_include.empty())
+ {
+ _M << _include << "/";
+ }
+ _M << _base << ".h>";
+
+ // Necessary for objc_getClass use when marshalling/unmarshalling proxies.
+ _M << nl << "#import <objc/runtime.h>";
+
+ _M << nl;
+
+ StringList includes = p->includeFiles();
+ for(StringList::const_iterator q = includes.begin(); q != includes.end(); ++q)
+ {
+ static const string headerDirPrefix = "objc:header-dir:";
+ DefinitionContextPtr dc = p->findDefinitionContext(*q);
+ assert(dc);
+ string meta = dc->findMetaData(headerDirPrefix);
+ string headerDir;
+ if(meta.size() > headerDirPrefix.size())
+ {
+ headerDir = meta.substr(headerDirPrefix.size());
+ }
+ _H << "\n#import <";
+ if(!headerDir.empty())
+ {
+ _H << headerDir << "/";
+ }
+ _H << changeInclude(*q, _includePaths) << ".h>";
+ }
+
+ UnitVisitor unitVisitor(_H, _M);
+ p->visit(&unitVisitor, false);
+
+ ObjectDeclVisitor objectDeclVisitor(_H, _M);
+ p->visit(&objectDeclVisitor, false);
+
+ ProxyDeclVisitor proxyDeclVisitor(_H, _M);
+ p->visit(&proxyDeclVisitor, false);
+
+ TypesVisitor typesVisitor(_H, _M);
+ p->visit(&typesVisitor, false);
+
+ ProxyVisitor proxyVisitor(_H, _M);
+ p->visit(&proxyVisitor, false);
+
+ DelegateMVisitor delegateMVisitor(_H, _M);
+ p->visit(&delegateMVisitor, false);
+
+ HelperVisitor HelperVisitor(_H, _M);
+ p->visit(&HelperVisitor, false);
+}
+
+void
+Slice::Gen::closeOutput()
+{
+ _H.close();
+ _M.close();
+}
+
+void
+Slice::Gen::printHeader(Output& o)
+{
+ static const char* header =
+"// **********************************************************************\n"
+"//\n"
+"// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.\n"
+"//\n"
+"// This copy of Ice is licensed to you under the terms described in the\n"
+"// ICE_LICENSE file included in this distribution.\n"
+"//\n"
+"// **********************************************************************\n"
+ ;
+
+ o << header;
+ o << "\n// Ice version " << ICE_STRING_VERSION;
+}
+
+Slice::Gen::UnitVisitor::UnitVisitor(Output& H, Output& M) :
+ ObjCVisitor(H, M)
+{
+}
+
+bool
+Slice::Gen::UnitVisitor::visitModuleStart(const ModulePtr& p)
+{
+ string dummy;
+ if(p->findMetaData("objc:prefix", dummy))
+ {
+ _prefixes.push_back(modulePrefix(p));
+ }
+ return true;
+}
+
+void
+Slice::Gen::UnitVisitor::visitUnitEnd(const UnitPtr& unit)
+{
+ string uuid = IceUtil::generateUUID();
+ for(string::size_type pos = 0; pos < uuid.size(); ++pos)
+ {
+ if(!isalnum(uuid[pos]))
+ {
+ uuid[pos] = '_';
+ }
+ }
+
+ if(!_prefixes.empty())
+ {
+ _M << sp << nl << "@implementation ICEInternalPrefixTable(C" << uuid << ")";
+ _M << nl << "-(void)addPrefixes_C" << uuid << ":(NSMutableDictionary*)prefixTable";
+ _M << sb;
+ for(vector<Slice::ObjCGenerator::ModulePrefix>::const_iterator p = _prefixes.begin(); p != _prefixes.end(); ++p)
+ {
+ _M << nl << "[prefixTable setObject:@\"" << p->name << "\" forKey:@\"" << p->m->scoped() << "\"];";
+ }
+ _M << eb;
+ _M << nl << "@end";
+ }
+}
+
+Slice::Gen::ObjectDeclVisitor::ObjectDeclVisitor(Output& H, Output& M)
+ : ObjCVisitor(H, M)
+{
+}
+
+void
+Slice::Gen::ObjectDeclVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ _H << sp << nl << "@class " << fixName(p) << ";";
+ _H << nl << "@protocol " << fixName(p) << ";";
+}
+
+Slice::Gen::ProxyDeclVisitor::ProxyDeclVisitor(Output& H, Output& M)
+ : ObjCVisitor(H, M)
+{
+}
+
+void
+Slice::Gen::ProxyDeclVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ _H << sp << nl << "@class " << fixName(p) << "Prx;";
+ _H << nl << "@protocol " << fixName(p) << "Prx;";
+}
+
+Slice::Gen::TypesVisitor::TypesVisitor(Output& H, Output& M)
+ : ObjCVisitor(H, M)
+{
+}
+
+bool
+Slice::Gen::TypesVisitor::visitModuleStart(const ModulePtr& p)
+{
+ string suffix;
+ StringList names = splitScopedName(p->scoped());
+ for(StringList::const_iterator i = names.begin(); i != names.end(); ++i)
+ {
+ if(i != names.begin())
+ {
+ suffix += "_";
+ }
+ suffix += *i;
+ }
+ string symbol = "ICE_MODULE_PREFIX_";
+ symbol += suffix;
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitModuleEnd(const ModulePtr&)
+{
+}
+
+bool
+Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string name = fixName(p);
+ ClassList bases = p->bases();
+
+ _H << sp << nl << "@protocol " << name;
+ if(!bases.empty())
+ {
+ _H << " <";
+ for(ClassList::const_iterator i = bases.begin(); i != bases.end(); ++i)
+ {
+ string baseName = fixName(*i);
+ if(i != bases.begin())
+ {
+ _H << ", ";
+ }
+ _H << baseName;
+ }
+ _H << ">";
+ }
+
+ _M << sp << nl << "@implementation " << name;
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ string name = fixName(p);
+ ClassList bases = p->bases();
+ bool basePreserved = p->inheritsMetaData("preserve-slice");
+ bool preserved = p->hasMetaData("preserve-slice");
+ bool hasBaseClass = !bases.empty() && !bases.front()->isInterface();
+ string baseName = hasBaseClass ? fixName(bases.front()) : "ICEObject";
+ DataMemberList baseDataMembers;
+ if(hasBaseClass)
+ {
+ baseDataMembers = bases.front()->allDataMembers();
+ }
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList optionalMembers = p->orderedOptionalDataMembers();
+ DataMemberList allDataMembers = p->allDataMembers();
+
+ _H << nl << "@end";
+
+ _H << sp << nl << "@interface " << name << " : " << baseName;
+
+ if(!dataMembers.empty() || (preserved && !basePreserved))
+ {
+ //
+ // Data member declarations.
+ //
+ _H << sb;
+
+ if(!dataMembers.empty())
+ {
+ writeMembers(dataMembers, BaseTypeObject);
+ }
+
+ if(preserved && !basePreserved)
+ {
+ _H << nl << "id<ICESlicedData> slicedData__;";
+ }
+
+ _H << eb;
+ _H << sp;
+
+ _M << sp;
+ }
+
+ //
+ // @property and @synthesize for each data member.
+ //
+ writeProperties(dataMembers, BaseTypeObject);
+ writeSynthesize(dataMembers, BaseTypeObject);
+
+ //
+ // Constructor.
+ //
+ if(!dataMembers.empty())
+ {
+ _H << sp;
+ }
+ if(!p->isInterface() && !dataMembers.empty())
+ {
+ if(p->hasDefaultValues())
+ {
+ _H << nl << "-(id) init;";
+ _M << sp << nl << "-(id) init";
+ _M << sb;
+ _M << nl << "self = [super init];";
+ _M << nl << "if(!self)";
+ _M << sb;
+ _M << nl << "return nil;";
+ _M << eb;
+ writeMemberDefaultValueInit(dataMembers, BaseTypeObject);
+ _M << nl << "return self;";
+ _M << eb;
+ }
+ _H << nl << "-(id) init";
+ _M << sp << nl << "-(id) init";
+ writeMemberSignature(allDataMembers, BaseTypeObject, Other);
+ _H << ";";
+ _M << sb;
+ _M << nl << "self = [super init";
+ writeMemberCall(baseDataMembers, BaseTypeObject, Other, WithEscape);
+ _M << "];";
+ _M << nl << "if(!self)";
+ _M << sb;
+ _M << nl << "return nil;";
+ _M << eb;
+ writeMemberInit(dataMembers, BaseTypeObject);
+ _M << nl << "return self;";
+ _M << eb;
+ }
+
+ //
+ // Convenience constructors.
+ //
+ if(!allDataMembers.empty())
+ {
+ string lowerCaseName = fixId(p->name());
+ *(lowerCaseName.begin()) = tolower(*lowerCaseName.begin());
+
+ _H << nl << "+(id) " << lowerCaseName;
+ _M << sp << nl << "+(id) " << lowerCaseName;
+ writeMemberSignature(allDataMembers, BaseTypeObject, Other);
+ _H << ";";
+ _M << sb;
+
+ //
+ // The cast avoids a compiler warning that is emitted if different structs
+ // have members with the same name but different types.
+ //
+ _M << nl << name << " *s__ = [(" << name << " *)[" << name << " alloc] init";
+ writeMemberCall(allDataMembers, BaseTypeObject, Other, WithEscape);
+ _M << "];";
+
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && !__has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "[s__ autorelease];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+
+ _M << nl << "return s__;";
+ _M << eb;
+
+ _H << nl << "+(id) " << lowerCaseName << ";";
+ _M << sp << nl << "+(id) " << lowerCaseName;
+ _M << sb;
+ _M << nl << name << " *s__ = [[" << name << " alloc] init];";
+
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && !__has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "[s__ autorelease];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+
+ _M << nl << "return s__;";
+ _M << eb;
+ }
+
+ if(!p->isInterface())
+ {
+ //
+ // copyWithZone and dealloc
+ //
+ if(!dataMembers.empty())
+ {
+ _M << sp << nl << "-(id) copyWithZone:(NSZone *)zone_p";
+ _M << sb;
+ _M << nl << "return [(" << name << " *)[[self class] allocWithZone:zone_p] init";
+ writeMemberCall(allDataMembers, BaseTypeObject, Other, NoEscape);
+ _M << "];";
+ _M << eb;
+ _H << nl << "// This class also overrides copyWithZone:.";
+
+ writeMemberDealloc(dataMembers, BaseTypeObject, preserved && !basePreserved);
+ }
+ }
+
+ //
+ // Setter, has, clear selectors for optionals
+ //
+ writeOptionalDataMemberSelectors(dataMembers, BaseTypeObject);
+
+ //
+ // If the class uses a compact id we generate a +load method to register the compact id
+ // with the compact id resolver.
+ //
+ if(p->compactId() >= 0)
+ {
+ _M << sp << nl << "+(void) load";
+ _M << sb;
+ _M << nl << "[CompactIdMapHelper registerClass:@\"" << p->scoped() << "\" value:" << p->compactId() << "];";
+ _M << eb;
+ }
+
+ //
+ // Operations
+ //
+ OperationList ops = p->operations();
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ _H << nl << "+(BOOL)" << op->name() << "___:(id<" << name
+ << ">)target current:(ICECurrent *)current "
+ << "is:(id<ICEInputStream>)is_ os:(id<ICEOutputStream>)os_;";
+ }
+
+ _M << sp << nl << "+(id)objectWithDelegate:(id)delegate";
+ _M << sb;
+ _M.zeroIndent();
+ _M << sp << nl << "#if defined(__clang__) && __has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "return [[" << name << " alloc] initWithDelegate:delegate];";
+ _M.zeroIndent();
+ _M << nl << "#else";
+ _M.restoreIndent();
+ _M << nl << "return [[[" << name << " alloc] initWithDelegate:delegate] autorelease];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ _M << eb;
+
+ //
+ // Marshaling/unmarshaling
+ //
+
+ _M << sp << nl << "-(void) writeImpl__:(id<ICEOutputStream>)os_";
+ _M << sb;
+ _M << nl << "[os_ startSlice:@\"" << p->scoped() << "\" compactId: " << p->compactId() << " lastSlice:"
+ << (!hasBaseClass ? "YES" : "NO") << "];";
+ writeMemberMarshal(dataMembers, optionalMembers, BaseTypeObject);
+ _M << nl << "[os_ endSlice];";
+ if(hasBaseClass)
+ {
+ _M << nl << "[super writeImpl__:os_];";
+ }
+ _M << eb;
+
+ _H << nl << "@end";
+
+ _M << sp << nl << "-(void) readImpl__:(id<ICEInputStream>)is_";
+ _M << sb;
+ _M << nl << "[is_ startSlice];";
+ writeMemberUnmarshal(dataMembers, optionalMembers, BaseTypeObject);
+ _M << nl << "[is_ endSlice];";
+ if(hasBaseClass)
+ {
+ _M << nl << "[super readImpl__:is_];";
+ }
+ _M << eb;
+
+ writeDispatchAndMarshalling(p);
+
+ if(preserved && !basePreserved)
+ {
+ _M << nl << "-(void) write__:(id<ICEOutputStream>)os";
+ _M << sb;
+ _M << nl << "[os startObject:slicedData__];";
+ _M << nl << "[self writeImpl__:os];";
+ _M << nl << "[os endObject];";
+ _M << eb;
+
+ _M << nl << "-(void) read__:(id<ICEInputStream>)is";
+ _M << sb;
+ _M << nl << "[is startObject];";
+ _M << nl << "[self readImpl__:is];";
+ _M << nl << "slicedData__ = [is endObject:YES];";
+ _M << eb;
+ }
+
+ _M << nl << "@end";
+}
+
+void
+Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = getName(p);
+ TypePtr returnType = p->returnType();
+ string retString = typeToString(returnType);
+ string params = getServerParams(p);
+
+
+ _H << nl << "-(" << inTypeToString(returnType, p->returnIsOptional()) << ") " << name << params;
+ if(!params.empty())
+ {
+ _H << " current";
+ }
+ _H << ":(ICECurrent *)current;";
+}
+
+void
+Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
+{
+ string prefix = moduleName(findModule(p));
+ string name = fixName(p);
+
+ if(isValueType(p->type()))
+ {
+ _H << sp << nl << "typedef NSData " << name << ";";
+ _H << nl << "typedef NSMutableData " << prefix << "Mutable" << p->name() << ";";
+ }
+ else
+ {
+ _H << sp << nl << "typedef NSArray " << name << ";";
+ _H << nl << "typedef NSMutableArray " << prefix << "Mutable" << p->name() << ";";
+ }
+}
+
+bool
+Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ string name = fixName(p);
+ ExceptionPtr base = p->base();
+ DataMemberList dataMembers = p->dataMembers();
+ bool basePreserved = p->inheritsMetaData("preserve-slice");
+ bool preserved = p->hasMetaData("preserve-slice");
+
+ _H << sp;
+
+ _H << nl << "@interface " << name << " : ";
+ if(base)
+ {
+ _H << fixName(base);
+ }
+ else
+ {
+ _H << (p->isLocal() ? "ICELocalException" : "ICEUserException");
+ }
+ if(!dataMembers.empty() || (preserved && !basePreserved))
+ {
+ _H << sb;
+ }
+
+ _M << sp << nl << "@implementation " << name;
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
+{
+ string name = fixName(p);
+
+ string lowerCaseName = fixId(p->name());
+ *(lowerCaseName.begin()) = tolower(*lowerCaseName.begin());
+ bool basePreserved = p->inheritsMetaData("preserve-slice");
+ bool preserved = p->hasMetaData("preserve-slice");
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList optionalMembers = p->orderedOptionalDataMembers();
+ DataMemberList allDataMembers = p->allDataMembers();
+ DataMemberList::const_iterator q;
+
+ DataMemberList baseDataMembers;
+ if(p->base())
+ {
+ baseDataMembers = p->base()->allDataMembers();
+ }
+
+ if(!dataMembers.empty() || (preserved && !basePreserved))
+ {
+ //
+ // Data member declarations.
+ //
+ if(!dataMembers.empty())
+ {
+ writeMembers(dataMembers, BaseTypeException);
+ }
+
+ if(preserved && !basePreserved)
+ {
+ _H << nl << "id<ICESlicedData> slicedData__;";
+ }
+
+ _H << eb;
+ _H << sp;
+ _M << sp;
+
+ //
+ // @property and @synthesize for each data member.
+ //
+ if(!dataMembers.empty())
+ {
+ writeProperties(dataMembers, BaseTypeException);
+ writeSynthesize(dataMembers, BaseTypeException);
+ }
+ _H << sp;
+ }
+
+ //
+ // ice_name
+ //
+ _H << nl << "-(NSString *) ice_name;";
+ _M << sp << nl << "-(NSString *) ice_name";
+ _M << sb;
+ _M << nl << "return @\"" << p->scoped().substr(2) << "\";";
+ _M << eb;
+
+ //
+ // Constructors.
+ //
+ if(p->isLocal() && !dataMembers.empty())
+ {
+ _H << nl << "-(id) init:(const char*)file__p line:(int)line__p;";
+ _M << sp << nl << "-(id) init:(const char*)file__p line:(int)line__p";
+ _M << sb;
+ _M << nl << "self = [super init:file__p line:line__p];";
+ _M << nl << "if(!self)";
+ _M << sb;
+ _M << nl << "return nil;";
+ _M << eb;
+ _M << nl << "return self;";
+ _M << eb;
+ }
+ if(!dataMembers.empty())
+ {
+ if(!p->base() || p->hasDefaultValues())
+ {
+ _H << sp << nl << "-(id) init;";
+ _M << sp << nl << "-(id) init";
+ _M << sb;
+ _M << nl << "self = ";
+ if(!p->base())
+ {
+ _M << "[super initWithName:[self ice_name] reason:nil userInfo:nil];";
+ }
+ else
+ {
+ _M << nl << "[super init];";
+ }
+ _M << nl << "if(!self)";
+ _M << sb;
+ _M << nl << "return nil;";
+ _M << eb;
+ if(p->hasDefaultValues())
+ {
+ writeMemberDefaultValueInit(dataMembers, BaseTypeObject);
+ }
+ _M << nl << "return self;";
+ _M << eb;
+ }
+
+ _H << nl << "-(id) init";
+ _M << sp << nl << "-(id) init";
+ writeMemberSignature(allDataMembers, BaseTypeException, p->isLocal() ? LocalException : Other);
+ _H << ";";
+ _M << sb;
+ _M << nl << "self = ";
+ if(!p->base())
+ {
+ _M << nl << "[super initWithName:[self ice_name] reason:nil userInfo:nil];";
+ }
+ else
+ {
+ _M << nl << "[super init";
+ if(p->isLocal())
+ {
+ _M << ":file__p line:line__p ";
+ }
+ writeMemberCall(baseDataMembers, BaseTypeException, p->isLocal() ? LocalException : Other, WithEscape);
+ _M << "];";
+ }
+ _M << nl << "if(!self)";
+ _M << sb;
+ _M << nl << "return nil;";
+ _M << eb;
+ if(!dataMembers.empty())
+ {
+ writeMemberInit(dataMembers, BaseTypeException);
+ }
+ _M << nl << "return self;";
+ _M << eb;
+ }
+
+ //
+ // Convenience constructors.
+ //
+ _H << nl << "+(id) " << lowerCaseName;
+ _M << sp << nl << "+(id) " << lowerCaseName;
+ writeMemberSignature(allDataMembers, BaseTypeException, p->isLocal() ? LocalException : Other);
+ _H << ";";
+
+ //
+ // The cast avoids a compiler warning that is emitted if different exceptions
+ // have members with the same name but different types.
+ //
+ _M << sb;
+ _M << nl << name << " *s__ = [(" << name << " *)[" << name << " alloc] init";
+ if(p->isLocal())
+ {
+ _M << ":file__p line:line__p";
+ }
+ writeMemberCall(allDataMembers, BaseTypeException, p->isLocal() ? LocalException : Other, WithEscape);
+ _M << "];";
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && !__has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "[s__ autorelease];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ _M << nl << "return s__;";
+ _M << eb;
+
+ if(!allDataMembers.empty())
+ {
+ _H << nl << "+(id) " << lowerCaseName;
+ _M << sp << nl << "+(id) " << lowerCaseName;
+ if(p->isLocal())
+ {
+ _H << ":(const char*)file__p line:(int)line__p";
+ _M << ":(const char*)file__p line:(int)line__p";
+ }
+ _H << ";";
+ _M << sb;
+ _M << nl << name << " *s__ = [[" << name << " alloc] init";
+ if(p->isLocal())
+ {
+ _M << ":file__p line:line__p";
+ }
+ _M << "];";
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && !__has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "[s__ autorelease];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ _M << nl << "return s__;";
+ _M << eb;
+ }
+
+ //
+ // copyWithZone and dealloc
+ //
+ if(!dataMembers.empty())
+ {
+ _M << sp << nl << "-(id) copyWithZone:(NSZone *)zone_p";
+ _M << sb;
+ _M << nl << "return [(" << name << " *)[[self class] allocWithZone:zone_p] init";
+ if(p->isLocal())
+ {
+ _M << ":file line:line";
+ }
+ writeMemberCall(allDataMembers, BaseTypeException, p->isLocal() ? LocalException : Other, NoEscape);
+ _M << "];";
+ _M << eb;
+ _H << nl << "// This class also overrides copyWithZone:.";
+
+ writeMemberDealloc(dataMembers, BaseTypeException, preserved && !basePreserved);
+ }
+
+ //
+ // Setter, has, clear selectors for optionals
+ //
+ writeOptionalDataMemberSelectors(dataMembers, BaseTypeObject);
+
+ //
+ // Marshaling/unmarshaling
+ //
+ ExceptionPtr base = p->base();
+ if(!p->allClassDataMembers().empty())
+ {
+ if(!base || (base && !base->usesClasses(false)))
+ {
+ _M << sp << nl << "-(BOOL) usesClasses__";
+ _M << sb;
+ _M << nl << "return YES;";
+ _M << eb;
+ }
+ }
+
+ if(!p->isLocal())
+ {
+ _M << sp << nl << "-(void) writeImpl__:(id<ICEOutputStream>)os_";
+ _M << sb;
+ _M << nl << "[os_ startSlice:@\"" << p->scoped() << "\" compactId:-1 lastSlice:"
+ << (!base ? "YES" : "NO") << "];";
+ writeMemberMarshal(dataMembers, optionalMembers, BaseTypeException);
+ _M << nl << "[os_ endSlice];";
+ if(base)
+ {
+ _M << nl << "[super writeImpl__:os_];";
+ }
+ _M << eb;
+
+ _M << sp << nl << "-(void) readImpl__:(id<ICEInputStream>)is_";
+ _M << sb;
+ _M << nl << "[is_ startSlice];";
+ writeMemberUnmarshal(dataMembers, optionalMembers, BaseTypeException);
+ _M << nl << "[is_ endSlice];";
+ if(base)
+ {
+ _M << nl << "[super readImpl__:is_];";
+ }
+ _M << eb;
+
+ if(preserved && !basePreserved)
+ {
+ _M << nl << nl << "-(void) write__:(id<ICEOutputStream>)os";
+ _M << sb;
+ _M << nl << "[os startException:slicedData__];";
+ _M << nl << "[self writeImpl__:os];";
+ _M << nl << "[os endException];";
+ _M << eb;
+
+ _M << nl << nl << "-(void) read__:(id<ICEInputStream>)is";
+ _M << sb;
+ _M << nl << "[is startException];";
+ _M << nl << "[self readImpl__:is];";
+ _M << nl << "slicedData__ = [is endException:YES];";
+ _M << eb;
+ }
+ }
+
+ _H << nl << "@end";
+ _M << nl << "@end";
+}
+
+bool
+Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
+{
+ string name = fixName(p);
+
+ _H << sp;
+
+ _H << nl << "@interface " << name << " : NSObject <NSCopying>";
+ _H << sb;
+ _H << nl << "@private";
+ _H.inc();
+
+ _M << sp << nl << "@implementation " << name << sp;
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
+{
+ string name = fixName(p);
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList::const_iterator q;
+
+ //
+ // Data member declarations.
+ //
+ writeMembers(dataMembers, BaseTypeObject);
+
+ _H.dec();
+ _H << eb;
+
+ _H << sp;
+
+ //
+ // @property and @synthesize for each data member.
+ //
+ writeProperties(dataMembers, BaseTypeObject);
+ writeSynthesize(dataMembers, BaseTypeObject);
+
+ //
+ // Constructor.
+ //
+ if(p->hasDefaultValues())
+ {
+ _H << sp << nl << "-(id) init;";
+ _M << sp << nl << "-(id) init";
+ _M << sb;
+ _M << nl << "self = [super init];";
+ _M << nl << "if(!self)";
+ _M << sb;
+ _M << nl << "return nil;";
+ _M << eb;
+ writeMemberDefaultValueInit(dataMembers, BaseTypeObject);
+ _M << nl << "return self;";
+ _M << eb;
+ }
+ _H << sp << nl << "-(id) init";
+ _M << sp << nl << "-(id) init";
+ writeMemberSignature(dataMembers, BaseTypeObject, Other);
+ _H << ";";
+ _M << sb;
+ _M << nl << "self = [super init];";
+ _M << nl << "if(!self)";
+ _M << sb;
+ _M << nl << "return nil;";
+ _M << eb;
+ writeMemberInit(dataMembers, BaseTypeObject);
+ _M << nl << "return self;";
+ _M << eb;
+
+ //
+ // Convenience constructor.
+ //
+ string lowerCaseName = fixId(p->name());
+ *(lowerCaseName.begin()) = tolower(*lowerCaseName.begin());
+
+ _H << nl << "+(id) " << lowerCaseName;
+ _M << sp << nl << "+(id) " << lowerCaseName;
+ writeMemberSignature(dataMembers, BaseTypeObject, Other);
+ _H << ";";
+ _M << sb;
+
+ //
+ // The cast avoids a compiler warning that is emitted if different structs
+ // have members with the same name but different types.
+ //
+ _M << nl << name << " *s__ = [(" << name << "* )[" << name << " alloc] init";
+ writeMemberCall(dataMembers, BaseTypeObject, Other, WithEscape);
+ _M << "];";
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && !__has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "[s__ autorelease];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ _M << nl << "return s__;";
+ _M << eb;
+
+ _H << nl << "+(id) " << lowerCaseName << ";";
+ _M << sp << nl << "+(id) " << lowerCaseName;
+ _M << sb;
+ _M << nl << name << " *s__ = [[" << name << " alloc] init];";
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && !__has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "[s__ autorelease];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ _M << nl << "return s__;";
+ _M << eb;
+
+ //
+ // copyWithZone
+ //
+ _M << sp << nl << "-(id) copyWithZone:(NSZone *)zone_p";
+ _M << sb;
+ _M << nl << "return [(" << name << " *)[[self class] allocWithZone:zone_p] init";
+ writeMemberCall(dataMembers, BaseTypeObject, Other, NoEscape);
+ _M << "];";
+ _M << eb;
+
+ //
+ // hash
+ //
+ writeMemberHashCode(dataMembers, BaseTypeObject);
+
+ //
+ // isEqual
+ //
+ _M << sp << nl << "-(BOOL) isEqual:(id)o_";
+ _M << sb;
+ _M << nl << "if(self == o_)";
+ _M << sb;
+ _M << nl << "return YES;";
+ _M << eb;
+ _M << nl << "if(!o_ || ![o_ isKindOfClass:[self class]])";
+ _M << sb;
+ _M << nl << "return NO;";
+ _M << eb;
+ writeMemberEquals(dataMembers, BaseTypeObject);
+ _M << eb;
+
+ _H << nl << "// This class also overrides copyWithZone:, hash, and isEqual:";
+
+ //
+ // dealloc
+ //
+ writeMemberDealloc(dataMembers, BaseTypeObject);
+
+ //
+ // Marshaling/unmarshaling
+ //
+ _H << nl << "-(void) write__:(id<ICEOutputStream>)os_;";
+ _H << nl << "-(void) read__:(id<ICEInputStream>)is_;";
+
+ _M << sp << nl << "-(void) write__:(id<ICEOutputStream>)os_";
+ _M << sb;
+ writeMemberMarshal(dataMembers, DataMemberList(), BaseTypeObject);
+ _M << eb;
+
+ _M << sp << nl << "-(void) read__:(id<ICEInputStream>)is_";
+ _M << sb;
+ writeMemberUnmarshal(dataMembers, DataMemberList(), BaseTypeObject);
+ _M << eb;
+
+ _H << nl << "@end";
+ _M << nl << "@end";
+}
+
+void
+Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ string prefix = moduleName(findModule(p));
+ string name = fixName(p);
+
+ _H << sp << nl << "typedef NSDictionary " << name << ";";
+ _H << nl << "typedef NSMutableDictionary " << prefix << "Mutable" << p->name() << ";";
+}
+
+void
+Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
+{
+ string name = fixName(p);
+ EnumeratorList enumerators = p->getEnumerators();
+ _H << sp;
+
+ //
+ // Check if any of the enumerators were assigned an explicit value.
+ //
+ const bool explicitValue = p->explicitValue();
+
+ _H << nl << "typedef enum : ICEInt";
+ _H << sb;
+ EnumeratorList::const_iterator en = enumerators.begin();
+ while(en != enumerators.end())
+ {
+ _H << nl << fixName(*en);
+ //
+ // If any of the enumerators were assigned an explicit value, we emit
+ // an explicit value for *all* enumerators.
+ //
+ if(explicitValue)
+ {
+ _H << " = " << int64ToString((*en)->value());
+ }
+ if(++en != enumerators.end())
+ {
+ _H << ',';
+ }
+ }
+ _H << eb << " " << name << ";";
+}
+
+void
+Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p)
+{
+ _H << sp;
+ if(isString(p->type()))
+ {
+ _H << nl << "static NSString * const";
+ }
+ else
+ {
+ _H << nl << "static const " << typeToString(p->type());
+ }
+ _H << " " << fixName(p) << " = ";
+ writeConstantValue(_H, p->type(), p->value());
+ _H << ';';
+}
+
+void
+Slice::Gen::TypesVisitor::writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const string& val) const
+{
+ if(isString(type))
+ {
+ //
+ // Expand strings into the basic source character set. We can't use isalpha() and the like
+ // here because they are sensitive to the current locale.
+ //
+ static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ "_{}[]#()<>%:;.?*+-/^&|~!=,\\\"' ";
+ static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end());
+
+ out << "@\""; // Opening @"
+
+ for(string::const_iterator c = val.begin(); c != val.end(); ++c)
+ {
+ if(charSet.find(*c) == charSet.end())
+ {
+ unsigned char uc = *c; // char may be signed, so make it positive
+ ostringstream s;
+ s << "\\"; // Print as octal if not in basic source character set
+ s.width(3);
+ s.fill('0');
+ s << oct;
+ s << static_cast<unsigned>(uc);
+ out << s.str();
+ }
+ else
+ {
+ out << *c; // Print normally if in basic source character set
+ }
+ }
+
+ out << "\""; // Closing "
+ }
+ else
+ {
+ EnumPtr ep = EnumPtr::dynamicCast(type);
+ if(ep)
+ {
+ out << moduleName(findModule(ep)) << val;
+ }
+ else
+ {
+ if(val == "true")
+ {
+ out << "YES";
+ }
+ else if(val == "false")
+ {
+ out << "NO";
+ }
+ else
+ {
+ out << val;
+ }
+ }
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeMembers(const DataMemberList& dataMembers, int baseType) const
+{
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string name = fixId((*q)->name(), baseType);
+
+ _H << nl << typeToString(type) << " ";
+ if(mapsToPointerType(type))
+ {
+ _H << "*";
+ }
+ _H << name << ";";
+
+ if((*q)->optional())
+ {
+ _H << nl << "BOOL has_" << name << "__;";
+ }
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberSignature(const DataMemberList& dataMembers, int baseType,
+ ContainerType ct) const
+{
+ if(ct == LocalException)
+ {
+ _H << ":(const char*)file__p line:(int)line__p";
+ _M << ":(const char*)file__p line:(int)line__p";
+ }
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string typeString = inTypeToString(type, (*q)->optional());
+ string name = fixId((*q)->name(), baseType);
+
+ if(q != dataMembers.begin() || ct == LocalException)
+ {
+ _H << " " << name;
+ _M << " " << name;
+ }
+ _H << ":(" << typeString << ")" << fixId((*q)->name());
+ _M << ":(" << typeString << ")" << fixId((*q)->name()) << "_p";
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberCall(const DataMemberList& dataMembers, int baseType,
+ ContainerType ct, Escape esc) const
+{
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string name = (*q)->name();
+
+ if(q != dataMembers.begin() || ct == LocalException)
+ {
+ _M << " " << fixId(name, baseType);
+ }
+
+ name = esc == NoEscape ? fixId(name, baseType) : fixId(name);
+ if(esc == NoEscape)
+ {
+ if((*q)->optional())
+ {
+ if(isValueType((*q)->type()))
+ {
+ _M << ":" << "(self->has_" << name << "__ ? @(self->" << name << ") : ICENone)";
+ }
+ else
+ {
+ _M << ":" << "(self->has_" << name << "__ ? self->" << name << " : ICENone)";
+ }
+ }
+ else
+ {
+ _M << ":" << name;
+ }
+ }
+ else
+ {
+ _M << ":" << name << "_p";
+ }
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberDefaultValueInit(const DataMemberList& dataMembers, int baseType) const
+{
+ for(DataMemberList::const_iterator p = dataMembers.begin(); p != dataMembers.end(); ++p)
+ {
+ if((*p)->defaultValueType())
+ {
+ string name = fixId((*p)->name(), baseType);
+ if((*p)->optional())
+ {
+ _M << nl << "self->has_" << name << "__ = YES;";
+ }
+ _M << nl << "self->" << name << " = ";
+ writeConstantValue(_M, (*p)->type(), (*p)->defaultValue());
+ _M << ";";
+ }
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberInit(const DataMemberList& dataMembers, int baseType) const
+{
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string name = fixId((*q)->name());
+ if((*q)->optional())
+ {
+ if(isValueType(type))
+ {
+ _M << nl << "self->has_" << name << "__ = [ICEOptionalGetter " << getOptionalHelperGetter(type) << ":";
+ _M << name << "_p value:&self->" << fixId((*q)->name(), baseType) << "];";
+ }
+ else
+ {
+ _M << nl << "self->has_" << name << "__ = [ICEOptionalGetter getRetained:";
+ _M << name << "_p value:&self->" << fixId((*q)->name(), baseType);
+ _M << " type:[" << typeToObjCTypeString(type) << " class]];";
+ }
+ }
+ else
+ {
+ if(isValueType(type))
+ {
+ _M << nl << "self->" << fixId((*q)->name(), baseType) << " = " << name << "_p;";
+ }
+ else
+ {
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && __has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "self->" << fixId((*q)->name(), baseType) << " = " << name << "_p;";
+ _M.zeroIndent();
+ _M << nl << "#else";
+ _M.restoreIndent();
+ _M << nl << "self->" << fixId((*q)->name(), baseType) << " = [" << name << "_p retain];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ }
+ }
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeProperties(const DataMemberList& dataMembers, int baseType) const
+{
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string name = fixId((*q)->name(), baseType);
+
+ string typeString = typeToString(type);
+ bool isValue = isValueType(type);
+
+ _H << nl << "@property(nonatomic, ";
+ if(isValue)
+ {
+ _H << "assign";
+ }
+ else
+ {
+ _H << "ICE_STRONG_ATTR";
+ }
+ _H << ") " << typeString << " ";
+ if(mapsToPointerType(type))
+ {
+ _H << "*";
+ }
+ _H << name << ";";
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeSynthesize(const DataMemberList& dataMembers, int baseType) const
+{
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string name = fixId((*q)->name(), baseType);
+ _M << nl << "@synthesize " << name << ";";
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeOptionalDataMemberSelectors(const DataMemberList& dataMembers, int baseType) const
+{
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if(!(*q)->optional())
+ {
+ continue;
+ }
+
+ TypePtr type = (*q)->type();
+ string typeString = inTypeToString(type, false);
+
+ string name = fixId((*q)->name(), baseType);
+
+ string capName = (*q)->name();
+ capName[0] = toupper(static_cast<unsigned char>(capName[0]));
+
+ _H << nl << "-(void)set" << capName << ":(" << typeString << ")" << name << "_p;";
+
+ _M << nl << "-(void)set" << capName << ":(" << typeString << ")" << name << "_p";
+ _M << sb;
+ _M << nl << "self->has_" << name << "__ = YES;";
+ bool isValue = isValueType(type);
+ if(isValue)
+ {
+ _M << nl << "self->" << name << " = " << name << "_p;";
+ }
+ else
+ {
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && __has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "self->" << name << " = " << name << "_p;";
+ _M.zeroIndent();
+ _M << nl << "#else";
+ _M.restoreIndent();
+ _M << nl << "[self->" << name << " release];";
+ _M << nl << "self->" << name << " = [" << name << "_p retain];";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ }
+ _M << eb;
+
+ _H << nl << "-(BOOL)has" << capName << ";";
+ _M << nl << "-(BOOL)has" << capName;
+ _M << sb;
+ _M << nl << "return self->has_" << name << "__;";
+ _M << eb;
+
+ _H << nl << "-(void)clear" << capName << ";";
+ _M << nl << "-(void)clear" << capName;
+ _M << sb;
+ _M << nl << "self->has_" << name << "__ = NO;";
+ if(!isValue)
+ {
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && __has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "self->" << name << " = nil;";
+ _M.zeroIndent();
+ _M << nl << "#else";
+ _M.restoreIndent();
+ _M << nl << "[self->" << name << " release];";
+ _M << nl << "self->" << name << " = nil;";
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ }
+ _M << eb;
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberHashCode(const DataMemberList& dataMembers, int baseType) const
+{
+ _M << sp << nl << "-(NSUInteger) hash";
+ _M << sb;
+ _M << nl << "NSUInteger h_ = 5381;";
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string name = fixId((*q)->name(), baseType);
+
+ _M << nl << "h_ = ((h_ << 5) + h_) ^ ";
+ if(isValueType(type))
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ if(builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble)
+ {
+ _M << "(2654435761u * (uint)" << name << ");";
+ }
+ else
+ {
+ _M << "(2654435761u * " << name << ");";
+ }
+ }
+ else
+ {
+ _M << name << ";";
+ }
+ }
+ else
+ {
+ _M << "[self->" << name << " hash];";
+ }
+ }
+ _M << nl << "return h_;";
+ _M << eb;
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberEquals(const DataMemberList& dataMembers, int baseType) const
+{
+ if(!dataMembers.empty())
+ {
+ ContainerPtr container = (*dataMembers.begin())->container();
+ ContainedPtr contained = ContainedPtr::dynamicCast(container);
+ string containerName = fixName(contained);
+ _M << nl << containerName << " *obj_ = (" << containerName << " *)o_;";
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ string name = fixId((*q)->name(), baseType);
+
+ if(isValueType(type))
+ {
+ _M << nl << "if(" << name << " != obj_->" << name << ")";
+ _M << sb;
+ _M << nl << "return NO;";
+ _M << eb;
+ }
+ else
+ {
+ _M << nl << "if(!" << name << ")";
+ _M << sb;
+ _M << nl << "if(obj_->" << name << ")";
+ _M << sb;
+ _M << nl << "return NO;";
+ _M << eb;
+ _M << eb;
+ _M << nl << "else";
+ _M << sb;
+ _M << nl << "if(![self." << name << " ";
+ _M << (isString(type) ? "isEqualToString" : "isEqual");
+ _M << ":obj_->" << name << "])";
+ _M << sb;
+ _M << nl << "return NO;";
+ _M << eb;
+ _M << eb;
+ }
+ }
+ }
+ _M << nl << "return YES;";
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberDealloc(const DataMemberList& dataMembers, int baseType, bool slicedData) const
+{
+ bool once = false;
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ TypePtr type = (*q)->type();
+ if(!isValueType(type))
+ {
+ if(!once)
+ {
+ once = true;
+ _M << sp;
+ _M.zeroIndent();
+ _M << nl << "#if defined(__clang__) && !__has_feature(objc_arc)";
+ _M.restoreIndent();
+ _M << nl << "-(void) dealloc";
+ _M << sb;
+ }
+
+ bool isValue = isValueType(type);
+ if(!isValue)
+ {
+ _M << nl << "[self->" << fixId((*q)->name(), baseType) << " release];";
+ }
+ }
+ }
+ if(once)
+ {
+ if(slicedData)
+ {
+ _M << nl << "[(NSObject*)slicedData__ release];";
+ }
+ _M << nl << "[super dealloc];";
+ _M << eb;
+ _M.zeroIndent();
+ _M << nl << "#endif";
+ _M.restoreIndent();
+ _H << nl << "// This class also overrides dealloc.";
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberMarshal(const DataMemberList& dataMembers, const DataMemberList& optionalMembers,
+ int baseType) const
+{
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if(!(*q)->optional())
+ {
+ writeMarshalUnmarshalCode(_M, (*q)->type(), "self->" + fixId((*q)->name(), baseType), true, false);
+ }
+ }
+ for(DataMemberList::const_iterator q = optionalMembers.begin(); q != optionalMembers.end(); ++q)
+ {
+ string name = fixId((*q)->name(), baseType);
+ string frmt = getOptionalFormat((*q)->type());
+ _M << nl << "if(self->has_" << name << "__ && [os_ writeOptional:" << (*q)->tag() << " format:" << frmt << "])";
+ _M << sb;
+ writeOptMemberMarshalUnmarshalCode(_M, (*q)->type(), "self->" + name, true);
+ _M << eb;
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::writeMemberUnmarshal(const DataMemberList& dataMembers, const DataMemberList& optionalMembers,
+ int baseType) const
+{
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if(!(*q)->optional())
+ {
+ writeMarshalUnmarshalCode(_M, (*q)->type(), "self->" + fixId((*q)->name(), baseType), false, false);
+ }
+ }
+ for(DataMemberList::const_iterator q = optionalMembers.begin(); q != optionalMembers.end(); ++q)
+ {
+ string name = fixId((*q)->name(), baseType);
+ string frmt = getOptionalFormat((*q)->type());
+ _M << nl << "if([is_ readOptional:" << (*q)->tag() << " format:" << frmt << "])";
+ _M << sb;
+ _M << nl << "self->has_" << name << "__ = YES;";
+ writeOptMemberMarshalUnmarshalCode(_M, (*q)->type(), "self->" + name, false);
+ _M << eb;
+ _M << nl << "else";
+ _M << sb;
+ _M << nl << "self->has_" << name << "__ = NO;";
+ _M << eb;
+ }
+}
+
+Slice::Gen::ProxyVisitor::ProxyVisitor(Output& H, Output& M)
+ : ObjCVisitor(H, M)
+{
+}
+
+bool
+Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string name = fixName(p);
+ ClassList bases = p->bases();
+
+ _H << sp << nl << "@protocol " << name << "Prx <";
+ if(bases.empty())
+ {
+ _H << "ICEObjectPrx";
+ }
+ else
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ _H << fixName(*q) + "Prx";
+ if(++q != bases.end())
+ {
+ _H << ", ";
+ }
+ }
+ }
+ _H << ">";
+
+ return true;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitClassDefEnd(const ClassDefPtr&)
+{
+ _H << nl << "@end";
+}
+
+void
+Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = getName(p);
+ TypePtr returnType = p->returnType();
+ string retString = outTypeToString(returnType, p->returnIsOptional());
+ string params = getParams(p);
+ string marshalParams = getMarshalParams(p);
+ string unmarshalParams = getUnmarshalParams(p);
+
+ //
+ // Write two versions of the operation--with and without a
+ // context parameter.
+ //
+ _H << nl << "-(" << retString << ") " << name << params << ";";
+
+ _H << nl << "-(" << retString << ") " << name << params;
+ if(!params.empty())
+ {
+ _H << " context";
+ }
+ _H << ":(ICEContext *)context;";
+
+ _H << nl << "-(id<ICEAsyncResult>) begin_" << p->name() << marshalParams << ";";
+ _H << nl << "-(id<ICEAsyncResult>) begin_" << p->name() << marshalParams;
+ if(!marshalParams.empty())
+ {
+ _H << " context";
+ }
+ _H << ":(ICEContext *)context;";
+
+ _H << nl << "-(" << retString << ") end_" << p->name() << unmarshalParams;
+ if(!unmarshalParams.empty())
+ {
+ _H << " result";
+ }
+ _H << ":(id<ICEAsyncResult>)result;";
+
+ string responseCBSig = getResponseCBSig(p);
+ _H << nl << "-(id<ICEAsyncResult>) begin_" << p->name() << marshalParams;
+ if(!marshalParams.empty())
+ {
+ _H << " response";
+ }
+ _H << ":(" << responseCBSig << ")response_ exception:(void(^)(ICEException*))exception_;";
+
+ _H << nl << "-(id<ICEAsyncResult>) begin_" << p->name() << marshalParams;
+ if(!marshalParams.empty())
+ {
+ _H << " context";
+ }
+ _H << ":(ICEContext *)context";
+ _H << " response:(" << responseCBSig << ")response_ exception:(void(^)(ICEException*))exception_;";
+
+ _H << nl << "-(id<ICEAsyncResult>) begin_" << p->name() << marshalParams;
+ if(!marshalParams.empty())
+ {
+ _H << " response";
+ }
+ _H << ":(" << responseCBSig << ")response_ exception:(void(^)(ICEException*))exception_ sent:(void(^)(BOOL))sent_;";
+
+ _H << nl << "-(id<ICEAsyncResult>) begin_" << p->name() << marshalParams;
+ if(!marshalParams.empty())
+ {
+ _H << " context";
+ }
+ _H << ":(ICEContext *)context";
+ _H << " response:(" << responseCBSig << ")response_ exception:(void(^)(ICEException*))exception_ sent:(void(^)(BOOL))sent_;";
+}
+
+Slice::Gen::HelperVisitor::HelperVisitor(Output& H, Output& M) :
+ ObjCVisitor(H, M)
+{
+}
+
+bool
+Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ //
+ // Proxy helper
+ //
+ {
+ string name = moduleName(findModule(p)) + p->name() + "PrxHelper";
+ _H << sp << nl << "@interface " << name << " : ICEProxyHelper";
+ _H << nl << "@end";
+
+ _M << sp << nl << "@implementation " << name;
+ _M << nl << "+(id) readRetained:(id<ICEInputStream>)stream";
+ _M << sb;
+ _M << nl << "return [stream newProxy:[" << fixName(p) << "Prx class]];";
+ _M << eb;
+ _M << nl << "@end";
+ }
+
+ //
+ // Class helper
+ //
+ {
+ string name = moduleName(findModule(p)) + p->name() + "Helper";
+ if(p->isInterface())
+ {
+ _H << sp << nl << "typedef ICEObjectHelper " << name << ";";
+ }
+ else
+ {
+ _H << sp << nl << "@interface " << name << " : ICEObjectHelper";
+ _H << nl << "@end";
+
+ _M << sp << nl << "@implementation " << name;
+ _M << nl << "+(void) readRetained:(ICEObject*ICE_STRONG_QUALIFIER*)obj stream:(id<ICEInputStream>)stream";
+ _M << sb;
+ _M << nl << "[stream newObject:obj expectedType:[" << fixName(p) << " class]];";
+ _M << eb;
+ _M << nl << "@end";
+ }
+ }
+ return false;
+}
+
+void
+Slice::Gen::HelperVisitor::visitEnum(const EnumPtr& p)
+{
+ string name = moduleName(findModule(p)) + p->name() + "Helper";
+
+ _H << sp << nl << "@interface " << name << " : ICEEnumHelper";
+ _H << nl << "@end";
+
+ _M << sp << nl << "@implementation " << name;
+ _M << nl << "+(ICEInt) getMinValue";
+ _M << sb;
+ _M << nl << "return " << p->minValue() << ";";
+ _M << eb;
+ _M << nl << "+(ICEInt) getMaxValue";
+ _M << sb;
+ _M << nl << "return " << p->maxValue() << ";";
+ _M << eb;
+ _M << nl << "@end";
+}
+
+void
+Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
+{
+ string name = moduleName(findModule(p)) + p->name() + "Helper";
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ if(builtin)
+ {
+ _H << sp << nl << "typedef ICE" << getBuiltinName(builtin) << "SequenceHelper " << name << ";";
+ return;
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(p->type());
+ if(en)
+ {
+ _H << sp << nl << "@interface " << name << " : ICEEnumSequenceHelper";
+ _H << nl << "@end";
+
+ string typeS = typeToString(en);
+ int min = en->minValue();
+ int max = en->maxValue();
+ _M << sp << nl << "@implementation " << name;
+ _M << nl << "+(id) readRetained:(id<ICEInputStream>)stream";
+ _M << sb;
+ _M << nl << "return [stream newEnumSeq:" << min << " max:" << max << "];";
+ _M << eb;
+ _M << nl << "+(void) write:(id)obj stream:(id<ICEOutputStream>)stream";
+ _M << sb;
+ _M << nl << "[stream writeEnumSeq:obj min:" << min << " max:" << max << "];";
+ _M << eb;
+ _M << nl << "@end";
+ return;
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(p->type());
+ if(cl)
+ {
+ _H << sp << nl << "@interface " << name << " : ICEObjectSequenceHelper";
+ _H << nl << "@end";
+
+ _M << sp << nl << "@implementation " << name;
+ _M << nl << "+(id) readRetained:(id<ICEInputStream>)stream";
+ _M << sb;
+ _M << nl << "return [stream newObjectSeq:[" << fixName(cl) << " class]];";
+ _M << eb;
+ _M << nl << "@end";
+ return;
+ }
+
+ ProxyPtr proxy = ProxyPtr::dynamicCast(p->type());
+ ContainedPtr contained = ContainedPtr::dynamicCast(p->type());
+ _H << sp << nl << "@interface " << name << " : ICEArraySequenceHelper";
+ _H << nl << "@end";
+
+ _M << sp << nl << "@implementation " << name;
+ _M << nl << "+(Class) getElementHelper";
+ _M << sb;
+ if(proxy)
+ {
+ string name = moduleName(findModule(proxy->_class())) + proxy->_class()->name();
+ _M << nl << "return [" << name << "PrxHelper class];";
+ }
+ else
+ {
+ assert(contained);
+ _M << nl << "return [" << moduleName(findModule(contained)) + contained->name() + "Helper class];";
+ }
+ _M << eb;
+ _M << nl << "+(Class) getOptionalHelper";
+ _M << sb;
+ if(p->type()->isVariableLength())
+ {
+ _M << nl << "return [ICEVarLengthOptionalHelper class];";
+ }
+ else if(p->type()->minWireSize() == 1)
+ {
+ _M << nl << "return [ICEFixedSize1SequenceOptionalHelper class];";
+ }
+ else
+ {
+ _M << nl << "return [ICEFixedSequenceOptionalHelper class];";
+ }
+ _M << eb;
+ _M << nl << "@end";
+}
+
+void
+Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ string name = moduleName(findModule(p)) + p->name() + "Helper";
+
+ TypePtr keyType = p->keyType();
+ string keyS;
+ BuiltinPtr keyBuiltin = BuiltinPtr::dynamicCast(keyType);
+ if(keyBuiltin)
+ {
+ keyS = "ICE" + getBuiltinName(BuiltinPtr::dynamicCast(keyType)) + "Helper";
+ }
+ else
+ {
+ ContainedPtr contained = ContainedPtr::dynamicCast(keyType);
+ keyS = moduleName(findModule(contained)) + contained->name() + "Helper";
+ }
+
+ string valueS;
+ TypePtr valueType = p->valueType();
+ BuiltinPtr valueBuiltin = BuiltinPtr::dynamicCast(valueType);
+ ClassDeclPtr valueClass = ClassDeclPtr::dynamicCast(valueType);
+ if((valueBuiltin && valueBuiltin->kind() == Builtin::KindObject) || valueClass)
+ {
+ _H << sp << nl << "@interface " << name << " : ICEObjectDictionaryHelper";
+ _H << nl << "@end";
+
+ _M << sp << nl << "@implementation " << name;
+ _M << nl << "+(id) readRetained:(id<ICEInputStream>)stream";
+ _M << sb;
+ if(valueClass && !valueClass->isInterface())
+ {
+ valueS = fixName(valueClass);
+ _M << nl << "return [stream newObjectDict:[" << keyS << " class] expectedType:[" << valueS << " class]];";
+ }
+ else
+ {
+ _M << nl << "return [stream newObjectDict:[" << keyS << " class] expectedType:[ICEObject class]];";
+ }
+ _M << eb;
+ _M << nl << "+(void) write:(id)obj stream:(id<ICEOutputStream>)stream";
+ _M << sb;
+ _M << nl << "[stream writeObjectDict:obj helper:[" << keyS << " class]];";
+ _M << eb;
+ _M << nl << "@end";
+ return;
+ }
+
+ ProxyPtr valueProxy = ProxyPtr::dynamicCast(valueType);
+ if(valueBuiltin)
+ {
+ valueS = "ICE" + getBuiltinName(BuiltinPtr::dynamicCast(valueType)) + "Helper";
+ }
+ else if(valueProxy)
+ {
+ valueS = moduleName(findModule(valueProxy->_class())) + valueProxy->_class()->name() + "PrxHelper";
+ }
+ else
+ {
+ ContainedPtr contained = ContainedPtr::dynamicCast(valueType);
+ valueS = moduleName(findModule(contained)) + contained->name() + "Helper";
+ }
+ _H << sp << nl << "@interface " << name << " : ICEDictionaryHelper";
+ _H << nl << "@end";
+
+ _M << sp << nl << "@implementation " << name;
+ _M << nl << "+(ICEKeyValueTypeHelper) getKeyValueHelper";
+ _M << sb;
+ _M << nl << "ICEKeyValueTypeHelper c;";
+ _M << nl << "c.key = [" << keyS << " class];";
+ _M << nl << "c.value = [" << valueS << " class];";
+ _M << nl << "return c;";
+ _M << eb;
+ _M << nl << "+(Class) getOptionalHelper";
+ _M << sb;
+ if(keyType->isVariableLength() || valueType->isVariableLength())
+ {
+ _M << nl << "return [ICEVarLengthOptionalHelper class];";
+ }
+ else
+ {
+ _M << nl << "return [ICEFixedDictionaryOptionalHelper class];";
+ }
+ _M << eb;
+ _M << nl << "@end";
+}
+
+
+bool
+Slice::Gen::HelperVisitor::visitStructStart(const StructPtr& p)
+{
+ string name = fixName(p);
+
+ _H << sp << nl << "@interface " << name << "Helper : ICEStructHelper";
+ _H << nl << "@end";
+
+ _M << sp << nl << "@implementation " << name << "Helper";
+
+ _M << nl << "+(Class) getType";
+ _M << sb;
+ _M << nl << "return [" << name << " class];";
+ _M << eb;
+ _M << nl << "+(Class) getOptionalHelper";
+ _M << sb;
+ if(p->isVariableLength())
+ {
+ _M << nl << "return [ICEVarLengthOptionalHelper class];";
+ }
+ else
+ {
+ _M << nl << "return [ICEFixedLengthOptionalHelper class];";
+ }
+ _M << eb;
+
+ _M << nl << "+(ICEInt) minWireSize";
+ _M << sb;
+ _M << nl << "return " << p->minWireSize() << ";";
+ _M << eb;
+
+ _M << nl << "@end";
+ return false;
+}
+
+Slice::Gen::DelegateMVisitor::DelegateMVisitor(Output& H, Output& M)
+ : ObjCVisitor(H, M)
+{
+}
+
+bool
+Slice::Gen::DelegateMVisitor::visitModuleStart(const ModulePtr& p)
+{
+ return true;
+}
+
+void
+Slice::Gen::DelegateMVisitor::visitModuleEnd(const ModulePtr&)
+{
+}
+
+bool
+Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string name = fixName(p);
+ ClassList bases = p->bases();
+ OperationList ops = p->allOperations();
+ OperationList::const_iterator r;
+
+ _H << sp << nl << "@interface " << name << "Prx : ICEObjectPrx <" << name << "Prx>";
+ _H << nl << "+(NSString *) ice_staticId;";
+
+ _M << sp << nl << "@implementation " << name << "Prx";
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ string opName = getName(*r);
+ TypePtr returnType = (*r)->returnType();
+ string retString = outTypeToString(returnType, (*r)->returnIsOptional());
+ string params = getParams(*r);
+ string args = getArgs(*r);
+
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+ ParamDeclList paramList = (*r)->parameters();
+ for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if((*pli)->isOutParam())
+ {
+ outParams.push_back(*pli);
+ }
+ else
+ {
+ inParams.push_back(*pli);
+ }
+ }
+
+ ContainerPtr container = (*r)->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string className = fixName(cl);
+
+ //
+ // Write context-less operation that forwards to the version with a context.
+ //
+ _M << sp << nl << "-(" << retString << ") " << opName << params;
+ _M << sb;
+ _M << nl;
+ if(returnType)
+ {
+ _M << "return ";
+ }
+ _M << "[self " << opName << args << (args.empty() ? ":nil" : " context:nil") << "];";
+ _M << eb;
+
+ //
+ // Write version with context.
+ //
+ _M << sp << nl << "-(" << retString << ") " << opName << params;
+ if(!params.empty())
+ {
+ _M << " context";
+ }
+ _M << ":(ICEContext *)ctx_";
+ _M << sb;
+ if(returnType)
+ {
+ _M << nl << "__block " << retString << " ret_";
+ if(!isValueType(returnType))
+ {
+ _M << " = nil;";
+ }
+ else
+ {
+ _M << ";";
+ }
+ }
+
+ string marshal;
+ string marshalArgs = getMarshalArgs(*r);
+ string marshalParams = getMarshalParams(*r);
+ if(!inParams.empty())
+ {
+ _M << nl << "ICEMarshalCB marshal_ = ^(id<ICEOutputStream> os_) ";
+ _M << "{ [" << className << "Prx " << (*r)->name() << "_marshal___" << marshalArgs;
+ _M << (marshalArgs.empty() ? ":os_" : " os:os_") << "]; };";
+ marshal = "marshal_";
+ }
+ else
+ {
+ marshal = "nil";
+ }
+
+ string unmarshal;
+ string unmarshalArgs = getUnmarshalArgs(*r);
+ string unmarshalParams = getUnmarshalParams(*r);
+ if((*r)->returnsData())
+ {
+ _M << nl << "ICEUnmarshalCB unmarshal_ = ^(id<ICEInputStream> is_, BOOL ok_) ";
+ if(returnType)
+ {
+ _M << "{ ret_ = ";
+ }
+ else
+ {
+ _M << "{ ";
+ }
+ _M << "[" << className << "Prx " << (*r)->name() << "_unmarshal___" << unmarshalArgs;
+ _M << (unmarshalArgs.empty() ? ":is_" : " is:is_") << " ok:ok_]; };";
+ unmarshal = "unmarshal_";
+ }
+ else
+ {
+ unmarshal = "nil";
+ }
+
+ _M << nl << "[self invoke__:@\"" << (*r)->name() << "\" mode:" << sliceModeToIceMode((*r)->sendMode())
+ << " format:" << opFormatTypeToString(*r) << " marshal:" << marshal
+ << " unmarshal:" << unmarshal << " context:ctx_];";
+ if(returnType)
+ {
+ _M << nl << "return ret_;";
+ }
+ _M << eb;
+
+ //
+ // Write begin_ context-less operation that forwards to the version with a context.
+ //
+ _M << sp << nl << "-(id<ICEAsyncResult>) begin_" << (*r)->name() << marshalParams;
+ _M << sb;
+ _M << nl << "return [self begin_" << (*r)->name() << marshalArgs;
+ _M << (marshalArgs.empty() ? "" : " context") << ":nil];";
+ _M << eb;
+
+ //
+ // Write begin_ version with context.
+ //
+ _M << sp << nl << "-(id<ICEAsyncResult>) begin_" << (*r)->name() << marshalParams;
+ _M << (marshalParams.empty() ? "" : " context") << ":(ICEContext *)ctx_";
+ _M << sb;
+ if(!inParams.empty())
+ {
+ _M << nl << "ICEMarshalCB marshal_ = ^(id<ICEOutputStream> os_) ";
+ _M << "{ [" << className << "Prx " << (*r)->name() << "_marshal___" << marshalArgs;
+ _M << (marshalArgs.empty() ? "" : " os") << ":os_]; };";
+ }
+ _M << nl << "return [self begin_invoke__:@\"" << (*r)->name() << "\" mode:"
+ << sliceModeToIceMode((*r)->sendMode()) << " format:" << opFormatTypeToString(*r)
+ << " marshal:" << marshal
+ << " returnsData:" << ((*r)->returnsData() ? "YES" : "NO")
+ << " context:ctx_];";
+ _M << eb;
+
+ //
+ // Write end_ operation
+ //
+ _M << sp << nl << "-(" << retString << ") end_" << (*r)->name() << unmarshalParams;
+ if(!unmarshalParams.empty())
+ {
+ _M << " result";
+ }
+ _M << ":(id<ICEAsyncResult>)result_";
+ _M << sb;
+ if(returnType)
+ {
+ _M << nl << "__block " << retString << " ret_";
+ if(!isValueType(returnType))
+ {
+ _M << " = nil;";
+ }
+ else
+ {
+ _M << ";";
+ }
+ }
+ if((*r)->returnsData())
+ {
+ _M << nl << "ICEUnmarshalCB unmarshal_ = ^(id<ICEInputStream> is_, BOOL ok_) ";
+ if(returnType)
+ {
+ _M << "{ ret_ = ";
+ }
+ else
+ {
+ _M << "{ ";
+ }
+ _M << "[" << className << "Prx " << (*r)->name() << "_unmarshal___" << unmarshalArgs;
+ _M << (unmarshalArgs.empty() ? ":is_" : " is:is_") << " ok:ok_]; };";
+ }
+ _M << nl << "[self end_invoke__:@\"" << (*r)->name() << "\" unmarshal:" << unmarshal << " result:result_];";
+ if(returnType)
+ {
+ _M << nl << "return ret_;";
+ }
+ _M << eb;
+
+ //
+ // Write begin_ operations with callbacks
+ //
+ string responseCBSig = getResponseCBSig(*r);
+
+ _M << sp << nl << "-(id<ICEAsyncResult>) begin_" << (*r)->name() << marshalParams;
+ _M << (marshalParams.empty() ? "" : " response") << ":(" << responseCBSig << ")response_";
+ _M << " exception:(void(^)(ICEException*))exception_";
+ _M << sb;
+ _M << nl << "return [self begin_" << (*r)->name() << marshalArgs;
+ _M << (marshalArgs.empty() ? "" : " context") << ":nil response:response_ exception:exception_ sent:nil];";
+ _M << eb;
+
+ _M << sp << nl << "-(id<ICEAsyncResult>) begin_" << (*r)->name() << marshalParams;
+ _M << (marshalParams.empty() ? "" : " response") << ":(" << responseCBSig << ")response_";
+ _M << " exception:(void(^)(ICEException*))exception_ sent:(void(^)(BOOL))sent_";
+ _M << sb;
+ _M << nl << "return [self begin_" << (*r)->name() << marshalArgs;
+ _M << (marshalArgs.empty() ? "" : " context") << ":nil response:response_ exception:exception_ sent:sent_];";
+ _M << eb;
+
+ _M << sp << nl << "-(id<ICEAsyncResult>) begin_" << (*r)->name() << marshalParams;
+ _M << (marshalParams.empty() ? "" : " context") << ":(ICEContext*)ctx_";
+ _M << " response:(" << responseCBSig << ")response_ exception:(void(^)(ICEException*))exception_ ";
+ _M << sb;
+ _M << nl << "return [self begin_" << (*r)->name() << marshalArgs;
+ _M << (marshalArgs.empty() ? "" : " context") << ":ctx_ response:response_ exception:exception_ sent:nil];";
+ _M << eb;
+
+ _M << sp << nl << "-(id<ICEAsyncResult>) begin_" << (*r)->name() << marshalParams;
+ _M << (marshalParams.empty() ? "" : " context") << ":(ICEContext*)ctx_";
+ _M << " response:(" << responseCBSig << ")response_ exception:(void(^)(ICEException*))exception_ ";
+ _M << " sent:(void(^)(BOOL))sent_";
+ _M << sb;
+ if(!inParams.empty())
+ {
+ _M << nl << "ICEMarshalCB marshal_ = ^(id<ICEOutputStream> os_) ";
+ _M << "{ [" << className << "Prx " << (*r)->name() << "_marshal___" << marshalArgs;
+ _M << (marshalArgs.empty() ? "" : " os") << ":os_]; };";
+ }
+ if((*r)->returnsData())
+ {
+ _M << nl << "void(^completed_)(id<ICEInputStream>, BOOL) = ^(id<ICEInputStream> is_, BOOL ok_)";
+ _M << sb;
+ string responseCallArgs;
+ string unmarshalCallArgs;
+ if(!outParams.empty() || returnType)
+ {
+ if(returnType)
+ {
+ responseCallArgs += "ret_";
+ }
+
+ for(ParamDeclList::const_iterator op = outParams.begin(); op != outParams.end(); ++op)
+ {
+ string name = fixId((*op)->name());
+ _M << nl << outTypeToString((*op)->type(), (*op)->optional(), true) << " " << name;
+ if(!isValueType((*op)->type()))
+ {
+ _M << " = nil";
+ }
+ _M << ";";
+
+ if(!unmarshalCallArgs.empty())
+ {
+ unmarshalCallArgs += " " + name;
+ }
+ unmarshalCallArgs += ":&" + name;
+
+ if(!responseCallArgs.empty())
+ {
+ responseCallArgs += ", ";
+ }
+ responseCallArgs += name;
+ }
+ if(returnType)
+ {
+ _M << nl << outTypeToString(returnType, (*r)->returnIsOptional(), true) << " ret_";
+ if(!isValueType(returnType))
+ {
+ _M << " = nil";
+ }
+ _M << ";";
+ }
+ }
+ _M << nl << "@try";
+ _M << sb;
+ _M << nl;
+ if(returnType)
+ {
+ _M << "ret_ = ";
+ }
+ _M << "[" << className << "Prx " << (*r)->name() << "_unmarshal___" << unmarshalCallArgs;
+ _M << (unmarshalCallArgs.empty() ? ":is_" : " is:is_") << " ok:ok_];";
+ _M << eb;
+ _M << nl << "@catch(ICEException* ex)";
+ _M << sb;
+ _M << nl << "if(exception_)";
+ _M << sb;
+ _M << nl << "exception_(ex);";
+ _M << eb;
+ _M << nl << "return;";
+ _M << eb;
+ _M << nl << "if(response_)";
+ _M << sb;
+ _M << nl << "response_(" << responseCallArgs << ");";
+ _M << eb;
+ _M << eb << ";";
+ if(returnType || !outParams.empty())
+ {
+ _M << nl << "return [self begin_invoke__:@\"" << (*r)->name() << "\" mode:"
+ << sliceModeToIceMode((*r)->sendMode()) << " format:" << opFormatTypeToString(*r)
+ << " marshal:" << marshal
+ << " completed:completed_ response:(response_ != nil) exception:exception_ sent:sent_ context:ctx_];";
+ }
+ else
+ {
+ _M << nl << "return [self begin_invoke__:@\"" << (*r)->name() << "\" mode:"
+ << sliceModeToIceMode((*r)->sendMode()) << " format:" << opFormatTypeToString(*r)
+ << " marshal:" << marshal << " completed:completed_ response:YES exception:exception_ sent:sent_ context:ctx_];";
+ }
+ }
+ else
+ {
+ _M << nl << "return [self begin_invoke__:@\"" << (*r)->name() << "\" mode:"
+ << sliceModeToIceMode((*r)->sendMode()) << " format:" << opFormatTypeToString(*r)
+ << " marshal:" << marshal << " response:response_ exception:exception_ sent:sent_ context:ctx_];";
+ }
+ _M << eb;
+ }
+
+ _M << sp << nl << "+(NSString *) ice_staticId";
+ _M << sb;
+ _M << nl << "return @\"" << p->scoped() << "\";";
+ _M << eb;
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateMVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ _H << nl << "@end";
+ _M << nl << "@end";
+}
+
+void
+Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p)
+{
+ TypePtr returnType = p->returnType();
+ string retString = outTypeToString(returnType, p->returnIsOptional());
+ string params = getParams(p);
+ string args = getParams(p);
+ string marshalParams = getMarshalParams(p);
+ string unmarshalParams = getUnmarshalParams(p);
+
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if((*pli)->isOutParam())
+ {
+ outParams.push_back(*pli);
+ }
+ else
+ {
+ inParams.push_back(*pli);
+ }
+ }
+
+ //
+ // Write class method to invoke each operation.
+ //
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string className = fixName(cl);
+ if(!inParams.empty())
+ {
+ _H << nl << "+(void) " << p->name() << "_marshal___" << marshalParams;
+ if(!marshalParams.empty())
+ {
+ _H << " os";
+ }
+ _H << ":(id<ICEOutputStream>)os_;";
+
+ _M << sp << nl << "+(void) " << p->name() << "_marshal___" << marshalParams;
+ if(!marshalParams.empty())
+ {
+ _M << " os";
+ }
+ _M << ":(id<ICEOutputStream>)os_";
+ _M << sb;
+ writeMarshalUnmarshalParams(inParams, 0, true);
+ if(p->sendsClasses(false))
+ {
+ _M << nl << "[os_ writePendingObjects];";
+ }
+ _M << eb;
+ }
+
+ if(p->returnsData())
+ {
+ _H << nl << "+(" << retString << ")" << p->name() << "_unmarshal___" << unmarshalParams;
+ if(!unmarshalParams.empty())
+ {
+ _H << " is";
+ }
+ _H << ":(id<ICEInputStream>)is_ ok:(BOOL)ok_;";
+
+ _M << nl << "+(" << retString << ")" << p->name() << "_unmarshal___" << unmarshalParams;
+ if(!unmarshalParams.empty())
+ {
+ _M << " is";
+ }
+ _M << ":(id<ICEInputStream>)is_ ok:(BOOL)ok_";
+ _M << sb;
+ if(returnType)
+ {
+ _M << nl << outTypeToString(returnType, p->returnIsOptional(), true) << " ret_";
+ if(!isValueType(returnType))
+ {
+ _M << " = nil;";
+ }
+ else
+ {
+ _M << ";";
+ }
+ }
+ if(p->returnsData())
+ {
+ for(ParamDeclList::const_iterator op = outParams.begin(); op != outParams.end(); ++op)
+ {
+ if(!isValueType((*op)->type()))
+ {
+ _M << nl << "*" << fixId((*op)->name()) << " = nil;";
+ }
+ }
+ }
+ _M << nl << "if(!ok_)";
+ _M << sb;
+ _M << nl << "@try";
+ _M << sb;
+ _M << nl << "[is_ startEncapsulation];";
+ _M << nl << "[is_ throwException];";
+ _M << eb;
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+ ExceptionList throws = p->throws();
+ throws.sort();
+ throws.unique();
+ throws.sort(Slice::DerivedToBaseCompare());
+
+ for(ExceptionList::const_iterator e = throws.begin(); e != throws.end(); ++e)
+ {
+ _M << nl << "@catch(" << fixName(*e) << " *ex_)";
+ _M << sb;
+ _M << nl << "[is_ endEncapsulation];";
+ _M << nl << "@throw;";
+ _M << eb;
+ }
+ _M << nl << "@catch(ICEUserException *ex_)";
+ _M << sb;
+ _M << nl << "[is_ endEncapsulation];";
+ _M << nl << "@throw [ICEUnknownUserException unknownUserException:__FILE__ line:__LINE__ "
+ << "unknown:[ex_ ice_name]];";
+ _M << eb;
+ _M << eb;
+
+ if(returnType || !outParams.empty())
+ {
+ _M << nl << "else";
+ _M << sb;
+ _M << nl << "[is_ startEncapsulation];";
+ writeMarshalUnmarshalParams(outParams, p, false, true);
+ if(p->returnsClasses(false))
+ {
+ _M << nl << "[is_ readPendingObjects];";
+ }
+ _M << nl << "[is_ endEncapsulation];";
+ _M << eb;
+ }
+
+ if(returnType)
+ {
+ _M << nl << "return ret_;";
+ }
+ _M << eb;
+ }
+}
+
diff --git a/cpp/src/slice2objc/Gen.h b/cpp/src/slice2objc/Gen.h
new file mode 100644
index 00000000000..2126057137e
--- /dev/null
+++ b/cpp/src/slice2objc/Gen.h
@@ -0,0 +1,186 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef GEN_H
+#define GEN_H
+
+#include <Slice/ObjCUtil.h>
+
+namespace Slice
+{
+
+
+class ObjCVisitor : public ObjCGenerator, public ParserVisitor
+{
+public:
+
+ ObjCVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&);
+ virtual ~ObjCVisitor();
+
+protected:
+
+ virtual void writeDispatchAndMarshalling(const ClassDefPtr&);
+ virtual void writeMarshalUnmarshalParams(const ParamDeclList&, const OperationPtr&, bool, bool = false);
+ virtual std::string getName(const OperationPtr&) const;
+ virtual std::string getSelector(const OperationPtr&) const;
+ virtual std::string getParams(const OperationPtr&) const;
+ virtual std::string getMarshalParams(const OperationPtr&) const;
+ virtual std::string getUnmarshalParams(const OperationPtr&) const;
+ virtual std::string getServerParams(const OperationPtr&) const;
+ virtual std::string getResponseCBSig(const OperationPtr&) const;
+ virtual std::string getArgs(const OperationPtr&) const;
+ virtual std::string getMarshalArgs(const OperationPtr&) const;
+ virtual std::string getUnmarshalArgs(const OperationPtr&) const;
+ virtual std::string getServerArgs(const OperationPtr&) const;
+
+ ::IceUtilInternal::Output& _H;
+ ::IceUtilInternal::Output& _M;
+};
+
+class Gen : private ::IceUtil::noncopyable
+{
+public:
+
+ Gen(const std::string&,
+ const std::string&,
+ const std::string&,
+ const std::vector<std::string>&,
+ const std::string&);
+ ~Gen();
+
+ bool operator!() const; // Returns true if there was a constructor error
+
+ void generate(const UnitPtr&);
+ void closeOutput();
+
+private:
+
+ IceUtilInternal::Output _H;
+ IceUtilInternal::Output _M;
+
+ std::string _base;
+ std::string _include;
+ std::vector<std::string> _includePaths;
+
+ void printHeader(::IceUtilInternal::Output&);
+
+ class UnitVisitor : public ObjCVisitor
+ {
+ public:
+
+ UnitVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitUnitEnd(const UnitPtr&);
+
+ private:
+
+ std::vector<Slice::ObjCGenerator::ModulePrefix> _prefixes;
+ };
+
+ class ObjectDeclVisitor : public ObjCVisitor
+ {
+ public:
+
+ ObjectDeclVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&);
+
+ virtual void visitClassDecl(const ClassDeclPtr&);
+ };
+
+ class ProxyDeclVisitor : public ObjCVisitor
+ {
+ public:
+
+ ProxyDeclVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&);
+
+ virtual void visitClassDecl(const ClassDeclPtr&);
+ };
+
+ class TypesVisitor : public ObjCVisitor
+ {
+ public:
+
+ TypesVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual void visitExceptionEnd(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitStructEnd(const StructPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+
+ private:
+
+ enum Escape { NoEscape, WithEscape };
+ enum ContainerType { LocalException, Other };
+
+ void writeConstantValue(IceUtilInternal::Output&, const TypePtr&, const std::string&) const;
+ void writeMembers(const DataMemberList&, int) const;
+ void writeMemberSignature(const DataMemberList&, int, ContainerType) const;
+ void writeMemberCall(const DataMemberList&, int, ContainerType, Escape) const;
+ void writeMemberDefaultValueInit(const DataMemberList&, int) const;
+ void writeMemberInit(const DataMemberList&, int) const;
+ void writeProperties(const DataMemberList&, int) const;
+ void writeSynthesize(const DataMemberList&, int) const;
+ void writeOptionalDataMemberSelectors(const DataMemberList&, int) const;
+ void writeMemberHashCode(const DataMemberList&, int) const;
+ void writeMemberEquals(const DataMemberList&, int) const;
+ void writeMemberDealloc(const DataMemberList&, int, bool slicedData = false) const;
+ void writeMemberMarshal(const DataMemberList&, const DataMemberList&, int) const;
+ void writeMemberUnmarshal(const DataMemberList&, const DataMemberList&, int) const;
+ };
+
+ class ProxyVisitor : public ObjCVisitor
+ {
+ public:
+
+ ProxyVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ };
+
+ class HelperVisitor : public ObjCVisitor
+ {
+ public:
+
+ HelperVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ };
+
+ class DelegateMVisitor : public ObjCVisitor
+ {
+ public:
+
+ DelegateMVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ };
+};
+
+}
+
+#endif
diff --git a/cpp/src/slice2objc/Main.cpp b/cpp/src/slice2objc/Main.cpp
new file mode 100644
index 00000000000..529c54134b2
--- /dev/null
+++ b/cpp/src/slice2objc/Main.cpp
@@ -0,0 +1,290 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/Options.h>
+#include <Slice/Preprocessor.h>
+#include <Slice/FileTracker.h>
+#include <IceUtil/CtrlCHandler.h>
+#include <IceUtil/Mutex.h>
+#include <IceUtil/MutexPtrLock.h>
+#include <Slice/Util.h>
+#include <Gen.h>
+
+using namespace std;
+using namespace Slice;
+
+namespace
+{
+
+IceUtil::Mutex* globalMutex = 0;
+bool interrupted = false;
+
+class Init
+{
+public:
+
+ Init()
+ {
+ globalMutex = new IceUtil::Mutex;
+ }
+
+ ~Init()
+ {
+ delete globalMutex;
+ globalMutex = 0;
+ }
+};
+
+Init init;
+
+}
+
+void
+interruptedCallback(int signal)
+{
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex);
+ interrupted = true;
+}
+
+void
+usage(const char* n)
+{
+ cerr << "Usage: " << n << " [options] slice-files...\n";
+ cerr <<
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ "-DNAME Define NAME as 1.\n"
+ "-DNAME=DEF Define NAME as DEF.\n"
+ "-UNAME Remove any definition for NAME.\n"
+ "-IDIR Put DIR in the include file search path.\n"
+ "-E Print preprocessor output on stdout.\n"
+ "--include-dir DIR Use DIR as the header include directory in source files.\n"
+ "--output-dir DIR Create files in the directory DIR.\n"
+ "--depend Generate Makefile dependencies.\n"
+ "--depend-xml Generate dependencies in XML format.\n"
+ "-d, --debug Print debug messages.\n"
+ "--ice Permit `Ice' prefix (for building Ice source code only)\n"
+ "--underscore Permit underscores in Slice identifiers.\n"
+ ;
+ // Note: --case-sensitive is intentionally not shown here!
+}
+
+int
+main(int argc, char* argv[])
+{
+ IceUtilInternal::Options opts;
+ opts.addOpt("h", "help");
+ opts.addOpt("v", "version");
+ opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("E");
+ opts.addOpt("", "include-dir", IceUtilInternal::Options::NeedArg);
+ opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg);
+ opts.addOpt("", "depend");
+ opts.addOpt("", "depend-xml");
+ opts.addOpt("d", "debug");
+ opts.addOpt("", "ice");
+ opts.addOpt("", "underscore");
+ opts.addOpt("", "case-sensitive");
+
+ vector<string> args;
+ try
+ {
+ args = opts.parse(argc, (const char**)argv);
+ }
+ catch(const IceUtilInternal::BadOptException& e)
+ {
+ cerr << argv[0] << ": " << e.reason << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if(opts.isSet("help"))
+ {
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+
+ if(opts.isSet("version"))
+ {
+ cout << ICE_STRING_VERSION << endl;
+ return EXIT_SUCCESS;
+ }
+
+ vector<string> cppArgs;
+ vector<string> optargs = opts.argVec("D");
+ vector<string>::const_iterator i;
+ for(i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs.push_back("-D" + *i);
+ }
+
+ optargs = opts.argVec("U");
+ for(i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs.push_back("-U" + *i);
+ }
+
+ vector<string> includePaths = opts.argVec("I");
+ for(i = includePaths.begin(); i != includePaths.end(); ++i)
+ {
+ cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i));
+ }
+
+ bool preprocess = opts.isSet("E");
+
+ string include = opts.optArg("include-dir");
+
+ string output = opts.optArg("output-dir");
+
+ bool depend = opts.isSet("depend");
+ bool dependxml = opts.isSet("depend-xml");
+
+ bool debug = opts.isSet("debug");
+
+ bool ice = opts.isSet("ice");
+
+ bool underscore = opts.isSet("underscore");
+
+ if(args.empty())
+ {
+ getErrorStream() << argv[0] << ": no input file" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ int status = EXIT_SUCCESS;
+
+ if(dependxml)
+ {
+ cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<dependencies>" << endl;
+ }
+
+ IceUtil::CtrlCHandler ctrlCHandler;
+ ctrlCHandler.setCallback(interruptedCallback);
+
+ for(i = args.begin(); i != args.end(); ++i)
+ {
+ if(depend || dependxml)
+ {
+ PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs);
+ FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2OBJC__");
+
+ if(cppHandle == 0)
+ {
+ return EXIT_FAILURE;
+ }
+
+ UnitPtr u = Unit::createUnit(false, false, ice, underscore);
+ int parseStatus = u->parse(*i, cppHandle, debug);
+ u->destroy();
+
+ if(parseStatus == EXIT_FAILURE)
+ {
+ return EXIT_FAILURE;
+ }
+
+ if(!icecpp->printMakefileDependencies(depend ? Preprocessor::ObjC : Preprocessor::JavaXML,
+ includePaths, "-D__SLICE2OBJC__"))
+ {
+ return EXIT_FAILURE;
+ }
+
+ if(!icecpp->close())
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs);
+ FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2OBJC__");
+
+ if(cppHandle == 0)
+ {
+ return EXIT_FAILURE;
+ }
+
+ if(preprocess)
+ {
+ char buf[4096];
+ while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
+ {
+ if(fputs(buf, stdout) == EOF)
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ if(!icecpp->close())
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ UnitPtr u = Unit::createUnit(false, false, ice, underscore);
+ int parseStatus = u->parse(*i, cppHandle, debug);
+
+ if(!icecpp->close())
+ {
+ u->destroy();
+ return EXIT_FAILURE;
+ }
+
+ if(parseStatus == EXIT_FAILURE)
+ {
+ status = EXIT_FAILURE;
+ }
+ else
+ {
+ try
+ {
+ Gen gen(argv[0], icecpp->getBaseName(), include, includePaths, output);
+ if(!gen)
+ {
+ u->destroy();
+ return EXIT_FAILURE;
+ }
+ gen.generate(u);
+ }
+ catch(const Slice::FileException& ex)
+ {
+ // If a file could not be created, then
+ // cleanup any created files.
+ FileTracker::instance()->cleanup();
+ u->destroy();
+ getErrorStream() << argv[0] << ": error: " << ex.reason() << endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ u->destroy();
+ }
+ }
+
+ {
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex);
+
+ if(interrupted)
+ {
+ FileTracker::instance()->cleanup();
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ if(dependxml)
+ {
+ cout << "</dependencies>\n";
+ }
+
+ return status;
+}
diff --git a/cpp/src/slice2objc/Makefile b/cpp/src/slice2objc/Makefile
new file mode 100644
index 00000000000..bd540f310b2
--- /dev/null
+++ b/cpp/src/slice2objc/Makefile
@@ -0,0 +1,31 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+NAME = $(bindir)/slice2objc$(EXE_EXT)
+
+TARGETS = $(NAME)
+
+OBJS = Gen.o \
+ Main.o
+
+RPATH_DIR = $(LOADER_PATH)/../$(libsubdir)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(NAME): $(OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(OBJS) $(SLICE_LIBS) $(MCPP_RPATH_LINK)
+
+install:: all
+ $(call installprogram,$(NAME),$(DESTDIR)$(install_bindir))
+ $(call installdata,$(top_srcdir)/../man/man1/slice2objc.1,$(DESTDIR)$(install_mandir))
diff --git a/demoscript/Util.py b/demoscript/Util.py
index 6f6412f0699..88767def2a9 100644
--- a/demoscript/Util.py
+++ b/demoscript/Util.py
@@ -292,7 +292,7 @@ def configurePaths():
# Setting the library path is necessary for interpreters to find
# the IceSSL library.
#
- if not isWin32() and iceHome != "/usr" and getMapping() in ["py", "rb", "php"]:
+ if not isWin32() and iceHome != "/usr" and getMapping() in ["py", "rb", "php", "objc"]:
libDir = os.path.join(getIceDir("cpp"), "lib")
if isUbuntu():
libDir = os.path.join(libDir, "x86_64-linux-gnu" if x64 else "i386-linux-gnu")
@@ -731,7 +731,7 @@ def spawn(command, cwd = None, mapping = None):
command = command.replace("java", "java -d64", 1)
if javaCmd != "java":
command = command.replace("java", javaCmd, 1)
- elif mapping == "cpp":
+ elif (mapping == "cpp" or mapping == "objc"):
if cwd != None:
desc = os.path.join(cwd, desc)
if isWin32():
diff --git a/man/man1/slice2objc.1 b/man/man1/slice2objc.1
new file mode 100644
index 00000000000..64672953a8c
--- /dev/null
+++ b/man/man1/slice2objc.1
@@ -0,0 +1,127 @@
+.TH slice2objc 1
+
+.SH NAME
+
+slice2objc - The Slice to Objective-C compiler.
+
+.SH SYNOPSIS
+
+slice2objc [options] [files]
+
+.SH DESCRIPTION
+
+slice2objc compiles Slice files to Objective-C.
+
+Full documentation for slice2objc is available online at:
+.br
+"http://doc.zeroc.com/display/Ice/slice2objc+Command-Line+Options".
+
+.SH OPTIONS
+
+.TP
+.BR \-h ", " \-\-help\fR
+.br
+Displays help message.
+
+.TP
+.BR \-v ", " \-\-version\fR
+Displays the compiler version.
+
+.TP
+.BR \-DNAME\fR
+.br
+Defines the preprocessor symbol NAME.
+
+.TP
+.BR \-DNAME=DEF\fR
+.br
+Defines the preprocessor symbol NAME with the value DEF.
+
+.TP
+.BR \-UNAME\fR
+.br
+Undefines the preprocessor symbol NAME.
+
+.TP
+.BR \-IDIR\fR
+.br
+Add the directory DIR to the search path for #include directives.
+
+.TP
+.BR \-E\fR
+.br
+Print the preprocessor output on stdout.
+
+.TP
+.BR \-\-output-dir " " DIR\fR
+.br
+Place the generated files into directory DIR.
+
+.TP
+.BR \-d ", " \-\-debug\fR
+.br
+Print debug information showing the operation of the Slice parser.
+
+.TP
+.BR \-\-ice\fR
+.br
+Permit use of the normally reserved prefix Ice for identifiers. Use this
+option only when compiling the source code for the Ice run time.
+
+.TP
+.BR \-\-underscore\fR
+.br
+Permit use of underscores in Slice identifiers.
+
+.TP
+.BR \-\-header-ext " " EXT\fR
+.br
+Changes the file extension for the generated header files from the default h
+to EXT.
+
+.TP
+.BR \-\-source-ext " " EXT\fR
+.br
+Changes the file extension for the generated source files from the default
+m to EXT.
+
+.TP
+.BR \-\-add-header " " HDR[,GUARD]
+.br
+This option adds an include directive for the specified header at the
+beginning of the generated source file (preceding any other include
+directives). If GUARD is specified, the include directive is protected by the
+specified guard.
+
+.TP
+.BR \-\-include-dir " " DIR\fR
+.br
+Modifies #include directives in source files to prepend the path name of each
+header file with the directory DIR.
+
+.TP
+.BR \-\-impl\fR
+.br
+Generate sample implementation files. This option will not overwrite an
+existing file.
+
+.TP
+.BR \-\-depend\fR
+Prints makefile dependency information to standard output.
+
+.TP
+.BR \-\-checksum\fR
+.br
+Generate checksums for Slice definitions.
+
+.SH SEE ALSO
+
+.BR slice2cpp (1),
+.BR slice2cs (1),
+.BR slice2freeze (1),
+.BR slice2freezej (1),
+.BR slice2html (1),
+.BR slice2java (1),
+.BR slice2php (1),
+.BR slice2py (1),
+.BR slice2rb (1)
diff --git a/objc/Makefile b/objc/Makefile
new file mode 100644
index 00000000000..23a6e75bb65
--- /dev/null
+++ b/objc/Makefile
@@ -0,0 +1,53 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = .
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = src include
+
+ifneq ($(MAKECMDGOALS),install)
+ SUBDIRS := $(SUBDIRS) test demo
+endif
+
+INSTALL_SUBDIRS = $(install_libdir)$(cpp11libdirsuffix) $(install_includedir)
+
+install:: install-common
+ @for subdir in $(INSTALL_SUBDIRS); \
+ do \
+ if test ! -d $(DESTDIR)$$subdir ; \
+ then \
+ echo "Creating $(DESTDIR)$$subdir..." ; \
+ mkdir -p $(DESTDIR)$$subdir ; \
+ chmod a+rx $(DESTDIR)$$subdir ; \
+ fi ; \
+ done
+ifeq ($(create_runpath_symlink),yes)
+ @if test -h $(embedded_runpath_prefix) ; \
+ then \
+ if `\rm -f $(embedded_runpath_prefix) 2>/dev/null`; \
+ then echo "Removed symbolic link $(embedded_runpath_prefix)"; fi \
+ fi
+ @if ! test -d $(embedded_runpath_prefix) ; \
+ then \
+ if `ln -s $(prefix) $(embedded_runpath_prefix) 2>/dev/null`; \
+ then echo "Created symbolic link $(embedded_runpath_prefix) --> $(prefix)"; fi \
+ fi
+endif
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
+
+test::
+ @python $(top_srcdir)/allTests.py
diff --git a/objc/allDemos.py b/objc/allDemos.py
new file mode 100755
index 00000000000..56b8230a2f9
--- /dev/null
+++ b/objc/allDemos.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os, sys
+
+for toplevel in [".", "..", "../..", "../../..", "../../../.."]:
+ toplevel = os.path.abspath(toplevel)
+ if os.path.exists(os.path.join(toplevel, "demoscript")):
+ break
+else:
+ raise RuntimeError("can't find toplevel directory!")
+
+sys.path.append(os.path.join(toplevel))
+from demoscript import Util
+
+#
+# List of all basic demos.
+#
+demos = [
+ "Ice/hello",
+ "Ice/minimal",
+ "Manual/simple_filesystem",
+ "Manual/printer"]
+
+if __name__ == "__main__":
+ Util.run(demos)
diff --git a/objc/allTests.py b/objc/allTests.py
new file mode 100755
index 00000000000..60b114d195c
--- /dev/null
+++ b/objc/allTests.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os, sys, re, getopt
+
+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 RuntimeError("can't find toplevel directory!")
+
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+#
+# List of all basic tests.
+#
+tests = [
+ ("Slice/keyword", []),
+ ("Ice/proxy", ["core"]),
+ ("Ice/ami", ["core"]),
+ ("Ice/operations", ["core"]),
+ ("Ice/exceptions", ["core"]),
+ ("Ice/inheritance", ["core"]),
+ ("Ice/invoke", ["core"]),
+ ("Ice/metrics", ["core", "nossl", "noipv6", "nocompress"]),
+ ("Ice/facets", ["core"]),
+ ("Ice/objects", ["core"]),
+ ("Ice/optional", ["core"]),
+ ("Ice/interceptor", ["core"]),
+ ("Ice/dispatcher", ["core"]),
+ ("Ice/defaultServant", ["core"]),
+ ("Ice/defaultValue", ["core"]),
+ ("Ice/binding", ["core"]),
+ ("Ice/stream", ["core"]),
+ ("Ice/hold", ["core"]),
+ ("Ice/faultTolerance", ["core"]),
+ ("Ice/location", ["core"]),
+ ("Ice/adapterDeactivation", ["core"]),
+ ("Ice/slicing/exceptions", ["core"]),
+ ("Ice/slicing/objects", ["core"]),
+ ("Ice/retry", ["core"]),
+ ("Ice/timeout", ["core"]),
+ ("Ice/hash", ["core"]),
+ ("Ice/info", ["core", "noipv6", "nocompress"]),
+ ("Ice/enums", ["once"]),
+ ]
+
+if __name__ == "__main__":
+ TestUtil.run(tests)
diff --git a/objc/config/Make.rules b/objc/config/Make.rules
new file mode 100644
index 00000000000..cd0847e0612
--- /dev/null
+++ b/objc/config/Make.rules
@@ -0,0 +1,194 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described
+# in the ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+#
+# Select an installation base directory. The directory will be created
+# if it does not exist.
+#
+prefix ?= /opt/Ice-$(VERSION)
+
+#
+# Define OPTIMIZE as yes if you want to build with
+# optimization. Otherwise Ice is build with debug information.
+#
+#OPTIMIZE = yes
+
+#
+# The "root directory" for runpath embedded in executables. Can be set
+# to change the runpath added to Ice executables. The default is
+# platform dependent.
+#
+#embedded_runpath_prefix ?= /opt/Ice-$(VERSION_MAJOR).$(VERSION_MINOR)
+
+#
+# Define create_runpath_symlink as yes if you would like 'make install'
+# to automatically create a symbolic link for the embedded runpath
+# directory. Only applies if embedded_runpath_prefix is also set.
+#
+create_runpath_symlink ?= no
+
+#
+# Define embedded_runpath as no if you don't want any RPATH added to
+# the executables.
+#
+embedded_runpath ?= yes
+
+#
+# The build architectures for gcc/llvm based builds. The format of
+# these build flags are OS dependent. For example, under OS X to
+# build binaries which support both i386 and x86_64 you would use
+# "-arch i386 -arch x86_64". The default is OS version dependent. Be
+# aware that this value may conflict with the setting of LP64 above.
+#
+#OBJCARCHFLAGS = -arch i386 -arch x86_64
+
+# ----------------------------------------------------------------------
+# Don't change anything below this line!
+# ----------------------------------------------------------------------
+
+#
+# Common definitions
+#
+ice_language = objc
+slice_translator = slice2objc
+
+ifeq ($(shell test -f $(top_srcdir)/config/Make.common.rules && echo 0),0)
+ include $(top_srcdir)/config/Make.common.rules
+else
+ include $(top_srcdir)/../config/Make.common.rules
+endif
+
+bindir = $(top_srcdir)/bin
+ifdef ice_src_dist
+ libdir = $(top_srcdir)/lib
+ includedir = $(top_srcdir)/include
+else
+ libdir = $(ice_dir)/$(libsubdir)
+ includedir = $(ice_dir)/include
+endif
+headerdir = $(top_srcdir)/include
+
+install_includedir := $(prefix)/include
+install_libdir := $(prefix)/$(libsubdir)
+install_bindir := $(prefix)/$(binsubdir)
+
+#
+# Platform specific definitions
+#
+include $(top_srcdir)/config/Make.rules.$(UNAME)
+
+ICECPPFLAGS = -I$(slicedir)
+SLICE2OBJCFLAGS = $(ICECPPFLAGS)
+FLEXFLAGS =
+BISONFLAGS = -dvt
+
+OBJDIR = .
+
+CPPFLAGS += -I$(includedir)
+LDFLAGS = $(OBJCFLAGS) -L$(libdir)
+
+ifdef ice_src_dist
+ ifeq ($(ice_cpp_dir), $(ice_dir)/cpp)
+ SLICE2OBJC = $(ice_cpp_dir)/bin/slice2objc
+ else
+ SLICE2OBJC = $(ice_cpp_dir)/$(binsubdir)/slice2objc
+ endif
+else
+ SLICE2OBJC = $(ice_dir)/$(binsubdir)/slice2objc
+endif
+
+# This cannot use .cpp:.o as we have multiple types of source files.
+
+EVERYTHING = all clean install
+EVERYTHING_EXCEPT_ALL = clean install
+
+.SUFFIXES:
+.SUFFIXES: .mm .m .o .cpp .c
+
+ifneq ($(SLICE_OBJS),)
+-include $(addprefix .depend/, $(SLICE_OBJS:.o=.ice.d))
+endif
+
+ifneq ($(OBJS),)
+-include $(addprefix .depend/, $(OBJS:.o=.d))
+endif
+
+ifeq ($(wildcard .depend/*.d),)
+ifneq ($(OBJCXX_OBJS),)
+$(OBJS): $(OBJC_OBJS:.o=.m) $(OBJCXX_OBJS:.o=.mm)
+else
+$(OBJS): $(OBJS:.o=.m)
+endif
+endif
+
+all:: $(TARGETS)
+
+.m.o:
+ $(CC) -c $(ARCFLAGS) $(CPPFLAGS) $(OBJCFLAGS) $<
+ @mkdir -p .depend
+ @$(CXX) -DMAKEDEPEND -M $(CPPFLAGS) $< > .depend/$(*F).d
+
+.mm.o:
+ $(CXX) -c $(ARCFLAGS) $(CPPFLAGS) $(OBJCFLAGS) $<
+ @mkdir -p .depend
+ @$(CXX) -DMAKEDEPEND -M $(CPPFLAGS) $< > .depend/$(*F).d
+
+$(HDIR)/%F.h: $(SDIR)/%F.ice $(SLICE2OBJC)
+ rm -f $(HDIR)/$(*F)F.h $(*F)F.m
+ $(SLICE2OBJC) $(SLICE2OBJCFLAGS) $<
+ mv $(*F)F.h $(HDIR)
+ @touch $(*F)F.m
+ @mkdir -p .depend
+ @$(SLICE2OBJC) $(SLICE2OBJCFLAGS) --depend $< | $(ice_dir)/config/makedepend.py "\$$(HDIR)/" > .depend/$(*F)F.ice.d
+
+$(HDIR)/%.h %.m: $(SDIR)/%.ice $(SLICE2OBJC)
+ rm -f $(HDIR)/$(*F).h $(*F).m
+ $(SLICE2OBJC) $(SLICE2OBJCFLAGS) $<
+ mv $(*F).h $(HDIR)
+ @touch $(*F).m
+ @mkdir -p .depend
+ @$(SLICE2OBJC) $(SLICE2OBJCFLAGS) --depend $< | $(ice_dir)/config/makedepend.py "\$$(HDIR)/" > .depend/$(*F).ice.d
+
+%.h %.m: %.ice $(SLICE2OBJC)
+ rm -f $(*F).h $(*F).m
+ $(SLICE2OBJC) $(SLICE2OBJCFLAGS) $<
+ @touch $(*F).m
+ @mkdir -p .depend
+ @$(SLICE2OBJC) $(SLICE2OBJCFLAGS) --depend $(*F).ice > .depend/$(*F).ice.d
+
+%.h %.m: %.y
+ rm -f $(*F).h $(*F).c
+ bison $(BISONFLAGS) $<
+ mv $(*F).tab.c $(*F).m
+ mv $(*F).tab.h $(*F).h
+ rm -f $(*F).output
+
+%.m: %.l
+ flex $(FLEXFLAGS) $<
+ rm -f $@
+ cat lex.yy.c >> $@
+ rm -f lex.yy.c
+
+clean::
+ -rm -f $(TARGETS)
+ -rm -f core *.o *.bak
+ -rm -rf .depend
+
+ifneq ($(SLICE_OBJS),)
+clean::
+ rm -f $(addsuffix .m, $(basename $(notdir $(SLICE_OBJS))))
+ rm -f $(addsuffix .h, $(basename $(notdir $(SLICE_OBJS))))
+endif
+
+ifneq ($(HDIR),)
+clean::
+ rm -f $(addprefix $(HDIR)/, $(addsuffix .h, $(basename $(SLICE_OBJS))))
+endif
+
+install::
diff --git a/objc/config/Make.rules.Darwin b/objc/config/Make.rules.Darwin
new file mode 100644
index 00000000000..af8d74ae7ae
--- /dev/null
+++ b/objc/config/Make.rules.Darwin
@@ -0,0 +1,101 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+#
+# This file is included by Make.rules when uname is Darwin.
+#
+
+OSX_TARGET_MIN_SDK_VERSION = 10.9
+
+CC = xcrun clang
+CXX = xcrun clang++
+
+CPPFLAGS += -pthread
+OBJCFLAGS += -Wall -Werror -mmacosx-version-min=$(OSX_TARGET_MIN_SDK_VERSION)
+
+
+#
+# By default we build x86_64 binaries.
+#
+ifeq ($(OBJCARCHFLAGS),)
+OBJCARCHFLAGS := -arch x86_64
+endif
+
+ifeq ($(OPTIMIZE),yes)
+ OBJCFLAGS := $(OBJCARCHFLAGS) -O2 -DNDEBUG $(OBJCFLAGS)
+else
+ OBJCFLAGS := $(OBJCARCHFLAGS) -g $(OBJCFLAGS)
+endif
+
+#
+# If embedded_runpath is not set to yes we do not add
+# an rpath dir.
+#
+ifeq ($(embedded_runpath),yes)
+ LOADER_PATH = @loader_path
+
+ #
+ # If embedded_runpath_prefix is set it has preference
+ #
+ ifneq ($(embedded_runpath_prefix),)
+ RPATH_DIR = $(embedded_runpath_prefix)
+ endif
+
+ ifeq ($(RPATH_DIR),)
+ ifdef ice_src_dist
+ RPATH_DIR = @loader_path/$(libdir)
+ else
+ RPATH_DIR = $(ice_dir)/$(libsubdir)
+ endif
+ endif
+
+ #
+ # Clear rpath setting when doing a system install
+ #
+ ifeq ($(ice_dir),/usr)
+ RPATH_DIR =
+ endif
+
+ ifneq ($(RPATH_DIR),)
+ LDEXEFLAGS = -Wl,-rpath,$(RPATH_DIR)
+ endif
+endif
+
+ifdef ice_src_dist
+rpathlink = -Wl,-rpath,$(1)
+endif
+
+#
+# Enable ARC for targets in demo/ and test/ subdirectories
+# when COMPILE_WITH_ARC is defined.
+#
+ifneq ($(findstring demo/,${CURDIR}),)
+TARGET_SUPPORT_ARC = yes
+endif
+
+ifneq ($(findstring test/,${CURDIR}),)
+TARGET_SUPPORT_ARC = yes
+endif
+
+ifeq ($(TARGET_SUPPORT_ARC),yes)
+ ifeq ($(COMPILE_WITH_ARC),yes)
+ #
+ # Don't add these to OBJCFLAGS flex and bison generated files used in
+ # some demos doesn't support ARC.
+ #
+ ARCFLAGS = -fobjc-arc -fobjc-arc-exceptions
+ endif
+endif
+
+mklib = libtool -static -o $(1) $(2)
+mkshlib = $(CXX) -dynamiclib $(LDFLAGS) -o $(1) -install_name @rpath/$(2) $(3) $(4)
+
+BASELIBS = -L$(ice_cpp_dir)/$(libsubdir) -lIce -lIceUtil -framework Foundation
+LIBS = -lIceObjC$(libsuffix) -framework Foundation
+TEST_LIBS = -lTestCommon $(LIBS)
diff --git a/objc/config/makegitignore.py b/objc/config/makegitignore.py
new file mode 100755
index 00000000000..27e149c99db
--- /dev/null
+++ b/objc/config/makegitignore.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os, sys, shutil, fnmatch, re, time, getopt
+
+#
+# NOTE: This scripts generates .gitignore files in directories
+# containing Makefile files with targets. The content of the
+# .gitignore file is generated by parsing the output of make -n
+# clean.
+#
+# In other words, the .gitignore file contains ignore rules for files
+# produced by the Makefile and supposed to be cleaned by make clean.
+#
+
+progname = os.path.basename(sys.argv[0])
+preamble = "// Generated by " + progname
+preamble = preamble + """
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+"""
+
+#
+# Find files matching a pattern.
+#
+def find(path, patt):
+ result = [ ]
+ files = os.listdir(path)
+ for x in files:
+ fullpath = os.path.join(path, x);
+ if os.path.isdir(fullpath) and not os.path.islink(fullpath):
+ result.extend(find(fullpath, patt))
+ elif fnmatch.fnmatch(x, patt):
+ result.append(fullpath)
+ return result
+
+
+def createGitIgnore(filename, gitIgnoreFiles):
+ file = open(filename, "r")
+ lines = file.readlines()
+ cwd = os.getcwd()
+ cwdStack = [] # Working directory stack
+ newLines = [ ]
+ ignore = ["*.o", "*.bak", "core"]
+
+ for x in lines:
+ x = x.strip()
+ if x.startswith("rm -f"):
+ x = x.replace("rm -f", "", 1)
+ elif x.startswith("rm -rf"):
+ x = x.replace("rm -rf", "", 1)
+ elif x.startswith("making clean in"):
+ # Don't clean sub-directories
+ break
+ else:
+ continue
+
+ if len(x) == 0:
+ continue
+
+ files = x.split()
+ for f in files:
+ if f in ignore:
+ continue
+
+ if f.startswith(".."):
+ k = os.path.join(cwd, os.path.dirname(f), ".gitignore")
+ v = os.path.basename(f) + "\n"
+ else:
+ k = os.path.join(cwd, ".gitignore")
+ v = f + "\n"
+
+ if v.find(".so.") > 0:
+ continue
+ elif v.endswith(".so\n"):
+ v = v.replace(".so", ".*")
+ elif v.endswith(".dylib\n"):
+ v = v.replace(".dylib", ".*")
+ if v.find('.', 0, len(v) - 3) > 0:
+ continue
+
+ k = os.path.normpath(k)
+ if not gitIgnoreFiles.has_key(k):
+ gitIgnoreFiles[k] = [ ]
+ gitIgnoreFiles[k].append(v)
+
+ file.close()
+
+def usage():
+ print "Usage: " + sys.argv[0] + " [options]"
+ print
+ print "Options:"
+ print "-e Run for Ice-E."
+ print "-h Show this message."
+ print
+
+icee = False
+try:
+ opts, args = getopt.getopt(sys.argv[1:], "he")
+except getopt.GetoptError:
+ usage()
+ sys.exit(1)
+for o, a in opts:
+ if o == "-h":
+ usage()
+ sys.exit(0)
+ elif o == "-e":
+ icee = True
+if len(args) != 0:
+ usage()
+ sys.exit(1)
+
+
+#
+# Find where the root of the tree is.
+#
+for toplevel in [".", "..", "../..", "../../..", "../../../.."]:
+ toplevel = os.path.abspath(toplevel)
+ if os.path.exists(os.path.join(toplevel, "objc", "config", "makegitignore.py")):
+ break
+else:
+ print("cannot find top-level directory")
+ sys.exit(1)
+
+makefiles = find(os.path.join(toplevel, "objc"), "Makefile")
+cwd = os.getcwd()
+gitIgnoreFiles = { }
+for i in makefiles:
+ os.chdir(os.path.dirname(i))
+ if not os.system('grep -q TARGETS Makefile'):
+ try:
+ os.system("make -n clean > .tmp-gitignore")
+ createGitIgnore(".tmp-gitignore", gitIgnoreFiles)
+ os.remove(".tmp-gitignore")
+ except:
+ os.remove(".tmp-gitignore")
+ raise
+ os.chdir(cwd)
+
+os.chdir(cwd)
+
+excludePath = [ os.path.join(toplevel, "objc", "bin"), os.path.join(toplevel, "objc", "lib") ]
+for (path, files) in gitIgnoreFiles.iteritems():
+ if os.path.dirname(path) in excludePath:
+ continue
+ if not os.path.exists(path):
+ print files
+ gitIgnore = open(path, "w")
+ gitIgnore.write(preamble);
+ gitIgnore.writelines(files)
+ gitIgnore.close()
+
diff --git a/objc/demo/Database/Makefile b/objc/demo/Database/Makefile
new file mode 100644
index 00000000000..5c67c5fb6ea
--- /dev/null
+++ b/objc/demo/Database/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = library
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/demo/Database/README b/objc/demo/Database/README
new file mode 100644
index 00000000000..2a61b68c0f7
--- /dev/null
+++ b/objc/demo/Database/README
@@ -0,0 +1,5 @@
+Demos in this directory:
+
+- library
+
+ This demo is a client for the java Database/library JDBC demo.
diff --git a/objc/demo/Database/library/.gitignore b/objc/demo/Database/library/.gitignore
new file mode 100644
index 00000000000..d5e7554b52d
--- /dev/null
+++ b/objc/demo/Database/library/.gitignore
@@ -0,0 +1,14 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+Library.m
+Session.m
+Glacier2Session.m
+Library.h
+Session.h
+Glacier2Session.h
+Grammar.m
+Grammar.h
+Scanner.m
diff --git a/objc/demo/Database/library/Client.m b/objc/demo/Database/library/Client.m
new file mode 100644
index 00000000000..0dca77cf622
--- /dev/null
+++ b/objc/demo/Database/library/Client.m
@@ -0,0 +1,57 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+
+#import <stdio.h>
+
+
+int runParser(int, char**, id<ICECommunicator>);
+
+int
+main(int argc, char* argv[])
+{
+ int status = 0;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties ];
+ [initData.properties load: @"config.client" ];
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ if(argc > 1)
+ {
+ fprintf(stderr, "%s: too many arguments\n", argv[0]);
+ return 1;
+ }
+ runParser(argc, argv, communicator);
+ }
+ @catch(ICELocalException* ex)
+ {
+ fprintf(stderr, "%s\n", [[ex description] UTF8String]);
+ status = 1;
+ }
+
+ if(communicator != nil)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICELocalException* ex)
+ {
+ fprintf(stderr, "%s\n", [[ex description] UTF8String]);
+ status = 1;
+ }
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Database/library/Glacier2Session.ice b/objc/demo/Database/library/Glacier2Session.ice
new file mode 100644
index 00000000000..1960983caef
--- /dev/null
+++ b/objc/demo/Database/library/Glacier2Session.ice
@@ -0,0 +1,47 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Glacier2/Session.ice>
+
+module Demo
+{
+
+/* Forward declaration. */
+interface Library;
+
+/**
+ *
+ * The session object. This is used to retrieve a per-session library
+ * on behalf of the client. If the session is not refreshed on a
+ * periodic basis, it will be automatically destroyed.
+ *
+ */
+interface Glacier2Session extends Glacier2::Session
+{
+ /**
+ *
+ * Get the library object.
+ *
+ * @return A proxy for the new library.
+ *
+ **/
+ Library* getLibrary();
+
+ /**
+ *
+ * Refresh a session. If a session is not refreshed on a regular
+ * basis by the client, it will be automatically destroyed.
+ *
+ **/
+ idempotent void refresh();
+};
+
+};
diff --git a/objc/demo/Database/library/Grammar.y b/objc/demo/Database/library/Grammar.y
new file mode 100644
index 00000000000..c8a9015e243
--- /dev/null
+++ b/objc/demo/Database/library/Grammar.y
@@ -0,0 +1,131 @@
+%{
+
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Parser.h>
+
+void
+yyerror(const char* s)
+{
+ [parser error: s];
+}
+
+%}
+
+%pure_parser
+
+%token TOK_HELP
+%token TOK_EXIT
+%token TOK_ADD_BOOK
+%token TOK_FIND_ISBN
+%token TOK_FIND_AUTHORS
+%token TOK_FIND_TITLE
+%token TOK_NEXT_FOUND_BOOK
+%token TOK_PRINT_CURRENT
+%token TOK_RENT_BOOK
+%token TOK_RETURN_BOOK
+%token TOK_REMOVE_CURRENT
+%token TOK_STRING
+
+%%
+
+// ----------------------------------------------------------------------
+start
+// ----------------------------------------------------------------------
+: commands
+{
+}
+|
+{
+}
+;
+
+// ----------------------------------------------------------------------
+commands
+// ----------------------------------------------------------------------
+: commands command
+{
+}
+| command
+{
+}
+;
+
+// ----------------------------------------------------------------------
+command
+// ----------------------------------------------------------------------
+: TOK_HELP ';'
+{
+ [parser usage];
+}
+| TOK_EXIT ';'
+{
+ return 0;
+}
+| TOK_ADD_BOOK strings ';'
+{
+ [parser addBook: $2];
+}
+| TOK_FIND_ISBN strings ';'
+{
+ [parser findIsbn: $2];
+}
+| TOK_FIND_AUTHORS strings ';'
+{
+ [parser findAuthors: $2];
+}
+| TOK_FIND_TITLE strings ';'
+{
+ [parser findTitle: $2];
+}
+| TOK_NEXT_FOUND_BOOK ';'
+{
+ [parser nextFoundBook];
+}
+| TOK_PRINT_CURRENT ';'
+{
+ [parser printCurrent];
+}
+| TOK_RENT_BOOK strings ';'
+{
+ [parser rentCurrent: $2];
+}
+| TOK_RETURN_BOOK ';'
+{
+ [parser returnCurrent];
+}
+| TOK_REMOVE_CURRENT ';'
+{
+ [parser removeCurrent];
+}
+| error ';'
+{
+ yyerrok;
+}
+| ';'
+{
+}
+;
+
+// ----------------------------------------------------------------------
+strings
+// ----------------------------------------------------------------------
+: TOK_STRING strings
+{
+ $$ = $2;
+ [$$ addObject: [$1 objectAtIndex:0]];
+}
+| TOK_STRING
+{
+ $$ = $1;
+}
+;
+
+%%
diff --git a/objc/demo/Database/library/Library.ice b/objc/demo/Database/library/Library.ice
new file mode 100644
index 00000000000..e4ed7f485f2
--- /dev/null
+++ b/objc/demo/Database/library/Library.ice
@@ -0,0 +1,285 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/BuiltinSequences.ice>
+
+module Demo
+{
+
+/**
+ *
+ * This local exception is used internally if a java.sql.SQLException
+ * is raised.
+ *
+ **/
+local exception JDBCException
+{
+};
+
+/**
+ *
+ * This exception is raised if the book already exists.
+ *
+ **/
+exception BookExistsException
+{
+};
+
+/**
+ *
+ * This exception is raised if a book has already been rented.
+ *
+ **/
+exception BookRentedException
+{
+ string renter;
+};
+
+/**
+ *
+ * This exception is raised if a customer name is invalid.
+ *
+ **/
+exception InvalidCustomerException
+{
+};
+
+/**
+ *
+ * This exception is raised if the book has not been rented.
+ *
+ **/
+exception BookNotRentedException
+{
+};
+
+/** Forward declaration for the interface Book. */
+interface Book;
+
+/**
+ *
+ * A description of a book.
+ *
+ **/
+struct BookDescription
+{
+ /** The ISBN number of the book. */
+ string isbn;
+
+ /** The title of the book. */
+ string title;
+
+ /** The authors of the book. */
+ ["java:type:java.util.LinkedList<String>:java.util.List<String>"] Ice::StringSeq authors;
+
+ /** The customer name of the renter. */
+ string rentedBy;
+
+ /** A proxy to the associated book. */
+ Book* proxy;
+};
+
+/** A sequence of book descriptions. */
+["java:type:java.util.LinkedList<BookDescription>:java.util.List<BookDescription>"]
+sequence<BookDescription> BookDescriptionSeq;
+
+/**
+ *
+ * This interface represents a book.
+ *
+ **/
+interface Book
+{
+ /**
+ *
+ * Get a description of the book.
+ *
+ * @return The book description.
+ *
+ **/
+ idempotent BookDescription describe();
+
+ /**
+ *
+ * Set the title of a book.
+ *
+ * @param title The book title.
+ *
+ **/
+ void setTitle(string title);
+
+ /**
+ *
+ * Set the book authors.
+ *
+ * @param authors The book authors.
+ *
+ **/
+ void setAuthors(["java:type:java.util.LinkedList<String>:java.util.List<String>"] Ice::StringSeq authors);
+
+ /**
+ *
+ * Rent the book to the specified customer.
+ *
+ * @param customer The customer.
+ *
+ * @throws BookRentedException Raised if the book has already been
+ * rented.
+ *
+ * @throws InvalidCustomerException Raised if the customer is invalid.
+ *
+ **/
+ void rentBook(string name)
+ throws InvalidCustomerException, BookRentedException;
+
+ /**
+ *
+ * Get the renter.
+ *
+ * @return The current rental customer.
+ *
+ * @throws BookNotRentedException Raised if the book is not
+ * currently rented.
+ *
+ **/
+ idempotent string getRenter()
+ throws BookNotRentedException;
+
+ /**
+ *
+ * Return the book.
+ *
+ * @throws BookNotRentedException Raised if the book is not
+ * currently rented.
+ *
+ **/
+ void returnBook()
+ throws BookNotRentedException;
+
+ /**
+ *
+ * Destroy the book.
+ *
+ **/
+ void destroy();
+};
+
+/**
+ *
+ * Interface to get query results.
+ *
+ **/
+interface BookQueryResult
+{
+ /**
+ *
+ * Get more query results.
+ *
+ * @param n The maximum number of results to return.
+ *
+ * @param destroyed There are no more results, and the query has
+ * been destroyed.
+ *
+ * @returns A sequence of up to n results.
+ *
+ **/
+ BookDescriptionSeq next(int n, out bool destroyed);
+
+ /**
+ *
+ * Destroy the query result.
+ *
+ **/
+ void destroy();
+};
+
+/**
+ *
+ * An interface to the library.
+ *
+ **/
+interface Library
+{
+ /**
+ *
+ * Query based on isbn number. The query is a partial match at the
+ * start of the isbn number.
+ *
+ * @param isbn The ISBN number.
+ *
+ * @param n The number of rows to retrieve in the initial request.
+
+ * @param first The first set of results, up to n results.
+ *
+ * @param nrows The total number of rows.
+ *
+ * @param result The remainder of the results. If there are no
+ * further results, a null proxy is returned.
+ *
+ **/
+ void queryByIsbn(string isbn, int n, out BookDescriptionSeq first, out int nrows, out BookQueryResult* result);
+
+ /**
+ *
+ * Query based on the author name. The query is a partial match of
+ * the author's name.
+ *
+ * @param author The authors name.
+ *
+ * @param n The number of rows to retrieve in the initial request.
+
+ * @param first The first set of results, up to n results.
+ *
+ * @param nrows The total number of rows.
+ *
+ * @param result The remainder of the results. If there are no
+ * further results, a null proxy is returned.
+ *
+ **/
+ void queryByAuthor(string author, int n, out BookDescriptionSeq first, out int nrows, out BookQueryResult* result);
+
+ /**
+ *
+ * Query based on the book title. The query is a partial match of
+ * the book title.
+ *
+ * @param author The authors name.
+ *
+ * @param n The number of rows to retrieve in the initial request.
+
+ * @param first The first set of results, up to n results.
+ *
+ * @param nrows The total number of rows.
+ *
+ * @param result The remainder of the results. If there are no
+ * further results, a null proxy is returned.
+ *
+ **/
+ void queryByTitle(string title, int n, out BookDescriptionSeq first, out int nrows, out BookQueryResult* result);
+
+ /**
+ *
+ * Create a book with the given description.
+ *
+ * @param description The book description.
+ *
+ * @return A proxy for the new book.
+ *
+ * @throws BookExistsException Raised if a book with the same ISBN
+ * number already exists.
+ *
+ **/
+ Book* createBook(string isbn, string title,
+ ["java:type:java.util.LinkedList<String>:java.util.List<String>"] Ice::StringSeq authors)
+ throws BookExistsException;
+};
+
+};
diff --git a/objc/demo/Database/library/Makefile b/objc/demo/Database/library/Makefile
new file mode 100644
index 00000000000..63d1578c319
--- /dev/null
+++ b/objc/demo/Database/library/Makefile
@@ -0,0 +1,47 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = Library.o \
+ Session.o \
+ Glacier2Session.o
+
+COBJS = Client.o \
+ Grammar.o \
+ Scanner.o \
+ Parser.o \
+ RunParser.o
+
+OBJS = $(SLICE_OBJS) $(COBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+#
+# Flex and bison generated files doesn't support ARC.
+#
+Grammar.o: Grammar.m
+ $(CC) -c $(CPPFLAGS) $(OBJCFLAGS) $(CFLAGS) $<
+
+Scanner.o: Scanner.m
+ $(CC) -c $(CPPFLAGS) $(OBJCFLAGS) $(CFLAGS) $<
+
+$(CLIENT): $(SLICE_OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(SLICE_OBJS) $(COBJS) -lGlacier2ObjC $(LIBS)
+
+clean::
+ -rm -f Grammar.m Grammar.h
+ -rm -f Scanner.m
diff --git a/objc/demo/Database/library/Parser.h b/objc/demo/Database/library/Parser.h
new file mode 100644
index 00000000000..a96518c049a
--- /dev/null
+++ b/objc/demo/Database/library/Parser.h
@@ -0,0 +1,80 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <Library.h>
+#import <Foundation/NSArray.h>
+
+//
+// Stuff for flex and bison
+//
+
+#define YYSTYPE NSMutableArray*
+#define YY_DECL int yylex(YYSTYPE* yylvalp)
+YY_DECL;
+int yyparse();
+
+//
+// I must set the initial stack depth to the maximum stack depth to
+// disable bison stack resizing. The bison stack resizing routines use
+// simple malloc/alloc/memcpy calls, which do not work for the
+// YYSTYPE, since YYSTYPE is a C++ type, with constructor, destructor,
+// assignment operator, etc.
+//
+#define YYMAXDEPTH 10000 // 10000 should suffice. Bison default is 10000 as maximum.
+#define YYINITDEPTH YYMAXDEPTH // Initial depth is set to max depth, for the reasons described above.
+
+//
+// Newer bison versions allow to disable stack resizing by defining
+// yyoverflow.
+//
+#define yyoverflow(a, b, c, d, e, f) yyerror(a)
+
+
+@interface Parser : NSObject
+{
+@private
+
+DemoBookQueryResultPrx* query;
+DemoBookDescription* current;
+id<DemoLibraryPrx> library;
+
+BOOL cont;
+int errors;
+}
+
+-(id)initWithLibrary:(id<DemoLibraryPrx>) library;
++(id)parserWithLibrary:(id<DemoLibraryPrx>) library;
+
+-(void) usage;
+
+-(void) addBook:(NSArray*) data;
+-(void) findIsbn:(NSArray*)data;
+-(void) findAuthors:(NSArray*)data;
+-(void) findTitle:(NSArray*)data;
+-(void) nextFoundBook;
+-(void) printCurrent;
+-(void) rentCurrent:(NSArray*)data;
+-(void) returnCurrent;
+-(void) removeCurrent;
+
+-(int) getInput:(char*)buf max:(int)max;
+-(void) continueLine;
+
+-(void) error:(const char*) s;
+-(void) errorWithString:(NSString*) s;
+
+-(void) warning:(const char*) s;
+-(void) warningWithString:(NSString*) s;
+
+-(int)parse;
+
+@end
+
+extern Parser* parser; // The current parser for bison/flex
diff --git a/objc/demo/Database/library/Parser.m b/objc/demo/Database/library/Parser.m
new file mode 100644
index 00000000000..d9f50abe999
--- /dev/null
+++ b/objc/demo/Database/library/Parser.m
@@ -0,0 +1,486 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Parser.h>
+#import <string.h>
+#import <stdio.h>
+
+extern FILE* yyin;
+Parser* parser;
+
+@interface Parser()
+
+@property(nonatomic, retain) DemoBookQueryResultPrx* query;
+@property(nonatomic, retain) DemoBookDescription* current;
+@property(nonatomic, retain) id<DemoLibraryPrx> library;
+
+@end
+
+@implementation Parser
+
+@synthesize query;
+@synthesize current;
+@synthesize library;
+
+-(id)initWithLibrary:(id<DemoLibraryPrx>)lib
+{
+ if((self = [super init]))
+ {
+ self.library = lib;
+ }
+ return self;
+}
+
++(id)parserWithLibrary:(id<DemoLibraryPrx>)library
+{
+ return [[Parser alloc] initWithLibrary:library];
+}
+
+-(void)usage
+{
+ printf("help Print this message.\n"
+ "exit, quit Exit this program.\n"
+ "add isbn title authors Create new book.\n"
+ "isbn NUMBER Find all books that start with the given ISBN number.\n"
+ "authors NAME Find all books by the given authors.\n"
+ "title NAME Find all books which have the given title.\n"
+ "next Set the current book to the next one that was found.\n"
+ "current Display the current book.\n"
+ "rent NAME Rent the current book for customer NAME.\n"
+ "return Return the currently rented book.\n"
+ "remove Permanently remove the current book from the library.\n");
+}
+
+-(void)addBook:(NSArray*)args
+{
+ if(args.count != 3)
+ {
+ [self errorWithString:@"`add' requires exactly three arguments (type `help' for more info)"];
+ return;
+ }
+
+ @try
+ {
+ NSString* isbn = [args objectAtIndex:0];
+ NSString* title = [args objectAtIndex:1];
+
+ NSArray* authors = [[args objectAtIndex:2] componentsSeparatedByString:@","];
+ [library createBook:isbn title:title authors:authors];
+ printf("added new book with isbn %s\n", [isbn UTF8String]);
+ }
+ @catch(DemoBookExistsException* ex)
+ {
+ [self errorWithString:@"the book already exists"];
+ }
+ @catch(ICELocalException* ex)
+ {
+ [self errorWithString:[ex description]];
+ }
+}
+-(void)findIsbn:(NSArray*)args
+{
+ if(args.count != 1)
+ {
+ [self errorWithString:@"`isbn' requires exactly one argument (type `help' for more info)"];
+ return;
+ }
+
+ @try
+ {
+ if(query != nil)
+ {
+ @try
+ {
+ [query destroy];
+ }
+ @catch(ICEException* e)
+ {
+ // Ignore
+ }
+
+ self.query = nil;
+ self.current = nil;
+ }
+
+ id<DemoBookQueryResultPrx> q;
+ DemoMutableBookDescriptionSeq *results;
+ int nrows;
+ [library queryByIsbn:[args objectAtIndex:0] n:1 first:&results nrows:&nrows result:&q];
+
+ printf("%d results\n", nrows);
+ if(nrows == 0)
+ {
+ return;
+ }
+
+ self.current = [results objectAtIndex:0];
+ self.query = q;
+
+ [self printCurrent];
+ }
+ @catch(ICELocalException* ex)
+ {
+ [self errorWithString:[ex description]];
+ }
+}
+
+-(void)findAuthors:(NSArray*)args
+{
+ if(args.count != 1)
+ {
+ [self errorWithString:@"`authors' requires exactly one argument (type `help' for more info)"];
+ return;
+ }
+
+ @try
+ {
+ if(query != nil)
+ {
+ @try
+ {
+ [query destroy];
+ }
+ @catch(ICEException* e)
+ {
+ // Ignore
+ }
+ self.query = nil;
+ self.current = nil;
+ }
+
+ id<DemoBookQueryResultPrx> q;
+ DemoMutableBookDescriptionSeq *results;
+ int nrows;
+ [library queryByAuthor:[args objectAtIndex:0] n:1 first:&results nrows:&nrows result:&q];
+
+ printf("%d results\n", nrows);
+ if(nrows == 0)
+ {
+ return;
+ }
+
+ self.current = [results objectAtIndex:0];
+ self.query = q;
+
+ [self printCurrent];
+ }
+ @catch(ICELocalException* ex)
+ {
+ [self errorWithString:[ex description]];
+ }
+}
+
+-(void)findTitle:(NSArray*)args
+{
+ if(args.count != 1)
+ {
+ [self errorWithString:@"`title' requires exactly one argument (type `help' for more info)"];
+ return;
+ }
+
+ @try
+ {
+ if(query != nil)
+ {
+ @try
+ {
+ [query destroy];
+ }
+ @catch(ICEException* e)
+ {
+ // Ignore
+ }
+ self.query = nil;
+ self.current = nil;
+ }
+
+ id<DemoBookQueryResultPrx> q;
+ DemoMutableBookDescriptionSeq *results;
+ int nrows;
+ [library queryByTitle:[args objectAtIndex:0] n:1 first:&results nrows:&nrows result:&q];
+
+ printf("%d results\n", nrows);
+ if(nrows == 0)
+ {
+ return;
+ }
+
+ self.current = [results objectAtIndex:0];
+ self.query = q;
+ [self printCurrent];
+ }
+ @catch(ICELocalException* ex)
+ {
+ [self errorWithString:[ex description]];
+ }
+}
+
+-(void)nextFoundBook
+{
+ if(query == nil)
+ {
+ printf("no next book\n");
+ return;
+ }
+
+ @try
+ {
+ BOOL destroyed;
+ NSArray* next = [query next:1 destroyed:&destroyed];
+ if(next.count > 0)
+ {
+ self.current = [next objectAtIndex:0];
+ }
+ else
+ {
+ NSAssert(destroyed, @"");
+ self.current = nil;
+ }
+
+ if(destroyed)
+ {
+ self.query = nil;
+ }
+
+ [self printCurrent];
+ }
+ @catch(ICEObjectNotExistException* ex)
+ {
+ printf("the query object no longer exists\n");
+ }
+ @catch(ICELocalException* ex)
+ {
+ [self errorWithString:[ex description]];
+ }
+}
+
+-(void)printCurrent
+{
+ if(current != nil)
+ {
+ printf("current book is:\n");
+ printf("isbn: %s\n", [current.isbn UTF8String]);
+ printf("title: %s\n", [current.title UTF8String]);
+ NSMutableString* auth = [[NSMutableString alloc] init];
+ for(NSString* s in current.authors)
+ {
+ if(s != [current.authors objectAtIndex:0])
+ {
+ [auth appendString:@", "];
+ }
+ [auth appendString:s];
+ }
+ printf("authors: %s\n", [auth UTF8String]);
+ if([current.rentedBy length] > 0)
+ {
+ printf("rented: %s\n", [current.rentedBy UTF8String]);
+ }
+ }
+ else
+ {
+ printf("no current book\n");
+ }
+}
+
+-(void)rentCurrent:(NSArray*)args
+{
+ if(args.count != 1)
+ {
+ [self errorWithString:@"`rent' requires exactly one argument (type `help' for more info)"];
+ return;
+ }
+
+ @try
+ {
+ if(current != nil)
+ {
+ [current.proxy rentBook:[args objectAtIndex:0]];
+ printf("the book is now rented by `%s'\n", [[args objectAtIndex:0] UTF8String]);
+ self.current = [current.proxy describe];
+ }
+ else
+ {
+ printf("no current book\n");
+ }
+ }
+ @catch(DemoBookRentedException* ex)
+ {
+ printf("the book has already been rented.\n");
+ }
+ @catch(ICEObjectNotExistException* ex)
+ {
+ printf("current book no longer exists\n");
+ }
+ @catch(ICELocalException* ex)
+ {
+ [self errorWithString:[ex description]];
+ }
+}
+
+-(void)returnCurrent
+{
+ @try
+ {
+ if(current != nil)
+ {
+ [current.proxy returnBook];
+ printf( "the book has been returned.\n");
+ self.current = [current.proxy describe];
+ }
+ else
+ {
+ printf("no current book\n");
+ }
+ }
+ @catch(DemoBookNotRentedException* ex)
+ {
+ printf("the book is not currently rented.\n");
+ }
+ @catch(ICEObjectNotExistException* ex)
+ {
+ printf("current book no longer exists\n");
+ }
+ @catch(ICELocalException* ex)
+ {
+ [self errorWithString:[ex description]];
+ }
+}
+
+-(void)removeCurrent
+{
+ @try
+ {
+ if(current != nil)
+ {
+ [current.proxy destroy];
+ self.current = nil;
+ printf("removed current book\n");
+ }
+ else
+ {
+ printf("no current book\n");
+ }
+ }
+ @catch(ICEObjectNotExistException* ex)
+ {
+ printf("current book no longer exists\n");
+ }
+ @catch(ICELocalException* ex)
+ {
+ [self errorWithString:[ex description]];
+ }
+}
+
+-(const char*)getPrompt
+{
+ if(cont)
+ {
+ cont = NO;
+ return "(cont) ";
+ }
+ else
+ {
+ return ">>> ";
+ }
+}
+
+-(int)getInput:(char*)buf max:(int)max
+{
+ printf("%s", self.getPrompt);
+ fflush(stdout);
+
+ NSMutableData* line = [[ NSMutableData alloc] init];
+ while(true)
+ {
+ char c = (char)(getc(yyin));
+ if(c == EOF)
+ {
+ if([line length])
+ {
+ c = '\n';
+ [line appendBytes:&c length:1];
+ }
+ break;
+ }
+
+ [line appendBytes:&c length:1];
+
+ if(c == '\n')
+ {
+ break;
+ }
+ }
+ NSString* ss = [[NSString alloc] initWithData:line encoding:NSUTF8StringEncoding];
+ int len;
+ const char* utf8 = [ss UTF8String];
+
+ len = strlen(utf8);
+ if(len > max)
+ {
+ [self errorWithString:@"input line too long"];
+ buf[0] = EOF;
+ return 1;
+ }
+ else
+ {
+ strcpy(buf, utf8);
+ }
+
+ return len;
+}
+
+-(void)continueLine
+{
+ cont = YES;
+}
+
+-(void)error:(const char*)s
+{
+ fprintf(stderr, "error: %s\n", s);
+}
+
+-(void)errorWithString:(NSString*)s
+{
+ fprintf(stderr, "error: %s\n", [s UTF8String]);
+}
+
+-(void)warning:(const char*)s
+{
+ fprintf(stderr, "warning: %s\n", s);
+}
+
+-(void)warningWithString:(NSString*)s
+{
+ fprintf(stderr, "warning: %s\n", [s UTF8String]);
+}
+
+-(int)parse
+{
+ NSAssert(!parser, @"");
+ parser = self;
+
+ errors = 0;
+ yyin = stdin;
+ NSAssert(yyin, @"");
+
+ cont = false;
+
+ self.query = nil;
+ self.current = nil;
+
+ int status = yyparse();
+ if(errors)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ parser = nil;
+ return status;
+}
+@end
diff --git a/objc/demo/Database/library/README b/objc/demo/Database/library/README
new file mode 100644
index 00000000000..67b558bb87d
--- /dev/null
+++ b/objc/demo/Database/library/README
@@ -0,0 +1,14 @@
+This demo is an Ice Touch client for the Java library demo located
+at demoj/Database/library in the Ice distribution. This application
+provides a command line interface to the library server. It permits
+you to:
+
+ - Create and delete books
+ - Query for books by ISBN, author or title
+ - Rent and return books
+
+ZeroC hosts a server for this demo on demo2.zeroc.com, which is the
+default host used by this client. The deployment on demo2.zeroc.com
+accepts both secure and non-secure connections using Glacier2. Direct
+connections to the library session manager are not permitted on
+demo2.zeroc.com.
diff --git a/objc/demo/Database/library/RunParser.m b/objc/demo/Database/library/RunParser.m
new file mode 100644
index 00000000000..8e61c7ea02d
--- /dev/null
+++ b/objc/demo/Database/library/RunParser.m
@@ -0,0 +1,215 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <objc/Glacier2.h>
+#import <Library.h>
+#import <Session.h>
+#import <Glacier2Session.h>
+#import <Parser.h>
+#import <stdio.h>
+#import <string.h>
+
+#import <Foundation/NSThread.h>
+#import <Foundation/NSLock.h>
+
+@interface SessionRefreshThread : NSThread
+{
+@private
+ id<ICELogger> logger;
+ id session;
+ NSCondition* cond;
+
+ long timeout;
+}
+
+-(id)initWithLogger:(id<ICELogger>) logger timeout:(long)timeout session:(id)session;
++(id)sessionRefreshThreadWithLogger:(id<ICELogger>)logger timeout:(long)timeout session:(id)session;
+@end
+
+@interface SessionRefreshThread()
+@property (nonatomic, retain) id<ICELogger> logger;
+@property (nonatomic, retain) id session;
+@property (nonatomic, retain) NSCondition* cond;
+@end
+
+@implementation SessionRefreshThread
+
+@synthesize logger;
+@synthesize session;
+@synthesize cond;
+
+-(id)initWithLogger:(id<ICELogger>)l timeout:(long)t session:(id)s
+{
+ if((self = [super init]))
+ {
+ self.logger = l;
+ self.session = s;
+ self.cond = [[NSCondition alloc] init];
+ timeout = t;
+ }
+ return self;
+}
+
++(id)sessionRefreshThreadWithLogger:(id<ICELogger>)logger timeout:(long)timeout session:(id)session
+{
+ return [[SessionRefreshThread alloc] initWithLogger:logger timeout:timeout session:session];
+}
+
+-(void)main
+{
+ [cond lock];
+ @try
+ {
+ while(!self.isCancelled)
+ {
+ [cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:timeout]];
+ if(!self.isCancelled)
+ {
+ @try
+ {
+ [session refresh];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSString* warning = [NSString stringWithFormat:@"SessionRefreshThread: %@", [ex description]];
+ [logger warning:warning];
+ [super cancel];
+ }
+ }
+ }
+ }
+ @finally
+ {
+ [cond unlock];
+ }
+}
+
+-(void)cancel
+{
+ [super cancel];
+ [cond lock];
+ @try
+ {
+ [cond signal];
+ }
+ @finally
+ {
+ [cond unlock];
+ }
+}
+
+@end
+
+int
+runParser(int argc, char* argv[], id<ICECommunicator> communicator)
+{
+ id<GLACIER2RouterPrx> router = [GLACIER2RouterPrx uncheckedCast:[communicator getDefaultRouter]];
+ ICELong timeout;
+ id<DemoLibraryPrx> library;
+ id session;
+ if(router != nil)
+ {
+ printf("This demo accepts any user-id / password combination.\n");
+
+ while(true)
+ {
+ char id[1024];
+ printf("user id: ");
+ fflush(stdout);
+ fgets(id, sizeof(id), stdin);
+ int len = strlen(id);
+ if(id[len-1] == '\n')
+ {
+ id[len-1] = '\0';
+ }
+ printf("password: ");
+ fflush(stdout);
+ char pw[1024];
+ fgets(pw, sizeof(pw), stdin);
+ len = strlen(pw);
+ if(pw[len-1] == '\n')
+ {
+ pw[len-1] = '\0';
+ }
+
+ @try
+ {
+ session = [DemoGlacier2SessionPrx uncheckedCast:
+ [router createSession:[NSString stringWithCString:id encoding:NSUTF8StringEncoding]
+ password:[NSString stringWithCString:pw encoding:NSUTF8StringEncoding]]];
+ break;
+ }
+ @catch(GLACIER2PermissionDeniedException* ex)
+ {
+ printf("permission denied:\n%s\n", [ex.reason UTF8String]);
+ }
+ @catch(GLACIER2CannotCreateSessionException* ex)
+ {
+ printf("cannot create session:\n%s\n", [ex.reason UTF8String]);
+ }
+ }
+ timeout = [router getSessionTimeout]/2;
+ library = [session getLibrary];
+ }
+ else
+ {
+ id<DemoSessionFactoryPrx> factory = [DemoSessionFactoryPrx checkedCast:[
+ communicator propertyToProxy:@"SessionFactory.Proxy"] ];
+ if(factory == nil)
+ {
+ fprintf(stderr, "%s: invalid object reference", argv[0]);
+ return 1;
+ }
+
+ session = [factory create];
+ timeout = [factory getSessionTimeout]/2;
+ library = [session getLibrary];
+ }
+
+ SessionRefreshThread* refresh = [SessionRefreshThread sessionRefreshThreadWithLogger:[communicator getLogger]
+ timeout:timeout/2 session:session];
+ [refresh start];
+
+ Parser* parser = [Parser parserWithLibrary:library];
+
+ int rc = [parser parse];
+
+ [refresh cancel];
+
+ // No join.
+ while(!refresh.isFinished)
+ {
+ [NSThread sleepForTimeInterval:0.1];
+ }
+
+ if(router)
+ {
+ @try
+ {
+ [router destroySession];
+ }
+ @catch(GLACIER2SessionNotExistException* ex)
+ {
+ NSLog(@"%@\n", [ex description]);
+ }
+ @catch(ICEConnectionLostException* ex)
+ {
+ //
+ // Expected: the router closed the connection.
+ //
+ }
+ }
+ else
+ {
+ [session destroy];
+ }
+
+ return rc;
+}
diff --git a/objc/demo/Database/library/Scanner.l b/objc/demo/Database/library/Scanner.l
new file mode 100644
index 00000000000..5c87279c213
--- /dev/null
+++ b/objc/demo/Database/library/Scanner.l
@@ -0,0 +1,257 @@
+%{
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Parser.h>
+#include <Grammar.h>
+#include <ctype.h>
+
+#import <Foundation/NSString.h>
+#import <Foundation/NSData.h>
+
+#define YY_INPUT(buf, result, maxSize) \
+ { \
+ result = [parser getInput: buf max: maxSize ]; \
+ }
+
+%}
+
+WS [ \t\v\f\r]
+NL [\n]
+
+%option noyywrap
+%option always-interactive
+
+%%
+
+"//" {
+ // C++-style comment
+ int c;
+ do
+ {
+ c = input();
+ }
+ while(c != '\n' && c != EOF);
+}
+
+"/*" {
+ // C-style comment
+ while(true)
+ {
+ int c = input();
+ if(c == '*')
+ {
+ int next = input();
+ if(next == '/')
+ {
+ break;
+ }
+ else
+ {
+ unput(next);
+ }
+ }
+ else if(c == EOF)
+ {
+ [parser warning: "EOF in comment"];
+ break;
+ }
+ }
+}
+
+"help" {
+ return TOK_HELP;
+}
+
+"quit"|"exit" {
+ return TOK_EXIT;
+}
+
+"add" {
+ return TOK_ADD_BOOK;
+}
+
+"isbn" {
+ return TOK_FIND_ISBN;
+}
+
+"authors" {
+ return TOK_FIND_AUTHORS;
+}
+
+"title" {
+ return TOK_FIND_TITLE;
+}
+
+"next" {
+ return TOK_NEXT_FOUND_BOOK;
+}
+
+"current" {
+ return TOK_PRINT_CURRENT;
+}
+
+"rent" {
+ return TOK_RENT_BOOK;
+}
+
+"return" {
+ return TOK_RETURN_BOOK;
+}
+
+"remove" {
+ return TOK_REMOVE_CURRENT;
+}
+
+{WS}*(\\{WS}*{NL})? {
+ size_t len = strlen(yytext);
+ size_t i;
+ for(i = 0; i < len; ++i)
+ {
+ if(yytext[i] == '\\')
+ {
+ [parser continueLine];
+ }
+ }
+}
+
+{NL}|; {
+ return ';';
+}
+
+\" {
+ // "..."-type strings
+ NSMutableData* s = [ [ NSMutableData alloc] init];
+ while(true)
+ {
+ char c = (char)(input());
+ if(c == '"')
+ {
+ break;
+ }
+ else if(c == EOF)
+ {
+ [parser warning: "EOF in string"];
+ break;
+ }
+ else if(c == '\\')
+ {
+ char next = (char)(input());
+ switch(next)
+ {
+ case '\\':
+ case '"':
+ {
+ c = next;
+ break;
+ }
+
+ case 'n':
+ {
+ c = '\n';
+ break;
+ }
+
+ case 'r':
+ {
+ c = '\r';
+ break;
+ }
+
+ case 't':
+ {
+ c = '\t';
+ break;
+ }
+
+ case 'v':
+ {
+ c = '\v';
+ break;
+ }
+
+ case 'f':
+ {
+ c = '\f';
+ break;
+ }
+
+ default:
+ {
+ unput(next);
+ }
+ }
+ }
+ [s appendBytes: &c length: 1];
+ }
+
+ *yylvalp = [NSMutableArray array];
+ NSString* ss = [ [NSString alloc] initWithData: s encoding: NSUTF8StringEncoding ];
+ [s release];
+ [*yylvalp addObject: ss];
+ [ss release];
+ return TOK_STRING;
+}
+
+\' {
+ // '...'-type strings
+ NSMutableData* s = [ [ NSMutableData alloc] init];
+ while(true)
+ {
+ char c = (char)(input());
+ if(c == '\'')
+ {
+ break;
+ }
+ else if(c == EOF)
+ {
+ [parser warning: "EOF in string"];
+ break;
+ }
+ else
+ {
+ [s appendBytes: &c length: 1];
+ }
+ }
+ *yylvalp = [NSMutableArray array];
+ NSString* ss = [ [NSString alloc] initWithData: s encoding: NSUTF8StringEncoding ];
+ [s release];
+ [*yylvalp addObject: ss];
+ [ss release];
+ return TOK_STRING;
+}
+
+. {
+ // Simple strings
+ NSMutableData* s = [ [ NSMutableData alloc] init];
+ [s appendBytes: yytext length: 1];
+ while(true)
+ {
+ char c = (char)(input());
+ if(c == EOF)
+ {
+ break;
+ }
+ else if(isspace(c) || c == ';')
+ {
+ unput(c);
+ break;
+ }
+
+ [s appendBytes: &c length: 1];
+ }
+ *yylvalp = [NSMutableArray array];
+ NSString* ss = [ [NSString alloc] initWithData: s encoding: NSUTF8StringEncoding ];
+ [s release];
+ [*yylvalp addObject: ss];
+ [ss release];
+ return TOK_STRING;
+}
+
+%%
diff --git a/objc/demo/Database/library/Session.ice b/objc/demo/Database/library/Session.ice
new file mode 100644
index 00000000000..3592981f45b
--- /dev/null
+++ b/objc/demo/Database/library/Session.ice
@@ -0,0 +1,79 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+module Demo
+{
+
+/* Forward declaration. */
+interface Library;
+
+/**
+ *
+ * The session object. This is used to retrieve a per-session library
+ * on behalf of the client. If the session is not refreshed on a
+ * periodic basis, it will be automatically destroyed.
+ *
+ */
+interface Session
+{
+ /**
+ *
+ * Get the library object.
+ *
+ * @return A proxy for the new library.
+ *
+ **/
+ Library* getLibrary();
+
+ /**
+ *
+ * Refresh a session. If a session is not refreshed on a regular
+ * basis by the client, it will be automatically destroyed.
+ *
+ **/
+ idempotent void refresh();
+
+ /**
+ *
+ * Destroy the session.
+ *
+ **/
+ void destroy();
+};
+
+/**
+ *
+ * Interface to create new sessions.
+ *
+ **/
+interface SessionFactory
+{
+ /**
+ *
+ * Create a session.
+ *
+ * @return A proxy to the session.
+ *
+ **/
+ Session* create();
+
+ /**
+ *
+ * Get the value of the session timeout. Sessions are destroyed
+ * if they see no activity for this period of time.
+ *
+ * @return The timeout (in seconds).
+ *
+ **/
+ ["nonmutating", "cpp:const"] idempotent long getSessionTimeout();
+};
+
+};
diff --git a/objc/demo/Database/library/config.client b/objc/demo/Database/library/config.client
new file mode 100644
index 00000000000..a43a5cd0ef2
--- /dev/null
+++ b/objc/demo/Database/library/config.client
@@ -0,0 +1,68 @@
+#
+# The client reads this property to create the reference to the
+# "SessionFactory" object in the server.
+#
+#SessionFactory.Proxy=SessionFactory:default -p 10000
+
+#
+# The proxy to the Glacier2 router for all outgoing connections. This
+# must match the value of Glacier2.Client.Endpoints in config.glacier2.
+#
+Ice.Default.Router=DemoGlacier2/router:ssl -p 4064 -h demo2.zeroc.com -t 10000
+
+#
+# If you want to use a local demo server, uncomment this line and change
+# the SSL setup below.
+#
+#Ice.Default.Router=DemoGlacier2/router:ssl -p 4064 -h 127.0.0.1 -t 10000
+
+#
+# No active connection management is permitted because of the session
+# interfaces. Connections must remain established.
+#
+Ice.ACM.Client=0
+
+#
+# Connection retry is not possible because of the session
+# interfaces. Connections must remain established.
+#
+Ice.RetryIntervals=-1
+
+#
+# Warn about connection exceptions
+#
+#Ice.Warn.Connections=1
+
+#
+# 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
+
+#
+# Security Tracing
+#
+# 0 = no security tracing
+# 1 = trace messages
+#
+#IceSSL.Trace.Security=1
+
+#
+# SSL Configuration
+#
+IceSSL.CertAuthFile=cacert.pem
+IceSSL.DefaultDir=../../../../certs
+IceSSL.TrustOnly.Client=CN="127.0.0.1"
+IceSSL.CheckCertName=0
diff --git a/objc/demo/Ice/Makefile b/objc/demo/Ice/Makefile
new file mode 100644
index 00000000000..ebe1e47f7e4
--- /dev/null
+++ b/objc/demo/Ice/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = minimal hello helloRouter optional
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/demo/Ice/README b/objc/demo/Ice/README
new file mode 100644
index 00000000000..77bae89714f
--- /dev/null
+++ b/objc/demo/Ice/README
@@ -0,0 +1,20 @@
+Demos in this directory:
+
+- hello
+
+ This demo illustrates how to invoke ordinary (twoway) operations, as
+ well as how to invoke oneway operations, use datagrams, secure
+ invocations, and how to use batched invocations.
+
+- helloRouter
+
+ This demo illustrates how to use the hello demo server from your
+ Mac with the iPhone router demo (demo/iPhone/router).
+
+- minimal
+
+ This demo illustrates a minimal Ice application.
+
+- optional
+
+ This demo shows the use of the optional keyword.
diff --git a/objc/demo/Ice/hello/.gitignore b/objc/demo/Ice/hello/.gitignore
new file mode 100644
index 00000000000..652acdba5de
--- /dev/null
+++ b/objc/demo/Ice/hello/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+Hello.m
+Hello.h
diff --git a/objc/demo/Ice/hello/Client.m b/objc/demo/Ice/hello/Client.m
new file mode 100644
index 00000000000..7897f0f6e1a
--- /dev/null
+++ b/objc/demo/Ice/hello/Client.m
@@ -0,0 +1,246 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <Hello.h>
+
+#import <stdio.h>
+
+void
+menu()
+{
+ printf("usage:\n"
+ "t: send greeting as twoway\n"
+ "o: send greeting as oneway\n"
+ "O: send greeting as batch oneway\n"
+ "d: send greeting as datagram\n"
+ "D: send greeting as batch datagram\n"
+ "f: flush all batch requests\n"
+ "T: set a timeout\n"
+ "P: set server delay\n"
+ "S: switch secure mode on/off\n"
+ "s: shutdown server\n"
+ "x: exit\n"
+ "?: help\n");
+}
+
+int
+run(int argc, char* argv[], id<ICECommunicator> communicator)
+{
+ if(argc > 1)
+ {
+ fprintf(stderr, "%s: too many arguments\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ id<DemoHelloPrx> twoway = [DemoHelloPrx checkedCast:
+ [[[[communicator propertyToProxy:@"Hello.Proxy"] ice_twoway] ice_timeout:-1] ice_secure:NO]];
+ if(!twoway)
+ {
+ fprintf(stderr, "%s: invalid proxy\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+ id<DemoHelloPrx> oneway = [twoway ice_oneway];
+ id<DemoHelloPrx> batchOneway = [twoway ice_batchOneway];
+ id<DemoHelloPrx> datagram = [twoway ice_datagram];
+ id<DemoHelloPrx> batchDatagram = [twoway ice_batchDatagram];
+
+ BOOL secure = NO;
+ int timeout = -1;
+ int delay = 0;
+
+ menu();
+
+ char c = 0;
+ do
+ {
+ @try
+ {
+ printf("==> ");
+ fflush(stdout);
+
+ do
+ {
+ c = getchar();
+ }
+ while(c != EOF && c == '\n');
+ if(c == 't')
+ {
+ [twoway sayHello:delay];
+ }
+ else if(c == 'o')
+ {
+ [oneway sayHello:delay];
+ }
+ else if(c == 'O')
+ {
+ [batchOneway sayHello:delay];
+ }
+ else if(c == 'd')
+ {
+ if(secure)
+ {
+ printf("secure datagrams are not supported\n");
+ fflush(stdout);
+ }
+ else
+ {
+ [datagram sayHello:delay];
+ }
+ }
+ else if(c == 'D')
+ {
+ if(secure)
+ {
+ printf("secure datagrams are not supported\n");
+ fflush(stdout);
+ }
+ else
+ {
+ [batchDatagram sayHello:delay];
+ }
+ }
+ else if(c == 'f')
+ {
+ [communicator flushBatchRequests];
+ }
+ else if(c == 'T')
+ {
+ if(timeout == -1)
+ {
+ timeout = 2000;
+ }
+ else
+ {
+ timeout = -1;
+ }
+
+ twoway = [twoway ice_timeout:timeout];
+ oneway = [oneway ice_timeout:timeout];
+ batchOneway = [batchOneway ice_timeout:timeout];
+
+ if(timeout == -1)
+ {
+ printf("timeout is now switched off\n");
+ fflush(stdout);
+ }
+ else
+ {
+ printf("timeout is now set to 2000ms\n");
+ fflush(stdout);
+ }
+ }
+ else if(c == 'P')
+ {
+ if(delay == 0)
+ {
+ delay = 2500;
+ }
+ else
+ {
+ delay = 0;
+ }
+
+ if(delay == 0)
+ {
+ printf("server delay is now deactivated\n");
+ fflush(stdout);
+ }
+ else
+ {
+ printf("server delay is now set to 2500ms\n");
+ fflush(stdout);
+ }
+ }
+ else if(c == 'S')
+ {
+ secure = !secure;
+
+ twoway = [twoway ice_secure:secure];
+ oneway = [oneway ice_secure:secure];
+ batchOneway = [batchOneway ice_secure:secure];
+ datagram = [datagram ice_secure:secure];
+ batchDatagram = [batchDatagram ice_secure:secure];
+
+ if(secure)
+ {
+ printf("secure mode is now on\n");
+ fflush(stdout);
+ }
+ else
+ {
+ printf("secure mode is now off\n");
+ fflush(stdout);
+ }
+ }
+ else if(c == 's')
+ {
+ [twoway shutdown];
+ }
+ else if(c == 'x')
+ {
+ // Nothing to do
+ }
+ else if(c == '?')
+ {
+ menu();
+ }
+ else
+ {
+ printf("unknown command `%c'\n", c);
+ menu();
+ }
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ }
+ }
+ while(c != EOF && c != 'x');
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_SUCCESS;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties];
+ [initData.properties load:@"config.client"];
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(argc, argv, communicator);
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator != nil)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Ice/hello/Hello.ice b/objc/demo/Ice/hello/Hello.ice
new file mode 100644
index 00000000000..f75c9795b97
--- /dev/null
+++ b/objc/demo/Ice/hello/Hello.ice
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+module Demo
+{
+
+interface Hello
+{
+ idempotent void sayHello(int delay);
+ void shutdown();
+};
+
+};
diff --git a/objc/demo/Ice/hello/HelloI.h b/objc/demo/Ice/hello/HelloI.h
new file mode 100644
index 00000000000..667f2cc2ca4
--- /dev/null
+++ b/objc/demo/Ice/hello/HelloI.h
@@ -0,0 +1,14 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Hello.h>
+
+@interface HelloI : DemoHello<DemoHello>
++(id) helloI;
+@end
diff --git a/objc/demo/Ice/hello/HelloI.m b/objc/demo/Ice/hello/HelloI.m
new file mode 100644
index 00000000000..b0d53885710
--- /dev/null
+++ b/objc/demo/Ice/hello/HelloI.m
@@ -0,0 +1,44 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <HelloI.h>
+
+#import <Foundation/NSThread.h>
+
+#import <stdio.h>
+
+@implementation HelloI
++(id) helloI
+{
+ id instance = [[HelloI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [instance autorelease];
+#endif
+ return instance;
+}
+
+-(void) sayHello:(int)delay current:(ICECurrent*)c
+{
+ if(delay != 0)
+ {
+ [NSThread sleepForTimeInterval:delay / 1000.f];
+ }
+ printf("Hello World!\n");
+ fflush(stdout);
+}
+
+-(void) shutdown:(ICECurrent*)c
+{
+ printf("Shutting down...\n");
+ fflush(stdout);
+ [[c.adapter getCommunicator] shutdown];
+}
+
+@end
diff --git a/objc/demo/Ice/hello/Makefile b/objc/demo/Ice/hello/Makefile
new file mode 100644
index 00000000000..3678dc05eaf
--- /dev/null
+++ b/objc/demo/Ice/hello/Makefile
@@ -0,0 +1,36 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = Hello.o
+
+COBJS = Client.o \
+
+SOBJS = HelloI.o \
+ Server.o
+
+OBJS = $(SLICE_OBJS) $(COBJS) $(SOBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(CLIENT): $(SLICE_OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(COBJS) $(LIBS)
+
+$(SERVER): $(SLICE_OBJS) $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(SOBJS) $(LIBS)
diff --git a/objc/demo/Ice/hello/README b/objc/demo/Ice/hello/README
new file mode 100644
index 00000000000..2d4632f3228
--- /dev/null
+++ b/objc/demo/Ice/hello/README
@@ -0,0 +1,43 @@
+The demo shows how to make:
+
+ - Twoway invocations. This is the default mode for any remote
+ invocation. A twoway invocation is not complete until a reply has
+ been received from the server.
+
+ - Oneway invocations. A oneway invocation is complete as soon as the
+ client has successfully sent the invocation. Oneway invocations
+ may not return values or throw user exceptions.
+
+ - Oneway batched invocations. See below for details on batching.
+
+ - Datagram invocations. Datagram invocations use the udp transport,
+ and as such have very minimal quality of service guarantees.
+ Datagram invocations are always oneway.
+
+ - Datagram batched invocations. See below for details on batching.
+
+Batching, which is only possible when using oneway or datagram
+invocations, combines several Ice messages into a single physical
+protocol message. Batching can result in higher throughput and smaller
+physical messages due to less protocol overhead. Ice does not actually
+send a batched message until it is flushed.
+
+If you enable secure invocations, oneway and twoway operations are
+sent using the SSL transport. It is not possible to secure datagram
+invocations.
+
+To run the demo, first start the server:
+
+$ server
+
+In a separate window, start the client:
+
+$ client
+
+To test timeouts you can use 'T' to set a timeout on the client proxy
+and 'P' to set a delayed response in the server to cause a timeout.
+You will notice that two "Hello World!" messages will be printed by
+the server in this case. This happens because the Slice operation
+sayHello is marked as idempotent, meaning that Ice does not need to
+preserve the at-most-once retry semantics. See the manual for
+more information about retry behavior.
diff --git a/objc/demo/Ice/hello/Server.m b/objc/demo/Ice/hello/Server.m
new file mode 100644
index 00000000000..50e3c4ab51b
--- /dev/null
+++ b/objc/demo/Ice/hello/Server.m
@@ -0,0 +1,65 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <HelloI.h>
+
+
+int
+run(int argc, char* argv[], id<ICECommunicator> communicator)
+{
+ if(argc > 1)
+ {
+ NSLog(@"%s: too many arguments", argv[0]);
+ return EXIT_FAILURE;
+ }
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"Hello"];
+ [adapter add:[HelloI helloI] identity:[communicator stringToIdentity:@"hello"]];
+ [adapter activate];
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_SUCCESS;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties];
+ [initData.properties load:@"config.server"];
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(argc, argv, communicator);
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator != nil)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Ice/hello/config.client b/objc/demo/Ice/hello/config.client
new file mode 100644
index 00000000000..d43ea2b6723
--- /dev/null
+++ b/objc/demo/Ice/hello/config.client
@@ -0,0 +1,65 @@
+#
+# The client reads this property to create the reference to the
+# "hello" object in the server.
+#
+Hello.Proxy=hello:tcp -p 10000:udp -p 10000:ssl -p 10001
+
+#
+# Uncomment to use the WebSocket transports instead.
+#
+#Hello.Proxy=hello:ws -p 10002:udp -p 10000:wss -p 10003
+
+#
+# Only connect to the localhost interface by default.
+#
+Ice.Default.Host=localhost
+
+#
+# Warn about connection exceptions
+#
+Ice.Warn.Connections=1
+
+#
+# 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
+
+#
+# Security Tracing
+#
+# 0 = no security tracing
+# 1 = trace messages
+#
+#IceSSL.Trace.Security=1
+
+#
+# SSL Configuration
+#
+Ice.Plugin.IceSSL=IceSSL:createIceSSL
+IceSSL.DefaultDir=../../../../certs
+IceSSL.CertAuthFile=cacert.pem
+IceSSL.CertFile=c_rsa1024.pfx
+IceSSL.Password=password
+IceSSL.Keychain=client.keychain
+IceSSL.KeychainPassword=password
+
+#
+# IceMX configuration.
+#
+#Ice.Admin.Endpoints=tcp -p 10004
+Ice.Admin.InstanceName=client
+IceMX.Metrics.Debug.GroupBy=id
+IceMX.Metrics.ByParent.GroupBy=parent
diff --git a/objc/demo/Ice/hello/config.server b/objc/demo/Ice/hello/config.server
new file mode 100644
index 00000000000..bb96a7a798b
--- /dev/null
+++ b/objc/demo/Ice/hello/config.server
@@ -0,0 +1,74 @@
+#
+# The server creates one single object adapter with the name
+# "Hello". The following line sets the endpoints for this
+# adapter.
+#
+# When no -h <host> option is specified in the endpoints, the default
+# value from the Ice.Default.Host property is used. If this property
+# isn't set, the endpoints will listen on all available network
+# interfaces.
+#
+Hello.Endpoints=tcp -p 10000:udp -p 10000:ssl -p 10001:ws -p 10002:wss -p 10003
+
+#
+# Only listen on the localhost interface by default. You can comment
+# out this property to allow listening on all available interfaces.
+#
+Ice.Default.Host=localhost
+
+#
+# For secure WebSocket (WSS) clients and Windows Store App clients,
+# you should disable this property. JavaScript browser clients and
+# Windows Store App clients don't use client-side authentication.
+#
+#IceSSL.VerifyPeer=0
+
+#
+# Warn about connection exceptions
+#
+Ice.Warn.Connections=1
+
+#
+# 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
+
+#
+# Security Tracing
+#
+# 0 = no security tracing
+# 1 = trace messages
+#
+#IceSSL.Trace.Security=1
+
+#
+# SSL Configuration
+#
+Ice.Plugin.IceSSL=IceSSL:createIceSSL
+IceSSL.DefaultDir=../../../../certs
+IceSSL.CertAuthFile=cacert.pem
+IceSSL.CertFile=s_rsa1024.pfx
+IceSSL.Password=password
+IceSSL.Keychain=server.keychain
+IceSSL.KeychainPassword=password
+
+#
+# IceMX configuration
+#
+#Ice.Admin.Endpoints=tcp -p 10004
+Ice.Admin.InstanceName=server
+IceMX.Metrics.Debug.GroupBy=id
+IceMX.Metrics.ByParent.GroupBy=parent
diff --git a/objc/demo/Ice/hello/expect.py b/objc/demo/Ice/hello/expect.py
new file mode 100755
index 00000000000..1a4bbf96ccb
--- /dev/null
+++ b/objc/demo/Ice/hello/expect.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import sys, os
+
+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, "demoscript")) ]
+if len(path) == 0:
+ raise RuntimeError("can't find toplevel directory!")
+sys.path.append(path[0])
+
+from demoscript import Util
+from demoscript.Ice import hello
+
+server = Util.spawn('./server --Ice.PrintAdapterReady --Ice.Warn.Connections=0')
+server.expect('.* ready')
+client = Util.spawn('./client --Ice.Warn.Connections=0')
+client.expect('.*==>')
+
+hello.run(client, server)
diff --git a/objc/demo/Ice/helloRouter/.gitignore b/objc/demo/Ice/helloRouter/.gitignore
new file mode 100644
index 00000000000..8660bff4f6c
--- /dev/null
+++ b/objc/demo/Ice/helloRouter/.gitignore
@@ -0,0 +1,9 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+Hello.m
+Router.m
+Hello.h
+Router.h
diff --git a/objc/demo/Ice/helloRouter/Client.m b/objc/demo/Ice/helloRouter/Client.m
new file mode 100644
index 00000000000..a67b120f7c0
--- /dev/null
+++ b/objc/demo/Ice/helloRouter/Client.m
@@ -0,0 +1,133 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <Hello.h>
+#import <Router.h>
+
+#import <stdio.h>
+
+
+void
+menu()
+{
+ printf("usage:\n"
+ "t: send greeting as twoway\n"
+ "o: send greeting as oneway\n"
+ "s: shutdown server\n"
+ "x: exit\n"
+ "?: help\n");
+}
+
+int
+run(int argc, char* argv[], id<ICECommunicator> communicator)
+{
+ if(argc > 1)
+ {
+ fprintf(stderr, "%s: too many arguments\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ id<DemoRouterPrx> router = [DemoRouterPrx checkedCast:[communicator getDefaultRouter]];
+ [router createSession];
+
+ id<DemoHelloPrx> twoway = [DemoHelloPrx checkedCast:[communicator propertyToProxy:@"Hello.Proxy"]];
+ if(!twoway)
+ {
+ fprintf(stderr, "%s: invalid proxy\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+ id<DemoHelloPrx> oneway = [twoway ice_oneway];
+
+ menu();
+
+ char c = 0;
+ do
+ {
+ @try
+ {
+ printf("==> ");
+ do
+ {
+ c = getchar();
+ }
+ while(c != EOF && c == '\n');
+ if(c == 't')
+ {
+ [twoway sayHello:0];
+ }
+ else if(c == 'o')
+ {
+ [oneway sayHello:0];
+ }
+ else if(c == 's')
+ {
+ [twoway shutdown];
+ }
+ else if(c == 'x')
+ {
+ // Nothing to do
+ }
+ else if(c == '?')
+ {
+ menu();
+ }
+ else
+ {
+ printf("unknown command `%c'\n", c);
+ menu();
+ }
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ }
+ }
+ while(c != EOF && c != 'x');
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_SUCCESS;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties];
+ [initData.properties load:@"config.client"];
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(argc, argv, communicator);
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator != nil)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Ice/helloRouter/Hello.ice b/objc/demo/Ice/helloRouter/Hello.ice
new file mode 100644
index 00000000000..f75c9795b97
--- /dev/null
+++ b/objc/demo/Ice/helloRouter/Hello.ice
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+module Demo
+{
+
+interface Hello
+{
+ idempotent void sayHello(int delay);
+ void shutdown();
+};
+
+};
diff --git a/objc/demo/Ice/helloRouter/Makefile b/objc/demo/Ice/helloRouter/Makefile
new file mode 100644
index 00000000000..fe4ef49348f
--- /dev/null
+++ b/objc/demo/Ice/helloRouter/Makefile
@@ -0,0 +1,29 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = Hello.o \
+ Router.o
+
+COBJS = Client.o
+
+OBJS = $(SLICE_OBJS) $(COBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(CLIENT): $(SLICE_OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(COBJS) -lGlacier2Objc $(LIBS)
diff --git a/objc/demo/Ice/helloRouter/README b/objc/demo/Ice/helloRouter/README
new file mode 100644
index 00000000000..f6a4f3a9560
--- /dev/null
+++ b/objc/demo/Ice/helloRouter/README
@@ -0,0 +1,12 @@
+This is a version of the hello demo for use with the iPhone router
+demo in demo/iPhone/router.
+
+To run the demo, first start the hello server in demo/Ice/hello:
+
+$ server
+
+Next start the router demo in demo/iPhone/router on the iPhone.
+
+Finally, in a separate window, start the client:
+
+$ client
diff --git a/objc/demo/Ice/helloRouter/Router.ice b/objc/demo/Ice/helloRouter/Router.ice
new file mode 100644
index 00000000000..8161446f594
--- /dev/null
+++ b/objc/demo/Ice/helloRouter/Router.ice
@@ -0,0 +1,70 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Glacier2/Router.ice>
+
+module Demo
+{
+
+/**
+ *
+ * The Demo router interface. This router is used to route requests directly
+ * to an Ice server.
+ *
+ **/
+interface Router extends Ice::Router
+{
+ /**
+ *
+ * Create a new session. The returned category must be used in the
+ * identities of all of the client's callback objects. This is necessary
+ * in order for the router to forward callback requests to the intended
+ * client.
+ *
+ * @return A category.
+ *
+ */
+ string createSession();
+
+ /**
+ *
+ * Create a new glacier2 session.
+ *
+ * @param router A proxy to the Glacier2 router.
+ *
+ * @param username The user id for which to check the password.
+ *
+ * @param password The password for the given user id.
+ *
+ * @param category The returned category that must be used in the
+ * identities of all of the client's callback objects.
+ *
+ * @param sessionTimeout The session timeout.
+ *
+ * @param sess The A proxy for the newly created session, or null
+ * if no [Glacier2::SessionManager] was defined.
+ *
+ * @throws Glacier2::PermissionDeniedException Raised if the password for
+ * the given user id is not correct, or if the user is not allowed
+ * access.
+ *
+ * @throws Glacier2::CannotCreateSessionException Raised if the session
+ * cannot be created.
+ *
+ */
+
+ void createGlacier2Session(Ice::Router* router, string userId, string password,
+ out string category, out int sessionTimeout,
+ out Glacier2::Session* sess)
+ throws Glacier2::PermissionDeniedException, Glacier2::CannotCreateSessionException;
+};
+
+};
diff --git a/objc/demo/Ice/helloRouter/config.client b/objc/demo/Ice/helloRouter/config.client
new file mode 100644
index 00000000000..134bdea5ab1
--- /dev/null
+++ b/objc/demo/Ice/helloRouter/config.client
@@ -0,0 +1,57 @@
+#
+# Proxy to the iPhone router.
+#
+Ice.Default.Router=iPhoneRouter/Router:tcp -h 169.254.37.90 -p 12000
+
+#
+# The client reads this property to create the reference to the
+# "hello" object in the server.
+#
+Hello.Proxy=hello:tcp -p 10000
+
+#
+# Warn about connection exceptions
+#
+Ice.Warn.Connections=1
+
+#
+# Client-side ACM is enabled by default, with an interval of 60
+# seconds. For this demo, we want to use a short timeout of 10
+# seconds. By enabling network tracing below, you can see ACM
+# automatically close idle connections.
+#
+Ice.ACM.Client=10
+
+#
+# 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
+
+#
+# Security Tracing
+#
+# 0 = no security tracing
+# 1 = trace messages
+#
+#IceSSL.Trace.Security=1
+
+#
+# SSL Configuration
+#
+IceSSL.DefaultDir=../../../../certs
+IceSSL.CertAuthFile=cacert.pem
+IceSSL.CertFile=c_rsa1024_pub.pem
+IceSSL.KeyFile=c_rsa1024_priv.pem
diff --git a/objc/demo/Ice/minimal/.gitignore b/objc/demo/Ice/minimal/.gitignore
new file mode 100644
index 00000000000..652acdba5de
--- /dev/null
+++ b/objc/demo/Ice/minimal/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+Hello.m
+Hello.h
diff --git a/objc/demo/Ice/minimal/Client.m b/objc/demo/Ice/minimal/Client.m
new file mode 100644
index 00000000000..b467d83af7a
--- /dev/null
+++ b/objc/demo/Ice/minimal/Client.m
@@ -0,0 +1,59 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <Hello.h>
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_SUCCESS;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ communicator = [ICEUtil createCommunicator:&argc argv:argv];
+ if(argc > 1)
+ {
+ NSLog(@"%s: too many arguments", argv[0]);
+ return EXIT_FAILURE;
+ }
+ id<DemoHelloPrx> hello = [DemoHelloPrx checkedCast:[communicator stringToProxy:@"hello:default -p 10000"]];
+ if(hello == nil)
+ {
+ NSLog(@"%s: invalid proxy", argv[0]);
+ status = EXIT_FAILURE;
+ }
+ else
+ {
+ [hello sayHello];
+ }
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator != nil)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Ice/minimal/Hello.ice b/objc/demo/Ice/minimal/Hello.ice
new file mode 100644
index 00000000000..33d311622fa
--- /dev/null
+++ b/objc/demo/Ice/minimal/Hello.ice
@@ -0,0 +1,20 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+module Demo
+{
+
+interface Hello
+{
+ idempotent void sayHello();
+};
+
+};
diff --git a/objc/demo/Ice/minimal/HelloI.h b/objc/demo/Ice/minimal/HelloI.h
new file mode 100644
index 00000000000..667f2cc2ca4
--- /dev/null
+++ b/objc/demo/Ice/minimal/HelloI.h
@@ -0,0 +1,14 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Hello.h>
+
+@interface HelloI : DemoHello<DemoHello>
++(id) helloI;
+@end
diff --git a/objc/demo/Ice/minimal/HelloI.m b/objc/demo/Ice/minimal/HelloI.m
new file mode 100644
index 00000000000..e9e75b9a362
--- /dev/null
+++ b/objc/demo/Ice/minimal/HelloI.m
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <HelloI.h>
+
+#include <stdio.h>
+
+@implementation HelloI
++(id) helloI
+{
+ id instance = [[HelloI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [instance autorelease];
+#endif
+ return instance;
+}
+
+-(void) sayHello:(ICECurrent*)current
+{
+ printf("Hello World!\n");
+ fflush(stdout);
+}
+@end
diff --git a/objc/demo/Ice/minimal/Makefile b/objc/demo/Ice/minimal/Makefile
new file mode 100644
index 00000000000..3678dc05eaf
--- /dev/null
+++ b/objc/demo/Ice/minimal/Makefile
@@ -0,0 +1,36 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = Hello.o
+
+COBJS = Client.o \
+
+SOBJS = HelloI.o \
+ Server.o
+
+OBJS = $(SLICE_OBJS) $(COBJS) $(SOBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(CLIENT): $(SLICE_OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(COBJS) $(LIBS)
+
+$(SERVER): $(SLICE_OBJS) $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(SOBJS) $(LIBS)
diff --git a/objc/demo/Ice/minimal/README b/objc/demo/Ice/minimal/README
new file mode 100644
index 00000000000..6052065fb3a
--- /dev/null
+++ b/objc/demo/Ice/minimal/README
@@ -0,0 +1,14 @@
+This demo is a minimal Ice "hello world" application. Each time the
+client is run, a "sayHello" invocation is sent to the server.
+
+To run the demo, first start the server:
+
+$ server
+
+In a separate window, start the client:
+
+$ client
+
+Note that this demo hardwires port 10000. If port 10000 is not
+available on your machine, you need to edit both client and server
+to use a free port.
diff --git a/objc/demo/Ice/minimal/Server.m b/objc/demo/Ice/minimal/Server.m
new file mode 100644
index 00000000000..b77cc035819
--- /dev/null
+++ b/objc/demo/Ice/minimal/Server.m
@@ -0,0 +1,55 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <HelloI.h>
+
+int
+main(int argc, char* argv[])
+{
+ int status = 0;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ communicator = [ICEUtil createCommunicator:&argc argv:argv];
+ if(argc > 1)
+ {
+ NSLog(@"%s: too many arguments", argv[0]);
+ return 1;
+ }
+
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapterWithEndpoints:@"Hello"
+ endpoints:@"default -p 10000"];
+ [adapter add:[HelloI helloI] identity:[communicator stringToIdentity:@"hello"]];
+ [adapter activate];
+ [communicator waitForShutdown];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = 1;
+ }
+
+ if(communicator != nil)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = 1;
+ }
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Ice/minimal/expect.py b/objc/demo/Ice/minimal/expect.py
new file mode 100755
index 00000000000..64a271f1549
--- /dev/null
+++ b/objc/demo/Ice/minimal/expect.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import sys, os, signal
+
+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, "demoscript")) ]
+if len(path) == 0:
+ raise RuntimeError("can't find toplevel directory!")
+sys.path.append(path[0])
+
+from demoscript import Util
+
+server = Util.spawn('./server --Ice.PrintAdapterReady')
+server.expect('.* ready')
+
+sys.stdout.write("testing... ")
+sys.stdout.flush()
+client = Util.spawn('./client')
+client.waitTestSuccess()
+server.expect('Hello World!')
+print("ok")
+
+server.kill(signal.SIGINT)
+server.waitTestFail()
diff --git a/objc/demo/Ice/optional/.gitignore b/objc/demo/Ice/optional/.gitignore
new file mode 100644
index 00000000000..4d4a8840fe8
--- /dev/null
+++ b/objc/demo/Ice/optional/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+Contact.m
+Contact.h
diff --git a/objc/demo/Ice/optional/Client.m b/objc/demo/Ice/optional/Client.m
new file mode 100644
index 00000000000..7aeed28e5b8
--- /dev/null
+++ b/objc/demo/Ice/optional/Client.m
@@ -0,0 +1,246 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <Contact.h>
+
+#import <stdio.h>
+
+int
+run(int argc, char* argv[], id<ICECommunicator> communicator)
+{
+ if(argc > 1)
+ {
+ fprintf(stderr, "%s: too many arguments\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ id<DemoContactDBPrx> contactdb = [DemoContactDBPrx checkedCast:[communicator propertyToProxy:@"ContactDB.Proxy"]];
+ if(contactdb == nil)
+ {
+ fprintf(stderr, "%s: invalid proxy\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ //
+ // Add a contact for "john". All parameters are provided.
+ //
+ NSString* johnNumber = @"123-456-7890";
+ [contactdb addContact:@"john" type:@(DemoHOME) number:johnNumber dialGroup:@0];
+
+ printf("Checking john... ");
+
+ //
+ // Find the phone number for "john"
+ //
+ id number = [contactdb queryNumber:@"john"];
+
+ //
+ // Compare number to ICENone to check if the optional value is set.
+ //
+ if(number == ICENone)
+ {
+ printf("number is incorrect ");
+ }
+
+ //
+ // If not ICENone, the optional is the number NSString.
+ //
+ if(![number isEqual:johnNumber])
+ {
+ printf("number is incorrect ");
+ }
+
+ // Optional can also be used in an out parameter.
+ id dialgroup;
+ [contactdb queryDialgroup:@"john" dialGroup:&dialgroup];
+ if(dialgroup == ICENone || [dialgroup intValue] != 0)
+ {
+ printf("dialgroup is incorrect ");
+ }
+
+ DemoContact* info = [contactdb query:@"john"];
+ //
+ // All of the info parameters should be set.
+ //
+ if(![info hasType] || ![info hasNumber] || ![info hasDialGroup])
+ {
+ printf("info is incorrect ");
+ }
+ else if(info.type != DemoHOME || ![info.number isEqual:johnNumber] || info.dialGroup != 0)
+ {
+ printf("info is incorrect ");
+ }
+ printf("ok\n");
+
+ //
+ // Add a contact for "steve". The behavior of the server is to
+ // default construct the Contact, and then assign all set parameters.
+ // Since the default value of NumberType in the slice definition
+ // is HOME and in this case the NumberType is unset it will take
+ // the default value.
+ //
+ NSString* steveNumber = @"234-567-8901";
+ [contactdb addContact:@"steve" type:ICENone number:steveNumber dialGroup:@1];
+
+ printf("Checking steve... ");
+ number = [contactdb queryNumber:@"steve"];
+ if(![number isEqual:steveNumber])
+ {
+ printf("number is incorrect ");
+ }
+
+ info = [contactdb query:@"steve"];
+ //
+ // Check the value for the NumberType.
+ //
+ if(![info hasType] || info.type != DemoHOME)
+ {
+ printf("info is incorrect ");
+ }
+
+ if(![info.number isEqual:steveNumber] || info.dialGroup != 1)
+ {
+ printf("info is incorrect ");
+ }
+
+ [contactdb queryDialgroup:@"steve" dialGroup:&dialgroup];
+ if(dialgroup == ICENone || [dialgroup intValue] != 1)
+ {
+ printf("dialgroup is incorrect ");
+ }
+
+ printf("ok\n");
+
+ //
+ // Add a contact from "frank". Here the dialGroup field isn't set.
+ //
+ NSString* frankNumber = @"345-678-9012";
+ [contactdb addContact:@"frank" type:@(DemoCELL) number:frankNumber dialGroup:ICENone];
+
+ printf("Checking frank... ");
+
+ number = [contactdb queryNumber:@"frank"];
+ if(![number isEqual:frankNumber])
+ {
+ printf("number is incorrect ");
+ }
+
+ info = [contactdb query:@"frank"];
+ //
+ // The dial group field should be unset.
+ //
+ if([info hasDialGroup])
+ {
+ printf("info is incorrect ");
+ }
+ if(info.type != DemoCELL || ![info.number isEqual:frankNumber])
+ {
+ printf("info is incorrect ");
+ }
+
+ [contactdb queryDialgroup:@"frank" dialGroup:&dialgroup];
+ if(dialgroup != ICENone)
+ {
+ printf("dialgroup is incorrect ");
+ }
+ printf("ok\n");
+
+ //
+ // Add a contact from "anne". The number field isn't set.
+ //
+ [contactdb addContact:@"anne" type:@(DemoOFFICE) number:ICENone dialGroup:@2];
+
+ printf("Checking anne... ");
+ number = [contactdb queryNumber:@"anne"];
+ if(number != ICENone)
+ {
+ printf("number is incorrect ");
+ }
+
+ info = [contactdb query:@"anne"];
+ //
+ // The number field should be unset.
+ //
+ if([info hasNumber])
+ {
+ printf("info is incorrect ");
+ }
+ if(info.type != DemoOFFICE || info.dialGroup != 2)
+ {
+ printf("info is incorrect ");
+ }
+
+ [contactdb queryDialgroup:@"anne" dialGroup:&dialgroup];
+ if(dialgroup == ICENone || [dialgroup intValue] != 2)
+ {
+ printf("dialgroup is incorrect ");
+ }
+
+ //
+ // The optional fields can be used to determine what fields to
+ // update on the contact. Here we update only the number for anne,
+ // the remainder of the fields are unchanged.
+ //
+ NSString* anneNumber = @"456-789-0123";
+ [contactdb updateContact:@"anne" type:ICENone number:anneNumber dialGroup:ICENone];
+ number = [contactdb queryNumber:@"anne"];
+ if(![number isEqual:anneNumber])
+ {
+ printf("number is incorrect ");
+ }
+ info = [contactdb query:@"anne"];
+ if(![info.number isEqual:anneNumber] || info.type != DemoOFFICE || info.dialGroup != 2)
+ {
+ printf("info is incorrect ");
+ }
+ printf("ok\n");
+
+ [contactdb shutdown];
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_SUCCESS;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties];
+ [initData.properties load:@"config.client"];
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(argc, argv, communicator);
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator != nil)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Ice/optional/Contact.ice b/objc/demo/Ice/optional/Contact.ice
new file mode 100644
index 00000000000..241c8f867a1
--- /dev/null
+++ b/objc/demo/Ice/optional/Contact.ice
@@ -0,0 +1,43 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+module Demo
+{
+
+enum NumberType
+{
+ HOME,
+ OFFICE,
+ CELL
+};
+
+class Contact
+{
+ string name;
+ optional(1) NumberType type = HOME;
+ optional(2) string number;
+ optional(3) int dialGroup;
+};
+
+interface ContactDB
+{
+ void addContact(string name, optional(1) NumberType type, optional(2) string number, optional(3) int dialGroup);
+ void updateContact(string name, optional(1) NumberType type, optional(2) string number, optional(3) int dialGroup);
+
+ Contact query(string name);
+ optional(1) string queryNumber(string name);
+ void queryDialgroup(string name, out optional(1) int dialGroup);
+
+ void shutdown();
+};
+
+};
+
diff --git a/objc/demo/Ice/optional/ContactDBI.h b/objc/demo/Ice/optional/ContactDBI.h
new file mode 100644
index 00000000000..ff11d32e5b0
--- /dev/null
+++ b/objc/demo/Ice/optional/ContactDBI.h
@@ -0,0 +1,20 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#import <Contact.h>
+
+@interface ContactDBI : DemoContactDB<DemoContactDB>
+{
+@private
+ NSMutableDictionary* contacts_;
+}
++(id) contactDBI;
+@end
diff --git a/objc/demo/Ice/optional/ContactDBI.m b/objc/demo/Ice/optional/ContactDBI.m
new file mode 100644
index 00000000000..65aa6daa771
--- /dev/null
+++ b/objc/demo/Ice/optional/ContactDBI.m
@@ -0,0 +1,114 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+
+#import <ContactDBI.h>
+
+#include <stdio.h>
+
+@implementation ContactDBI
+-(id) init
+{
+ self = [super init];
+ if(self)
+ {
+ self->contacts_ = [[NSMutableDictionary alloc] init];
+ }
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [self->contacts_ release];
+ [super dealloc];
+}
+#endif
+
++(id) contactDBI
+{
+ id instance = [[ContactDBI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [instance autorelease];
+#endif
+ return instance;
+}
+
+-(void) addContact:(NSMutableString*)name type:(id)type number:(id)number dialGroup:(id)dialGroup
+ current:(ICECurrent*)current
+{
+ DemoContact* contact = [DemoContact contact];
+ contact.name = name;
+ if(type != ICENone)
+ {
+ contact.type = [type intValue];
+ }
+ if(number != ICENone)
+ {
+ contact.number = number;
+ }
+ if(dialGroup != ICENone)
+ {
+ contact.dialGroup = [dialGroup intValue];
+ }
+ [contacts_ setObject:contact forKey:name];
+}
+
+-(void) updateContact:(NSMutableString*)name type:(id)type number:(id)number dialGroup:(id)dialGroup
+ current:(ICECurrent *)current
+{
+ DemoContact* contact = [contacts_ objectForKey:name];
+ if(contact != nil)
+ {
+ if(type != ICENone)
+ {
+ contact.type = [type intValue];
+ }
+ if(number != ICENone)
+ {
+ contact.number = number;
+ }
+ if(dialGroup != ICENone)
+ {
+ contact.dialGroup = [dialGroup intValue];
+ }
+ }
+}
+
+-(DemoContact*) query:(NSMutableString*)name current:(ICECurrent *)current
+{
+ return [contacts_ objectForKey:name];
+}
+
+-(id) queryNumber:(NSMutableString*)name current:(ICECurrent *)current
+{
+ DemoContact* contact = [contacts_ objectForKey:name];
+ if(contact != nil && [contact hasNumber])
+ {
+ return contact.number;
+ }
+ return ICENone;
+}
+
+-(void) queryDialgroup:(NSMutableString*)name dialGroup:(id*)dialGroup current:(ICECurrent *)current
+{
+ DemoContact* contact = [contacts_ objectForKey:name];
+ if(contact != nil && [contact hasDialGroup])
+ {
+ *dialGroup = @(contact.dialGroup);
+ }
+}
+
+-(void) shutdown:(ICECurrent *)current
+{
+ printf("Shutting down...\n");
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
diff --git a/objc/demo/Ice/optional/Makefile b/objc/demo/Ice/optional/Makefile
new file mode 100644
index 00000000000..bc70921eb5e
--- /dev/null
+++ b/objc/demo/Ice/optional/Makefile
@@ -0,0 +1,36 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = Contact.o
+
+COBJS = Client.o \
+
+SOBJS = ContactDBI.o \
+ Server.o
+
+OBJS = $(SLICE_OBJS) $(COBJS) $(SOBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(CLIENT): $(SLICE_OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(COBJS) $(LIBS)
+
+$(SERVER): $(SLICE_OBJS) $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(SOBJS) $(LIBS)
diff --git a/objc/demo/Ice/optional/README b/objc/demo/Ice/optional/README
new file mode 100644
index 00000000000..c8e2f5efa44
--- /dev/null
+++ b/objc/demo/Ice/optional/README
@@ -0,0 +1,10 @@
+This demo illustrates the use of optional class members and
+parameters.
+
+To run the demo, first start the server:
+
+$ server
+
+In a separate window, start the client:
+
+$ client
diff --git a/objc/demo/Ice/optional/Server.m b/objc/demo/Ice/optional/Server.m
new file mode 100644
index 00000000000..91f278daac0
--- /dev/null
+++ b/objc/demo/Ice/optional/Server.m
@@ -0,0 +1,65 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <ContactDBI.h>
+
+
+int
+run(int argc, char* argv[], id<ICECommunicator> communicator)
+{
+ if(argc > 1)
+ {
+ NSLog(@"%s: too many arguments", argv[0]);
+ return EXIT_FAILURE;
+ }
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"ContactDB"];
+ [adapter add:[ContactDBI contactDBI] identity:[communicator stringToIdentity:@"contactdb"]];
+ [adapter activate];
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_SUCCESS;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties];
+ [initData.properties load:@"config.server"];
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(argc, argv, communicator);
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator != nil)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Ice/optional/config.client b/objc/demo/Ice/optional/config.client
new file mode 100644
index 00000000000..596855e5e00
--- /dev/null
+++ b/objc/demo/Ice/optional/config.client
@@ -0,0 +1,10 @@
+#
+# The client reads this property to create the reference to the
+# "ContactDB" object in the server.
+#
+ContactDB.Proxy=contactdb:default -p 10000 -h localhost
+
+#
+# Warn about connection exceptions
+#
+Ice.Warn.Connections=1
diff --git a/objc/demo/Ice/optional/config.server b/objc/demo/Ice/optional/config.server
new file mode 100644
index 00000000000..28294ccd18e
--- /dev/null
+++ b/objc/demo/Ice/optional/config.server
@@ -0,0 +1,11 @@
+#
+# The server creates one single object adapter with the name
+# "ContactDB". The following line sets the endpoints for this
+# adapter.
+#
+ContactDB.Endpoints=default -p 10000 -h localhost
+
+#
+# Warn about connection exceptions
+#
+Ice.Warn.Connections=1
diff --git a/objc/demo/Ice/optional/expect.py b/objc/demo/Ice/optional/expect.py
new file mode 100755
index 00000000000..ec5d2825528
--- /dev/null
+++ b/objc/demo/Ice/optional/expect.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import sys, os
+
+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, "demoscript")) ]
+if len(path) == 0:
+ raise RuntimeError("can't find toplevel directory!")
+sys.path.append(path[0])
+
+from demoscript import Util
+from demoscript.Ice import optional
+
+server = Util.spawn('./server --Ice.PrintAdapterReady --Ice.Warn.Connections=0')
+server.expect('.* ready')
+client = Util.spawn('./client --Ice.Warn.Connections=0')
+
+optional.run(client, server)
diff --git a/objc/demo/Makefile b/objc/demo/Makefile
new file mode 100644
index 00000000000..db858c45c7a
--- /dev/null
+++ b/objc/demo/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = Ice Database Manual
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/demo/Manual/Makefile b/objc/demo/Manual/Makefile
new file mode 100644
index 00000000000..4a954e0f0bf
--- /dev/null
+++ b/objc/demo/Manual/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = printer simple_filesystem
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/demo/Manual/README b/objc/demo/Manual/README
new file mode 100644
index 00000000000..909403402a1
--- /dev/null
+++ b/objc/demo/Manual/README
@@ -0,0 +1,11 @@
+Demos in this directory:
+
+- printer
+
+ An implementation of the simple printer example at the beginning of
+ the Ice manual.
+
+- simple_filesystem
+
+ An implementation of the simple (non-persistent, non-life-cycle)
+ version of the file system example.
diff --git a/objc/demo/Manual/printer/.gitignore b/objc/demo/Manual/printer/.gitignore
new file mode 100644
index 00000000000..db9e318076b
--- /dev/null
+++ b/objc/demo/Manual/printer/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+Printer.m
+Printer.h
diff --git a/objc/demo/Manual/printer/Client.m b/objc/demo/Manual/printer/Client.m
new file mode 100644
index 00000000000..11f8341e751
--- /dev/null
+++ b/objc/demo/Manual/printer/Client.m
@@ -0,0 +1,49 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <Printer.h>
+#import <stdio.h>
+
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_FAILURE;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ communicator = [ICEUtil createCommunicator:&argc argv:argv];
+ id<ICEObjectPrx> base = [communicator stringToProxy:@"SimplePrinter:default -p 10000"];
+ id<DemoPrinterPrx> printer = [DemoPrinterPrx checkedCast:base];
+ if(!printer)
+ {
+ [NSException raise:@"Invalid proxy" format:@""];
+ }
+ [printer printString:@"Hello World!"];
+ status = EXIT_SUCCESS;
+ }
+ @catch(NSException* ex)
+ {
+ NSLog(@"%@", ex);
+ }
+
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch (NSException* ex)
+ {
+ NSLog(@"%@", ex);
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Manual/printer/Makefile b/objc/demo/Manual/printer/Makefile
new file mode 100644
index 00000000000..8229a1b58e2
--- /dev/null
+++ b/objc/demo/Manual/printer/Makefile
@@ -0,0 +1,35 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = Printer.o
+
+COBJS = Client.o
+
+SOBJS = Server.o
+
+OBJS = $(SLICE_OBJS) $(COBJS) $(SOBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(CLIENT): $(SLICE_OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(COBJS) $(LIBS)
+
+$(SERVER): $(SLICE_OBJS) $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(SOBJS) $(LIBS)
diff --git a/objc/demo/Manual/printer/Printer.ice b/objc/demo/Manual/printer/Printer.ice
new file mode 100644
index 00000000000..673897fa777
--- /dev/null
+++ b/objc/demo/Manual/printer/Printer.ice
@@ -0,0 +1,20 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+module Demo
+{
+
+ interface Printer
+ {
+ void printString(string s);
+ };
+
+};
diff --git a/objc/demo/Manual/printer/README b/objc/demo/Manual/printer/README
new file mode 100644
index 00000000000..a08f94f511a
--- /dev/null
+++ b/objc/demo/Manual/printer/README
@@ -0,0 +1,8 @@
+This demo implements the printer example in the Ice manual. To run it,
+start the server in a window:
+
+$ server
+
+In a separate window, run the client:
+
+$ client
diff --git a/objc/demo/Manual/printer/Server.m b/objc/demo/Manual/printer/Server.m
new file mode 100644
index 00000000000..d0359b07460
--- /dev/null
+++ b/objc/demo/Manual/printer/Server.m
@@ -0,0 +1,68 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <Printer.h>
+#import <stdio.h>
+
+@interface PrinterI : DemoPrinter <DemoPrinter>
+@end
+
+@implementation PrinterI
++(id) printerI
+{
+ id instance = [[PrinterI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [instance autorelease];
+#endif
+ return instance;
+}
+-(void) printString:(NSMutableString *)s current:(ICECurrent *)current
+{
+ printf("%s\n", [s UTF8String]);
+ fflush(stdout);
+}
+@end
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_FAILURE;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ communicator = [ICEUtil createCommunicator:&argc argv:argv];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapterWithEndpoints:@"SimplePrinterAdapter"
+ endpoints:@"default -p 10000"];
+ [adapter add:[PrinterI printerI] identity:[communicator stringToIdentity:@"SimplePrinter"]];
+ [adapter activate];
+
+ [communicator waitForShutdown];
+
+ status = EXIT_SUCCESS;
+ }
+ @catch (NSException* ex)
+ {
+ NSLog(@"%@", ex);
+ }
+
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch (NSException* ex)
+ {
+ NSLog(@"%@", ex);
+ }
+
+ }
+ return status;
+}
diff --git a/objc/demo/Manual/printer/expect.py b/objc/demo/Manual/printer/expect.py
new file mode 100755
index 00000000000..a0237fca2e5
--- /dev/null
+++ b/objc/demo/Manual/printer/expect.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import sys, os
+
+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, "demoscript")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(path[0])
+
+from demoscript import *
+import signal
+
+server = Util.spawn('./server --Ice.PrintAdapterReady')
+server.expect('.* ready')
+
+print "testing...",
+sys.stdout.flush()
+client = Util.spawn('./client')
+client.waitTestSuccess()
+server.expect('Hello World!')
+server.kill(signal.SIGTERM)
+server.waitTestSuccess(-signal.SIGTERM)
+print "ok"
diff --git a/objc/demo/Manual/simple_filesystem/.gitignore b/objc/demo/Manual/simple_filesystem/.gitignore
new file mode 100644
index 00000000000..091f857486f
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+Filesystem.m
+Filesystem.h
diff --git a/objc/demo/Manual/simple_filesystem/Client.m b/objc/demo/Manual/simple_filesystem/Client.m
new file mode 100644
index 00000000000..08119f30d68
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/Client.m
@@ -0,0 +1,99 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <Filesystem.h>
+#import <stdio.h>
+
+
+static void
+printIndent(int depth)
+{
+ while(depth-- > 0)
+ {
+ putchar('\t');
+ }
+}
+
+// Recursively print the contents of directory "dir" in tree fashion.
+// For files, show the contents of each file. The "depth"
+// parameter is the current nesting level (for indentation).
+
+static void
+listRecursive(id<FSDirectoryPrx> dir, int depth)
+{
+ ++depth;
+ FSNodeSeq *contents = [dir list];
+
+ for(id<FSNodePrx> node in contents)
+ {
+ id<FSDirectoryPrx> dir = [FSDirectoryPrx checkedCast:node];
+ id<FSFilePrx> file = [FSFilePrx uncheckedCast:node];
+ printIndent(depth);
+ printf("%s%s\n", [[node name] UTF8String], (dir ? " (directory):" : " (file):"));
+ if(dir)
+ {
+ listRecursive(dir, depth);
+ }
+ else
+ {
+ FSLines *text = [file read];
+ for(NSString *line in text)
+ {
+ printIndent(depth);
+ printf("\t%s\n", [line UTF8String]);
+ }
+ }
+ }
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_FAILURE;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ communicator = [ICEUtil createCommunicator:&argc argv:argv];
+ //
+ // Create a proxy for the root directory
+ //
+ id<FSDirectoryPrx> rootDir = [FSDirectoryPrx checkedCast:
+ [communicator stringToProxy:@"RootDir:default -p 10000"]];
+ if(!rootDir)
+ {
+ [NSException raise:@"invalid proxy" format:@"nil"];
+ }
+
+ //
+ // Recursively list the contents of the root directory
+ //
+ printf("Contents of root directory:\n");
+ listRecursive(rootDir, 0);
+
+ status = EXIT_SUCCESS;
+ }
+ @catch (NSException *ex)
+ {
+ NSLog(@"%@\n", ex);
+ }
+
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch (NSException* ex)
+ {
+ NSLog(@"%@\n", ex);
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Manual/simple_filesystem/DirectoryI.h b/objc/demo/Manual/simple_filesystem/DirectoryI.h
new file mode 100644
index 00000000000..a82e49beea6
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/DirectoryI.h
@@ -0,0 +1,28 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Filesystem.h>
+
+@interface DirectoryI : FSDirectory <FSDirectory>
+{
+ @private
+ NSString *myName;
+ DirectoryI *parent;
+ ICEIdentity *ident;
+ NSMutableArray *contents;
+}
+@property(nonatomic, retain) NSString *myName;
+@property(nonatomic, retain) DirectoryI *parent;
+@property(nonatomic, retain) ICEIdentity *ident;
+@property(nonatomic, retain) NSMutableArray *contents;
+
++(id) directoryi:(NSString *)name parent:(DirectoryI *)parent;
+-(void) addChild:(id<FSNodePrx>)child;
+-(void) activate:(id<ICEObjectAdapter>)a;
+@end
diff --git a/objc/demo/Manual/simple_filesystem/DirectoryI.m b/objc/demo/Manual/simple_filesystem/DirectoryI.m
new file mode 100644
index 00000000000..bfd0bc7be6a
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/DirectoryI.m
@@ -0,0 +1,68 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <objc/Ice.h>
+#include <DirectoryI.h>
+
+@implementation DirectoryI
+
+@synthesize myName;
+@synthesize parent;
+@synthesize ident;
+@synthesize contents;
+
++(id) directoryi:(NSString *)name parent:(DirectoryI *)parent
+{
+ DirectoryI *instance = [[DirectoryI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [instance autorelease];
+#endif
+ if(instance == nil)
+ {
+ return nil;
+ }
+ instance.myName = name;
+ instance.parent = parent;
+ instance.ident = [ICEIdentity identity:(parent ? [ICEUtil generateUUID] : @"RootDir") category:nil];
+ instance.contents = [[NSMutableArray alloc] init];
+ return instance;
+}
+
+-(NSString *) name:(ICECurrent *)current
+{
+ return myName;
+}
+
+-(NSArray *) list:(ICECurrent *)current
+{
+ return contents;
+}
+
+-(void) addChild:(id<FSNodePrx>)child
+{
+ [contents addObject:child];
+}
+
+-(void) activate:(id<ICEObjectAdapter>)a
+{
+ id<FSNodePrx> thisNode = [FSNodePrx uncheckedCast:[a add:self identity:ident]];
+ [parent addChild:thisNode];
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [myName release];
+ [parent release];
+ [ident release];
+ [contents release];
+ [super dealloc];
+}
+#endif
+@end
diff --git a/objc/demo/Manual/simple_filesystem/FileI.h b/objc/demo/Manual/simple_filesystem/FileI.h
new file mode 100644
index 00000000000..7179269e785
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/FileI.h
@@ -0,0 +1,31 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Filesystem.h>
+
+@class DirectoryI;
+
+@interface FileI : FSFile <FSFile>
+{
+ @private
+ NSString *myName;
+ DirectoryI *parent;
+ ICEIdentity *ident;
+ NSArray *lines;
+}
+
+@property(nonatomic, retain) NSString *myName;
+@property(nonatomic, retain) DirectoryI *parent;
+@property(nonatomic, retain) ICEIdentity *ident;
+@property(nonatomic, retain) NSArray *lines;
+
++(id) filei:(NSString *)name parent:(DirectoryI *)parent;
+-(void) write:(NSMutableArray *)text current:(ICECurrent *)current;
+-(void) activate:(id<ICEObjectAdapter>)a;
+@end
diff --git a/objc/demo/Manual/simple_filesystem/FileI.m b/objc/demo/Manual/simple_filesystem/FileI.m
new file mode 100644
index 00000000000..7f67a94b81a
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/FileI.m
@@ -0,0 +1,68 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <objc/Ice.h>
+#include <FileI.h>
+#include <DirectoryI.h>
+
+@implementation FileI
+
+@synthesize myName;
+@synthesize parent;
+@synthesize ident;
+@synthesize lines;
+
++(id) filei:(NSString *)name parent:(DirectoryI *)parent
+{
+ FileI *instance = [[FileI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [instance autorelease];
+#endif
+ if(instance == nil)
+ {
+ return nil;
+ }
+ instance.myName = name;
+ instance.parent = parent;
+ instance.ident = [ICEIdentity identity:[ICEUtil generateUUID] category:nil];
+ return instance;
+}
+
+-(NSString *) name:(ICECurrent *)current
+{
+ return myName;
+}
+
+-(NSArray *) read:(ICECurrent *)current
+{
+ return lines;
+}
+
+-(void) write:(NSMutableArray *)text current:(ICECurrent *)current
+{
+ self.lines = text;
+}
+
+-(void) activate:(id<ICEObjectAdapter>)a
+{
+ id<FSNodePrx> thisNode = [FSNodePrx uncheckedCast:[a add:self identity:ident]];
+ [parent addChild:thisNode];
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [myName release];
+ [parent release];
+ [ident release];
+ [lines release];
+ [super dealloc];
+}
+#endif
+@end
diff --git a/objc/demo/Manual/simple_filesystem/Filesystem.ice b/objc/demo/Manual/simple_filesystem/Filesystem.ice
new file mode 100644
index 00000000000..6bc1550deae
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/Filesystem.ice
@@ -0,0 +1,32 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+["objc:prefix:FS"]
+module Filesystem {
+ exception GenericError {
+ string reason;
+ };
+
+ interface Node {
+ idempotent string name();
+ };
+
+ sequence<string> Lines;
+
+ interface File extends Node {
+ idempotent Lines read();
+ idempotent void write(Lines text) throws GenericError;
+ };
+
+ sequence<Node*> NodeSeq;
+
+ interface Directory extends Node {
+ idempotent NodeSeq list();
+ };
+};
diff --git a/objc/demo/Manual/simple_filesystem/Makefile b/objc/demo/Manual/simple_filesystem/Makefile
new file mode 100644
index 00000000000..13d2cab31a6
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = Filesystem.o
+
+COBJS = Client.o
+
+SOBJS = Server.o \
+ DirectoryI.o \
+ FileI.o
+
+OBJS = $(SLICE_OBJS) $(COBJS) $(SOBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(CLIENT): $(SLICE_OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(COBJS) $(LIBS)
+
+$(SERVER): $(SLICE_OBJS) $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SLICE_OBJS) $(SOBJS) $(LIBS)
diff --git a/objc/demo/Manual/simple_filesystem/README b/objc/demo/Manual/simple_filesystem/README
new file mode 100644
index 00000000000..3340e363bad
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/README
@@ -0,0 +1,10 @@
+This demo implements the simple filesystem application shown in the
+Objective-C mapping documentation.
+
+To run it, start the server in a window:
+
+$ server
+
+Then run the client in a separate window:
+
+$ client
diff --git a/objc/demo/Manual/simple_filesystem/Server.m b/objc/demo/Manual/simple_filesystem/Server.m
new file mode 100644
index 00000000000..b8f5a6488cb
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/Server.m
@@ -0,0 +1,86 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <FileI.h>
+#import <DirectoryI.h>
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_FAILURE;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ communicator = [ICEUtil createCommunicator:&argc argv:argv];
+
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapterWithEndpoints:@"SimpleFilesystem"
+ endpoints:@"default -p 10000"];
+
+ //
+ // Create the root directory (with name "/" and no parent)
+ //
+ DirectoryI *root = [DirectoryI directoryi:@"/" parent:nil];
+ [root activate:adapter];
+
+ //
+ // Create a file called "README" in the root directory
+ //
+ FileI *file = [FileI filei:@"README" parent:root];
+ NSMutableArray *text = [NSMutableArray arrayWithObject:@"This file system contains a collection of poetry."];
+ [file write:text current:nil];
+ [file activate:adapter];
+
+ //
+ // Create a directory called "Coleridge" in the root directory
+ //
+ DirectoryI *coleridge = [DirectoryI directoryi:@"Coleridge" parent:root];
+ [coleridge activate:adapter];
+
+ //
+ // Create a file called "Kubla_Khan" in the Coleridge directory
+ //
+ file = [FileI filei:@"Kubla_Khan" parent:coleridge];
+ text = [NSMutableArray arrayWithObjects:@"In Xanadu did Kubla Khan",
+ @"A stately pleasure-dome decree:",
+ @"Where Alph, the sacred river, ran",
+ @"Through caverns measureless to man",
+ @"Down to a sunless sea.", nil];
+ [file write:text current:nil];
+ [file activate:adapter];
+
+ //
+ // All objects are created, allow client requests now
+ //
+ [adapter activate];
+
+ //
+ // Wait until we are done
+ //
+ [communicator waitForShutdown];
+ status = EXIT_SUCCESS;
+ }
+ @catch (NSException* ex)
+ {
+ NSLog(@"%@", ex);
+ }
+
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch (NSException* ex)
+ {
+ NSLog(@"%@", ex);
+ }
+ }
+ return status;
+}
diff --git a/objc/demo/Manual/simple_filesystem/expect.py b/objc/demo/Manual/simple_filesystem/expect.py
new file mode 100755
index 00000000000..f99aae6caca
--- /dev/null
+++ b/objc/demo/Manual/simple_filesystem/expect.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import sys, os
+
+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, "demoscript")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(path[0])
+
+from demoscript import *
+
+import signal
+
+server = Util.spawn('./server --Ice.PrintAdapterReady')
+server.expect('.* ready')
+
+print "testing...",
+sys.stdout.flush()
+client = Util.spawn('./client')
+client.expect('Contents of root directory:\n.*Down to a sunless sea.')
+client.waitTestSuccess()
+server.kill(signal.SIGINT)
+server.waitTestSuccess(-2)
+print "ok"
diff --git a/objc/demo/README b/objc/demo/README
new file mode 100644
index 00000000000..fbb8e1fd642
--- /dev/null
+++ b/objc/demo/README
@@ -0,0 +1,10 @@
+This directory contains demos for various Ice components. The demos
+are provided to get you started on how to use a particular feature or
+coding technique. See the README file in each subdirectory for details
+on the demos.
+
+The Manual directory contains demos for some of the code examples in the
+Ice manual.
+
+For more examples of the features of the Ice services (Glacier2,
+IceGrid, IceStorm) please see the demos in the Ice for C++ distibution.
diff --git a/objc/include/Makefile b/objc/include/Makefile
new file mode 100644
index 00000000000..2a18dba02a5
--- /dev/null
+++ b/objc/include/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = objc
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/include/objc/Glacier2.h b/objc/include/objc/Glacier2.h
new file mode 100644
index 00000000000..7221a60b7a4
--- /dev/null
+++ b/objc/include/objc/Glacier2.h
@@ -0,0 +1,10 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Glacier2 Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import "Glacier2/Glacier2.h"
diff --git a/objc/include/objc/Glacier2/.gitignore b/objc/include/objc/Glacier2/.gitignore
new file mode 100644
index 00000000000..382c7a11d64
--- /dev/null
+++ b/objc/include/objc/Glacier2/.gitignore
@@ -0,0 +1,10 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+Metrics.h
+PermissionsVerifierF.h
+PermissionsVerifier.h
+Router.h
+RouterF.h
+Session.h
+SSLInfo.h
diff --git a/objc/include/objc/Glacier2/Glacier2.h b/objc/include/objc/Glacier2/Glacier2.h
new file mode 100644
index 00000000000..e4b1185f184
--- /dev/null
+++ b/objc/include/objc/Glacier2/Glacier2.h
@@ -0,0 +1,14 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Glacier2/Metrics.h>
+#import <objc/Glacier2/PermissionsVerifier.h>
+#import <objc/Glacier2/Router.h>
+#import <objc/Glacier2/SSLInfo.h>
+#import <objc/Glacier2/Session.h>
diff --git a/objc/include/objc/Glacier2/Makefile b/objc/include/objc/Glacier2/Makefile
new file mode 100644
index 00000000000..e5efc6949fc
--- /dev/null
+++ b/objc/include/objc/Glacier2/Makefile
@@ -0,0 +1,26 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+install::
+ @if test ! -d $(DESTDIR)$(install_includedir)/Glacier2 ; \
+ then \
+ echo "Creating $(DESTDIR)$(install_includedir)/Glacier2..." ; \
+ $(call mkdir,$(DESTDIR)$(install_includedir)/Glacier2) ; \
+ fi
+
+ @for i in *.h ; \
+ do \
+ echo "Installing $$i" ; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(install_includedir)/Glacier2/$$i ; \
+ chmod a+r $(DESTDIR)$(install_includedir)/Glacier2/$$i ; \
+ done
diff --git a/objc/include/objc/Ice.h b/objc/include/objc/Ice.h
new file mode 100644
index 00000000000..e551f1a54d4
--- /dev/null
+++ b/objc/include/objc/Ice.h
@@ -0,0 +1,10 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import "Ice/Ice.h"
diff --git a/objc/include/objc/Ice/.gitignore b/objc/include/objc/Ice/.gitignore
new file mode 100644
index 00000000000..072c49f1ac4
--- /dev/null
+++ b/objc/include/objc/Ice/.gitignore
@@ -0,0 +1,17 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+BuiltinSequences.h
+Identity.h
+Locator.h
+LocatorF.h
+LocalException.h
+Metrics.h
+Process.h
+ProcessF.h
+PropertiesAdmin.h
+RemoteLogger.h
+Router.h
+RouterF.h
+SliceChecksumDict.h
+Version.h
diff --git a/objc/include/objc/Ice/Communicator.h b/objc/include/objc/Ice/Communicator.h
new file mode 100644
index 00000000000..4c25016fa4f
--- /dev/null
+++ b/objc/include/objc/Ice/Communicator.h
@@ -0,0 +1,63 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+//
+// Forward declarations
+//
+@protocol ICEObjectPrx;
+@protocol ICERouterPrx;
+@protocol ICELocatorPrx;
+@protocol ICELogger;
+@protocol ICEProperties;
+@protocol ICEObjectAdapter;
+@protocol ICEObjectFactory;
+@protocol ICEAsyncResult;
+@protocol ICEImplicitContext;
+@protocol ICEObject;
+@class ICEIdentity;
+@class ICEException;
+
+@protocol ICECommunicator <NSObject>
+-(void) destroy;
+-(void) shutdown;
+-(void) waitForShutdown;
+-(BOOL) isShutdown;
+-(id<ICEObjectPrx>) stringToProxy:(NSString*)str;
+-(NSString*)proxyToString:(id<ICEObjectPrx>)obj;
+-(id<ICEObjectPrx>)propertyToProxy:(NSString*)property;
+-(NSMutableDictionary*)proxyToProperty:(id<ICEObjectPrx>)prx property:(NSString*)property;
+-(ICEIdentity*) stringToIdentity:(NSString*)str;
+-(NSString*) identityToString:(ICEIdentity*)ident;
+-(id<ICEObjectAdapter>) createObjectAdapter:(NSString*)name;
+-(id<ICEObjectAdapter>) createObjectAdapterWithEndpoints:(NSString*)name endpoints:(NSString*)endpoints;
+-(id<ICEObjectAdapter>) createObjectAdapterWithRouter:(NSString*)name router:(id<ICERouterPrx>)rtr;
+-(void) addObjectFactory:(id<ICEObjectFactory>)factory sliceId:(NSString*)sliceId;
+-(id<ICEObjectFactory>) findObjectFactory:(NSString*)sliceId;
+-(id<ICEImplicitContext>) getImplicitContext;
+-(id<ICEProperties>) getProperties;
+-(id<ICELogger>) getLogger;
+//-(ICEStats*) getStats;
+-(id<ICERouterPrx>) getDefaultRouter;
+-(void) setDefaultRouter:(id<ICERouterPrx>)rtr;
+-(id<ICELocatorPrx>) getDefaultLocator;
+-(void) setDefaultLocator:(id<ICELocatorPrx>)loc;
+//-(PluginManager*) getPluginManager;
+-(void) flushBatchRequests;
+-(id<ICEAsyncResult>) begin_flushBatchRequests;
+-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(void) end_flushBatchRequests:(id<ICEAsyncResult>)result;
+-(id<ICEObjectPrx>) getAdmin;
+//void addAdminFacet(Object servant, NSString* facet);
+//Object removeAdminFacet(NSString* facet);
+-(id<ICEObject>) findAdminFacet:(NSString*)facet;
+
+@end
diff --git a/objc/include/objc/Ice/Config.h b/objc/include/objc/Ice/Config.h
new file mode 100644
index 00000000000..cef64455eb5
--- /dev/null
+++ b/objc/include/objc/Ice/Config.h
@@ -0,0 +1,41 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+//
+// Some import files we need almost everywhere
+//
+#import <Foundation/NSObject.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSData.h>
+#import <Foundation/NSNull.h>
+
+#import <stdlib.h>
+
+//
+// Don't forget to update the conversion methods from Util.h if the types below
+// are changed.
+//
+typedef unsigned char ICEByte;
+typedef short ICEShort;
+typedef int ICEInt;
+typedef long long ICELong;
+typedef float ICEFloat;
+typedef double ICEDouble;
+
+#if defined(__clang__) && __has_feature(objc_arc)
+# define ICE_STRONG_QUALIFIER __strong
+# define ICE_AUTORELEASING_QUALIFIER __autoreleasing
+# define ICE_STRONG_ATTR strong
+#else
+# define ICE_STRONG_QUALIFIER
+# define ICE_AUTORELEASING_QUALIFIER
+# define ICE_STRONG_ATTR retain
+#endif
diff --git a/objc/include/objc/Ice/Connection.h b/objc/include/objc/Ice/Connection.h
new file mode 100644
index 00000000000..6ab911cca2b
--- /dev/null
+++ b/objc/include/objc/Ice/Connection.h
@@ -0,0 +1,89 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+//
+// Forward declarations
+//
+@class ICEIdentity;
+@class ICEException;
+
+@protocol ICEObjectPrx;
+@protocol ICEObjectAdapter;
+@protocol ICEAsyncResult;
+@protocol ICEEndpoint;
+
+@interface ICEConnectionInfo : NSObject
+{
+@protected
+ BOOL incoming;
+ NSString* adapterName;
+ NSString* connectionId;
+}
+
+@property(nonatomic) BOOL incoming;
+@property(nonatomic, retain) NSString* adapterName;
+@property(nonatomic, retain) NSString* connectionId;
+@end
+
+@interface ICEIPConnectionInfo : ICEConnectionInfo
+{
+@protected
+ NSString* localAddress;
+ ICEInt localPort;
+ NSString* remoteAddress;
+ ICEInt remotePort;
+}
+
+@property(nonatomic, retain) NSString* localAddress;
+@property(nonatomic) ICEInt localPort;
+@property(nonatomic, retain) NSString* remoteAddress;
+@property(nonatomic) ICEInt remotePort;
+@end
+
+@interface ICETCPConnectionInfo : ICEIPConnectionInfo
+@end
+
+@interface ICEUDPConnectionInfo : ICEIPConnectionInfo
+{
+@private
+ NSString* mcastAddress;
+ ICEInt mcastPort;
+}
+@property(nonatomic, retain) NSString* mcastAddress;
+@property(nonatomic) ICEInt mcastPort;
+@end
+
+@interface ICESSLConnectionInfo : ICEIPConnectionInfo
+{
+@private
+ NSString* cipher;
+ NSArray* certs;
+}
+@property(nonatomic, retain) NSString* cipher;
+@property(nonatomic, retain) NSArray* certs;
+@end
+
+@protocol ICEConnection <NSObject>
+-(void) close:(BOOL)force;
+-(id<ICEObjectPrx>) createProxy:(ICEIdentity*)identity;
+-(void) setAdapter:(id<ICEObjectAdapter>)adapter;
+-(id<ICEObjectAdapter>) getAdapter;
+-(void) flushBatchRequests;
+-(id<ICEAsyncResult>) begin_flushBatchRequests;
+-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(void) end_flushBatchRequests:(id<ICEAsyncResult>)result;
+-(NSString*) type;
+-(ICEInt) timeout;
+-(NSString*) toString;
+-(ICEConnectionInfo*) getInfo;
+-(id<ICEEndpoint>) getEndpoint;
+@end
diff --git a/objc/include/objc/Ice/Current.h b/objc/include/objc/Ice/Current.h
new file mode 100644
index 00000000000..6f4f0c793f5
--- /dev/null
+++ b/objc/include/objc/Ice/Current.h
@@ -0,0 +1,85 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+#import <objc/Ice/Stream.h>
+
+//
+// Forward declarations
+//
+@protocol ICEObjectAdapter;
+@protocol ICEConnection;
+@class ICEIdentity;
+@class ICEEncodingVersion;
+
+typedef NSDictionary ICEContext;
+typedef NSMutableDictionary ICEMutableContext;
+
+typedef enum
+{
+ ICENormal,
+ ICENonmutating,
+ ICEIdempotent
+} ICEOperationMode;
+
+@interface ICECurrent : NSObject <NSCopying>
+{
+ @private
+ id<ICEObjectAdapter> adapter;
+ id<ICEConnection> con;
+ ICEIdentity *id_;
+ NSString *facet;
+ NSString *operation;
+ ICEOperationMode mode;
+ NSDictionary *ctx;
+ ICEInt requestId;
+ ICEEncodingVersion *encoding;
+}
+
+@property(nonatomic, retain) id<ICEObjectAdapter> adapter;
+@property(nonatomic, retain) id<ICEConnection> con;
+@property(nonatomic, retain) ICEIdentity *id_;
+@property(nonatomic, retain) NSString *facet;
+@property(nonatomic, retain) NSString *operation;
+@property(nonatomic, assign) ICEOperationMode mode;
+@property(nonatomic, retain) NSDictionary *ctx;
+@property(nonatomic, assign) ICEInt requestId;
+@property(nonatomic, assign) ICEEncodingVersion *encoding;
+
+-(id) init:(id<ICEObjectAdapter>)adapter
+ con:(id<ICEConnection>)con_
+ id_:(ICEIdentity *)id_
+ facet:(NSString *)facet
+ operation:(NSString *)operation
+ mode:(ICEOperationMode)mode
+ ctx:(NSDictionary *)ctx
+ requestId:(ICEInt)requestId
+ encoding:(ICEEncodingVersion*)encoding;
+
++(id) current:(id<ICEObjectAdapter>)adapter
+ con:(id<ICEConnection>)con_
+ id_:(ICEIdentity *)id_
+ facet:(NSString *)facet
+ operation:(NSString *)operation
+ mode:(ICEOperationMode)mode
+ ctx:(NSDictionary *)ctx
+ requestId:(ICEInt)requestId
+ encoding:(ICEEncodingVersion*)encoding;
+
++(id) current;
+// This class also overrides copyWithZone:, hash, isEqual:, and dealloc.
+@end
+
+@interface ICEContextHelper : ICEDictionaryHelper
+@end
+
+@interface ICEOperationModeHelper : ICEEnumHelper
++(ICEInt) getMinValue;
++(ICEInt) getMaxValue;
+@end
diff --git a/objc/include/objc/Ice/DispatchInterceptor.h b/objc/include/objc/Ice/DispatchInterceptor.h
new file mode 100644
index 00000000000..2e6a773e6ed
--- /dev/null
+++ b/objc/include/objc/Ice/DispatchInterceptor.h
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Object.h>
+
+@protocol ICEDispatchInterceptor <ICEObject>
+-(BOOL) dispatch:(id<ICERequest>)request;
+@end
+
+@interface ICEDispatchInterceptor : ICEObject
+@end
+
+@interface ICEMainThreadDispatch : ICEDispatchInterceptor<ICEDispatchInterceptor>
+{
+ ICEObject* servant;
+}
+
+-(id)init:(ICEObject*)servant;
++(id)mainThreadDispatch:(ICEObject*)servant;
+@end
+
diff --git a/objc/include/objc/Ice/Endpoint.h b/objc/include/objc/Ice/Endpoint.h
new file mode 100644
index 00000000000..fb5fb7c2f8b
--- /dev/null
+++ b/objc/include/objc/Ice/Endpoint.h
@@ -0,0 +1,90 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+typedef enum
+{
+ ICERandom,
+ ICEOrdered
+} ICEEndpointSelectionType;
+
+extern const int ICETCPEndpointType;
+extern const int ICESSLEndpointType;
+extern const int ICEUDPEndpointType;
+
+@class ICEEncodingVersion; // Required by ICEOpaqueEndpointInfo
+
+@protocol ICEEndpointInfo<NSObject>
+-(ICEShort) type;
+-(BOOL) datagram;
+-(BOOL) secure;
+@end
+
+@interface ICEEndpointInfo : NSObject<ICEEndpointInfo>
+{
+@protected
+ ICEInt timeout;
+ BOOL compress;
+ ICEShort type_;
+ BOOL datagram_;
+ BOOL secure_;
+}
+
+@property(nonatomic) ICEInt timeout;
+@property(nonatomic) BOOL compress;
+
+-(id) init;
+@end
+
+@interface ICEIPEndpointInfo : ICEEndpointInfo
+{
+@private
+ NSString* host;
+ ICEInt port;
+}
+
+@property(nonatomic, retain) NSString* host;
+@property(nonatomic) ICEInt port;
+@end
+
+
+@interface ICETCPEndpointInfo : ICEIPEndpointInfo
+@end
+
+@interface ICEUDPEndpointInfo : ICEIPEndpointInfo
+{
+@private
+ NSString* mcastInterface;
+ ICEInt mcastTtl;
+}
+@property(nonatomic, retain) NSString* mcastInterface;
+@property(nonatomic) ICEInt mcastTtl;
+@end
+
+@interface ICEOpaqueEndpointInfo : ICEEndpointInfo
+{
+@private
+ ICEEncodingVersion* rawEncoding;
+ NSData* rawBytes;
+}
+@property(nonatomic, retain) ICEEncodingVersion* rawEncoding;
+@property(nonatomic, retain) NSData* rawBytes;
+@end
+
+@interface ICESSLEndpointInfo : ICEIPEndpointInfo
+@end
+
+@protocol ICEEndpoint <NSObject>
+-(ICEEndpointInfo*) getInfo;
+-(NSString*) toString;
+@end
+
+typedef NSArray ICEEndpointSeq;
+typedef NSMutableArray ICEMutableEndpointSeq;
diff --git a/objc/include/objc/Ice/Exception.h b/objc/include/objc/Ice/Exception.h
new file mode 100644
index 00000000000..7d0754b533f
--- /dev/null
+++ b/objc/include/objc/Ice/Exception.h
@@ -0,0 +1,46 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+#import <Foundation/NSException.h>
+
+//
+// Forward declarations
+//
+@protocol ICEOutputStream;
+@protocol ICEInputStream;
+
+@class NSCoder;
+
+@interface ICEException : NSException
+-(NSString*)ice_name;
+@end
+
+@interface ICELocalException : ICEException
+{
+@protected
+ const char* file;
+ int line;
+}
+
+@property(nonatomic, readonly) NSString* file;
+@property(nonatomic, readonly) int line;
+
+-(id)init:(const char*)file line:(int)line;
++(id)localException:(const char*)file line:(int)line;
+@end
+
+@interface ICEUserException : ICEException
+-(BOOL)usesClasses__;
+-(void)write__:(id<ICEOutputStream>)stream;
+-(void) writeImpl__:(id<ICEOutputStream>)os;
+-(void)read__:(id<ICEInputStream>)stream;
+-(void) readImpl__:(id<ICEInputStream>)is;
+@end
diff --git a/objc/include/objc/Ice/Format.h b/objc/include/objc/Ice/Format.h
new file mode 100644
index 00000000000..e6935d5c68e
--- /dev/null
+++ b/objc/include/objc/Ice/Format.h
@@ -0,0 +1,15 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+typedef enum
+{
+ ICEDefaultFormat,
+ ICECompactFormat,
+ ICESlicedFormat
+} ICEFormatType; \ No newline at end of file
diff --git a/objc/include/objc/Ice/Ice.h b/objc/include/objc/Ice/Ice.h
new file mode 100644
index 00000000000..4cf5a9f8bd8
--- /dev/null
+++ b/objc/include/objc/Ice/Ice.h
@@ -0,0 +1,30 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Communicator.h>
+#import <objc/Ice/Connection.h>
+#import <objc/Ice/Current.h>
+#import <objc/Ice/DispatchInterceptor.h>
+#import <objc/Ice/Exception.h>
+#import <objc/Ice/Identity.h>
+#import <objc/Ice/Initialize.h>
+#import <objc/Ice/LocalException.h>
+#import <objc/Ice/Locator.h>
+#import <objc/Ice/Logger.h>
+#import <objc/Ice/Object.h>
+#import <objc/Ice/ObjectAdapter.h>
+#import <objc/Ice/Properties.h>
+#import <objc/Ice/Proxy.h>
+#import <objc/Ice/Router.h>
+#import <objc/Ice/Stream.h>
+#import <objc/Ice/ObjectFactory.h>
+#import <objc/Ice/SlicedData.h>
+#import <objc/Ice/Version.h>
+#import <objc/Ice/ImplicitContext.h>
+#import <objc/Ice/Metrics.h>
diff --git a/objc/include/objc/Ice/ImplicitContext.h b/objc/include/objc/Ice/ImplicitContext.h
new file mode 100644
index 00000000000..df32f3da99e
--- /dev/null
+++ b/objc/include/objc/Ice/ImplicitContext.h
@@ -0,0 +1,20 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+#import <objc/Ice/Current.h>
+
+@protocol ICEImplicitContext<NSObject>
+-(ICEMutableContext*) getContext;
+-(void) setContext:(ICEContext*)context;
+-(BOOL) containsKey:(NSString*)key;
+-(NSString*) get:(NSString*)key;
+-(NSString*) put:(NSString*)key value:(NSString*)value;
+-(NSString*) remove:(NSString*)key;
+@end
diff --git a/objc/include/objc/Ice/Initialize.h b/objc/include/objc/Ice/Initialize.h
new file mode 100644
index 00000000000..845a8b1baad
--- /dev/null
+++ b/objc/include/objc/Ice/Initialize.h
@@ -0,0 +1,80 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+#import <objc/Ice/Communicator.h>
+#import <objc/Ice/Properties.h>
+#import <objc/Ice/Stream.h>
+#import <objc/Ice/Connection.h>
+#import <objc/Ice/Version.h>
+
+//
+// Forward declarations.
+//
+@protocol ICELogger;
+
+@protocol ICEDispatcherCall <NSObject>
+-(void) run;
+@end
+
+@interface ICEInitializationData : NSObject
+{
+@private
+ id<ICEProperties> properties;
+ id<ICELogger> logger;
+ void(^dispatcher)(id<ICEDispatcherCall>, id<ICEConnection>);
+ NSDictionary* prefixTable__;
+}
+@property(retain, nonatomic) id<ICEProperties> properties;
+@property(retain, nonatomic) id<ICELogger> logger;
+@property(copy, nonatomic) void(^dispatcher)(id<ICEDispatcherCall>, id<ICEConnection>);
+@property(retain, nonatomic) NSDictionary* prefixTable__;
+
+-(id) init:(id<ICEProperties>)properties logger:(id<ICELogger>)logger
+ dispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))d;
++(id) initializationData;
++(id) initializationData:(id<ICEProperties>)properties logger:(id<ICELogger>)logger
+ dispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))d;
+// This class also overrides copyWithZone:, hash, isEqual:, and dealloc.
+@end
+
+extern ICEEncodingVersion* ICEEncoding_1_0;
+extern ICEEncodingVersion* ICEEncoding_1_1;
+extern ICEEncodingVersion* ICECurrentEncoding;
+
+extern ICEProtocolVersion* ICEProtocol_1_0;
+extern ICEProtocolVersion* ICECurrentProtocol;
+extern ICEEncodingVersion* ICECurrentProtocolEncoding;
+
+@interface ICEUtil : NSObject
++(id<ICEProperties>) createProperties;
++(id<ICEProperties>) createProperties:(int*)argc argv:(char*[])argv;
++(id<ICECommunicator>) createCommunicator;
++(id<ICECommunicator>) createCommunicator:(ICEInitializationData *)initData;
++(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv;
++(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv initData:(ICEInitializationData *)initData;
++(id<ICEInputStream>) createInputStream:(id<ICECommunicator>)communicator data:(NSData*)data;
++(id<ICEInputStream>) createInputStream:(id<ICECommunicator>)c data:(NSData*)data encoding:(ICEEncodingVersion*)e;
++(id<ICEInputStream>) wrapInputStream:(id<ICECommunicator>)communicator data:(NSData*)data;
++(id<ICEInputStream>) wrapInputStream:(id<ICECommunicator>)c data:(NSData*)data encoding:(ICEEncodingVersion*)e;
++(id<ICEOutputStream>) createOutputStream:(id<ICECommunicator>)communicator;
++(id<ICEOutputStream>) createOutputStream:(id<ICECommunicator>)c encoding:(ICEEncodingVersion*)e;
++(NSString*) generateUUID;
++(NSArray*)argsToStringSeq:(int)argc argv:(char*[])argv;
++(void)stringSeqToArgs:(NSArray*)args argc:(int*)argc argv:(char*[])argv;
+@end
+
+@interface ICEEncodingVersion(StringConv)
++(ICEEncodingVersion*) encodingVersionWithString:(NSString*)str;
+@end
+
+@interface ICEProtocolVersion(StringConv)
++(ICEProtocolVersion*) protocolVersionWithString:(NSString*)str;
+@end
diff --git a/objc/include/objc/Ice/Logger.h b/objc/include/objc/Ice/Logger.h
new file mode 100644
index 00000000000..1e9d7431c3f
--- /dev/null
+++ b/objc/include/objc/Ice/Logger.h
@@ -0,0 +1,18 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+@protocol ICELogger <NSObject>
+-(void) print:(NSString*)message;
+-(void) trace:(NSString*)category message:(NSString*)message;
+-(void) warning:(NSString*)message;
+-(void) error:(NSString*)message;
+-(NSString*) getPrefix;
+@end
diff --git a/objc/include/objc/Ice/Makefile b/objc/include/objc/Ice/Makefile
new file mode 100644
index 00000000000..b1f775aef11
--- /dev/null
+++ b/objc/include/objc/Ice/Makefile
@@ -0,0 +1,26 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+install::
+ @if test ! -d $(DESTDIR)$(install_includedir)/Ice ; \
+ then \
+ echo "Creating $(DESTDIR)$(install_includedir)/Ice..." ; \
+ $(call mkdir,$(DESTDIR)$(install_includedir)/Ice) ; \
+ fi
+
+ @for i in *.h ; \
+ do \
+ echo "Installing $$i" ; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(install_includedir)/Ice/$$i ; \
+ chmod a+r $(DESTDIR)$(install_includedir)/Ice/$$i ; \
+ done
diff --git a/objc/include/objc/Ice/Object.h b/objc/include/objc/Ice/Object.h
new file mode 100644
index 00000000000..6d2ea5ff31e
--- /dev/null
+++ b/objc/include/objc/Ice/Object.h
@@ -0,0 +1,78 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+#import <objc/Ice/Current.h>
+
+//
+// Forward declarations.
+//
+@class ICEObject;
+@protocol ICEInputStream;
+@protocol ICEOutputStream;
+
+#if defined(__cplusplus)
+extern "C"
+#endif
+int ICEInternalLookupString(NSString * const
+ arr[], size_t, NSString * __unsafe_unretained);
+#if defined(__cplusplus)
+extern "C"
+#endif
+void ICEInternalCheckModeAndSelector(id, ICEOperationMode, SEL, ICECurrent*);
+
+@interface ICEInternalPrefixTable : NSObject
+@end
+
+@protocol ICERequest <NSObject>
+-(ICECurrent*) getCurrent;
+@end
+
+@protocol ICEObject <NSObject>
+-(BOOL) ice_isA:(NSString*)typeId current:(ICECurrent*)current;
+-(void) ice_ping:(ICECurrent*)current;
+-(NSString*) ice_id:(ICECurrent*)current;
+-(NSArray*) ice_ids:(ICECurrent*)current;
+@end
+
+@interface ICEObject : NSObject<ICEObject, NSCopying>
+{
+ void* object__;
+ id delegate__;
+}
+-(id)initWithDelegate:(id)delegate;
++(id)objectWithDelegate:(id)delegate;
+-(BOOL) ice_isA:(NSString*)typeId;
+-(void) ice_ping;
+-(NSString*) ice_id;
+-(NSArray*) ice_ids;
+-(void) ice_preMarshal;
+-(void) ice_postUnmarshal;
+-(BOOL) ice_dispatch:(id<ICERequest>)request;
++(NSString*) ice_staticId;
++(NSString*const*) staticIds__:(int*)count idIndex:(int*)idx;
++(BOOL) ice_isA___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os;
++(BOOL) ice_ping___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os;
++(BOOL) ice_id___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os;
++(BOOL) ice_ids___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os;
+-(BOOL) dispatch__:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os;
+-(void) write__:(id<ICEOutputStream>)os;
+-(void) writeImpl__:(id<ICEOutputStream>)os;
+-(void) read__:(id<ICEInputStream>)is;
+-(void) readImpl__:(id<ICEInputStream>)is;
+-(id)target__;
+@end
+
+@protocol ICEBlobject<ICEObject>
+-(BOOL) ice_invoke:(NSData*)inEncaps outEncaps:(NSMutableData**)outEncaps current:(ICECurrent*)current;
+@end
+
+@interface ICEBlobject : ICEObject
+@end
diff --git a/objc/include/objc/Ice/ObjectAdapter.h b/objc/include/objc/Ice/ObjectAdapter.h
new file mode 100644
index 00000000000..30e0735bc68
--- /dev/null
+++ b/objc/include/objc/Ice/ObjectAdapter.h
@@ -0,0 +1,53 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+#import <objc/Ice/Endpoint.h>
+
+//
+// Forward declarations.
+//
+@protocol ICEObjectPrx;
+@protocol ICELocatorPrx;
+@protocol ICECommunicator;
+@class ICEIdentity;
+@class ICEObject;
+
+@protocol ICEObjectAdapter <NSObject>
+-(NSString*) getName;
+-(id<ICECommunicator>) getCommunicator;
+-(void) activate;
+-(void) hold;
+-(void) waitForHold;
+-(void) deactivate;
+-(void) waitForDeactivate;
+-(BOOL) isDeactivated;
+-(void) destroy;
+-(id<ICEObjectPrx>) add:(ICEObject*)servant identity:(ICEIdentity*)ident;
+-(id<ICEObjectPrx>) addFacet:(ICEObject*)servant identity:(ICEIdentity*)ident facet:(NSString*)facet;
+-(id<ICEObjectPrx>) addWithUUID:(ICEObject*)servant;
+-(id<ICEObjectPrx>) addFacetWithUUID:(ICEObject*)servant facet:(NSString*)facet;
+-(void) addDefaultServant:(ICEObject*)servant category:(NSString*)category;
+-(ICEObject*) remove:(ICEIdentity*)ident;
+-(ICEObject*) removeFacet:(ICEIdentity*)ident facet:(NSString*)facet;
+-(NSDictionary*) removeAllFacets:(ICEIdentity*)ident;
+-(ICEObject*) find:(ICEIdentity*)ident;
+-(ICEObject*) findFacet:(ICEIdentity*)ident facet:(NSString*)facet;
+-(NSDictionary*) findAllFacets:(ICEIdentity*)ident;
+-(ICEObject*) findByProxy:(id<ICEObjectPrx>)proxy;
+-(ICEObject*) findDefaultServant:(NSString*)category;
+-(id<ICEObjectPrx>) createProxy:(ICEIdentity*)ident;
+-(id<ICEObjectPrx>) createDirectProxy:(ICEIdentity*)ident;
+-(id<ICEObjectPrx>) createIndirectProxy:(ICEIdentity*)ident;
+-(void) setLocator:(id<ICELocatorPrx>)loc;
+-(void) refreshPublishedEndpoints;
+-(ICEEndpointSeq*) getEndpoints;
+-(ICEEndpointSeq*) getPublishedEndpoints;
+@end
diff --git a/objc/include/objc/Ice/ObjectFactory.h b/objc/include/objc/Ice/ObjectFactory.h
new file mode 100644
index 00000000000..c13b2e667df
--- /dev/null
+++ b/objc/include/objc/Ice/ObjectFactory.h
@@ -0,0 +1,16 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+@protocol ICEObjectFactory <NSObject>
+-(ICEObject*) create:(NSString*)sliceId NS_RETURNS_RETAINED;
+-(void) destroy;
+@end
+
diff --git a/objc/include/objc/Ice/Properties.h b/objc/include/objc/Ice/Properties.h
new file mode 100644
index 00000000000..a8045ce4772
--- /dev/null
+++ b/objc/include/objc/Ice/Properties.h
@@ -0,0 +1,44 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+#import <objc/Ice/PropertiesAdmin.h>
+
+@protocol ICEProperties <NSObject>
+
+-(NSString*) getProperty:(NSString*)key;
+-(NSString*) getPropertyWithDefault:(NSString*)key value:(NSString*)value;
+-(ICEInt) getPropertyAsInt:(NSString*)key;
+-(ICEInt) getPropertyAsIntWithDefault:(NSString*)key value:(ICEInt)value;
+-(NSArray*) getPropertyAsList:(NSString*)key;
+-(NSArray*) getPropertyAsListWithDefault:(NSString*)key value:(NSArray*)value;
+-(NSDictionary*) getPropertiesForPrefix:(NSString*)prefix;
+-(void) setProperty:(NSString*)key value:(NSString*)value;
+-(NSArray*) getCommandLineOptions;
+-(NSArray*) parseCommandLineOptions:(NSString*)prefix options:(NSArray*)options;
+-(NSArray*) parseIceCommandLineOptions:(NSArray*)options;
+-(void) load:(NSString*)file;
+-(id<ICEProperties>) clone;
+
+@end
+
+@protocol ICEPropertiesAdminUpdateCallback <NSObject>
+-(void) updated:(ICEMutablePropertyDict*)properties;
+@end
+
+@interface ICEPropertiesAdminUpdateCallback : NSObject
+{
+ void* cxxObject_;
+}
+@end
+
+@protocol ICENativePropertiesAdmin <NSObject>
+-(void) addUpdateCallback:(id<ICEPropertiesAdminUpdateCallback>)callback;
+-(void) removeUpdateCallback:(id<ICEPropertiesAdminUpdateCallback>)callback;
+@end
diff --git a/objc/include/objc/Ice/Proxy.h b/objc/include/objc/Ice/Proxy.h
new file mode 100644
index 00000000000..58d46c24f1c
--- /dev/null
+++ b/objc/include/objc/Ice/Proxy.h
@@ -0,0 +1,182 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+#import <objc/Ice/Format.h> // For ICEFormatType
+#import <objc/Ice/Current.h> // For ICEOperationMode
+#import <objc/Ice/Endpoint.h> // For ICEEndpointSelectionType
+
+#import <Foundation/NSProxy.h>
+
+//
+// Forward declarations.
+//
+@class ICEObjectPrx;
+@class ICEException;
+@protocol ICECommunicator;
+@protocol ICERouterPrx;
+@protocol ICELocatorPrx;
+@protocol ICEOutputStream;
+@protocol ICEInputStream;
+
+//
+// Marshal/Unmarshall callbacks
+//
+typedef void (^ICEMarshalCB)(id<ICEOutputStream>);
+typedef void (^ICEUnmarshalCB)(id<ICEInputStream>, BOOL);
+
+@protocol ICEAsyncResult <NSObject>
+-(id<ICECommunicator>) getCommunicator;
+-(id<ICEConnection>) getConnection;
+-(id<ICEObjectPrx>) getProxy;
+
+-(BOOL) isCompleted;
+-(void) waitForCompleted;
+
+-(BOOL) isSent;
+-(void) waitForSent;
+
+-(void) throwLocalException;
+
+-(BOOL) sentSynchronously;
+-(NSString*) getOperation;
+@end
+
+@protocol ICEObjectPrx <NSObject, NSCopying>
+
+-(NSComparisonResult) compareIdentity:(id<ICEObjectPrx>)aProxy;
+-(NSComparisonResult) compareIdentityAndFacet:(id<ICEObjectPrx>)aProxy;
+
+-(id<ICECommunicator>) ice_getCommunicator;
+-(NSString*) ice_toString;
+-(BOOL) ice_isA:(NSString*)typeId;
+-(BOOL) ice_isA:(NSString*)typeId context:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId;
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId context:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId response:(void(^)(BOOL))response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId context:(ICEContext*)context response:(void(^)(BOOL))response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId response:(void(^)(BOOL))response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId context:(ICEContext*)context response:(void(^)(BOOL))response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(BOOL) end_ice_isA:(id<ICEAsyncResult>)result;
+-(void) ice_ping;
+-(void) ice_ping:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_ping;
+-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_ping:(void(^)())response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context response:(void(^)())response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_ping:(void(^)())response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context response:(void(^)())response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(void) end_ice_ping:(id<ICEAsyncResult>)result;
+-(NSArray*) ice_ids;
+-(NSArray*) ice_ids:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_ids;
+-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_ids:(void(^)(NSArray*))response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context response:(void(^)(NSArray*))response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_ids:(void(^)(NSArray*))response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context response:(void(^)(NSArray*))response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(NSArray*) end_ice_ids:(id<ICEAsyncResult>)result;
+-(NSString*) ice_id;
+-(NSString*) ice_id:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_id;
+-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_id:(void(^)(NSString*))response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context response:(void(^)(NSString*))response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_id:(void(^)(NSString*))response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context response:(void(^)(NSString*))response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(NSString*) end_ice_id:(id<ICEAsyncResult>)result;
+-(BOOL) ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps outEncaps:(NSMutableData**)outEncaps;
+-(BOOL) ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps outEncaps:(NSMutableData**)outEncaps context:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps;
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps context :(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps response:(void(^)(BOOL, NSMutableData*))response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps context:(ICEContext*)context response:(void(^)(BOOL, NSMutableData*))response exception:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps response:(void(^)(BOOL, NSMutableData*))response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps context:(ICEContext*)context response:(void(^)(BOOL, NSMutableData*))response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(BOOL) end_ice_invoke:(NSMutableData**)outEncaps result:(id<ICEAsyncResult>)result;
+-(ICEIdentity*) ice_getIdentity;
+-(id) ice_identity:(ICEIdentity*)identity;
+-(ICEMutableContext*) ice_getContext;
+-(id) ice_context:(ICEContext*)context;
+-(NSString*) ice_getFacet;
+-(id) ice_facet:(NSString*)facet;
+-(NSString*) ice_getAdapterId;
+-(id) ice_adapterId:(NSString*)adapterId;
+-(ICEEndpointSeq*) ice_getEndpoints;
+-(id) ice_endpoints:(ICEEndpointSeq*)endpoints;
+-(ICEInt) ice_getLocatorCacheTimeout;
+-(id) ice_locatorCacheTimeout:(ICEInt)timeout;
+-(BOOL) ice_isConnectionCached;
+-(id) ice_connectionCached:(BOOL)cached;
+-(ICEEndpointSelectionType) ice_getEndpointSelection;
+-(id) ice_endpointSelection:(ICEEndpointSelectionType)type;
+-(BOOL) ice_isSecure;
+-(id) ice_secure:(BOOL)secure;
+-(ICEEncodingVersion*) ice_getEncodingVersion;
+-(id) ice_encodingVersion:(ICEEncodingVersion*)encoding;
+-(BOOL) ice_isPreferSecure;
+-(id) ice_preferSecure:(BOOL)preferSecure;
+-(id<ICERouterPrx>) ice_getRouter;
+-(id) ice_router:(id<ICERouterPrx>)router;
+-(id<ICELocatorPrx>) ice_getLocator;
+-(id) ice_locator:(id<ICELocatorPrx>)locator;
+//-(BOOL) ice_isCollocationOptimized;
+//-(id) ice_collocationOptimized:(BOOL)collocOptimized;
+-(id) ice_twoway;
+-(BOOL) ice_isTwoway;
+-(id) ice_oneway;
+-(BOOL) ice_isOneway;
+-(id) ice_batchOneway;
+-(BOOL) ice_isBatchOneway;
+-(id) ice_datagram;
+-(BOOL) ice_isDatagram;
+-(id) ice_batchDatagram;
+-(BOOL) ice_isBatchDatagram;
+-(id) ice_compress:(BOOL)compress;
+-(id) ice_timeout:(int)timeout;
+-(id) ice_connectionId:(NSString*)connectionId;
+-(id<ICEConnection>) ice_getConnection;
+-(id<ICEConnection>) ice_getCachedConnection;
+-(void) ice_flushBatchRequests;
+-(id<ICEAsyncResult>) begin_ice_flushBatchRequests;
+-(id<ICEAsyncResult>) begin_ice_flushBatchRequests:(void(^)(ICEException*))exception;
+-(id<ICEAsyncResult>) begin_ice_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent;
+-(void) end_ice_flushBatchRequests:(id<ICEAsyncResult>)result;
+@end
+
+@interface ICEObjectPrx : NSObject<ICEObjectPrx>
+{
+ void* objectPrx__;
+ id<ICECommunicator> communicator__;
+}
++(id) uncheckedCast:(id<ICEObjectPrx>)proxy;
++(id) uncheckedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet;
++(id) checkedCast:(id<ICEObjectPrx>)proxy;
++(id) checkedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet;
++(id) checkedCast:(id<ICEObjectPrx>)proxy context:(ICEContext*)context;
++(id) checkedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet context:(ICEContext*)context;
++(NSString*) ice_staticId;
+
++(Protocol*) protocol__;
+-(id<ICEOutputStream>) createOutputStream__;
+-(void) invoke__:(NSString*)operation mode:(ICEOperationMode)mode format:(ICEFormatType)format marshal:(ICEMarshalCB)marshal
+ unmarshal:(ICEUnmarshalCB)unmarshal context:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_invoke__:(NSString*)operation mode:(ICEOperationMode)mode format:(ICEFormatType)format marshal:(ICEMarshalCB)marshal
+ returnsData:(BOOL)returnsData context:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_invoke__:(NSString*)operation mode:(ICEOperationMode)mode format:(ICEFormatType)format marshal:(ICEMarshalCB)marshal
+ response:(void(^)())response
+ exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent
+ context:(ICEContext*)context;
+-(id<ICEAsyncResult>) begin_invoke__:(NSString*)operation mode:(ICEOperationMode)mode format:(ICEFormatType)format marshal:(ICEMarshalCB)marshal
+ completed:(void(^)(id<ICEInputStream>, BOOL))completed
+ response:(BOOL)response exception:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent
+ context:(ICEContext*)context;
+-(void)end_invoke__:(NSString*)operation unmarshal:(ICEUnmarshalCB)unmarshal result:(id<ICEAsyncResult>)result;
+@end
diff --git a/objc/include/objc/Ice/SlicedData.h b/objc/include/objc/Ice/SlicedData.h
new file mode 100644
index 00000000000..1c4c1df1a42
--- /dev/null
+++ b/objc/include/objc/Ice/SlicedData.h
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in
+// the ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+#import <objc/Ice/Object.h>
+
+@protocol ICESlicedData<NSObject>
+@end
+
+@interface ICEUnknownSlicedObject : ICEObject
+{
+@private
+ NSString* unknownTypeId_;
+ id<ICESlicedData> slicedData_;
+}
+-(NSString*) getUnknownTypeId;
+-(id<ICESlicedData>) getSlicedData;
+@end
diff --git a/objc/include/objc/Ice/Stream.h b/objc/include/objc/Ice/Stream.h
new file mode 100644
index 00000000000..74b0a0b57c5
--- /dev/null
+++ b/objc/include/objc/Ice/Stream.h
@@ -0,0 +1,369 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+#import <objc/Ice/Format.h> // for ICEFormatType
+
+#import <Foundation/NSData.h>
+
+//
+// Forward declarations
+//
+@class ICEObject;
+@protocol ICEObjectPrx;
+@protocol ICECommunicator;
+@protocol ICESlicedData;
+@class ICEUserException;
+@class ICEEncodingVersion;
+
+typedef enum
+{
+ ICEOptionalFormatF1 = 0,
+ ICEOptionalFormatF2 = 1,
+ ICEOptionalFormatF4 = 2,
+ ICEOptionalFormatF8 = 3,
+ ICEOptionalFormatSize = 4,
+ ICEOptionalFormatVSize = 5,
+ ICEOptionalFormatFSize = 6,
+ ICEOptionalFormatClass = 7
+} ICEOptionalFormat;
+
+@protocol ICEReadObjectCallback <NSObject>
+-(void)invoke:(ICEObject*)obj;
+@end
+
+//
+// ICENone singleton to specify not set optionals.
+//
+extern id ICENone;
+
+typedef struct
+{
+ Class key;
+ Class value;
+} ICEKeyValueTypeHelper;
+
+@protocol ICEInputStream <NSObject>
+
+-(id<ICECommunicator>) communicator;
+
+-(void) sliceObjects:(BOOL)b;
+
+-(BOOL) readBool;
+-(NSMutableData*) newBoolSeq;
+-(NSMutableData*) readBoolSeq;
+
+-(ICEByte) readByte;
+-(NSMutableData*) newByteSeq;
+-(NSMutableData*) readByteSeq;
+-(NSData*) readByteSeqNoCopy;
+
+-(ICEShort) readShort;
+-(NSMutableData*) newShortSeq;
+-(NSMutableData*) readShortSeq;
+
+-(ICEInt) readInt;
+-(NSMutableData*) newIntSeq;
+-(NSMutableData*) readIntSeq;
+
+-(ICELong) readLong;
+-(NSMutableData*) newLongSeq;
+-(NSMutableData*) readLongSeq;
+
+-(ICEFloat) readFloat;
+-(NSMutableData*) newFloatSeq;
+-(NSMutableData*) readFloatSeq;
+
+-(ICEDouble) readDouble;
+-(NSMutableData*) newDoubleSeq;
+-(NSMutableData*) readDoubleSeq;
+
+-(NSMutableString*) newString;
+-(NSMutableString*) readString;
+-(NSMutableArray*) newStringSeq;
+-(NSMutableArray*) readStringSeq;
+
+-(ICEInt) readEnumerator:(ICEInt)min max:(ICEInt)max;
+-(NSMutableData*) newEnumSeq:(ICEInt)min max:(ICEInt)max;
+-(NSMutableData*) readEnumSeq:(ICEInt)min max:(ICEInt)max;
+
+-(id<ICEObjectPrx>) newProxy:(Class)c;
+-(id<ICEObjectPrx>) readProxy:(Class)c;
+
+-(void) newObject:(ICEObject*ICE_STRONG_QUALIFIER*)object;
+-(void) newObject:(ICEObject*ICE_STRONG_QUALIFIER*)object expectedType:(Class)type;
+-(void) readObject:(ICEObject**)object;
+-(void) readObject:(ICEObject**)object expectedType:(Class)type;
+-(NSMutableArray*) newObjectSeq:(Class)expectedType;
+-(NSMutableArray*) readObjectSeq:(Class)expectedType;
+-(NSMutableDictionary*) newObjectDict:(Class)keyType expectedType:(Class)type;
+-(NSMutableDictionary*) readObjectDict:(Class)keyType expectedType:(Class)type;
+
+-(NSMutableArray*) newSequence:(Class)type;
+-(NSMutableArray*) readSequence:(Class)type;
+-(NSMutableDictionary*) newDictionary:(ICEKeyValueTypeHelper)type;
+-(NSMutableDictionary*) readDictionary:(ICEKeyValueTypeHelper)type;
+
+-(BOOL) readOptional:(ICEInt)tag format:(ICEOptionalFormat)format;
+
+-(ICEInt) readSize;
+-(ICEInt) readAndCheckSeqSize:(ICEInt)minSize;
+
+-(void) throwException;
+
+-(void) startObject;
+-(id<ICESlicedData>) endObject:(BOOL)preserve NS_RETURNS_RETAINED;
+
+-(void) startException;
+-(id<ICESlicedData>) endException:(BOOL)preserve NS_RETURNS_RETAINED;
+
+-(void) startSlice;
+-(void) endSlice;
+-(void) skipSlice;
+
+-(ICEEncodingVersion*) startEncapsulation;
+-(void) endEncapsulation;
+-(ICEEncodingVersion*) skipEncapsulation;
+
+-(ICEEncodingVersion*) getEncoding;
+
+-(void) readPendingObjects;
+
+-(void) rewind;
+
+-(void) skip:(ICEInt)sz;
+-(void) skipSize;
+@end
+
+@protocol ICEOutputStream <NSObject>
+
+-(id<ICECommunicator>) communicator;
+
+-(void) writeBool:(BOOL)v;
+-(void) writeBoolSeq:(NSData*)v;
+
+-(void) writeByte:(ICEByte)v;
+-(void) writeByteSeq:(NSData*)v;
+
+-(void) writeShort:(ICEShort)v;
+-(void) writeShortSeq:(NSData*)v;
+
+-(void) writeInt:(ICEInt)v;
+-(void) writeIntSeq:(NSData*)v;
+
+-(void) writeLong:(ICELong)v;
+-(void) writeLongSeq:(NSData*)v;
+
+-(void) writeFloat:(ICEFloat)v;
+-(void) writeFloatSeq:(NSData*)v;
+
+-(void) writeDouble:(ICEDouble)v;
+-(void) writeDoubleSeq:(NSData*)v;
+
+-(void) writeString:(NSString*)v;
+-(void) writeStringSeq:(NSArray*)v;
+
+-(void) writeEnumerator:(ICEInt)v min:(ICEInt)min max:(ICEInt)max;
+-(void) writeEnumSeq:(NSData*)v min:(ICEInt)min max:(ICEInt)max;
+
+-(void) writeProxy:(id<ICEObjectPrx>)v;
+
+-(void) writeObject:(ICEObject*)v;
+-(void) writeObjectSeq:(NSArray*)v;
+-(void) writeObjectDict:(NSDictionary*)v helper:(Class)helper;
+
+-(void) writeSequence:(NSArray*)arr helper:(Class)helper;
+-(void) writeDictionary:(NSDictionary*)dictionary helper:(ICEKeyValueTypeHelper)helper;
+
+-(BOOL) writeOptional:(ICEInt)tag format:(ICEOptionalFormat)format;
+
+-(void) writeSize:(ICEInt)v;
+
+-(void) writeException:(ICEUserException*)v;
+
+-(void) startObject:(id<ICESlicedData>)slicedData;
+-(void) endObject;
+
+-(void) startException:(id<ICESlicedData>)slicedData;
+-(void) endException;
+
+-(void) startSlice:(NSString*)typeId compactId:(ICEInt)compactId lastSlice:(BOOL)lastSlice;
+-(void) endSlice;
+
+-(void) startEncapsulation;
+-(void) startEncapsulation:(ICEEncodingVersion*)encoding format:(ICEFormatType)format;
+-(void) endEncapsulation;
+
+-(ICEEncodingVersion*) getEncoding;
+
+-(void) writePendingObjects;
+
+-(NSMutableData*) finished;
+-(NSData*) finishedNoCopy;
+
+-(void) reset:(BOOL)clearBuffer;
+@end
+
+//
+// Helper protocol implemented by helpers for marshaling/un-marshaling
+// Slice types.
+//
+@protocol ICEStreamHelper
++(id) readRetained:(id<ICEInputStream>)stream NS_RETURNS_RETAINED;
++(id) read:(id<ICEInputStream>)stream;
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream;
++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag;
++(id) readOpt:(id<ICEInputStream>)stream tag:(ICEInt)tag;
++(void) writeOpt:(id)obj stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag;
++(ICEInt) minWireSize;
+@end
+
+@interface ICEStreamHelper : NSObject<ICEStreamHelper>
+@end
+
+//
+// Helper classes for streaming Slice types
+//
+@interface ICEBoolHelper : ICEStreamHelper
+@end
+
+@interface ICEByteHelper : ICEStreamHelper
+@end
+
+@interface ICEShortHelper : ICEStreamHelper
+@end
+
+@interface ICEIntHelper : ICEStreamHelper
+@end
+
+@interface ICELongHelper : ICEStreamHelper
+@end
+
+@interface ICEFloatHelper : ICEStreamHelper
+@end
+
+@interface ICEDoubleHelper : ICEStreamHelper
+@end
+
+@interface ICEStringHelper : ICEStreamHelper
+@end
+
+@interface ICEObjectHelper : ICEStreamHelper
++(void)read:(ICEObject**)v stream:(id<ICEInputStream>)stream;
++(void)readOpt:(id*)v stream:(id<ICEInputStream>)stream tag:(ICEInt)tag;
+@end
+
+@interface ICEProxyHelper : ICEStreamHelper
+@end
+
+@interface ICEEnumHelper : ICEStreamHelper
++(ICEInt) getMinValue;
++(ICEInt) getMaxValue;
+@end
+
+@interface ICEStructHelper : ICEStreamHelper
++(Class) getOptionalHelper;
+@end
+
+@protocol ICESequenceStreamHelper<ICEStreamHelper>
++(Class) getElementHelper;
++(ICEInt) count:(id)obj;
+@end
+
+@interface ICEArraySequenceHelper : ICEStreamHelper<ICESequenceStreamHelper>
++(Class) getOptionalHelper;
+@end
+
+@interface ICEDataSequenceHelper : ICEStreamHelper<ICESequenceStreamHelper>
+@end
+
+@interface ICEBoolSequenceHelper : ICEDataSequenceHelper
+@end
+
+@interface ICEByteSequenceHelper : ICEDataSequenceHelper
+@end
+
+@interface ICEShortSequenceHelper : ICEDataSequenceHelper
+@end
+
+@interface ICEIntSequenceHelper : ICEDataSequenceHelper
+@end
+
+@interface ICELongSequenceHelper : ICEDataSequenceHelper
+@end
+
+@interface ICEFloatSequenceHelper : ICEDataSequenceHelper
+@end
+
+@interface ICEDoubleSequenceHelper : ICEDataSequenceHelper
+@end
+
+@interface ICEEnumSequenceHelper : ICEDataSequenceHelper
+@end
+
+@interface ICEStringSequenceHelper : ICEArraySequenceHelper
+@end
+
+@interface ICEObjectSequenceHelper : ICEArraySequenceHelper
+@end
+
+@interface ICEProxySequenceHelper : ICEArraySequenceHelper
+@end
+
+@protocol ICEDictionaryStreamHelper<ICEStreamHelper>
++(ICEInt) count:(id)obj;
+@end
+
+@interface ICEDictionaryHelper : ICEStreamHelper<ICEDictionaryStreamHelper>
++(Class) getOptionalHelper;
+@end
+
+@interface ICEObjectDictionaryHelper : ICEDictionaryHelper
+@end
+
+//
+// Helper for optionals
+//
+@protocol ICEOptionalStreamHelper
++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper NS_RETURNS_RETAINED;
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper;
++(ICEOptionalFormat) optionalFormat;
+@end
+
+@interface ICEFixedLengthOptionalHelper : NSObject<ICEOptionalStreamHelper>
+@end
+
+@interface ICEVarLengthOptionalHelper : NSObject<ICEOptionalStreamHelper>
+@end
+
+@interface ICEFixedSequenceOptionalHelper : NSObject<ICEOptionalStreamHelper>
+@end
+
+@interface ICEFixedSize1SequenceOptionalHelper : NSObject<ICEOptionalStreamHelper>
+@end
+
+@interface ICEFixedDictionaryOptionalHelper : NSObject<ICEOptionalStreamHelper>
+@end
+
+@interface CompactIdMapHelper : NSObject
++(void) initialize;
++(void) registerClass:(NSString*)type value:(ICEInt)value;
+@end
+
+@interface ICEOptionalGetter : NSObject
++(BOOL) get:(id)value value:(id ICE_STRONG_QUALIFIER*)v type:(Class)cl;
++(BOOL) getRetained:(id)value value:(id ICE_STRONG_QUALIFIER*)v type:(Class)cl;
++(BOOL) getByte:(id)value value:(ICEByte*)v;
++(BOOL) getBool:(id)value value:(BOOL*)v;
++(BOOL) getShort:(id)value value:(ICEShort*)v;
++(BOOL) getInt:(id)value value:(ICEInt*)v;
++(BOOL) getLong:(id)value value:(ICELong*)v;
++(BOOL) getFloat:(id)value value:(ICEFloat*)v;
++(BOOL) getDouble:(id)value value:(ICEDouble*)v;
+@end
diff --git a/objc/include/objc/IceGrid.h b/objc/include/objc/IceGrid.h
new file mode 100644
index 00000000000..d81e101dd03
--- /dev/null
+++ b/objc/include/objc/IceGrid.h
@@ -0,0 +1,10 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import "IceGrid/IceGrid.h"
diff --git a/objc/include/objc/IceGrid/.gitignore b/objc/include/objc/IceGrid/.gitignore
new file mode 100644
index 00000000000..41f5d685b02
--- /dev/null
+++ b/objc/include/objc/IceGrid/.gitignore
@@ -0,0 +1,15 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+Admin.h
+Descriptor.h
+Discovery.h
+Exception.h
+FileParser.h
+Locator.h
+Observer.h
+PluginFacade.h
+Query.h
+Registry.h
+Session.h
+UserAccountMapper.h
diff --git a/objc/include/objc/IceGrid/IceGrid.h b/objc/include/objc/IceGrid/IceGrid.h
new file mode 100644
index 00000000000..32c734a5d44
--- /dev/null
+++ b/objc/include/objc/IceGrid/IceGrid.h
@@ -0,0 +1,19 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/IceGrid/Admin.h>
+#import <objc/IceGrid/Exception.h>
+#import <objc/IceGrid/Observer.h>
+#import <objc/IceGrid/Registry.h>
+#import <objc/IceGrid/UserAccountMapper.h>
+#import <objc/IceGrid/Descriptor.h>
+#import <objc/IceGrid/FileParser.h>
+#import <objc/IceGrid/Locator.h>
+#import <objc/IceGrid/Query.h>
+#import <objc/IceGrid/Session.h>
diff --git a/objc/include/objc/IceGrid/Makefile b/objc/include/objc/IceGrid/Makefile
new file mode 100644
index 00000000000..d0305fd73ae
--- /dev/null
+++ b/objc/include/objc/IceGrid/Makefile
@@ -0,0 +1,26 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+install::
+ @if test ! -d $(DESTDIR)$(install_includedir)/IceGrid ; \
+ then \
+ echo "Creating $(DESTDIR)$(install_includedir)/IceGrid..." ; \
+ $(call mkdir,$(DESTDIR)$(install_includedir)/IceGrid) ; \
+ fi
+
+ @for i in *.h ; \
+ do \
+ echo "Installing $$i" ; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(install_includedir)/IceGrid/$$i ; \
+ chmod a+r $(DESTDIR)$(install_includedir)/IceGrid/$$i ; \
+ done
diff --git a/objc/include/objc/IceStorm.h b/objc/include/objc/IceStorm.h
new file mode 100644
index 00000000000..7089fb8c50b
--- /dev/null
+++ b/objc/include/objc/IceStorm.h
@@ -0,0 +1,10 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import "IceStorm/IceStorm.h"
diff --git a/objc/include/objc/IceStorm/.gitignore b/objc/include/objc/IceStorm/.gitignore
new file mode 100644
index 00000000000..bb5bf8a8dc7
--- /dev/null
+++ b/objc/include/objc/IceStorm/.gitignore
@@ -0,0 +1,5 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+Metrics.h
+IceStorm.h
diff --git a/objc/include/objc/IceStorm/Makefile b/objc/include/objc/IceStorm/Makefile
new file mode 100644
index 00000000000..97b7e1bdd1d
--- /dev/null
+++ b/objc/include/objc/IceStorm/Makefile
@@ -0,0 +1,26 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+install::
+ @if test ! -d $(DESTDIR)$(install_includedir)/IceStorm ; \
+ then \
+ echo "Creating $(DESTDIR)$(install_includedir)/IceStorm..." ; \
+ $(call mkdir,$(DESTDIR)$(install_includedir)/IceStorm) ; \
+ fi
+
+ @for i in *.h ; \
+ do \
+ echo "Installing $$i" ; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(install_includedir)/IceStorm/$$i ; \
+ chmod a+r $(DESTDIR)$(install_includedir)/IceStorm/$$i ; \
+ done
diff --git a/objc/include/objc/Makefile b/objc/include/objc/Makefile
new file mode 100644
index 00000000000..1776a2985eb
--- /dev/null
+++ b/objc/include/objc/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = Ice Glacier2 IceStorm IceGrid
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/lib/.gitignore b/objc/lib/.gitignore
new file mode 100644
index 00000000000..39af5887579
--- /dev/null
+++ b/objc/lib/.gitignore
@@ -0,0 +1 @@
+# Dummy file, so that git retains this otherwise empty directory.
diff --git a/objc/src/Glacier2/.gitignore b/objc/src/Glacier2/.gitignore
new file mode 100644
index 00000000000..ece727d3b20
--- /dev/null
+++ b/objc/src/Glacier2/.gitignore
@@ -0,0 +1,18 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+.depend
+Metrics.m
+PermissionsVerifierF.m
+PermissionsVerifier.m
+Router.m
+RouterF.m
+Session.m
+SSLInfo.m
+Metrics.h
+PermissionsVerifierF.h
+PermissionsVerifier.h
+Router.h
+RouterF.h
+Session.h
+SSLInfo.h
diff --git a/objc/src/Glacier2/Makefile b/objc/src/Glacier2/Makefile
new file mode 100644
index 00000000000..50f5d7cf7c0
--- /dev/null
+++ b/objc/src/Glacier2/Makefile
@@ -0,0 +1,50 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+LIBFILENAME = $(call mklibfilename,Glacier2ObjC,$(VERSION))
+SONAME = $(call mksoname,Glacier2ObjC,$(SOVERSION))
+LIBNAME = $(call mklibname,Glacier2ObjC)
+
+TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME))
+
+SLICE_OBJS = Metrics.o \
+ PermissionsVerifierF.o \
+ PermissionsVerifier.o \
+ Router.o \
+ RouterF.o \
+ Session.o \
+ SSLInfo.o
+
+OBJS = $(SLICE_OBJS)
+
+HDIR = $(headerdir)/objc/Glacier2
+SDIR = $(slicedir)/Glacier2
+
+include $(top_srcdir)/config/Make.rules
+
+SLICE2OBJCFLAGS := --ice --include-dir objc/Glacier2 $(SLICE2OBJCFLAGS)
+
+$(libdir)/$(LIBFILENAME): $(OBJS) $(HDIR)/PermissionsVerifierF.h $(HDIR)/RouterF.h
+ @mkdir -p $(dir $@)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(OBJS),$(LIBS))
+
+$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME)
+ rm -f $@
+ ln -s $(LIBFILENAME) $@
+
+$(libdir)/$(LIBNAME): $(libdir)/$(SONAME)
+ @mkdir -p $(libdir)
+ rm -f $@
+ ln -s $(SONAME) $@
+
+install:: all
+ $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME))
diff --git a/objc/src/Ice/.gitignore b/objc/src/Ice/.gitignore
new file mode 100644
index 00000000000..704e8c6c2b0
--- /dev/null
+++ b/objc/src/Ice/.gitignore
@@ -0,0 +1,33 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+.depend
+BuiltinSequences.m
+Identity.m
+Locator.m
+LocatorF.m
+LocalException.m
+Metrics.m
+Process.m
+ProcessF.m
+PropertiesAdmin.m
+RemoteLogger.m
+Router.m
+RouterF.m
+SliceChecksumDict.m
+Version.m
+BuiltinSequences.h
+Identity.h
+Locator.h
+LocatorF.h
+LocalException.h
+Metrics.h
+Process.h
+ProcessF.h
+PropertiesAdmin.h
+RemoteLogger.h
+Router.h
+RouterF.h
+SliceChecksumDict.h
+Version.h
+include/**
diff --git a/objc/src/Ice/Communicator.mm b/objc/src/Ice/Communicator.mm
new file mode 100644
index 00000000000..7557af3ba27
--- /dev/null
+++ b/objc/src/Ice/Communicator.mm
@@ -0,0 +1,608 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <CommunicatorI.h>
+#import <PropertiesI.h>
+#import <ProxyI.h>
+#import <IdentityI.h>
+#import <LoggerI.h>
+#import <ObjectAdapterI.h>
+#import <Util.h>
+#import <StreamI.h>
+#import <SlicedDataI.h>
+#import <ImplicitContextI.h>
+#import <ProxyI.h>
+
+#include <IceCpp/Router.h>
+#include <IceCpp/Locator.h>
+#include <IceCpp/ObjectFactory.h>
+
+#import <objc/Ice/Router.h>
+#import <objc/Ice/Locator.h>
+#import <objc/Ice/ObjectFactory.h>
+
+#import <objc/runtime.h>
+
+#define COMMUNICATOR dynamic_cast<Ice::Communicator*>(static_cast<IceUtil::Shared*>(cxxObject_))
+
+namespace IceObjC
+{
+
+class UnknownSlicedObjectFactoryI : public Ice::ObjectFactory
+{
+public:
+
+ virtual Ice::ObjectPtr
+ create(const std::string&)
+ {
+ ICEUnknownSlicedObject* obj = [[ICEUnknownSlicedObject alloc] init];
+ Ice::ObjectPtr o = [ICEInputStream createObjectReader:obj];
+ [obj release];
+ return o;
+ }
+
+ virtual void
+ destroy()
+ {
+ }
+};
+
+class ObjectFactoryI : public Ice::ObjectFactory
+{
+public:
+
+ // We must explicitely CFRetain/CFRelease so that the garbage
+ // collector does not trash the dictionaries.
+ ObjectFactoryI(NSDictionary* factories, NSDictionary* prefixTable) :
+ _factories(factories), _prefixTable(prefixTable)
+ {
+ CFRetain(_factories);
+ CFRetain(_prefixTable);
+ }
+
+ ~ObjectFactoryI()
+ {
+ CFRelease(_factories);
+ CFRelease(_prefixTable);
+ }
+
+ virtual Ice::ObjectPtr
+ create(const std::string& type)
+ {
+ NSString* sliceId = [[NSString alloc] initWithUTF8String:type.c_str()];
+ @try
+ {
+ id<ICEObjectFactory> factory = nil;
+ @synchronized(_factories)
+ {
+ factory = [_factories objectForKey:sliceId];
+ if(factory == nil)
+ {
+ factory = [_factories objectForKey:@""];
+ }
+ }
+
+ ICEObject* obj = nil;
+ if(factory != nil)
+ {
+ obj = [factory create:sliceId];
+ }
+
+ if(obj == nil)
+ {
+ std::string tId = toObjCSliceId(type, _prefixTable);
+ Class c = objc_lookUpClass(tId.c_str());
+ if(c == nil)
+ {
+ return 0; // No object factory.
+ }
+ if([c isSubclassOfClass:[ICEObject class]])
+ {
+ obj = (ICEObject*)[[c alloc] init];
+ }
+ }
+
+ Ice::ObjectPtr o;
+ if(obj != nil)
+ {
+ o = [ICEInputStream createObjectReader:obj];
+ [obj release];
+ }
+ return o;
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ @finally
+ {
+ [sliceId release];
+ }
+ return nil; // Keep the compiler happy.
+ }
+
+ virtual void
+ destroy()
+ {
+ for(NSString* k in _factories)
+ {
+ [[_factories objectForKey:k] destroy];
+ }
+ }
+
+private:
+
+ NSDictionary* _factories;
+ NSDictionary* _prefixTable;
+};
+
+}
+
+@interface ICEInternalPrefixTable(ICEInternal)
++(NSDictionary*) newPrefixTable;
+@end
+
+@implementation ICEInternalPrefixTable(ICEInternal)
++(NSDictionary*) newPrefixTable
+{
+ NSMutableDictionary* prefixTable = [[NSMutableDictionary alloc] init];
+ ICEInternalPrefixTable* table = [[ICEInternalPrefixTable alloc] init];
+ unsigned int count;
+ Method* methods = class_copyMethodList([ICEInternalPrefixTable class], &count);
+ for(unsigned int i = 0; i < count; ++i)
+ {
+ SEL selector = method_getName(methods[i]);
+ const char* methodName = sel_getName(selector);
+ if(strncmp(methodName, "addPrefixes_C", 13) == 0)
+ {
+ [table performSelector:selector withObject:prefixTable];
+ }
+ }
+ free(methods);
+ [table release];
+ return prefixTable;
+}
+@end
+
+@implementation ICECommunicator
+-(void)setup:(NSDictionary*)prefixTable
+{
+ objectFactories_ = [[NSMutableDictionary alloc] init];
+ if(prefixTable)
+ {
+ prefixTable_ = [prefixTable retain];
+ }
+ else
+ {
+ prefixTable_ = [ICEInternalPrefixTable newPrefixTable];
+ }
+ COMMUNICATOR->addObjectFactory(new IceObjC::UnknownSlicedObjectFactoryI, "::Ice::Object");
+ COMMUNICATOR->addObjectFactory(new IceObjC::ObjectFactoryI(objectFactories_, prefixTable_), "");
+}
+-(void) dealloc
+{
+ [prefixTable_ release];
+ [objectFactories_ release];
+ [super dealloc];
+}
+-(Ice::Communicator*) communicator
+{
+ return COMMUNICATOR;
+}
+-(NSDictionary*) getPrefixTable
+{
+ return prefixTable_;
+}
+
+//
+// Methods from @protocol ICECommunicator
+//
+
+-(void) destroy
+{
+ NSException* nsex = nil;
+ try
+ {
+ COMMUNICATOR->destroy();
+ return;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) shutdown
+{
+ NSException* nsex = nil;
+ try
+ {
+ COMMUNICATOR->shutdown();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) waitForShutdown
+{
+ NSException* nsex = nil;
+ try
+ {
+ COMMUNICATOR->waitForShutdown();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(BOOL) isShutdown
+{
+ NSException* nsex = nil;
+ try
+ {
+ return COMMUNICATOR->isShutdown();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return NO; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>) stringToProxy:(NSString*)str
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:COMMUNICATOR->stringToProxy(fromNSString(str))];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSString*)proxyToString:(id<ICEObjectPrx>)obj
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSString(COMMUNICATOR->proxyToString([(ICEObjectPrx*)obj objectPrx__])) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>)propertyToProxy:(NSString*)property
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:COMMUNICATOR->propertyToProxy(fromNSString(property))];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSMutableDictionary*)proxyToProperty:(id<ICEObjectPrx>)prx property:(NSString*)property
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSDictionary(COMMUNICATOR->proxyToProperty([(ICEObjectPrx*)prx objectPrx__],
+ fromNSString(property))) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEIdentity*) stringToIdentity:(NSString*)str
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEIdentity identityWithIdentity:COMMUNICATOR->stringToIdentity(fromNSString(str))];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSString*) identityToString:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSString(COMMUNICATOR->identityToString([ident identity])) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectAdapter>) createObjectAdapter:(NSString*)name;
+{
+ NSException* nsex = nil;
+ try
+ {
+ ICEObjectAdapter* adapter = [ICEObjectAdapter wrapperWithCxxObject:
+ COMMUNICATOR->createObjectAdapter(
+ fromNSString(name)).get()];
+ return adapter;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectAdapter>) createObjectAdapterWithEndpoints:(NSString*)name endpoints:(NSString*)endpoints;
+{
+ NSException* nsex = nil;
+ try
+ {
+ ICEObjectAdapter* adapter = [ICEObjectAdapter wrapperWithCxxObject:
+ COMMUNICATOR->createObjectAdapterWithEndpoints(
+ fromNSString(name), fromNSString(endpoints)).get()];
+ return adapter;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectAdapter>) createObjectAdapterWithRouter:(NSString*)name router:(id<ICERouterPrx>)rtr
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)rtr objectPrx__]));
+ ICEObjectAdapter* adapter = [ICEObjectAdapter wrapperWithCxxObject:
+ COMMUNICATOR->createObjectAdapterWithRouter(
+ fromNSString(name), router).get()];
+ return adapter;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(void) addObjectFactory:(id<ICEObjectFactory>)factory sliceId:(NSString*)sliceId
+{
+ @synchronized(objectFactories_)
+ {
+ [objectFactories_ setObject:factory forKey:sliceId];
+ }
+}
+-(id<ICEObjectFactory>) findObjectFactory:(NSString*)sliceId
+{
+ @synchronized(objectFactories_)
+ {
+ return [objectFactories_ objectForKey:sliceId];
+ }
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEImplicitContext>) getImplicitContext
+{
+ return [ICEImplicitContext implicitContextWithImplicitContext:COMMUNICATOR->getImplicitContext().get()];
+}
+
+-(id<ICEProperties>) getProperties
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEProperties wrapperWithCxxObject:COMMUNICATOR->getProperties().get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICELogger>) getLogger
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICELogger wrapperWithCxxObject:COMMUNICATOR->getLogger().get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICERouterPrx>) getDefaultRouter
+{
+ NSException* nsex = nil;
+ try
+ {
+ return (id<ICERouterPrx>)[ICERouterPrx objectPrxWithObjectPrx__:COMMUNICATOR->getDefaultRouter()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(void) setDefaultRouter:(id<ICERouterPrx>)rtr
+{
+ NSException* nsex = nil;
+ try
+ {
+ COMMUNICATOR->setDefaultRouter(Ice::RouterPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)rtr objectPrx__])));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(id<ICELocatorPrx>) getDefaultLocator
+{
+ NSException* nsex = nil;
+ try
+ {
+ return (id<ICELocatorPrx>)[ICELocatorPrx objectPrxWithObjectPrx__:COMMUNICATOR->getDefaultLocator()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(void) setDefaultLocator:(id<ICELocatorPrx>)loc
+{
+ NSException* nsex = nil;
+ try
+ {
+ COMMUNICATOR->setDefaultLocator(Ice::LocatorPrx::uncheckedCast(
+ Ice::ObjectPrx([(ICEObjectPrx*)loc objectPrx__])));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) flushBatchRequests
+{
+ NSException* nsex = nil;
+ try
+ {
+ COMMUNICATOR->flushBatchRequests();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+-(id<ICEAsyncResult>) begin_flushBatchRequests
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result)
+ {
+ result = COMMUNICATOR->begin_flushBatchRequests();
+ });
+}
+-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception
+{
+ return [self begin_flushBatchRequests:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb)
+ {
+ result = COMMUNICATOR->begin_flushBatchRequests(cb);
+ },
+ ^(const Ice::AsyncResultPtr& result) {
+ COMMUNICATOR->end_flushBatchRequests(result);
+ },
+ exception, sent);
+}
+-(void) end_flushBatchRequests:(id<ICEAsyncResult>)result
+{
+ endCppCall(^(const Ice::AsyncResultPtr& r)
+ {
+ COMMUNICATOR->end_flushBatchRequests(r);
+ }, result);
+}
+
+-(id<ICEObjectPrx>) getAdmin
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:COMMUNICATOR->getAdmin()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id) findAdminFacet:(NSString*)facet
+{
+ if([facet isEqualToString:@"Properties"])
+ {
+ Ice::ObjectPtr obj = COMMUNICATOR->findAdminFacet(fromNSString(facet));
+ return [ICENativePropertiesAdmin wrapperWithCxxObject:Ice::NativePropertiesAdminPtr::dynamicCast(obj).get()];
+ }
+ else
+ {
+ return nil;
+ }
+}
+@end
diff --git a/objc/src/Ice/CommunicatorI.h b/objc/src/Ice/CommunicatorI.h
new file mode 100644
index 00000000000..4b30e3fe9d3
--- /dev/null
+++ b/objc/src/Ice/CommunicatorI.h
@@ -0,0 +1,28 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Communicator.h>
+
+#import <Wrapper.h>
+
+#import <Foundation/NSSet.h>
+
+#include <IceCpp/Communicator.h>
+
+@class ICEObjectAdapter;
+
+@interface ICECommunicator : ICEInternalWrapper<ICECommunicator>
+{
+ NSMutableDictionary* objectFactories_;
+ NSDictionary* prefixTable_;
+}
+-(void)setup:(NSDictionary*)prefixTable;
+-(Ice::Communicator*)communicator;
+-(NSDictionary*)getPrefixTable;
+@end
diff --git a/objc/src/Ice/Connection.mm b/objc/src/Ice/Connection.mm
new file mode 100644
index 00000000000..703d611f575
--- /dev/null
+++ b/objc/src/Ice/Connection.mm
@@ -0,0 +1,424 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ConnectionI.h>
+#import <EndpointI.h>
+#import <IdentityI.h>
+#import <ObjectAdapterI.h>
+#import <ProxyI.h>
+#import <Util.h>
+
+@implementation ICEConnectionInfo
+
+@synthesize incoming;
+@synthesize adapterName;
+@synthesize connectionId;
+
+-(id) initWithConnectionInfo:(Ice::ConnectionInfo*)connectionInfo;
+{
+ self = [super init];
+ if(self != nil)
+ {
+ self->incoming = connectionInfo->incoming;
+ self->adapterName = [[NSString alloc] initWithUTF8String:connectionInfo->adapterName.c_str()];
+ self->connectionId = [[NSString alloc] initWithUTF8String:connectionInfo->connectionId.c_str()];
+ }
+ return self;
+}
+
+-(void) dealloc
+{
+ [self->adapterName release];
+ [self->connectionId release];
+ [super dealloc];
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ ICEConnectionInfo *obj_ = (ICEConnectionInfo *)o_;
+ if(self->incoming != obj_->incoming)
+ {
+ return NO;
+ }
+ if(![self->adapterName isEqualToString:obj_->adapterName])
+ {
+ return NO;
+ }
+ if(![self->connectionId isEqualToString:obj_->connectionId])
+ {
+ return NO;
+ }
+ return YES;
+}
+
++(id) connectionInfoWithConnectionInfo:(Ice::ConnectionInfo*)connectionInfo
+{
+ if(!connectionInfo)
+ {
+ return nil;
+ }
+ else if(dynamic_cast<Ice::UDPConnectionInfo*>(connectionInfo))
+ {
+ return [[[ICEUDPConnectionInfo alloc]
+ initWithUDPConnectionInfo:dynamic_cast<Ice::UDPConnectionInfo*>(connectionInfo)] autorelease];
+ }
+ else if(dynamic_cast<Ice::TCPConnectionInfo*>(connectionInfo))
+ {
+ return [[[ICETCPConnectionInfo alloc]
+ initWithTCPConnectionInfo:dynamic_cast<Ice::TCPConnectionInfo*>(connectionInfo)] autorelease];
+ }
+ else if(dynamic_cast<IceSSL::ConnectionInfo*>(connectionInfo))
+ {
+ return [[[ICESSLConnectionInfo alloc]
+ initWithSSLConnectionInfo:dynamic_cast<IceSSL::ConnectionInfo*>(connectionInfo)] autorelease];
+ }
+ return nil;
+}
+@end
+
+@implementation ICEIPConnectionInfo
+
+@synthesize localAddress;
+@synthesize localPort;
+@synthesize remoteAddress;
+@synthesize remotePort;
+
+-(id) initWithIPConnectionInfo:(Ice::IPConnectionInfo*)ipConnectionInfo
+{
+ self = [super initWithConnectionInfo:ipConnectionInfo];
+ if(self)
+ {
+ self->localAddress = [[NSString alloc] initWithUTF8String:ipConnectionInfo->localAddress.c_str()];
+ self->localPort = ipConnectionInfo->localPort;
+ self->remoteAddress = [[NSString alloc] initWithUTF8String:ipConnectionInfo->remoteAddress.c_str()];
+ self->remotePort = ipConnectionInfo->remotePort;
+ }
+ return self;
+}
+
+-(void) dealloc
+{
+ [self->localAddress release];
+ [self->remoteAddress release];
+ [super dealloc];
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ if(![super isEqual:o_])
+ {
+ return NO;
+ }
+ ICEIPConnectionInfo *obj_ = (ICEIPConnectionInfo *)o_;
+ if(![self->localAddress isEqualToString:obj_->localAddress])
+ {
+ return NO;
+ }
+ if(self->localPort != obj_->localPort)
+ {
+ return NO;
+ }
+ if(![self->remoteAddress isEqualToString:obj_->remoteAddress])
+ {
+ return NO;
+ }
+ if(self->remotePort != obj_->remotePort)
+ {
+ return NO;
+ }
+ return YES;
+}
+@end
+
+@implementation ICETCPConnectionInfo
+
+-(id) initWithTCPConnectionInfo:(Ice::TCPConnectionInfo*)tcpConnectionInfo
+{
+ self = [super initWithIPConnectionInfo:tcpConnectionInfo];
+ return self;
+}
+@end
+
+@implementation ICEUDPConnectionInfo
+
+@synthesize mcastAddress;
+@synthesize mcastPort;
+
+-(id) initWithUDPConnectionInfo:(Ice::UDPConnectionInfo*)udpConnectionInfo
+{
+ self = [super initWithIPConnectionInfo:udpConnectionInfo];
+ if(self)
+ {
+ self->mcastAddress = [[NSString alloc] initWithUTF8String:udpConnectionInfo->mcastAddress.c_str()];
+ self->mcastPort = udpConnectionInfo->mcastPort;
+ }
+ return self;
+}
+
+-(void) dealloc
+{
+ [self->mcastAddress release];
+ [super dealloc];
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ if(![super isEqual:o_])
+ {
+ return NO;
+ }
+ ICEUDPConnectionInfo *obj_ = (ICEUDPConnectionInfo *)o_;
+ if(![self->mcastAddress isEqualToString:obj_->mcastAddress])
+ {
+ return NO;
+ }
+ if(self->mcastPort != obj_->mcastPort)
+ {
+ return NO;
+ }
+ return YES;
+}
+@end
+
+@implementation ICESSLConnectionInfo
+
+@synthesize cipher;
+@synthesize certs;
+
+-(id) initWithSSLConnectionInfo:(IceSSL::ConnectionInfo*)sslConnectionInfo
+{
+ self = [super initWithIPConnectionInfo:sslConnectionInfo];
+ if(self)
+ {
+ self->cipher = [[NSString alloc] initWithUTF8String:sslConnectionInfo->cipher.c_str()];
+ self->certs = toNSArray(sslConnectionInfo->certs);
+ }
+ return self;
+}
+
+-(void) dealloc
+{
+ [self->cipher release];
+ [self->certs release];
+ [super dealloc];
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ if(![super isEqual:o_])
+ {
+ return NO;
+ }
+ ICESSLConnectionInfo* obj_ = (ICESSLConnectionInfo*)o_;
+ if(![self->cipher isEqualToString:obj_->cipher])
+ {
+ return NO;
+ }
+ if(![self->certs isEqual:obj_->certs])
+ {
+ return NO;
+ }
+ return YES;
+}
+@end
+
+#define CONNECTION dynamic_cast<Ice::Connection*>(static_cast<IceUtil::Shared*>(cxxObject_))
+
+@implementation ICEConnection
+-(void) close:(BOOL)force
+{
+ NSException* nsex = nil;
+ try
+ {
+ CONNECTION->close(force);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+-(id<ICEObjectPrx>) createProxy:(ICEIdentity*)identity
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:CONNECTION->createProxy([identity identity])];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(void) setAdapter:(id<ICEObjectAdapter>)adapter
+{
+ NSException* nsex = nil;
+ try
+ {
+ CONNECTION->setAdapter([(ICEObjectAdapter*)adapter adapter]);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+-(id<ICEObjectAdapter>) getAdapter
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectAdapter wrapperWithCxxObject:CONNECTION->getAdapter().get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(void) flushBatchRequests
+{
+ NSException* nsex = nil;
+ try
+ {
+ CONNECTION->flushBatchRequests();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+-(id<ICEAsyncResult>) begin_flushBatchRequests
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result)
+ {
+ result = CONNECTION->begin_flushBatchRequests();
+ });
+}
+-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception
+{
+ return [self begin_flushBatchRequests:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb)
+ {
+ result = CONNECTION->begin_flushBatchRequests(cb);
+ },
+ ^(const Ice::AsyncResultPtr& result) {
+ CONNECTION->end_flushBatchRequests(result);
+ },
+ exception, sent);
+}
+-(void) end_flushBatchRequests:(id<ICEAsyncResult>)result
+{
+ endCppCall(^(const Ice::AsyncResultPtr& r)
+ {
+ CONNECTION->end_flushBatchRequests(r);
+ }, result);
+}
+-(NSString*) type
+{
+ return [toNSString(CONNECTION->type()) autorelease];
+}
+-(ICEInt) timeout
+{
+ return CONNECTION->timeout();
+}
+-(NSString*) toString
+{
+ return [toNSString(CONNECTION->toString()) autorelease];
+}
+-(NSString*) description
+{
+ return [toNSString(CONNECTION->toString()) autorelease];
+}
+
+-(ICEConnectionInfo*) getInfo
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ConnectionInfoPtr info = CONNECTION->getInfo();
+ return [ICEConnectionInfo connectionInfoWithConnectionInfo:info.get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil;
+}
+
+-(ICEEndpoint*) getEndpoint
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEEndpoint wrapperWithCxxObject:CONNECTION->getEndpoint().get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil;
+}
+@end
diff --git a/objc/src/Ice/ConnectionI.h b/objc/src/Ice/ConnectionI.h
new file mode 100644
index 00000000000..86c6df4e001
--- /dev/null
+++ b/objc/src/Ice/ConnectionI.h
@@ -0,0 +1,39 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Connection.h>
+
+#import <Wrapper.h>
+
+#include <IceCpp/Connection.h>
+#include <IceSSLCpp/ConnectionInfo.h>
+
+@interface ICEConnectionInfo ()
+-(id) initWithConnectionInfo:(Ice::ConnectionInfo*)connectionInfo;
++(id) connectionInfoWithConnectionInfo:(Ice::ConnectionInfo*)connectionInfo;
+@end
+
+@interface ICEIPConnectionInfo ()
+-(id) initWithIPConnectionInfo:(Ice::IPConnectionInfo*)ipConnectionInfo;
+@end
+
+@interface ICETCPConnectionInfo ()
+-(id) initWithTCPConnectionInfo:(Ice::TCPConnectionInfo*)tcpConnectionInfo;
+@end
+
+@interface ICEUDPConnectionInfo ()
+-(id) initWithUDPConnectionInfo:(Ice::UDPConnectionInfo*)udpConnectionInfo;
+@end
+
+@interface ICESSLConnectionInfo ()
+-(id) initWithSSLConnectionInfo:(IceSSL::ConnectionInfo*)sslConnectionInfo;
+@end
+
+@interface ICEConnection : ICEInternalWrapper<ICEConnection>
+@end
diff --git a/objc/src/Ice/Current.mm b/objc/src/Ice/Current.mm
new file mode 100644
index 00000000000..2490a142f53
--- /dev/null
+++ b/objc/src/Ice/Current.mm
@@ -0,0 +1,287 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <CurrentI.h>
+#import <VersionI.h>
+#import <ObjectAdapterI.h>
+#import <ConnectionI.h>
+#import <IdentityI.h>
+#import <Util.h>
+
+//
+// NOTE: Current.h/Current.m are not generated from the Slice
+// Current.ice file for few reasons:
+//
+// - Current.ice includes a number of other Slice files that we don't need to generate.
+// - the Current structure is local and slice2objc doesn't support local structures.
+//
+
+@implementation ICECurrent
+
+@synthesize adapter;
+@synthesize con;
+@synthesize id_;
+@synthesize facet;
+@synthesize operation;
+@synthesize mode;
+@synthesize ctx;
+@synthesize requestId;
+@synthesize encoding;
+
+-(id) init:(id<ICEObjectAdapter>)adapter_
+ con:(id<ICEConnection>)con_
+ id_:(ICEIdentity *)id__
+ facet:(NSString *)facet_
+ operation:(NSString *)operation_
+ mode:(ICEOperationMode)mode_
+ ctx:(NSDictionary *)ctx_
+ requestId:(ICEInt)requestId_
+ encoding:(ICEEncodingVersion*)encoding_
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ adapter = [adapter_ retain];
+ con = [con_ retain];
+ id_ = [id__ retain];
+ facet = [facet_ retain];
+ operation = [operation_ retain];
+ mode = mode_;
+ ctx = [ctx_ retain];
+ requestId = requestId_;
+ encoding = [encoding_ retain];
+ return self;
+}
+
++(id) current:(id<ICEObjectAdapter>)adapter_
+ con:(id<ICEConnection>)con_
+ id_:(ICEIdentity *)id__
+ facet:(NSString *)facet_
+ operation:(NSString *)operation_
+ mode:(ICEOperationMode)mode_
+ ctx:(NSDictionary *)ctx_
+ requestId:(ICEInt)requestId_
+ encoding:(ICEEncodingVersion*)encoding_
+{
+ ICECurrent *s__ = [((ICECurrent *)[ICECurrent alloc]) init:adapter_
+ con:con_
+ id_:id__
+ facet:facet_
+ operation:operation_
+ mode:mode_
+ ctx:ctx_
+ requestId:requestId_
+ encoding:encoding_];
+ [s__ autorelease];
+ return s__;
+}
+
++(id) current
+{
+ ICECurrent *s__ = [[ICECurrent alloc] init];
+ [s__ autorelease];
+ return s__;
+}
+
+-(id) copyWithZone:(NSZone *)zone
+{
+ ICECurrent *copy_ = [ICECurrent allocWithZone:zone];
+ copy_->adapter = [adapter retain];
+ copy_->con = [con retain];
+ copy_->id_ = [id_ retain];
+ copy_->facet = [facet retain];
+ copy_->operation = [operation retain];
+ copy_->mode = mode;
+ copy_->ctx = [ctx retain];
+ copy_->requestId = requestId;
+ copy_->encoding = [encoding retain];
+ return copy_;
+}
+
+-(NSUInteger) hash
+{
+ NSUInteger h_ = 0;
+ h_ = (h_ << 1) ^ (!adapter ? 0 : [adapter hash]);
+ h_ = (h_ << 1) ^ (!con ? 0 : [con hash]);
+ h_ = (h_ << 1) ^ (!id_ ? 0 : [id_ hash]);
+ h_ = (h_ << 1) ^ (!facet ? 0 : [facet hash]);
+ h_ = (h_ << 1) ^ (!operation ? 0 : [operation hash]);
+ h_ = (h_ << 1) ^ mode;
+ h_ = (h_ << 1) ^ (!ctx ? 0 : [ctx hash]);
+ h_ = (h_ << 1) ^ requestId;
+ h_ = (h_ << 1) ^ (!encoding ? 0 : [encoding hash]);
+ return h_;
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ ICECurrent *obj_ = (ICECurrent *)o_;
+ if(!adapter)
+ {
+ if(obj_->adapter)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![adapter isEqual:obj_->adapter])
+ {
+ return NO;
+ }
+ }
+ if(!con)
+ {
+ if(obj_->con)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![con isEqual:obj_->con])
+ {
+ return NO;
+ }
+ }
+ if(!id_)
+ {
+ if(obj_->id_)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![id_ isEqual:obj_->id_])
+ {
+ return NO;
+ }
+ }
+ if(!facet)
+ {
+ if(obj_->facet)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![facet isEqualToString:obj_->facet])
+ {
+ return NO;
+ }
+ }
+ if(!operation)
+ {
+ if(obj_->operation)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![operation isEqualToString:obj_->operation])
+ {
+ return NO;
+ }
+ }
+ if(mode != obj_->mode)
+ {
+ return NO;
+ }
+ if(!ctx)
+ {
+ if(obj_->ctx)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![ctx isEqual:obj_->ctx])
+ {
+ return NO;
+ }
+ }
+ if(requestId != obj_->requestId)
+ {
+ return NO;
+ }
+ return YES;
+}
+
+-(void) dealloc
+{
+ [adapter release];
+ [con release];
+ [id_ release];
+ [facet release];
+ [operation release];
+ [ctx release];
+ [encoding release];
+ [super dealloc];
+}
+
+-(ICECurrent*) initWithCurrent:(const Ice::Current&)current
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+
+ //
+ // TODO: Optimize: the servant blobject should cache an ICECurrent object to
+ // avoid re-creating the wrappers for each dispatched invocation.
+ //
+ adapter = [ICEObjectAdapter wrapperWithCxxObjectNoAutoRelease:current.adapter.get()];
+ con = [ICEConnection wrapperWithCxxObjectNoAutoRelease:current.con.get()];
+ id_ = [[ICEIdentity alloc] initWithIdentity:current.id];
+ facet = [[NSString alloc] initWithUTF8String:current.facet.c_str()];
+ operation = [[NSString alloc] initWithUTF8String:current.operation.c_str()];
+ mode = (ICEOperationMode)current.mode;
+ ctx = toNSDictionary(current.ctx);
+ requestId = current.requestId;
+ encoding = [[ICEEncodingVersion encodingVersionWithEncodingVersion:current.encoding] retain];
+ return self;
+}
+@end
+
+@implementation ICEContextHelper
++(ICEKeyValueTypeHelper) getKeyValueHelper
+{
+ ICEKeyValueTypeHelper c;
+ c.key = [ICEStringHelper class];
+ c.value = [ICEStringHelper class];
+ return c;
+}
+@end
+
+@implementation ICEOperationModeHelper
++(ICEInt) getMinValue
+{
+ return 0;
+}
+
++(ICEInt) getMaxValue
+{
+ return 3;
+}
+@end
diff --git a/objc/src/Ice/CurrentI.h b/objc/src/Ice/CurrentI.h
new file mode 100644
index 00000000000..5c8910fdaac
--- /dev/null
+++ b/objc/src/Ice/CurrentI.h
@@ -0,0 +1,16 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Current.h>
+
+#include <IceCpp/Current.h>
+
+@interface ICECurrent ()
+-(ICECurrent*) initWithCurrent:(const Ice::Current&)arg;
+@end
diff --git a/objc/src/Ice/DispatchInterceptor.m b/objc/src/Ice/DispatchInterceptor.m
new file mode 100644
index 00000000000..3acb01db3f9
--- /dev/null
+++ b/objc/src/Ice/DispatchInterceptor.m
@@ -0,0 +1,60 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/DispatchInterceptor.h>
+
+#import <Request.h>
+
+#import <Foundation/NSThread.h>
+#import <Foundation/NSInvocation.h>
+
+@implementation ICEDispatchInterceptor
+-(BOOL) dispatch__:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os
+{
+ ICERequest* request = [ICERequest request:current is:is os:os];
+ id<ICEDispatchInterceptor> dispatchInterceptor = (id<ICEDispatchInterceptor>)self;
+ return [dispatchInterceptor dispatch:request];
+}
+@end
+
+@implementation ICEMainThreadDispatch
+
+-(id)init:(ICEObject*)s
+{
+ servant = [s retain];
+ return self;
+}
+
++(id)mainThreadDispatch:(ICEObject*)s
+{
+ return [[[self alloc] init:s] autorelease];
+}
+
+-(BOOL) dispatch:(id<ICERequest>)request
+{
+ SEL selector = @selector(ice_dispatch:);
+ NSMethodSignature* sig = [[servant class] instanceMethodSignatureForSelector:selector];
+ NSInvocation* inv = [NSInvocation invocationWithMethodSignature:sig];
+ [inv setTarget:servant];
+ [inv setSelector:selector];
+ [inv setArgument:&request atIndex:2];
+
+ [inv performSelectorOnMainThread:@selector(invokeWithTarget:) withObject:servant waitUntilDone:YES];
+
+ BOOL status;
+ [inv getReturnValue:&status];
+ return status;
+}
+
+-(void)dealloc
+{
+ [servant release];
+ [super dealloc];
+}
+@end
diff --git a/objc/src/Ice/Dispatcher.mm b/objc/src/Ice/Dispatcher.mm
new file mode 100644
index 00000000000..6e055bd0476
--- /dev/null
+++ b/objc/src/Ice/Dispatcher.mm
@@ -0,0 +1,96 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <DispatcherI.h>
+#import <Util.h>
+#import <ConnectionI.h>
+
+#include <Block.h>
+
+namespace
+{
+
+class DispatcherI : public Ice::Dispatcher
+{
+public:
+
+// We must explicitely retain/release so that the garbage
+// collector does not trash the dispatcher.
+DispatcherI(void(^dispatcher)(id<ICEDispatcherCall>, id<ICEConnection>)) : _dispatcher(Block_copy(dispatcher))
+{
+}
+
+virtual ~DispatcherI()
+{
+ Block_release(_dispatcher);
+}
+
+virtual void
+dispatch(const Ice::DispatcherCallPtr& call, const Ice::ConnectionPtr& connection)
+{
+ id<ICEConnection> con = [ICEConnection wrapperWithCxxObjectNoAutoRelease:connection.get()];
+ id<ICEDispatcherCall> c = [[ICEDispatcherCall alloc] initWithCall:call.get()];
+ @try
+ {
+ _dispatcher(c, con);
+ }
+ @finally
+ {
+ [con release];
+ [c release];
+ }
+}
+
+private:
+
+void(^_dispatcher)(id<ICEDispatcherCall>, id<ICEConnection>);
+
+};
+typedef IceUtil::Handle<DispatcherI> DispatcherIPtr;
+
+}
+
+@implementation ICEDispatcher
++(Ice::Dispatcher*) dispatcherWithDispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))dispatcher
+{
+ return new DispatcherI(dispatcher);
+}
+@end
+
+@implementation ICEDispatcherCall
+-(id) initWithCall:(Ice::DispatcherCall*)call
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+
+ cxxCall_ = call;
+ cxxCall_->__incRef();
+ return self;
+}
+-(void) dealloc
+{
+ cxxCall_->__decRef();
+ cxxCall_ = 0;
+ [super dealloc];
+}
+-(void) finalize
+{
+ cxxCall_->__decRef();
+ cxxCall_ = 0;
+ [super finalize];
+}
+
+-(void) run
+{
+ cppCall(^ { cxxCall_->run(); });
+}
+@end
diff --git a/objc/src/Ice/DispatcherI.h b/objc/src/Ice/DispatcherI.h
new file mode 100644
index 00000000000..8b09e28bde9
--- /dev/null
+++ b/objc/src/Ice/DispatcherI.h
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Initialize.h>
+#import <objc/Ice/Connection.h>
+
+#import <Wrapper.h>
+
+#include <IceCpp/Dispatcher.h>
+
+@interface ICEDispatcher : NSObject
++(Ice::Dispatcher*)dispatcherWithDispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))arg;
+@end
+
+@interface ICEDispatcherCall : NSObject<ICEDispatcherCall>
+{
+ Ice::DispatcherCall* cxxCall_;
+}
+-(id) initWithCall:(Ice::DispatcherCall*)call;
+@end
+
diff --git a/objc/src/Ice/Endpoint.mm b/objc/src/Ice/Endpoint.mm
new file mode 100644
index 00000000000..9fc13d39721
--- /dev/null
+++ b/objc/src/Ice/Endpoint.mm
@@ -0,0 +1,321 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in
+// the ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <EndpointI.h>
+#import <Util.h>
+#import <VersionI.h>
+
+#import <objc/Ice/BuiltinSequences.h>
+
+#import <IceCpp/Endpoint.h>
+
+
+const int ICETCPEndpointType = 1;
+const int ICESSLEndpointType = 2;
+const int ICEUDPEndpointType = 3;
+
+#define ENDPOINT dynamic_cast<Ice::Endpoint*>(static_cast<IceUtil::Shared*>(cxxObject_))
+
+@implementation ICEEndpoint
+
+-(Ice::Endpoint*) endpoint
+{
+ return ENDPOINT;
+}
+
+-(ICEEndpointInfo*) getInfo
+{
+ Ice::EndpointInfoPtr info = ENDPOINT->getInfo();
+ return [ICEEndpointInfo enpointInfoWithEndpointInfo:info.get()];
+}
+
+-(NSString*) toString
+{
+ return [toNSString(ENDPOINT->toString()) autorelease];
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ ICEEndpoint* obj_ = (ICEEndpoint*)o_;
+ return *ENDPOINT == *(dynamic_cast<Ice::Endpoint*>(static_cast<IceUtil::Shared*>(obj_->cxxObject_)));
+}
+@end
+
+@implementation ICEEndpointInfo
+
+@synthesize timeout;
+@synthesize compress;
+
+-(id) init
+{
+ self = [super init];
+ return self;
+}
+
+-(id) initWithEndpointInfo:(Ice::EndpointInfo*)endpointInfo;
+{
+ self = [super init];
+ if(self)
+ {
+ self->timeout = endpointInfo->timeout;
+ self->compress = endpointInfo->compress;
+ self->type_ = endpointInfo->type();
+ self->datagram_ = endpointInfo->datagram();
+ self->secure_ = endpointInfo->secure();
+ }
+ return self;
+}
+
++(id) enpointInfoWithEndpointInfo:(Ice::EndpointInfo*)endpointInfo
+{
+ if(!endpointInfo)
+ {
+ return nil;
+ }
+ else if(dynamic_cast<Ice::TCPEndpointInfo*>(endpointInfo))
+ {
+ return [[[ICETCPEndpointInfo alloc]
+ initWithTCPEndpointInfo:dynamic_cast<Ice::TCPEndpointInfo*>(endpointInfo)] autorelease];
+ }
+ else if(dynamic_cast<Ice::UDPEndpointInfo*>(endpointInfo))
+ {
+ return [[[ICEUDPEndpointInfo alloc]
+ initWithUDPEndpointInfo:dynamic_cast<Ice::UDPEndpointInfo*>(endpointInfo)] autorelease];
+}
+ else if(dynamic_cast<Ice::OpaqueEndpointInfo*>(endpointInfo))
+ {
+ return [[[ICEOpaqueEndpointInfo alloc]
+ initWithOpaqueEndpointInfo:dynamic_cast<Ice::OpaqueEndpointInfo*>(endpointInfo)] autorelease];
+ }
+ else if(dynamic_cast<IceSSL::EndpointInfo*>(endpointInfo))
+ {
+ return [[[ICESSLEndpointInfo alloc]
+ initWithSSLEndpointInfo:dynamic_cast<IceSSL::EndpointInfo*>(endpointInfo)] autorelease];
+ }
+ return nil;
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ ICEEndpointInfo* obj_ = (ICEEndpointInfo*)o_;
+ if(self->timeout != obj_->timeout)
+ {
+ return NO;
+ }
+ if(self->compress != obj_->compress)
+ {
+ return NO;
+ }
+ if(self->type_ != obj_->type_)
+ {
+ return NO;
+ }
+ if(self->datagram_ != obj_->datagram_)
+ {
+ return NO;
+ }
+ if(self->secure_ != obj_->secure_)
+ {
+ return NO;
+ }
+ return YES;
+}
+
+-(ICEShort) type
+{
+ return type_;
+}
+
+-(BOOL) datagram;
+{
+ return datagram_;
+}
+
+-(BOOL) secure;
+{
+ return secure_;
+}
+@end
+
+@implementation ICEIPEndpointInfo
+
+@synthesize host;
+@synthesize port;
+
+-(id) initWithIPEndpointInfo:(Ice::IPEndpointInfo*)ipEndpointInfo;
+{
+ self = [super initWithEndpointInfo:ipEndpointInfo];
+ if(self)
+ {
+ self->host = [[NSString alloc] initWithUTF8String:ipEndpointInfo->host.c_str()];
+ self->port = ipEndpointInfo->port;
+ }
+ return self;
+}
+
+-(void) dealloc
+{
+ [self->host release];
+ [super dealloc];
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ if(![super isEqual:o_])
+ {
+ return NO;
+ }
+ ICEIPEndpointInfo* obj_ = (ICEIPEndpointInfo*)o_;
+ if(![self->host isEqualToString:obj_->host])
+ {
+ return NO;
+ }
+ if(self->port != obj_->port)
+ {
+ return NO;
+ }
+ return YES;
+}
+@end
+
+@implementation ICETCPEndpointInfo
+-(id) initWithTCPEndpointInfo:(Ice::TCPEndpointInfo*)tcpEndpointInfo
+{
+ self = [super initWithIPEndpointInfo:tcpEndpointInfo];
+ return self;
+}
+@end
+
+@implementation ICEUDPEndpointInfo
+
+@synthesize mcastInterface;
+@synthesize mcastTtl;
+
+-(id) initWithUDPEndpointInfo:(Ice::UDPEndpointInfo*)udpEndpointInfo
+{
+ self = [super initWithIPEndpointInfo:udpEndpointInfo];
+ if(self)
+ {
+ self->mcastInterface = [[NSString alloc] initWithUTF8String:udpEndpointInfo->mcastInterface.c_str()];
+ self->mcastTtl = udpEndpointInfo->mcastTtl;
+ }
+ return self;
+}
+
+-(void) dealloc
+{
+ [self->mcastInterface release];
+ [super dealloc];
+
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ if(![super isEqual:o_])
+ {
+ return NO;
+ }
+ ICEUDPEndpointInfo* obj_ = (ICEUDPEndpointInfo*)o_;
+ if(![self->mcastInterface isEqualToString:obj_->mcastInterface])
+ {
+ return NO;
+ }
+ if(self->mcastTtl != obj_->mcastTtl)
+ {
+ return NO;
+ }
+ return YES;
+}
+@end
+
+@implementation ICEOpaqueEndpointInfo
+
+@synthesize rawEncoding;
+@synthesize rawBytes;
+
+-(id) initWithOpaqueEndpointInfo:(Ice::OpaqueEndpointInfo*)opaqueEndpointInfo
+{
+ self = [super init];
+ if(self)
+ {
+ self->rawEncoding = [[ICEEncodingVersion alloc] initWithEncodingVersion:opaqueEndpointInfo->rawEncoding];
+ self->rawBytes = toNSData(opaqueEndpointInfo->rawBytes);
+ }
+ return self;
+}
+
+-(void) dealloc
+{
+ [self->rawEncoding release];
+ [self->rawBytes release];
+ [super dealloc];
+}
+
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ ICEOpaqueEndpointInfo* obj_ = (ICEOpaqueEndpointInfo*)o_;
+ if(![self->rawEncoding isEqual:obj_->rawEncoding])
+ {
+ return NO;
+ }
+ if(![self->rawBytes isEqual:obj_->rawBytes])
+ {
+ return NO;
+ }
+ return YES;
+}
+@end
+
+@implementation ICESSLEndpointInfo
+-(id) initWithSSLEndpointInfo:(IceSSL::EndpointInfo*)sslEndpointInfo
+{
+ self = [super initWithIPEndpointInfo:sslEndpointInfo];
+ return self;
+}
+@end
diff --git a/objc/src/Ice/EndpointI.h b/objc/src/Ice/EndpointI.h
new file mode 100644
index 00000000000..a0b02bafa64
--- /dev/null
+++ b/objc/src/Ice/EndpointI.h
@@ -0,0 +1,45 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in
+// the ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Endpoint.h>
+
+#import <Wrapper.h>
+
+#include <IceCpp/Endpoint.h>
+#include <IceSSLCpp/EndpointInfo.h>
+
+@interface ICEEndpoint : ICEInternalWrapper<ICEEndpoint>
+-(Ice::Endpoint*) endpoint;
+@end
+
+
+@interface ICEEndpointInfo ()
+-(id) initWithEndpointInfo:(Ice::EndpointInfo*)endpointInfo;
++(id) enpointInfoWithEndpointInfo:(Ice::EndpointInfo*)endpointInfo;
+@end
+
+@interface ICEIPEndpointInfo ()
+-(id) initWithIPEndpointInfo:(Ice::IPEndpointInfo*)ipEndpointInfo;
+@end
+
+@interface ICETCPEndpointInfo ()
+-(id) initWithTCPEndpointInfo:(Ice::TCPEndpointInfo*)tcpEndpointInfo;
+@end
+
+@interface ICEUDPEndpointInfo ()
+-(id) initWithUDPEndpointInfo:(Ice::UDPEndpointInfo*)udpEndpointInfo;
+@end
+
+@interface ICEOpaqueEndpointInfo ()
+-(id) initWithOpaqueEndpointInfo:(Ice::OpaqueEndpointInfo*)opaqueEndpointInfo;
+@end
+
+@interface ICESSLEndpointInfo ()
+-(id) initWithSSLEndpointInfo:(IceSSL::EndpointInfo*)sslEndpointInfo;
+@end
diff --git a/objc/src/Ice/Exception.mm b/objc/src/Ice/Exception.mm
new file mode 100644
index 00000000000..908ad553630
--- /dev/null
+++ b/objc/src/Ice/Exception.mm
@@ -0,0 +1,919 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ExceptionI.h>
+#import <IdentityI.h>
+#import <Util.h>
+#import <VersionI.h>
+
+#import <objc/Ice/LocalException.h>
+
+#include <IceCpp/LocalException.h>
+
+#import <Foundation/NSKeyedArchiver.h>
+
+@implementation ICEException
+-(id)init
+{
+ return [super initWithName:[self ice_name] reason:nil userInfo:nil];
+}
+
+-(id)initWithReason:(NSString*)reason
+{
+ return [super initWithName:[self ice_name] reason:reason userInfo:nil];
+}
+-(NSString*)ice_name
+{
+ NSAssert(false, @"ice_name not overriden");
+ return nil;
+}
+
+-(id) initWithCoder:(NSCoder*)decoder
+{
+ [NSException raise:NSInvalidArchiveOperationException format:@"ICEExceptions do not support NSCoding"];
+ return nil;
+}
+
+-(void) encodeWithCoder:(NSCoder*)coder
+{
+ [NSException raise:NSInvalidArchiveOperationException format:@"ICEExceptions do not support NSCoding"];
+}
+
+-(id) copyWithZone:(NSZone *)zone
+{
+ NSAssert(false, @"copyWithZone: must be overriden");
+ return nil;
+}
+
+-(void) dealloc
+{
+ [super dealloc];
+}
+@end
+
+static NSString*
+localExceptionToString(const Ice::LocalException& ex)
+{
+ std::ostringstream os;
+ os << ex;
+ std::string str = os.str();
+ const std::string prefix = "../../../cpp/src/";
+ if(str.find(prefix) == 0)
+ {
+ str = str.substr(prefix.size());
+ }
+ return [NSString stringWithUTF8String:str.c_str()];
+}
+
+@implementation ICELocalException
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithReason:localExceptionToString(ex)];
+ if(!self)
+ {
+ return nil;
+ }
+ file = ex.ice_file();
+ line = ex.ice_line();
+ return self;
+}
+
+-(void)rethrowCxx
+{
+ NSAssert(false, @"rethrowCxx must be overriden");
+}
+
++(id)localExceptionWithLocalException:(const Ice::LocalException&)ex
+{
+ return [[[self alloc] initWithLocalException:ex] autorelease];
+}
+
+-(NSString*) file
+{
+ return [toNSString(file) autorelease];
+}
+
+@synthesize line;
+
+-(id)init:(const char*)f line:(int)l
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ file = f;
+ line = l;
+ return self;
+}
+
++(id)localException:(const char*)file line:(int)line
+{
+ return [[[self alloc] init:file line:line] autorelease];
+}
+
+-(NSString*)description
+{
+ try
+ {
+ [self rethrowCxx];
+ return @""; // Keep the compiler happy.
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ return localExceptionToString(ex);
+ }
+}
+
+-(id) copyWithZone:(NSZone *)zone
+{
+ return [[[self class] allocWithZone:zone] init:file line:line];
+}
+
+-(void) dealloc
+{
+ [super dealloc];
+}
+@end
+
+@implementation ICEUserException
+-(BOOL)usesClasses__
+{
+ return NO;
+}
+
+-(void)write__:(id<ICEOutputStream>)os
+{
+ [os startException:nil];
+ [self writeImpl__:os];
+ [os endException];
+}
+
+-(void) writeImpl__:(id<ICEOutputStream>)os
+{
+ NSAssert(NO, @"writeImpl__ requires override");
+}
+
+-(void)read__:(id<ICEInputStream>)is
+{
+ [is startException];
+ [self readImpl__:is];
+ [is endException:NO];
+}
+
+-(void) readImpl__:(id<ICEInputStream>)is
+{
+ NSAssert(NO, @"readImpl__ requires override");
+}
+
+-(id) copyWithZone:(NSZone *)zone
+{
+ return [[[self class] allocWithZone:zone] init];
+}
+
+-(void) dealloc
+{
+ [super dealloc];
+}
+@end
+
+@implementation ICEInitializationException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::InitializationException*>(&ex), @"invalid local exception type");
+ const Ice::InitializationException& localEx = dynamic_cast<const Ice::InitializationException&>(ex);
+ reason_ = toNSString(localEx.reason);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::InitializationException(file, line, fromNSString(reason_));
+}
+@end
+
+@implementation ICEPluginInitializationException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::PluginInitializationException*>(&ex), @"invalid local exception type");
+ const Ice::PluginInitializationException& localEx = dynamic_cast<const Ice::PluginInitializationException&>(ex);
+ reason_ = toNSString(localEx.reason);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::PluginInitializationException(file, line, fromNSString(reason_));
+}
+@end
+
+@implementation ICECollocationOptimizationException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::CollocationOptimizationException(file, line);
+}
+@end
+
+@implementation ICEAlreadyRegisteredException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::AlreadyRegisteredException*>(&ex), @"invalid local exception type");
+ const Ice::AlreadyRegisteredException& localEx = dynamic_cast<const Ice::AlreadyRegisteredException&>(ex);
+ kindOfObject = toNSString(localEx.kindOfObject);
+ id_ = toNSString(localEx.id);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::AlreadyRegisteredException(file, line, fromNSString(kindOfObject), fromNSString(id_));
+}
+@end
+
+@implementation ICENotRegisteredException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::NotRegisteredException*>(&ex), @"invalid local exception type");
+ const Ice::NotRegisteredException& localEx = dynamic_cast<const Ice::NotRegisteredException&>(ex);
+ kindOfObject = toNSString(localEx.kindOfObject);
+ id_ = toNSString(localEx.id);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::NotRegisteredException(file, line, fromNSString(kindOfObject), fromNSString(id_));
+}
+@end
+
+@implementation ICETwowayOnlyException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::TwowayOnlyException*>(&ex), @"invalid local exception type");
+ const Ice::TwowayOnlyException& localEx = dynamic_cast<const Ice::TwowayOnlyException&>(ex);
+ operation = toNSString(localEx.operation);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::TwowayOnlyException(file, line, fromNSString(operation));
+}
+@end
+
+@implementation ICEUnknownException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::UnknownException*>(&ex), @"invalid local exception type");
+ const Ice::UnknownException& localEx = dynamic_cast<const Ice::UnknownException&>(ex);
+ unknown = toNSString(localEx.unknown);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::UnknownException(file, line, fromNSString(unknown));
+}
+@end
+
+@implementation ICEUnknownLocalException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::UnknownLocalException(file, line, fromNSString([self unknown]));
+}
+@end
+
+@implementation ICEUnknownUserException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::UnknownUserException(file, line, fromNSString([self unknown]));
+}
+@end
+
+@implementation ICEVersionMismatchException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::VersionMismatchException(file, line);
+}
+@end
+
+@implementation ICECommunicatorDestroyedException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::CommunicatorDestroyedException(file, line);
+}
+@end
+
+@implementation ICEObjectAdapterDeactivatedException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::ObjectAdapterDeactivatedException*>(&ex), @"invalid local exception type");
+ const Ice::ObjectAdapterDeactivatedException& localEx = dynamic_cast<const Ice::ObjectAdapterDeactivatedException&>(ex);
+ name_ = toNSString(localEx.name);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::ObjectAdapterDeactivatedException(file, line, fromNSString(name_));
+}
+@end
+
+@implementation ICEObjectAdapterIdInUseException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::ObjectAdapterIdInUseException*>(&ex), @"invalid local exception type");
+ const Ice::ObjectAdapterIdInUseException& localEx = dynamic_cast<const Ice::ObjectAdapterIdInUseException&>(ex);
+ id_ = toNSString(localEx.id);
+ return self;
+}
+@end
+
+@implementation ICENoEndpointException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::NoEndpointException*>(&ex), @"invalid local exception type");
+ const Ice::NoEndpointException& localEx = dynamic_cast<const Ice::NoEndpointException&>(ex);
+ proxy = toNSString(localEx.proxy);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::NoEndpointException(file, line, fromNSString(proxy));
+}
+@end
+
+@implementation ICEEndpointParseException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::EndpointParseException*>(&ex), @"invalid local exception type");
+ const Ice::EndpointParseException& localEx = dynamic_cast<const Ice::EndpointParseException&>(ex);
+ str = toNSString(localEx.str);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::EndpointParseException(file, line, fromNSString(str));
+}
+@end
+
+@implementation ICEEndpointSelectionTypeParseException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::EndpointSelectionTypeParseException*>(&ex), @"invalid local exception type");
+ const Ice::EndpointSelectionTypeParseException& localEx = dynamic_cast<const Ice::EndpointSelectionTypeParseException&>(ex);
+ str = toNSString(localEx.str);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::EndpointSelectionTypeParseException(file, line, fromNSString(str));
+}
+@end
+
+@implementation ICEIdentityParseException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::IdentityParseException*>(&ex), @"invalid local exception type");
+ const Ice::IdentityParseException& localEx = dynamic_cast<const Ice::IdentityParseException&>(ex);
+ str = toNSString(localEx.str);
+ return self;
+}
+@end
+
+@implementation ICEProxyParseException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::ProxyParseException*>(&ex), @"invalid local exception type");
+ const Ice::ProxyParseException& localEx = dynamic_cast<const Ice::ProxyParseException&>(ex);
+ str = toNSString(localEx.str);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::ProxyParseException(file, line, fromNSString(str));
+}
+@end
+
+@implementation ICEIllegalIdentityException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::IllegalIdentityException*>(&ex), @"invalid local exception type");
+ const Ice::IllegalIdentityException& localEx = dynamic_cast<const Ice::IllegalIdentityException&>(ex);
+ id_ = [[ICEIdentity alloc] initWithIdentity:localEx.id];
+ return self;
+}
+-(void) rethrowCxx
+{
+ Ice::Identity ident = { fromNSString(id_.name), fromNSString(id_.category) };
+ throw Ice::IllegalIdentityException(file, line, ident);
+}
+@end
+
+@implementation ICERequestFailedException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::RequestFailedException*>(&ex), @"invalid local exception type");
+ const Ice::RequestFailedException& localEx = dynamic_cast<const Ice::RequestFailedException&>(ex);
+ id_ = [[ICEIdentity alloc] initWithIdentity:localEx.id];
+ facet = toNSString(localEx.facet);
+ operation = toNSString(localEx.operation);
+ return self;
+}
+-(void) rethrowCxx
+{
+ Ice::Identity ident = { fromNSString(id_.name), fromNSString(id_.category) };
+ throw Ice::RequestFailedException(file, line, ident, fromNSString(facet), fromNSString(operation));
+}
+@end
+
+@implementation ICEObjectNotExistException (ICEInternal)
+-(void) rethrowCxx
+{
+ Ice::Identity ident = { fromNSString([self id_].name), fromNSString([self id_].category) };
+ throw Ice::ObjectNotExistException(file, line, ident, fromNSString([self facet]), fromNSString([self operation]));
+}
+@end
+
+@implementation ICEFacetNotExistException (ICEInternal)
+-(void) rethrowCxx
+{
+ Ice::Identity ident = { fromNSString([self id_].name), fromNSString([self id_].category) };
+ throw Ice::FacetNotExistException(file, line, ident, fromNSString([self facet]), fromNSString([self operation]));
+}
+@end
+
+@implementation ICEOperationNotExistException (ICEInternal)
+-(void) rethrowCxx
+{
+ Ice::Identity ident = { fromNSString([self id_].name), fromNSString([self id_].category) };
+ throw Ice::OperationNotExistException(file, line, ident, fromNSString([self facet]), fromNSString([self operation]));
+}
+@end
+
+@implementation ICESyscallException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::SyscallException*>(&ex), @"invalid local exception type");
+ const Ice::SyscallException& localEx = dynamic_cast<const Ice::SyscallException&>(ex);
+ error = localEx.error;
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::SyscallException(file, line, error);
+}
+@end
+
+@implementation ICESocketException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::SocketException(file, line, [self error]);
+}
+@end
+
+@implementation ICEConnectFailedException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ConnectFailedException(file, line, [self error]);
+}
+@end
+
+@implementation ICEConnectionRefusedException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ConnectionRefusedException(file, line, [self error]);
+}
+@end
+
+@implementation ICEConnectionLostException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ConnectionLostException(file, line, [self error]);
+}
+@end
+
+@implementation ICEFileException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::FileException*>(&ex), @"invalid local exception type");
+ const Ice::FileException& localEx = dynamic_cast<const Ice::FileException&>(ex);
+ path = toNSString(localEx.path);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::FileException(file, line, [self error], fromNSString(path));
+}
+@end
+
+@implementation ICEDNSException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::DNSException*>(&ex), @"invalid local exception type");
+ const Ice::DNSException& localEx = dynamic_cast<const Ice::DNSException&>(ex);
+ error = localEx.error;
+ host = toNSString(localEx.host);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::DNSException(file, line, [self error], fromNSString(host));
+}
+@end
+
+@implementation ICETimeoutException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::TimeoutException(file, line);
+}
+@end
+
+@implementation ICEConnectTimeoutException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ConnectTimeoutException(file, line);
+}
+@end
+
+@implementation ICECloseTimeoutException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::CloseTimeoutException(file, line);
+}
+@end
+
+@implementation ICEConnectionTimeoutException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ConnectionTimeoutException(file, line);
+}
+@end
+
+@implementation ICEProtocolException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::ProtocolException*>(&ex), @"invalid local exception type");
+ const Ice::ProtocolException& localEx = dynamic_cast<const Ice::ProtocolException&>(ex);
+ reason_ = toNSString(localEx.reason);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::ProtocolException(file, line, fromNSString(reason_));
+}
+@end
+
+@implementation ICEUnknownMessageException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::UnknownMessageException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEConnectionNotValidatedException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ConnectionNotValidatedException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEUnknownRequestIdException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::UnknownRequestIdException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEUnknownReplyStatusException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::UnknownReplyStatusException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICECloseConnectionException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::CloseConnectionException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEForcedCloseConnectionException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ForcedCloseConnectionException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEIllegalMessageSizeException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::IllegalMessageSizeException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICECompressionException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::CompressionException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEDatagramLimitException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::DatagramLimitException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEMarshalException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::MarshalException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEProxyUnmarshalException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ProxyUnmarshalException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEUnmarshalOutOfBoundsException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::UnmarshalOutOfBoundsException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEMemoryLimitException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::MemoryLimitException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEStringConversionException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::StringConversionException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEEncapsulationException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::EncapsulationException(file, line, fromNSString([self reason_]));
+}
+@end
+
+@implementation ICEBadMagicException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::BadMagicException*>(&ex), @"invalid local exception type");
+ const Ice::BadMagicException& localEx = dynamic_cast<const Ice::BadMagicException&>(ex);
+ badMagic = toNSData(localEx.badMagic);
+ return self;
+}
+-(void) rethrowCxx
+{
+ Ice::ByteSeq s;
+ throw Ice::BadMagicException(file, line, fromNSString([self reason_]), fromNSData(badMagic, s));
+}
+@end
+
+@implementation ICEUnsupportedProtocolException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::UnsupportedProtocolException*>(&ex), @"invalid local exception type");
+ const Ice::UnsupportedProtocolException& localEx = dynamic_cast<const Ice::UnsupportedProtocolException&>(ex);
+ bad = [[ICEProtocolVersion protocolVersionWithProtocolVersion:localEx.bad] retain];
+ supported = [[ICEProtocolVersion protocolVersionWithProtocolVersion:localEx.supported] retain];
+ return self;
+}
+-(void) rethrowCxx
+{
+ Ice::ProtocolVersion badVersion = [bad protocolVersion];
+ Ice::ProtocolVersion supportedVersion = [supported protocolVersion];
+ throw Ice::UnsupportedProtocolException(file, line, fromNSString([self reason_]), badVersion, supportedVersion);
+}
+@end
+
+@implementation ICEUnsupportedEncodingException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::UnsupportedEncodingException*>(&ex), @"invalid local exception type");
+ const Ice::UnsupportedEncodingException& localEx = dynamic_cast<const Ice::UnsupportedEncodingException&>(ex);
+ bad = [[ICEEncodingVersion encodingVersionWithEncodingVersion:localEx.bad] retain];
+ supported = [[ICEEncodingVersion encodingVersionWithEncodingVersion:localEx.supported] retain];
+ return self;
+}
+-(void) rethrowCxx
+{
+ Ice::EncodingVersion badVersion = [bad encodingVersion];
+ Ice::EncodingVersion supportedVersion = [supported encodingVersion];
+ throw Ice::UnsupportedEncodingException(file, line, fromNSString([self reason_]), badVersion, supportedVersion);
+}
+@end
+
+@implementation ICENoObjectFactoryException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::NoObjectFactoryException*>(&ex), @"invalid local exception type");
+ const Ice::NoObjectFactoryException& localEx = dynamic_cast<const Ice::NoObjectFactoryException&>(ex);
+ type = toNSString(localEx.type);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::NoObjectFactoryException(file, line, fromNSString([self reason_]), fromNSString(type));
+}
+@end
+
+@implementation ICEUnexpectedObjectException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::UnexpectedObjectException*>(&ex), @"invalid local exception type");
+ const Ice::UnexpectedObjectException& localEx = dynamic_cast<const Ice::UnexpectedObjectException&>(ex);
+ type = toNSString(localEx.type);
+ expectedType = toNSString(localEx.expectedType);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::UnexpectedObjectException(file, line, fromNSString([self reason_]), fromNSString(type), fromNSString(expectedType));
+}
+@end
+
+@implementation ICEFeatureNotSupportedException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::FeatureNotSupportedException*>(&ex), @"invalid local exception type");
+ const Ice::FeatureNotSupportedException& localEx = dynamic_cast<const Ice::FeatureNotSupportedException&>(ex);
+ unsupportedFeature = toNSString(localEx.unsupportedFeature);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::FeatureNotSupportedException(file, line, fromNSString(unsupportedFeature));
+}
+@end
+
+@implementation ICESecurityException (ICEInternal)
+-(id)initWithLocalException:(const Ice::LocalException&)ex
+{
+ self = [super initWithLocalException:ex];
+ if(!self)
+ {
+ return nil;
+ }
+ NSAssert(dynamic_cast<const Ice::SecurityException*>(&ex), @"invalid local exception type");
+ const Ice::SecurityException& localEx = dynamic_cast<const Ice::SecurityException&>(ex);
+ reason_ = toNSString(localEx.reason);
+ return self;
+}
+-(void) rethrowCxx
+{
+ throw Ice::SecurityException(file, line, fromNSString(reason_));
+}
+@end
+
+@implementation ICEFixedProxyException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::FixedProxyException(file, line);
+}
+@end
+
+@implementation ICEResponseSentException (ICEInternal)
+-(void) rethrowCxx
+{
+ throw Ice::ResponseSentException(file, line);
+}
+@end
diff --git a/objc/src/Ice/ExceptionI.h b/objc/src/Ice/ExceptionI.h
new file mode 100644
index 00000000000..b65ca66cabf
--- /dev/null
+++ b/objc/src/Ice/ExceptionI.h
@@ -0,0 +1,18 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Exception.h>
+
+#include <IceCpp/Exception.h>
+
+@interface ICELocalException ()
+-(id) initWithLocalException:(const Ice::LocalException&)ex;
+-(void) rethrowCxx;
++(id) localExceptionWithLocalException:(const Ice::LocalException&)ex;
+@end
diff --git a/objc/src/Ice/IdentityI.h b/objc/src/Ice/IdentityI.h
new file mode 100644
index 00000000000..2236c51d8b5
--- /dev/null
+++ b/objc/src/Ice/IdentityI.h
@@ -0,0 +1,18 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Identity.h>
+
+#include <IceCpp/Identity.h>
+
+@interface ICEIdentity (ICEInternal)
+-(ICEIdentity*)initWithIdentity:(const Ice::Identity&)arg;
+-(Ice::Identity)identity;
++(ICEIdentity*)identityWithIdentity:(const Ice::Identity&)arg;
+@end
diff --git a/objc/src/Ice/IdentityI.mm b/objc/src/Ice/IdentityI.mm
new file mode 100644
index 00000000000..d8200de49a2
--- /dev/null
+++ b/objc/src/Ice/IdentityI.mm
@@ -0,0 +1,40 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <IdentityI.h>
+#import <Util.h>
+
+@implementation ICEIdentity (ICEInternal)
+
+-(ICEIdentity*) initWithIdentity:(const Ice::Identity&)arg
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ category = [[NSString alloc] initWithUTF8String:arg.category.c_str()];
+ name = [[NSString alloc] initWithUTF8String:arg.name.c_str()];
+ return self;
+}
+
+-(Ice::Identity) identity
+{
+ Ice::Identity ident;
+ ident.category = fromNSString(category);
+ ident.name = fromNSString(name);
+ return ident;
+}
+
++(ICEIdentity*) identityWithIdentity:(const Ice::Identity&)arg
+{
+ return [[[ICEIdentity alloc] initWithIdentity:arg] autorelease];
+}
+
+@end
diff --git a/objc/src/Ice/ImplicitContext.mm b/objc/src/Ice/ImplicitContext.mm
new file mode 100644
index 00000000000..689a081e981
--- /dev/null
+++ b/objc/src/Ice/ImplicitContext.mm
@@ -0,0 +1,83 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ImplicitContextI.h>
+#import <Util.h>
+
+@implementation ICEImplicitContext
+
+-(id) init:(Ice::ImplicitContext*)implicitContext
+{
+ self = [super init];
+ if(self)
+ {
+ self->implicitContext__ = implicitContext;
+ self->implicitContext__->__incRef();
+ }
+ return self;
+}
+
++(id) implicitContextWithImplicitContext:(Ice::ImplicitContext*)implicitContext
+{
+ if(!implicitContext)
+ {
+ return nil;
+ }
+ else
+ {
+ return [[[ICEImplicitContext alloc] init:implicitContext] autorelease];
+ }
+}
+
+-(void) dealloc
+{
+ self->implicitContext__->__decRef();
+ [super dealloc];
+}
+
+-(ICEContext*) getContext
+{
+ return [toNSDictionary(implicitContext__->getContext()) autorelease];
+}
+
+-(void) setContext:(ICEContext*)context
+{
+ Ice::Context ctx;
+ fromNSDictionary(context, ctx);
+ implicitContext__->setContext(ctx);
+}
+
+-(BOOL) containsKey:(NSString*)key
+{
+ return implicitContext__->containsKey(fromNSString(key));
+}
+
+-(NSString*) get:(NSString*)key
+{
+ if(implicitContext__->containsKey(fromNSString(key)))
+ {
+ return [toNSString(implicitContext__->get(fromNSString(key))) autorelease];
+ }
+ else
+ {
+ return nil;
+ }
+}
+
+-(NSString*) put:(NSString*)key value:(NSString*)value
+{
+ return [toNSString(implicitContext__->put(fromNSString(key), fromNSString(value))) autorelease];
+}
+
+-(NSString*) remove:(NSString*)key
+{
+ return [toNSString(implicitContext__->remove(fromNSString(key))) autorelease];
+}
+
+@end
diff --git a/objc/src/Ice/ImplicitContextI.h b/objc/src/Ice/ImplicitContextI.h
new file mode 100644
index 00000000000..a7566e1b9cd
--- /dev/null
+++ b/objc/src/Ice/ImplicitContextI.h
@@ -0,0 +1,22 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/ImplicitContext.h>
+
+#include <IceCpp/ImplicitContext.h>
+
+@interface ICEImplicitContext : NSObject<ICEImplicitContext>
+{
+@private
+
+ Ice::ImplicitContext* implicitContext__;
+}
+-(id) init:(Ice::ImplicitContext*)implicitContext;
++(id) implicitContextWithImplicitContext:(Ice::ImplicitContext*)implicitContext;
+@end
diff --git a/objc/src/Ice/Initialize.mm b/objc/src/Ice/Initialize.mm
new file mode 100644
index 00000000000..81956a161a2
--- /dev/null
+++ b/objc/src/Ice/Initialize.mm
@@ -0,0 +1,623 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <InitializeI.h>
+#import <PropertiesI.h>
+#import <CommunicatorI.h>
+#import <StreamI.h>
+#import <LoggerI.h>
+#import <DispatcherI.h>
+#import <Util.h>
+#import <VersionI.h>
+
+#import <objc/Ice/LocalException.h>
+
+#include <IceCpp/Initialize.h>
+#include <IceUtilCpp/UUID.h>
+#include <IceUtilCpp/MutexPtrLock.h>
+
+#include <Availability.h>
+
+#import <Foundation/NSAutoreleasePool.h>
+#import <Foundation/NSThread.h>
+
+#ifdef ICE_NO_KQUEUE
+# define ICE_USE_CFSTREAM 1
+#endif
+
+namespace
+{
+typedef std::map<int, std::string> CompactIdMap;
+
+IceUtil::Mutex* _compactIdMapMutex = 0;
+CompactIdMap* _compactIdMap = 0;
+
+class CompactIdResolverI : public Ice::CompactIdResolver
+{
+public:
+
+ virtual ::std::string
+ resolve(::Ice::Int value) const
+ {
+ assert(_compactIdMapMutex);
+ assert(_compactIdMap);
+
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_compactIdMapMutex);
+ CompactIdMap::iterator p = _compactIdMap->find(value);
+ if(p != _compactIdMap->end())
+ {
+ return p->second;
+ }
+ return ::std::string();
+ }
+};
+
+//
+// We don't use the constructor to initialize the compactIdMap as
+// static initializtion takes place after +load is called.
+//
+class Init
+{
+public:
+
+ ~Init()
+ {
+ if(_compactIdMap)
+ {
+ delete _compactIdMap;
+ _compactIdMap = 0;
+ }
+
+ if(_compactIdMapMutex)
+ {
+ delete _compactIdMapMutex;
+ _compactIdMapMutex = 0;
+ }
+ }
+};
+Init init;
+
+}
+
+@implementation CompactIdMapHelper
++(void) initialize
+{
+ assert(!_compactIdMapMutex);
+ assert(!_compactIdMap);
+ _compactIdMapMutex = new ::IceUtil::Mutex;
+ _compactIdMap = new CompactIdMap;
+}
+
++(void) registerClass:(NSString*)type value:(ICEInt)value
+{
+ assert(_compactIdMapMutex);
+ assert(_compactIdMap);
+
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_compactIdMapMutex);
+ CompactIdMap::iterator p = _compactIdMap->find(value);
+ if(p != _compactIdMap->end())
+ {
+ _compactIdMap->erase(p);
+ }
+ _compactIdMap->insert(CompactIdMap::value_type(value, fromNSString(type)));
+}
+@end
+
+namespace IceObjC
+{
+
+class ThreadNotification : public Ice::ThreadNotification, public IceUtil::Mutex
+{
+public:
+
+ ThreadNotification()
+ {
+ }
+
+ virtual void start()
+ {
+ Lock sync(*this);
+ _pools.insert(std::make_pair(IceUtil::ThreadControl().id(), [[NSAutoreleasePool alloc] init]));
+ }
+
+ virtual void stop()
+ {
+ Lock sync(*this);
+ std::map<IceUtil::ThreadControl::ID, NSAutoreleasePool*>::iterator p =
+ _pools.find(IceUtil::ThreadControl().id());
+ [p->second drain];
+ _pools.erase(p);
+ }
+
+private:
+
+ std::map<IceUtil::ThreadControl::ID, NSAutoreleasePool*> _pools;
+};
+
+};
+
+@implementation ICEInitializationData (ICEInternal)
+-(Ice::InitializationData)initializationData
+{
+ Ice::InitializationData data;
+ data.properties = [(ICEProperties*)properties properties];
+ data.logger = [ICELogger loggerWithLogger:logger];
+ if(dispatcher)
+ {
+ data.dispatcher = [ICEDispatcher dispatcherWithDispatcher:dispatcher];
+ }
+ data.compactIdResolver = new CompactIdResolverI;
+ return data;
+}
+@end
+
+@implementation ICEInitializationData
+
+@synthesize properties;
+@synthesize logger;
+@synthesize dispatcher;
+@synthesize prefixTable__;
+
+-(id) init:(id<ICEProperties>)props logger:(id<ICELogger>)log
+dispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))d;
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ properties = [props retain];
+ logger = [log retain];
+ dispatcher = [d copy];
+ return self;
+}
+
++(id) initializationData;
+{
+ ICEInitializationData *s = [[ICEInitializationData alloc] init];
+ [s autorelease];
+ return s;
+}
+
++(id) initializationData:(id<ICEProperties>)p logger:(id<ICELogger>)l
+ dispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))d;
+{
+ return [[((ICEInitializationData *)[ICEInitializationData alloc]) init:p logger:l dispatcher:d] autorelease];
+}
+
+-(id) copyWithZone:(NSZone *)zone
+{
+ ICEInitializationData *copy = [ICEInitializationData allocWithZone:zone];
+ copy->properties = [properties retain];
+ copy->logger = [logger retain];
+ copy->dispatcher = [dispatcher copy];
+ copy->prefixTable__ = [prefixTable__ retain];
+ return copy;
+}
+
+-(NSUInteger) hash;
+{
+ NSUInteger h = 0;
+ h = (h << 1 ^ [properties hash]);
+ h = (h << 1 ^ [logger hash]);
+ h = (h << 1 ^ [prefixTable__ hash]);
+ return h;
+}
+
+-(BOOL) isEqual:(id)anObject;
+{
+ if(self == anObject)
+ {
+ return YES;
+ }
+ if(!anObject || ![anObject isKindOfClass:[self class]])
+ {
+ return NO;
+ }
+ ICEInitializationData * obj =(ICEInitializationData *)anObject;
+ if(!properties)
+ {
+ if(obj->properties)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![properties isEqual:obj->properties])
+ {
+ return NO;
+ }
+ }
+ if(!logger)
+ {
+ if(obj->logger)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![logger isEqual:obj->logger])
+ {
+ return NO;
+ }
+ }
+ if(!dispatcher)
+ {
+ if(obj->dispatcher)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(dispatcher == obj->dispatcher)
+ {
+ return NO;
+ }
+ }
+ if(!prefixTable__)
+ {
+ if(obj->prefixTable__)
+ {
+ return NO;
+ }
+ }
+ else
+ {
+ if(![prefixTable__ isEqual:obj->prefixTable__])
+ {
+ return NO;
+ }
+ }
+ return YES;
+}
+
+-(void) dealloc;
+{
+ [properties release];
+ [logger release];
+ [dispatcher release];
+ [prefixTable__ release];
+ [super dealloc];
+}
+@end
+
+@implementation ICEUtil
++(id<ICEProperties>) createProperties
+{
+ return [self createProperties:nil argv:nil];
+}
+
++(id<ICEProperties>) createProperties:(int*)argc argv:(char*[])argv
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::PropertiesPtr properties;
+ if(argc != nil && argv != nil)
+ {
+ properties = Ice::createProperties(*argc, argv);
+ }
+ else
+ {
+ properties = Ice::createProperties();
+ }
+ return [ICEProperties wrapperWithCxxObject:properties.get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
++(id<ICECommunicator>) createCommunicator
+{
+ return [self createCommunicator:nil argv:nil initData:nil];
+}
+
++(id<ICECommunicator>) createCommunicator:(ICEInitializationData*)initData
+{
+ return [self createCommunicator:nil argv:nil initData:initData];
+}
+
++(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv
+{
+ return [self createCommunicator:argc argv:argv initData:nil];
+}
+
++(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv initData:(ICEInitializationData*)initData
+{
+ if(![NSThread isMultiThreaded]) // Ensure sure Cocoa is multithreaded.
+ {
+ NSThread* thread = [[NSThread alloc] init];
+ [thread start];
+ [thread release];
+ }
+
+ id<ICEProperties> properties = [initData properties];
+ if(properties != nil && ![properties isKindOfClass:[ICEProperties class]])
+ {
+ @throw [ICEInitializationException initializationException:__FILE__ line:__LINE__
+ reason_:@"properties were not created with createProperties"];
+ }
+
+ NSException* nsex = nil;
+ try
+ {
+ Ice::InitializationData data;
+ if(initData != nil)
+ {
+ data = [initData initializationData];
+ }
+ data.threadHook = new IceObjC::ThreadNotification();
+ if(!data.properties)
+ {
+ data.properties = Ice::createProperties();
+ }
+ data.properties->setProperty("Ice.Default.CollocationOptimized", "0");
+
+ if(argc != nil && argv != nil)
+ {
+ data.properties = createProperties(*argc, argv, data.properties);
+ }
+
+ Ice::CommunicatorPtr communicator;
+ if(argc != nil && argv != nil)
+ {
+ communicator = Ice::initialize(*argc, argv, data);
+ }
+ else
+ {
+ communicator = Ice::initialize(data);
+ }
+
+ ICECommunicator* c = [ICECommunicator wrapperWithCxxObject:communicator.get()];
+ [c setup:initData.prefixTable__];
+ return c;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
++(id<ICEInputStream>) createInputStream:(id<ICECommunicator>)communicator data:(NSData*)data
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::CommunicatorPtr com = [(ICECommunicator*)communicator communicator];
+ Ice::Byte* start = (Ice::Byte*)[data bytes];
+ Ice::Byte* end = (Ice::Byte*)[data bytes] + [data length];
+ Ice::InputStreamPtr is = Ice::createInputStream(com, std::make_pair(start, end));
+ if(is)
+ {
+ return [ICEInputStream wrapperWithCxxObject:is.get()];
+ }
+ else
+ {
+ return nil;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
++(id<ICEInputStream>) createInputStream:(id<ICECommunicator>)c data:(NSData*)data encoding:(ICEEncodingVersion*)e
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::CommunicatorPtr com = [(ICECommunicator*)c communicator];
+ Ice::Byte* start = (Ice::Byte*)[data bytes];
+ Ice::Byte* end = (Ice::Byte*)[data bytes] + [data length];
+ Ice::InputStreamPtr is = Ice::createInputStream(com, std::make_pair(start, end), [e encodingVersion]);
+ if(is)
+ {
+ return [ICEInputStream wrapperWithCxxObject:is.get()];
+ }
+ else
+ {
+ return nil;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
++(id<ICEInputStream>) wrapInputStream:(id<ICECommunicator>)communicator data:(NSData*)data
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::CommunicatorPtr com = [(ICECommunicator*)communicator communicator];
+ Ice::Byte* start = (Ice::Byte*)[data bytes];
+ Ice::Byte* end = (Ice::Byte*)[data bytes] + [data length];
+ Ice::InputStreamPtr is = Ice::wrapInputStream(com, std::make_pair(start, end));
+ if(is)
+ {
+ return [ICEInputStream wrapperWithCxxObject:is.get()];
+ }
+ else
+ {
+ return nil;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
++(id<ICEInputStream>) wrapInputStream:(id<ICECommunicator>)c data:(NSData*)data encoding:(ICEEncodingVersion*)e
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::CommunicatorPtr com = [(ICECommunicator*)c communicator];
+ Ice::Byte* start = (Ice::Byte*)[data bytes];
+ Ice::Byte* end = (Ice::Byte*)[data bytes] + [data length];
+ Ice::InputStreamPtr is = Ice::wrapInputStream(com, std::make_pair(start, end), [e encodingVersion]);
+ if(is)
+ {
+ return [ICEInputStream wrapperWithCxxObject:is.get()];
+ }
+ else
+ {
+ return nil;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
++(id<ICEOutputStream>) createOutputStream:(id<ICECommunicator>)communicator
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::CommunicatorPtr com = [(ICECommunicator*)communicator communicator];
+ Ice::OutputStreamPtr os = Ice::createOutputStream(com);
+ if(os)
+ {
+ return [ICEOutputStream wrapperWithCxxObject:os.get()];
+ }
+ else
+ {
+ return nil;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
++(id<ICEOutputStream>) createOutputStream:(id<ICECommunicator>)communicator encoding:(ICEEncodingVersion*)encoding
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::CommunicatorPtr com = [(ICECommunicator*)communicator communicator];
+ Ice::OutputStreamPtr os = Ice::createOutputStream(com, [encoding encodingVersion]);
+ if(os)
+ {
+ return [ICEOutputStream wrapperWithCxxObject:os.get()];
+ }
+ else
+ {
+ return nil;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
++(NSString*) generateUUID
+{
+ return [NSString stringWithUTF8String:IceUtil::generateUUID().c_str()];
+}
+
++(NSArray*)argsToStringSeq:(int)argc argv:(char*[])argv
+{
+ NSMutableArray* ns = [NSMutableArray array];
+ int i;
+ for(i = 0; i < argc; ++i)
+ {
+ [ns addObject:[NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding]];
+ }
+ return [[ns copy] autorelease];
+}
+
++(void)stringSeqToArgs:(NSArray*)args argc:(int*)argc argv:(char*[])argv;
+{
+ //
+ // Shift all elements in argv which are present in args to the
+ // beginning of argv. We record the original value of argc so
+ // that we can know later if we've shifted the array.
+ //
+ const int argcOrig = *argc;
+ int i = 0;
+ while(i < *argc)
+ {
+ BOOL found = NO;
+ for(NSString* s in args)
+ {
+ if([s compare:[NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding]] == 0)
+ {
+ found = YES;
+ break;
+ }
+ }
+ if(!found)
+ {
+ int j;
+ for(j = i; j < *argc - 1; j++)
+ {
+ argv[j] = argv[j + 1];
+ }
+ --(*argc);
+ }
+ else
+ {
+ ++i;
+ }
+ }
+
+ //
+ // Make sure that argv[*argc] == 0, the ISO C++ standard requires this.
+ // We can only do this if we've shifted the array, otherwise argv[*argc]
+ // may point to an invalid address.
+ //
+ if(argv && argcOrig != *argc)
+ {
+ argv[*argc] = 0;
+ }
+}
+@end
+
+@implementation ICEEncodingVersion(StringConv)
++(ICEEncodingVersion*) encodingVersionWithString:(NSString*)str
+{
+ return [ICEEncodingVersion encodingVersionWithEncodingVersion:Ice::stringToEncodingVersion(fromNSString(str))];
+}
+@end
+
+@implementation ICEProtocolVersion(StringConv)
++(ICEProtocolVersion*) protocolVersionWithString:(NSString*)str
+{
+ return [ICEProtocolVersion protocolVersionWithProtocolVersion:Ice::stringToProtocolVersion(fromNSString(str))];
+}
+@end
diff --git a/objc/src/Ice/InitializeI.h b/objc/src/Ice/InitializeI.h
new file mode 100644
index 00000000000..22fed8e692a
--- /dev/null
+++ b/objc/src/Ice/InitializeI.h
@@ -0,0 +1,16 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Initialize.h>
+
+#include <IceCpp/Initialize.h>
+
+@interface ICEInitializationData (ICEInternal)
+-(Ice::InitializationData)initializationData;
+@end
diff --git a/objc/src/Ice/Logger.mm b/objc/src/Ice/Logger.mm
new file mode 100644
index 00000000000..804ea99edca
--- /dev/null
+++ b/objc/src/Ice/Logger.mm
@@ -0,0 +1,194 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <LoggerI.h>
+#import <Util.h>
+
+#import <Foundation/NSDate.h>
+
+namespace
+{
+
+class LoggerI : public Ice::Logger
+{
+public:
+
+// We must explicitely CFRetain/CFRelease so that the garbage
+// collector does not trash the logger.
+LoggerI(id<ICELogger> logger) : _logger(logger)
+{
+ CFRetain(_logger);
+}
+
+virtual ~LoggerI()
+{
+ CFRelease(_logger);
+}
+
+virtual void
+print(const std::string& msg)
+{
+ NSString* s = toNSString(msg);
+ @try
+ {
+ [_logger print:s];
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ @finally
+ {
+ [s release];
+ }
+}
+
+virtual void
+trace(const std::string& category, const std::string& msg)
+{
+ NSString* s1 = toNSString(category);
+ NSString* s2 = toNSString(msg);
+ @try
+ {
+ [_logger trace:s1 message:s2];
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ @finally
+ {
+ [s1 release];
+ [s2 release];
+ }
+}
+
+virtual void
+warning(const std::string& msg)
+{
+ NSString* s = toNSString(msg);
+ @try
+ {
+ [_logger warning:s];
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ @finally
+ {
+ [s release];
+ }
+}
+
+virtual void
+error(const std::string& msg)
+{
+ NSString* s = toNSString(msg);
+ @try
+ {
+ [_logger error:s];
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ @finally
+ {
+ [s release];
+ }
+}
+
+virtual Ice::LoggerPtr
+cloneWithPrefix(const std::string& prefix)
+{
+ return this;
+}
+
+virtual std::string
+getPrefix()
+{
+ return fromNSString([_logger getPrefix]);
+}
+
+id<ICELogger>
+getLogger()
+{
+ return _logger;
+}
+
+private:
+
+id<ICELogger> _logger;
+
+};
+typedef IceUtil::Handle<LoggerI> LoggerIPtr;
+
+}
+
+@implementation ICELogger
++(Ice::Logger*) loggerWithLogger:(id<ICELogger>)logger
+{
+ if(logger == 0)
+ {
+ id<ICELogger> l = [[self alloc] init];
+ Ice::Logger* impl = new LoggerI(l);
+ [l release];
+ return impl;
+ }
+ else
+ {
+ return new LoggerI(logger);
+ }
+}
++(id) wrapperWithCxxObject:(IceUtil::Shared*)cxxObject
+{
+ LoggerI* impl = dynamic_cast<LoggerI*>(cxxObject);
+ assert(impl);
+ return [[impl->getLogger() retain] autorelease];
+}
+
+//
+// @protocol Logger methods.
+//
+
+-(void) print:(NSString*)message
+{
+ NSLog(@"%@", message);
+}
+
+-(void) trace:(NSString*)category message:(NSString*)message
+{
+ NSMutableString* s = [[NSMutableString alloc] initWithFormat:@"[%@: %@]", category, message];
+#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+ [s replaceOccurrencesOfString:@"\n" withString:@" " options:0 range:NSMakeRange(0, s.length)];
+#endif
+ [self print:s];
+ [s release];
+}
+
+-(void) warning:(NSString*)message
+{
+ NSString* s = [[NSString alloc] initWithFormat:@"warning: %@", message];
+ [self print:s];
+ [s release];
+}
+
+-(void) error:(NSString*)message
+{
+ NSString* s = [[NSString alloc] initWithFormat:@"error: %@", message];
+ [self print:s];
+ [s release];
+}
+
+-(NSString*) getPrefix
+{
+ return @"";
+}
+@end
diff --git a/objc/src/Ice/LoggerI.h b/objc/src/Ice/LoggerI.h
new file mode 100644
index 00000000000..d01e3490c42
--- /dev/null
+++ b/objc/src/Ice/LoggerI.h
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Logger.h>
+
+#import <Wrapper.h>
+
+#include <IceCpp/Logger.h>
+
+@interface ICELogger : NSObject<ICELogger>
+{
+}
++(Ice::Logger*)loggerWithLogger:(id<ICELogger>)arg;
++(id) wrapperWithCxxObject:(IceUtil::Shared*)cxxObject;
+@end
diff --git a/objc/src/Ice/Makefile b/objc/src/Ice/Makefile
new file mode 100644
index 00000000000..c3c88356e95
--- /dev/null
+++ b/objc/src/Ice/Makefile
@@ -0,0 +1,140 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+LIBFILENAME = $(call mklibfilename,IceObjC$(libsuffix),$(VERSION))
+SONAME = $(call mksoname,IceObjC$(libsuffix),$(SOVERSION))
+LIBNAME = $(call mklibname,IceObjC$(libsuffix))
+
+TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME))
+
+SLICE_OBJS = BuiltinSequences.o \
+ Identity.o \
+ Locator.o \
+ LocatorF.o \
+ LocalException.o \
+ Metrics.o \
+ Process.o \
+ ProcessF.o \
+ PropertiesAdmin.o \
+ RemoteLogger.o \
+ Router.o \
+ RouterF.o \
+ SliceChecksumDict.o \
+ Version.o
+
+OBJC_OBJS = DispatchInterceptor.o \
+ Request.o \
+ $(SLICE_OBJS)
+
+OBJCXX_OBJS = Communicator.o \
+ Connection.o \
+ Current.o \
+ Exception.o \
+ Dispatcher.o \
+ IdentityI.o \
+ Initialize.o \
+ Logger.o \
+ Object.o \
+ ObjectAdapter.o \
+ Properties.o \
+ Proxy.o \
+ Stream.o \
+ SlicedData.o \
+ Util.o \
+ VersionI.o \
+ Wrapper.o \
+ ImplicitContext.o \
+ Endpoint.o
+
+OBJS := $(OBJC_OBJS) $(OBJCXX_OBJS)
+
+HDIR = $(includedir)/objc/Ice
+SDIR = $(slicedir)/Ice
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -Iinclude $(CPPFLAGS)
+SLICE2OBJCFLAGS := --ice --include-dir objc/Ice $(SLICE2OBJCFLAGS)
+DEPENDFLAGS = --obj-dir
+LINKWITH := $(BASELIBS)
+
+ifeq ($(wildcard .depend/*.d),)
+
+ice_cpp_include = $(ice_cpp_dir)/include
+
+$(OBJCXX_OBJS:.o=.mm): \
+ $(patsubst $(ice_cpp_include)/IceUtil/%.h,include/IceUtilCpp/%.h,$(wildcard $(ice_cpp_include)/IceUtil/*.h)) \
+ $(patsubst $(ice_cpp_include)/Ice/%.h,include/IceCpp/%.h,$(wildcard $(ice_cpp_include)/Ice/*.h)) \
+ $(patsubst $(ice_cpp_include)/IceSSL/%.h,include/IceSSLCpp/%.h,$(wildcard $(ice_cpp_include)/IceSSL/*.h))
+
+include/IceUtilCpp/%.h: $(ice_cpp_include)/IceUtil/%.h
+ @echo Creating $@ from $<
+ @mkdir -p include/IceUtilCpp
+ @sed -e "s%IceUtil/%IceUtilCpp/%g" $< > $@
+
+include/IceCpp/%.h: $(ice_cpp_include)/Ice/%.h
+ @echo Creating $@ from $<
+ @mkdir -p include/IceCpp
+ @sed -e "s%IceUtil/%IceUtilCpp/%g;s%Ice/%IceCpp/%g" $< > $@
+
+include/IceSSLCpp/%.h: $(ice_cpp_include)/IceSSL/%.h
+ @echo Creating $@ from $<
+ @mkdir -p include/IceSSLCpp
+ @sed -e "s%IceUtil/%IceUtilCpp/%g;s%Ice/%IceCpp/%g;s%IceSSL/%IceSSLCpp/%g" $< > $@
+
+endif
+
+$(libdir)/$(LIBFILENAME): $(OBJS)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH))
+
+$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME)
+ rm -f $@
+ ln -s $(LIBFILENAME) $@
+
+$(libdir)/$(LIBNAME): $(libdir)/$(SONAME)
+ rm -f $@
+ ln -s $(SONAME) $@
+
+# Prevent generation of these files from .ice files
+
+$(HDIR)/ImplicitContext.h ImplicitContext.m:
+ @echo
+
+$(HDIR)/Communicator.h Communicator.m:
+ @echo
+
+$(HDIR)/Current.h Current.m:
+ @echo
+
+$(HDIR)/Logger.h Logger.m:
+ @echo
+
+$(HDIR)/ObjectAdapter.h ObjectAdapter.m:
+ @echo
+
+$(HDIR)/Properties.h Properties.m:
+ @echo
+
+$(HDIR)/Endpoint.h Endpoint.m:
+ @echo
+
+$(HDIR)/Connection.h Connection.m:
+ @echo
+
+$(HDIR)/ObjectFactory.h ObjectFactory.m:
+ @echo
+
+install:: all
+ $(call installlib,$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME))
+
+clean::
+ rm -rf include
diff --git a/objc/src/Ice/Object.mm b/objc/src/Ice/Object.mm
new file mode 100644
index 00000000000..cd2b7704fed
--- /dev/null
+++ b/objc/src/Ice/Object.mm
@@ -0,0 +1,567 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ObjectI.h>
+#import <StreamI.h>
+#import <CurrentI.h>
+#import <Util.h>
+#import <Request.h>
+
+#import <objc/Ice/LocalException.h>
+
+#include <IceCpp/Object.h>
+#include <IceCpp/IncomingAsync.h>
+#include <IceCpp/Initialize.h>
+#include <IceCpp/ObjectAdapter.h>
+
+#import <Foundation/NSAutoreleasePool.h>
+
+int
+ICEInternalLookupString(NSString* const array[], size_t count, NSString* __unsafe_unretained str)
+{
+ size_t low = 0;
+ size_t high = count - 1;
+ while(low <= high)
+ {
+ size_t mid = (low + high) / 2;
+ switch([array[mid] compare:str])
+ {
+ case NSOrderedDescending:
+ if(mid == 0)
+ {
+ return -1;
+ }
+ high = mid - 1;
+ break;
+ case NSOrderedAscending:
+ low = mid + 1;
+ break;
+ case NSOrderedSame:
+ return mid;
+ default:
+ return -1; // Can't be reached
+ }
+ }
+ return -1;
+}
+
+static NSString*
+operationModeToString(ICEOperationMode mode)
+{
+ switch(mode)
+ {
+ case ICENormal:
+ return @"::Ice::Normal";
+
+ case ICENonmutating:
+ return @"::Ice::Nonmutating";
+
+ case ICEIdempotent:
+ return @"::Ice::Idempotent";
+
+ default:
+ return [NSString stringWithFormat:@"unknown value(%d)", mode];
+ }
+}
+
+void
+ICEInternalCheckModeAndSelector(id target, ICEOperationMode expected, SEL sel, ICECurrent* current)
+{
+ ICEOperationMode received = current.mode;
+ if(expected != received)
+ {
+ if(expected == ICEIdempotent && received == ICENonmutating)
+ {
+ //
+ // Fine: typically an old client still using the deprecated nonmutating keyword
+ //
+
+ //
+ // Note that expected == Nonmutating and received == Idempotent is not ok:
+ // the server may still use the deprecated nonmutating keyword to detect updates
+ // and the client should not break this (deprecated) feature.
+ //
+ }
+ else
+ {
+ ICEMarshalException* ex = [ICEMarshalException marshalException:__FILE__ line:__LINE__];
+ [ex setReason_:[NSString stringWithFormat:@"unexpected operation mode. expected = %@ received=%@",
+ operationModeToString(expected), operationModeToString(received)]];
+ @throw ex;
+ }
+ }
+
+ if(![target respondsToSelector:sel])
+ {
+ @throw [ICEOperationNotExistException operationNotExistException:__FILE__
+ line:__LINE__
+ id_:current.id_
+ facet:current.facet
+ operation:current.operation];
+ }
+}
+
+namespace IceObjC
+{
+
+class ObjectI : public ObjectWrapper, public Ice::BlobjectArrayAsync
+{
+public:
+
+ ObjectI(id<ICEObject>);
+
+ virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&,
+ const std::pair<const Ice::Byte*, const Ice::Byte*>&,
+ const Ice::Current&);
+
+ virtual ICEObject* getObject()
+ {
+ return _object;
+ }
+
+ // We must explicitely CFRetain/CFRelease so that the garbage
+ // collector does not trash the _object.
+ virtual void __incRef()
+ {
+ CFRetain(_object);
+ }
+
+ virtual void __decRef()
+ {
+ CFRelease(_object);
+ }
+
+private:
+
+ ICEObject* _object;
+};
+
+class BlobjectI : public ObjectWrapper, public Ice::BlobjectArrayAsync
+{
+public:
+
+ BlobjectI(ICEBlobject*);
+
+ virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&,
+ const std::pair<const Ice::Byte*, const Ice::Byte*>&,
+ const Ice::Current&);
+
+ virtual ICEObject* getObject()
+ {
+ return _blobject;
+ }
+
+ // We must explicitely CFRetain/CFRelease so that the garbage
+ // collector does not trash the _blobject.
+ virtual void __incRef()
+ {
+ CFRetain(_blobject);
+ }
+
+ virtual void __decRef()
+ {
+ CFRelease(_blobject);
+ }
+
+private:
+
+ ICEBlobject* _blobject;
+ id _target;
+};
+
+}
+
+IceObjC::ObjectI::ObjectI(id<ICEObject> object) : _object((ICEObject*)object)
+{
+}
+
+void
+IceObjC::ObjectI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb,
+ const std::pair<const Ice::Byte*, const Ice::Byte*>& inParams,
+ const Ice::Current& current)
+{
+ ICEInputStream* is = nil;
+ ICEOutputStream* os = nil;
+ {
+ Ice::InputStreamPtr s = Ice::createInputStream(current.adapter->getCommunicator(), inParams);
+ is = [ICEInputStream wrapperWithCxxObjectNoAutoRelease:s.get()];
+ }
+ {
+ Ice::OutputStreamPtr s = Ice::createOutputStream(current.adapter->getCommunicator());
+ os = [ICEOutputStream wrapperWithCxxObjectNoAutoRelease:s.get()];
+ }
+
+ NSException* exception = nil;
+ BOOL ok = YES; // Keep the compiler happy
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ ICECurrent* c = [[ICECurrent alloc] initWithCurrent:current];
+ @try
+ {
+ ok = [_object dispatch__:c is:is os:os];
+ }
+ @catch(id ex)
+ {
+ exception = [ex retain];
+ }
+ @finally
+ {
+ [c release];
+ [is release];
+ [pool drain];
+ }
+
+ if(exception != nil)
+ {
+ [os release];
+ rethrowCxxException(exception, true); // True = release the exception.
+ }
+
+ std::vector<Ice::Byte> outParams;
+ [os os]->finished(outParams);
+ [os release];
+
+ cb->ice_response(ok, std::make_pair(&outParams[0], &outParams[0] + outParams.size()));
+}
+
+IceObjC::BlobjectI::BlobjectI(ICEBlobject* blobject) : _blobject(blobject), _target([blobject target__])
+{
+}
+
+void
+IceObjC::BlobjectI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb,
+ const std::pair<const Ice::Byte*, const Ice::Byte*>& inEncaps,
+ const Ice::Current& current)
+{
+ NSException* exception = nil;
+ BOOL ok = YES; // Keep the compiler happy.
+ NSMutableData* outE = nil;
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ ICECurrent* c = [[ICECurrent alloc] initWithCurrent:current];
+ NSData* inE = [NSData dataWithBytesNoCopy:const_cast<Ice::Byte*>(inEncaps.first)
+ length:(inEncaps.second - inEncaps.first)
+ freeWhenDone:NO];
+ @try
+ {
+ ok = [_target ice_invoke:inE outEncaps:&outE current:c];
+ [outE retain];
+ }
+ @catch(id ex)
+ {
+ exception = [ex retain];
+ }
+ @finally
+ {
+ [c release];
+ [pool drain];
+ }
+
+ if(exception != nil)
+ {
+ rethrowCxxException(exception, true); // True = release the exception.
+ }
+
+ cb->ice_response(ok, std::make_pair((ICEByte*)[outE bytes], (ICEByte*)[outE bytes] + [outE length]));
+ [outE release];
+}
+
+@implementation ICEInternalPrefixTable
+@end
+
+@implementation ICEObject (ICEInternal)
+
+-(id)init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ object__ = 0;
+ delegate__ = 0;
+ return self;
+}
+
+-(Ice::Object*) object__
+{
+ @synchronized([self class])
+ {
+ if(object__ == 0)
+ {
+ //
+ // NOTE: IceObjC::ObjectI implements it own reference counting and there's no need
+ // to call __incRef/__decRef here. The C++ object and Objective-C object are sharing
+ // the same reference count (the one of the Objective-C object). This is necessary
+ // to properly release both objects when there's either no more C++ handle/ObjC
+ // reference to the object (without this, servants added to the object adapter
+ // couldn't be retained or released easily).
+ //
+ object__ = (IceObjC::ObjectWrapper*)new IceObjC::ObjectI(self);
+ }
+ }
+ return (IceObjC::ObjectWrapper*)object__;
+}
+
+-(void) dealloc
+{
+ if(object__)
+ {
+ delete (IceObjC::ObjectWrapper*)object__;
+ object__ = 0;
+ }
+ [delegate__ release];
+ [super dealloc];
+}
+
+-(void) finalize
+{
+ if(object__)
+ {
+ delete (IceObjC::ObjectWrapper*)object__;
+ object__ = 0;
+ }
+ [super finalize];
+}
+
+@end
+
+@implementation ICEObject
+
+static NSString* ICEObject_ids__[1] =
+{
+ @"::Ice::Object"
+};
+
+static NSString* ICEObject_all__[4] =
+{
+ @"ice_id",
+ @"ice_ids",
+ @"ice_isA",
+ @"ice_ping"
+};
+
+-(id)initWithDelegate:(id)delegate
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+
+ object__ = 0;
+ delegate__ = [delegate retain];
+ return self;
+}
+
++(id)objectWithDelegate:(id)delegate
+{
+ return [[[ICEObject alloc] initWithDelegate:delegate] autorelease];
+}
+
++(BOOL) ice_isA___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os
+{
+ ICEEncodingVersion* encoding = [is startEncapsulation];
+ NSString* id__ = [is readString];
+ [is endEncapsulation];
+ [os startEncapsulation:encoding format:ICEDefaultFormat];
+ BOOL ret__ = [servant ice_isA:id__ current:current];
+ [os writeBool:ret__];
+ [os endEncapsulation];
+ return YES;
+}
+
++(BOOL) ice_ping___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os
+{
+ ICEEncodingVersion* encoding = [is startEncapsulation];
+ [is endEncapsulation];
+ [os startEncapsulation:encoding format:ICEDefaultFormat];
+ [servant ice_ping:current];
+ [os endEncapsulation];
+ return YES;
+}
+
++(BOOL) ice_id___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os
+{
+ ICEEncodingVersion* encoding = [is startEncapsulation];
+ [is endEncapsulation];
+ [os startEncapsulation:encoding format:ICEDefaultFormat];
+ NSString* ret__ = [servant ice_id:current];
+ [os writeString:ret__];
+ [os endEncapsulation];
+ return YES;
+}
+
++(BOOL) ice_ids___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os
+{
+ ICEEncodingVersion* encoding = [is startEncapsulation];
+ [is endEncapsulation];
+ [os startEncapsulation:encoding format:ICEDefaultFormat];
+ NSArray* ret__ = [servant ice_ids:current];
+ [os writeStringSeq:ret__];
+ [os endEncapsulation];
+ return YES;
+}
+
+-(BOOL) ice_isA:(NSString*)typeId
+{
+ return [self ice_isA:typeId current:nil];
+}
+
+-(BOOL) ice_isA:(NSString*)typeId current:(ICECurrent*)current
+{
+ int count, index;
+ NSString*const* staticIds = [[self class] staticIds__:&count idIndex:&index];
+ return ICEInternalLookupString(staticIds, count, typeId) >= 0;
+}
+
+-(void) ice_ping
+{
+ [self ice_ping:nil];
+}
+
+-(void) ice_ping:(ICECurrent*)current
+{
+ // Nothing to do.
+}
+
+-(NSString*) ice_id
+{
+ return [self ice_id:nil];
+}
+
+-(NSString*) ice_id:(ICECurrent*)current
+{
+ return [[self class] ice_staticId];
+}
+
+-(NSArray*) ice_ids
+{
+ return [self ice_ids:nil];
+}
+
+-(NSArray*) ice_ids:(ICECurrent*)current
+{
+ int count, index;
+ NSString*const* staticIds = [[self class] staticIds__:&count idIndex:&index];
+ return [NSArray arrayWithObjects:staticIds count:count];
+}
+
++(NSString*) ice_staticId
+{
+ int count, index;
+ NSString*const* staticIds = [self staticIds__:&count idIndex:&index];
+ return staticIds[index];
+}
+
+-(void) ice_preMarshal
+{
+}
+
+-(void) ice_postUnmarshal
+{
+}
+
++(NSString*const*) staticIds__:(int*)count idIndex:(int*)idx
+{
+ *count = sizeof(ICEObject_ids__) / sizeof(NSString*);
+ *idx = 0;
+ return ICEObject_ids__;
+}
+
+-(BOOL) ice_dispatch:(id<ICERequest>)request
+{
+ @try
+ {
+ ICERequest* requestI = (ICERequest*)request;
+ return [requestI callDispatch:self];
+ }
+ @catch(ICELocalException*)
+ {
+ @throw;
+ }
+ return FALSE;
+}
+
+-(BOOL) dispatch__:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os
+{
+ switch(ICEInternalLookupString(ICEObject_all__, sizeof(ICEObject_all__) / sizeof(NSString*), current.operation))
+ {
+ case 0:
+ return [ICEObject ice_id___:self current:current is:is os:os];
+ case 1:
+ return [ICEObject ice_ids___:self current:current is:is os:os];
+ case 2:
+ return [ICEObject ice_isA___:self current:current is:is os:os];
+ case 3:
+ return [ICEObject ice_ping___:self current:current is:is os:os];
+ default:
+ @throw [ICEOperationNotExistException requestFailedException:__FILE__
+ line:__LINE__
+ id_:current.id_
+ facet:current.facet
+ operation:current.operation];
+ }
+}
+
+-(void) write__:(id<ICEOutputStream>)os
+{
+ [os startObject:nil];
+ [self writeImpl__:os];
+ [os endObject];
+}
+
+-(void) read__:(id<ICEInputStream>)is
+{
+ [is startObject];
+ [self readImpl__:is];
+ [is endObject:NO];
+}
+
+-(void) writeImpl__:(id<ICEOutputStream>)os
+{
+ NSAssert(NO, @"writeImpl__ requires override");
+}
+
+-(void) readImpl__:(id<ICEInputStream>)is
+{
+ NSAssert(NO, @"readImpl__ requires override");
+}
+
+-(id) copyWithZone:(NSZone*)zone
+{
+ return [[[self class] allocWithZone:zone] init];
+}
+
+-(id)target__
+{
+ return (delegate__ == 0) ? self : delegate__;
+}
+@end
+
+@implementation ICEBlobject
+-(Ice::Object*) object__
+{
+ @synchronized([self class])
+ {
+ if(object__ == 0)
+ {
+ //
+ // NOTE: IceObjC::ObjectI implements it own reference counting and there's no need
+ // to call __incRef/__decRef here. The C++ object and Objective-C object are sharing
+ // the same reference count (the one of the Objective-C object). This is necessary
+ // to properly release both objects when there's either no more C++ handle/ObjC
+ // reference to the object (without this, servants added to the object adapter
+ // couldn't be retained or released easily).
+ //
+ object__ = (IceObjC::ObjectWrapper*)new IceObjC::BlobjectI(self);
+ }
+ }
+ return (IceObjC::ObjectWrapper*)object__;
+}
+@end
diff --git a/objc/src/Ice/ObjectAdapter.mm b/objc/src/Ice/ObjectAdapter.mm
new file mode 100644
index 00000000000..89282d4312d
--- /dev/null
+++ b/objc/src/Ice/ObjectAdapter.mm
@@ -0,0 +1,565 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ObjectAdapterI.h>
+#import <CommunicatorI.h>
+#import <ProxyI.h>
+#import <IdentityI.h>
+#import <ObjectI.h>
+#import <Util.h>
+
+#include <IceCpp/Locator.h>
+#include <IceCpp/ServantLocator.h>
+
+namespace
+{
+class DefaultServantLocator : public Ice::ServantLocator
+{
+public:
+
+ DefaultServantLocator(const Ice::ObjectPtr& s) :
+ _servant(s)
+ {
+ }
+
+ virtual Ice::ObjectPtr
+ locate(const Ice::Current&, Ice::LocalObjectPtr&)
+ {
+ return _servant;
+ }
+
+ virtual void
+ finished(const Ice::Current&, const Ice::ObjectPtr&, const Ice::LocalObjectPtr&)
+ {
+ }
+
+ virtual void
+ deactivate(const std::string&)
+ {
+ }
+
+ const Ice::ObjectPtr&
+ servant() const
+ {
+ return _servant;
+ }
+
+private:
+ Ice::ObjectPtr _servant;
+};
+}
+
+#define OBJECTADAPTER dynamic_cast<Ice::ObjectAdapter*>(static_cast<IceUtil::Shared*>(cxxObject_))
+
+@implementation ICEObjectAdapter
+-(Ice::ObjectAdapter*) adapter
+{
+ return OBJECTADAPTER;
+}
+//
+// @protocol ICEObjectAdapter methods.
+//
+
+-(id<ICECommunicator>) getCommunicator
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICECommunicator wrapperWithCxxObject:OBJECTADAPTER->getCommunicator().get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSString*) getName
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSString(OBJECTADAPTER->getName()) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(void) activate
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTADAPTER->activate();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) hold
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTADAPTER->hold();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) waitForHold
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTADAPTER->waitForHold();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) deactivate
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTADAPTER->deactivate();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) waitForDeactivate
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTADAPTER->waitForDeactivate();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(BOOL) isDeactivated
+{
+ NSException* nsex = nil;
+ try
+ {
+ return OBJECTADAPTER->isDeactivated();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return NO; // Keep the compiler happy.
+}
+
+-(void) destroy
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTADAPTER->destroy();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(id<ICEObjectPrx>) add:(ICEObject*)servant identity:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->add([servant object__], [ident identity])];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>) addFacet:(ICEObject*)servant identity:(ICEIdentity*)ident facet:(NSString*)facet
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->addFacet([servant object__], [ident identity],
+ fromNSString(facet))];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>) addWithUUID:(ICEObject*)servant
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->addWithUUID([servant object__])];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>) addFacetWithUUID:(ICEObject*)servant facet:(NSString*)facet
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->addFacetWithUUID([servant object__],
+ fromNSString(facet))];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(void) addDefaultServant:(ICEObject*)servant category:(NSString*)category
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ServantLocatorPtr servantLocator = new DefaultServantLocator([servant object__]);
+ OBJECTADAPTER->addServantLocator(servantLocator, fromNSString(category));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(ICEObject*) remove:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ObjectPtr wrapper = OBJECTADAPTER->remove([ident identity]);
+ return [[IceObjC::ObjectWrapperPtr::dynamicCast(wrapper)->getObject() retain] autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(ICEObject*) removeFacet:(ICEIdentity*)ident facet:(NSString*)facet
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ObjectPtr wrapper = OBJECTADAPTER->removeFacet([ident identity], fromNSString(facet));
+ return [[IceObjC::ObjectWrapperPtr::dynamicCast(wrapper)->getObject() retain] autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSDictionary*) removeAllFacets:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::FacetMap wrappers = OBJECTADAPTER->removeAllFacets([ident identity]);
+ NSMutableDictionary* servants = [[[NSMutableDictionary alloc] initWithCapacity:wrappers.size()] autorelease];
+ for(Ice::FacetMap::const_iterator p = wrappers.begin(); p != wrappers.end(); ++p)
+ {
+ NSObject<NSCopying>* key = toObjC(p->first);
+ [servants setObject:IceObjC::ObjectWrapperPtr::dynamicCast(p->second)->getObject() forKey:key];
+ [key release];
+ }
+ return servants;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEObject*) find:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ObjectPtr wrapper = OBJECTADAPTER->find([ident identity]);
+ return [[IceObjC::ObjectWrapperPtr::dynamicCast(wrapper)->getObject() retain] autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEObject*) findFacet:(ICEIdentity*)ident facet:(NSString*)facet
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ObjectPtr wrapper = OBJECTADAPTER->findFacet([ident identity], fromNSString(facet));
+ return [[IceObjC::ObjectWrapperPtr::dynamicCast(wrapper)->getObject() retain] autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSDictionary*) findAllFacets:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::FacetMap wrappers = OBJECTADAPTER->findAllFacets([ident identity]);
+ NSMutableDictionary* servants = [[[NSMutableDictionary alloc] initWithCapacity:wrappers.size()] autorelease];
+ for(Ice::FacetMap::const_iterator p = wrappers.begin(); p != wrappers.end(); ++p)
+ {
+ NSObject<NSCopying>* key = toObjC(p->first);
+ [servants setObject:IceObjC::ObjectWrapperPtr::dynamicCast(p->second)->getObject() forKey:key];
+ [key release];
+ }
+ return servants;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEObject*) findByProxy:(id<ICEObjectPrx>)proxy
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ObjectPtr wrapper = OBJECTADAPTER->findByProxy([(ICEObjectPrx*)proxy objectPrx__]);
+ return [[IceObjC::ObjectWrapperPtr::dynamicCast(wrapper)->getObject() retain] autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEObject*) findDefaultServant:(NSString*)category
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ServantLocatorPtr servantLocator = OBJECTADAPTER->findServantLocator(fromNSString(category));
+ if(servantLocator == 0)
+ {
+ return nil;
+ }
+ DefaultServantLocator* defaultServantLocator = dynamic_cast<DefaultServantLocator*>(servantLocator.get());
+ if(defaultServantLocator == 0)
+ {
+ return nil; // should never happen!
+ }
+ else
+ {
+ Ice::ObjectPtr wrapper = defaultServantLocator->servant();
+ return [[IceObjC::ObjectWrapperPtr::dynamicCast(wrapper)->getObject() retain] autorelease];
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>) createProxy:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->createProxy([ident identity])];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>) createDirectProxy:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->createDirectProxy([ident identity])];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>) createIndirectProxy:(ICEIdentity*)ident
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->createIndirectProxy([ident identity])];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(void) setLocator:(id<ICELocatorPrx>)loc
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTADAPTER->setLocator(Ice::LocatorPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)loc objectPrx__])));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) refreshPublishedEndpoints
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTADAPTER->refreshPublishedEndpoints();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(ICEEndpointSeq*) getEndpoints
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSArray(OBJECTADAPTER->getEndpoints()) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil;
+}
+
+-(ICEEndpointSeq*) getPublishedEndpoints
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSArray(OBJECTADAPTER->getPublishedEndpoints()) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil;
+}
+
+@end
diff --git a/objc/src/Ice/ObjectAdapterI.h b/objc/src/Ice/ObjectAdapterI.h
new file mode 100644
index 00000000000..1711cfd6958
--- /dev/null
+++ b/objc/src/Ice/ObjectAdapterI.h
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/ObjectAdapter.h>
+
+#import <Wrapper.h>
+
+#include <IceCpp/ObjectAdapter.h>
+
+@class ICECommunicator;
+
+@interface ICEObjectAdapter : ICEInternalWrapper<ICEObjectAdapter>
+-(Ice::ObjectAdapter*) adapter;
+@end
+
diff --git a/objc/src/Ice/ObjectI.h b/objc/src/Ice/ObjectI.h
new file mode 100644
index 00000000000..e882c5eb8e5
--- /dev/null
+++ b/objc/src/Ice/ObjectI.h
@@ -0,0 +1,37 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Object.h>
+
+#include <IceCpp/Object.h>
+
+//
+// Forward declarations.
+//
+@class ICECurrent;
+@class ICEInputStream;
+@class ICEOutputStream;
+
+namespace IceObjC
+{
+
+class ObjectWrapper : virtual public Ice::Object
+{
+public:
+
+ virtual ~ObjectWrapper() { }
+ virtual ICEObject* getObject() = 0;
+};
+typedef IceUtil::Handle<ObjectWrapper> ObjectWrapperPtr;
+
+};
+
+@interface ICEObject (ICEInternal)
+-(Ice::Object*) object__;
+@end
diff --git a/objc/src/Ice/Properties.mm b/objc/src/Ice/Properties.mm
new file mode 100644
index 00000000000..7713ea9e6bc
--- /dev/null
+++ b/objc/src/Ice/Properties.mm
@@ -0,0 +1,304 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <PropertiesI.h>
+#import <Util.h>
+
+@implementation ICEProperties
+-(id) initWithCxxObject:(IceUtil::Shared*)cxxObject
+{
+ self = [super initWithCxxObject:cxxObject];
+ if(!self)
+ {
+ return nil;
+ }
+ properties_ = dynamic_cast<Ice::Properties*>(cxxObject);
+ return self;
+}
+-(Ice::Properties*) properties
+{
+ return (Ice::Properties*)properties_;
+}
+
+// @protocol ICEProperties methods.
+
+-(NSString*) getProperty:(NSString*)key
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSString(properties_->getProperty(fromNSString(key))) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(NSString*) getPropertyWithDefault:(NSString*)key value:(NSString*)value
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSString(properties_->getPropertyWithDefault(fromNSString(key), fromNSString(value))) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(int) getPropertyAsInt:(NSString*)key
+{
+ NSException* nsex = nil;
+ try
+ {
+ return properties_->getPropertyAsInt(fromNSString(key));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0; // Keep the compiler happy.
+}
+-(int) getPropertyAsIntWithDefault:(NSString*)key value:(int)value
+{
+ NSException* nsex = nil;
+ try
+ {
+ return properties_->getPropertyAsIntWithDefault(fromNSString(key), value);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0; // Keep the compiler happy.
+}
+-(NSArray*) getPropertyAsList:(NSString*)key
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSArray(properties_->getPropertyAsList(fromNSString(key))) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(NSArray*) getPropertyAsListWithDefault:(NSString*)key value:(NSArray*)value
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::vector<std::string> s;
+ fromNSArray(value, s);
+ return [toNSArray(properties_->getPropertyAsListWithDefault(fromNSString(key), s)) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(NSDictionary*) getPropertiesForPrefix:(NSString*)prefix
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSDictionary(properties_->getPropertiesForPrefix(fromNSString(prefix))) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(void) setProperty:(NSString*)key value:(NSString*)value
+{
+ NSException* nsex = nil;
+ try
+ {
+ properties_->setProperty(fromNSString(key), fromNSString(value));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+-(NSArray*) getCommandLineOptions
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [toNSArray(properties_->getCommandLineOptions()) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(NSArray*) parseCommandLineOptions:(NSString*)prefix options:(NSArray*)options
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::vector<std::string> o;
+ fromNSArray(options, o);
+ return [toNSArray(properties_->parseCommandLineOptions(fromNSString(prefix), o)) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(NSArray*) parseIceCommandLineOptions:(NSArray*)options
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::vector<std::string> o;
+ fromNSArray(options, o);
+ return [toNSArray(properties_->parseIceCommandLineOptions(o)) autorelease];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(void) load:(NSString*)file
+{
+ NSException* nsex = nil;
+ try
+ {
+ properties_->load(fromNSString(file));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+-(id<ICEProperties>) clone
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEProperties wrapperWithCxxObject:properties_->clone().get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+@end
+
+namespace
+{
+
+class UpdateCallbackI : public Ice::PropertiesAdminUpdateCallback
+{
+public:
+
+ UpdateCallbackI(id<ICEPropertiesAdminUpdateCallback> callback) :
+ _callback(callback)
+ {
+ [(ICEPropertiesAdminUpdateCallback*)callback setPropertiesAdminUpdateCallback:this];
+ }
+
+ void
+ updated(const Ice::PropertyDict& properties)
+ {
+ [_callback updated:[toNSDictionary(properties) autorelease]];
+ }
+
+private:
+
+ id<ICEPropertiesAdminUpdateCallback> _callback;
+};
+
+}
+
+#define PROPERTIESADMINUPDATECALLBACK \
+ dynamic_cast<Ice::PropertiesAdminUpdateCallback*>(static_cast<IceUtil::Shared*>(cxxObject_))
+
+@implementation ICEPropertiesAdminUpdateCallback
+-(void) dealloc
+{
+ if(PROPERTIESADMINUPDATECALLBACK)
+ {
+ PROPERTIESADMINUPDATECALLBACK->__decRef();
+ }
+ [super dealloc];
+}
+
+-(void) setPropertiesAdminUpdateCallback:(Ice::PropertiesAdminUpdateCallback*)cxxObject
+{
+ assert(!PROPERTIESADMINUPDATECALLBACK);
+ cxxObject_ = static_cast<IceUtil::Shared*>(cxxObject);
+ PROPERTIESADMINUPDATECALLBACK->__incRef();
+}
+
+-(Ice::PropertiesAdminUpdateCallback*) propertiesAdminUpdateCallback
+{
+ return PROPERTIESADMINUPDATECALLBACK;
+}
+@end
+
+#define NATIVEPROPERTIESADMIN dynamic_cast<Ice::NativePropertiesAdmin*>(static_cast<IceUtil::Shared*>(cxxObject_))
+
+@implementation ICENativePropertiesAdmin
+-(void) addUpdateCallback:(id<ICEPropertiesAdminUpdateCallback>)callback
+{
+ NSAssert([callback isKindOfClass:[ICEPropertiesAdminUpdateCallback class]],
+ @"callback not extends ICEPropertiesAdminUpdateCallback class");
+ if([(ICEPropertiesAdminUpdateCallback*)callback propertiesAdminUpdateCallback])
+ {
+ NATIVEPROPERTIESADMIN->addUpdateCallback(
+ [(ICEPropertiesAdminUpdateCallback*)callback propertiesAdminUpdateCallback]);
+ }
+ else
+ {
+ NATIVEPROPERTIESADMIN->addUpdateCallback(new UpdateCallbackI(callback));
+ }
+}
+
+-(void) removeUpdateCallback:(id<ICEPropertiesAdminUpdateCallback>)callback
+{
+ NSAssert([callback isKindOfClass:[ICEPropertiesAdminUpdateCallback class]],
+ @"callback not extends ICEPropertiesAdminUpdateCallback class");
+
+ NATIVEPROPERTIESADMIN->removeUpdateCallback(
+ [(ICEPropertiesAdminUpdateCallback*)callback propertiesAdminUpdateCallback]);
+}
+@end
diff --git a/objc/src/Ice/PropertiesI.h b/objc/src/Ice/PropertiesI.h
new file mode 100644
index 00000000000..18e71076804
--- /dev/null
+++ b/objc/src/Ice/PropertiesI.h
@@ -0,0 +1,30 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Properties.h>
+
+#import <Wrapper.h>
+
+#include <IceCpp/Properties.h>
+#include <IceCpp/NativePropertiesAdmin.h>
+
+@interface ICEProperties : ICEInternalWrapper<ICEProperties>
+{
+ Ice::Properties* properties_;
+}
+-(Ice::Properties*)properties;
+@end
+
+@interface ICEPropertiesAdminUpdateCallback ()
+-(void) setPropertiesAdminUpdateCallback:(Ice::PropertiesAdminUpdateCallback*)callback;
+-(Ice::PropertiesAdminUpdateCallback*) propertiesAdminUpdateCallback;
+@end
+
+@interface ICENativePropertiesAdmin : ICEInternalWrapper<ICENativePropertiesAdmin>
+@end
diff --git a/objc/src/Ice/Proxy.mm b/objc/src/Ice/Proxy.mm
new file mode 100644
index 00000000000..d0754cbedf8
--- /dev/null
+++ b/objc/src/Ice/Proxy.mm
@@ -0,0 +1,1721 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ProxyI.h>
+#import <Util.h>
+#import <StreamI.h>
+#import <VersionI.h>
+#import <CommunicatorI.h>
+#import <IdentityI.h>
+#import <ConnectionI.h>
+
+#import <objc/Ice/Object.h>
+#import <objc/Ice/LocalException.h>
+#import <objc/Ice/Router.h>
+#import <objc/Ice/Locator.h>
+
+#include <IceCpp/Initialize.h>
+#include <IceCpp/Proxy.h>
+#include <IceCpp/LocalException.h>
+#include <IceCpp/Router.h>
+#include <IceCpp/Locator.h>
+
+#import <objc/runtime.h>
+#import <objc/message.h>
+
+#import <Foundation/NSThread.h>
+#import <Foundation/NSInvocation.h>
+#import <Foundation/NSAutoreleasePool.h>
+
+#include <Block.h>
+
+#define OBJECTPRX ((IceProxy::Ice::Object*)objectPrx__)
+#define ASYNCRESULT ((Ice::AsyncResult*)asyncResult__)
+
+namespace
+{
+
+class BeginInvokeAsyncCallback : public IceUtil::Shared
+{
+public:
+
+BeginInvokeAsyncCallback(void (^completed)(id<ICEInputStream>, BOOL),
+ void (^exception)(ICEException*),
+ void (^sent)(BOOL),
+ BOOL returnsData) :
+ _completed(Block_copy(completed)),
+ _exception(Block_copy(exception)),
+ _sent(Block_copy(sent)),
+ _returnsData(returnsData)
+{
+}
+
+virtual ~BeginInvokeAsyncCallback()
+{
+ Block_release(_completed);
+ Block_release(_exception);
+ Block_release(_sent);
+}
+
+void completed(const Ice::AsyncResultPtr& result)
+{
+ BOOL ok = YES; // Keep the compiler happy.
+ id<ICEInputStream> is = nil;
+ NSException* nsex = nil;
+ Ice::ObjectPrx proxy = result->getProxy();
+ try
+ {
+ std::vector<Ice::Byte> outParams;
+ ok = proxy->end_ice_invoke(outParams, result);
+ if(_returnsData)
+ {
+ Ice::InputStreamPtr s = Ice::createInputStream(proxy->ice_getCommunicator(), outParams);
+ is = [ICEInputStream wrapperWithCxxObjectNoAutoRelease:s.get()];
+ }
+ else if(!outParams.empty())
+ {
+ if(ok)
+ {
+ if(outParams.size() != 6)
+ {
+ throw Ice::EncapsulationException(__FILE__, __LINE__);
+ }
+ }
+ else
+ {
+ Ice::InputStreamPtr s = Ice::createInputStream(proxy->ice_getCommunicator(), outParams);
+ try
+ {
+ s->startEncapsulation();
+ s->throwException();
+ }
+ catch(const Ice::UserException& ex)
+ {
+ s->endEncapsulation();
+ throw Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_name());
+ }
+ }
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ if(is != nil)
+ {
+ [is release];
+ is = nil;
+ }
+ nsex = toObjCException(ex);
+ }
+
+ NSException* exception = nil;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ @try
+ {
+ if(nsex != nil)
+ {
+ @try
+ {
+ @throw nsex;
+ }
+ @catch(ICEException* ex)
+ {
+ if(_exception)
+ {
+ _exception(ex);
+ }
+ return;
+ }
+ }
+
+ _completed(is, ok);
+ }
+ @catch(id e)
+ {
+ exception = [e retain];
+ }
+ @finally
+ {
+ [is release];
+ [pool drain];
+ }
+
+ if(exception != nil)
+ {
+ rethrowCxxException(exception, true); // True = release the exception.
+ }
+}
+
+void sent(const Ice::AsyncResultPtr& result)
+{
+ if(!_sent)
+ {
+ return;
+ }
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSException* exception = nil;
+ @try
+ {
+ _sent(result->sentSynchronously());
+ }
+ @catch(id e)
+ {
+ exception = [e retain];
+ }
+ @finally
+ {
+ [pool drain];
+ }
+
+ if(exception != nil)
+ {
+ rethrowCxxException(exception, true); // True = release the exception.
+ }
+}
+
+private:
+
+void (^_completed)(id<ICEInputStream>, BOOL);
+void (^_exception)(ICEException*);
+void (^_sent)(BOOL);
+BOOL _returnsData;
+
+};
+
+};
+
+@implementation ICEAsyncResult
+-(ICEAsyncResult*) initWithAsyncResult__:(const Ice::AsyncResultPtr&)arg
+ operation:(NSString*)op
+ proxy:(id<ICEObjectPrx>)p;
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+
+ asyncResult__ = arg.get();
+ ASYNCRESULT->__incRef();
+ operation_ = [op retain];
+ proxy_ = [p retain];
+ return self;
+}
+
+-(Ice::AsyncResult*) asyncResult__
+{
+ return ASYNCRESULT;
+}
+
+-(void) dealloc
+{
+ ASYNCRESULT->__decRef();
+ asyncResult__ = 0;
+ [operation_ release];
+ [proxy_ release];
+ [super dealloc];
+}
+
+-(void) finalize
+{
+ ASYNCRESULT->__decRef();
+ asyncResult__ = 0;
+ [super finalize];
+}
+
++(ICEAsyncResult*) asyncResultWithAsyncResult__:(const Ice::AsyncResultPtr&)arg
+{
+ return [self asyncResultWithAsyncResult__:arg operation:nil proxy:nil];
+}
++(ICEAsyncResult*) asyncResultWithAsyncResult__:(const Ice::AsyncResultPtr&)arg
+ operation:(NSString*)op
+ proxy:(id<ICEObjectPrx>)p
+{
+ if(!arg)
+ {
+ return nil;
+ }
+ else
+ {
+ return [[[self alloc] initWithAsyncResult__:arg operation:op proxy:p] autorelease];
+ }
+}
+-(NSString*) operation
+{
+ return operation_;
+}
+
+-(id<ICECommunicator>) getCommunicator
+{
+ return [ICECommunicator wrapperWithCxxObject:ASYNCRESULT->getCommunicator().get()];
+}
+
+-(id<ICEConnection>) getConnection
+{
+ return [ICEConnection wrapperWithCxxObject:ASYNCRESULT->getConnection().get()];
+}
+
+-(id<ICEObjectPrx>) getProxy
+{
+ return [[proxy_ retain] autorelease];
+}
+
+-(BOOL) isCompleted
+{
+ return ASYNCRESULT->isCompleted();
+}
+
+-(void) waitForCompleted
+{
+ ASYNCRESULT->waitForCompleted();
+}
+
+-(BOOL) isSent
+{
+ return ASYNCRESULT->isSent();
+}
+
+-(void) waitForSent
+{
+ ASYNCRESULT->waitForSent();
+}
+
+-(BOOL) sentSynchronously
+{
+ return ASYNCRESULT->sentSynchronously();
+}
+
+-(void) throwLocalException
+{
+ NSException* nsex;
+ try
+ {
+ ASYNCRESULT->throwLocalException();
+ return;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+-(NSString*) getOperation
+{
+ if(operation_ != nil)
+ {
+ return [[operation_ retain] autorelease];
+ }
+ else
+ {
+ return [toNSString(ASYNCRESULT->getOperation()) autorelease];
+ }
+}
+@end
+
+@implementation ICEObjectPrx
+
+-(ICEObjectPrx*) initWithObjectPrx__:(const Ice::ObjectPrx&)arg
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ communicator__ = [ICECommunicator wrapperWithCxxObjectNoAutoRelease:arg->ice_getCommunicator().get()];
+ objectPrx__ = arg.get();
+ OBJECTPRX->__incRef();
+ return self;
+}
+
+-(IceProxy::Ice::Object*) objectPrx__
+{
+ return (IceProxy::Ice::Object*)objectPrx__;
+}
+
+-(void) dealloc
+{
+ OBJECTPRX->__decRef();
+ objectPrx__ = 0;
+ [communicator__ release];
+ [super dealloc];
+}
+
+-(void) finalize
+{
+ OBJECTPRX->__decRef();
+ objectPrx__ = 0;
+ [super finalize];
+}
+
++(ICEObjectPrx*) objectPrxWithObjectPrx__:(const Ice::ObjectPrx&)arg
+{
+ if(!arg)
+ {
+ return nil;
+ }
+ else
+ {
+ return [[[self alloc] initWithObjectPrx__:arg] autorelease];
+ }
+}
+
++(id) uncheckedCast:(id<ICEObjectPrx>)proxy
+{
+ if(proxy != nil)
+ {
+ if([(ICEObjectPrx*)proxy isKindOfClass:self])
+ {
+ return [[proxy retain] autorelease];
+ }
+ else
+ {
+ return [[[self alloc] initWithObjectPrx__:[(ICEObjectPrx*)proxy objectPrx__]] autorelease];
+ }
+ }
+ return nil;
+}
++(id) uncheckedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet
+{
+ return [self uncheckedCast:[proxy ice_facet:facet]];
+}
++(id) checkedCast:(id<ICEObjectPrx>)proxy
+{
+ if(proxy != nil)
+ {
+ if([(ICEObjectPrx*)proxy isKindOfClass:self])
+ {
+ return [[proxy retain] autorelease];
+ }
+ else if([(ICEObjectPrx*)proxy conformsToProtocol:[self protocol__]] ||
+ [proxy ice_isA:[self ice_staticId]])
+ {
+ return [[[self alloc] initWithObjectPrx__:[(ICEObjectPrx*)proxy objectPrx__]] autorelease];
+ }
+ }
+ return nil;
+}
++(id) checkedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet
+{
+ @try
+ {
+ return [self checkedCast:[proxy ice_facet:facet]];
+ }
+ @catch(ICEFacetNotExistException* ex)
+ {
+ return nil;
+ }
+}
++(id) checkedCast:(id<ICEObjectPrx>)proxy context:(ICEContext*)context
+{
+ if(proxy != nil)
+ {
+ if([(ICEObjectPrx*)proxy isKindOfClass:self])
+ {
+ return [[proxy retain] autorelease];
+ }
+ else if([(ICEObjectPrx*)proxy conformsToProtocol:[self protocol__]] ||
+ [proxy ice_isA:[self ice_staticId] context:context])
+ {
+ return [[[self alloc] initWithObjectPrx__:[(ICEObjectPrx*)proxy objectPrx__]] autorelease];
+ }
+ }
+ return nil;
+}
++(id) checkedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet context:(ICEContext*)context
+{
+ @try
+ {
+ return [self checkedCast:[proxy ice_facet:facet] context:context];
+ }
+ @catch(ICEFacetNotExistException* ex)
+ {
+ return nil;
+ }
+}
++(NSString*) ice_staticId
+{
+ return @"::Ice::Object";
+}
+
++(Protocol*) protocol__
+{
+ return objc_getProtocol(class_getName([self class]));
+}
+
+-(id<ICEOutputStream>) createOutputStream__
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::OutputStreamPtr os = Ice::createOutputStream(OBJECTPRX->ice_getCommunicator());
+ return [ICEOutputStream wrapperWithCxxObjectNoAutoRelease:os.get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(void) checkAsyncTwowayOnly__:(NSString*)operation
+{
+ //
+ // No mutex lock necessary, there is nothing mutable in this
+ // operation.
+ //
+
+ if(![self ice_isTwoway])
+ {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"`%@' can only be called with a twoway proxy", operation]
+ userInfo:nil];
+ }
+}
+
+-(void) invoke__:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ format:(ICEFormatType)format
+ marshal:(ICEMarshalCB)marshal
+ unmarshal:(ICEUnmarshalCB)unmarshal
+ context:(ICEContext*)context
+{
+ if(unmarshal && !OBJECTPRX->ice_isTwoway())
+ {
+ @throw [ICETwowayOnlyException twowayOnlyException:__FILE__ line:__LINE__ operation:operation];
+ }
+
+ ICEOutputStream<ICEOutputStream>* os = nil;
+ if(marshal)
+ {
+ os = [self createOutputStream__];
+ try
+ {
+ [os os]->startEncapsulation(IceInternal::getCompatibleEncoding(OBJECTPRX->ice_getEncodingVersion()),
+ (Ice::FormatType)format);
+ }
+ catch(const std::exception& ex)
+ {
+ [os release];
+ @throw toObjCException(ex);
+ }
+
+ @try
+ {
+ marshal(os);
+ }
+ @catch(id ex)
+ {
+ [os release];
+ @throw ex;
+ }
+ }
+
+ BOOL ok = YES; // Keep the compiler happy.
+ ICEInputStream<ICEInputStream>* is = nil;
+ NSException* nsex = nil;
+ try
+ {
+ std::vector<Ice::Byte> inParams;
+ if(os)
+ {
+ [os os]->endEncapsulation();
+ [os os]->finished(inParams);
+ [os release];
+ os = nil;
+ }
+
+ std::vector<Ice::Byte> outParams;
+ if(context != nil)
+ {
+ Ice::Context ctx;
+ fromNSDictionary(context, ctx);
+ ok = OBJECTPRX->ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, outParams, ctx);
+ }
+ else
+ {
+ ok = OBJECTPRX->ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, outParams);
+ }
+
+ if(unmarshal)
+ {
+ Ice::InputStreamPtr s = Ice::createInputStream(OBJECTPRX->ice_getCommunicator(), outParams);
+ is = [ICEInputStream wrapperWithCxxObjectNoAutoRelease:s.get()];
+ }
+ else if(!outParams.empty())
+ {
+ if(ok)
+ {
+ if(outParams.size() != 6)
+ {
+ throw Ice::EncapsulationException(__FILE__, __LINE__);
+ }
+ }
+ else
+ {
+ Ice::InputStreamPtr s = Ice::createInputStream(OBJECTPRX->ice_getCommunicator(), outParams);
+ try
+ {
+ s->startEncapsulation();
+ s->throwException();
+ }
+ catch(const Ice::UserException& ex)
+ {
+ s->endEncapsulation();
+ throw Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_name());
+ }
+ }
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ if(os != nil)
+ {
+ [os release];
+ os = nil;
+ }
+ if(is != nil)
+ {
+ [is release];
+ is = nil;
+ }
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+
+ NSAssert(os == nil, @"output stream not cleared");
+ if(is)
+ {
+ @try
+ {
+ unmarshal(is, ok);
+ }
+ @finally
+ {
+ [is release];
+ }
+ }
+}
+
+-(id<ICEAsyncResult>) begin_invoke__:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ format:(ICEFormatType)format
+ marshal:(void(^)(id<ICEOutputStream>))marshal
+ returnsData:(BOOL)returnsData
+ context:(ICEContext*)context
+{
+ if(returnsData)
+ {
+ [self checkAsyncTwowayOnly__:operation];
+ }
+
+ ICEOutputStream<ICEOutputStream>* os = nil;
+ if(marshal)
+ {
+ os = [self createOutputStream__];
+ try
+ {
+ [os os]->startEncapsulation(IceInternal::getCompatibleEncoding(OBJECTPRX->ice_getEncodingVersion()),
+ (Ice::FormatType)format);
+ }
+ catch(const std::exception& ex)
+ {
+ [os release];
+ @throw toObjCException(ex);
+ }
+
+ @try
+ {
+ marshal(os);
+ }
+ @catch(id ex)
+ {
+ [os release];
+ @throw ex;
+ }
+ }
+
+ NSException* nsex = nil;
+ try
+ {
+ std::vector<Ice::Byte> inParams;
+ if(os)
+ {
+ [os os]->endEncapsulation();
+ [os os]->finished(inParams);
+ [os release];
+ os = nil;
+ }
+
+ Ice::AsyncResultPtr r;
+ if(context != nil)
+ {
+ Ice::Context ctx;
+ fromNSDictionary(context, ctx);
+ r = OBJECTPRX->begin_ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, ctx);
+ }
+ else
+ {
+ r = OBJECTPRX->begin_ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams);
+ }
+ return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:operation proxy:self];
+ }
+ catch(const std::exception& ex)
+ {
+ if(os != nil)
+ {
+ [os release];
+ os = nil;
+ }
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil; // Keep the compiler happy.
+}
+
+-(id<ICEAsyncResult>) begin_invoke__:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ format:(ICEFormatType)format
+ marshal:(void(^)(id<ICEOutputStream>))marshal
+ returnsData:(BOOL)returnsData
+ completed:(void(^)(id<ICEInputStream>, BOOL))completed
+ response:(BOOL)response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+ context:(ICEContext*)context
+{
+ if(returnsData)
+ {
+ [self checkAsyncTwowayOnly__:operation];
+ if(!response)
+ {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"Response callback is nil"
+ userInfo:nil];
+ }
+ }
+
+ if(!exception)
+ {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"Exception callback is nil"
+ userInfo:nil];
+ }
+
+ ICEOutputStream<ICEOutputStream>* os = nil;
+ if(marshal)
+ {
+ os = [self createOutputStream__];
+ try
+ {
+ [os os]->startEncapsulation(IceInternal::getCompatibleEncoding(OBJECTPRX->ice_getEncodingVersion()),
+ (Ice::FormatType)format);
+ }
+ catch(const std::exception& ex)
+ {
+ [os release];
+ @throw toObjCException(ex);
+ }
+
+ @try
+ {
+ marshal(os);
+ }
+ @catch(id ex)
+ {
+ [os release];
+ @throw ex;
+ }
+ }
+
+ NSException* nsex = nil;
+ try
+ {
+ std::vector<Ice::Byte> inParams;
+ if(os)
+ {
+ [os os]->endEncapsulation();
+ [os os]->finished(inParams);
+ [os release];
+ os = nil;
+ }
+
+ Ice::CallbackPtr cb = Ice::newCallback(new BeginInvokeAsyncCallback(completed, exception, sent, returnsData),
+ &BeginInvokeAsyncCallback::completed,
+ &BeginInvokeAsyncCallback::sent);
+ Ice::AsyncResultPtr r;
+ if(context != nil)
+ {
+ Ice::Context ctx;
+ fromNSDictionary(context, ctx);
+ r = OBJECTPRX->begin_ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, ctx, cb);
+ }
+ else
+ {
+ r = OBJECTPRX->begin_ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, cb);
+ }
+ return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:operation proxy:self];
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ if(os != nil)
+ {
+ [os release];
+ os = nil;
+ }
+ nsex = [NSException exceptionWithName:NSInvalidArgumentException reason:[toNSString(ex.reason()) autorelease]
+ userInfo:nil];
+ }
+ catch(const std::exception& ex)
+ {
+ if(os != nil)
+ {
+ [os release];
+ os = nil;
+ }
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil; // Keep the compiler happy.
+}
+-(id<ICEAsyncResult>) begin_invoke__:(NSString*)op
+ mode:(ICEOperationMode)mode
+ format:(ICEFormatType)format
+ marshal:(void(^)(id<ICEOutputStream>))marshal
+ response:(void(^)())response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+ context:(ICEContext*)ctx
+{
+ void(^completed)(id<ICEInputStream>, BOOL) = ^(id<ICEInputStream>, BOOL) {
+ if(response)
+ {
+ response();
+ }
+ };
+ return [self begin_invoke__:op
+ mode:mode
+ format:format
+ marshal:marshal
+ returnsData:NO
+ completed:completed
+ response:TRUE
+ exception:exception
+ sent:sent
+ context:ctx];
+}
+
+-(id<ICEAsyncResult>) begin_invoke__:(NSString*)op
+ mode:(ICEOperationMode)mode
+ format:(ICEFormatType)format
+ marshal:(void(^)(id<ICEOutputStream>))marshal
+ completed:(void(^)(id<ICEInputStream>, BOOL))completed
+ response:(BOOL)response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+ context:(ICEContext*)ctx
+{
+ return [self begin_invoke__:op
+ mode:mode
+ format:format
+ marshal:marshal
+ returnsData:TRUE
+ completed:completed
+ response:response
+ exception:exception
+ sent:sent context:ctx];
+}
+
+-(void)end_invoke__:(NSString*)operation unmarshal:(ICEUnmarshalCB)unmarshal result:(id<ICEAsyncResult>)r
+{
+ ICEAsyncResult* result = (ICEAsyncResult*)r;
+ if(operation != [result operation])
+ {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Incorrect operation for end_%@ method: %@",
+ operation, [result operation]]
+ userInfo:nil];
+ }
+ if(result == nil)
+ {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"ICEAsyncResult is nil"
+ userInfo:nil];
+ }
+
+ BOOL ok = YES; // Keep the compiler happy.
+ NSException* nsex = nil;
+ ICEInputStream* is = nil;
+ try
+ {
+ std::vector<Ice::Byte> outParams;
+ ok = OBJECTPRX->end_ice_invoke(outParams, [result asyncResult__]);
+
+ if(unmarshal)
+ {
+ Ice::InputStreamPtr s = Ice::createInputStream(OBJECTPRX->ice_getCommunicator(), outParams);
+ is = [ICEInputStream wrapperWithCxxObjectNoAutoRelease:s.get()];
+ }
+ else if(!outParams.empty())
+ {
+ if(ok)
+ {
+ if(outParams.size() != 6)
+ {
+ throw Ice::EncapsulationException(__FILE__, __LINE__);
+ }
+ }
+ else
+ {
+ Ice::InputStreamPtr s = Ice::createInputStream(OBJECTPRX->ice_getCommunicator(), outParams);
+ try
+ {
+ s->startEncapsulation();
+ s->throwException();
+ }
+ catch(const Ice::UserException& ex)
+ {
+ s->endEncapsulation();
+ throw Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_name());
+ }
+ }
+ }
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ if(is != nil)
+ {
+ [is release];
+ is = nil;
+ }
+ nsex = [NSException exceptionWithName:NSInvalidArgumentException reason:[toNSString(ex.reason()) autorelease]
+ userInfo:nil];
+ }
+ catch(const std::exception& ex)
+ {
+ if(is != nil)
+ {
+ [is release];
+ is = nil;
+ }
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+
+ if(is != nil)
+ {
+ @try
+ {
+ unmarshal(is, ok);
+ }
+ @finally
+ {
+ [is release];
+ }
+ }
+}
+
+-(id) copyWithZone:(NSZone *)zone
+{
+ return [self retain];
+}
+
+-(NSUInteger) hash
+{
+ return (NSUInteger)OBJECTPRX->__hash();
+}
+-(NSString*) description
+{
+ return [toNSString(OBJECTPRX->ice_toString()) autorelease];
+}
+-(BOOL) isEqual:(id)o_
+{
+ if(self == o_)
+ {
+ return YES;
+ }
+ if(!o_ || ![o_ isKindOfClass:[ICEObjectPrx class]])
+ {
+ return NO;
+ }
+ return *OBJECTPRX == *[o_ objectPrx__];
+}
+
+-(NSComparisonResult) compareIdentity:(id<ICEObjectPrx>)aProxy
+{
+ IceProxy::Ice::Object* lhs = OBJECTPRX;
+ IceProxy::Ice::Object* rhs = [(ICEObjectPrx*)aProxy objectPrx__];
+ if(Ice::proxyIdentityEqual(lhs, rhs))
+ {
+ return NSOrderedSame;
+ }
+ else if(Ice::proxyIdentityLess(lhs, rhs))
+ {
+ return NSOrderedAscending;
+ }
+ else
+ {
+ return NSOrderedDescending;
+ }
+}
+
+-(NSComparisonResult) compareIdentityAndFacet:(id<ICEObjectPrx>)aProxy
+{
+ IceProxy::Ice::Object* lhs = OBJECTPRX;
+ IceProxy::Ice::Object* rhs = [(ICEObjectPrx*)aProxy objectPrx__];
+ if(Ice::proxyIdentityAndFacetEqual(lhs, rhs))
+ {
+ return NSOrderedSame;
+ }
+ else if(Ice::proxyIdentityAndFacetLess(lhs, rhs))
+ {
+ return NSOrderedAscending;
+ }
+ else
+ {
+ return NSOrderedDescending;
+ }
+}
+
+-(id<ICECommunicator>) ice_getCommunicator
+{
+ return [[communicator__ retain] autorelease];
+}
+
+-(NSString*) ice_toString
+{
+ return [toNSString(OBJECTPRX->ice_toString()) autorelease];
+}
+
+-(BOOL) ice_isA:(NSString*)typeId
+{
+ __block BOOL ret__;
+ cppCall(^ { ret__ = OBJECTPRX->ice_isA(fromNSString(typeId)); });
+ return ret__;
+}
+-(BOOL) ice_isA:(NSString*)typeId context:(ICEContext*)context
+{
+ __block BOOL ret__;
+ cppCall(^(const Ice::Context& ctx) { ret__ = OBJECTPRX->ice_isA(fromNSString(typeId), ctx); }, context);
+ return ret__;
+}
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result)
+ {
+ result = OBJECTPRX->begin_ice_isA(fromNSString(typeId));
+ }, self);
+}
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId context:(ICEContext*)context
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx)
+ {
+ result = OBJECTPRX->begin_ice_isA(fromNSString(typeId), ctx);
+ }, context, self);
+}
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId
+ response:(void(^)(BOOL))response
+ exception:(void(^)(ICEException*))exception
+{
+ return [self begin_ice_isA:typeId response:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId
+ context:(ICEContext*)context
+ response:(void(^)(BOOL))response
+ exception:(void(^)(ICEException*))exception
+
+{
+ return [self begin_ice_isA:typeId context:context response:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId
+ response:(void(^)(BOOL))response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_isA(fromNSString(typeId), cb);
+ },
+ ^(const Ice::AsyncResultPtr& result) {
+ BOOL ret__ = OBJECTPRX->end_ice_isA(result);
+ if(response)
+ {
+ response(ret__);
+ }
+ },
+ exception, sent, self);
+
+}
+-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId
+ context:(ICEContext*)context
+ response:(void(^)(BOOL))response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_isA(fromNSString(typeId), ctx, cb);
+ },
+ context,
+ ^(const Ice::AsyncResultPtr& result) {
+ BOOL ret__ = OBJECTPRX->end_ice_isA(result);
+ if(response)
+ {
+ response(ret__);
+ }
+ },
+ exception, sent, self);
+}
+-(BOOL) end_ice_isA:(id<ICEAsyncResult>)result
+{
+ __block BOOL ret__;
+ endCppCall(^(const Ice::AsyncResultPtr& r) { ret__ = OBJECTPRX->end_ice_isA(r); }, result);
+ return ret__;
+}
+
+-(void) ice_ping
+{
+ cppCall(^ { OBJECTPRX->ice_ping(); });
+}
+-(void) ice_ping:(ICEContext*)context
+{
+ cppCall(^(const Ice::Context& ctx) { OBJECTPRX->ice_ping(ctx); }, context);
+}
+-(id<ICEAsyncResult>) begin_ice_ping
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result) { result = OBJECTPRX->begin_ice_ping(); }, self);
+}
+-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx)
+ {
+ result = OBJECTPRX->begin_ice_ping(ctx);
+ }, context, self);
+}
+
+-(id<ICEAsyncResult>) begin_ice_ping:(void(^)())response exception:(void(^)(ICEException*))exception
+{
+ return [self begin_ice_ping:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context
+ response:(void(^)())response
+ exception:(void(^)(ICEException*))exception
+
+{
+ return [self begin_ice_ping:context response:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_ping:(void(^)())response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_ping(cb);
+ },
+ ^(const Ice::AsyncResultPtr& result) {
+ OBJECTPRX->end_ice_ping(result);
+ if(response)
+ {
+ response();
+ }
+ },
+ exception, sent, self);
+}
+
+-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context
+ response:(void(^)())response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_ping(ctx, cb);
+ },
+ context,
+ ^(const Ice::AsyncResultPtr& result) {
+ OBJECTPRX->end_ice_ping(result);
+ if(response)
+ {
+ response();
+ }
+ },
+ exception, sent, self);
+}
+-(void) end_ice_ping:(id<ICEAsyncResult>)result
+{
+ endCppCall(^(const Ice::AsyncResultPtr& r) { OBJECTPRX->end_ice_ping(r); }, result);
+}
+
+-(NSArray*) ice_ids
+{
+ __block NSArray* ret__;
+ cppCall(^ { ret__ = [toNSArray(OBJECTPRX->ice_ids()) autorelease]; });
+ return ret__;
+}
+-(NSArray*) ice_ids:(ICEContext*)context
+{
+ __block NSArray* ret__;
+ cppCall(^(const Ice::Context& ctx) { ret__ = [toNSArray(OBJECTPRX->ice_ids(ctx)) autorelease]; }, context);
+ return ret__;
+}
+-(id<ICEAsyncResult>) begin_ice_ids
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result) { result = OBJECTPRX->begin_ice_ids(); } , self);
+}
+
+-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx)
+ {
+ result = OBJECTPRX->begin_ice_ids(ctx);
+ }, context, self);
+}
+-(id<ICEAsyncResult>) begin_ice_ids:(void(^)(NSArray*))response exception:(void(^)(ICEException*))exception
+{
+ return [self begin_ice_ids:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context
+ response:(void(^)(NSArray*))response
+ exception:(void(^)(ICEException*))exception
+{
+ return [self begin_ice_ids:context response:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_ids:(void(^)(NSArray*))response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_ids(cb);
+ },
+ ^(const Ice::AsyncResultPtr& result) {
+ NSArray* ret__ = [toNSArray(OBJECTPRX->end_ice_ids(result)) autorelease];
+ if(response)
+ {
+ response(ret__);
+ }
+ },
+ exception, sent, self);
+}
+-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context
+ response:(void(^)(NSArray*))response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_ids(ctx, cb);
+ },
+ context,
+ ^(const Ice::AsyncResultPtr& result) {
+ NSArray* ret__ = [toNSArray(OBJECTPRX->end_ice_ids(result)) autorelease];
+ if(response)
+ {
+ response(ret__);
+ }
+ },
+ exception, sent, self);
+}
+-(NSArray*) end_ice_ids:(id<ICEAsyncResult>)result
+{
+ __block NSArray* ret__;
+ endCppCall(^(const Ice::AsyncResultPtr& r) { ret__ = [toNSArray(OBJECTPRX->end_ice_ids(r)) autorelease]; },
+ result);
+ return ret__;
+}
+
+-(NSString*) ice_id
+{
+ __block NSString* ret__;
+ cppCall(^ { ret__ = [toNSString(OBJECTPRX->ice_id()) autorelease]; });
+ return ret__;
+}
+-(NSString*) ice_id:(ICEContext*)context
+{
+ __block NSString* ret__;
+ cppCall(^(const Ice::Context& ctx) { ret__ = [toNSString(OBJECTPRX->ice_id(ctx)) autorelease]; }, context);
+ return ret__;
+}
+-(id<ICEAsyncResult>) begin_ice_id
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result) { result = OBJECTPRX->begin_ice_id(); } , self);
+}
+-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx)
+ {
+ result = OBJECTPRX->begin_ice_id(ctx);
+ }, context, self);
+}
+-(id<ICEAsyncResult>) begin_ice_id:(void(^)(NSString*))response exception:(void(^)(ICEException*))exception
+{
+ return [self begin_ice_id:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context
+ response:(void(^)(NSString*))response
+ exception:(void(^)(ICEException*))exception
+
+{
+ return [self begin_ice_id:context response:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_id:(void(^)(NSString*))response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_id(cb);
+ },
+ ^(const Ice::AsyncResultPtr& result) {
+ NSString* ret__ = [toNSString(OBJECTPRX->end_ice_id(result)) autorelease];
+ if(response)
+ {
+ response(ret__);
+ }
+ },
+ exception, sent, self);
+}
+-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context
+ response:(void(^)(NSString*))response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_id(ctx, cb);
+ },
+ context,
+ ^(const Ice::AsyncResultPtr& result) {
+ NSString* ret__ = [toNSString(OBJECTPRX->end_ice_id(result)) autorelease];
+ if(response)
+ {
+ response(ret__);
+ }
+ },
+ exception, sent, self);
+}
+-(NSString*) end_ice_id:(id<ICEAsyncResult>)result
+{
+ __block NSString* ret__;
+ endCppCall(^(const Ice::AsyncResultPtr& r) { ret__ = [toNSString(OBJECTPRX->end_ice_id(r)) autorelease]; },
+ result);
+ return ret__;
+}
+
+-(BOOL) ice_invoke:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ inEncaps:(NSData*)inEncaps
+ outEncaps:(NSMutableData**)outEncaps
+{
+ __block BOOL ret__;
+ cppCall(^ {
+ std::pair<const Ice::Byte*, const Ice::Byte*> inP((ICEByte*)[inEncaps bytes],
+ (ICEByte*)[inEncaps bytes] + [inEncaps length]);
+ std::vector<Ice::Byte> outP;
+ ret__ = OBJECTPRX->ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inP, outP);
+ *outEncaps = [NSMutableData dataWithBytes:&outP[0] length:outP.size()];
+ });
+ return ret__;
+}
+
+-(BOOL) ice_invoke:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ inEncaps:(NSData*)inEncaps
+ outEncaps:(NSMutableData**)outEncaps
+ context:(ICEContext*)context
+{
+ __block BOOL ret__;
+ cppCall(^(const Ice::Context& ctx) {
+ std::pair<const Ice::Byte*, const Ice::Byte*> inP((ICEByte*)[inEncaps bytes],
+ (ICEByte*)[inEncaps bytes] + [inEncaps length]);
+ std::vector<Ice::Byte> outP;
+ ret__ = OBJECTPRX->ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inP, outP, ctx);
+ *outEncaps = [NSMutableData dataWithBytes:&outP[0] length:outP.size()];
+ }, context);
+ return ret__;
+}
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result)
+ {
+ std::pair<const Ice::Byte*, const Ice::Byte*>
+ inP((ICEByte*)[inEncaps bytes], (ICEByte*)[inEncaps bytes] + [inEncaps length]);
+ result = OBJECTPRX->begin_ice_invoke(fromNSString(operation),
+ (Ice::OperationMode)mode,
+ inP);
+ }, self);
+}
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ inEncaps:(NSData*)inEncaps
+ context:(ICEContext*)context
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx)
+ {
+ std::pair<const Ice::Byte*, const Ice::Byte*>
+ inP((ICEByte*)[inEncaps bytes], (ICEByte*)[inEncaps bytes] + [inEncaps length]);
+ result = OBJECTPRX->begin_ice_invoke(fromNSString(operation),
+ (Ice::OperationMode)mode,
+ inP,
+ ctx);
+ }, context, self);
+}
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ inEncaps:(NSData*)inEncaps
+ response:(void(^)(BOOL, NSMutableData*))response
+ exception:(void(^)(ICEException*))exception
+{
+ return [self begin_ice_invoke:operation mode:mode inEncaps:inEncaps response:response exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ inEncaps:(NSData*)inEncaps
+ context:(ICEContext*)context
+ response:(void(^)(BOOL, NSMutableData*))response
+ exception:(void(^)(ICEException*))exception
+{
+ return [self begin_ice_invoke:operation mode:mode inEncaps:inEncaps context:context response:response
+ exception:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ inEncaps:(NSData*)inEncaps
+ response:(void(^)(BOOL, NSMutableData*))response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb)
+ {
+ std::pair<const Ice::Byte*, const Ice::Byte*>
+ inP((ICEByte*)[inEncaps bytes], (ICEByte*)[inEncaps bytes] + [inEncaps length]);
+ result = OBJECTPRX->begin_ice_invoke(fromNSString(operation),
+ (Ice::OperationMode)mode,
+ inP,
+ cb);
+ },
+ ^(const Ice::AsyncResultPtr& result) {
+ std::pair<const ::Ice::Byte*, const ::Ice::Byte*> outP;
+ BOOL ret__ = OBJECTPRX->___end_ice_invoke(outP, result);
+ NSMutableData* outEncaps =
+ [NSMutableData dataWithBytes:outP.first length:(outP.second - outP.first)];
+ if(response)
+ {
+ response(ret__, outEncaps);
+ }
+ },
+ exception, sent, self);
+}
+-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation
+ mode:(ICEOperationMode)mode
+ inEncaps:(NSData*)inEncaps
+ context:(ICEContext*)context
+ response:(void(^)(BOOL, NSMutableData*))response
+ exception:(void(^)(ICEException*))exception
+ sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb)
+ {
+ std::pair<const Ice::Byte*, const Ice::Byte*>
+ inP((ICEByte*)[inEncaps bytes], (ICEByte*)[inEncaps bytes] + [inEncaps length]);
+ result = OBJECTPRX->begin_ice_invoke(fromNSString(operation),
+ (Ice::OperationMode)mode,
+ inP,
+ ctx,
+ cb);
+ },
+ context,
+ ^(const Ice::AsyncResultPtr& result) {
+ std::pair<const ::Ice::Byte*, const ::Ice::Byte*> outP;
+ BOOL ret__ = OBJECTPRX->___end_ice_invoke(outP, result);
+ NSMutableData* outEncaps =
+ [NSMutableData dataWithBytes:outP.first length:(outP.second - outP.first)];
+ if(response)
+ {
+ response(ret__, outEncaps);
+ }
+ },
+ exception, sent, self);
+}
+-(BOOL) end_ice_invoke:(NSMutableData**)outEncaps result:(id<ICEAsyncResult>)result
+
+{
+ __block BOOL ret__;
+ endCppCall(^(const Ice::AsyncResultPtr& r)
+ {
+ std::vector<Ice::Byte> outP;
+ ret__ = OBJECTPRX->end_ice_invoke(outP, r);
+ *outEncaps = [NSMutableData dataWithBytes:&outP[0] length:outP.size()];
+ }, result);
+ return ret__;
+}
+
+-(ICEIdentity*) ice_getIdentity
+{
+ return [ICEIdentity identityWithIdentity:OBJECTPRX->ice_getIdentity()];
+}
+-(id) ice_identity:(ICEIdentity*)identity
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_identity([identity identity])];
+}
+-(ICEMutableContext*) ice_getContext
+{
+ return [toNSDictionary(OBJECTPRX->ice_getContext()) autorelease];
+}
+-(id) ice_context:(ICEContext*)context
+{
+ Ice::Context ctx;
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_context(fromNSDictionary(context, ctx))];
+}
+-(NSString*) ice_getFacet
+{
+ return [toNSString(OBJECTPRX->ice_getFacet()) autorelease];
+}
+-(id) ice_facet:(NSString*)facet
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_facet(fromNSString(facet))];
+}
+-(NSString*) ice_getAdapterId
+{
+ return [toNSString(OBJECTPRX->ice_getAdapterId()) autorelease];
+}
+
+-(ICEEndpointSeq*) ice_getEndpoints
+{
+ return [toNSArray(OBJECTPRX->ice_getEndpoints()) autorelease];
+}
+
+-(id) ice_endpoints:(ICEEndpointSeq*)endpoints
+{
+ Ice::EndpointSeq cxxEndpoints;
+ fromNSArray(endpoints, cxxEndpoints);
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_endpoints(cxxEndpoints)];
+}
+
+-(id) ice_adapterId:(NSString*)adapterId
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_adapterId(fromNSString(adapterId))];
+}
+
+-(ICEInt) ice_getLocatorCacheTimeout
+{
+ return OBJECTPRX->ice_getLocatorCacheTimeout();
+}
+-(id) ice_locatorCacheTimeout:(ICEInt)timeout
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_locatorCacheTimeout(timeout)];
+}
+-(BOOL) ice_isConnectionCached
+{
+ return OBJECTPRX->ice_isConnectionCached();
+}
+-(id) ice_connectionCached:(BOOL)cached
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_connectionCached(cached)];
+}
+-(ICEEndpointSelectionType) ice_getEndpointSelection
+{
+ return (ICEEndpointSelectionType)OBJECTPRX->ice_getEndpointSelection();
+}
+-(id) ice_endpointSelection:(ICEEndpointSelectionType)type
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_endpointSelection((Ice::EndpointSelectionType)type)];
+}
+-(BOOL) ice_isSecure
+{
+ return OBJECTPRX->ice_isSecure();
+}
+-(id) ice_secure:(BOOL)secure
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_secure(secure)];
+}
+
+-(ICEEncodingVersion*) ice_getEncodingVersion
+{
+ return [ICEEncodingVersion encodingVersionWithEncodingVersion:OBJECTPRX->ice_getEncodingVersion()];
+}
+
+-(id) ice_encodingVersion:(ICEEncodingVersion*)encoding;
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_encodingVersion([encoding encodingVersion])];
+}
+
+-(BOOL) ice_isPreferSecure
+{
+ return OBJECTPRX->ice_isPreferSecure();
+}
+-(id) ice_preferSecure:(BOOL)preferSecure
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_preferSecure(preferSecure)];
+}
+-(id<ICERouterPrx>) ice_getRouter
+{
+ return (id<ICERouterPrx>)[ICERouterPrx objectPrxWithObjectPrx__:OBJECTPRX->ice_getRouter()];
+}
+-(id) ice_router:(id<ICERouterPrx>)router
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_router(
+ Ice::RouterPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)router objectPrx__])))];
+}
+-(id<ICELocatorPrx>) ice_getLocator
+{
+ return (id<ICELocatorPrx>)[ICELocatorPrx objectPrxWithObjectPrx__:OBJECTPRX->ice_getLocator()];
+}
+-(id) ice_locator:(id<ICELocatorPrx>)locator
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_locator(
+ Ice::LocatorPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)locator objectPrx__])))];
+}
+// -(BOOL) ice_isCollocationOptimized
+// {
+// return OBJECTPRX->ice_isCollocationOptimized();
+// }
+// -(id) ice_collocationOptimized:(BOOL)collocOptimized
+// {
+// return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_collocationOptimized(collocOptimized)];
+// }
+-(id) ice_twoway
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_twoway()];
+}
+-(BOOL) ice_isTwoway
+{
+ return OBJECTPRX->ice_isTwoway();
+}
+-(id) ice_oneway
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_oneway()];
+}
+-(BOOL) ice_isOneway
+{
+ return OBJECTPRX->ice_isOneway();
+}
+-(id) ice_batchOneway
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_batchOneway()];
+}
+-(BOOL) ice_isBatchOneway
+{
+ return OBJECTPRX->ice_isBatchOneway();
+}
+-(id) ice_datagram
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_datagram()];
+}
+-(BOOL) ice_isDatagram
+{
+ return OBJECTPRX->ice_isDatagram();
+}
+-(id) ice_batchDatagram
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_batchDatagram()];
+}
+-(BOOL) ice_isBatchDatagram
+{
+ return OBJECTPRX->ice_isBatchDatagram();
+}
+-(id) ice_compress:(BOOL)compress
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_compress(compress)];
+}
+-(id) ice_timeout:(int)timeout
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_timeout(timeout)];
+}
+-(id) ice_connectionId:(NSString*)connectionId
+{
+ return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_connectionId(fromNSString(connectionId))];
+}
+-(id<ICEConnection>) ice_getConnection
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEConnection wrapperWithCxxObject:OBJECTPRX->ice_getConnection().get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(id<ICEConnection>) ice_getCachedConnection
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEConnection wrapperWithCxxObject:OBJECTPRX->ice_getCachedConnection().get()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(void) ice_flushBatchRequests
+{
+ NSException* nsex = nil;
+ try
+ {
+ OBJECTPRX->ice_flushBatchRequests();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(id<ICEAsyncResult>) begin_ice_flushBatchRequests
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result)
+ {
+ result = OBJECTPRX->begin_ice_flushBatchRequests();
+ }, self);
+}
+-(id<ICEAsyncResult>) begin_ice_flushBatchRequests:(void(^)(ICEException*))exception
+{
+ return [self begin_ice_flushBatchRequests:exception sent:nil];
+}
+-(id<ICEAsyncResult>) begin_ice_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent
+{
+ return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb)
+ {
+ result = OBJECTPRX->begin_ice_flushBatchRequests(cb);
+ },
+ ^(const Ice::AsyncResultPtr& result) {
+ OBJECTPRX->end_ice_flushBatchRequests(result);
+ },
+ exception, sent, self);
+}
+-(void) end_ice_flushBatchRequests:(id<ICEAsyncResult>)result
+{
+ endCppCall(^(const Ice::AsyncResultPtr& r)
+ {
+ OBJECTPRX->end_ice_flushBatchRequests(r);
+ }, result);
+}
+@end
diff --git a/objc/src/Ice/ProxyI.h b/objc/src/Ice/ProxyI.h
new file mode 100644
index 00000000000..771b6c1b177
--- /dev/null
+++ b/objc/src/Ice/ProxyI.h
@@ -0,0 +1,32 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Proxy.h>
+
+#include <IceCpp/Proxy.h>
+
+@interface ICEAsyncResult : NSObject<ICEAsyncResult>
+{
+@private
+ void* asyncResult__;
+ NSString* operation_;
+ id<ICEObjectPrx> proxy_;
+}
+-(ICEAsyncResult*)initWithAsyncResult__:(const Ice::AsyncResultPtr&)arg operation:(NSString*)op proxy:(id<ICEObjectPrx>)p;
+-(Ice::AsyncResult*) asyncResult__;
++(ICEAsyncResult*)asyncResultWithAsyncResult__:(const Ice::AsyncResultPtr&)arg;
++(ICEAsyncResult*)asyncResultWithAsyncResult__:(const Ice::AsyncResultPtr&)arg operation:(NSString*)op proxy:(id<ICEObjectPrx>)p;
+-(NSString*)operation;
+@end
+
+@interface ICEObjectPrx ()
+-(ICEObjectPrx*)initWithObjectPrx__:(const Ice::ObjectPrx&)arg;
+-(IceProxy::Ice::Object*) objectPrx__;
++(ICEObjectPrx*)objectPrxWithObjectPrx__:(const Ice::ObjectPrx&)arg;
+@end
diff --git a/objc/src/Ice/Request.h b/objc/src/Ice/Request.h
new file mode 100644
index 00000000000..31fa49e1a95
--- /dev/null
+++ b/objc/src/Ice/Request.h
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Object.h>
+
+@interface ICERequest : NSObject<ICERequest>
+{
+ @private
+ ICECurrent* current;
+ id<ICEInputStream> is;
+ id<ICEOutputStream> os;
+ BOOL needReset;
+}
++(id) request:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os;
+-(id) init:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os;
+-(BOOL) callDispatch:(ICEObject*)servant;
+@end
diff --git a/objc/src/Ice/Request.m b/objc/src/Ice/Request.m
new file mode 100644
index 00000000000..45d32a89097
--- /dev/null
+++ b/objc/src/Ice/Request.m
@@ -0,0 +1,59 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Request.h>
+
+@implementation ICERequest
+-(ICECurrent*) getCurrent
+{
+ return current;
+}
+
++(id) request:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os
+{
+ ICERequest* result = [((ICERequest*)[ICERequest alloc]) init:current is:is os:os];
+ [result autorelease];
+ return result;
+}
+
+-(id) init:(ICECurrent*)current_ is:(id<ICEInputStream>)is_ os:(id<ICEOutputStream>)os_
+{
+ if(![super init])
+ {
+ return nil;
+ }
+ current = [current_ retain];
+ is = [is_ retain];
+ os = [os_ retain];
+ needReset = NO;
+ return self;
+}
+
+-(BOOL) callDispatch:(ICEObject*)servant
+{
+ if(needReset == NO)
+ {
+ needReset = YES;
+ }
+ else
+ {
+ [is rewind];
+ [os reset:NO];
+ }
+ return [servant dispatch__:current is:is os:os];
+}
+
+-(void) dealloc
+{
+ [current release];
+ [is release];
+ [os release];
+ [super dealloc];
+}
+@end
diff --git a/objc/src/Ice/SlicedData.mm b/objc/src/Ice/SlicedData.mm
new file mode 100644
index 00000000000..040a391c2a9
--- /dev/null
+++ b/objc/src/Ice/SlicedData.mm
@@ -0,0 +1,89 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in
+// the ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <SlicedDataI.h>
+#import <Util.h>
+
+#import <IceCpp/SlicedData.h>
+
+@implementation ICESlicedData
+
+-(id) initWithSlicedData:(Ice::SlicedData*)slicedData
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ self->slicedData__ = slicedData;
+ self->slicedData__->__incRef();
+ return self;
+}
+
+-(void) dealloc
+{
+ self->slicedData__->__decRef();
+ [super dealloc];
+}
+
+-(Ice::SlicedData*) slicedData
+{
+ return slicedData__;
+}
+
+@end
+
+@implementation ICEUnknownSlicedObject
+
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ self->unknownTypeId_ = nil;
+ self->slicedData_ = nil;
+ return self;
+}
+
+-(void) dealloc
+{
+ [slicedData_ release];
+ [unknownTypeId_ release];
+ [super dealloc];
+}
+
+-(NSString*) getUnknownTypeId
+{
+ return [[unknownTypeId_ retain] autorelease];
+}
+
+-(ICESlicedData*) getSlicedData
+{
+ return [[slicedData_ retain] autorelease];
+}
+
+-(void) write__:(id<ICEOutputStream>)os
+{
+ [os startObject:slicedData_];
+ [os endObject];
+}
+
+-(void) read__:(id<ICEInputStream>)is
+{
+ [is startObject];
+ slicedData_ = [is endObject:YES];
+
+ // Initialize unknown type ID to type ID of first slice.
+ Ice::SlicedData* slicedData = [((ICESlicedData*)slicedData_) slicedData];
+ assert(!slicedData->slices.empty());
+ unknownTypeId_ = toNSString(slicedData->slices[0]->typeId);
+}
+@end
diff --git a/objc/src/Ice/SlicedDataI.h b/objc/src/Ice/SlicedDataI.h
new file mode 100644
index 00000000000..665bee44617
--- /dev/null
+++ b/objc/src/Ice/SlicedDataI.h
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in
+// the ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/SlicedData.h>
+
+#include <IceCpp/SlicedData.h>
+
+@interface ICESlicedData : NSObject<ICESlicedData>
+{
+@private
+ Ice::SlicedData* slicedData__;
+}
+-(id) initWithSlicedData:(Ice::SlicedData*)slicedData;
+-(Ice::SlicedData*) slicedData;
+@end
diff --git a/objc/src/Ice/Stream.mm b/objc/src/Ice/Stream.mm
new file mode 100644
index 00000000000..d3dc9a7e780
--- /dev/null
+++ b/objc/src/Ice/Stream.mm
@@ -0,0 +1,3440 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <StreamI.h>
+#import <CommunicatorI.h>
+#import <ProxyI.h>
+#import <Util.h>
+#import <ObjectI.h>
+#import <SlicedDataI.h>
+#import <VersionI.h>
+
+#import <objc/Ice/LocalException.h>
+
+#include <IceCpp/Stream.h>
+#include <IceCpp/SlicedData.h>
+
+#import <objc/runtime.h>
+
+id ICENone = nil;
+
+namespace IceObjC
+{
+
+class ObjectWriter : public Ice::ObjectWriter
+{
+public:
+
+ ObjectWriter(ICEObject* obj, ICEOutputStream* stream) : _obj(obj), _stream(stream)
+ {
+ }
+
+ virtual void
+ write(const Ice::OutputStreamPtr& stream) const
+ {
+ @try
+ {
+ [_obj write__:_stream];
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ }
+
+ virtual void ice_preMarshal()
+ {
+ [_obj ice_preMarshal];
+ }
+
+private:
+
+ ICEObject* _obj;
+ ICEOutputStream* _stream;
+};
+
+class ObjectReader : public Ice::ObjectReader
+{
+public:
+
+ // We must explicitely CFRetain/CFRelease so that the garbage
+ // collector does not trash the _obj.
+ ObjectReader(ICEObject* obj) : _obj(obj)
+ {
+ CFRetain(_obj);
+ }
+
+ virtual ~ObjectReader()
+ {
+ CFRelease(_obj);
+ }
+
+ virtual void
+ read(const Ice::InputStreamPtr& stream)
+ {
+ @try
+ {
+ //
+ // TODO: explain why calling getWrapperWithCxxObjectNoAutoRelease is safe here
+ //
+ ICEInputStream* is = [ICEInputStream getWrapperWithCxxObjectNoAutoRelease:stream.get()];
+ assert(is != 0);
+ [_obj read__:is];
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ }
+
+ ICEObject*
+ getObject()
+ {
+ return _obj;
+ }
+
+ virtual void ice_postUnmarshal()
+ {
+ [_obj ice_postUnmarshal];
+ }
+
+private:
+
+ ICEObject* _obj;
+};
+typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr;
+
+class ReadObjectBase : public Ice::ReadObjectCallback
+{
+public:
+
+ ReadObjectBase(Class expectedType) : _expectedType(expectedType)
+ {
+ }
+
+ void checkType(ICEObject*);
+
+private:
+
+ Class _expectedType;
+};
+
+void
+ReadObjectBase::checkType(ICEObject* o)
+{
+ if(o != nil && ![o isKindOfClass:_expectedType])
+ {
+ NSString* actualType = [o ice_id];
+ NSString* expectedType = [_expectedType ice_staticId];
+ NSString* reason = [NSString stringWithFormat:@"expected element of type `%@' but received `%@'",
+ expectedType, actualType];
+
+ @throw [ICEUnexpectedObjectException unexpectedObjectException:__FILE__
+ line:__LINE__
+ reason_:reason
+ type:actualType
+ expectedType:expectedType];
+ }
+}
+
+class ReadObject : public ReadObjectBase
+{
+public:
+
+ ReadObject(ICEObject** addr, Class expectedType, bool autorelease) :
+ ReadObjectBase(expectedType), _addr(addr), _autorelease(autorelease)
+ {
+ }
+
+ virtual void
+ invoke(const Ice::ObjectPtr& obj)
+ {
+ @try
+ {
+ if(obj)
+ {
+ ICEObject* o = ObjectReaderPtr::dynamicCast(obj)->getObject();
+ checkType(o);
+ *_addr = [o retain];
+ if(_autorelease)
+ {
+ [*_addr autorelease];
+ }
+ }
+ else
+ {
+ *_addr = nil;
+ }
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ }
+
+private:
+
+ ICEObject** _addr;
+ bool _autorelease;
+};
+
+class ReadObjectAtIndex : public ReadObjectBase
+{
+public:
+
+ ReadObjectAtIndex(NSMutableArray* array, ICEInt index, Class expectedType) :
+ ReadObjectBase(expectedType), _array(array), _index(index)
+ {
+ }
+
+ virtual void
+ invoke(const Ice::ObjectPtr& obj)
+ {
+ @try
+ {
+ if(obj)
+ {
+ ICEObject* o = ObjectReaderPtr::dynamicCast(obj)->getObject();
+ checkType(o);
+ [_array replaceObjectAtIndex:_index withObject:o];
+ }
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ }
+
+private:
+
+ NSMutableArray* _array;
+ ICEInt _index;
+};
+
+class ReadObjectForKey : public ReadObjectBase
+{
+public:
+
+ // We must explicitely CFRetain/CFRelease so that the garbage
+ // collector does not trash the _key.
+ ReadObjectForKey(NSMutableDictionary* dict, id key, Class expectedType) :
+ ReadObjectBase(expectedType), _dict(dict), _key(key)
+ {
+ CFRetain(_key);
+ }
+
+ virtual ~ReadObjectForKey()
+ {
+ CFRelease(_key);
+ }
+
+ virtual void
+ invoke(const Ice::ObjectPtr& obj)
+ {
+ @try
+ {
+ if(obj)
+ {
+ ICEObject* o = ObjectReaderPtr::dynamicCast(obj)->getObject();
+ checkType(o);
+ [_dict setObject:o forKey:_key];
+ }
+ else
+ {
+ [_dict setObject:[NSNull null] forKey:_key];
+ }
+ }
+ @catch(id ex)
+ {
+ rethrowCxxException(ex);
+ }
+ }
+
+private:
+
+ NSMutableDictionary* _dict;
+ id _key;
+};
+
+class ExceptionWriter : public Ice::UserExceptionWriter
+{
+public:
+
+ ExceptionWriter(const Ice::CommunicatorPtr& communicator, ICEOutputStream* stream, ICEUserException* ex) :
+ Ice::UserExceptionWriter(communicator),
+ _stream(stream),
+ _ex(ex)
+ {
+
+ }
+
+ virtual bool
+ usesClasses() const
+ {
+ return [_ex usesClasses__];
+ }
+
+ virtual std::string
+ ice_name() const
+ {
+ return [[_ex ice_name] UTF8String];
+ }
+
+ virtual Ice::UserException*
+ ice_clone() const
+ {
+ return new ExceptionWriter(*this);
+ }
+
+ virtual void
+ ice_throw() const
+ {
+ throw *this;
+ }
+
+ virtual void
+ write(const Ice::OutputStreamPtr& stream) const
+ {
+ [_ex write__:_stream];
+ }
+
+private:
+
+ ICEOutputStream* _stream;
+ ICEUserException* _ex;
+};
+
+class ExceptionReader : public Ice::UserExceptionReader
+{
+public:
+
+ ExceptionReader(const Ice::CommunicatorPtr& communicator, ICEInputStream* stream, ICEUserException* ex) :
+ Ice::UserExceptionReader(communicator),
+ _stream(stream),
+ _ex(ex)
+ {
+ }
+
+ void
+ read(const Ice::InputStreamPtr& stream) const
+ {
+ [_ex read__:_stream];
+ }
+
+ virtual std::string
+ ice_name() const
+ {
+ return [[_ex ice_name] UTF8String];
+ }
+
+ virtual bool
+ usesClasses() const
+ {
+ return [_ex usesClasses__];
+ }
+
+ virtual Ice::UserException*
+ ice_clone() const
+ {
+ assert(false);
+ return 0;
+ }
+
+ virtual void
+ ice_throw() const
+ {
+ throw *this;
+ }
+
+ ICEUserException* getException() const
+ {
+ return _ex;
+ }
+
+private:
+
+ ICEInputStream* _stream;
+ ICEUserException* _ex;
+};
+
+class UserExceptionReaderFactoryI : public Ice::UserExceptionReaderFactory
+{
+public:
+
+ UserExceptionReaderFactoryI(const Ice::CommunicatorPtr& communicator, ICEInputStream* is) :
+ _communicator(communicator),
+ _is(is)
+ {
+ }
+
+ virtual void createAndThrow(const std::string& typeId) const
+ {
+ ICEUserException* ex = nil;
+ std::string objcId = toObjCSliceId(typeId,
+ [[ICECommunicator wrapperWithCxxObject:_communicator.get()] getPrefixTable]);
+ Class c = objc_lookUpClass(objcId.c_str());
+ if(c != nil)
+ {
+ ex = [[c alloc] init];
+ throw ExceptionReader(_communicator, _is, ex);
+ }
+ }
+
+private:
+
+ Ice::CommunicatorPtr _communicator;
+ ICEInputStream* _is;
+};
+
+}
+
+@interface ICEInternalNone : NSObject
+@end
+
+@implementation ICEInternalNone
++(void)load
+{
+ ICENone = [[ICEInternalNone alloc] init];
+}
+-(id) copyWithZone:(NSZone *)zone
+{
+ return self;
+}
+-(id) retain
+{
+ return self;
+}
+-(NSUInteger) retainCount
+{
+ return NSUIntegerMax;
+}
+-(oneway void) release
+{
+}
+-(id) autorelease
+{
+ return self;
+}
+@end
+
+@implementation ICEInputStream
+-(id) initWithCxxObject:(IceUtil::Shared*)cxxObject
+{
+ self = [super initWithCxxObject:cxxObject];
+ if(!self)
+ {
+ return nil;
+ }
+ is_ = dynamic_cast<Ice::InputStream*>(cxxObject);
+ return self;
+}
+
++(Ice::Object*)createObjectReader:(ICEObject*)obj
+{
+ return new IceObjC::ObjectReader(obj);
+}
+
+-(Ice::InputStream*) is
+{
+ return is_;
+}
+
+// @protocol ICEInputStream methods
+
+-(id<ICECommunicator>) communicator
+{
+ return [ICECommunicator wrapperWithCxxObject:is_->communicator().get()];
+}
+
+-(void) sliceObjects:(BOOL)b
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->sliceObjects(b);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(BOOL)readBool
+{
+ NSException* nsex = nil;
+ try
+ {
+ bool value;
+ is_->read(value);
+ return value;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return NO; // Keep the compiler happy.
+}
+
+-(NSMutableData*) readBoolSeq
+{
+ return [[self newBoolSeq] autorelease];
+}
+
+-(NSMutableData*) newBoolSeq
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const bool*, const bool*> seq;
+ IceUtil::ScopedArray<bool> result;
+ is_->read(seq, result);
+ return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(BOOL)];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEByte) readByte
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Byte value;
+ is_->read(value);
+ return value;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0; // Keep the compiler happy.
+}
+
+-(NSMutableData*) readByteSeq
+{
+ return [[self newByteSeq] autorelease];
+}
+
+-(NSMutableData*) newByteSeq
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const Ice::Byte*, const Ice::Byte*> seq;
+ is_->read(seq);
+ return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first)];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+-(NSData*) readByteSeqNoCopy
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const Ice::Byte*, const Ice::Byte*> seq;
+ is_->read(seq);
+ return [NSData dataWithBytesNoCopy:const_cast<Ice::Byte*>(seq.first)
+ length:(seq.second - seq.first) freeWhenDone:NO];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEShort) readShort
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Short value;
+ is_->read(value);
+ return value;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0; // Keep the compiler happy.
+}
+
+-(NSMutableData*) readShortSeq
+{
+ return [[self newShortSeq] autorelease];
+}
+
+-(NSMutableData*) newShortSeq
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const Ice::Short*, const Ice::Short*> seq;
+ IceUtil::ScopedArray<Ice::Short> result;
+ is_->read(seq, result);
+ return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICEShort)];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEInt) readInt
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Int value;
+ is_->read(value);
+ return value;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0; // Keep the compiler happy.
+}
+
+-(NSMutableData*) readIntSeq
+{
+ return [[self newIntSeq] autorelease];
+}
+
+-(NSMutableData*) newIntSeq
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const Ice::Int*, const Ice::Int*> seq;
+ IceUtil::ScopedArray<Ice::Int> result;
+ is_->read(seq, result);
+ return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICEInt)];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICELong) readLong
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Long value;
+ is_->read(value);
+ return value;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0; // Keep the compiler happy.
+}
+
+-(NSMutableData*) readLongSeq
+{
+ return [[self newLongSeq] autorelease];
+}
+
+-(NSMutableData*) newLongSeq
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const Ice::Long*, const Ice::Long*> seq;
+ IceUtil::ScopedArray<Ice::Long> result;
+ is_->read(seq, result);
+ return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICELong)];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEFloat) readFloat
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Float value;
+ is_->read(value);
+ return value;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0.f; // Keep the compiler happy.
+}
+
+-(NSMutableData*) readFloatSeq
+{
+ return [[self newFloatSeq] autorelease];
+}
+
+-(NSMutableData*) newFloatSeq
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const Ice::Float*, const Ice::Float*> seq;
+ IceUtil::ScopedArray<Ice::Float> result;
+ is_->read(seq, result);
+ return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICEFloat)];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEDouble) readDouble
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Double value;
+ is_->read(value);
+ return value;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0.0; // Keep the compiler happy.
+}
+
+-(NSMutableData*) readDoubleSeq
+{
+ return [[self newDoubleSeq] autorelease];
+}
+
+-(NSMutableData*) newDoubleSeq
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const Ice::Double*, const Ice::Double*> seq;
+ IceUtil::ScopedArray<Ice::Double> result;
+ is_->read(seq, result);
+ return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICEDouble)];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSMutableString*)readString
+{
+ return [[self newString] autorelease];
+}
+
+-(NSMutableString*)newString
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::string value;
+ is_->read(value);
+ return toNSMutableString(value);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSMutableArray*) readStringSeq
+{
+ return [[self newStringSeq] autorelease];
+}
+
+-(NSMutableArray*) newStringSeq
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::StringSeq value;
+ is_->read(value);
+ return toNSArray(value);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEInt) readEnumerator:(ICEInt)min max:(ICEInt)max
+{
+ NSException* nsex = nil;
+ ICEInt val = 0; // Keep the compiler happy.
+ try
+ {
+ if(is_->getEncoding() == Ice::Encoding_1_0)
+ {
+ if(max <= 0x7f)
+ {
+ val = [self readByte];
+ }
+ else if(max <= 0x7fff)
+ {
+ val = [self readShort];
+ }
+ else
+ {
+ val = [self readInt];
+ }
+ }
+ else
+ {
+ val = [self readSize];
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ if(val > max || val < min)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"enumerator out of range"];
+ }
+ return val;
+}
+
+//
+// Size of an enum. Slice enum underling type is specified as ICEInt so
+// all Slice enums have the same size as an ICEInt.
+//
+#define ENUM_SIZE sizeof(ICEInt)
+
+-(NSMutableData*) readEnumSeq:(ICEInt)min max:(ICEInt)max
+{
+ return [[self newEnumSeq:(ICEInt)min max:(ICEInt)max] autorelease];
+}
+
+-(NSMutableData*) newEnumSeq:(ICEInt)min max:(ICEInt)max
+{
+ int minWireSize;
+ if(max <= 0x7f)
+ {
+ minWireSize = 1;
+ }
+ else if(max <= 0x7fff)
+ {
+ minWireSize = 2;
+ }
+ else
+ {
+ minWireSize = 4;
+ }
+
+ NSException* nsex = nil;
+ NSMutableData* ret = 0;
+ try
+ {
+ int count = is_->readAndCheckSeqSize(minWireSize);
+ if((ret = [[NSMutableData alloc] initWithLength:(count * ENUM_SIZE)]) == 0)
+ {
+ return ret;
+ }
+
+ ICEInt *v = (ICEInt *)[ret bytes];
+ if(max <= 0x7f)
+ {
+ while(count-- > 0)
+ {
+ *v = [self readByte];
+ if(*v > max || *v < min)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__
+ reason_:@"enumerator out of range"];
+ }
+ ++v;
+ }
+ }
+ else if(max <= 0x7fff)
+ {
+ while(count-- > 0)
+ {
+ *v = [self readShort];
+ if(*v > max || *v < min)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__
+ reason_:@"enumerator out of range"];
+ }
+ ++v;
+ }
+ }
+ else
+ {
+ while(count-- > 0)
+ {
+ *v = [self readInt];
+ if(*v > max || *v < min)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__
+ reason_:@"enumerator out of range"];
+ }
+ ++v;
+ }
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return ret;
+}
+
+-(ICEInt) readSize
+{
+ NSException* nsex = nil;
+ try
+ {
+ return is_->readSize();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0; // Keep the compiler happy.
+}
+
+-(ICEInt) readAndCheckSeqSize:(ICEInt)minSize
+{
+ NSException* nsex = nil;
+ try
+ {
+ return is_->readAndCheckSeqSize(minSize);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return 0; // Keep the compiler happy.
+}
+
+-(id<ICEObjectPrx>) readProxy:(Class)type
+{
+ return [[self newProxy:type] autorelease];
+}
+
+-(id<ICEObjectPrx>) newProxy:(Class)type
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::ObjectPrx p = is_->readProxy();
+ if(!p)
+ {
+ return nil;
+ }
+ else
+ {
+ return [[type alloc] initWithObjectPrx__:p];
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+-(void) readObject:(ICEObject**)object
+{
+ [self readObject:object expectedType:[ICEObject class]];
+}
+-(void) readObject:(ICEObject**)object expectedType:(Class)type
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->readObject(new IceObjC::ReadObject(object, type, true));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+-(void) newObject:(ICEObject*ICE_STRONG_QUALIFIER*)object
+{
+ [self newObject:object expectedType:[ICEObject class]];
+}
+-(void) newObject:(ICEObject*ICE_STRONG_QUALIFIER*)object expectedType:(Class)type
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->readObject(new IceObjC::ReadObject(object, type, false));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(NSMutableArray*) readObjectSeq:(Class)type
+{
+ return [[self newObjectSeq:(Class)type] autorelease];
+}
+
+-(NSMutableArray*) newObjectSeq:(Class)type
+{
+ ICEInt sz = [self readAndCheckSeqSize:1];
+ NSMutableArray* arr = [[NSMutableArray alloc] initWithCapacity:sz];
+ NSException* nsex = nil;
+ try
+ {
+ int i;
+ id null = [NSNull null];
+ for(i = 0; i < sz; i++)
+ {
+ [arr addObject:null];
+ is_->readObject(new IceObjC::ReadObjectAtIndex(arr, i, type));
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ [arr release];
+ @throw nsex;
+ }
+ return arr;
+}
+
+-(NSMutableDictionary*) readObjectDict:(Class)keyHelper expectedType:(Class)type
+{
+ return [[self newObjectDict:(Class)keyHelper expectedType:(Class)type] autorelease];
+}
+
+-(NSMutableDictionary*) newObjectDict:(Class)keyHelper expectedType:(Class)type
+{
+ ICEInt sz = [self readAndCheckSeqSize:[keyHelper minWireSize] + 1];
+ NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] initWithCapacity:sz];
+ id key = nil;
+ for(int i = 0; i < sz; ++i)
+ {
+ @try
+ {
+ key = [keyHelper readRetained:self];
+ }
+ @catch(id ex)
+ {
+ [dictionary release];
+ @throw ex;
+ }
+
+ NSException* nsex = nil;
+ try
+ {
+ is_->readObject(new IceObjC::ReadObjectForKey(dictionary, key, type));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ [key release];
+ [dictionary release];
+ @throw nsex;
+ }
+ [key release];
+ }
+ return dictionary;
+}
+
+-(NSMutableArray*) readSequence:(Class)helper
+{
+ return [[self newSequence:(Class)helper] autorelease];
+}
+
+-(NSMutableArray*) newSequence:(Class)helper
+{
+ ICEInt sz = [self readAndCheckSeqSize:[helper minWireSize]];
+ NSMutableArray* arr = [[NSMutableArray alloc] initWithCapacity:sz];
+ id obj = nil;
+ @try
+ {
+ while(sz-- > 0)
+ {
+ obj = [helper readRetained:self];
+ if(obj == nil)
+ {
+ [arr addObject:[NSNull null]];
+ }
+ else
+ {
+ [arr addObject:obj];
+ [obj release];
+ }
+ }
+ }
+ @catch(id ex)
+ {
+ [arr release];
+ [obj release];
+ @throw ex;
+ }
+ return arr;
+}
+
+-(NSMutableDictionary*) readDictionary:(ICEKeyValueTypeHelper)helper
+{
+ return [[self newDictionary:(ICEKeyValueTypeHelper)helper] autorelease];
+}
+
+-(NSMutableDictionary*) newDictionary:(ICEKeyValueTypeHelper)helper
+{
+ ICEInt sz = [self readAndCheckSeqSize:[helper.key minWireSize] + [helper.value minWireSize]];
+ NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] initWithCapacity:sz];
+ id key = nil;
+ id value = nil;
+ @try
+ {
+ while(sz-- > 0)
+ {
+ key = [helper.key readRetained:self];
+ value = [helper.value readRetained:self];
+ if(value == nil)
+ {
+ [dictionary setObject:[NSNull null] forKey:key];
+ }
+ else
+ {
+ [dictionary setObject:value forKey:key];
+ [value release];
+ }
+ [key release];
+ }
+ }
+ @catch(id ex)
+ {
+ [dictionary release];
+ [key release];
+ [value release];
+ @throw ex;
+ }
+ return dictionary;
+}
+
+-(BOOL) readOptional:(ICEInt)tag format:(ICEOptionalFormat)format
+{
+ NSException* nsex = nil;
+ try
+ {
+ return is_->readOptional(tag, static_cast<Ice::OptionalFormat>(format));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return NO; // Keep the compiler happy.
+}
+
+-(void) throwException
+{
+ ICEUserException* ex = nil;
+ NSException* nsex = nil;
+ try
+ {
+ Ice::UserExceptionReaderFactoryPtr factory =
+ new IceObjC::UserExceptionReaderFactoryI(is_->communicator().get(), self);
+ is_->throwException(factory);
+ }
+ catch(const IceObjC::ExceptionReader& reader)
+ {
+ ex = reader.getException();
+ @throw [ex autorelease]; // NOTE: exceptions are always auto-released, no need for the caller to do it.
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ @throw nsex;
+ }
+}
+
+-(void) startObject
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->startObject();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(id<ICESlicedData>) endObject:(BOOL)preserve
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::SlicedDataPtr slicedData = is_->endObject(preserve);
+ return slicedData ? [[ICESlicedData alloc] initWithSlicedData:slicedData.get()] : nil;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil; // Make compiler happy
+}
+
+-(void) startException
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->startException();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(id<ICESlicedData>) endException:(BOOL)preserve
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::SlicedDataPtr slicedData = is_->endException(preserve);
+ return slicedData ? [[ICESlicedData alloc] initWithSlicedData:slicedData.get()] : nil;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil; // Make compiler happy
+}
+
+-(void) startSlice
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->startSlice();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) endSlice
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->endSlice();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) skipSlice
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->skipSlice();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(ICEEncodingVersion*) startEncapsulation
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEEncodingVersion encodingVersionWithEncodingVersion:is_->startEncapsulation()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil; // Keep the compiler happy.
+}
+
+-(void) endEncapsulation
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->endEncapsulation();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(ICEEncodingVersion*) skipEncapsulation
+{
+ NSException* nsex = nil;
+ try
+ {
+ return [ICEEncodingVersion encodingVersionWithEncodingVersion:is_->skipEncapsulation()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return nil; // Keep the compiler happy.
+}
+
+-(ICEEncodingVersion*) getEncoding
+{
+ return [ICEEncodingVersion encodingVersionWithEncodingVersion:is_->getEncoding()];
+}
+
+-(void) readPendingObjects
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->readPendingObjects();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) rewind
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->rewind();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) skip:(ICEInt)sz
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->skip(sz);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) skipSize
+{
+ NSException* nsex = nil;
+ try
+ {
+ is_->skipSize();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+@end
+
+@implementation ICEOutputStream
+-(id) initWithCxxObject:(IceUtil::Shared*)cxxObject
+{
+ self = [super initWithCxxObject:cxxObject];
+ if(!self)
+ {
+ return nil;
+ }
+ os_ = dynamic_cast<Ice::OutputStream*>(cxxObject);
+ objectWriters_ = 0;
+ return self;
+}
+
+-(Ice::OutputStream*) os
+{
+ return os_;
+}
+
+-(void) dealloc
+{
+ if(objectWriters_)
+ {
+ delete objectWriters_;
+ }
+ [super dealloc];
+}
+
+-(void) finalize
+{
+ if(objectWriters_)
+ {
+ delete objectWriters_;
+ }
+ [super finalize];
+}
+
+// @protocol ICEOutputStream methods
+
+-(id<ICECommunicator>) communicator
+{
+ return [ICECommunicator wrapperWithCxxObject:os_->communicator().get()];
+}
+
+-(void)writeBool:(BOOL)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->write(static_cast<bool>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeBoolSeq:(NSData*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ v == nil ? os_->writeSize(0)
+ : os_->write((bool*)[v bytes], (bool*)[v bytes] + [v length] / sizeof(BOOL));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeByte:(ICEByte)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->write(static_cast<Ice::Byte>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeByteSeq:(NSData*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ v == nil ? os_->writeSize(0)
+ : os_->write((ICEByte*)[v bytes], (ICEByte*)[v bytes] + [v length]);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeShort:(ICEShort)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->write(static_cast<Ice::Short>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeShortSeq:(NSData*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ v == nil ? os_->writeSize(0)
+ : os_->write((ICEShort*)[v bytes], (ICEShort*)[v bytes] + [v length] / sizeof(ICEShort));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeInt:(ICEInt)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->write(static_cast<Ice::Int>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeIntSeq:(NSData*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ v == nil ? os_->writeSize(0)
+ : os_->write((ICEInt*)[v bytes], (ICEInt*)[v bytes] + [v length] / sizeof(ICEInt));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeLong:(ICELong)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->write(static_cast<Ice::Long>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeLongSeq:(NSData*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ v == nil ? os_->writeSize(0)
+ : os_->write((ICELong*)[v bytes], (ICELong*)[v bytes] + [v length] / sizeof(ICELong));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeFloat:(ICEFloat)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->write(static_cast<Ice::Float>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeFloatSeq:(NSData*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ v == nil ? os_->writeSize(0)
+ : os_->write((ICEFloat*)[v bytes], (ICEFloat*)[v bytes] + [v length] / sizeof(ICEFloat));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeDouble:(ICEDouble)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->write(static_cast<Ice::Double>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeDoubleSeq:(NSData*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ v == nil ? os_->writeSize(0)
+ : os_->write((ICEDouble*)[v bytes],
+ (ICEDouble*)[v bytes] + [v length] / sizeof(ICEDouble));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeString:(NSString*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->write(fromNSString(v));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeStringSeq:(NSArray*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::vector<std::string> s;
+ os_->write(fromNSArray(v, s));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void)writeSequence:(NSArray*)arr helper:(Class)helper
+{
+ if(arr == nil)
+ {
+ [self writeSize:0];
+ return;
+ }
+
+ [self writeSize:[arr count]];
+ for(id i in arr)
+ {
+ [helper write:(i == [NSNull null] ? nil : i) stream:self];
+ }
+}
+
+-(void) writeDictionary:(NSDictionary*)dictionary helper:(ICEKeyValueTypeHelper)helper
+{
+ if(dictionary == nil)
+ {
+ [self writeSize:0];
+ return;
+ }
+
+ [self writeSize:[dictionary count]];
+ NSEnumerator* e = [dictionary keyEnumerator];
+ id key;
+ while((key = [e nextObject]))
+ {
+ if(key == [NSNull null])
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [helper.key write:key stream:self];
+ NSObject *obj = [dictionary objectForKey:key];
+ [helper.value write:(obj == [NSNull null] ? nil : obj) stream:self];
+ }
+}
+
+-(BOOL) writeOptional:(ICEInt)tag format:(ICEOptionalFormat)format
+{
+ NSException* nsex = nil;
+ try
+ {
+ return os_->writeOptional(tag, static_cast<Ice::OptionalFormat>(format));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+ return NO; // Keep the compiler happy.
+}
+
+-(void) writeEnumerator:(ICEInt)v min:(int)min max:(int)max
+{
+ if(v > max || v < min)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"enumerator out of range"];
+ }
+ NSException* nsex = nil;
+ try
+ {
+ if(os_->getEncoding() == Ice::Encoding_1_0)
+ {
+ if(max <= 0x7f)
+ {
+ os_->write(static_cast<Ice::Byte>(v));
+ }
+ else if(max <= 0x7fff)
+ {
+ os_->write(static_cast<Ice::Short>(v));
+ }
+ else
+ {
+ os_->write(static_cast<Ice::Int>(v));
+ }
+ }
+ else
+ {
+ os_->writeSize(static_cast<Ice::Int>(v));
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+//
+// The C standard does not fix the size of an enum. The compiler is free
+// to choose an enum size that depends on the number of enumerators, and
+// the choice may vary depending on the processor. This means that we don't
+// know what the size of an enum is until run time, so the marshaling
+// has to be generic and copy with enums that could be 8, 16, or 32 bits wide.
+//
+-(void) writeEnumSeq:(NSData*)v min:(ICEInt)min max:(ICEInt)max
+{
+ NSException* nsex = nil;
+ try
+ {
+ int count = v == nil ? 0 : [v length] / ENUM_SIZE;
+ [self writeSize:count];
+ if(count == 0)
+ {
+ return;
+ }
+
+ const ICEInt* p = (const ICEInt*)[v bytes];
+ if(max <= 0x7f)
+ {
+ while(count-- > 0)
+ {
+ if(*p > max || *p < min)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__
+ reason_:@"enumerator out of range"];
+ }
+ [self writeByte:*p++];
+ }
+ }
+ else if(max <= 0x7fff)
+ {
+ while(count-- > 0)
+ {
+ if(*p > max || *p < min)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__
+ reason_:@"enumerator out of range"];
+ }
+ [self writeShort:*p++];
+ }
+ }
+ else
+ {
+ while(count-- > 0)
+ {
+ if(*p > max || *p < min)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__
+ reason_:@"enumerator out of range"];
+ }
+ [self writeInt:*p++];
+ }
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeSize:(ICEInt)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->writeSize(v);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+
+-(void) writeProxy:(id<ICEObjectPrx>)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->writeProxy([(ICEObjectPrx*)v objectPrx__]);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeObject:(ICEObject*)v
+{
+ NSException* nsex = nil;
+ try
+ {
+ if(v == nil)
+ {
+ os_->writeObject(0);
+ }
+ else
+ {
+ os_->writeObject([self addObject:v]);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) writeObjectSeq:(NSArray*)arr
+{
+ if(arr == nil)
+ {
+ [self writeSize:0];
+ return;
+ }
+
+ [self writeSize:[arr count]];
+ for(id i in arr)
+ {
+ [self writeObject:(i == [NSNull null] ? nil : i)];
+ }
+}
+
+-(void) writeObjectDict:(NSDictionary*)dictionary helper:(Class)helper
+{
+ if(dictionary == nil)
+ {
+ [self writeSize:0];
+ return;
+ }
+
+ [self writeSize:[dictionary count]];
+ NSEnumerator* e = [dictionary keyEnumerator];
+ id key;
+ while((key = [e nextObject]))
+ {
+ if(key == [NSNull null])
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [helper write:key stream:self];
+ id obj = [dictionary objectForKey:key];
+ [self writeObject:(obj == [NSNull null] ? nil : obj)];
+ }
+}
+
+-(void) writeException:(ICEUserException*)ex
+{
+ IceObjC::ExceptionWriter writer(os_->communicator().get(), self, ex);
+ os_->writeException(writer);
+}
+
+-(void) startObject:(id<ICESlicedData>)slicedData
+{
+ NSException* nsex = nil;
+ try
+ {
+ if(slicedData != nil)
+ {
+ os_->startObject([self writeSlicedData:slicedData]);
+ }
+ else
+ {
+ os_->startObject(0);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) endObject
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->endObject();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) startException:(id<ICESlicedData>)slicedData
+{
+ NSException* nsex = nil;
+ try
+ {
+ if(slicedData != nil)
+ {
+ os_->startException([self writeSlicedData:slicedData]);
+ }
+ else
+ {
+ os_->startException(0);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) endException
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->endException();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) startSlice:(NSString*)typeId compactId:(ICEInt)compactId lastSlice:(BOOL)lastSlice
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->startSlice([typeId UTF8String], compactId, static_cast<bool>(lastSlice));
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) endSlice
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->endSlice();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) startEncapsulation
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->startEncapsulation();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) startEncapsulation:(ICEEncodingVersion*)encoding format:(ICEFormatType)format
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->startEncapsulation([encoding encodingVersion], (Ice::FormatType)format);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(void) endEncapsulation
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->endEncapsulation();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(ICEEncodingVersion*) getEncoding
+{
+ return [ICEEncodingVersion encodingVersionWithEncodingVersion:os_->getEncoding()];
+}
+
+-(void) writePendingObjects
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->writePendingObjects();
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(NSMutableData*) finished
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::vector<Ice::Byte> buf;
+ os_->finished(buf);
+ return [NSMutableData dataWithBytes:&buf[0] length:buf.size()];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(NSData*) finishedNoCopy
+{
+ NSException* nsex = nil;
+ try
+ {
+ std::pair<const Ice::Byte*, const Ice::Byte*> b = os_->finished();
+ return [NSData dataWithBytesNoCopy:const_cast<Ice::Byte*>(b.first) length:(b.second - b.first) freeWhenDone:NO];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+ return nil; // Keep the compiler happy.
+}
+
+-(void) reset:(BOOL)clearBuffer
+{
+ NSException* nsex = nil;
+ try
+ {
+ os_->reset(clearBuffer);
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ if(nsex != nil)
+ {
+ @throw nsex;
+ }
+}
+
+-(Ice::Object*) addObject:(ICEObject*)object
+{
+ //
+ // Ice::ObjectWriter is a subclass of Ice::Object that wraps an Objective-C object for marshaling.
+ // It is possible that this Objective-C object has already been marshaled, therefore we first must
+ // check the object map to see if this object is present. If so, we use the existing ObjectWriter,
+ // otherwise we create a new one.
+ //
+ if(!objectWriters_)
+ {
+ objectWriters_ = new std::map<ICEObject*, Ice::ObjectPtr>();
+ }
+ std::map<ICEObject*, Ice::ObjectPtr>::const_iterator p = objectWriters_->find(object);
+ if(p != objectWriters_->end())
+ {
+ return p->second.get();
+ }
+ else
+ {
+ Ice::ObjectWriterPtr writer = new IceObjC::ObjectWriter(object, self);
+ objectWriters_->insert(std::make_pair(object, writer));
+ return writer.get();
+ }
+}
+
+-(Ice::SlicedData*) writeSlicedData:(id<ICESlicedData>)sd
+{
+ NSAssert([sd isKindOfClass:[ICESlicedData class]], @"invalid sliced data object");
+ Ice::SlicedData* origSlicedData = [((ICESlicedData*)sd) slicedData];
+ Ice::SliceInfoSeq slices;
+ for(Ice::SliceInfoSeq::const_iterator p = origSlicedData->slices.begin(); p != origSlicedData->slices.end(); ++p)
+ {
+ Ice::SliceInfoPtr info = new Ice::SliceInfo;
+ info->typeId = (*p)->typeId;
+ info->compactId = (*p)->compactId;
+ info->bytes = (*p)->bytes;
+ info->hasOptionalMembers = (*p)->hasOptionalMembers;
+ info->isLastSlice = (*p)->isLastSlice;
+
+ for(std::vector<Ice::ObjectPtr>::const_iterator q = (*p)->objects.begin(); q != (*p)->objects.end(); ++q)
+ {
+ if(*q)
+ {
+ assert(IceObjC::ObjectReaderPtr::dynamicCast(*q));
+ info->objects.push_back([self addObject:IceObjC::ObjectReaderPtr::dynamicCast(*q)->getObject()]);
+ }
+ else
+ {
+ info->objects.push_back(0);
+ }
+ }
+ slices.push_back(info);
+ }
+ return new Ice::SlicedData(slices);
+}
+
+@end
+
+@implementation ICEStreamHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ NSAssert(NO, @"requires override");
+ return nil;
+}
++(id) read:(id<ICEInputStream>)stream
+{
+ return [[self readRetained:stream] autorelease];
+ return nil;
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ NSAssert(NO, @"requires override");
+}
++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ NSAssert(NO, @"requires override");
+ return nil;
+}
++(id) readOpt:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ return [[self readOptRetained:stream tag:tag] autorelease];
+ return nil;
+}
++(void) writeOpt:(id)obj stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ NSAssert(NO, @"requires override");
+}
++(ICEInt) minWireSize
+{
+ NSAssert(NO, @"requires override");
+ return 0;
+}
+@end
+
+@implementation ICEBoolHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [[NSNumber alloc] initWithBool:[stream readBool]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [stream writeBool:[obj boolValue]];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatF1])
+ {
+ return [[NSNumber alloc] initWithBool:[stream readBool]];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ BOOL value;
+ if([ICEOptionalGetter getBool:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF1])
+ {
+ [stream writeBool:value];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 1;
+}
+@end
+
+@implementation ICEByteHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [[NSNumber alloc] initWithUnsignedChar:[stream readByte]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [stream writeByte:[obj unsignedCharValue]];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatF1])
+ {
+ return [[NSNumber alloc] initWithUnsignedChar:[stream readByte]];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICEByte value;
+ if([ICEOptionalGetter getByte:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF1])
+ {
+ [stream writeByte:value];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 1;
+}
+@end
+
+@implementation ICEShortHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [[NSNumber alloc] initWithShort:[stream readShort]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [stream writeShort:[obj shortValue]];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatF2])
+ {
+ return [[NSNumber alloc] initWithShort:[stream readShort]];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICEShort value;
+ if([ICEOptionalGetter getShort:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF2])
+ {
+ [stream writeShort:value];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 2;
+}
+@end
+
+@implementation ICEIntHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [[NSNumber alloc] initWithInt:[stream readInt]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [stream writeInt:[obj intValue]];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatF4])
+ {
+ return [[NSNumber alloc] initWithInt:[stream readInt]];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICEInt value;
+ if([ICEOptionalGetter getInt:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF4])
+ {
+ [stream writeInt:value];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 4;
+}
+@end
+
+@implementation ICELongHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [[NSNumber alloc] initWithLong:[stream readLong]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [stream writeLong:[obj longValue]];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatF8])
+ {
+ return [[NSNumber alloc] initWithLong:[stream readLong]];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICELong value;
+ if([ICEOptionalGetter getLong:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF8])
+ {
+ [stream writeLong:value];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 8;
+}
+@end
+
+@implementation ICEFloatHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [[NSNumber alloc] initWithFloat:[stream readFloat]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [stream writeFloat:[obj floatValue]];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatF4])
+ {
+ return [[NSNumber alloc] initWithFloat:[stream readFloat]];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICEFloat value;
+ if([ICEOptionalGetter getFloat:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF4])
+ {
+ [stream writeFloat:value];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 4;
+}
+@end
+
+@implementation ICEDoubleHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [[NSNumber alloc] initWithDouble:[stream readDouble]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [stream writeDouble:[obj doubleValue]];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatF8])
+ {
+ return [[NSNumber alloc] initWithDouble:[stream readDouble]];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICEDouble value;
+ if([ICEOptionalGetter getDouble:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF8])
+ {
+ [stream writeDouble:value];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 8;
+}
+@end
+
+@implementation ICEStringHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newString];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == [NSNull null])
+ {
+ obj = nil;
+ }
+ [stream writeString:obj];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatVSize])
+ {
+ return [stream newString];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ NSString* value;
+ if([ICEOptionalGetter get:v value:&value type:[NSString class]] &&
+ [stream writeOptional:tag format:ICEOptionalFormatVSize])
+ {
+ [stream writeString:v];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 1;
+}
+@end
+
+@implementation ICEEnumHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [[NSNumber alloc] initWithInt:[stream readEnumerator:[self getMinValue] max:[self getMaxValue]]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason_:@"illegal NSNull value"];
+ }
+ [stream writeEnumerator:[obj intValue] min:[self getMinValue] max:[self getMaxValue]];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatSize])
+ {
+ return [[NSNumber alloc] initWithInt:[stream readEnumerator:[self getMinValue] max:[self getMaxValue]]];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICEInt value;
+ if([ICEOptionalGetter getInt:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatSize])
+ {
+ [stream writeEnumerator:value min:[self getMinValue] max:[self getMaxValue]];
+ }
+}
++(ICEInt) getMinValue
+{
+ NSAssert(NO, @"ICEEnumHelper getMinValue requires override");
+ return 0;
+}
++(ICEInt) getMaxValue
+{
+ NSAssert(NO, @"ICEEnumHelper getMaxValue requires override");
+ return 0;
+}
++(ICEInt) minWireSize
+{
+ return 1;
+}
+@end
+
+@implementation ICEObjectHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ //
+ // This will only work with the 1.1 encoding. With the 1.0 encoding
+ // objects are read when readPendingObjects is called.
+ //
+ ICEObject* obj;
+ [stream newObject:&obj];
+ return (id)obj;
+}
++(void)readRetained:(ICEObject**)v stream:(id<ICEInputStream>)stream
+{
+ [stream newObject:v];
+}
++(void)read:(ICEObject**)v stream:(id<ICEInputStream>)stream
+{
+ [stream readObject:v];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeObject:obj];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatClass])
+ {
+ return [self readRetained:stream];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICEObject* value;
+ if([ICEOptionalGetter get:v value:&value type:[ICEObject class]] &&
+ [stream writeOptional:tag format:ICEOptionalFormatClass])
+ {
+ [self write:value stream:stream];
+ }
+}
++(void)readOptRetained:(id *)v stream:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatClass])
+ {
+ [self readRetained:(ICEObject**)v stream:stream];
+ }
+ else
+ {
+ *v = ICENone;
+ }
+}
++(void)readOpt:(id *)v stream:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatClass])
+ {
+ [self read:(ICEObject**)v stream:stream];
+ }
+ else
+ {
+ *v = ICENone;
+ }
+}
++(ICEInt) minWireSize
+{
+ return 1;
+}
+@end
+
+@implementation ICEProxyHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newProxy:[ICEObjectPrx class]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeProxy:obj];
+}
++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatFSize])
+ {
+ return [ICEVarLengthOptionalHelper readRetained:stream helper:self];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ ICEObjectPrx* value;
+ if([ICEOptionalGetter get:v value:&value type:[ICEObjectPrx class]] &&
+ [stream writeOptional:tag format:ICEOptionalFormatFSize])
+ {
+ [ICEVarLengthOptionalHelper write:v stream:stream helper:self];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 2;
+}
+@end
+
+@implementation ICEStructHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ id p = [[self getType] new];
+ @try
+ {
+ [p read__:stream];
+ }
+ @catch(NSException *ex)
+ {
+ [p release];
+ @throw ex;
+ }
+ return p;
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ if(obj == nil)
+ {
+ obj = [[self getType] new];
+ @try
+ {
+ [obj write__:stream];
+ }
+ @finally
+ {
+ [obj release];
+ }
+ }
+ else
+ {
+ [obj write__:stream];
+ }
+}
++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ Class helper = [self getOptionalHelper];
+ if([stream readOptional:tag format:[helper optionalFormat]])
+ {
+ return [helper readRetained:stream helper:self];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)s tag:(ICEInt)tag
+{
+ Class helper = [self getOptionalHelper];
+ NSObject* a;
+ if([ICEOptionalGetter get:v value:&a type:[self getType]] && [s writeOptional:tag format:[helper optionalFormat]])
+ {
+ [helper write:a stream:s helper:self];
+ }
+}
++(Class) getType
+{
+ NSAssert(NO, @"getType requires override");
+ return nil;
+}
++(Class) getOptionalHelper
+{
+ NSAssert(NO, @"getOptionalHelper requires override");
+ return nil;
+}
++(ICEInt) minWireSize
+{
+ NSAssert(NO, @"minWireSize requires override");
+ return 0;
+}
+@end
+
+@implementation ICEArraySequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newSequence:[self getElementHelper]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeSequence:obj helper:[self getElementHelper]];
+}
++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ Class helper = [self getOptionalHelper];
+ if([stream readOptional:tag format:[helper optionalFormat]])
+ {
+ return [helper readRetained:stream helper:self];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)s tag:(ICEInt)tag
+{
+ Class helper = [self getOptionalHelper];
+ NSArray* a;
+ if([ICEOptionalGetter get:v value:&a type:[NSArray class]] && [s writeOptional:tag format:[helper optionalFormat]])
+ {
+ [helper write:a stream:s helper:self];
+ }
+}
++(Class) getElementHelper
+{
+ NSAssert(NO, @"getElementHelper requires override");
+ return nil;
+}
++(Class) getOptionalHelper
+{
+ NSAssert(NO, @"getOptionalHelper requires override");
+ return nil;
+}
++(ICEInt) minWireSize
+{
+ return 1;
+}
++(ICEInt) count:(id)obj
+{
+ return [obj count];
+}
+@end
+
+@implementation ICEDataSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ NSAssert(NO, @"readRetained requires override");
+ return nil;
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ NSAssert(NO, @"write requires override");
+}
++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatVSize])
+ {
+ return [ICEFixedSequenceOptionalHelper readRetained:stream helper:self];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ NSData* a;
+ if([ICEOptionalGetter get:v value:&a type:[NSData class]] &&
+ [stream writeOptional:tag format:ICEOptionalFormatVSize])
+ {
+ [ICEFixedSequenceOptionalHelper write:a stream:stream helper:self];
+ }
+}
++(ICEInt) minWireSize
+{
+ return 1;
+}
++(ICEInt) count:(id)obj
+{
+ return [obj length] / [[self getElementHelper] minWireSize];
+}
++(Class) getElementHelper
+{
+ return [ICEShortHelper class];
+}
+@end
+
+@implementation ICEBoolSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newBoolSeq];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeBoolSeq:obj];
+}
++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatVSize])
+ {
+ return [stream newBoolSeq];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ NSData* a;
+ if([ICEOptionalGetter get:v value:&a type:[NSData class]] &&
+ [stream writeOptional:tag format:ICEOptionalFormatVSize])
+ {
+ [stream writeBoolSeq:a];
+ }
+}
++(Class) getElementHelper
+{
+ return [ICEBoolHelper class];
+}
+@end
+
+@implementation ICEByteSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newByteSeq];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeByteSeq:obj];
+}
++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ if([stream readOptional:tag format:ICEOptionalFormatVSize])
+ {
+ return [stream newByteSeq];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag
+{
+ NSData* a;
+ if([ICEOptionalGetter get:v value:&a type:[NSData class]] &&
+ [stream writeOptional:tag format:ICEOptionalFormatVSize])
+ {
+ [stream writeByteSeq:a];
+ }
+}
++(Class) getElementHelper
+{
+ return [ICEIntHelper class];
+}
+@end
+
+@implementation ICEShortSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newShortSeq];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeShortSeq:obj];
+}
++(Class) getElementHelper
+{
+ return [ICEShortHelper class];
+}
+@end
+
+@implementation ICEIntSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newIntSeq];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeIntSeq:obj];
+}
++(Class) getElementHelper
+{
+ return [ICEIntHelper class];
+}
+@end
+
+@implementation ICELongSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newLongSeq];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeLongSeq:obj];
+}
++(Class) getElementHelper
+{
+ return [ICELongHelper class];
+}
+@end
+
+@implementation ICEFloatSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newFloatSeq];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeFloatSeq:obj];
+}
++(Class) getElementHelper
+{
+ return [ICEFloatHelper class];
+}
+@end
+
+@implementation ICEDoubleSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newDoubleSeq];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeDoubleSeq:obj];
+}
++(Class) getElementHelper
+{
+ return [ICEDoubleHelper class];
+}
+@end
+
+@implementation ICEEnumSequenceHelper
++(ICEInt) count:(id)obj
+{
+ return [obj length] / ENUM_SIZE;
+}
++(Class) getElementHelper
+{
+ return [ICEEnumHelper class];
+}
+@end
+
+@implementation ICEStringSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newStringSeq];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeStringSeq:obj];
+}
++(Class) getElementHelper
+{
+ return [ICEStringHelper class];
+}
++(Class) getOptionalHelper
+{
+ return [ICEVarLengthOptionalHelper class];
+}
+@end
+
+@implementation ICEObjectSequenceHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newObjectSeq:[ICEObject class]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeObjectSeq:obj];
+}
++(Class) getElementHelper
+{
+ return [ICEObjectHelper class];
+}
++(Class) getOptionalHelper
+{
+ return [ICEVarLengthOptionalHelper class];
+}
+@end
+
+@implementation ICEProxySequenceHelper
++(Class) getElementHelper
+{
+ return [ICEProxyHelper class];
+}
++(Class) getOptionalHelper
+{
+ return [ICEVarLengthOptionalHelper class];
+}
+@end
+
+@implementation ICEDictionaryHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ return [stream newDictionary:[self getKeyValueHelper]];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ [stream writeDictionary:obj helper:[self getKeyValueHelper]];
+}
++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag
+{
+ Class helper = [self getOptionalHelper];
+ if([stream readOptional:tag format:[helper optionalFormat]])
+ {
+ return [helper readRetained:stream helper:self];
+ }
+ return ICENone;
+}
++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)s tag:(ICEInt)tag
+{
+ Class helper = [self getOptionalHelper];
+ NSDictionary* a;
+ if([ICEOptionalGetter get:v value:&a type:[NSDictionary class]] &&
+ [s writeOptional:tag format:[helper optionalFormat]])
+ {
+ [helper write:a stream:s helper:self];
+ }
+}
++(Class) getOptionalHelper
+{
+ NSAssert(NO, @"getOptionalHelper requires override");
+ return nil;
+}
++(ICEKeyValueTypeHelper) getKeyValueHelper
+{
+ NSAssert(NO, @"ICEDictionaryHelper getKeyValueHelper requires override");
+ ICEKeyValueTypeHelper dummy;
+ return dummy; // Keep compiler quiet
+}
++(ICEInt) minWireSize
+{
+ return 1;
+}
++(ICEInt) count:(id)obj
+{
+ return [obj count];
+}
+@end
+
+@implementation ICEObjectDictionaryHelper
++(id) readRetained:(id<ICEInputStream>)stream
+{
+ NSAssert(NO, @"ICEObjectDictionaryHelper readRetained requires override");
+ return nil;
+}
+
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream
+{
+ NSAssert(NO, @"ICEObjectDictionaryHelper write requires override");
+}
+@end
+
+@implementation ICEVarLengthOptionalHelper
++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper
+{
+ [stream skip:4];
+ return [helper readRetained:stream];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper
+{
+ Ice::OutputStream* os = [(ICEOutputStream*)stream os];
+ os->write(static_cast<Ice::Int>(0));
+ Ice::OutputStream::size_type p = os->pos();
+ [helper write:obj stream:stream];
+ os->rewrite(static_cast<Ice::Int>(os->pos() - p), p - 4);
+}
++(ICEOptionalFormat) optionalFormat
+{
+ return ICEOptionalFormatFSize;
+}
+@end
+
+@implementation ICEFixedLengthOptionalHelper
++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper
+{
+ [stream skipSize];
+ return [helper readRetained:stream];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper
+{
+ [stream writeSize:[helper minWireSize]];
+ [helper write:obj stream:stream];
+}
++(ICEOptionalFormat) optionalFormat
+{
+ return ICEOptionalFormatVSize;
+}
+@end
+
+@implementation ICEFixedSequenceOptionalHelper
++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper
+{
+ [stream skipSize];
+ return [helper readRetained:stream];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper
+{
+ //
+ // The container size is the number of elements * the size of
+ // an element and the size-encoded number of elements (1 or
+ // 5 depending on the number of elements).
+ //
+ ICEInt n = [helper count:obj];
+ ICEInt sz = [[helper getElementHelper] minWireSize];
+ [stream writeSize:sz * n + (n < 255 ? 1 : 5)];
+ [helper write:obj stream:stream];
+}
++(ICEOptionalFormat) optionalFormat
+{
+ return ICEOptionalFormatVSize;
+}
+@end
+
+@implementation ICEFixedSize1SequenceOptionalHelper
++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper
+{
+ return [helper readRetained:stream];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper
+{
+ [helper write:obj stream:stream];
+}
++(ICEOptionalFormat) optionalFormat
+{
+ return ICEOptionalFormatVSize;
+}
+@end
+
+@implementation ICEFixedDictionaryOptionalHelper
++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper
+{
+ [stream skipSize];
+ return [helper readRetained:stream];
+}
++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper
+{
+ //
+ // The container size is the number of elements * the size of
+ // an element and the size-encoded number of elements (1 or
+ // 5 depending on the number of elements).
+ //
+ ICEInt n = [helper count:obj];
+ ICEKeyValueTypeHelper h = [helper getKeyValueHelper];
+ ICEInt sz = [h.key minWireSize] + [h.value minWireSize];
+ [stream writeSize:sz * n + (n < 255 ? 1 : 5)];
+ [helper write:obj stream:stream];
+}
++(ICEOptionalFormat) optionalFormat
+{
+ return ICEOptionalFormatVSize;
+}
+@end
+
+@implementation ICEOptionalGetter
++(BOOL) get:(id)value type:(Class)cl
+{
+ if(value == ICENone)
+ {
+ return NO;
+ }
+ else
+ {
+ if(value != nil && ![value isKindOfClass:cl])
+ {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"unexpected type" userInfo:cl];
+ }
+ return YES;
+ }
+}
++(BOOL) get:(id)value value:(id*)v type:(Class)cl
+{
+ if([self get:value type:cl])
+ {
+ *v = value;
+ return YES;
+ }
+ return NO;
+}
++(BOOL) getRetained:(id)value value:(id*)v type:(Class)cl
+{
+ BOOL r = [self get:value value:v type:cl];
+ [*v retain];
+ return r;
+}
++(BOOL) getByte:(id)value value:(ICEByte*)v
+{
+ if([self get:value type:[NSNumber class]])
+ {
+ *v = [value unsignedCharValue];
+ return YES;
+ }
+ return NO;
+}
++(BOOL) getBool:(id)value value:(BOOL*)v
+{
+ if([self get:value type:[NSNumber class]])
+ {
+ *v = [value boolValue];
+ return YES;
+ }
+ return NO;
+}
++(BOOL) getShort:(id)value value:(ICEShort*)v
+{
+ if([self get:value type:[NSNumber class]])
+ {
+ *v = [value shortValue];
+ return YES;
+ }
+ return NO;
+}
++(BOOL) getInt:(id)value value:(ICEInt*)v
+{
+ if([self get:value type:[NSNumber class]])
+ {
+ *v = [value intValue];
+ return YES;
+ }
+ return NO;
+}
++(BOOL) getLong:(id)value value:(ICELong*)v
+{
+ if([self get:value type:[NSNumber class]])
+ {
+ *v = [value longValue];
+ return YES;
+ }
+ return NO;
+}
++(BOOL) getFloat:(id)value value:(ICEFloat*)v
+{
+ if([self get:value type:[NSNumber class]])
+ {
+ *v = [value floatValue];
+ return YES;
+ }
+ return NO;
+}
++(BOOL) getDouble:(id)value value:(ICEDouble*)v
+{
+ if([self get:value type:[NSNumber class]])
+ {
+ *v = [value doubleValue];
+ return YES;
+ }
+ return NO;
+}
+@end
diff --git a/objc/src/Ice/StreamI.h b/objc/src/Ice/StreamI.h
new file mode 100644
index 00000000000..b0263dc62f3
--- /dev/null
+++ b/objc/src/Ice/StreamI.h
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Stream.h>
+#import <Wrapper.h>
+
+#include <IceCpp/Stream.h>
+
+@interface ICEInputStream : ICEInternalWrapper<ICEInputStream>
+{
+ Ice::InputStream* is_;
+}
++(Ice::Object*)createObjectReader:(ICEObject*)obj;
+-(Ice::InputStream*) is;
+@end
+
+@interface ICEOutputStream : ICEInternalWrapper<ICEOutputStream>
+{
+ Ice::OutputStream* os_;
+ std::map<ICEObject*, Ice::ObjectPtr>* objectWriters_;
+}
+-(Ice::OutputStream*) os;
+@end
diff --git a/objc/src/Ice/Util.h b/objc/src/Ice/Util.h
new file mode 100644
index 00000000000..ab7f0834a99
--- /dev/null
+++ b/objc/src/Ice/Util.h
@@ -0,0 +1,242 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Foundation/NSException.h>
+
+#import <objc/Ice/Config.h>
+#import <objc/Ice/Current.h>
+
+#include <IceCpp/Proxy.h>
+#include <IceCpp/Endpoint.h>
+
+#import <EndpointI.h>
+
+#include <exception>
+#include <vector>
+#include <map>
+#include <string>
+
+@class ICEAsyncResult;
+@class ICEObjectPrx;
+@class ICEException;
+@class ICEEndpoint;
+
+void cppCall(void (^fn)());
+void cppCall(void (^fn)(const Ice::Context&), ICEContext*);
+ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&), ICEObjectPrx* = nil);
+ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::CallbackPtr&),
+ void (^completed)(const Ice::AsyncResultPtr&),
+ void (^exception)(ICEException*),
+ void (^sent)(BOOL),
+ ICEObjectPrx* = nil);
+ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::Context&), ICEContext*, ICEObjectPrx* = nil);
+ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::Context&, const Ice::CallbackPtr&),
+ ICEContext*,
+ void (^completed)(const Ice::AsyncResultPtr&),
+ void (^exception)(ICEException*),
+ void (^sent)(BOOL),
+ ICEObjectPrx* = nil);
+void endCppCall(void (^fn)(const Ice::AsyncResultPtr&), ICEAsyncResult*);
+
+
+NSException* toObjCException(const std::exception&);
+void rethrowCxxException(id, bool = false);
+
+//
+// The toXXX methods don't auto release the returned object: the caller
+// must assume ownership of the returned object.
+//
+
+inline NSObject<NSCopying>* toObjC(bool v) { return [[NSNumber alloc] initWithBool:v]; }
+inline NSObject<NSCopying>* toObjC(ICEByte v) { return [[NSNumber alloc] initWithUnsignedChar:v]; }
+inline NSObject<NSCopying>* toObjC(ICEShort v) { return [[NSNumber alloc] initWithShort:v]; }
+inline NSObject<NSCopying>* toObjC(ICEInt v) { return [[NSNumber alloc] initWithInt:v]; }
+inline NSObject<NSCopying>* toObjC(ICELong v) { return [[NSNumber alloc] initWithLongLong:v]; }
+inline NSObject<NSCopying>* toObjC(ICEFloat v) { return [[NSNumber alloc] initWithFloat:v]; }
+inline NSObject<NSCopying>* toObjC(ICEDouble v) { return [[NSNumber alloc] initWithDouble:v]; }
+
+inline void fromObjC(id object, bool& v) { v = [object boolValue]; }
+inline void fromObjC(id object, ICEByte& v) { v = [object unsignedCharValue]; }
+inline void fromObjC(id object, ICEShort& v) { v = [object shortValue]; }
+inline void fromObjC(id object, ICEInt& v) { v = [object intValue];}
+inline void fromObjC(id object, ICELong& v) { v = [object longLongValue]; }
+inline void fromObjC(id object, ICEFloat& v) { v = [object floatValue]; }
+inline void fromObjC(id object, ICEDouble& v) { v = [object doubleValue]; }
+
+inline NSObject<NSCopying>*
+toObjC(const std::string& s)
+{
+ return [[NSString alloc] initWithUTF8String:s.c_str()];
+}
+
+inline void
+fromObjC(id object, std::string& s)
+{
+ s = object == [NSNull null] ? ::std::string() : [object UTF8String];
+}
+
+NSObject<NSCopying>* toObjC(const Ice::EndpointPtr& endpoint);
+void fromObjC(id object, Ice::EndpointPtr& endpoint);
+
+inline NSMutableArray*
+toNSArray(const char* arr[], size_t size)
+{
+ NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:size];
+ for(size_t i = 0; i < size; ++i)
+ {
+ NSObject* obj = [[NSString alloc] initWithUTF8String:arr[i]];
+ [array addObject:obj];
+ [obj release];
+ }
+ return array;
+}
+
+template<typename T> NSMutableArray*
+toNSArray(const std::vector<T>& seq)
+{
+ NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:seq.size()];
+ for(typename std::vector<T>::const_iterator p = seq.begin(); p != seq.end(); ++p)
+ {
+ NSObject* obj = toObjC(*p);
+ [array addObject:obj];
+ [obj release];
+ }
+ return array;
+}
+
+template<typename T> NSMutableData*
+toNSData(const std::vector<T>& seq)
+{
+ NSMutableData* array = [[NSMutableData alloc] initWithLength:seq.size() * sizeof(T)];
+ T* target = (T*)[array bytes];
+ for(typename std::vector<T>::const_iterator p = seq.begin(); p != seq.end(); ++p)
+ {
+ *target++ = *p;
+ }
+ return array;
+}
+
+template<typename T> std::vector<T>&
+fromNSArray(NSArray* array, std::vector<T>& seq)
+{
+ if(array != nil)
+ {
+ seq.reserve([array count]);
+ NSEnumerator* enumerator = [array objectEnumerator];
+ id obj = nil;
+ while((obj = [enumerator nextObject]))
+ {
+ T v;
+ fromObjC(obj, v);
+ seq.push_back(v);
+ }
+ }
+ return seq;
+}
+
+template<typename T> std::vector<T>&
+fromNSData(NSData* array, std::vector<T>& seq)
+{
+ if(array != nil)
+ {
+ int len = [array length] / sizeof(T);
+ seq.reserve(len);
+ T* src = (T*)[array bytes];
+ while(len-- > 0)
+ {
+ seq.push_back(*src++);
+ }
+ }
+ return seq;
+}
+
+template<typename K, typename V> NSMutableDictionary*
+toNSDictionary(const std::map<K, V>& dict)
+{
+ NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] initWithCapacity:dict.size()];
+ for(typename std::map<K, V>::const_iterator p = dict.begin(); p != dict.end(); ++p)
+ {
+ NSObject<NSCopying>* key = toObjC(p->first);
+ NSObject* value = toObjC(p->second);
+ [dictionary setObject:value forKey:key];
+ [key release];
+ [value release];
+ }
+ return dictionary;
+}
+
+template<typename K, typename V> std::map<K, V>&
+fromNSDictionary(NSDictionary* dictionary, std::map<K, V>& dict)
+{
+ if(dictionary != nil)
+ {
+ NSEnumerator* enumerator = [dictionary keyEnumerator];
+ id obj = nil;
+ while((obj = [enumerator nextObject]))
+ {
+ K k;
+ fromObjC(obj, k);
+ V v;
+ fromObjC([dictionary objectForKey:obj], v);
+ dict.insert(std::pair<K, V>(k, v));
+ }
+ }
+ return dict;
+}
+
+inline NSString*
+toNSString(const char* s)
+{
+ return [[NSString alloc] initWithCString:s encoding:[NSString defaultCStringEncoding]];
+}
+
+inline NSString*
+toNSString(const std::string& s)
+{
+ return [[NSString alloc] initWithUTF8String:s.c_str()];
+}
+
+inline NSMutableString*
+toNSMutableString(const std::string& s)
+{
+ return [[NSMutableString alloc] initWithUTF8String:s.c_str()];
+}
+
+inline std::string
+fromNSString(NSString* s)
+{
+ return s == nil ? std::string() : [s UTF8String];
+}
+
+std::string toObjCSliceId(const std::string&, NSDictionary*);
+
+namespace IceObjC
+{
+
+class Exception : public IceUtil::Exception
+{
+public:
+
+ Exception(id<NSObject>);
+ Exception(const Exception&);
+ virtual ~Exception() throw();
+
+ virtual std::string ice_name() const;
+ virtual void ice_print(std::ostream& os) const;
+ virtual Exception* ice_clone() const;
+ virtual void ice_throw() const;
+
+ id<NSObject> exception() const { return _ex; }
+
+private:
+
+ id<NSObject> _ex;
+};
+
+}
diff --git a/objc/src/Ice/Util.mm b/objc/src/Ice/Util.mm
new file mode 100644
index 00000000000..99bd95358ac
--- /dev/null
+++ b/objc/src/Ice/Util.mm
@@ -0,0 +1,477 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Util.h>
+#import <ExceptionI.h>
+#import <StreamI.h>
+#import <ProxyI.h>
+
+#import <objc/Ice/LocalException.h>
+
+#include <IceCpp/LocalException.h>
+#include <IceCpp/Initialize.h>
+
+#include <Block.h>
+
+#import <objc/runtime.h>
+#import <Foundation/NSAutoreleasePool.h>
+
+namespace
+{
+
+class AsyncCallback : public IceUtil::Shared
+{
+public:
+
+AsyncCallback(void (^completed)(const Ice::AsyncResultPtr&), void (^exception)(ICEException*), void (^sent)(BOOL)) :
+ _completed(Block_copy(completed)), _exception(Block_copy(exception)), _sent(Block_copy(sent))
+{
+}
+
+virtual ~AsyncCallback()
+{
+ Block_release(_completed);
+ Block_release(_exception);
+ Block_release(_sent);
+}
+
+void completed(const Ice::AsyncResultPtr& result)
+{
+ NSException* exception = nil;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ @try
+ {
+ try
+ {
+ _completed(result);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ @try
+ {
+ NSException* nsex = toObjCException(ex);
+ @throw nsex;
+ }
+ @catch(ICEException* e)
+ {
+ if(_exception)
+ {
+ _exception(e);
+ }
+ }
+ }
+ }
+ @catch(NSException* e)
+ {
+ exception = [e retain];
+ }
+ @finally
+ {
+ [pool drain];
+ }
+
+ if(exception != nil)
+ {
+ rethrowCxxException(exception, true); // True = release the exception.
+ }
+}
+
+void sent(const Ice::AsyncResultPtr& result)
+{
+ if(!_sent)
+ {
+ return;
+ }
+
+ NSException* exception = nil;
+ @autoreleasepool
+ {
+ @try
+ {
+ _sent(result->sentSynchronously());
+ }
+ @catch(NSException* e)
+ {
+ exception = [e retain];
+ }
+ }
+
+ if(exception != nil)
+ {
+ rethrowCxxException(exception, true); // True = release the exception.
+ }
+}
+
+private:
+
+void (^_completed)(const Ice::AsyncResultPtr&);
+void (^_exception)(ICEException*);
+void (^_sent)(BOOL);
+
+};
+
+};
+
+void cppCall(void (^fn)())
+{
+ NSException* nsex = nil;
+ try
+ {
+ fn();
+ return;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+void cppCall(void (^fn)(const Ice::Context&), ICEContext* context)
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Context ctx;
+ fromNSDictionary(context, ctx);
+ fn(ctx);
+ return;
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&), ICEObjectPrx* prx)
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::AsyncResultPtr r;
+ fn(r);
+ return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:nil proxy:prx];
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ nsex = [NSException exceptionWithName:NSInvalidArgumentException reason:[toNSString(ex.reason()) autorelease]
+ userInfo:nil];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::CallbackPtr&),
+ void (^completed)(const Ice::AsyncResultPtr&),
+ void (^exception)(ICEException*),
+ void (^sent)(BOOL),
+ ICEObjectPrx* prx)
+{
+ NSException* nsex = nil;
+ try
+ {
+ AsyncCallback* cb = new AsyncCallback(completed, exception, sent);
+ Ice::AsyncResultPtr r;
+ Ice::CallbackPtr callback = Ice::newCallback(cb, &AsyncCallback::completed, &AsyncCallback::sent);
+ fn(r, callback);
+ return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:nil proxy:prx];
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ nsex = [NSException exceptionWithName:NSInvalidArgumentException reason:[toNSString(ex.reason()) autorelease]
+ userInfo:nil];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::Context&),
+ ICEContext* context,
+ ICEObjectPrx* prx)
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Context ctx;
+ fromNSDictionary(context, ctx);
+ Ice::AsyncResultPtr r;
+ fn(r, ctx);
+ return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:nil proxy:prx];
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ nsex = [NSException exceptionWithName:NSInvalidArgumentException reason:[toNSString(ex.reason()) autorelease]
+ userInfo:nil];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::Context&, const Ice::CallbackPtr&),
+ ICEContext* context,
+ void (^completed)(const Ice::AsyncResultPtr&),
+ void (^exception)(ICEException*),
+ void (^sent)(BOOL),
+ ICEObjectPrx* prx)
+{
+ NSException* nsex = nil;
+ try
+ {
+ Ice::Context ctx;
+ fromNSDictionary(context, ctx);
+ AsyncCallback* cb = new AsyncCallback(completed, exception, sent);
+ Ice::AsyncResultPtr r;
+ Ice::CallbackPtr callback = Ice::newCallback(cb, &AsyncCallback::completed, &AsyncCallback::sent);
+ fn(r, ctx, callback);
+ return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:nil proxy:prx];
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ nsex = [NSException exceptionWithName:NSInvalidArgumentException reason:[toNSString(ex.reason()) autorelease]
+ userInfo:nil];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+void endCppCall(void (^fn)(const Ice::AsyncResultPtr&), ICEAsyncResult* r)
+{
+ NSException* nsex = nil;
+ try
+ {
+ fn([r asyncResult__]);
+ return;
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
+ {
+ nsex = [NSException exceptionWithName:NSInvalidArgumentException reason:[toNSString(ex.reason()) autorelease]
+ userInfo:nil];
+ }
+ catch(const std::exception& ex)
+ {
+ nsex = toObjCException(ex);
+ }
+ @throw nsex;
+}
+
+NSException*
+toObjCException(const std::exception& ex)
+{
+ NSException* nsex;
+ {
+ const Ice::LocalException* lex = dynamic_cast<const Ice::LocalException*>(&ex);
+ if(lex)
+ {
+ std::string typeId = std::string("ICE") + lex->ice_name().substr(5);
+ Class c = objc_getClass(typeId.c_str());
+ if(c != nil)
+ {
+ nsex = [c localExceptionWithLocalException:*lex];
+ }
+ else
+ {
+ Ice::UnknownLocalException ulex(__FILE__, __LINE__, ex.what());
+ nsex = [ICEUnknownLocalException localExceptionWithLocalException:ulex];
+ }
+ }
+ else
+ {
+ const Ice::UserException* uex = dynamic_cast<const Ice::UserException*>(&ex);
+ if(uex)
+ {
+ Ice::UnknownUserException uuex(__FILE__, __LINE__, ex.what());
+ nsex = [ICEUnknownUserException localExceptionWithLocalException:uuex];
+ }
+ else
+ {
+ const IceObjC::Exception* objCEx = dynamic_cast<const IceObjC::Exception*>(&ex);
+ if(objCEx)
+ {
+ id<NSObject> oex = objCEx->exception();
+ if(oex == nil)
+ {
+ nsex = [NSException exceptionWithName:@"unknown Objective-C exception"
+ reason:[NSString stringWithUTF8String:ex.what()]
+ userInfo:nil];
+ }
+ else if([oex isKindOfClass:[NSException class]])
+ {
+ nsex = [[(NSException*)oex retain] autorelease];
+ }
+ else
+ {
+ nsex = [NSException exceptionWithName:@"unknown Objective-C exception"
+ reason:[oex description]
+ userInfo:nil];
+ }
+ }
+ else
+ {
+ //
+ // std::exception from the Ice runtime are translated to NSException.
+ //
+ //Ice::UnknownException e(__FILE__, __LINE__, ex.what());
+ //nsex = [ICEUnknownException localExceptionWithLocalException:e];
+ nsex = [NSException exceptionWithName:@"std::exception"
+ reason:[NSString stringWithUTF8String:ex.what()]
+ userInfo:nil];
+ }
+ }
+ }
+ }
+ return nsex;
+}
+
+void
+rethrowCxxException(id e, bool release)
+{
+ @try
+ {
+ @throw e;
+ }
+ @catch(ICEUserException* ex)
+ {
+ Ice::UnknownUserException uuex(__FILE__, __LINE__, fromNSString([ex description]));
+ if(release)
+ {
+ [ex release];
+ }
+ throw uuex;
+ }
+ @catch(ICELocalException* ex)
+ {
+ if(release)
+ {
+ try
+ {
+ [ex rethrowCxx];
+ }
+ catch(const std::exception&)
+ {
+ [ex release];
+ throw;
+ }
+ }
+ else
+ {
+ [ex rethrowCxx];
+ }
+ }
+ @catch(id ex)
+ {
+ if([ex conformsToProtocol:@protocol(NSObject)])
+ {
+ IceObjC::Exception exo(ex);
+ if(release)
+ {
+ [ex release];
+ }
+ throw exo;
+ }
+ else
+ {
+ throw IceObjC::Exception(nil);
+ }
+ }
+}
+
+std::string
+toObjCSliceId(const std::string& sliceId, NSDictionary* prefixTable)
+{
+ std::string objcType = sliceId;
+
+ if(objcType.find("::Ice::") == 0)
+ {
+ return objcType.replace(0, 7, "ICE");
+ }
+
+ std::string::size_type pos = objcType.rfind("::");
+ if(pos != std::string::npos)
+ {
+ NSString* moduleName = toNSString(objcType.substr(0, pos));
+ NSString* prefix = [prefixTable objectForKey:moduleName];
+ [moduleName release];
+ if(prefix)
+ {
+ return objcType.replace(0, pos + 2, fromNSString(prefix));
+ }
+ }
+
+ while((pos = objcType.find("::")) != std::string::npos)
+ {
+ objcType = objcType.replace(pos, 2, "");
+ }
+ return objcType;
+}
+
+IceObjC::Exception::Exception(id<NSObject> ex) : _ex([ex retain])
+{
+}
+
+IceObjC::Exception::Exception(const IceObjC::Exception& ex) : _ex([ex._ex retain])
+{
+}
+
+IceObjC::Exception::~Exception() throw()
+{
+ [_ex release];
+}
+
+std::string
+IceObjC::Exception::ice_name() const
+{
+ return "IceObjC::Exception";
+}
+
+void
+IceObjC::Exception::ice_print(std::ostream& os) const
+{
+ IceUtil::Exception::ice_print(os);
+ if(_ex != nil)
+ {
+ os << ":\n" << fromNSString([_ex description]);
+ }
+}
+
+IceObjC::Exception*
+IceObjC::Exception::ice_clone() const
+{
+ return new Exception(*this);
+}
+
+void
+IceObjC::Exception::ice_throw() const
+{
+ throw *this;
+}
+
+NSObject<NSCopying>*
+toObjC(const Ice::EndpointPtr& endpoint)
+{
+ return [ICEEndpoint wrapperWithCxxObjectNoAutoRelease:endpoint.get()];
+}
+
+void
+fromObjC(id object, Ice::EndpointPtr& endpoint)
+{
+ endpoint = object == [NSNull null] ? 0 : [object endpoint];
+}
diff --git a/objc/src/Ice/VersionI.h b/objc/src/Ice/VersionI.h
new file mode 100644
index 00000000000..01b13e416dc
--- /dev/null
+++ b/objc/src/Ice/VersionI.h
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Version.h>
+
+#include <IceCpp/Version.h>
+
+@interface ICEProtocolVersion (ICEInternal)
++(void) load;
+-(ICEProtocolVersion*)initWithProtocolVersion:(const Ice::ProtocolVersion&)arg;
+-(Ice::ProtocolVersion)protocolVersion;
++(ICEProtocolVersion*)protocolVersionWithProtocolVersion:(const Ice::ProtocolVersion&)arg;
+@end
+
+@interface ICEEncodingVersion (ICEInternal)
++(void) load;
+-(ICEEncodingVersion*)initWithEncodingVersion:(const Ice::EncodingVersion&)arg;
+-(Ice::EncodingVersion)encodingVersion;
++(ICEEncodingVersion*)encodingVersionWithEncodingVersion:(const Ice::EncodingVersion&)arg;
+@end
+
diff --git a/objc/src/Ice/VersionI.mm b/objc/src/Ice/VersionI.mm
new file mode 100644
index 00000000000..762e82fb699
--- /dev/null
+++ b/objc/src/Ice/VersionI.mm
@@ -0,0 +1,127 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <VersionI.h>
+#import <Util.h>
+
+ICEEncodingVersion* ICEEncoding_1_0;
+ICEEncodingVersion* ICEEncoding_1_1;
+ICEEncodingVersion* ICECurrentEncoding;
+
+@implementation ICEEncodingVersion (ICEInternal)
+
++(void) load
+{
+ ICEEncoding_1_0 = [[ICEEncodingVersion alloc] init:1 minor:0];
+ ICEEncoding_1_1 = [[ICEEncodingVersion alloc] init:1 minor:1];
+ ICECurrentEncoding = [[ICEEncodingVersion alloc] init:IceInternal::encodingMajor minor:IceInternal::encodingMinor];
+}
+
+-(ICEEncodingVersion*) initWithEncodingVersion:(const Ice::EncodingVersion&)arg
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ major = arg.major;
+ minor = arg.minor;
+ return self;
+}
+
+-(Ice::EncodingVersion) encodingVersion
+{
+ Ice::EncodingVersion v;
+ v.major = major;
+ v.minor = minor;
+ return v;
+}
+
++(ICEEncodingVersion*) encodingVersionWithEncodingVersion:(const Ice::EncodingVersion&)arg
+{
+ if(arg == Ice::Encoding_1_0)
+ {
+ return ICEEncoding_1_0;
+ }
+ else if(arg == Ice::Encoding_1_1)
+ {
+ return ICEEncoding_1_1;
+ }
+ else if(arg == Ice::currentEncoding)
+ {
+ return ICECurrentEncoding;
+ }
+ else
+ {
+ return [[[ICEEncodingVersion alloc] initWithEncodingVersion:arg] autorelease];
+ }
+}
+
+-(NSString*) description
+{
+ return [toNSString(Ice::encodingVersionToString([self encodingVersion])) autorelease];
+}
+@end
+
+
+ICEProtocolVersion* ICEProtocol_1_0;
+ICEProtocolVersion* ICECurrentProtocol;
+ICEEncodingVersion* ICECurrentProtocolEncoding;
+
+@implementation ICEProtocolVersion (ICEInternal)
+
++(void) load
+{
+ ICEProtocol_1_0 = [[ICEProtocolVersion alloc] init:1 minor:0];
+ ICECurrentProtocol = [[ICEProtocolVersion alloc] init:IceInternal::protocolMajor minor:IceInternal::protocolMinor];
+ ICECurrentProtocolEncoding = [[ICEEncodingVersion alloc] init:IceInternal::protocolEncodingMajor
+ minor:IceInternal::protocolEncodingMinor];
+}
+
+-(ICEProtocolVersion*) initWithProtocolVersion:(const Ice::ProtocolVersion&)arg
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ major = arg.major;
+ minor = arg.minor;
+ return self;
+}
+
+-(Ice::ProtocolVersion) protocolVersion
+{
+ Ice::ProtocolVersion v;
+ v.major = major;
+ v.minor = minor;
+ return v;
+}
+
++(ICEProtocolVersion*) protocolVersionWithProtocolVersion:(const Ice::ProtocolVersion&)arg
+{
+ if(arg == Ice::Protocol_1_0)
+ {
+ return ICEProtocol_1_0;
+ }
+ else if(arg == Ice::currentProtocol)
+ {
+ return ICECurrentProtocol;
+ }
+ else
+ {
+ return [[[ICEProtocolVersion alloc] initWithProtocolVersion:arg] autorelease];
+ }
+}
+
+-(NSString*) description
+{
+ return [toNSString(Ice::protocolVersionToString([self protocolVersion])) autorelease];
+}
+@end
diff --git a/objc/src/Ice/Wrapper.h b/objc/src/Ice/Wrapper.h
new file mode 100644
index 00000000000..53d4d2b512c
--- /dev/null
+++ b/objc/src/Ice/Wrapper.h
@@ -0,0 +1,32 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice/Config.h>
+
+namespace IceUtil
+{
+class Shared;
+}
+
+@interface ICEInternalWrapper : NSObject
+{
+ void* cxxObject_;
+}
+-(id) initWithCxxObject:(IceUtil::Shared*)arg;
+
+//
+// Note: the returned object is NOT retained. It must be held
+// some other way by the calling thread.
+//
++(id) getWrapperWithCxxObjectNoAutoRelease:(IceUtil::Shared*)arg;
+
++(id) wrapperWithCxxObjectNoAutoRelease:(IceUtil::Shared*)arg;
++(id) wrapperWithCxxObject:(IceUtil::Shared*)arg;
+-(IceUtil::Shared*) cxxObject;
+@end
diff --git a/objc/src/Ice/Wrapper.mm b/objc/src/Ice/Wrapper.mm
new file mode 100644
index 00000000000..7bdb91670d8
--- /dev/null
+++ b/objc/src/Ice/Wrapper.mm
@@ -0,0 +1,258 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Wrapper.h>
+
+//
+// Using NSMapTable is necessary for this code to work properly with GC.
+// We could also use NSMapTable on MacOS without GC, however,
+// it's preferable to use the same code for non-GC on MacOS and other platforms
+//
+// #if defined(ICE_OBJC_GC) || !TARGET_OS_IPHONE
+//
+#ifdef ICE_OBJC_GC
+ #define ICE_USE_MAP_TABLE 1
+#endif
+
+#ifdef ICE_USE_MAP_TABLE
+ #import <Foundation/NSMapTable.h>
+#else
+ #include <map>
+#endif
+
+#include <IceUtilCpp/Shared.h>
+#include <Foundation/Foundation.h>
+
+#define CXXOBJECT ((IceUtil::Shared*)cxxObject_)
+
+#ifndef ICE_USE_MAP_TABLE
+namespace
+{
+
+std::map<IceUtil::Shared*, ICEInternalWrapper*>* cachedObjects = 0;
+
+class Init
+{
+public:
+
+ Init()
+ {
+ cachedObjects = new std::map<IceUtil::Shared*, ICEInternalWrapper*>;
+ }
+
+ ~Init()
+ {
+ delete cachedObjects;
+ }
+};
+
+Init init;
+}
+#endif
+
+
+@implementation ICEInternalWrapper
+
+#ifdef ICE_USE_MAP_TABLE
+//
+// mapTable singleton
+//
++(NSMapTable*) mapTable
+{
+ static NSMapTable* instance;
+ @synchronized(self)
+ {
+ if(instance == 0)
+ {
+ //
+ // Unfortunately the values we use are not very well documented, and small variations
+ // (like using the opaque pointer memory personality for keys) introduces strange bugs
+ //
+ instance = [NSMapTable
+ mapTableWithKeyOptions:NSPointerFunctionsOpaquePersonality
+ valueOptions:NSMapTableZeroingWeakMemory];
+
+ CFRetain(instance); // leak it!
+ }
+ }
+ return instance;
+}
+#endif
+
+-(id) initWithCxxObject:(IceUtil::Shared*)arg
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cxxObject_ = arg;
+ CXXOBJECT->__incRef();
+
+#ifdef ICE_USE_MAP_TABLE
+ //
+ // No synchronization because initWithCxxObject is always called with mapTable locked, see below
+ //
+ NSMapTable* mapTable = [ICEInternalWrapper mapTable];
+ void* result = NSMapInsertIfAbsent(mapTable, arg, self);
+ // COMPILERFIX: NSMapTable bug where the entry sometime doesn't get properly
+ // added. Adding it a second time works.
+ if(NSMapGet(mapTable, arg) == 0)
+ {
+ result = NSMapInsertIfAbsent([ICEInternalWrapper mapTable], arg, self);
+ }
+ assert(result == 0);
+#else
+ //
+ // No synchronization because initWithCxxObject is always called with the wrapper class object locked
+ //
+ assert(cachedObjects->find(CXXOBJECT) == cachedObjects->end());
+ cachedObjects->insert(std::make_pair(CXXOBJECT, self));
+#endif
+
+ return self;
+}
+
+-(IceUtil::Shared*) cxxObject
+{
+ return CXXOBJECT;
+}
+
+-(void) dealloc
+{
+
+#ifdef ICE_USE_MAP_TABLE
+ //
+ // No synchronization because dealloc is always called with
+ // mapTable locked, see below
+ //
+ NSMapRemove([ICEInternalWrapper mapTable], cxxObject_);
+#else
+ //
+ // No synchronization because dealloc is always called with the wrapper class object locked
+ //
+ cachedObjects->erase(CXXOBJECT);
+#endif
+
+ CXXOBJECT->__decRef();
+ cxxObject_ = 0;
+ [super dealloc];
+}
+
+#ifdef ICE_USE_MAP_TABLE
+//
+// No GC and therefore finalize without the MapTable!
+//
+-(void) finalize
+{
+ assert(cxxObject_ != 0);
+ CXXOBJECT->__decRef();
+ cxxObject_ = 0;
+ [super finalize];
+}
+#endif
+
++(id) getWrapperWithCxxObjectNoAutoRelease:(IceUtil::Shared*)arg
+{
+ //
+ // Note: the returned object is NOT retained. It must be held
+ // some other way by the calling thread.
+ //
+
+ if(arg == 0)
+ {
+ return nil;
+ }
+
+#ifdef ICE_USE_MAP_TABLE
+ NSMapTable* mapTable = [ICEInternalWrapper mapTable];
+ @synchronized(mapTable)
+ {
+ id val = (id)NSMapGet(mapTable, arg);
+ return val;
+ }
+#else
+ @synchronized([ICEInternalWrapper class])
+ {
+ std::map<IceUtil::Shared*, ICEInternalWrapper*>::const_iterator p = cachedObjects->find(arg);
+ if(p != cachedObjects->end())
+ {
+ return p->second;
+ }
+ }
+#endif
+ return nil;
+}
+
++(id) wrapperWithCxxObjectNoAutoRelease:(IceUtil::Shared*)arg
+{
+ if(arg == 0)
+ {
+ return nil;
+ }
+
+#ifdef ICE_USE_MAP_TABLE
+ NSMapTable* mapTable = [ICEInternalWrapper mapTable];
+ @synchronized(mapTable)
+ {
+ id val = (id)NSMapGet(mapTable, arg);
+
+ if(val == nil)
+ {
+ return [[self alloc] initWithCxxObject:arg];
+ }
+ else
+ {
+ return [val retain];
+ }
+ }
+#else
+ @synchronized([ICEInternalWrapper class])
+ {
+ std::map<IceUtil::Shared*, ICEInternalWrapper*>::const_iterator p = cachedObjects->find(arg);
+ if(p != cachedObjects->end())
+ {
+ return [p->second retain];
+ }
+ else
+ {
+ return [[self alloc] initWithCxxObject:arg];
+ }
+ }
+#endif
+ return nil; // Keep the compiler happy.
+}
+
++(id) wrapperWithCxxObject:(IceUtil::Shared*)arg
+{
+ return [[self wrapperWithCxxObjectNoAutoRelease:arg] autorelease];
+}
+
+
+-(id) retain
+{
+ NSIncrementExtraRefCount(self);
+ return self;
+}
+
+-(oneway void) release
+{
+#ifdef ICE_USE_MAP_TABLE
+ @synchronized([ICEInternalWrapper mapTable])
+#else
+ @synchronized([ICEInternalWrapper class])
+#endif
+ {
+ if(NSDecrementExtraRefCountWasZero(self))
+ {
+ [self dealloc];
+ }
+ }
+}
+@end
diff --git a/objc/src/IceGrid/.gitignore b/objc/src/IceGrid/.gitignore
new file mode 100644
index 00000000000..1d8a22c0997
--- /dev/null
+++ b/objc/src/IceGrid/.gitignore
@@ -0,0 +1,28 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+.depend
+Admin.m
+Descriptor.m
+Discovery.m
+Exception.m
+FileParser.m
+Locator.m
+Observer.m
+PluginFacade.m
+Query.m
+Registry.m
+Session.m
+UserAccountMapper.m
+Admin.h
+Descriptor.h
+Discovery.h
+Exception.h
+FileParser.h
+Locator.h
+Observer.h
+PluginFacade.h
+Query.h
+Registry.h
+Session.h
+UserAccountMapper.h
diff --git a/objc/src/IceGrid/Makefile b/objc/src/IceGrid/Makefile
new file mode 100644
index 00000000000..a314c048157
--- /dev/null
+++ b/objc/src/IceGrid/Makefile
@@ -0,0 +1,56 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+LIBFILENAME = $(call mklibfilename,IceGridObjC,$(VERSION))
+SONAME = $(call mksoname,IceGridObjC,$(SOVERSION))
+LIBNAME = $(call mklibname,IceGridObjC)
+
+TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME))
+
+SLICE_OBJS = Admin.o \
+ Descriptor.o \
+ Discovery.o \
+ Exception.o \
+ FileParser.o \
+ Locator.o \
+ Observer.o \
+ PluginFacade.o \
+ Query.o \
+ Registry.o \
+ Session.o \
+ UserAccountMapper.o
+
+OBJS = $(SLICE_OBJS)
+
+HDIR = $(headerdir)/objc/IceGrid
+SDIR = $(slicedir)/IceGrid
+
+include $(top_srcdir)/config/Make.rules
+
+SLICE2OBJCFLAGS := --ice --include-dir objc/IceGrid $(SLICE2OBJCFLAGS)
+LINKWITH := -lGlacier2ObjC $(LIBS)
+
+$(libdir)/$(LIBFILENAME): $(OBJS)
+ @mkdir -p $(dir $@)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH))
+
+$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME)
+ rm -f $@
+ ln -s $(LIBFILENAME) $@
+
+$(libdir)/$(LIBNAME): $(libdir)/$(SONAME)
+ @mkdir -p $(libdir)
+ rm -f $@
+ ln -s $(SONAME) $@
+
+install:: all
+ $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME))
diff --git a/objc/src/IceStorm/.gitignore b/objc/src/IceStorm/.gitignore
new file mode 100644
index 00000000000..166500719d4
--- /dev/null
+++ b/objc/src/IceStorm/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+.depend
+Metrics.m
+IceStorm.m
+Metrics.h
+IceStorm.h
diff --git a/objc/src/IceStorm/Makefile b/objc/src/IceStorm/Makefile
new file mode 100644
index 00000000000..2e4d1abefb6
--- /dev/null
+++ b/objc/src/IceStorm/Makefile
@@ -0,0 +1,45 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+LIBFILENAME = $(call mklibfilename,IceStormObjC,$(VERSION))
+SONAME = $(call mksoname,IceStormObjC,$(SOVERSION))
+LIBNAME = $(call mklibname,IceStormObjC)
+
+TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME))
+
+SLICE_OBJS = Metrics.o \
+ IceStorm.o
+
+OBJS = $(SLICE_OBJS)
+
+HDIR = $(headerdir)/objc/IceStorm
+SDIR = $(slicedir)/IceStorm
+
+include $(top_srcdir)/config/Make.rules
+
+SLICE2OBJCFLAGS := --ice --include-dir objc/IceStorm $(SLICE2OBJCFLAGS)
+
+$(libdir)/$(LIBFILENAME): $(OBJS)
+ @mkdir -p $(dir $@)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(OBJS),$(LIBS))
+
+$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME)
+ rm -f $@
+ ln -s $(LIBFILENAME) $@
+
+$(libdir)/$(LIBNAME): $(libdir)/$(SONAME)
+ @mkdir -p $(libdir)
+ rm -f $@
+ ln -s $(SONAME) $@
+
+install:: all
+ $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME))
diff --git a/objc/src/Makefile b/objc/src/Makefile
new file mode 100644
index 00000000000..b0bc669c5af
--- /dev/null
+++ b/objc/src/Makefile
@@ -0,0 +1,40 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = Ice Glacier2 IceStorm IceGrid
+
+.PHONY: $(EVERYTHING) $(SUBDIRS)
+
+#
+# Dependencies for 'all' target when using -jx
+#
+
+Glacier2 IceStorm IceGrid: Ice
+
+IceGrid: Glacier2
+
+all:: $(SUBDIRS)
+
+$(SUBDIRS):
+ @echo "making all in $@"
+ @$(MAKE) all --directory=$@
+
+$(EVERYTHING_EXCEPT_ALL)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ if test -d $$subdir ; \
+ then \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ fi; \
+ done
diff --git a/objc/test/Common/.gitignore b/objc/test/Common/.gitignore
new file mode 100644
index 00000000000..3a412ca89c7
--- /dev/null
+++ b/objc/test/Common/.gitignore
@@ -0,0 +1,4 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+.depend
diff --git a/objc/test/Common/Makefile b/objc/test/Common/Makefile
new file mode 100644
index 00000000000..ae5bd29f922
--- /dev/null
+++ b/objc/test/Common/Makefile
@@ -0,0 +1,50 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+LIBNAME = $(call mklibname,TestCommon)
+
+TARGETS = ../../lib/$(LIBNAME)
+
+OBJS = TestCommon.o
+
+SRCS := $(OBJS:.o=.m)
+DEPENDFLAGS = --obj-dir
+
+include $(top_srcdir)/config/Make.rules
+
+ifeq ($(STATICLIBS),yes)
+ mklibname = lib$(1).a
+else
+ mklibname = lib$(1).dylib
+endif
+
+OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
+
+CPPFLAGS := -I../include $(CPPFLAGS)
+
+ifeq ($(STATICLIBS),yes)
+
+../../lib/$(LIBNAME): $(OBJS)
+ rm -f $@
+ $(call mklib,$@,$(OBJS))
+
+else
+
+../../lib/$(LIBNAME): $(OBJS)
+ rm -f $@
+ $(call mkshlib,$@,$(LIBNAME),$(OBJS),$(LIBS))
+
+endif
+
+$(OBJDIR)/%.o: %.m
+ $(CC) -c $(CPPFLAGS) $(OBJCFLAGS) $(CFLAGS) $< -o $@
+
+
diff --git a/objc/test/Common/TestCommon.m b/objc/test/Common/TestCommon.m
new file mode 100644
index 00000000000..69cd7e9c4ff
--- /dev/null
+++ b/objc/test/Common/TestCommon.m
@@ -0,0 +1,251 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <TestCommon.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#import <objc/Ice.h>
+
+@implementation TestFailedException
+-(id)init
+{
+ return [super initWithName:@"TestFailedException" reason:nil userInfo:nil];
+}
+@end
+
+#if TARGET_OS_IPHONE
+
+#import <Foundation/NSString.h>
+#import <Foundation/NSObject.h>
+#import <Foundation/NSThread.h>
+
+#include <Ice/Ice.h>
+
+static id outputTarget;
+static id testRun;
+static SEL readySelector;
+static SEL outputSelector;
+static id<ICECommunicator> communicator = nil;
+static BOOL ssl;
+
+static BOOL sliced;
+static BOOL encoding10;
+
+#endif
+
+id<ICEProperties>
+defaultServerProperties(int *argc, char** argv)
+{
+ id<ICEProperties> properties = [ICEUtil createProperties];
+
+#if TARGET_OS_IPHONE
+ static NSString* defaults[] =
+ {
+ @"Ice.NullHandleAbort", @"1",
+ @"Ice.Warn.Connections", @"1",
+ @"Ice.ThreadPool.Server.Size", @"1",
+ @"Ice.ThreadPool.Server.SizeMax", @"3",
+ @"Ice.ThreadPool.Server.SizeWarn", @"0",
+ //@"Ice.PrintAdapterReady", @"1",
+ @"Ice.ServerIdleTime", @"30",
+ @"Ice.Default.Host", @"127.0.0.1",
+ @"Ice.Trace.Network", @"0",
+ @"Ice.Trace.Protocol", @"0"
+ };
+
+ static NSString* ssldefaults[] =
+ {
+ @"Ice.Default.Protocol", @"ssl",
+ @"Ice.Override.ConnectTimeout", @"10000", // COMPILERFIX: Workaround for SSL hang on iOS devices
+ @"IceSSL.CertAuthFile", @"cacert.der",
+ @"IceSSL.CheckCertName", @"0",
+ @"IceSSL.CertFile", @"s_rsa1024.pfx",
+ @"IceSSL.Password", @"password"
+ };
+
+ int i;
+ for(i = 0; i < sizeof(defaults)/sizeof(defaults[0]); i += 2)
+ {
+ [properties setProperty:defaults[i] value:defaults[i+1]];
+ }
+ if(ssl)
+ {
+ for(i = 0; i < sizeof(ssldefaults)/sizeof(ssldefaults[0]); i += 2)
+ {
+ [properties setProperty:ssldefaults[i] value:ssldefaults[i+1]];
+ }
+ }
+
+ if(sliced)
+ {
+ [properties setProperty:@"Ice.Default.SlicedFormat" value:@"1"];
+ }
+ else if(encoding10)
+ {
+ [properties setProperty:@"Ice.Default.EncodingVersion" value:@"1.0"];
+ }
+#endif
+
+ NSArray* args = [properties parseIceCommandLineOptions:[ICEUtil argsToStringSeq:*argc argv:argv]];
+ [ICEUtil stringSeqToArgs:args argc:argc argv:argv];
+
+ return properties;
+}
+
+id<ICEProperties>
+defaultClientProperties(int* argc, char** argv)
+{
+ id<ICEProperties> properties = [ICEUtil createProperties];
+
+#if TARGET_OS_IPHONE
+ static NSString* defaults[] =
+ {
+ @"Ice.NullHandleAbort", @"1",
+ @"Ice.Warn.Connections", @"1",
+ @"Ice.Default.Host", @"127.0.0.1",
+ @"Ice.Trace.Network", @"0",
+ @"Ice.Trace.Protocol", @"0"
+ };
+
+ static NSString* ssldefaults[] =
+ {
+ @"Ice.Default.Protocol", @"ssl",
+ @"Ice.Override.ConnectTimeout", @"10000", // COMPILERFIX: Workaround for SSL hang on iOS devices
+ @"IceSSL.CheckCertName", @"0",
+ @"IceSSL.CertAuthFile", @"cacert.der",
+ @"IceSSL.CertFile", @"c_rsa1024.pfx",
+ @"IceSSL.Password", @"password",
+ @"IceSSL.TrustOnly.Client", @"25 9D 03 60 D5 6D 46 3C 32 EE FE 54 48 7A 76 68 FF 6A 87 1D"
+ };
+
+ int i;
+ for(i = 0; i < sizeof(defaults)/sizeof(defaults[0]); i += 2)
+ {
+ [properties setProperty:defaults[i] value:defaults[i+1]];
+ }
+
+ if(ssl)
+ {
+ for(i = 0; i < sizeof(ssldefaults)/sizeof(ssldefaults[0]); i += 2)
+ {
+ [properties setProperty:ssldefaults[i] value:ssldefaults[i+1]];
+ }
+ }
+ if(sliced)
+ {
+ [properties setProperty:@"Ice.Default.SlicedFormat" value:@""];
+ }
+ else if(encoding10)
+ {
+ [properties setProperty:@"Ice.Default.EncodingVersion" value:@"1.0"];
+ }
+#endif
+
+ NSArray* args = [properties parseIceCommandLineOptions:[ICEUtil argsToStringSeq:*argc argv:argv]];
+ [ICEUtil stringSeqToArgs:args argc:argc argv:argv];
+ return properties;
+}
+
+#if TARGET_OS_IPHONE
+
+void
+TestCommonInit(id target, SEL output)
+{
+ outputTarget = target;
+ outputSelector = output;
+}
+
+void
+TestCommonTestInit(id r, SEL ready, BOOL s, BOOL sl, BOOL e10)
+{
+ testRun = r;
+ readySelector = ready;
+ ssl = s;
+ sliced = sl;
+ encoding10 = e10;
+}
+
+void
+serverReady(id<ICECommunicator> c)
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [communicator release];
+ communicator = [c retain];
+#else
+ communicator = c;
+#endif
+ [testRun performSelectorOnMainThread:readySelector withObject:nil waitUntilDone:NO];
+}
+
+void
+serverStop()
+{
+ [communicator shutdown];
+}
+
+void
+tprintf(const char* fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+#if defined(__clang__) && !__has_feature(objc_arc)
+ NSString* s = [[[NSString alloc] initWithFormat:[NSString stringWithCString:fmt encoding:NSUTF8StringEncoding]
+ arguments:va] autorelease];
+#else
+ NSString* s = [[NSString alloc] initWithFormat:[NSString stringWithCString:fmt encoding:NSUTF8StringEncoding]
+ arguments:va];
+
+#endif
+ va_end(va);
+ [outputTarget performSelectorOnMainThread:outputSelector withObject:s waitUntilDone:NO];
+}
+
+void
+testFailed(const char* expr, const char* file, unsigned int line)
+{
+ tprintf("failed!\n");
+ tprintf("%s:%u: assertion `%s' failed\n", file, line, expr);
+#if defined(__clang__) && !__has_feature(objc_arc)
+ @throw [[[TestFailedException alloc] init] autorelease];
+#else
+ @throw [[TestFailedException alloc] init];
+#endif
+}
+
+#else
+
+#include <stdio.h>
+
+void
+tprintf(const char* fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+ NSString* s = [[[NSString alloc] initWithFormat:[NSString stringWithCString:fmt encoding:NSUTF8StringEncoding]
+ arguments:va] autorelease];
+ va_end(va);
+ fputs([s UTF8String], stdout);
+ fflush(stdout);
+}
+
+void
+serverReady(id<ICECommunicator> c)
+{
+}
+
+void
+testFailed(const char* expr, const char* file, unsigned int line)
+{
+ tprintf("failed!\n");
+ tprintf("%s:%u: assertion `%s' failed\n", file, line, expr);
+ abort();
+}
+#endif
diff --git a/objc/test/Ice/Makefile b/objc/test/Ice/Makefile
new file mode 100644
index 00000000000..a4a3f4f6c62
--- /dev/null
+++ b/objc/test/Ice/Makefile
@@ -0,0 +1,47 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = proxy \
+ ami \
+ operations \
+ exceptions \
+ inheritance \
+ facets \
+ objects \
+ optional \
+ interceptor \
+ invoke \
+ dispatcher \
+ defaultServant \
+ defaultValue \
+ enums \
+ faultTolerance \
+ location \
+ adapterDeactivation \
+ slicing \
+ binding \
+ hold \
+ retry \
+ stream \
+ timeout \
+ hash \
+ info \
+ metrics \
+ services
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/test/Ice/adapterDeactivation/.gitignore b/objc/test/Ice/adapterDeactivation/.gitignore
new file mode 100644
index 00000000000..4027eaac940
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+AdapterDeactivationTest.m
+AdapterDeactivationTest.h
diff --git a/objc/test/Ice/adapterDeactivation/AdapterDeactivationTest.ice b/objc/test/Ice/adapterDeactivation/AdapterDeactivationTest.ice
new file mode 100644
index 00000000000..e7dee062747
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/AdapterDeactivationTest.ice
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestAdapterDeactivation"]
+module Test
+{
+
+interface TestIntf
+{
+ void transient();
+
+ void deactivate();
+};
+
+};
diff --git a/objc/test/Ice/adapterDeactivation/AllTests.m b/objc/test/Ice/adapterDeactivation/AllTests.m
new file mode 100644
index 00000000000..31714ecd975
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/AllTests.m
@@ -0,0 +1,70 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <AdapterDeactivationTest.h>
+
+id<TestAdapterDeactivationTestIntfPrx>
+adapterDeactivationAllTests(id<ICECommunicator> communicator)
+{
+ tprintf("testing stringToProxy... ");
+ id<ICEObjectPrx> base = [communicator stringToProxy:@"test:default -p 12010"];
+ test(base);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestAdapterDeactivationTestIntfPrx> obj = [TestAdapterDeactivationTestIntfPrx checkedCast:base];
+ test(obj);
+ test([obj isEqual:base]);
+ tprintf("ok\n");
+
+ {
+ tprintf("creating/destroying/recreating object adapter... ");
+ id<ICEObjectAdapter> adapter =
+ [communicator createObjectAdapterWithEndpoints:@"TransientTestAdapter" endpoints:@"default -p 9999"];
+ @try
+ {
+ [communicator createObjectAdapterWithEndpoints:@"TransientTestAdapter" endpoints:@"default -p 9998"];
+ test(NO);
+ }
+ @catch(ICEAlreadyRegisteredException*)
+ {
+ }
+ [adapter destroy];
+
+ //
+ // Use a different port than the first adapter to avoid an @"address already in use" error.
+ //
+ adapter = [communicator createObjectAdapterWithEndpoints:@"TransientTestAdapter" endpoints:@"default -p 9998"];
+ [adapter destroy];
+ tprintf("ok\n");
+ }
+
+ tprintf("creating/activating/deactivating object adapter in one operation... ");
+ [obj transient];
+ tprintf("ok\n");
+
+ tprintf("deactivating object adapter in the server... ");
+ [obj deactivate];
+ tprintf("ok\n");
+
+ tprintf("testing whether server is gone... ");
+ @try
+ {
+ [obj ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ tprintf("ok\n");
+ }
+
+ return obj;
+}
diff --git a/objc/test/Ice/adapterDeactivation/Client.m b/objc/test/Ice/adapterDeactivation/Client.m
new file mode 100644
index 00000000000..862dd0ceb9d
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/Client.m
@@ -0,0 +1,76 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <AdapterDeactivationTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestAdapterDeactivationTestIntfPrx> adapterDeactivationAllTests(id<ICECommunicator>);
+ adapterDeactivationAllTests(communicator);
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main adapterDeactivationClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestAdapterDeactivation", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/adapterDeactivation/Makefile b/objc/test/Ice/adapterDeactivation/Makefile
new file mode 100644
index 00000000000..aad957767db
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = AdapterDeactivationTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/adapterDeactivation/Server.m b/objc/test/Ice/adapterDeactivation/Server.m
new file mode 100644
index 00000000000..e22da9b9f29
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/Server.m
@@ -0,0 +1,82 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <adapterDeactivation/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adapter add:[[[TestAdapterDeactivationI alloc] init] autorelease] identity:[communicator stringToIdentity:@"test"]];
+#else
+ [adapter add:[[TestAdapterDeactivationI alloc] init] identity:[communicator stringToIdentity:@"test"]];
+#endif
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [adapter waitForDeactivate];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main adapterDeactivationServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestAdapterDeactivation", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/adapterDeactivation/TestI.h b/objc/test/Ice/adapterDeactivation/TestI.h
new file mode 100644
index 00000000000..d6427154cfb
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/TestI.h
@@ -0,0 +1,15 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <AdapterDeactivationTest.h>
+
+@interface TestAdapterDeactivationI : TestAdapterDeactivationTestIntf<TestAdapterDeactivationTestIntf>
+-(void) transient:(ICECurrent*)current;
+-(void) deactivate:(ICECurrent*)current;
+@end
diff --git a/objc/test/Ice/adapterDeactivation/TestI.m b/objc/test/Ice/adapterDeactivation/TestI.m
new file mode 100644
index 00000000000..40b8ba8b849
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/TestI.m
@@ -0,0 +1,31 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <adapterDeactivation/TestI.h>
+
+#import <Foundation/NSThread.h>
+
+@implementation TestAdapterDeactivationI
+
+-(void) transient:(ICECurrent*)current
+{
+ id<ICECommunicator> communicator = [current.adapter getCommunicator];
+ id<ICEObjectAdapter> adapter =
+ [communicator createObjectAdapterWithEndpoints:@"TransientTestAdapter" endpoints:@"default -p 9999"];
+ [adapter activate];
+ [adapter destroy];
+}
+
+-(void) deactivate:(ICECurrent*)current
+{
+ [current.adapter deactivate];
+ [NSThread sleepForTimeInterval:1];
+}
+@end
diff --git a/objc/test/Ice/adapterDeactivation/run.py b/objc/test/Ice/adapterDeactivation/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/adapterDeactivation/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/ami/.gitignore b/objc/test/Ice/ami/.gitignore
new file mode 100644
index 00000000000..0c850ff8ce7
--- /dev/null
+++ b/objc/test/Ice/ami/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+AMITest.m
+AMITest.h
diff --git a/objc/test/Ice/ami/AMITest.ice b/objc/test/Ice/ami/AMITest.ice
new file mode 100644
index 00000000000..43feb67be75
--- /dev/null
+++ b/objc/test/Ice/ami/AMITest.ice
@@ -0,0 +1,41 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/BuiltinSequences.ice>
+
+["objc:prefix:TestAMI"]
+module Test
+{
+
+exception TestIntfException
+{
+};
+
+interface TestIntf
+{
+ void op();
+ void opWithPayload(Ice::ByteSeq seq);
+ int opWithResult();
+ void opWithUE()
+ throws TestIntfException;
+ void opBatch();
+ int opBatchCount();
+ bool waitForBatch(int count);
+ void shutdown();
+};
+
+interface TestIntfController
+{
+ void holdAdapter();
+ void resumeAdapter();
+};
+
+};
diff --git a/objc/test/Ice/ami/AllTests.m b/objc/test/Ice/ami/AllTests.m
new file mode 100644
index 00000000000..99c0ef5c944
--- /dev/null
+++ b/objc/test/Ice/ami/AllTests.m
@@ -0,0 +1,760 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <AMITest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface TestAMICallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+}
+-(BOOL) check;
+-(void) called;
+@end
+
+@implementation TestAMICallback
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(BOOL) check
+{
+ [cond lock];
+ while(!called)
+ {
+ if(![cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:50]])
+ {
+ return NO;
+ }
+ }
+ called = NO;
+ [cond unlock];
+ return YES;
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+
++(id) create
+{
+#if defined(__clang__) && __has_feature(objc_arc)
+ return [[TestAMICallback alloc] init];
+#else
+ return [[[TestAMICallback alloc] init] autorelease];
+#endif
+}
+
+@end
+
+void
+amiAllTests(id<ICECommunicator> communicator)
+{
+ NSString* ref = @"test:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:(ref)];
+ id<TestAMITestIntfPrx> p = [TestAMITestIntfPrx checkedCast:base];
+ test(p);
+
+ ref = @"testController:tcp -p 12011";
+ base = [communicator stringToProxy:ref];
+ TestAMITestIntfControllerPrx* testController = [TestAMITestIntfControllerPrx uncheckedCast:base];
+ test(testController);
+
+ tprintf("testing begin/end invocation... ");
+ {
+ ICEContext* ctx = [ICEContext dictionary];
+ id<ICEAsyncResult> result;
+
+ result = [p begin_ice_isA:[TestAMITestIntfPrx ice_staticId]];
+ test([p end_ice_isA:result]);
+ result = [p begin_ice_isA:[TestAMITestIntfPrx ice_staticId] context:ctx];
+ test([p end_ice_isA:result]);
+
+ result = [p begin_ice_ping];
+ [p end_ice_ping:result];
+ result = [p begin_ice_ping:ctx];
+ [p end_ice_ping:result];
+
+ result = [p begin_ice_id];
+ test([[p end_ice_id:result] isEqualToString:[TestAMITestIntfPrx ice_staticId]]);
+ result = [p begin_ice_id:ctx];
+ test([[p end_ice_id:result] isEqualToString:[TestAMITestIntfPrx ice_staticId]]);
+
+ result = [p begin_ice_ids];
+ test([[p end_ice_ids:result] count] == 2);
+ result = [p begin_ice_ids:ctx];
+ test([[p end_ice_ids:result] count] == 2);
+
+ result = [p begin_op];
+ [p end_op:result];
+ result = [p begin_op:ctx];
+ [p end_op:result];
+
+ result = [p begin_opWithResult];
+ test([p end_opWithResult:result] == 15);
+ result = [p begin_opWithResult:ctx];
+ test([p end_opWithResult:result] == 15);
+
+ result = [p begin_opWithUE];
+ @try
+ {
+ [p end_opWithUE:result];
+ test(NO);
+ }
+ @catch(TestAMITestIntfException*)
+ {
+ }
+ result = [p begin_opWithUE:ctx];
+ @try
+ {
+ [p end_opWithUE:result];
+ test(NO);
+ }
+ @catch(TestAMITestIntfException*)
+ {
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing response callback... ");
+ {
+ TestAMICallback* cb = [TestAMICallback create];
+ ICEContext* ctx = [NSDictionary dictionary];
+ void (^exCB)(ICEException*) = ^(ICEException* ex)
+ {
+ test(NO);
+ };
+
+ void (^isACB)(BOOL) = ^(BOOL ret) { test(ret); [cb called]; };
+ [p begin_ice_isA:[TestAMITestIntfPrx ice_staticId] response:isACB exception:exCB];
+ [cb check];
+ [p begin_ice_isA:[TestAMITestIntfPrx ice_staticId] context:ctx response:isACB exception:exCB];
+ [cb check];
+
+ void (^pingCB)() = ^ { [cb called]; };
+ [p begin_ice_ping:pingCB exception:exCB];
+ [cb check];
+ [p begin_ice_ping:ctx response:pingCB exception:exCB];
+ [cb check];
+
+ void (^idCB)(NSString* typeId) = ^(NSString* typeId)
+ {
+ test([typeId isEqualToString:[TestAMITestIntfPrx ice_staticId]]);
+ [cb called];
+ };
+
+ [p begin_ice_id:idCB exception:exCB];
+ [cb check];
+ [p begin_ice_id:ctx response:idCB exception:exCB];
+ [cb check];
+
+ void (^idsCB)(NSArray* types) = ^(NSArray* types)
+ {
+ test([types count] == 2);
+ [cb called];
+ };
+
+ [p begin_ice_ids:idsCB exception:exCB];
+ [cb check];
+ [p begin_ice_ids:ctx response:idsCB exception:exCB];
+ [cb check];
+
+ void (^opCB)() = ^ { [cb called]; };
+ [p begin_op:opCB exception:exCB];
+ [cb check];
+ [p begin_op:ctx response:opCB exception:exCB];
+ [cb check];
+ [p begin_op:nil exception:exCB];
+ [p begin_op:ctx response:nil exception:exCB];
+
+ void (^opWithResultCB)(ICEInt) = ^(ICEInt r)
+ {
+ test(r == 15);
+ [cb called];
+ };
+ [p begin_opWithResult:opWithResultCB exception:exCB];
+ [cb check];
+ [p begin_opWithResult:ctx response:opWithResultCB exception:exCB];
+ [cb check];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ void (^opWithUE)() = [[ ^() { test(NO); } copy ] autorelease];
+#else
+ void (^opWithUE)() = [ ^() { test(NO); } copy ];
+#endif
+ void (^opWithUEEx)(ICEException*) = ^(ICEException* ex)
+ {
+ @try
+ {
+ @throw ex;
+ test(NO);
+ }
+ @catch(TestAMITestIntfException*)
+ {
+ [cb called];
+ }
+ };
+ [p begin_opWithUE:opWithUE exception:opWithUEEx];
+ [cb check];
+ [p begin_opWithUE:ctx response:opWithUE exception:opWithUEEx];
+ [cb check];
+ [p begin_opWithUE:nil exception:opWithUEEx];
+ [cb check];
+ [p begin_opWithUE:ctx response:nil exception:opWithUEEx];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("testing local exceptions... ");
+ {
+ TestAMITestIntfPrx* indirect = [TestAMITestIntfPrx uncheckedCast:[p ice_adapterId:@"dummy"]];
+ id<ICEAsyncResult> r;
+
+ r = [indirect begin_op];
+ @try
+ {
+ [indirect end_op:r];
+ test(NO);
+ }
+ @catch(ICENoEndpointException*)
+ {
+ }
+
+ @try
+ {
+ r = [[p ice_oneway] begin_ice_id];
+ test(NO);
+ }
+ @catch(NSException* ex)
+ {
+ test([ex name] == NSInvalidArgumentException);
+ }
+ @try
+ {
+ r = [[p ice_oneway] begin_opWithResult];
+ test(NO);
+ }
+ @catch(NSException* ex)
+ {
+ test([ex name] == NSInvalidArgumentException);
+ }
+
+ @try
+ {
+ r = [p begin_op:nil exception:nil];
+ test(NO);
+ }
+ @catch(NSException* ex)
+ {
+ test([ex name] == NSInvalidArgumentException);
+ }
+
+ //
+ // Check that CommunicatorDestroyedException is raised directly.
+ //
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ [initData setProperties:[[communicator getProperties] clone]];
+ id<ICECommunicator> ic = [ICEUtil createCommunicator:initData];
+ id<ICEObjectPrx> obj = [ic stringToProxy:[p ice_toString]];
+ id<TestAMITestIntfPrx> p2 = [TestAMITestIntfPrx checkedCast:obj];
+
+ [ic destroy];
+
+ @try
+ {
+ [p2 begin_op];
+ test(NO);
+ }
+ @catch(ICECommunicatorDestroyedException*)
+ {
+ // Expected.
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing exception callback... ");
+ {
+ id<TestAMITestIntfPrx> i = [TestAMITestIntfPrx uncheckedCast:[p ice_adapterId:@"dummy"]];
+ TestAMICallback* cb = [TestAMICallback create];
+ ICEContext* ctx = [NSDictionary dictionary];
+
+ void (^exCB)(ICEException*) = ^(ICEException* ex) {
+ test([ex isKindOfClass:[ICENoEndpointException class]]);
+ [cb called];
+ };
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ void (^isACB)(BOOL) = [[ ^(BOOL ret) { test(NO); } copy ] autorelease];
+#else
+ void (^isACB)(BOOL) = [ ^(BOOL ret) { test(NO); } copy ];
+#endif
+ [i begin_ice_isA:@"dummy" response:isACB exception:exCB];
+ [cb check];
+ [i begin_ice_isA:@"dummy" context:ctx response:isACB exception:exCB];
+ [cb check];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ void (^pingCB)() = [[ ^ { test(NO); } copy ] autorelease];
+#else
+ void (^pingCB)() = [ ^ { test(NO); } copy ];
+#endif
+ [i begin_ice_ping:pingCB exception:exCB];
+ [cb check];
+ [i begin_ice_ping:ctx response:pingCB exception:exCB];
+ [cb check];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ void (^idCB)(NSString*) = [[ ^(NSString* ret) { test(NO); } copy ] autorelease];
+#else
+ void (^idCB)(NSString*) = [ ^(NSString* ret) { test(NO); } copy ];
+#endif
+ [i begin_ice_id:idCB exception:exCB];
+ [cb check];
+ [i begin_ice_id:ctx response:idCB exception:exCB];
+ [cb check];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ void (^idsCB)(NSArray*) = [[ ^(NSArray* ret) { test(NO); } copy ] autorelease];
+#else
+ void (^idsCB)(NSArray*) = [ ^(NSArray* ret) { test(NO); } copy ];
+#endif
+ [i begin_ice_ids:idsCB exception:exCB];
+ [cb check];
+ [i begin_ice_ids:ctx response:idsCB exception:exCB];
+ [cb check];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ void (^opCB)() = [[ ^ { test(NO); } copy ] autorelease];
+#else
+ void (^opCB)() = [ ^ { test(NO); } copy ];
+#endif
+ [i begin_op:opCB exception:exCB];
+ [cb check];
+ [i begin_op:ctx response:opCB exception:exCB];
+ [cb check];
+
+ @try
+ {
+ [p begin_opWithResult:nil exception:^(ICEException* ex) { test(NO); }];
+ test(NO);
+ }
+ @catch(NSException* ex)
+ {
+ test([ex name] == NSInvalidArgumentException);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing sent callback... ");
+ {
+ TestAMICallback* cb = [TestAMICallback create];
+ ICEContext* ctx = [NSDictionary dictionary];
+ void (^exCB)(ICEException*) = ^(ICEException* ex) {
+ test(NO);
+ };
+
+ void (^sentCB)(BOOL) = ^(BOOL ss) { [cb called]; };
+
+ [p begin_ice_isA:@"test" response:nil exception:exCB sent:sentCB];
+ [cb check];
+ [p begin_ice_isA:@"test" context:ctx response:nil exception:exCB sent:sentCB];
+ [cb check];
+
+ [p begin_ice_ping:nil exception:exCB sent:sentCB];
+ [cb check];
+ [p begin_ice_ping:ctx response:nil exception:exCB sent:sentCB];
+ [cb check];
+
+ [p begin_ice_id:nil exception:exCB sent:sentCB];
+ [cb check];
+ [p begin_ice_id:ctx response:nil exception:exCB sent:sentCB];
+ [cb check];
+
+ [p begin_ice_ids:nil exception:exCB sent:sentCB];
+ [cb check];
+ [p begin_ice_ids:ctx response:nil exception:exCB sent:sentCB];
+ [cb check];
+
+ [p begin_op:nil exception:exCB sent:sentCB];
+ [cb check];
+ [p begin_op:ctx response:nil exception:exCB sent:sentCB];
+ [cb check];
+
+ ICEByte d[1024];
+ ICEMutableByteSeq* seq = [ICEMutableByteSeq dataWithBytes:d length:sizeof(d)];
+ [testController holdAdapter];
+ NSMutableArray* cbs = [NSMutableArray array];
+
+ @autoreleasepool
+ {
+ @try
+ {
+ TestAMICallback* cb = [TestAMICallback create];
+ while(true)
+ {
+ if(![[p begin_opWithPayload:seq response:nil exception:exCB sent:
+ ^(BOOL ss) {
+ [cb called];
+ }] sentSynchronously])
+ {
+ [cbs addObject:cb];
+ break;
+ }
+ [cbs addObject:cb];
+ cb = [TestAMICallback create];
+ }
+ }
+ @catch(NSException* ex)
+ {
+ [testController resumeAdapter];
+ @throw ex;
+ }
+ [testController resumeAdapter];
+ for(TestAMICallback* cb in cbs)
+ {
+ [cb check];
+ }
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing illegal arguments... ");
+ {
+ id<ICEAsyncResult> result;
+
+ result = [p begin_op];
+ [p end_op:result];
+ @try
+ {
+ [p end_op:result];
+ test(NO);
+ }
+ @catch(NSException* ex)
+ {
+ test([ex name] == NSInvalidArgumentException);
+ }
+
+ result = [p begin_op];
+ @try
+ {
+ [p end_opWithResult:result];
+ test(NO);
+ }
+ @catch(NSException* ex)
+ {
+ test([ex name] == NSInvalidArgumentException);
+ }
+
+ @try
+ {
+ [p end_op:nil];
+ test(NO);
+ }
+ @catch(NSException* ex)
+ {
+ test([ex name] == NSInvalidArgumentException);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing unexpected exceptions from callback... ");
+ {
+ id<TestAMITestIntfPrx> q = [TestAMITestIntfPrx uncheckedCast:[p ice_adapterId:@"dummy"]];
+ TestAMICallback* cb = [TestAMICallback create];
+ void (^thrower)() = ^(int i)
+ {
+ [cb called];
+ switch(i)
+ {
+ case 0:
+ {
+ @throw [ICEObjectNotExistException objectNotExistException:__FILE__ line:__LINE__];
+ }
+ case 1:
+ {
+ @throw [TestAMITestIntfException testIntfException];
+ }
+ case 2:
+ {
+ @throw [NSException exceptionWithName:@"" reason:nil userInfo:nil];
+ }
+ }
+ };
+
+ void (^exCB)(ICEException*) = ^(ICEException* ex)
+ {
+ test(NO);
+ };
+
+ int i;
+ for(i = 0; i < 3; ++i)
+ {
+ void (^throwResponse)() = ^{ thrower(i); };
+ void (^throwEx)(ICEException*) = ^(ICEException* ex){ thrower(i); };
+ void (^throwSent)(BOOL) = ^(BOOL b){ thrower(i); };
+
+ [p begin_ice_ping:throwResponse exception:exCB];
+ [cb check];
+
+ [q begin_ice_ping:nil exception:throwEx];
+ [cb check];
+
+ [p begin_ice_ping:nil exception:exCB sent:throwSent];
+ [cb check];
+
+ [p begin_op:throwResponse exception:exCB];
+ [cb check];
+
+ [q begin_op:nil exception:throwEx];
+ [cb check];
+
+ [p begin_op:nil exception:exCB sent:throwSent];
+ [cb check];
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing batch requests with proxy... ");
+ {
+ {
+ test([p opBatchCount] == 0);
+ id<TestAMITestIntfPrx> b1 = [p ice_batchOneway];
+ [b1 opBatch];
+ [b1 opBatch];
+ TestAMICallback* cb = [TestAMICallback create];
+ id<ICEAsyncResult> r = [b1 begin_ice_flushBatchRequests:^(ICEException* ex) { test(NO); }
+ sent:^(BOOL sentSynchronously) { [cb called]; }];
+ [cb check];
+ test([r isSent]);
+ test([r isCompleted]);
+ test([p waitForBatch:2]);
+ }
+
+ {
+ test([p opBatchCount] == 0);
+ id<TestAMITestIntfPrx> b1 = [p ice_batchOneway];
+ [b1 opBatch];
+ [[b1 ice_getConnection] close:false];
+ TestAMICallback* cb = [TestAMICallback create];
+ id<ICEAsyncResult> r = [b1 begin_ice_flushBatchRequests:^(ICEException* ex) { [cb called]; }
+ sent:^(BOOL sentSynchronously) { test(NO); }];
+ [cb check];
+ test(![r isSent]);
+ test([r isCompleted]);
+ test([p opBatchCount] == 0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing batch requests with connection... ");
+ {
+ {
+ test([p opBatchCount] == 0);
+ id<TestAMITestIntfPrx> b1 = [p ice_batchOneway];
+ [b1 opBatch];
+ [b1 opBatch];
+ TestAMICallback* cb = [TestAMICallback create];
+ id<ICEAsyncResult> r = [[b1 ice_getConnection] begin_flushBatchRequests:^(ICEException* ex) { test(NO); }
+ sent:^(BOOL sentSynchronously) { [cb called]; }];
+ [cb check];
+ test([r isSent]);
+ test([r isCompleted]);
+ test([p waitForBatch:2]);
+ }
+
+ {
+ test([p opBatchCount] == 0);
+ TestAMITestIntfPrx* b1 = [p ice_batchOneway];
+ [b1 opBatch];
+ [[b1 ice_getConnection] close:false];
+ TestAMICallback* cb = [TestAMICallback create];
+ id<ICEAsyncResult> r = [[b1 ice_getConnection] begin_flushBatchRequests:
+ ^(ICEException* ex) { [cb called]; }
+ sent:^(BOOL sentSynchronously) { test(NO); }];
+ [cb check];
+ test(![r isSent]);
+ test([r isCompleted]);
+ test([p opBatchCount] == 0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing batch requests with communicator... ");
+ {
+ {
+ test([p opBatchCount] == 0);
+ id<TestAMITestIntfPrx> b1 = [p ice_batchOneway];
+ [b1 opBatch];
+ [b1 opBatch];
+ TestAMICallback* cb = [TestAMICallback create];
+ id<ICEAsyncResult> r = [communicator begin_flushBatchRequests:^(ICEException* ex) { test(NO); }
+ sent:^(BOOL sentSynchronously) { [cb called]; }];
+ [cb check];
+ test([r isSent]);
+ test([r isCompleted]);
+ test([p waitForBatch:2]);
+ }
+
+ {
+ test([p opBatchCount] == 0);
+ TestAMITestIntfPrx* b1 = [p ice_batchOneway];
+ [b1 opBatch];
+ [[b1 ice_getConnection] close:false];
+ TestAMICallback* cb = [TestAMICallback create];
+ id<ICEAsyncResult> r = [communicator begin_flushBatchRequests:^(ICEException* ex) { test(NO); }
+ sent:^(BOOL sentSynchronously) { [cb called]; }];
+ [cb check];
+ test([r isSent]);
+ test([r isCompleted]);
+ test([p opBatchCount] == 0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing AsyncResult operations... ");
+ {
+ {
+ id<TestAMITestIntfPrx> indirect = [TestAMITestIntfPrx uncheckedCast:[p ice_adapterId:@"dummy"]];
+ id<ICEAsyncResult> r = [indirect begin_op];
+ @try
+ {
+ [r waitForCompleted];
+ [r throwLocalException];
+ }
+ @catch(ICENoEndpointException* ex)
+ {
+ }
+
+ [testController holdAdapter];
+ id<ICEAsyncResult> r1;
+ id<ICEAsyncResult> r2;
+ @try
+ {
+ r1 = [p begin_op];
+ ICEByte d[1024];
+ ICEMutableByteSeq* seq = [ICEMutableByteSeq dataWithBytes:d length:sizeof(d)];
+ while([(r2 = [p begin_opWithPayload:seq]) sentSynchronously]);
+
+ test(r1 == r1);
+ test(r1 != r2);
+
+ test(([r1 sentSynchronously] && [r1 isSent] && ![r1 isCompleted]) ||
+ (![r1 sentSynchronously] && ![r1 isCompleted]));
+
+ test(![r2 sentSynchronously] && ![r2 isCompleted]);
+ }
+ @catch(NSException* ex)
+ {
+ [testController resumeAdapter];
+ @throw ex;
+ }
+ [testController resumeAdapter];
+
+ [r1 waitForSent];
+ test([r1 isSent]);
+
+ [r2 waitForSent];
+ test([r2 isSent]);
+
+ [r1 waitForCompleted];
+ test([r1 isCompleted]);
+
+ [r2 waitForCompleted];
+ test([r2 isCompleted]);
+
+ test([[r1 getOperation] isEqualToString:@"op"]);
+ test([[r2 getOperation] isEqualToString:@"opWithPayload"]);
+ }
+
+ {
+ id<ICEAsyncResult> r;
+
+ //
+ // Twoway
+ //
+ r = [p begin_ice_ping];
+ test([[r getOperation] isEqualToString:@"ice_ping"]);
+ test([r getConnection] == nil); // Expected
+ test([r getCommunicator] == communicator);
+ test([[r getProxy] isEqual:p]);
+ [p end_ice_ping:r];
+
+ id<TestAMITestIntfPrx> p2;
+
+ //
+ // Oneway
+ //
+ p2 = [p ice_oneway];
+ r = [p2 begin_ice_ping];
+ test([[r getOperation] isEqualToString:@"ice_ping"]);
+ test(![r getConnection]); // Expected
+ test([r getCommunicator] == communicator);
+ test([[r getProxy] isEqual:p2]);
+
+ //
+ // Batch request via proxy
+ //
+ p2 = [p ice_batchOneway];
+ [p2 ice_ping];
+ r = [p2 begin_ice_flushBatchRequests];
+ test([r getConnection] == nil); // Expected
+ test([r getCommunicator] == communicator);
+ test([[r getProxy] isEqual:p2]);
+ [p2 end_ice_flushBatchRequests:r];
+
+ //
+ // Batch request via connection
+ //
+ id<ICEConnection> con = [p ice_getConnection];
+ p2 = [p ice_batchOneway];
+ [p2 ice_ping];
+ r = [con begin_flushBatchRequests];
+ test([[r getConnection] isEqual:con]);
+ test([r getCommunicator] == communicator);
+ test([r getProxy] == nil); // Expected
+ [con end_flushBatchRequests:r];
+
+ //
+ // Batch request via communicator
+ //
+ p2 = [p ice_batchOneway];
+ [p2 ice_ping];
+ r = [communicator begin_flushBatchRequests];
+ test([r getConnection] == nil); // Expected
+ test([r getCommunicator] == communicator);
+ test([r getProxy] == nil); // Expected
+ [communicator end_flushBatchRequests:r];
+ }
+ }
+ tprintf("ok\n");
+
+ [p shutdown];
+}
diff --git a/objc/test/Ice/ami/Client.m b/objc/test/Ice/ami/Client.m
new file mode 100644
index 00000000000..f3928e205a6
--- /dev/null
+++ b/objc/test/Ice/ami/Client.m
@@ -0,0 +1,93 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <AMITest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ void amiAllTests(id<ICECommunicator>);
+ amiAllTests(communicator);
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main amiClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+ //
+ // In this test, we need at least two threads in the
+ // client side thread pool for nested AMI.
+ //
+ [initData.properties setProperty:@"Ice.ThreadPool.Client.Size" value:@"2"];
+ [initData.properties setProperty:@"Ice.ThreadPool.Client.SizeWarn" value:@"0"];
+ [initData.properties setProperty:@"Ice.Warn.AMICallback" value:@"0"];
+
+ //
+ // We must set MessageSizeMax to an explicit values, because
+ // we run tests to check whether Ice.MemoryLimitException is
+ // raised as expected.
+ //
+ [initData.properties setProperty:@"Ice.MessageSizeMax" value:@"100"];
+
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestAMI", @"::Test",
+ nil];
+#endif
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/ami/Makefile b/objc/test/Ice/ami/Makefile
new file mode 100644
index 00000000000..47b7ecc1506
--- /dev/null
+++ b/objc/test/Ice/ami/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = AMITest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/ami/Server.m b/objc/test/Ice/ami/Server.m
new file mode 100644
index 00000000000..1ac7c651ea9
--- /dev/null
+++ b/objc/test/Ice/ami/Server.m
@@ -0,0 +1,103 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <ami/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAMIAdapter.Endpoints" value:@"default -p 12010:udp"];
+ [[communicator getProperties] setProperty:@"ControllerAdapter.Endpoints" value:@"tcp -p 12011"];
+ [[communicator getProperties] setProperty:@"ControllerAdapter.ThreadPool.Size" value:@"1"];
+
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAMIAdapter"];
+ id<ICEObjectAdapter> adapter2 = [communicator createObjectAdapter:@"ControllerAdapter"];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ TestAMITestIntfControllerI* testController
+ = [[[TestAMITestIntfControllerI alloc] initWithAdapter:adapter] autorelease];
+
+ [adapter add:[[[TestAMITestIntfI alloc] init] autorelease] identity:[communicator stringToIdentity:@"test"]];
+#else
+ TestAMITestIntfControllerI* testController
+ = [[TestAMITestIntfControllerI alloc] initWithAdapter:adapter];
+
+ [adapter add:[[TestAMITestIntfI alloc] init] identity:[communicator stringToIdentity:@"test"]];
+#endif
+ [adapter activate];
+
+ [adapter2 add:testController identity:[communicator stringToIdentity:@"testController"]];
+ [adapter2 activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main amiServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+
+ //
+ // Its possible to have batch oneway requests dispatched after
+ // the adapter is deactivated due to thread scheduling so we
+ // supress this warning.
+ //
+ [initData.properties setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestAMI", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/ami/TestI.h b/objc/test/Ice/ami/TestI.h
new file mode 100644
index 00000000000..3535f73f0c8
--- /dev/null
+++ b/objc/test/Ice/ami/TestI.h
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <AMITest.h>
+#import <Foundation/Foundation.h>
+
+//
+// Servant implementation
+//
+@interface TestAMITestIntfI : TestAMITestIntf<TestAMITestIntf>
+{
+ int _batchCount;
+ NSCondition* _cond;
+}
+@end
+
+@interface TestAMITestIntfControllerI : TestAMITestIntfController<TestAMITestIntfController>
+{
+ id<ICEObjectAdapter> _adapter;
+}
+-(id) initWithAdapter:(id<ICEObjectAdapter>)adapter;
+@end
+
diff --git a/objc/test/Ice/ami/TestI.m b/objc/test/Ice/ami/TestI.m
new file mode 100644
index 00000000000..0357daeef42
--- /dev/null
+++ b/objc/test/Ice/ami/TestI.m
@@ -0,0 +1,114 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+
+#import <ami/TestI.h>
+#import <TestCommon.h>
+
+@implementation TestAMITestIntfI
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ _cond = [[NSCondition alloc] init];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [_cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) op:(ICECurrent*)current
+{
+}
+-(void) opWithPayload:(ICEMutableByteSeq*)data current:(ICECurrent*)current
+{
+}
+-(int) opWithResult:(ICECurrent*)current
+{
+ return 15;
+}
+-(void) opWithUE:(ICECurrent*)current
+{
+ @throw [TestAMITestIntfException testIntfException];
+}
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+-(void) opBatch:(ICECurrent *)current
+{
+ [_cond lock];
+ ++_batchCount;
+ [_cond signal];
+ [_cond unlock];
+}
+-(ICEInt) opBatchCount:(ICECurrent *)current
+{
+ [_cond lock];
+ @try
+ {
+ return _batchCount;
+ }
+ @finally
+ {
+ [_cond unlock];
+ }
+ return 0;
+}
+-(BOOL) waitForBatch:(ICEInt)count current:(ICECurrent *)current
+{
+ [_cond lock];
+ @try
+ {
+ while(_batchCount < count)
+ {
+ [_cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:500]];
+ }
+ BOOL result = count == _batchCount;
+ _batchCount = 0;
+ return result;
+ }
+ @finally
+ {
+ [_cond unlock];
+ }
+ return NO;
+}
+@end
+
+@implementation TestAMITestIntfControllerI
+-(id) initWithAdapter:(id<ICEObjectAdapter>)adapter
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ _adapter = adapter;
+ return self;
+}
+-(void) holdAdapter:(ICECurrent*)current
+{
+ [_adapter hold];
+}
+-(void) resumeAdapter:(ICECurrent*)current
+{
+ [_adapter activate];
+}
+@end
diff --git a/objc/test/Ice/ami/run.py b/objc/test/Ice/ami/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/ami/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/binding/.gitignore b/objc/test/Ice/binding/.gitignore
new file mode 100644
index 00000000000..111134fb8e1
--- /dev/null
+++ b/objc/test/Ice/binding/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+BindingTest.m
+BindingTest.h
diff --git a/objc/test/Ice/binding/AllTests.m b/objc/test/Ice/binding/AllTests.m
new file mode 100644
index 00000000000..6fe816d3262
--- /dev/null
+++ b/objc/test/Ice/binding/AllTests.m
@@ -0,0 +1,886 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <BindingTest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface GetAdapterNameCB : NSObject
+{
+ NSCondition* cond_;
+ NSString* name_;
+}
+-(id) init;
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc;
+#endif
+-(void) response:(NSString*)name;
+-(void) exception:(ICEException*)ex;
+-(NSString*) getResult;
+@end
+
+@implementation GetAdapterNameCB
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond_ = [[NSCondition alloc] init];
+ name_ = nil;
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond_ release];
+ [name_ release];
+ [super dealloc];
+}
+#endif
+
+-(void) response:(NSString*)name
+{
+ [cond_ lock];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ name_ = [name retain];
+#else
+ name_ = name;
+#endif
+ [cond_ signal];
+ [cond_ unlock];
+}
+-(void) exception:(ICEException*)ex
+{
+ tprintf("unexpected exception: %@", ex);
+ test(NO);
+}
+-(NSString*) getResult
+{
+ [cond_ lock];
+ @try
+ {
+ while(name_ == nil)
+ {
+ [cond_ wait];
+ }
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[name_ retain] autorelease];
+#else
+ return name_;
+#endif
+ }
+ @finally
+ {
+ [cond_ unlock];
+ }
+ return nil;
+}
+@end
+
+NSString*
+getAdapterNameWithAMI(id<TestBindingTestIntfPrx> test)
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ GetAdapterNameCB* cb = [[[GetAdapterNameCB alloc] init] autorelease];
+#else
+ GetAdapterNameCB* cb = [[GetAdapterNameCB alloc] init];
+#endif
+ [test begin_getAdapterName:^(NSMutableString* name) { [cb response:name]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ return [cb getResult];
+}
+
+NSArray*
+getEndpoints(id<TestBindingTestIntfPrx> proxy)
+{
+ NSMutableArray* edpts = [NSMutableArray array];
+ bool escape = NO;
+ int beg = 0;
+ int length = 0;
+ NSString* s = [proxy ice_toString];
+ int index;
+ for(index = 0; index < [s length]; ++index)
+ {
+ unichar c = [s characterAtIndex:index];
+ if(c == '"')
+ {
+ escape = !escape;
+ }
+
+ if(!escape && c == ':')
+ {
+ NSRange range = { beg, length };
+ [edpts addObject:[s substringWithRange:range]];
+ beg = beg + length + 1;
+ length = 0;
+ }
+ else
+ {
+ ++length;
+ }
+ }
+ if(length > 0)
+ {
+ NSRange range = { beg, length };
+ [edpts addObject:[s substringWithRange:range]];
+ }
+ [edpts removeObjectAtIndex:0];
+ return edpts;
+}
+
+id<TestBindingTestIntfPrx>
+createTestIntfPrx(NSArray* adapters)
+{
+ NSMutableArray* endpoints = [NSMutableArray arrayWithCapacity:[adapters count]];
+ id<TestBindingTestIntfPrx> test = nil;
+ for(id<TestBindingRemoteObjectAdapterPrx> a in adapters)
+ {
+ test = [a getTestIntf];
+ [endpoints addObjectsFromArray:getEndpoints(test)];
+ }
+ NSString* proxy = [[test ice_getCommunicator] identityToString:[test ice_getIdentity]];
+ for(NSString* e in endpoints)
+ {
+ proxy = [proxy stringByAppendingString:@":"];
+ proxy = [proxy stringByAppendingString:e];
+ }
+ return [TestBindingTestIntfPrx uncheckedCast:[[test ice_getCommunicator] stringToProxy:proxy]];
+}
+
+void
+deactivate(id<TestBindingRemoteCommunicatorPrx> com, NSArray* adapters)
+{
+ for(id<TestBindingRemoteObjectAdapterPrx> a in adapters)
+ {
+ [com deactivateObjectAdapter:a];
+ }
+}
+
+void
+random_shuffle(NSMutableArray* array)
+{
+ NSUInteger count = [array count];
+ while(count--)
+ {
+ [array exchangeObjectAtIndex:count withObjectAtIndex:(random() % (count + 1))];
+ }
+}
+
+void
+bindingAllTests(id<ICECommunicator> communicator)
+{
+ NSString* ref = @"communicator:default -p 12010";
+ id<TestBindingRemoteCommunicatorPrx> com = [TestBindingRemoteCommunicatorPrx uncheckedCast:[
+ communicator stringToProxy:ref]];
+
+ tprintf("testing binding with single endpoint... ");
+ {
+ id<TestBindingRemoteObjectAdapterPrx> adapter = [com createObjectAdapter:@"Adapter" endpoints:@"default"];
+
+ id<TestBindingTestIntfPrx> test1 = [adapter getTestIntf];
+ id<TestBindingTestIntfPrx> test2 = [adapter getTestIntf];
+ test([[test1 ice_getConnection] isEqual:[test2 ice_getConnection]]);
+
+ [test1 ice_ping];
+ [test2 ice_ping];
+
+ [com deactivateObjectAdapter:adapter];
+
+ id<TestBindingTestIntfPrx> test3 = [TestBindingTestIntfPrx uncheckedCast:test1];
+ test([[test3 ice_getConnection] isEqual:[test1 ice_getConnection]]);
+ test([[test3 ice_getConnection] isEqual:[test2 ice_getConnection]]);
+
+ @try
+ {
+ [test3 ice_ping];
+ test(NO);
+ }
+ @catch(ICEConnectionRefusedException*)
+ {
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing binding with multiple endpoints... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"Adapter11" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter12" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter13" endpoints:@"default"]];
+
+ //
+ // Ensure that when a connection is opened it's reused for new
+ // proxies and that all endpoints are eventually tried.
+ //
+ NSMutableSet* names = [NSMutableSet setWithCapacity:3];
+ [names addObject:@"Adapter11"];
+ [names addObject:@"Adapter12"];
+ [names addObject:@"Adapter13"];
+ while([names count] != 0)
+ {
+ NSMutableArray* adpts = [adapters mutableCopy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adpts autorelease];
+#endif
+ id<TestBindingTestIntfPrx> test1 = createTestIntfPrx(adpts);
+ random_shuffle(adpts);
+ id<TestBindingTestIntfPrx> test2 = createTestIntfPrx(adpts);
+ random_shuffle(adpts);
+ id<TestBindingTestIntfPrx> test3 = createTestIntfPrx(adpts);
+
+ test([[test1 ice_getConnection] isEqual:[test2 ice_getConnection]]);
+ test([[test2 ice_getConnection] isEqual:[test3 ice_getConnection]]);
+
+ [names removeObject:[test1 getAdapterName]];
+ [[test1 ice_getConnection] close:NO];
+ }
+
+ //
+ // Ensure that the proxy correctly caches the connection (we
+ // always send the request over the same connection.)
+ //
+ {
+ for(id<TestBindingRemoteObjectAdapterPrx> a in adapters)
+ {
+ [[a getTestIntf] ice_ping];
+ }
+
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ NSString* name = [test getAdapterName];
+ const int nRetry = 10;
+ int i;
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:name]; i++);
+ test(i == nRetry);
+
+ for(id<TestBindingRemoteObjectAdapterPrx> a in adapters)
+ {
+ [[[a getTestIntf] ice_getConnection] close:NO];
+ }
+ }
+
+ //
+ // Deactivate an adapter and ensure that we can still
+ // establish the connection to the remaining adapters.
+ //
+ [com deactivateObjectAdapter:[adapters objectAtIndex:0]];
+ [names addObject:@"Adapter12"];
+ [names addObject:@"Adapter13"];
+ while([names count] != 0)
+ {
+ NSMutableArray* adpts = [adapters mutableCopy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adpts autorelease];
+#endif
+ id<TestBindingTestIntfPrx> test1 = createTestIntfPrx(adpts);
+ random_shuffle(adpts);
+ id<TestBindingTestIntfPrx> test2 = createTestIntfPrx(adpts);
+ random_shuffle(adpts);
+ id<TestBindingTestIntfPrx> test3 = createTestIntfPrx(adpts);
+
+ test([[test1 ice_getConnection] isEqual:[test2 ice_getConnection]]);
+ test([[test2 ice_getConnection] isEqual:[test3 ice_getConnection]]);
+
+ [names removeObject:[test1 getAdapterName]];
+ [[test1 ice_getConnection] close:NO];
+ }
+
+ //
+ // Deactivate an adapter and ensure that we can still
+ // establish the connection to the remaining adapter.
+ //
+ [com deactivateObjectAdapter:[adapters objectAtIndex:2]];
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ test([[test getAdapterName] isEqualToString:@"Adapter12"]);
+
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing binding with multiple endpoints and AMI... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI11" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI12" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI13" endpoints:@"default"]];
+
+ //
+ // Ensure that when a connection is opened it's reused for new
+ // proxies and that all endpoints are eventually tried.
+ //
+ NSMutableSet* names = [NSMutableSet setWithCapacity:3];
+ [names addObject:@"AdapterAMI11"];
+ [names addObject:@"AdapterAMI12"];
+ [names addObject:@"AdapterAMI13"];
+ while([names count] != 0)
+ {
+ NSMutableArray* adpts = [adapters mutableCopy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adpts autorelease];
+#endif
+
+ id<TestBindingTestIntfPrx> test1 = createTestIntfPrx(adpts);
+ random_shuffle(adpts);
+ id<TestBindingTestIntfPrx> test2 = createTestIntfPrx(adpts);
+ random_shuffle(adpts);
+ id<TestBindingTestIntfPrx> test3 = createTestIntfPrx(adpts);
+
+ test([[test1 ice_getConnection] isEqual:[test2 ice_getConnection]]);
+ test([[test2 ice_getConnection] isEqual:[test3 ice_getConnection]]);
+
+ [names removeObject:getAdapterNameWithAMI(test1)];
+ [[test1 ice_getConnection] close:NO];
+ }
+
+ //
+ // Ensure that the proxy correctly caches the connection (we
+ // always send the request over the same connection.)
+ //
+ {
+ for(id<TestBindingRemoteObjectAdapterPrx> a in adapters)
+ {
+ [[a getTestIntf] ice_ping];
+ }
+
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ NSString* name = getAdapterNameWithAMI(test);
+ const int nRetry = 10;
+ int i;
+ for(i = 0; i < nRetry && [getAdapterNameWithAMI(test) isEqualToString:name]; i++);
+ test(i == nRetry);
+
+ for(id<TestBindingRemoteObjectAdapterPrx> a in adapters)
+ {
+ [[[a getTestIntf] ice_getConnection] close:NO];
+ }
+ }
+
+ //
+ // Deactivate an adapter and ensure that we can still
+ // establish the connection to the remaining adapters.
+ //
+ [com deactivateObjectAdapter:[adapters objectAtIndex:0]];
+ [names addObject:@"AdapterAMI12"];
+ [names addObject:@"AdapterAMI13"];
+ while([names count] != 0)
+ {
+ NSMutableArray* adpts = [adapters mutableCopy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adpts autorelease];
+#endif
+
+ id<TestBindingTestIntfPrx> test1 = createTestIntfPrx(adpts);
+ random_shuffle(adpts);
+ id<TestBindingTestIntfPrx> test2 = createTestIntfPrx(adpts);
+ random_shuffle(adpts);
+ id<TestBindingTestIntfPrx> test3 = createTestIntfPrx(adpts);
+
+ test([[test1 ice_getConnection] isEqual:[test2 ice_getConnection]]);
+ test([[test2 ice_getConnection] isEqual:[test3 ice_getConnection]]);
+
+ [names removeObject:[test1 getAdapterName]];
+ [[test1 ice_getConnection] close:NO];
+ }
+
+ //
+ // Deactivate an adapter and ensure that we can still
+ // establish the connection to the remaining adapter.
+ //
+ [com deactivateObjectAdapter:[adapters objectAtIndex:2]];
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ test([[test getAdapterName] isEqualToString:@"AdapterAMI12"]);
+
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing random endpoint selection... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"Adapter21" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter22" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter23" endpoints:@"default"]];
+
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ test([test ice_getEndpointSelection] == ICERandom);
+
+ NSMutableSet* names = [NSMutableSet setWithCapacity:3];
+ [names addObject:@"Adapter21"];
+ [names addObject:@"Adapter22"];
+ [names addObject:@"Adapter23"];
+ while([names count] != 0)
+ {
+ [names removeObject:[test getAdapterName]];
+ [[test ice_getConnection] close:NO];
+ }
+
+ test = [TestBindingTestIntfPrx uncheckedCast:[test ice_endpointSelection:ICERandom]];
+ test([test ice_getEndpointSelection] == ICERandom);
+
+ [names addObject:@"Adapter21"];
+ [names addObject:@"Adapter22"];
+ [names addObject:@"Adapter23"];
+ while([names count] != 0)
+ {
+ [names removeObject:[test getAdapterName]];
+ [[test ice_getConnection] close:NO];
+ }
+
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing ordered endpoint selection... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"Adapter31" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter32" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter33" endpoints:@"default"]];
+
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ test = [TestBindingTestIntfPrx uncheckedCast:[test ice_endpointSelection:ICEOrdered]];
+ test([test ice_getEndpointSelection] == ICEOrdered);
+ const int nRetry = 5;
+ int i;
+
+ //
+ // Ensure that endpoints are tried in order by deactiving the adapters
+ // one after the other.
+ //
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter31"]; i++);
+#if TARGET_OS_IPHONE > 0
+ if(i != nRetry)
+ {
+ [[test ice_getConnection] close:NO];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter31"]; i++);
+ }
+#endif
+ test(i == nRetry);
+ [com deactivateObjectAdapter:[adapters objectAtIndex:0]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter32"]; i++);
+#if TARGET_OS_IPHONE > 0
+ if(i != nRetry)
+ {
+ [[test ice_getConnection] close:NO];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter32"]; i++);
+ }
+#endif
+ test(i == nRetry);
+ [com deactivateObjectAdapter:[adapters objectAtIndex:1]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter33"]; i++);
+#if TARGET_OS_IPHONE > 0
+ if(i != nRetry)
+ {
+ [[test ice_getConnection] close:NO];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter33"]; i++);
+ }
+#endif
+ test(i == nRetry);
+ [com deactivateObjectAdapter:[adapters objectAtIndex:2]];
+
+ @try
+ {
+ [test getAdapterName];
+ }
+ @catch(ICEConnectionRefusedException*)
+ {
+ }
+
+ NSArray* endpoints = getEndpoints(test);
+
+ adapters = [NSMutableArray arrayWithCapacity:3];
+
+ //
+ // Now, re-activate the adapters with the same endpoints in the opposite
+ // order.
+ //
+ [adapters addObject:[com createObjectAdapter:@"Adapter36" endpoints:[endpoints objectAtIndex:2]]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter36"]; i++);
+#if TARGET_OS_IPHONE > 0
+ if(i != nRetry)
+ {
+ [[test ice_getConnection] close:NO];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter36"]; i++);
+ }
+#endif
+ test(i == nRetry);
+ [[test ice_getConnection] close:NO];
+ [adapters addObject:[com createObjectAdapter:@"Adapter35" endpoints:[endpoints objectAtIndex:1]]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter35"]; i++);
+#if TARGET_OS_IPHONE > 0
+ if(i != nRetry)
+ {
+ [[test ice_getConnection] close:NO];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter35"]; i++);
+ }
+#endif
+ test(i == nRetry);
+ [[test ice_getConnection] close:NO];
+ [adapters addObject:[com createObjectAdapter:@"Adapter34" endpoints:[endpoints objectAtIndex:0]]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter34"]; i++);
+#if TARGET_OS_IPHONE > 0
+ if(i != nRetry)
+ {
+ [[test ice_getConnection] close:NO];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter34"]; i++);
+ }
+#endif
+ test(i == nRetry);
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing per request binding with single endpoint... ");
+ {
+ id<TestBindingRemoteObjectAdapterPrx> adapter = [com createObjectAdapter:@"Adapter41" endpoints:@"default"];
+
+ id<TestBindingTestIntfPrx> test1 = [TestBindingTestIntfPrx uncheckedCast:[[adapter getTestIntf] ice_connectionCached:NO]];
+ id<TestBindingTestIntfPrx> test2 = [TestBindingTestIntfPrx uncheckedCast:[[adapter getTestIntf] ice_connectionCached:NO]];
+ test(![test1 ice_isConnectionCached]);
+ test(![test2 ice_isConnectionCached]);
+ test([[test1 ice_getConnection] isEqual:[test2 ice_getConnection]]);
+
+ [test1 ice_ping];
+
+ [com deactivateObjectAdapter:adapter];
+
+ id<TestBindingTestIntfPrx> test3 = [TestBindingTestIntfPrx uncheckedCast:test1];
+ @try
+ {
+ test([[test3 ice_getConnection] isEqual:[test1 ice_getConnection]]);
+ test(NO);
+ }
+ @catch(ICEConnectionRefusedException*)
+ {
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing per request binding with multiple endpoints... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"Adapter51" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter52" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter53" endpoints:@"default"]];
+
+ id<TestBindingTestIntfPrx> test = [createTestIntfPrx(adapters) ice_connectionCached:NO];
+ test(![test ice_isConnectionCached]);
+
+ NSMutableSet* names = [NSMutableSet setWithCapacity:3];
+ [names addObject:@"Adapter51"];
+ [names addObject:@"Adapter52"];
+ [names addObject:@"Adapter53"];
+ while([names count] != 0)
+ {
+ [names removeObject:[test getAdapterName]];
+ }
+
+ [com deactivateObjectAdapter:[adapters objectAtIndex:0]];
+
+ [names addObject:@"Adapter52"];
+ [names addObject:@"Adapter53"];
+ while([names count] != 0)
+ {
+ [names removeObject:[test getAdapterName]];
+ }
+
+ [com deactivateObjectAdapter:[adapters objectAtIndex:2]];
+
+
+ test([[test getAdapterName] isEqualToString:@"Adapter52"]);
+
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing per request binding with multiple endpoints and AMI... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI51" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI52" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI53" endpoints:@"default"]];
+
+ id<TestBindingTestIntfPrx> test = [createTestIntfPrx(adapters) ice_connectionCached:NO];
+ test(![test ice_isConnectionCached]);
+
+ NSMutableSet* names = [NSMutableSet setWithCapacity:3];
+ [names addObject:@"AdapterAMI51"];
+ [names addObject:@"AdapterAMI52"];
+ [names addObject:@"AdapterAMI53"];
+ while([names count] != 0)
+ {
+ [names removeObject:getAdapterNameWithAMI(test)];
+ }
+
+ [com deactivateObjectAdapter:[adapters objectAtIndex:0]];
+
+ [names addObject:@"AdapterAMI52"];
+ [names addObject:@"AdapterAMI53"];
+ while([names count] != 0)
+ {
+ [names removeObject:getAdapterNameWithAMI(test)];
+ }
+
+ [com deactivateObjectAdapter:[adapters objectAtIndex:2]];
+
+ test([[test getAdapterName] isEqualToString:@"AdapterAMI52"]);
+
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing per request binding and ordered endpoint selection... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"Adapter61" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter62" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter63" endpoints:@"default"]];
+
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ test = [TestBindingTestIntfPrx uncheckedCast:[test ice_endpointSelection:ICEOrdered]];
+ test([test ice_getEndpointSelection] == ICEOrdered);
+ test = [TestBindingTestIntfPrx uncheckedCast:[test ice_connectionCached:NO]];
+ test(![test ice_isConnectionCached]);
+ const int nRetry = 5;
+ int i;
+
+ //
+ // Ensure that endpoints are tried in order by deactiving the adapters
+ // one after the other.
+ //
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter61"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [com deactivateObjectAdapter:[adapters objectAtIndex:0]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter62"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [com deactivateObjectAdapter:[adapters objectAtIndex:1]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter63"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [com deactivateObjectAdapter:[adapters objectAtIndex:2]];
+
+ @try
+ {
+ [test getAdapterName];
+ }
+ @catch(ICEConnectionRefusedException*)
+ {
+ }
+
+ NSArray* endpoints = getEndpoints(test);
+
+ adapters = [NSMutableArray arrayWithCapacity:3];
+
+ //
+ // Now, re-activate the adapters with the same endpoints in the opposite
+ // order.
+ //
+ [adapters addObject:[com createObjectAdapter:@"Adapter66" endpoints:[endpoints objectAtIndex:2]]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter66"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [adapters addObject:[com createObjectAdapter:@"Adapter65" endpoints:[endpoints objectAtIndex:1]]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter65"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [adapters addObject:[com createObjectAdapter:@"Adapter64" endpoints:[endpoints objectAtIndex:0]]];
+ for(i = 0; i < nRetry && [[test getAdapterName] isEqualToString:@"Adapter64"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing per request binding and ordered endpoint selection and AMI... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI61" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI62" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI63" endpoints:@"default"]];
+
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ test = [TestBindingTestIntfPrx uncheckedCast:[test ice_endpointSelection:ICEOrdered]];
+ test([test ice_getEndpointSelection] == ICEOrdered);
+ test = [TestBindingTestIntfPrx uncheckedCast:[test ice_connectionCached:NO]];
+ test(![test ice_isConnectionCached]);
+ const int nRetry = 5;
+ int i;
+
+ //
+ // Ensure that endpoints are tried in order by deactiving the adapters
+ // one after the other.
+ //
+ for(i = 0; i < nRetry && [getAdapterNameWithAMI(test) isEqualToString:@"AdapterAMI61"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [com deactivateObjectAdapter:[adapters objectAtIndex:0]];
+ for(i = 0; i < nRetry && [getAdapterNameWithAMI(test) isEqualToString:@"AdapterAMI62"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [com deactivateObjectAdapter:[adapters objectAtIndex:1]];
+ for(i = 0; i < nRetry && [getAdapterNameWithAMI(test) isEqualToString:@"AdapterAMI63"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [com deactivateObjectAdapter:[adapters objectAtIndex:2]];
+
+ @try
+ {
+ [test getAdapterName];
+ }
+ @catch(ICEConnectionRefusedException*)
+ {
+ }
+
+ NSArray* endpoints = getEndpoints(test);
+
+ adapters = [NSMutableArray arrayWithCapacity:3];
+
+ //
+ // Now, re-activate the adapters with the same endpoints in the opposite
+ // order.
+ //
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI66" endpoints:[endpoints objectAtIndex:2]]];
+ for(i = 0; i < nRetry && [getAdapterNameWithAMI(test) isEqualToString:@"AdapterAMI66"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI65" endpoints:[endpoints objectAtIndex:1]]];
+ for(i = 0; i < nRetry && [getAdapterNameWithAMI(test) isEqualToString:@"AdapterAMI65"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+ [adapters addObject:[com createObjectAdapter:@"AdapterAMI64" endpoints:[endpoints objectAtIndex:0]]];
+ for(i = 0; i < nRetry && [getAdapterNameWithAMI(test) isEqualToString:@"AdapterAMI64"]; i++);
+#if TARGET_OS_IPHONE > 0
+ test(i >= nRetry - 1); // WORKAROUND: for connection establishment hang.
+#else
+ test(i == nRetry);
+#endif
+
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing endpoint mode filtering... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"Adapter71" endpoints:@"default"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter72" endpoints:@"udp"]];
+
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ test([[test getAdapterName] isEqualToString:@"Adapter71"]);
+
+ id<TestBindingTestIntfPrx> testUDP = [TestBindingTestIntfPrx uncheckedCast:[test ice_datagram]];
+ test([test ice_getConnection] != [testUDP ice_getConnection]);
+ @try
+ {
+ [testUDP getAdapterName];
+ }
+ @catch(ICETwowayOnlyException*)
+ {
+ }
+ }
+ tprintf("ok\n");
+
+ if([[[communicator getProperties] getProperty:@"Ice.Default.Protocol"] isEqual:@"ssl"])
+ {
+ tprintf("testing unsecure vs. secure endpoints... ");
+ {
+ NSMutableArray* adapters = [NSMutableArray arrayWithCapacity:3];
+ [adapters addObject:[com createObjectAdapter:@"Adapter81" endpoints:@"ssl"]];
+ [adapters addObject:[com createObjectAdapter:@"Adapter82" endpoints:@"tcp"]];
+
+ id<TestBindingTestIntfPrx> test = createTestIntfPrx(adapters);
+ int i;
+ for(i = 0; i < 5; i++)
+ {
+ test([[test getAdapterName] isEqualToString:@"Adapter82"]);
+ [[test ice_getConnection] close:NO];
+ }
+
+ id<TestBindingTestIntfPrx> testSecure = [TestBindingTestIntfPrx uncheckedCast:[test ice_secure:YES]];
+ test([testSecure ice_isSecure]);
+ testSecure = [TestBindingTestIntfPrx uncheckedCast:[test ice_secure:NO]];
+ test(![testSecure ice_isSecure]);
+ testSecure = [TestBindingTestIntfPrx uncheckedCast:[test ice_secure:YES]];
+ test([testSecure ice_isSecure]);
+ test([test ice_getConnection] != [testSecure ice_getConnection]);
+
+ [com deactivateObjectAdapter:[adapters objectAtIndex:1]];
+
+ for(i = 0; i < 5; i++)
+ {
+ test([[test getAdapterName] isEqualToString:@"Adapter81"]);
+ [[test ice_getConnection] close:NO];
+ }
+
+ [com createObjectAdapter:@"Adapter83" endpoints:[getEndpoints(test) objectAtIndex:1]]; // Reactive tcp OA.
+
+ for(i = 0; i < 5; i++)
+ {
+ test([[test getAdapterName] isEqualToString:@"Adapter83"]);
+ [[test ice_getConnection] close:NO];
+ }
+
+ [com deactivateObjectAdapter:[adapters objectAtIndex:0]];
+ @try
+ {
+ [testSecure ice_ping];
+ test(NO);
+ }
+ @catch(ICEConnectionRefusedException*)
+ {
+ }
+
+ deactivate(com, adapters);
+ }
+ tprintf("ok\n");
+ }
+
+ [com shutdown];
+}
+
diff --git a/objc/test/Ice/binding/BindingTest.ice b/objc/test/Ice/binding/BindingTest.ice
new file mode 100644
index 00000000000..867b62f3e1b
--- /dev/null
+++ b/objc/test/Ice/binding/BindingTest.ice
@@ -0,0 +1,37 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestBinding"]
+module Test
+{
+
+interface TestIntf
+{
+ string getAdapterName();
+};
+
+interface RemoteObjectAdapter
+{
+ TestIntf* getTestIntf();
+
+ void deactivate();
+};
+
+interface RemoteCommunicator
+{
+ RemoteObjectAdapter* createObjectAdapter(string name, string endpoints);
+
+ void deactivateObjectAdapter(RemoteObjectAdapter* adapter);
+
+ void shutdown();
+};
+
+};
diff --git a/objc/test/Ice/binding/Client.m b/objc/test/Ice/binding/Client.m
new file mode 100644
index 00000000000..34315765336
--- /dev/null
+++ b/objc/test/Ice/binding/Client.m
@@ -0,0 +1,75 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <BindingTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ void bindingAllTests(id<ICECommunicator>);
+ bindingAllTests(communicator);
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main bindingClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestBinding", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/binding/Makefile b/objc/test/Ice/binding/Makefile
new file mode 100644
index 00000000000..faaade67717
--- /dev/null
+++ b/objc/test/Ice/binding/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = BindingTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/binding/Server.m b/objc/test/Ice/binding/Server.m
new file mode 100644
index 00000000000..bfcdec84bf0
--- /dev/null
+++ b/objc/test/Ice/binding/Server.m
@@ -0,0 +1,86 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <binding/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+ ICEIdentity* ident = [communicator stringToIdentity:@"communicator"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adapter add:[[[RemoteCommunicatorI alloc] init] autorelease] identity:ident];
+#else
+ [adapter add:[[RemoteCommunicatorI alloc] init] identity:ident];
+#endif
+ [adapter activate];
+
+ // Disable ready print for further adapters.
+ [[communicator getProperties] setProperty:@"Ice.PrintAdapterReady" value:@"0"];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main bindingServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ @autoreleasepool
+ {
+ int status;
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestBinding", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+ }
+}
diff --git a/objc/test/Ice/binding/TestI.h b/objc/test/Ice/binding/TestI.h
new file mode 100644
index 00000000000..142d231ade1
--- /dev/null
+++ b/objc/test/Ice/binding/TestI.h
@@ -0,0 +1,35 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <BindingTest.h>
+
+@interface RemoteCommunicatorI : TestBindingRemoteCommunicator<TestBindingRemoteCommunicator>
+{
+ int nextPort_;
+}
+-(id<TestBindingRemoteObjectAdapterPrx>) createObjectAdapter:(NSMutableString *)name
+ endpoints:(NSMutableString *)endpoints current:(ICECurrent *)current;
+-(void) deactivateObjectAdapter:(id<TestBindingRemoteObjectAdapterPrx>)adapter current:(ICECurrent *)current;
+-(void) shutdown:(ICECurrent *)current;
+@end
+
+@interface RemoteObjectAdapterI : TestBindingRemoteObjectAdapter<TestBindingRemoteObjectAdapter>
+{
+ id<ICEObjectAdapter> adapter_;
+ id<TestBindingTestIntfPrx> testIntf_;
+}
+-(id)initWithAdapter:(id<ICEObjectAdapter>)adapter;
+-(id<TestBindingTestIntfPrx>) getTestIntf:(ICECurrent *)current;
+-(void) deactivate:(ICECurrent *)current;
+@end
+
+@interface TestBindingI : TestBindingTestIntf<TestBindingTestIntf>
+-(NSString *) getAdapterName:(ICECurrent *)current;
+@end
+
diff --git a/objc/test/Ice/binding/TestI.m b/objc/test/Ice/binding/TestI.m
new file mode 100644
index 00000000000..d7f4cb112ba
--- /dev/null
+++ b/objc/test/Ice/binding/TestI.m
@@ -0,0 +1,105 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <binding/TestI.h>
+
+@implementation RemoteCommunicatorI
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ nextPort_ = 10001;
+ return self;
+}
+
+
+-(id<TestBindingRemoteObjectAdapterPrx>) createObjectAdapter:(NSMutableString*)name endpoints:(NSMutableString*)endpts
+ current:(ICECurrent*)current
+{
+ id<ICECommunicator> com = [current.adapter getCommunicator];
+ [[com getProperties] setProperty:[name stringByAppendingString:@".ThreadPool.Size"] value:@"1"];
+ id<ICEObjectAdapter> adapter = [com createObjectAdapterWithEndpoints:name endpoints:endpts];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ RemoteObjectAdapterI* remote = [[[RemoteObjectAdapterI alloc] initWithAdapter:adapter] autorelease];
+#else
+ RemoteObjectAdapterI* remote = [[RemoteObjectAdapterI alloc] initWithAdapter:adapter];
+#endif
+ return [TestBindingRemoteObjectAdapterPrx uncheckedCast:[current.adapter addWithUUID:remote]];
+}
+
+-(void) deactivateObjectAdapter:(id<TestBindingRemoteObjectAdapterPrx>)adapter current:(ICECurrent*)current
+{
+ [adapter deactivate]; // Collocated call
+}
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
+
+@implementation RemoteObjectAdapterI
+-(id) initWithAdapter:(id<ICEObjectAdapter>)adapter
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+#if defined(__clang__) && !__has_feature(objc_arc)
+ adapter_ = [adapter retain];
+ testIntf_ = [TestBindingTestIntfPrx uncheckedCast:[adapter_ add:[[[TestBindingI alloc] init] autorelease]
+ identity:[[adapter_ getCommunicator] stringToIdentity:@"test"]]];
+ [testIntf_ retain];
+#else
+ adapter_ = adapter;
+ testIntf_ = [TestBindingTestIntfPrx uncheckedCast:[
+ adapter_ add:[[TestBindingI alloc] init]
+ identity:[[adapter_ getCommunicator] stringToIdentity:@"test"]]];
+#endif
+ [adapter_ activate];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [testIntf_ release];
+ [adapter_ release];
+ [super dealloc];
+}
+#endif
+
+-(id<TestBindingTestIntfPrx>) getTestIntf:(ICECurrent*)current
+{
+ return testIntf_;
+}
+
+-(void) deactivate:(ICECurrent*)current
+{
+ @try
+ {
+ [adapter_ destroy];
+ }
+ @catch(ICEObjectAdapterDeactivatedException*)
+ {
+ }
+}
+@end
+
+@implementation TestBindingI
+-(NSString*) getAdapterName:(ICECurrent*)current
+{
+ return [current.adapter getName];
+}
+@end
diff --git a/objc/test/Ice/binding/run.py b/objc/test/Ice/binding/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/binding/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/defaultServant/.gitignore b/objc/test/Ice/defaultServant/.gitignore
new file mode 100644
index 00000000000..f330ebd1012
--- /dev/null
+++ b/objc/test/Ice/defaultServant/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+DefaultServantTest.m
+DefaultServantTest.h
diff --git a/objc/test/Ice/defaultServant/Client.m b/objc/test/Ice/defaultServant/Client.m
new file mode 100644
index 00000000000..fb48ecc4ac0
--- /dev/null
+++ b/objc/test/Ice/defaultServant/Client.m
@@ -0,0 +1,204 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <DefaultServantTest.h>
+#import <defaultServant/MyObjectI.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ //
+ // Create OA
+ //
+ id<ICEObjectAdapter> oa = [communicator createObjectAdapterWithEndpoints:@"MyOA" endpoints:@"tcp -h localhost"];
+ [oa activate];
+ ICEObject* servant = [[TestDefaultServantMyObjectI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [servant autorelease];
+#endif
+ //
+ // Register default servant with category "foo"
+ //
+ [oa addDefaultServant:servant category:@"foo"];
+
+ //
+ // Start test
+ //
+ tprintf("testing single category... ");
+ ICEObject* r = [oa findDefaultServant:@"foo"];
+ test(r == servant);
+
+ r = [oa findDefaultServant:@"bar"];
+ test(r == nil);
+
+ ICEIdentity* identity = [ICEIdentity identity:@"" category:@"foo"];
+ NSArray* stringArray = [NSArray arrayWithObjects:@"foo", @"bar", @"x", @"y", @"abcdefg", nil];
+
+ for(NSString* name in stringArray)
+ {
+ [identity setName:name];
+ id<TestDefaultServantMyObjectPrx> prx = [TestDefaultServantMyObjectPrx uncheckedCast:[oa createProxy:identity]];
+ [prx ice_ping];
+ test([[prx getName] isEqualToString:name]);
+ }
+
+ [identity setName:@"ObjectNotExist"];
+ id<TestDefaultServantMyObjectPrx> prx = [TestDefaultServantMyObjectPrx uncheckedCast:[oa createProxy:identity]];
+ @try
+ {
+ [prx ice_ping];
+ //test(NO);
+ }
+ @catch(ICEObjectNotExistException*)
+ {
+ // expected
+ }
+ @try
+ {
+ [prx getName];
+ test(NO);
+ }
+ @catch(ICEObjectNotExistException*)
+ {
+ // expected
+ }
+
+ [identity setName:@"FacetNotExist"];
+ prx = [TestDefaultServantMyObjectPrx uncheckedCast:[oa createProxy:identity]];
+
+ @try
+ {
+ [prx ice_ping];
+ test(NO);
+ }
+ @catch(ICEFacetNotExistException*)
+ {
+ // expected
+ }
+
+ @try
+ {
+ [prx getName];
+ test(NO);
+ }
+ @catch(ICEFacetNotExistException*)
+ {
+ // expected
+ }
+
+ [identity setCategory:@"bar"];
+ for(NSString* name in stringArray)
+ {
+ [identity setName:name];
+ id<TestDefaultServantMyObjectPrx> prx = [TestDefaultServantMyObjectPrx uncheckedCast:[oa createProxy:identity]];
+
+ @try
+ {
+ [prx ice_ping];
+ test(NO);
+ }
+ @catch(ICEObjectNotExistException*)
+ {
+ }
+
+ @try
+ {
+ [prx getName];
+ test(NO);
+ }
+ @catch(ICEObjectNotExistException*)
+ {
+ }
+ }
+ tprintf("ok\n");
+ tprintf("testing default category... ");
+
+ [oa addDefaultServant:servant category:@""];
+
+ r = [oa findDefaultServant:@"bar"];
+ test(r == nil);
+
+ r = [oa findDefaultServant:@""];
+ test(r == servant);
+
+ for(NSString* name in stringArray)
+ {
+ [identity setName:name];
+ id<TestDefaultServantMyObjectPrx> prx = [TestDefaultServantMyObjectPrx uncheckedCast:[oa createProxy:identity]];
+ [prx ice_ping];
+ test([[prx getName] isEqualToString:name]);
+ }
+ tprintf("ok\n");
+ return 0;
+}
+
+#if TARGET_OS_IPHONE
+# define main defaultServantClient
+
+int
+defaultServantServer(int argc, char* argv[])
+{
+ serverReady(nil);
+ return 0;
+}
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestDefaultServant", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
+
diff --git a/objc/test/Ice/defaultServant/DefaultServantTest.ice b/objc/test/Ice/defaultServant/DefaultServantTest.ice
new file mode 100644
index 00000000000..cba349190f8
--- /dev/null
+++ b/objc/test/Ice/defaultServant/DefaultServantTest.ice
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestDefaultServant"]
+module Test
+{
+
+interface MyObject
+{
+ string getName();
+};
+
+};
diff --git a/objc/test/Ice/defaultServant/Makefile b/objc/test/Ice/defaultServant/Makefile
new file mode 100644
index 00000000000..c050bf6f0f0
--- /dev/null
+++ b/objc/test/Ice/defaultServant/Makefile
@@ -0,0 +1,29 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = DefaultServantTest.o
+
+COBJS = Client.o \
+ MyObjectI.o
+
+OBJS = $(COBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/defaultServant/MyObjectI.h b/objc/test/Ice/defaultServant/MyObjectI.h
new file mode 100644
index 00000000000..22c7d09e5db
--- /dev/null
+++ b/objc/test/Ice/defaultServant/MyObjectI.h
@@ -0,0 +1,13 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <DefaultServantTest.h>
+
+@interface TestDefaultServantMyObjectI : TestDefaultServantMyObject<TestDefaultServantMyObject>
+@end
diff --git a/objc/test/Ice/defaultServant/MyObjectI.m b/objc/test/Ice/defaultServant/MyObjectI.m
new file mode 100644
index 00000000000..fc726d2452f
--- /dev/null
+++ b/objc/test/Ice/defaultServant/MyObjectI.m
@@ -0,0 +1,46 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <defaultServant/MyObjectI.h>
+
+@implementation TestDefaultServantMyObjectI
+
+-(void) ice_ping:(ICECurrent*)current
+{
+ NSString* name = current.id_.name;
+
+ if([name isEqualToString:@"ObjectNotExist"])
+ {
+ @throw [ICEObjectNotExistException objectNotExistException:__FILE__ line:__LINE__];
+ }
+
+ if([name isEqualToString:@"FacetNotExist"])
+ {
+ @throw [ICEFacetNotExistException facetNotExistException:__FILE__ line:__LINE__];
+ }
+}
+
+-(NSString*) getName:(ICECurrent*)current
+{
+ NSString* name = current.id_.name;
+
+ if([name isEqualToString:@"ObjectNotExist"])
+ {
+ @throw [ICEObjectNotExistException objectNotExistException:__FILE__ line:__LINE__];
+ }
+
+ if([name isEqualToString:@"FacetNotExist"])
+ {
+ @throw [ICEFacetNotExistException facetNotExistException:__FILE__ line:__LINE__];
+ }
+
+ return name;
+}
+@end
diff --git a/objc/test/Ice/defaultServant/run.py b/objc/test/Ice/defaultServant/run.py
new file mode 100755
index 00000000000..eed9bface4f
--- /dev/null
+++ b/objc/test/Ice/defaultServant/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+client = os.path.join(os.getcwd(), "client")
+
+TestUtil.simpleTest(client)
diff --git a/objc/test/Ice/defaultValue/.gitignore b/objc/test/Ice/defaultValue/.gitignore
new file mode 100644
index 00000000000..e4c2ca683a3
--- /dev/null
+++ b/objc/test/Ice/defaultValue/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+DefaultValueTest.m
+DefaultValueTest.h
diff --git a/objc/test/Ice/defaultValue/AllTests.m b/objc/test/Ice/defaultValue/AllTests.m
new file mode 100644
index 00000000000..8f389d93624
--- /dev/null
+++ b/objc/test/Ice/defaultValue/AllTests.m
@@ -0,0 +1,110 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <DefaultValueTest.h>
+
+#import <Foundation/Foundation.h>
+
+void
+defaultValueAllTests()
+{
+ tprintf("testing default values... ");
+
+ {
+ TestDefaultValueStruct1* v = [TestDefaultValueStruct1 struct1];
+ test(!v.boolFalse);
+ test(v.boolTrue);
+ test(v.b == 254);
+ test(v.s == 16000);
+ test(v.i == 3);
+ test(v.l == 4);
+ test(v.f == 5.0);
+ test(v.d == 6.0);
+ test([v.str isEqualToString:@"foo bar"]);
+ test(v.c == TestDefaultValuered);
+ test([v.noDefault length] == 0);
+ }
+
+ {
+ TestDefaultValueStruct2* v = [TestDefaultValueStruct2 struct2];
+ test(!v.boolFalse);
+ test(v.boolTrue);
+ test(v.b == 1);
+ test(v.s == 2);
+ test(v.i == 3);
+ test(v.l == 4);
+ test(v.f == 5.0);
+ test(v.d == 6.0);
+ test([v.str isEqualToString:@"foo bar"]);
+ test(v.c == TestDefaultValueblue);
+ test([v.noDefault length] == 0);
+ }
+
+ {
+ TestDefaultValueBase* v = [TestDefaultValueBase base];
+ test(!v.boolFalse);
+ test(v.boolTrue);
+ test(v.b == 1);
+ test(v.s == 2);
+ test(v.i == 3);
+ test(v.l == 4);
+ test(v.f == 5.0);
+ test(v.d == 6.0);
+ test([v.str isEqualToString:@"foo bar"]);
+ test([v.noDefault length] == 0);
+ }
+
+ {
+ TestDefaultValueDerived* v = [TestDefaultValueDerived derived];
+ test(!v.boolFalse);
+ test(v.boolTrue);
+ test(v.b == 1);
+ test(v.s == 2);
+ test(v.i == 3);
+ test(v.l == 4);
+ test(v.f == 5.0);
+ test(v.d == 6.0);
+ test([v.str isEqualToString:@"foo bar"]);
+ test([v.noDefault length] == 0);
+ test(v.c == TestDefaultValuegreen);
+ }
+
+ {
+ TestDefaultValueBaseEx* v = [TestDefaultValueBaseEx baseEx];
+ test(!v.boolFalse);
+ test(v.boolTrue);
+ test(v.b == 1);
+ test(v.s == 2);
+ test(v.i == 3);
+ test(v.l == 4);
+ test(v.f == 5.0);
+ test(v.d == 6.0);
+ test([v.str isEqualToString:@"foo bar"]);
+ test([v.noDefault length] == 0);
+ }
+
+ {
+ TestDefaultValueDerivedEx* v = [TestDefaultValueDerivedEx derivedEx];
+ test(!v.boolFalse);
+ test(v.boolTrue);
+ test(v.b == 1);
+ test(v.s == 2);
+ test(v.i == 3);
+ test(v.l == 4);
+ test(v.f == 5.0);
+ test(v.d == 6.0);
+ test([v.str isEqualToString:@"foo bar"]);
+ test([v.noDefault length] == 0);
+ test(v.c == TestDefaultValuegreen);
+ }
+
+ tprintf("ok\n");
+}
diff --git a/objc/test/Ice/defaultValue/Client.m b/objc/test/Ice/defaultValue/Client.m
new file mode 100644
index 00000000000..94fa41cf8c9
--- /dev/null
+++ b/objc/test/Ice/defaultValue/Client.m
@@ -0,0 +1,53 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <DefaultValueTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run()
+{
+ void defaultValueAllTests();
+ defaultValueAllTests();
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main defaultValueClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ @autoreleasepool
+ {
+ int status;
+ @try
+ {
+ status = run();
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+ }
+}
diff --git a/objc/test/Ice/defaultValue/DefaultValueTest.ice b/objc/test/Ice/defaultValue/DefaultValueTest.ice
new file mode 100644
index 00000000000..93e2eee3fd8
--- /dev/null
+++ b/objc/test/Ice/defaultValue/DefaultValueTest.ice
@@ -0,0 +1,87 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestDefaultValue"]
+module Test
+{
+
+enum Color { red, green, blue };
+
+struct Struct1
+{
+ bool boolFalse = false;
+ bool boolTrue = true;
+ byte b = 254;
+ short s = 16000;
+ int i = 3;
+ long l = 4;
+ float f = 5.0;
+ double d = 6.0;
+ string str = "foo bar";
+ Color c = red;
+ string noDefault;
+};
+
+["cpp:class"]
+struct Struct2
+{
+ bool boolFalse = false;
+ bool boolTrue = true;
+ byte b = 1;
+ short s = 2;
+ int i = 3;
+ long l = 4;
+ float f = 5.0;
+ double d = 6.0;
+ string str = "foo bar";
+ Color c = blue;
+ string noDefault;
+};
+
+class Base
+{
+ bool boolFalse = false;
+ bool boolTrue = true;
+ byte b = 1;
+ short s = 2;
+ int i = 3;
+ long l = 4;
+ float f = 5.0;
+ double d = 6.0;
+ string str = "foo bar";
+ string noDefault;
+};
+
+class Derived extends Base
+{
+ Color c = green;
+};
+
+exception BaseEx
+{
+ bool boolFalse = false;
+ bool boolTrue = true;
+ byte b = 1;
+ short s = 2;
+ int i = 3;
+ long l = 4;
+ float f = 5.0;
+ double d = 6.0;
+ string str = "foo bar";
+ string noDefault;
+};
+
+exception DerivedEx extends BaseEx
+{
+ Color c = green;
+};
+
+};
diff --git a/objc/test/Ice/defaultValue/Makefile b/objc/test/Ice/defaultValue/Makefile
new file mode 100644
index 00000000000..a116331df5a
--- /dev/null
+++ b/objc/test/Ice/defaultValue/Makefile
@@ -0,0 +1,29 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = DefaultValueTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+OBJS = $(COBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/defaultValue/run.py b/objc/test/Ice/defaultValue/run.py
new file mode 100755
index 00000000000..ac32c445572
--- /dev/null
+++ b/objc/test/Ice/defaultValue/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+client = os.path.join(os.getcwd(), "client")
+TestUtil.simpleTest(client)
+
diff --git a/objc/test/Ice/dispatcher/.gitignore b/objc/test/Ice/dispatcher/.gitignore
new file mode 100644
index 00000000000..b814b2f0fbb
--- /dev/null
+++ b/objc/test/Ice/dispatcher/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+DispatcherTest.m
+DispatcherTest.h
diff --git a/objc/test/Ice/dispatcher/AllTests.m b/objc/test/Ice/dispatcher/AllTests.m
new file mode 100644
index 00000000000..cb93d5b2ea0
--- /dev/null
+++ b/objc/test/Ice/dispatcher/AllTests.m
@@ -0,0 +1,156 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <DispatcherTest.h>
+
+#import <Foundation/Foundation.h>
+
+NSThread* dispatcherThread = nil;
+
+static BOOL isDispatcherThread()
+{
+ if(dispatcherThread == nil)
+ {
+ dispatcherThread = [NSThread currentThread];
+ test(dispatcherThread);
+ }
+ return dispatcherThread == [NSThread currentThread];
+}
+
+@interface TestDispatcherCallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+}
+-(void) check;
+-(void) called;
+@end
+
+@implementation TestDispatcherCallback
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) check
+{
+ [cond lock];
+ while(!called)
+ {
+ [cond wait];
+ }
+ called = NO;
+ [cond unlock];
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) response
+{
+ test(isDispatcherThread());
+ [self called];
+}
+
+-(void) exception:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICENoEndpointException class]]);
+ test(isDispatcherThread());
+ [self called];
+}
+
+-(void) payload
+{
+ test(isDispatcherThread());
+}
+
+-(void) ignoreEx:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICECommunicatorDestroyedException class]]);
+}
+
+-(void) sent:(BOOL)sentSynchronously
+{
+ test(sentSynchronously || isDispatcherThread());
+}
+
+@end
+
+id<TestDispatcherTestIntfPrx>
+dispatcherAllTests(id<ICECommunicator> communicator)
+{
+ NSString* sref = @"test:default -p 12010";
+ id<ICEObjectPrx> obj = [communicator stringToProxy:sref];
+ test(obj);
+
+ id<TestDispatcherTestIntfPrx> p = [TestDispatcherTestIntfPrx uncheckedCast:obj];
+
+ sref = @"testController:tcp -p 12011";
+ obj = [communicator stringToProxy:sref];
+ test(obj);
+
+ id<TestDispatcherTestIntfControllerPrx> testController = [TestDispatcherTestIntfControllerPrx uncheckedCast:obj];
+
+ tprintf("testing dispatcher... ");
+ {
+ [p op];
+
+ TestDispatcherCallback* cb = [[TestDispatcherCallback alloc] init];
+ [p begin_op:^ { [cb response]; } exception:^(ICEException* ex) { [cb exception:ex]; }];
+ [cb check];
+
+ TestDispatcherTestIntfPrx* i = [p ice_adapterId:@"dummy"];
+ [i begin_op:^ { [cb response]; } exception:^(ICEException* ex) { [cb exception:ex]; }];
+ [cb check];
+
+ [testController holdAdapter];
+
+ ICEByte d[1024];
+ ICEMutableByteSeq* seq = [ICEMutableByteSeq dataWithBytes:d length:sizeof(d)];
+
+ id<ICEAsyncResult> result;
+ @autoreleasepool
+ {
+ id response = ^{ [cb payload]; };
+ id exception = ^(ICEException* ex) { [cb ignoreEx:ex]; };
+ id sent = ^(BOOL ss) { [cb sent:ss]; };
+
+ while([(result = [p begin_opWithPayload:seq response:response
+ exception:exception
+ sent:sent]) sentSynchronously]);
+ [testController resumeAdapter];
+ [result waitForCompleted];
+ }
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [cb release];
+#endif
+ }
+ tprintf("ok\n");
+
+ return p;
+}
diff --git a/objc/test/Ice/dispatcher/Client.m b/objc/test/Ice/dispatcher/Client.m
new file mode 100644
index 00000000000..5f1776bc34e
--- /dev/null
+++ b/objc/test/Ice/dispatcher/Client.m
@@ -0,0 +1,81 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <DispatcherTest.h>
+#include <dispatch/dispatch.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ TestDispatcherTestIntfPrx* dispatcherAllTests(id<ICECommunicator>);
+ TestDispatcherTestIntfPrx* dispatcher = dispatcherAllTests(communicator);
+ [dispatcher shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main dispatcherClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+ initData.dispatcher = ^(id<ICEDispatcherCall> call, id<ICEConnection> con) {
+ dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ { [call run]; });
+ };
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestDispatcher", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/dispatcher/DispatcherTest.ice b/objc/test/Ice/dispatcher/DispatcherTest.ice
new file mode 100644
index 00000000000..7631a9a3061
--- /dev/null
+++ b/objc/test/Ice/dispatcher/DispatcherTest.ice
@@ -0,0 +1,31 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/BuiltinSequences.ice>
+
+["objc:prefix:TestDispatcher"]
+module Test
+{
+
+interface TestIntf
+{
+ void op();
+ void opWithPayload(Ice::ByteSeq seq);
+ void shutdown();
+};
+
+interface TestIntfController
+{
+ void holdAdapter();
+ void resumeAdapter();
+};
+
+};
diff --git a/objc/test/Ice/dispatcher/Makefile b/objc/test/Ice/dispatcher/Makefile
new file mode 100644
index 00000000000..2697492c928
--- /dev/null
+++ b/objc/test/Ice/dispatcher/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = DispatcherTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/dispatcher/Server.m b/objc/test/Ice/dispatcher/Server.m
new file mode 100644
index 00000000000..24e7d58be9d
--- /dev/null
+++ b/objc/test/Ice/dispatcher/Server.m
@@ -0,0 +1,96 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <dispatcher/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ [[communicator getProperties] setProperty:@"ControllerAdapter.Endpoints" value:@"tcp -p 12011"];
+ [[communicator getProperties] setProperty:@"ControllerAdapter.ThreadPool.Size" value:@"1"];
+
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+ id<ICEObjectAdapter> adapter2 = [communicator createObjectAdapter:@"ControllerAdapter"];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ TestDispatcherTestIntfControllerI* testController
+ = [[[TestDispatcherTestIntfControllerI alloc] initWithAdapter:adapter] autorelease];
+
+ ICEObject* object = [[[TestDispatcherTestIntfI alloc] init] autorelease];
+#else
+ TestDispatcherTestIntfControllerI* testController
+ = [[TestDispatcherTestIntfControllerI alloc] initWithAdapter:adapter];
+
+ ICEObject* object = [[TestDispatcherTestIntfI alloc] init];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"test"]];
+ [adapter activate];
+
+ [adapter2 add:testController identity:[communicator stringToIdentity:@"testController"]];
+ [adapter2 activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main dispatcherServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestDispatcher", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/dispatcher/TestI.h b/objc/test/Ice/dispatcher/TestI.h
new file mode 100644
index 00000000000..c417c27415e
--- /dev/null
+++ b/objc/test/Ice/dispatcher/TestI.h
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <DispatcherTest.h>
+
+@interface TestDispatcherTestIntfI : TestDispatcherTestIntf
+-(void) op:(ICECurrent *)current;
+-(void) opWithPayload:(ICEMutableByteSeq*)seq current:(ICECurrent *)current;
+-(void) shutdown:(ICECurrent *)current;
+@end
+
+@interface TestDispatcherTestIntfControllerI : TestDispatcherTestIntfController
+{
+ id<ICEObjectAdapter> _adapter;
+}
+-(id) initWithAdapter:(id<ICEObjectAdapter>)adapter;
+-(void) holdAdapter:(ICECurrent*)current;
+-(void) resumeAdapter:(ICECurrent*)current;
+@end
diff --git a/objc/test/Ice/dispatcher/TestI.m b/objc/test/Ice/dispatcher/TestI.m
new file mode 100644
index 00000000000..6b5e3a0503a
--- /dev/null
+++ b/objc/test/Ice/dispatcher/TestI.m
@@ -0,0 +1,45 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <dispatcher/TestI.h>
+
+@implementation TestDispatcherTestIntfI
+-(void) op:(ICECurrent*)current
+{
+}
+-(void) opWithPayload:(ICEMutableByteSeq*)data current:(ICECurrent*)current
+{
+}
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
+
+@implementation TestDispatcherTestIntfControllerI
+-(id) initWithAdapter:(id<ICEObjectAdapter>)adapter
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ _adapter = adapter;
+ return self;
+}
+-(void) holdAdapter:(ICECurrent*)current
+{
+ [_adapter hold];
+}
+-(void) resumeAdapter:(ICECurrent*)current
+{
+ [_adapter activate];
+}
+@end
diff --git a/objc/test/Ice/dispatcher/run.py b/objc/test/Ice/dispatcher/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/dispatcher/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/enums/.gitignore b/objc/test/Ice/enums/.gitignore
new file mode 100644
index 00000000000..657ea9d677b
--- /dev/null
+++ b/objc/test/Ice/enums/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+EnumTest.m
+EnumTest.h
diff --git a/objc/test/Ice/enums/AllTests.m b/objc/test/Ice/enums/AllTests.m
new file mode 100644
index 00000000000..5b89a67f79c
--- /dev/null
+++ b/objc/test/Ice/enums/AllTests.m
@@ -0,0 +1,388 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <EnumTest.h>
+
+
+TestEnumTestIntfPrx*
+enumAllTests(id<ICECommunicator> communicator)
+{
+
+ ICEObjectPrx* obj = [communicator stringToProxy:@"test:default -p 12010"];
+ test(obj);
+ TestEnumTestIntfPrx* proxy = [TestEnumTestIntfPrx checkedCast:obj];
+ test(proxy);
+
+ tprintf("testing enum values... ");
+
+ test((int)(TestEnumbenum1) == 0);
+ test((int)(TestEnumbenum2) == 1);
+ test((int)(TestEnumbenum3) == TestEnumByteConst1);
+ test((int)(TestEnumbenum4) == TestEnumByteConst1 + 1);
+ test((int)(TestEnumbenum5) == TestEnumShortConst1);
+ test((int)(TestEnumbenum6) == TestEnumShortConst1 + 1);
+ test((int)(TestEnumbenum7) == TestEnumIntConst1);
+ test((int)(TestEnumbenum8) == TestEnumIntConst1 + 1);
+ test((int)(TestEnumbenum9) == TestEnumLongConst1);
+ test((int)(TestEnumbenum10) == TestEnumLongConst1 + 1);
+ test((int)(TestEnumbenum11) == TestEnumByteConst2);
+
+ test((int)(TestEnumsenum1) == 3);
+ test((int)(TestEnumsenum2) == 4);
+ test((int)(TestEnumsenum3) == TestEnumByteConst1);
+ test((int)(TestEnumsenum4) == TestEnumByteConst1 + 1);
+ test((int)(TestEnumsenum5) == TestEnumShortConst1);
+ test((int)(TestEnumsenum6) == TestEnumShortConst1 + 1);
+ test((int)(TestEnumsenum7) == TestEnumIntConst1);
+ test((int)(TestEnumsenum8) == TestEnumIntConst1 + 1);
+ test((int)(TestEnumsenum9) == TestEnumLongConst1);
+ test((int)(TestEnumsenum10) == TestEnumLongConst1 + 1);
+ test((int)(TestEnumsenum11) == TestEnumShortConst2);
+
+ test((int)(TestEnumienum1) == 0);
+ test((int)(TestEnumienum2) == 1);
+ test((int)(TestEnumienum3) == TestEnumByteConst1);
+ test((int)(TestEnumienum4) == TestEnumByteConst1 + 1);
+ test((int)(TestEnumienum5) == TestEnumShortConst1);
+ test((int)(TestEnumienum6) == TestEnumShortConst1 + 1);
+ test((int)(TestEnumienum7) == TestEnumIntConst1);
+ test((int)(TestEnumienum8) == TestEnumIntConst1 + 1);
+ test((int)(TestEnumienum9) == TestEnumLongConst1);
+ test((int)(TestEnumienum10) == TestEnumLongConst1 + 1);
+ test((int)(TestEnumienum11) == TestEnumIntConst2);
+ test((int)(TestEnumienum12) == TestEnumLongConst2);
+
+ test((int)(TestEnumred) == 0);
+ test((int)(TestEnumgreen) == 1);
+ test((int)(TestEnumblue) == 2);
+
+ tprintf("ok\n");
+
+ tprintf("testing enum operations... ");
+
+ TestEnumByteEnum byteEnum;
+ test([proxy opByte:TestEnumbenum1 b2:&byteEnum] == TestEnumbenum1);
+ test(byteEnum == TestEnumbenum1);
+ test([proxy opByte:TestEnumbenum11 b2:&byteEnum] == TestEnumbenum11);
+ test(byteEnum == TestEnumbenum11);
+
+ TestEnumShortEnum shortEnum;
+ test([proxy opShort:TestEnumsenum1 s2:&shortEnum] == TestEnumsenum1);
+ test(shortEnum == TestEnumsenum1);
+ test([proxy opShort:TestEnumsenum11 s2:&shortEnum] == TestEnumsenum11);
+ test(shortEnum == TestEnumsenum11);
+
+ TestEnumIntEnum intEnum;
+ test([proxy opInt:TestEnumienum1 i2:&intEnum] == TestEnumienum1);
+ test(intEnum == TestEnumienum1);
+ test([proxy opInt:TestEnumienum11 i2:&intEnum] == TestEnumienum11);
+ test(intEnum == TestEnumienum11);
+ test([proxy opInt:TestEnumienum12 i2:&intEnum] == TestEnumienum12);
+ test(intEnum == TestEnumienum12);
+
+ TestEnumSimpleEnum s;
+ test([proxy opSimple:TestEnumgreen s2:&s] == TestEnumgreen);
+ test(s == TestEnumgreen);
+ tprintf("ok\n");
+
+ tprintf("testing enum sequences operations... ");
+
+ {
+ TestEnumByteEnum values[] = {TestEnumbenum1, TestEnumbenum2, TestEnumbenum3, TestEnumbenum4, TestEnumbenum5,
+ TestEnumbenum6, TestEnumbenum7, TestEnumbenum8, TestEnumbenum9, TestEnumbenum10,
+ TestEnumbenum11};
+
+ int enumSize = sizeof(TestEnumByteEnum);
+ int length = sizeof(values);
+ int elements = length/enumSize;
+
+ TestEnumMutableByteEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableByteEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ TestEnumByteEnumSeq* enumSeq3 = [proxy opByteSeq:enumSeq1 b2:&enumSeq2];
+
+ ICEByte* p1 = (ICEByte *)[enumSeq1 bytes];
+ ICEByte* p2 = (ICEByte *)[enumSeq2 bytes];
+ ICEByte* p3 = (ICEByte *)[enumSeq3 bytes];
+
+ for(int i = 0; i < elements; ++i)
+ {
+ test(*p1 == *p2);
+ test(*p1 == *p3);
+ p1++;
+ p2++;
+ p3++;
+ }
+ }
+
+ {
+
+ TestEnumShortEnum values[] = {TestEnumsenum1, TestEnumsenum2, TestEnumsenum3, TestEnumsenum4, TestEnumsenum5,
+ TestEnumsenum6, TestEnumsenum7, TestEnumsenum8, TestEnumsenum9, TestEnumsenum10,
+ TestEnumsenum11};
+
+ int enumSize = sizeof(TestEnumShortEnum);
+ int length = sizeof(values);
+ int elements = length/enumSize;
+
+ TestEnumMutableShortEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableShortEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ TestEnumShortEnumSeq* enumSeq3 = [proxy opShortSeq:enumSeq1 s2:&enumSeq2];
+
+ ICEByte* p1 = (ICEByte *)[enumSeq1 bytes];
+ ICEByte* p2 = (ICEByte *)[enumSeq2 bytes];
+ ICEByte* p3 = (ICEByte *)[enumSeq3 bytes];
+
+ for(int i = 0; i < elements; ++i)
+ {
+ test(*p1 == *p2);
+ test(*p1 == *p3);
+ p1++;
+ p2++;
+ p3++;
+ }
+ }
+
+ {
+
+ TestEnumIntEnum values[] = {TestEnumienum1, TestEnumienum2, TestEnumienum3, TestEnumienum4, TestEnumienum5,
+ TestEnumienum6, TestEnumienum7, TestEnumienum8, TestEnumienum9, TestEnumienum10,
+ TestEnumienum11};
+
+ int enumSize = sizeof(TestEnumShortEnum);
+ int length = sizeof(values);
+ int elements = length/enumSize;
+
+ TestEnumMutableShortEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableShortEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ TestEnumShortEnumSeq* enumSeq3 = [proxy opIntSeq:enumSeq1 i2:&enumSeq2];
+
+ ICEByte* p1 = (ICEByte *)[enumSeq1 bytes];
+ ICEByte* p2 = (ICEByte *)[enumSeq2 bytes];
+ ICEByte* p3 = (ICEByte *)[enumSeq3 bytes];
+
+ for(int i = 0; i < elements; ++i)
+ {
+ test(*p1 == *p2);
+ test(*p1 == *p3);
+ p1++;
+ p2++;
+ p3++;
+ }
+ }
+
+ {
+
+ TestEnumSimpleEnum values[] = {TestEnumred, TestEnumgreen, TestEnumblue};
+
+ int enumSize = sizeof(TestEnumShortEnum);
+ int length = sizeof(values);
+ int elements = length/enumSize;
+
+ TestEnumMutableShortEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableShortEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ TestEnumShortEnumSeq* enumSeq3 = [proxy opSimpleSeq:enumSeq1 s2:&enumSeq2];
+
+ ICEByte* p1 = (ICEByte *)[enumSeq1 bytes];
+ ICEByte* p2 = (ICEByte *)[enumSeq2 bytes];
+ ICEByte* p3 = (ICEByte *)[enumSeq3 bytes];
+
+ for(int i = 0; i < elements; ++i)
+ {
+ test(*p1 == *p2);
+ test(*p1 == *p3);
+ p1++;
+ p2++;
+ p3++;
+ }
+ }
+
+ tprintf("ok\n");
+
+ tprintf("testing enum exceptions... ");
+
+ @try
+ {
+ [proxy opByte:(TestEnumByteEnum)-1 b2:&byteEnum]; // Negative enumerators are not supported
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+
+ @try
+ {
+ [proxy opByte:(TestEnumByteEnum)127 b2:&byteEnum]; // Invalid enumerator
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+
+ @try
+ {
+ [proxy opShort:(TestEnumShortEnum)-1 s2:&shortEnum]; // Negative enumerators are not supported
+ test(NO);
+ }
+ @catch(const ICEMarshalException*)
+ {
+ }
+
+ @try
+ {
+ [proxy opShort:(TestEnumShortEnum)0 s2:&shortEnum]; // Invalid enumerator
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+
+ @try
+ {
+ [proxy opShort:(TestEnumShortEnum)32767 s2:&shortEnum]; // Invalid enumerator
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+
+ @try
+ {
+ [proxy opInt:(TestEnumIntEnum)-1 i2:&intEnum]; // Negative enumerators are not supported
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+
+ {
+ TestEnumByteEnum values[] = {TestEnumbenum1, TestEnumbenum2, TestEnumbenum3, TestEnumbenum4, TestEnumbenum5,
+ TestEnumbenum6, (TestEnumByteEnum)-1, TestEnumbenum8, TestEnumbenum9, TestEnumbenum10,
+ TestEnumbenum11}; // Negative enumerators are not supported
+
+ int length = sizeof(values);
+
+ TestEnumMutableByteEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableByteEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ @try
+ {
+ [proxy opByteSeq:enumSeq1 b2:&enumSeq2];
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+ }
+
+ {
+ TestEnumByteEnum values[] = {TestEnumbenum1, TestEnumbenum2, TestEnumbenum3, TestEnumbenum4, TestEnumbenum5,
+ TestEnumbenum6, (TestEnumByteEnum)127, TestEnumbenum8, TestEnumbenum9, TestEnumbenum10,
+ TestEnumbenum11}; // Invalid enumerator
+
+ int length = sizeof(values);
+
+ TestEnumMutableByteEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableByteEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ @try
+ {
+ [proxy opByteSeq:enumSeq1 b2:&enumSeq2];
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+ }
+
+ {
+
+ TestEnumShortEnum values[] = {TestEnumsenum1, TestEnumsenum2, TestEnumsenum3, TestEnumsenum4, TestEnumsenum5,
+ (TestEnumShortEnum)-1, TestEnumsenum7, TestEnumsenum8, TestEnumsenum9, TestEnumsenum10,
+ TestEnumsenum11}; // Negative enumerators are not supported
+
+ int length = sizeof(values);
+
+ TestEnumMutableShortEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableShortEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ @try
+ {
+ [proxy opShortSeq:enumSeq1 s2:&enumSeq2];
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+ }
+
+ {
+
+ TestEnumShortEnum values[] = {TestEnumsenum1, TestEnumsenum2, TestEnumsenum3, TestEnumsenum4, TestEnumsenum5,
+ (TestEnumShortEnum)0, TestEnumsenum7, TestEnumsenum8, TestEnumsenum9, TestEnumsenum10,
+ TestEnumsenum11}; // Invalid enumerator
+
+ int length = sizeof(values);
+
+ TestEnumMutableShortEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableShortEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ @try
+ {
+ [proxy opShortSeq:enumSeq1 s2:&enumSeq2];
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+ }
+
+ {
+
+ TestEnumShortEnum values[] = {TestEnumsenum1, TestEnumsenum2, TestEnumsenum3, TestEnumsenum4, TestEnumsenum5,
+ (TestEnumShortEnum)32767, TestEnumsenum7, TestEnumsenum8, TestEnumsenum9, TestEnumsenum10,
+ TestEnumsenum11}; // Invalid enumerator
+
+ int length = sizeof(values);
+
+ TestEnumMutableShortEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableShortEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ @try
+ {
+ [proxy opShortSeq:enumSeq1 s2:&enumSeq2];
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+ }
+
+ {
+
+ TestEnumIntEnum values[] = {TestEnumienum1, TestEnumienum2, TestEnumienum3, TestEnumienum4, TestEnumienum5,
+ (TestEnumIntEnum)-1, TestEnumienum7, TestEnumienum8, TestEnumienum9, TestEnumienum10,
+ TestEnumienum11}; // Negative enumerators are not supported
+
+ int length = sizeof(values);
+
+ TestEnumMutableShortEnumSeq* enumSeq1 = [NSMutableData dataWithBytes:values length:length];
+ TestEnumMutableShortEnumSeq* enumSeq2 = [NSMutableData dataWithLength:length];
+ @try
+ {
+ [proxy opIntSeq:enumSeq1 i2:&enumSeq2];
+ test(NO);
+ }
+ @catch(ICEMarshalException*)
+ {
+ }
+ }
+
+
+
+ tprintf("ok\n");
+
+ return proxy;
+}
diff --git a/objc/test/Ice/enums/Client.m b/objc/test/Ice/enums/Client.m
new file mode 100644
index 00000000000..3e9b09fa86d
--- /dev/null
+++ b/objc/test/Ice/enums/Client.m
@@ -0,0 +1,79 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <EnumTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ TestEnumTestIntfPrx* enumAllTests(id<ICECommunicator>);
+ TestEnumTestIntfPrx* test = enumAllTests(communicator);
+
+ [test shutdown];
+
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main enumClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestEnum", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/enums/EnumTest.ice b/objc/test/Ice/enums/EnumTest.ice
new file mode 100644
index 00000000000..762bc7d89d4
--- /dev/null
+++ b/objc/test/Ice/enums/EnumTest.ice
@@ -0,0 +1,98 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestEnum"]
+module Test
+{
+
+const byte ByteConst1 = 10;
+const short ShortConst1 = 20;
+const int IntConst1 = 30;
+const long LongConst1 = 40;
+
+const byte ByteConst2 = 126;
+const short ShortConst2 = 32766;
+const int IntConst2 = 2147483647;
+const long LongConst2 = 2147483646;
+
+enum ByteEnum
+{
+ benum1,
+ benum2,
+ benum3 = ByteConst1,
+ benum4,
+ benum5 = ShortConst1,
+ benum6,
+ benum7 = IntConst1,
+ benum8,
+ benum9 = LongConst1,
+ benum10,
+ benum11 = ByteConst2
+};
+sequence<ByteEnum> ByteEnumSeq;
+
+enum ShortEnum
+{
+ senum1 = 3,
+ senum2,
+ senum3 = ByteConst1,
+ senum4,
+ senum5 = ShortConst1,
+ senum6,
+ senum7 = IntConst1,
+ senum8,
+ senum9 = LongConst1,
+ senum10,
+ senum11 = ShortConst2
+};
+sequence<ShortEnum> ShortEnumSeq;
+
+enum IntEnum
+{
+ ienum1,
+ ienum2,
+ ienum3 = ByteConst1,
+ ienum4,
+ ienum5 = ShortConst1,
+ ienum6,
+ ienum7 = IntConst1,
+ ienum8,
+ ienum9 = LongConst1,
+ ienum10,
+ ienum11 = IntConst2,
+ ienum12 = LongConst2
+};
+sequence<IntEnum> IntEnumSeq;
+
+enum SimpleEnum
+{
+ red,
+ green,
+ blue
+};
+sequence<SimpleEnum> SimpleEnumSeq;
+
+interface TestIntf
+{
+ ByteEnum opByte(ByteEnum b1, out ByteEnum b2);
+ ShortEnum opShort(ShortEnum s1, out ShortEnum s2);
+ IntEnum opInt(IntEnum i1, out IntEnum i2);
+ SimpleEnum opSimple(SimpleEnum s1, out SimpleEnum s2);
+
+ ByteEnumSeq opByteSeq(ByteEnumSeq b1, out ByteEnumSeq b2);
+ ShortEnumSeq opShortSeq(ShortEnumSeq s1, out ShortEnumSeq s2);
+ IntEnumSeq opIntSeq(IntEnumSeq i1, out IntEnumSeq i2);
+ SimpleEnumSeq opSimpleSeq(SimpleEnumSeq s1, out SimpleEnumSeq s2);
+
+ void shutdown();
+};
+
+};
diff --git a/objc/test/Ice/enums/Makefile b/objc/test/Ice/enums/Makefile
new file mode 100644
index 00000000000..93f4caae0cf
--- /dev/null
+++ b/objc/test/Ice/enums/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = EnumTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/enums/Server.m b/objc/test/Ice/enums/Server.m
new file mode 100644
index 00000000000..877202be6a8
--- /dev/null
+++ b/objc/test/Ice/enums/Server.m
@@ -0,0 +1,83 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <enums/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adapter add:[[[TestEnumTestIntfI alloc] init] autorelease]
+ identity:[communicator stringToIdentity:@"test"]];
+#else
+ [adapter add:[[TestEnumTestIntfI alloc] init] identity:[communicator stringToIdentity:@"test"]];
+#endif
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main enumServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestEnum", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/enums/TestI.h b/objc/test/Ice/enums/TestI.h
new file mode 100644
index 00000000000..4283e41babd
--- /dev/null
+++ b/objc/test/Ice/enums/TestI.h
@@ -0,0 +1,15 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <EnumTest.h>
+
+@interface TestEnumTestIntfI : TestEnumTestIntf<TestEnumTestIntf>
+{
+}
+@end
diff --git a/objc/test/Ice/enums/TestI.m b/objc/test/Ice/enums/TestI.m
new file mode 100644
index 00000000000..6b4daf75e61
--- /dev/null
+++ b/objc/test/Ice/enums/TestI.m
@@ -0,0 +1,69 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <enums/TestI.h>
+#import <TestCommon.h>
+
+@implementation TestEnumTestIntfI
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[[current adapter] getCommunicator] shutdown];
+}
+
+-(TestEnumByteEnum) opByte:(TestEnumByteEnum)b1 b2:(TestEnumByteEnum*)b2 current:(ICECurrent*)current
+{
+ *b2 = b1;
+ return b1;
+}
+
+-(TestEnumShortEnum) opShort:(TestEnumShortEnum)s1 s2:(TestEnumShortEnum*)s2 current:(ICECurrent*)current
+{
+ *s2 = s1;
+ return s1;
+}
+
+-(TestEnumIntEnum) opInt:(TestEnumIntEnum)i1 i2:(TestEnumIntEnum*)i2 current:(ICECurrent*)current
+{
+ *i2 = i1;
+ return i1;
+}
+
+-(TestEnumSimpleEnum) opSimple:(TestEnumSimpleEnum)s1 s2:(TestEnumSimpleEnum*)s2 current:(ICECurrent*)current
+{
+ *s2 = s1;
+ return s1;
+}
+
+-(TestEnumByteEnumSeq*) opByteSeq:(TestEnumByteEnumSeq*)b1 b2:(TestEnumByteEnumSeq**)b2 current:(ICECurrent*)current
+{
+ *b2 = b1;
+ return b1;
+}
+
+-(TestEnumShortEnumSeq*) opShortSeq:(TestEnumShortEnumSeq*)s1 s2:(TestEnumShortEnumSeq**)s2 current:(ICECurrent*)current
+{
+ *s2 = s1;
+ return s1;
+}
+
+-(TestEnumIntEnumSeq*) opIntSeq:(TestEnumIntEnumSeq*)i1 i2:(TestEnumIntEnumSeq**)i2 current:(ICECurrent*)current
+{
+ *i2 = i1;
+ return i1;
+}
+
+-(TestEnumSimpleEnumSeq*) opSimpleSeq:(TestEnumSimpleEnumSeq*)s1 s2:(TestEnumSimpleEnumSeq**)s2 current:(ICECurrent*)current
+{
+ *s2 = s1;
+ return s1;
+}
+
+@end
diff --git a/objc/test/Ice/enums/run.py b/objc/test/Ice/enums/run.py
new file mode 100755
index 00000000000..efa77639a65
--- /dev/null
+++ b/objc/test/Ice/enums/run.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+print("Running test with 1.0 encoding.")
+TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0",
+ additionalServerOptions="--Ice.Default.EncodingVersion=1.0")
+
+print("Running test with 1.1 encoding.")
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/exceptions/.gitignore b/objc/test/Ice/exceptions/.gitignore
new file mode 100644
index 00000000000..540725b83c2
--- /dev/null
+++ b/objc/test/Ice/exceptions/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+ExceptionsTest.m
+ExceptionsTest.h
diff --git a/objc/test/Ice/exceptions/AllTests.m b/objc/test/Ice/exceptions/AllTests.m
new file mode 100644
index 00000000000..8a57ccd7f90
--- /dev/null
+++ b/objc/test/Ice/exceptions/AllTests.m
@@ -0,0 +1,501 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <ExceptionsTest.h>
+
+@interface ExceptionsEmptyI : TestExceptionsEmpty<TestExceptionsEmpty>
+@end
+
+@implementation ExceptionsEmptyI
+@end
+
+id<TestExceptionsThrowerPrx>
+exceptionsAllTests(id<ICECommunicator> communicator, BOOL collocated)
+{
+ tprintf("testing object adapter registration exceptions... ");
+ {
+ id<ICEObjectAdapter> first;
+ @try
+ {
+ first = [communicator createObjectAdapter:@"TestAdapter0"];
+ test(false);
+ }
+ @catch(ICEInitializationException *ex)
+ {
+ // Expeccted
+ }
+
+ [[communicator getProperties] setProperty:@"TestAdapter0.Endpoints" value:@"default"];
+ first = [communicator createObjectAdapter:@"TestAdapter0"];
+ @try
+ {
+ [communicator createObjectAdapter:@"TestAdapter0"];
+ test(false);
+ }
+ @catch(ICEAlreadyRegisteredException *ex)
+ {
+ // Expected
+ }
+
+ @try
+ {
+ }
+ @catch(ICEAlreadyRegisteredException *ex)
+ {
+ // Expected
+ }
+
+ //
+ // Properties must remain unaffected if an exception occurs.
+ //
+ test([[[communicator getProperties] getProperty:@"TestAdapter0.Endpoints"] isEqualToString:@"default"]);
+ [first deactivate];
+ }
+ tprintf("ok\n");
+
+ tprintf("testing servant registration exceptions... ");
+ {
+ [[communicator getProperties] setProperty:@"TestAdapter1.Endpoints" value:@"default"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter1"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* obj = [[[ExceptionsEmptyI alloc] init] autorelease];
+#else
+ ICEObject* obj = [[ExceptionsEmptyI alloc] init];
+#endif
+ [adapter add:obj identity:[communicator stringToIdentity:@"x"]];
+ @try
+ {
+ [adapter add:obj identity:[communicator stringToIdentity:@"x"]];
+ test(false);
+ }
+ @catch(ICEAlreadyRegisteredException *ex)
+ {
+ }
+
+ [adapter remove:[communicator stringToIdentity:@"x"]];
+ @try
+ {
+ [adapter remove:[communicator stringToIdentity:@"x"]];
+ test(false);
+ }
+ @catch(ICENotRegisteredException *ex)
+ {
+ }
+
+ [adapter deactivate];
+ }
+ tprintf("ok\n");
+
+ tprintf("testing stringToProxy... ");
+ NSString *ref = @"thrower:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ test(base);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestExceptionsThrowerPrx> thrower = [TestExceptionsThrowerPrx checkedCast:base];
+ test(thrower);
+ test([thrower isEqual:base]);
+ tprintf("ok\n");
+
+ tprintf("catching exact types... ");
+
+ @try
+ {
+ [thrower throwAasA:1];
+ test(false);
+ }
+ @catch(TestExceptionsA *ex)
+ {
+ test(ex.aMem == 1);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwAorDasAorD:1];
+ test(false);
+ }
+ @catch(TestExceptionsA *ex)
+ {
+ test(ex.aMem == 1);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwAorDasAorD:-1];
+ test(false);
+ }
+ @catch(TestExceptionsD *ex)
+ {
+ test(ex.dMem == -1);
+ }
+ @catch(NSException* ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwBasB:1 b:2];
+ test(false);
+ }
+ @catch(TestExceptionsB *ex)
+ {
+ test(ex.aMem == 1);
+ test(ex.bMem == 2);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwCasC:1 b:2 c:3];
+ test(false);
+ }
+ @catch(TestExceptionsC *ex)
+ {
+ test(ex.aMem == 1);
+ test(ex.bMem == 2);
+ test(ex.cMem == 3);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwModA:1 a2:2];
+ test(false);
+ }
+ @catch(TestExceptionsModA *ex)
+ {
+ test(ex.aMem == 1);
+ test(ex.a2Mem == 2);
+ }
+ @catch(ICEOperationNotExistException *ex)
+ {
+ //
+ // This operation is not supported in Java.
+ //
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ tprintf("ok\n");
+
+ tprintf("catching base types... ");
+
+ @try
+ {
+ [thrower throwBasB:1 b:2];
+ test(false);
+ }
+ @catch(TestExceptionsA *ex)
+ {
+ test(ex.aMem == 1);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwCasC:1 b:2 c:3];
+ test(false);
+ }
+ @catch(TestExceptionsB *ex)
+ {
+ test(ex.aMem == 1);
+ test(ex.bMem == 2);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwModA:1 a2:2];
+ test(false);
+ }
+ @catch(TestExceptionsA *ex)
+ {
+ test(ex.aMem == 1);
+ }
+ @catch(ICEOperationNotExistException *ex)
+ {
+ //
+ // This operation is not supported in Java.
+ //
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ tprintf("ok\n");
+
+ tprintf("catching derived types... ");
+
+ @try
+ {
+ [thrower throwBasA:1 b:2];
+ test(false);
+ }
+ @catch(TestExceptionsB *ex)
+ {
+ test(ex.aMem == 1);
+ test(ex.bMem == 2);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwCasA:1 b:2 c:3];
+ test(false);
+ }
+ @catch(TestExceptionsC *ex)
+ {
+ test(ex.aMem == 1);
+ test(ex.bMem == 2);
+ test(ex.cMem == 3);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwCasB:1 b:2 c:3];
+ test(false);
+ }
+ @catch(TestExceptionsC *ex)
+ {
+ test(ex.aMem == 1);
+ test(ex.bMem == 2);
+ test(ex.cMem == 3);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ tprintf("ok\n");
+
+ if([thrower supportsUndeclaredExceptions])
+ {
+ tprintf("catching unknown user exception... ");
+
+ @try
+ {
+ [thrower throwUndeclaredA:1];
+ test(false);
+ }
+ @catch(ICEUnknownUserException *ex)
+ {
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwUndeclaredB:1 b:2];
+ test(false);
+ }
+ @catch(ICEUnknownUserException *ex)
+ {
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwUndeclaredC:1 b:2 c:3];
+ test(false);
+ }
+ @catch(ICEUnknownUserException *ex)
+ {
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("testing memory limit marshal exception...");
+ @try
+ {
+ ICEByteSeq *bs = [NSMutableData dataWithLength:0];
+ [thrower throwMemoryLimitException:bs];
+ test(false);
+ }
+ @catch(ICEMemoryLimitException *ex)
+ {
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ @try
+ {
+ [thrower throwMemoryLimitException:[NSMutableData dataWithLength:20 * 1024]]; // 20KB
+ test(false);
+ }
+ @catch(ICEConnectionLostException *ex)
+ {
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+ tprintf("ok\n");
+ }
+
+ tprintf("catching object not exist exception... ");
+
+ ICEIdentity *id_ = [communicator stringToIdentity:@"does not exist"];
+ @try
+ {
+ id<TestExceptionsThrowerPrx> thrower2 = [TestExceptionsThrowerPrx uncheckedCast:[thrower ice_identity:id_]];
+ [thrower2 throwAasA:1];
+// //[thrower2 ice_ping];
+ test(false);
+ }
+ @catch(ICEObjectNotExistException *ex)
+ {
+ test([ex.id_ isEqual:id_]);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ tprintf("ok\n");
+
+ tprintf("catching facet not exist exception... ");
+
+ @try
+ {
+ id<TestExceptionsThrowerPrx> thrower2 = [TestExceptionsThrowerPrx uncheckedCast:thrower facet:@"no such facet"];
+ @try
+ {
+ [thrower2 ice_ping];
+ test(false);
+ }
+ @catch(ICEFacetNotExistException *ex)
+ {
+ test([ex.facet isEqualToString:@"no such facet"]);
+ }
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ tprintf("ok\n");
+
+ tprintf("catching operation not exist exception... ");
+
+ @try
+ {
+ id<TestExceptionsWrongOperationPrx> thrower2 = [TestExceptionsWrongOperationPrx uncheckedCast:thrower];
+ [thrower2 noSuchOperation];
+ test(false);
+ }
+ @catch(ICEOperationNotExistException *ex)
+ {
+ test([ex.operation isEqualToString:@"noSuchOperation"]);
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+
+ tprintf("ok\n");
+
+ tprintf("catching unknown local exception... ");
+
+ @try
+ {
+ [thrower throwLocalException];
+ test(false);
+ }
+ @catch(ICEUnknownLocalException *ex)
+ {
+ }
+ @catch(NSException *ex)
+ {
+ test(false);
+ }
+ @try
+ {
+ [thrower throwLocalExceptionIdempotent];
+ test(false);
+ }
+ @catch(ICEUnknownLocalException*)
+ {
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+ @catch(NSException* ex)
+ {
+ test(false);
+ }
+
+
+ tprintf("ok\n");
+
+ tprintf("catching unknown non-Ice exception... ");
+
+ @try
+ {
+ [thrower throwNonIceException];
+ test(false);
+ }
+ @catch(ICEUnknownException *)
+ {
+ }
+ @catch(NSException *)
+ {
+ test(false);
+ }
+
+ tprintf("ok\n");
+
+ return thrower;
+}
diff --git a/objc/test/Ice/exceptions/Client.m b/objc/test/Ice/exceptions/Client.m
new file mode 100644
index 00000000000..c988600b617
--- /dev/null
+++ b/objc/test/Ice/exceptions/Client.m
@@ -0,0 +1,79 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <ExceptionsTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ TestExceptionsThrowerPrx* exceptionsAllTests(id<ICECommunicator>, BOOL);
+ TestExceptionsThrowerPrx* thrower = exceptionsAllTests(communicator, NO);
+ [thrower shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main exceptionsClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+ [initData.properties setProperty:@"Ice.MessageSizeMax" value:@"10"]; // 10KB max
+ [initData.properties setProperty:@"Ice.Warn.Connections" value:@"0"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestExceptions", @"::Test",
+ @"TestExceptionsMod", @"::Test::Mod",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/exceptions/ExceptionsTest.ice b/objc/test/Ice/exceptions/ExceptionsTest.ice
new file mode 100644
index 00000000000..6d3c247076f
--- /dev/null
+++ b/objc/test/Ice/exceptions/ExceptionsTest.ice
@@ -0,0 +1,88 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/BuiltinSequences.ice>
+
+["objc:prefix:TestExceptions"]
+module Test
+{
+
+interface Empty
+{
+};
+
+interface Thrower;
+
+exception A
+{
+ int aMem;
+};
+
+exception B extends A
+{
+ int bMem;
+};
+
+exception C extends B
+{
+ int cMem;
+};
+
+exception D
+{
+ int dMem;
+};
+
+["objc:prefix:TestExceptionsMod"]
+module Mod
+{
+ exception A extends ::Test::A
+ {
+ int a2Mem;
+ };
+};
+
+
+interface Thrower
+{
+ void shutdown();
+ bool supportsUndeclaredExceptions();
+ bool supportsAssertException();
+
+ void throwAasA(int a) throws A;
+ void throwAorDasAorD(int a) throws A, D;
+ void throwBasA(int a, int b) throws A;
+ void throwCasA(int a, int b, int c) throws A;
+ void throwBasB(int a, int b) throws B;
+ void throwCasB(int a, int b, int c) throws B;
+ void throwCasC(int a, int b, int c) throws C;
+
+ void throwModA(int a, int a2) throws Mod::A;
+
+ void throwUndeclaredA(int a);
+ void throwUndeclaredB(int a, int b);
+ void throwUndeclaredC(int a, int b, int c);
+ void throwLocalException();
+ void throwNonIceException();
+ void throwAssertException();
+ Ice::ByteSeq throwMemoryLimitException(Ice::ByteSeq seq);
+ idempotent void throwLocalExceptionIdempotent();
+
+ void throwAfterResponse();
+ void throwAfterException() throws A;
+};
+
+interface WrongOperation
+{
+ void noSuchOperation();
+};
+
+};
diff --git a/objc/test/Ice/exceptions/Makefile b/objc/test/Ice/exceptions/Makefile
new file mode 100644
index 00000000000..ad1f1c56002
--- /dev/null
+++ b/objc/test/Ice/exceptions/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = ExceptionsTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/exceptions/Server.m b/objc/test/Ice/exceptions/Server.m
new file mode 100644
index 00000000000..9d5f81998b2
--- /dev/null
+++ b/objc/test/Ice/exceptions/Server.m
@@ -0,0 +1,90 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <exceptions/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* object = [[[ThrowerI alloc] init] autorelease];
+#else
+ ICEObject* object = [[ThrowerI alloc] init];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"thrower"]];
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main exceptionsServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+ [initData.properties setProperty:@"Ice.MessageSizeMax" value:@"10"]; // 10KB max
+ [initData.properties setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+ [initData.properties setProperty:@"Ice.Warn.Connections" value:@"0"];
+
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestExceptions", @"::Test",
+ @"TestExceptionsMod", @"::Test::Mod",
+ nil];
+#endif
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/exceptions/TestI.h b/objc/test/Ice/exceptions/TestI.h
new file mode 100644
index 00000000000..8046ca912e6
--- /dev/null
+++ b/objc/test/Ice/exceptions/TestI.h
@@ -0,0 +1,16 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ExceptionsTest.h>
+
+@interface ThrowerI : TestExceptionsThrower<TestExceptionsThrower>
+{
+}
+
+@end
diff --git a/objc/test/Ice/exceptions/TestI.m b/objc/test/Ice/exceptions/TestI.m
new file mode 100644
index 00000000000..77620336a74
--- /dev/null
+++ b/objc/test/Ice/exceptions/TestI.m
@@ -0,0 +1,153 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+
+#import <exceptions/TestI.h>
+#import <TestCommon.h>
+#import <Foundation/NSException.h>
+
+@interface FooException : NSException
+@end
+
+@implementation FooException
+-(id)init
+{
+ self = [super initWithName:@"FooException" reason:@"no reason" userInfo:nil];
+ if(!self)
+ {
+ return nil;
+ }
+ return self;
+}
+@end
+
+@implementation ThrowerI
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+
+-(BOOL) supportsUndeclaredExceptions:(ICECurrent*)current
+{
+ return YES;
+}
+
+-(BOOL) supportsAssertException:(ICECurrent*)current
+{
+ return NO;
+}
+
+-(void) throwAasA:(ICEInt)a current:(ICECurrent*)current
+{
+ @throw [TestExceptionsA a:a];
+}
+
+-(void) throwAorDasAorD:(ICEInt)a current:(ICECurrent*)current
+{
+ if(a > 0)
+ {
+ @throw [TestExceptionsA a:a];
+ }
+ else
+ {
+ @throw [TestExceptionsD d:a];
+ }
+}
+
+-(void) throwBasA:(ICEInt)a b:(ICEInt)b current:(ICECurrent*)current
+{
+ [self throwBasB:a b:b current:current];
+}
+
+-(void) throwCasA:(ICEInt)a b:(ICEInt)b c:(ICEInt) c current:(ICECurrent*)current
+{
+ [self throwCasC:a b:b c:c current:current];
+}
+
+-(void) throwBasB:(ICEInt)a b:(ICEInt)b current:(ICECurrent*)current
+{
+ @throw [TestExceptionsB b:a bMem:b];
+}
+
+-(void) throwCasB:(ICEInt)a b:(ICEInt)b c:(ICEInt)c current:(ICECurrent*)current
+{
+ [self throwCasC:a b:b c:c current:current];
+}
+
+-(void) throwCasC:(ICEInt)a b:(ICEInt)b c:(ICEInt)c current:(ICECurrent*)current
+{
+ @throw [TestExceptionsC c:a bMem:b cMem:c];
+}
+
+-(void) throwModA:(ICEInt)a a2:(ICEInt)a2 current:(ICECurrent*)current
+{
+ @throw [TestExceptionsModA a:a a2Mem:a2];
+}
+
+-(void) throwUndeclaredA:(ICEInt)a current:(ICECurrent*)current
+{
+ @throw [TestExceptionsA a:a];
+}
+
+-(void) throwUndeclaredB:(ICEInt)a b:(ICEInt)b current:(ICECurrent*)current
+{
+ @throw [TestExceptionsB b:a bMem:b];
+}
+
+-(void) throwUndeclaredC:(ICEInt)a b:(ICEInt)b c:(ICEInt)c current:(ICECurrent*)current
+{
+ @throw [TestExceptionsC c:a bMem:b cMem:c];
+}
+
+-(void) throwLocalException:(ICECurrent*)current
+{
+ @throw [ICETimeoutException timeoutException:__FILE__ line:__LINE__];
+}
+
+-(ICEByteSeq*) throwMemoryLimitException:(ICEMutableByteSeq*)bs current:(ICECurrent*)current
+{
+ int limit = 20 * 1024;
+ ICEMutableByteSeq *r = [NSMutableData dataWithLength:limit];
+ ICEByte *p = (ICEByte *)[r bytes];
+ while(--limit > 0)
+ {
+ *p++ = limit % 0x80;
+ }
+ return r;
+}
+
+-(void) throwNonIceException:(ICECurrent*)current
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ @throw [[[FooException alloc] init] autorelease];
+#else
+ @throw [[FooException alloc] init];
+#endif
+}
+
+-(void) throwAssertException:(ICECurrent*)current
+{
+ // Not supported.
+}
+
+-(void) throwLocalExceptionIdempotent:(ICECurrent*)current
+{
+ @throw [ICETimeoutException timeoutException:__FILE__ line:__LINE__];
+}
+-(void) throwAfterResponse:(ICECurrent*)current
+{
+ // Only relevant for AMD
+}
+-(void) throwAfterException:(ICECurrent*)current
+{
+ // Only relevant for AMD
+}
+@end
diff --git a/objc/test/Ice/exceptions/run.py b/objc/test/Ice/exceptions/run.py
new file mode 100755
index 00000000000..37acea1668c
--- /dev/null
+++ b/objc/test/Ice/exceptions/run.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+print("Running test with compact (default) format.")
+TestUtil.clientServerTest()
+
+print("Running test with sliced format.")
+TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.SlicedFormat",
+ additionalServerOptions="--Ice.Default.SlicedFormat")
+
+print("Running test with 1.0 encoding.")
+TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0",
+ additionalServerOptions="--Ice.Default.EncodingVersion=1.0")
diff --git a/objc/test/Ice/facets/.gitignore b/objc/test/Ice/facets/.gitignore
new file mode 100644
index 00000000000..9d788e0b4c2
--- /dev/null
+++ b/objc/test/Ice/facets/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+FacetsTest.m
+FacetsTest.h
diff --git a/objc/test/Ice/facets/AllTests.m b/objc/test/Ice/facets/AllTests.m
new file mode 100644
index 00000000000..00c496ee62e
--- /dev/null
+++ b/objc/test/Ice/facets/AllTests.m
@@ -0,0 +1,196 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <FacetsTest.h>
+
+
+@interface FacetsEmptyI : TestFacetsEmpty
+@end
+
+@implementation FacetsEmptyI
+@end
+
+id<TestFacetsGPrx>
+facetsAllTests(id<ICECommunicator> communicator)
+{
+// tprintf("testing Ice.Admin.Facets property... ");
+// test([[[communicator getProperties] getPropertyAsList:@"Ice.Admin.Facets"] length] > 0);
+// [[communicator getProperties] setProperty:@"Ice.Admin.Facets" value:@"foobar"];
+// ICEStringSeq facetFilter = [[communicator getProperties] getPropertyAsList:@"Ice.Admin.Facets"];
+// test([[facetFilter count] == 1 && [facetFilter objectAtIndex:0] isEqualToString:@"foobar"]);
+// [[communicator getProperties] setProperty:@"Ice.Admin.Facets" value:@"foo'bar"];
+// facetFilter = [[communicator getProperties] getPropertyAsList:@"Ice.Admin.Facets"];
+// test([[facetFilter count] == 1 && [facetFilter objectAtIndex:0] isEqualToString:@"foo'bar"]);
+// [[communicator getProperties] setProperty:@"Ice.Admin.Facets" value:@"'foo bar' toto 'titi'"];
+// facetFilter = [[communicator getProperties] getPropertyAsList:@"Ice.Admin.Facets"];
+// test([[facetFilter count] == 3 && [facetFilter objectAtIndex:0] isEqualToString:@"foo bar" && [facetFilter objectAtIndex:1]:isEqualToString:@"toto" && [facetFilter objectAtIndex:2]:isEqualToString:@"titi"]);
+// [[communicator getProperties] setProperty:@"Ice.Admin.Facets" value:@"'foo bar\\' toto' 'titi'"];
+// facetFilter = [[communicator getProperties] getPropertyAsList:@"Ice.Admin.Facets"];
+// test([[facetFilter count] == 2 && [facetFilter objectAtIndex:0] isEqualToString:@"foo bar' toto" && [facetFilter objectAtIndex:1]:isEqualToString:@"titi"]);
+// // [[communicator getProperties] setProperty:@"Ice.Admin.Facets" value:@"'foo bar' 'toto titi"];
+// // facetFilter = [[communicator getProperties] getPropertyAsList:@"Ice.Admin.Facets"];
+// // test([facetFilter count] == 0);
+// [[communicator getProperties] setProperty:@"Ice.Admin.Facets" value:@""];
+// tprintf("ok\n");
+
+ tprintf("testing facet registration exceptions... ");
+ [[communicator getProperties] setProperty:@"FacetExceptionTestAdapter.Endpoints" value:@"default"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"FacetExceptionTestAdapter"];
+ ICEObject* obj = [[FacetsEmptyI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [obj autorelease];
+#endif
+ [adapter add:obj identity:[communicator stringToIdentity:@"d"]];
+ [adapter addFacet:obj identity:[communicator stringToIdentity:@"d"] facet:@"facetABCD"];
+ @try
+ {
+ [adapter addFacet:obj identity:[communicator stringToIdentity:@"d"] facet:@"facetABCD"];
+ test(NO);
+ }
+ @catch(ICEAlreadyRegisteredException*)
+ {
+ }
+ [adapter removeFacet:[communicator stringToIdentity:@"d"] facet:@"facetABCD"];
+ @try
+ {
+ [adapter removeFacet:[communicator stringToIdentity:@"d"] facet:@"facetABCD"];
+ test(NO);
+ }
+ @catch(ICENotRegisteredException*)
+ {
+ }
+ tprintf("ok\n");
+
+ tprintf("testing removeAllFacets... ");
+ ICEObject* obj1 = [[FacetsEmptyI alloc] init];
+ ICEObject* obj2 = [[FacetsEmptyI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [obj1 autorelease];
+ [obj2 autorelease];
+#endif
+
+ [adapter addFacet:obj1 identity:[communicator stringToIdentity:@"id1"] facet:@"f1"];
+ [adapter addFacet:obj2 identity:[communicator stringToIdentity:@"id1"] facet:@"f2"];
+
+ ICEObject* obj3 = [[FacetsEmptyI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [obj3 autorelease];
+#endif
+
+ [adapter addFacet:obj1 identity:[communicator stringToIdentity:@"id2"] facet:@"f1"];
+ [adapter addFacet:obj2 identity:[communicator stringToIdentity:@"id2"] facet:@"f2"];
+ [adapter addFacet:obj3 identity:[communicator stringToIdentity:@"id2"] facet:@""];
+ NSDictionary* fm = [adapter removeAllFacets:[communicator stringToIdentity:@"id1"]];
+ test([fm count] == 2);
+ test([fm objectForKey:@"f1"] == obj1);
+ test([fm objectForKey:@"f2"] == obj2);
+ @try
+ {
+ [adapter removeAllFacets:[communicator stringToIdentity:@"id1"]];
+ test(NO);
+ }
+ @catch(ICENotRegisteredException*)
+ {
+ }
+ fm = [adapter removeAllFacets:[communicator stringToIdentity:@"id2"]];
+ test([fm count] == 3);
+ test([fm objectForKey:@"f1"] == obj1);
+ test([fm objectForKey:@"f2"] == obj2);
+ test([fm objectForKey:@""] == obj3);
+ tprintf("ok\n");
+
+ [adapter deactivate];
+
+ tprintf("testing stringToProxy... ");
+ NSString* ref = @"d:default -p 12010";
+ id<ICEObjectPrx> db = [communicator stringToProxy:ref];
+ test(db);
+ tprintf("ok\n");
+
+ tprintf("testing unchecked cast... ");
+ id<ICEObjectPrx> prx = [ICEObjectPrx uncheckedCast:db];
+ test([[prx ice_getFacet] length] == 0);
+ prx = [ICEObjectPrx uncheckedCast:db facet:@"facetABCD"];
+ test([[prx ice_getFacet] isEqualToString:@"facetABCD"]);
+ id<ICEObjectPrx> prx2 = [ICEObjectPrx uncheckedCast:prx];
+ test([[prx2 ice_getFacet] isEqualToString:@"facetABCD"]);
+ id<ICEObjectPrx> prx3 = [ICEObjectPrx uncheckedCast:prx facet:@""];
+ test([[prx3 ice_getFacet] length] == 0);
+ id<TestFacetsDPrx> d = [TestFacetsDPrx uncheckedCast:db];
+ test([[d ice_getFacet] length] == 0);
+ id<TestFacetsDPrx> df = [TestFacetsDPrx uncheckedCast:db facet:@"facetABCD"];
+ test([[df ice_getFacet] isEqualToString:@"facetABCD"]);
+ id<TestFacetsDPrx> df2 = [TestFacetsDPrx uncheckedCast:df];
+ test([[df2 ice_getFacet] isEqualToString:@"facetABCD"]);
+ id<TestFacetsDPrx> df3 = [TestFacetsDPrx uncheckedCast:df facet:@""];
+ test([[df3 ice_getFacet] length] == 0);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ prx = [ICEObjectPrx checkedCast:db];
+ test([[prx ice_getFacet] length] == 0);
+ prx = [ICEObjectPrx checkedCast:db facet:@"facetABCD"];
+ test([[prx ice_getFacet] isEqualToString:@"facetABCD"]);
+ prx2 = [ICEObjectPrx checkedCast:prx];
+ test([[prx2 ice_getFacet] isEqualToString:@"facetABCD"]);
+ prx3 = [ICEObjectPrx checkedCast:prx facet:@""];
+ test([[prx3 ice_getFacet] length] == 0);
+ d = [TestFacetsDPrx checkedCast:db];
+ test([[d ice_getFacet] length] == 0);
+ df = [TestFacetsDPrx checkedCast:db facet:@"facetABCD"];
+ test([[df ice_getFacet] isEqualToString:@"facetABCD"]);
+ df2 = [TestFacetsDPrx checkedCast:df];
+ test([[df2 ice_getFacet] isEqualToString:@"facetABCD"]);
+ df3 = [TestFacetsDPrx checkedCast:df facet:@""];
+ test([[df3 ice_getFacet] length] == 0);
+ tprintf("ok\n");
+
+ tprintf("testing non-facets A, B, C, and D... ");
+ d = [TestFacetsDPrx checkedCast:db];
+ test(d);
+ test([d isEqual:db]);
+ test([[d callA] isEqualToString:@"A"]);
+ test([[d callB] isEqualToString:@"B"]);
+ test([[d callC] isEqualToString:@"C"]);
+ test([[d callD] isEqualToString:@"D"]);
+ tprintf("ok\n");
+
+ tprintf("testing facets A, B, C, and D... ");
+ df = [TestFacetsDPrx checkedCast:d facet:@"facetABCD"];
+ test(df);
+ test([[df callA] isEqualToString:@"A"]);
+ test([[df callB] isEqualToString:@"B"]);
+ test([[df callC] isEqualToString:@"C"]);
+ test([[df callD] isEqualToString:@"D"]);
+ tprintf("ok\n");
+
+ tprintf("testing facets E and F... ");
+ id<TestFacetsFPrx> ff = [TestFacetsFPrx checkedCast:d facet:@"facetEF"];
+ test(ff);
+ test([[ff callE] isEqualToString:@"E"]);
+ test([[ff callF] isEqualToString:@"F"]);
+ tprintf("ok\n");
+
+ tprintf("testing facet G... ");
+ id<TestFacetsGPrx> gf = [TestFacetsGPrx checkedCast:ff facet:@"facetGH"];
+ test(gf);
+ test([[gf callG] isEqualToString:@"G"]);
+ tprintf("ok\n");
+
+ tprintf("testing whether casting preserves the facet... ");
+ id<TestFacetsHPrx> hf = [TestFacetsHPrx checkedCast:gf];
+ test(hf);
+ test([[hf callG] isEqualToString:@"G"]);
+ test([[hf callH] isEqualToString:@"H"]);
+ tprintf("ok\n");
+
+ return gf;
+}
diff --git a/objc/test/Ice/facets/Client.m b/objc/test/Ice/facets/Client.m
new file mode 100644
index 00000000000..13a704cb259
--- /dev/null
+++ b/objc/test/Ice/facets/Client.m
@@ -0,0 +1,77 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <FacetsTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestFacetsGPrx> facetsAllTests(id<ICECommunicator>);
+ id<TestFacetsGPrx> g = facetsAllTests(communicator);
+ [g shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main facetsClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestFacets", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/facets/FacetsTest.ice b/objc/test/Ice/facets/FacetsTest.ice
new file mode 100644
index 00000000000..435e9343cdb
--- /dev/null
+++ b/objc/test/Ice/facets/FacetsTest.ice
@@ -0,0 +1,61 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestFacets"]
+module Test
+{
+
+interface Empty
+{
+};
+
+interface A
+{
+ string callA();
+};
+
+interface B extends A
+{
+ string callB();
+};
+
+interface C extends A
+{
+ string callC();
+};
+
+interface D extends B, C
+{
+ string callD();
+};
+
+interface E
+{
+ string callE();
+};
+
+interface F extends E
+{
+ string callF();
+};
+
+interface G
+{
+ void shutdown();
+ string callG();
+};
+
+interface H extends G
+{
+ string callH();
+};
+
+};
diff --git a/objc/test/Ice/facets/Makefile b/objc/test/Ice/facets/Makefile
new file mode 100644
index 00000000000..5b6bd5534ec
--- /dev/null
+++ b/objc/test/Ice/facets/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = FacetsTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/facets/Server.m b/objc/test/Ice/facets/Server.m
new file mode 100644
index 00000000000..1efa7568116
--- /dev/null
+++ b/objc/test/Ice/facets/Server.m
@@ -0,0 +1,91 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <facets/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* d = [[[TestFacetsDI alloc] init] autorelease];
+ ICEObject* f = [[[TestFacetsFI alloc] init] autorelease];
+ ICEObject* h = [[[TestFacetsHI alloc] init] autorelease];
+#else
+ ICEObject* d = [[TestFacetsDI alloc] init];
+ ICEObject* f = [[TestFacetsFI alloc] init];
+ ICEObject* h = [[TestFacetsHI alloc] init];
+#endif
+ [adapter add:d identity:[communicator stringToIdentity:@"d"]];
+ [adapter addFacet:d identity:[communicator stringToIdentity:@"d"] facet:@"facetABCD"];
+ [adapter addFacet:f identity:[communicator stringToIdentity:@"d"] facet:@"facetEF"];
+ [adapter addFacet:h identity:[communicator stringToIdentity:@"d"] facet:@"facetGH"];
+
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main facetsServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestFacets", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/facets/TestI.h b/objc/test/Ice/facets/TestI.h
new file mode 100644
index 00000000000..c56837bbd42
--- /dev/null
+++ b/objc/test/Ice/facets/TestI.h
@@ -0,0 +1,40 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <FacetsTest.h>
+
+@interface TestFacetsAI : TestFacetsA<TestFacetsA>
+@end
+
+@interface TestFacetsBI : TestFacetsB<TestFacetsB>
+@end
+
+@interface TestFacetsCI : TestFacetsC<TestFacetsC>
+@end
+
+@interface TestFacetsDI : TestFacetsD<TestFacetsD>
+@end
+
+@interface TestFacetsEI : TestFacetsE<TestFacetsE>
+@end
+
+@interface TestFacetsFI : TestFacetsF<TestFacetsF>
+@end
+
+@interface TestFacetsGI : TestFacetsG<TestFacetsG>
+{
+ id<ICECommunicator> communicator_;
+}
+-(void) shutdown:(ICECurrent*)current;
+-(NSString*) callG:(ICECurrent*)current;
+@end
+
+@interface TestFacetsHI : TestFacetsH<TestFacetsH>
+-(NSString*) callH:(ICECurrent*)current;
+@end
diff --git a/objc/test/Ice/facets/TestI.m b/objc/test/Ice/facets/TestI.m
new file mode 100644
index 00000000000..b032e7d39a0
--- /dev/null
+++ b/objc/test/Ice/facets/TestI.m
@@ -0,0 +1,103 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <facets/TestI.h>
+
+@implementation TestFacetsAI
+-(NSString*) callA:(ICECurrent*)current
+{
+ return @"A";
+}
+@end
+
+@implementation TestFacetsBI
+-(NSString*) callA:(ICECurrent*)current
+{
+ return @"A";
+}
+-(NSString*) callB:(ICECurrent*)current
+{
+ return @"B";
+}
+@end
+
+@implementation TestFacetsCI
+-(NSString*) callA:(ICECurrent*)current
+{
+ return @"A";
+}
+-(NSString*) callC:(ICECurrent*)current
+{
+ return @"C";
+}
+@end
+
+@implementation TestFacetsDI
+-(NSString*) callA:(ICECurrent*)current
+{
+ return @"A";
+}
+-(NSString*) callB:(ICECurrent*)current
+{
+ return @"B";
+}
+-(NSString*) callC:(ICECurrent*)current
+{
+ return @"C";
+}
+-(NSString*) callD:(ICECurrent*)current
+{
+ return @"D";
+}
+@end
+
+@implementation TestFacetsEI
+-(NSString*) callE:(ICECurrent*)current
+{
+ return @"E";
+}
+@end
+
+@implementation TestFacetsFI
+-(NSString*) callE:(ICECurrent*)current
+{
+ return @"E";
+}
+-(NSString*) callF:(ICECurrent*)current
+{
+ return @"F";
+}
+@end
+
+@implementation TestFacetsGI
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+-(NSString*) callG:(ICECurrent*)current
+{
+ return @"G";
+}
+@end
+
+@implementation TestFacetsHI
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+-(NSString*) callG:(ICECurrent*)current
+{
+ return @"G";
+}
+-(NSString*) callH:(ICECurrent*)current
+{
+ return @"H";
+}
+@end
diff --git a/objc/test/Ice/facets/run.py b/objc/test/Ice/facets/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/facets/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/faultTolerance/.gitignore b/objc/test/Ice/faultTolerance/.gitignore
new file mode 100644
index 00000000000..aa38efcc5dc
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+Test.m
+Test.h
diff --git a/objc/test/Ice/faultTolerance/AllTests.m b/objc/test/Ice/faultTolerance/AllTests.m
new file mode 100644
index 00000000000..0251e6b97e5
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/AllTests.m
@@ -0,0 +1,292 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <faultTolerance/Test.h>
+
+#import <Foundation/Foundation.h>
+
+@interface Callback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+ ICEInt pid;
+}
+-(void) check;
+-(void) called;
+-(ICEInt) pid;
+@end
+
+@implementation Callback
+-(id) init
+{
+ if(![super init])
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) check
+{
+ [cond lock];
+ while(!called)
+ {
+ [cond wait];
+ }
+ called = NO;
+ [cond unlock];
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) pidResponse:(ICEInt)p
+{
+ pid = p;
+ [self called];
+}
+
+-(void) pidException:(ICEException*)ex
+{
+ test(NO);
+}
+-(ICEInt) pid
+{
+ return pid;
+}
+-(void) shutdownResponse
+{
+ [self called];
+}
+
+-(void) shutdownException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) abortResponse
+{
+ test(NO);
+}
+-(void) abortException:(ICEException*)ex
+{
+ @try
+ {
+ @throw ex;
+ }
+ @catch(ICEConnectionLostException*)
+ {
+ }
+ @catch(ICEConnectFailedException*)
+ {
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ [self called];
+}
+-(void) idempotentAbortResponse
+{
+ test(NO);
+}
+-(void) idempotentAbortException:(ICEException*)ex
+{
+ @try
+ {
+ @throw ex;
+ }
+ @catch(ICEConnectionLostException*)
+ {
+ }
+ @catch(ICEConnectFailedException*)
+ {
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ [self called];
+}
+@end
+
+void
+allTests(id<ICECommunicator> communicator, NSArray* ports)
+{
+ tprintf("testing stringToProxy... ");
+ NSString* ref = @"test";
+ for(NSString* p in ports)
+ {
+ ref = [ref stringByAppendingString:@":default -p "];
+ ref = [ref stringByAppendingString:p];
+ }
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ test(base);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestTestIntfPrx> obj = [TestTestIntfPrx checkedCast:base];
+ test(obj);
+ test([obj isEqual:base]);
+ tprintf("ok\n");
+
+ int oldPid = 0;
+ BOOL ami = NO;
+ unsigned int i, j;
+ for(i = 1, j = 0; i <= [ports count]; ++i, ++j)
+ {
+ if(j > 3)
+ {
+ j = 0;
+ ami = !ami;
+ }
+
+ if(!ami)
+ {
+ tprintf("testing server %d... ", i);
+ int pid = [obj pid];
+ test(pid != oldPid);
+ tprintf("ok\n");
+ oldPid = pid;
+ }
+ else
+ {
+ tprintf("testing server %d with AMI... ", i);
+ Callback* cb = [[Callback alloc] init];
+ [obj begin_pid:^(ICEInt pid) { [cb pidResponse:pid]; }
+ exception:^(ICEException* ex) { [cb pidException:ex]; } ];
+ [cb check];
+ int pid = [cb pid];
+ test(pid != oldPid);
+ oldPid = pid;
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [cb release];
+#endif
+ tprintf("ok\n");
+ }
+
+ if(j == 0)
+ {
+ if(!ami)
+ {
+ tprintf("shutting down server %d... ", i);
+ [obj shutdown];
+ tprintf("ok\n");
+ }
+ else
+ {
+ tprintf("shutting down server %d with AMI... ", i);
+ Callback* cb = [[Callback alloc] init];
+ [obj begin_shutdown:^{ [cb shutdownResponse]; }
+ exception:^(ICEException* ex) { [cb shutdownException:ex]; }];
+ [cb check];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [cb release];
+#endif
+ tprintf("ok\n");
+ }
+ }
+ else if(j == 1 || i + 1 > [ports count])
+ {
+ if(!ami)
+ {
+ tprintf("aborting server %d... ", i);
+ @try
+ {
+ [obj abort];
+ test(NO);
+ }
+ @catch(ICEConnectionLostException*)
+ {
+ tprintf("ok\n");
+ }
+ @catch(ICEConnectFailedException*)
+ {
+ tprintf("ok\n");
+ }
+ }
+ else
+ {
+ tprintf("aborting server %d with AMI... ", i);
+ Callback* cb = [[Callback alloc] init];
+ [obj begin_abort:^{ [cb abortResponse]; } exception:^(ICEException* ex) { [cb abortException:ex]; }];
+ [cb check];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [cb release];
+#endif
+ tprintf("ok\n");
+ }
+ }
+ else if(j == 2 || j == 3)
+ {
+ if(!ami)
+ {
+ tprintf("aborting server %d and #%d with idempotent call... ", i, i + 1);
+ @try
+ {
+ [obj idempotentAbort];
+ test(NO);
+ }
+ @catch(ICEConnectionLostException*)
+ {
+ tprintf("ok\n");
+ }
+ @catch(ICEConnectFailedException*)
+ {
+ tprintf("ok\n");
+ }
+ }
+ else
+ {
+ tprintf("aborting server %d and #%d with idempotent AMI call... ", i, i + 1);
+ Callback* cb = [[Callback alloc] init];
+ [obj begin_idempotentAbort:^{ [cb idempotentAbortResponse]; }
+ exception:^(ICEException* ex) { [cb idempotentAbortException:ex]; }];
+ [cb check];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [cb release];
+#endif
+ tprintf("ok\n");
+ }
+
+ ++i;
+ }
+ else
+ {
+ test(NO);
+ }
+ }
+
+ tprintf("testing whether all servers are gone... ");
+ @try
+ {
+ [obj ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ tprintf("ok\n");
+ }
+}
+
diff --git a/objc/test/Ice/faultTolerance/Client.m b/objc/test/Ice/faultTolerance/Client.m
new file mode 100644
index 00000000000..314e7fa6b80
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/Client.m
@@ -0,0 +1,106 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <faultTolerance/Test.h>
+#import <stdio.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+void
+usage(const char* n)
+{
+ printf("Usage: %s port\n", n);
+}
+
+int
+run(int argc, char* argv[], id<ICECommunicator> communicator)
+{
+ NSMutableArray* ports = [NSMutableArray array];
+ int i;
+ for(i = 1; i < argc; ++i)
+ {
+ if(argv[i][0] == '-')
+ {
+ fprintf(stderr, "%s: unknown option `%s'", argv[0], argv[i]);
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ [ports addObject:[NSString stringWithUTF8String:argv[i]]];
+ }
+
+ if([ports count] == 0)
+ {
+ fprintf(stderr, "%s: no ports specified", argv[0]);
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ @try
+ {
+ void allTests(id<ICECommunicator>, NSArray*);
+ allTests(communicator, ports);
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+
+ //
+ // This test aborts servers, so we don't want warnings.
+ //
+ [initData.properties setProperty:@"Ice.Warn.Connections" value:@"0"];
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+
+ status = run(argc, argv, communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/faultTolerance/Makefile b/objc/test/Ice/faultTolerance/Makefile
new file mode 100644
index 00000000000..80e19841796
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = Test.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/faultTolerance/Server.m b/objc/test/Ice/faultTolerance/Server.m
new file mode 100644
index 00000000000..998279cb5e0
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/Server.m
@@ -0,0 +1,115 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <faultTolerance/TestI.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+#import <stdio.h>
+
+static void
+usage(const char* n)
+{
+ printf("Usage: %s port\n", n);
+}
+
+static int
+run(int argc, char** argv, id<ICECommunicator> communicator)
+{
+ int port = 0;
+ int i;
+ for(i = 1; i < argc; ++i)
+ {
+ if(argv[i][0] == '-')
+ {
+ fprintf(stderr, "%s: unknown option `%s'", argv[0], argv[i]);
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if(port > 0)
+ {
+ fprintf(stderr, "%s: only one port can be specified", argv[0]);
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ port = atoi(argv[i]);
+ }
+
+ if(port <= 0)
+ {
+ fprintf(stderr, "%s: no port specified", argv[0]);
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ NSString* endpts = [NSString stringWithFormat:@"default -p %d:udp", port];
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:endpts];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* object = [[[TestI alloc] init] autorelease];
+#else
+ ICEObject* object = [[TestI alloc] init];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"test"]];
+ [adapter activate];
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ //
+ // In this test, we need a longer server idle time, otherwise
+ // our test servers may time out before they are used in the
+ // test.
+ //
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties:&argc argv:argv];
+ [initData.properties setProperty:@"Ice.ServerIdleTime" value:@"120"]; // Two minutes.
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(argc, argv, communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ NSLog(@"%@", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/faultTolerance/Test.ice b/objc/test/Ice/faultTolerance/Test.ice
new file mode 100644
index 00000000000..8b1e15a963e
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/Test.ice
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+module Test
+{
+
+interface TestIntf
+{
+ void shutdown();
+ void abort();
+ idempotent void idempotentAbort();
+ idempotent int pid();
+};
+
+};
diff --git a/objc/test/Ice/faultTolerance/TestI.h b/objc/test/Ice/faultTolerance/TestI.h
new file mode 100644
index 00000000000..0f9d2672c50
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/TestI.h
@@ -0,0 +1,14 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <faultTolerance/Test.h>
+
+@interface TestI : TestTestIntf<TestTestIntf>
+@end
+
diff --git a/objc/test/Ice/faultTolerance/TestI.m b/objc/test/Ice/faultTolerance/TestI.m
new file mode 100644
index 00000000000..12ce4ea3cf5
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/TestI.m
@@ -0,0 +1,36 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <faultTolerance/TestI.h>
+
+#include <unistd.h>
+
+@implementation TestI
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+
+-(void) abort:(ICECurrent*)current
+{
+ exit(0);
+}
+
+-(void) idempotentAbort:(ICECurrent*)current
+{
+ exit(0);
+}
+
+-(ICEInt) pid:(ICECurrent*)current
+{
+ return getpid();
+}
+@end
+
diff --git a/objc/test/Ice/faultTolerance/run.py b/objc/test/Ice/faultTolerance/run.py
new file mode 100755
index 00000000000..01a58d2a3d0
--- /dev/null
+++ b/objc/test/Ice/faultTolerance/run.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+server = os.path.join(os.getcwd(), "server")
+client = os.path.join(os.getcwd(), "client")
+
+num = 12
+base = 13340
+
+serverProc = []
+for i in range(0, num):
+ print "starting server #%d..." % (i + 1),
+ serverProc.append(TestUtil.startServer(server, "%d" % (base + i)))
+ print "ok"
+
+ports = ""
+for i in range(0, num):
+ ports = "%s %d" % (ports, base + i)
+
+print "starting client...",
+clientProc = TestUtil.startClient(client, ports + " " + "--Ice.Trace.Network=0", startReader = False)
+print "ok"
+clientProc.startReader()
+
+clientProc.waitTestSuccess()
+for p in serverProc:
+ p.waitTestSuccess()
diff --git a/objc/test/Ice/hash/.gitignore b/objc/test/Ice/hash/.gitignore
new file mode 100644
index 00000000000..be837f9fdf3
--- /dev/null
+++ b/objc/test/Ice/hash/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+HashTest.m
+HashTest.h
diff --git a/objc/test/Ice/hash/AllTests.m b/objc/test/Ice/hash/AllTests.m
new file mode 100644
index 00000000000..f63e9d56759
--- /dev/null
+++ b/objc/test/Ice/hash/AllTests.m
@@ -0,0 +1,163 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <HashTest.h>
+
+#import <Foundation/Foundation.h>
+
+void
+hashAllTests()
+{
+ int maxCollisions = 10;
+ int maxIterations = 10000;
+
+ {
+ tprintf("testing proxy hash algorithm collisions... ");
+ int collisions = 0;
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties];
+ id<ICECommunicator> communicator = [ICEUtil createCommunicator:initData];
+ NSMutableDictionary* seenObject = [[NSMutableDictionary alloc] init];
+ for(int i = 0; collisions < maxCollisions && i < maxIterations; ++i)
+ {
+ NSString* s = [NSString stringWithFormat:@"%i:tcp -p %i -t 10%i:udp -p %i -h %i",
+ i, arc4random() % 65536, arc4random() % 1000000,
+ arc4random() % 65536, arc4random() % 100];
+ ICEObjectPrx* obj = [communicator stringToProxy:s];
+
+ NSNumber* hash = [NSNumber numberWithUnsignedInteger:[obj hash]];
+
+ if([seenObject objectForKey:hash])
+ {
+ if([obj isEqual:[seenObject objectForKey:hash]])
+ {
+ continue;
+ }
+ ++collisions;
+ }
+ else
+ {
+ [seenObject setObject:obj forKey:hash];
+ }
+ //
+ // Test the same object produce always the same hash.
+ //
+ test([obj hash] == [obj hash]);
+ test(collisions < maxCollisions);
+ }
+ [seenObject removeAllObjects];
+ [communicator destroy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [seenObject release];
+#endif
+ tprintf("ok\n");
+ }
+
+ tprintf("testing struct hash algorithm collisions... ");
+ {
+ int collisions = 0;
+ NSMutableDictionary* seenObject = [[NSMutableDictionary alloc] init];
+ for(int i = 0; collisions < maxCollisions && i < maxIterations; ++i)
+ {
+ TestHashPoint* obj = [TestHashPoint point:(arc4random() % 1000)
+ y:(arc4random() % 1000)];
+ NSNumber* hash = [NSNumber numberWithUnsignedInteger:[obj hash]];
+ if([seenObject objectForKey:hash])
+ {
+ if([obj isEqual:[seenObject objectForKey:hash]])
+ {
+ continue;
+ }
+ ++collisions;
+ }
+ else
+ {
+ [seenObject setObject:obj forKey:hash];
+ }
+ //
+ // Test the same object produce always the same hash.
+ //
+ test([obj hash] == [obj hash]);
+ test(collisions < maxCollisions);
+ }
+ [seenObject removeAllObjects];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [seenObject release];
+#endif
+ }
+ {
+ int collisions = 0;
+ NSMutableDictionary* seenObject = [[NSMutableDictionary alloc] init];
+ for(int i = 0; collisions < maxCollisions && i < maxIterations; ++i)
+ {
+ TestHashPointF* obj = [TestHashPointF pointF:(arc4random() % 1000)/3
+ y:(arc4random() % 1000)/5
+ z:(arc4random() % 1000)/7];
+
+ NSNumber* hash = [NSNumber numberWithUnsignedInteger:[obj hash]];
+ if([seenObject objectForKey:hash])
+ {
+ if([obj isEqual:[seenObject objectForKey:hash]])
+ {
+ continue;
+ }
+ ++collisions;
+ }
+ else
+ {
+ [seenObject setObject:obj forKey:hash];
+ }
+ //
+ // Test the same object produce always the same hash.
+ //
+ test([obj hash] == [obj hash]);
+ test(collisions < maxCollisions);
+ }
+ [seenObject removeAllObjects];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [seenObject release];
+#endif
+ }
+
+ {
+ int collisions = 0;
+ NSMutableDictionary* seenObject = [[NSMutableDictionary alloc] init];
+ for(int i = 0; collisions < maxCollisions && i < maxIterations; ++i)
+ {
+ TestHashPointD* obj = [TestHashPointD pointD:(arc4random() % 1000)/3
+ y:(arc4random() % 1000)/5
+ z:(arc4random() % 1000)/7];
+ NSNumber* hash = [NSNumber numberWithUnsignedInteger:[obj hash]];
+ if([seenObject objectForKey:hash])
+ {
+ if([obj isEqual:[seenObject objectForKey:hash]])
+ {
+ continue;
+ }
+ ++collisions;
+ }
+ else
+ {
+ [seenObject setObject:obj forKey:hash];
+ }
+ //
+ // Test the same object produce always the same hash.
+ //
+ test([obj hash] == [obj hash]);
+ test(collisions < maxCollisions);
+ }
+ [seenObject removeAllObjects];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [seenObject release];
+#endif
+ }
+ tprintf("ok\n");
+}
diff --git a/objc/test/Ice/hash/Client.m b/objc/test/Ice/hash/Client.m
new file mode 100644
index 00000000000..e91fddc6370
--- /dev/null
+++ b/objc/test/Ice/hash/Client.m
@@ -0,0 +1,53 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <HashTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run()
+{
+ void hashAllTests();
+ hashAllTests();
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main hashClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ @try
+ {
+ status = run();
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/hash/HashTest.ice b/objc/test/Ice/hash/HashTest.ice
new file mode 100644
index 00000000000..d9e8e42bee0
--- /dev/null
+++ b/objc/test/Ice/hash/HashTest.ice
@@ -0,0 +1,93 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestHash"]
+module Test
+{
+
+
+exception BaseException
+{
+};
+
+exception InvalidPointException extends BaseException
+{
+ int index;
+};
+
+exception InvalidLengthException extends BaseException
+{
+ int length;
+};
+
+exception OtherException
+{
+ int x;
+ int y;
+ int z;
+ bool b;
+};
+
+
+struct PointF
+{
+ float x;
+ float y;
+ float z;
+};
+
+struct PointD
+{
+ double x;
+ double y;
+ double z;
+};
+
+struct Point
+{
+ int x;
+ int y;
+};
+sequence<Point> Points;
+
+struct Polyline
+{
+ Points vertices;
+};
+
+struct Color
+{
+ int r;
+ int g;
+ int b;
+ int a;
+};
+dictionary<int, Color> StringColorMap;
+
+struct ColorPalette
+{
+ StringColorMap colors;
+};
+
+class Pen
+{
+ int thickness;
+ Test::Color color;
+};
+
+struct Draw
+{
+ Test::Color backgroundColor;
+ Test::Pen pen;
+ bool shared;
+};
+
+};
diff --git a/objc/test/Ice/hash/Makefile b/objc/test/Ice/hash/Makefile
new file mode 100644
index 00000000000..cf6376b4c5e
--- /dev/null
+++ b/objc/test/Ice/hash/Makefile
@@ -0,0 +1,29 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = HashTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+OBJS = $(COBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/hash/run.py b/objc/test/Ice/hash/run.py
new file mode 100755
index 00000000000..ac32c445572
--- /dev/null
+++ b/objc/test/Ice/hash/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+client = os.path.join(os.getcwd(), "client")
+TestUtil.simpleTest(client)
+
diff --git a/objc/test/Ice/hold/.gitignore b/objc/test/Ice/hold/.gitignore
new file mode 100644
index 00000000000..4e573bb9e5f
--- /dev/null
+++ b/objc/test/Ice/hold/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+HoldTest.m
+HoldTest.h
diff --git a/objc/test/Ice/hold/AllTests.m b/objc/test/Ice/hold/AllTests.m
new file mode 100644
index 00000000000..30219fa74c1
--- /dev/null
+++ b/objc/test/Ice/hold/AllTests.m
@@ -0,0 +1,266 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <HoldTest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface Condition : NSObject
+{
+ BOOL value;
+}
+-(id) initWithValue:(BOOL)value;
+@property (assign) BOOL value;
+@end
+
+@implementation Condition
+
+@synthesize value;
+
+-(id) initWithValue:(BOOL)v
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ value = v;
+ return self;
+}
+@end
+
+@interface AMICheckSetValue : NSObject
+{
+ Condition* condition;
+ ICEInt expected;
+ BOOL sent;
+ NSCondition* cond;
+}
+-(id)init:(Condition*)cond expected:(ICEInt)expected;
+-(void) waitForSent;
+@end
+
+@implementation AMICheckSetValue
+-(id)init:(Condition*)c expected:(ICEInt)e
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ condition = [c retain];
+#else
+ condition = c;
+#endif
+ expected = e;
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [condition release];
+ [super dealloc];
+}
+#endif
+
+-(void) ice_response:(ICEInt)value
+{
+ if(value != expected)
+ {
+ condition.value = NO;
+ }
+}
+-(void) ice_exception:(ICEException*)ex
+{
+ tprintf("unexpected exception: %@", ex);
+ test(false);
+}
+-(void) ice_sent
+{
+ [cond lock];
+ sent = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) waitForSent
+{
+ [cond lock];
+ while(!sent)
+ {
+ [cond wait];
+ }
+ [cond unlock];
+}
+@end
+
+void
+allTests(id<ICECommunicator> communicator)
+{
+ tprintf("testing stringToProxy... ");
+ NSString* ref = @"hold:default -p 12010 -t 30000";
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ test(base);
+ NSString* refSerialized = @"hold:default -p 12011 -t 60000";
+ id<ICEObjectPrx> baseSerialized = [communicator stringToProxy:refSerialized];
+ test(base);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestHoldHoldPrx> hold = [TestHoldHoldPrx checkedCast:base];
+ test(hold);
+ test([hold isEqual:base]);
+ id<TestHoldHoldPrx> holdSerialized = [TestHoldHoldPrx checkedCast:baseSerialized];
+ test(holdSerialized);
+ test([holdSerialized isEqual:baseSerialized]);
+ tprintf("ok\n");
+
+ tprintf("changing state between active and hold rapidly... ");
+ int i;
+ for(i = 0; i < 100; ++i)
+ {
+ [hold putOnHold:0];
+ }
+ for(i = 0; i < 100; ++i)
+ {
+ [[hold ice_oneway] putOnHold:0];
+ }
+ for(i = 0; i < 100; ++i)
+ {
+ [holdSerialized putOnHold:0];
+ }
+ for(i = 0; i < 100; ++i)
+ {
+ [[holdSerialized ice_oneway] putOnHold:0];
+ }
+ tprintf("ok\n");
+
+ tprintf("testing without serialize mode... ");
+ {
+#if defined(__clang__) && !__has_feature(objc_arc)
+ Condition* cond = [[[Condition alloc] initWithValue:YES] autorelease];
+#else
+ Condition* cond = [[Condition alloc] initWithValue:YES];
+#endif
+ int value = 0;
+ AMICheckSetValue* cb;
+ while([cond value])
+ {
+#if defined(__clang__) && !__has_feature(objc_arc)
+ cb = [[[AMICheckSetValue alloc] init:cond expected:value] autorelease];
+#else
+ cb = [[AMICheckSetValue alloc] init:cond expected:value];
+#endif
+ if([hold begin_set:++value delay:(random() % 5 + 1) response:^(ICEInt r) { [cb ice_response:r]; }
+ exception:^(ICEException* ex) { [cb ice_exception:ex]; } sent:^(BOOL ss) { [cb ice_sent]; }])
+ {
+ cb = 0;
+ }
+ if(value % 100 == 0)
+ {
+ if(cb)
+ {
+ [cb waitForSent];
+ cb = 0;
+ }
+ }
+ }
+ if(cb)
+ {
+ [cb waitForSent];
+ cb = 0;
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing with serialize mode... ");
+ {
+#if defined(__clang__) && !__has_feature(objc_arc)
+ Condition* cond = [[[Condition alloc] initWithValue:YES] autorelease];
+#else
+ Condition* cond = [[Condition alloc] initWithValue:YES];
+#endif
+ int value = 0;
+ AMICheckSetValue* cb;
+#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+ while(value < 300 && [cond value])
+#else
+ while(value < 3000 && [cond value])
+#endif
+ {
+#if defined(__clang__) && !__has_feature(objc_arc)
+ cb = [[[AMICheckSetValue alloc] init:cond expected:value] autorelease];
+#else
+ cb = [[AMICheckSetValue alloc] init:cond expected:value];
+#endif
+ if([holdSerialized begin_set:++value delay:0 response:^(ICEInt r) { [cb ice_response:r]; }
+ exception:^(ICEException* ex) { [cb ice_exception:ex]; } sent:^(BOOL ss) { [cb ice_sent]; }])
+ {
+ cb = 0;
+ }
+ if(value % 100 == 0)
+ {
+ if(cb)
+ {
+ [cb waitForSent];
+ cb = 0;
+ }
+ }
+ }
+ if(cb)
+ {
+ [cb waitForSent];
+ cb = 0;
+ }
+ test([cond value]);
+ int i;
+#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+ for(i = 0; i < 400; ++i)
+#else
+ for(i = 0; i < 20000; ++i)
+#endif
+ {
+ [[holdSerialized ice_oneway] setOneway:(value + 1) expected:value];
+ ++value;
+ if((i % 100) == 0)
+ {
+ [[holdSerialized ice_oneway] putOnHold:1];
+ }
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing waitForHold... ");
+ {
+ [hold waitForHold];
+ [hold waitForHold];
+ for(i = 0; i < 1000; ++i)
+ {
+ [[hold ice_oneway] ice_ping];
+ if((i % 20) == 0)
+ {
+ [hold putOnHold:0];
+ }
+ }
+ [hold putOnHold:-1];
+ [hold ice_ping];
+ [hold putOnHold:-1];
+ [hold ice_ping];
+ }
+ tprintf("ok\n");
+
+ tprintf("changing state to hold and shutting down server... ");
+ [hold shutdown];
+ tprintf("ok\n");
+}
diff --git a/objc/test/Ice/hold/Client.m b/objc/test/Ice/hold/Client.m
new file mode 100644
index 00000000000..d3b5a40408a
--- /dev/null
+++ b/objc/test/Ice/hold/Client.m
@@ -0,0 +1,76 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <HoldTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+int
+run(id<ICECommunicator> communicator)
+{
+ void allTests(id<ICECommunicator>);
+ allTests(communicator);
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main holdClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestHold", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/hold/HoldTest.ice b/objc/test/Ice/hold/HoldTest.ice
new file mode 100644
index 00000000000..bc77416ef31
--- /dev/null
+++ b/objc/test/Ice/hold/HoldTest.ice
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestHold"]
+module Test
+{
+
+interface Hold
+{
+ void putOnHold(int seconds);
+ void waitForHold();
+ int set(int value, int delay);
+ void setOneway(int value, int expected);
+ void shutdown();
+};
+
+};
diff --git a/objc/test/Ice/hold/Makefile b/objc/test/Ice/hold/Makefile
new file mode 100644
index 00000000000..bf682f4e99f
--- /dev/null
+++ b/objc/test/Ice/hold/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = HoldTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/hold/Server.m b/objc/test/Ice/hold/Server.m
new file mode 100644
index 00000000000..0c0c4918524
--- /dev/null
+++ b/objc/test/Ice/hold/Server.m
@@ -0,0 +1,101 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <hold/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter1.Endpoints" value:@"default -p 12010 -t 10000:udp"];
+ [[communicator getProperties] setProperty:@"TestAdapter1.ThreadPool.Size" value:@"5"];
+ [[communicator getProperties] setProperty:@"TestAdapter1.ThreadPool.SizeMax" value:@"5"];
+ [[communicator getProperties] setProperty:@"TestAdapter1.ThreadPool.SizeWarn" value:@"0"];
+ [[communicator getProperties] setProperty:@"TestAdapter1.ThreadPool.Serialize" value:@"0"];
+ id<ICEObjectAdapter> adapter1 = [communicator createObjectAdapter:@"TestAdapter1"];
+
+
+ [[communicator getProperties] setProperty:@"TestAdapter2.Endpoints" value:@"default -p 12011 -t 10000:udp"];
+ [[communicator getProperties] setProperty:@"TestAdapter2.ThreadPool.Size" value:@"5"];
+ [[communicator getProperties] setProperty:@"TestAdapter2.ThreadPool.SizeMax" value:@"5"];
+ [[communicator getProperties] setProperty:@"TestAdapter2.ThreadPool.SizeWarn" value:@"0"];
+ [[communicator getProperties] setProperty:@"TestAdapter2.ThreadPool.Serialize" value:@"1"];
+ id<ICEObjectAdapter> adapter2 = [communicator createObjectAdapter:@"TestAdapter2"];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adapter1 add:[[[HoldI alloc] init] autorelease] identity:[communicator stringToIdentity:@"hold"]];
+ [adapter2 add:[[[HoldI alloc] init] autorelease] identity:[communicator stringToIdentity:@"hold"]];
+#else
+ [adapter1 add:[[HoldI alloc] init] identity:[communicator stringToIdentity:@"hold"]];
+ [adapter2 add:[[HoldI alloc] init] identity:[communicator stringToIdentity:@"hold"]];
+#endif
+
+ [adapter1 activate];
+ [adapter2 activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main holdServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ @autoreleasepool
+ {
+ int status;
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestHold", @"::Test",
+ nil];
+#endif
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+ }
+}
diff --git a/objc/test/Ice/hold/TestI.h b/objc/test/Ice/hold/TestI.h
new file mode 100644
index 00000000000..07c6906264c
--- /dev/null
+++ b/objc/test/Ice/hold/TestI.h
@@ -0,0 +1,28 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+
+#import <HoldTest.h>
+
+#include <dispatch/dispatch.h>
+
+@interface Timer : NSObject
+{
+ dispatch_queue_t queue;
+}
+-(void) schedule:(void(^)())callback timeout:(ICEInt)timeout;
+@end
+
+@interface HoldI : TestHoldHold<TestHoldHold>
+{
+ ICEInt last;
+ Timer* timer;
+}
+
+@end
diff --git a/objc/test/Ice/hold/TestI.m b/objc/test/Ice/hold/TestI.m
new file mode 100644
index 00000000000..c65ec48a150
--- /dev/null
+++ b/objc/test/Ice/hold/TestI.m
@@ -0,0 +1,140 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <hold/TestI.h>
+#import <TestCommon.h>
+
+#import <Foundation/Foundation.h>
+
+@implementation Timer
+-(id) init
+{
+ self = [super init];
+ if(self != nil)
+ {
+ queue = dispatch_queue_create("timer", NULL);
+ }
+ return self;
+}
+-(void) dealloc
+{
+ dispatch_release(queue);
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [super dealloc];
+#endif
+}
+-(void) schedule:(void(^)())callback timeout:(ICEInt)t
+{
+ dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
+ dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, t * NSEC_PER_MSEC), DISPATCH_TIME_FOREVER, 0);
+ dispatch_source_set_event_handler(timer, ^{
+ callback();
+ dispatch_source_cancel(timer);
+ dispatch_release(timer);
+ });
+ dispatch_resume(timer);
+}
+@end
+
+@implementation HoldI
+-(id) init
+{
+ self = [super init];
+ if(self != nil)
+ {
+ timer = [Timer new];
+ }
+ return self;
+}
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [timer release];
+ [super dealloc];
+}
+#endif
+-(void) putOnHold:(ICEInt)milliSeconds current:(ICECurrent*)current
+{
+ if(milliSeconds < 0)
+ {
+ [current.adapter hold];
+ }
+ else if(milliSeconds == 0)
+ {
+ [current.adapter hold];
+ [current.adapter activate];
+ }
+ else
+ {
+ [timer schedule:^{
+ @try
+ {
+ [current.adapter hold];
+ [current.adapter activate];
+ }
+ @catch(ICEObjectAdapterDeactivatedException* ex)
+ {
+ }
+ @catch(id ex)
+ {
+ test(NO);
+ }
+ } timeout:milliSeconds];
+ }
+}
+
+-(void) waitForHold:(ICECurrent*)current
+{
+ [timer schedule:^{
+ @try
+ {
+ [current.adapter waitForHold];
+ [current.adapter activate];
+ }
+ @catch(ICEObjectAdapterDeactivatedException* ex)
+ {
+ test(NO);
+ }
+ @catch(id ex)
+ {
+ test(NO);
+ }
+ } timeout:0];
+}
+
+-(ICEInt) set:(ICEInt)value delay:(ICEInt)delay current:(ICECurrent*)current
+{
+ [NSThread sleepForTimeInterval:delay / 1000.0];
+ @synchronized(self)
+ {
+ ICEInt tmp = last;
+ last = value;
+ return tmp;
+ }
+ return 0;
+}
+
+
+-(void) setOneway:(ICEInt)value expected:(ICEInt)expected current:(ICECurrent*)current
+{
+ @synchronized(self)
+ {
+ test(last == expected);
+ last = value;
+ }
+}
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [current.adapter hold];
+ [[current.adapter getCommunicator] shutdown];
+}
+
+@end
diff --git a/objc/test/Ice/hold/run.py b/objc/test/Ice/hold/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/hold/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/info/.gitignore b/objc/test/Ice/info/.gitignore
new file mode 100644
index 00000000000..23a7fa22453
--- /dev/null
+++ b/objc/test/Ice/info/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+InfoTest.m
+InfoTest.h
diff --git a/objc/test/Ice/info/AllTests.m b/objc/test/Ice/info/AllTests.m
new file mode 100644
index 00000000000..c364ed99d4e
--- /dev/null
+++ b/objc/test/Ice/info/AllTests.m
@@ -0,0 +1,173 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <InfoTest.h>
+
+
+TestInfoTestIntfPrx*
+infoAllTests(id<ICECommunicator> communicator)
+{
+ tprintf("testing proxy endpoint information... ");
+ {
+ ICEObjectPrx* p1 = [communicator stringToProxy:@"test -t:default -h tcphost -p 10000 -t 1200 -z:"
+ "udp -h udphost -p 10001 --interface eth0 --ttl 5:"
+ "opaque -e 1.8 -t 100 -v ABCD"];
+
+ ICEEndpointSeq* endps = [p1 ice_getEndpoints];
+ id<ICEEndpoint> endpoint = [endps objectAtIndex:0];
+ ICEIPEndpointInfo* ipEndpoint = (ICEIPEndpointInfo*)[endpoint getInfo];
+ test([ipEndpoint isKindOfClass:[ICEIPEndpointInfo class]]);
+ test([[ipEndpoint host] isEqualToString:@"tcphost"]);
+ test(ipEndpoint.port == 10000);
+ test(ipEndpoint.timeout == 1200);
+ test(ipEndpoint.compress);
+ test(![ipEndpoint datagram]);
+ test(([ipEndpoint type] == ICETCPEndpointType && ![ipEndpoint secure]) ||
+ ([ipEndpoint type] == ICESSLEndpointType && [ipEndpoint secure]));
+
+ test(([ipEndpoint type] == ICETCPEndpointType && [ipEndpoint isKindOfClass:[ICETCPEndpointInfo class]]) ||
+ ([ipEndpoint type] == ICESSLEndpointType && [ipEndpoint isKindOfClass:[ICESSLEndpointInfo class]]));
+
+
+ endpoint = [endps objectAtIndex:1];
+ ICEUDPEndpointInfo* udpEndpoint = (ICEUDPEndpointInfo*)[endpoint getInfo];
+ test([udpEndpoint isKindOfClass:[ICEUDPEndpointInfo class]]);
+ test([udpEndpoint.host isEqualToString:@"udphost"]);
+ test(udpEndpoint.port == 10001);
+ test([udpEndpoint.mcastInterface isEqualToString:@"eth0"]);
+ test(udpEndpoint.mcastTtl == 5);
+ test(udpEndpoint.timeout == -1);
+ test(!udpEndpoint.compress);
+ test(![udpEndpoint secure]);
+ test([udpEndpoint datagram]);
+ test([udpEndpoint type] == ICEUDPEndpointType);
+
+ endpoint = [endps objectAtIndex:2];
+ ICEOpaqueEndpointInfo* opaqueEndpoint = (ICEOpaqueEndpointInfo*)[endpoint getInfo];
+ test([opaqueEndpoint isKindOfClass:[ICEOpaqueEndpointInfo class]]);
+ ICEEncodingVersion* rev = [[ICEEncodingVersion alloc] init:1 minor:8];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [rev autorelease];
+#endif
+ test([opaqueEndpoint.rawEncoding isEqual:rev]);
+ }
+ tprintf("ok\n");
+
+ NSString* defaultHost = [[communicator getProperties] getProperty:@"Ice.Default.Host"];
+ tprintf("test object adapter endpoint information... ");
+ {
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -t 15000:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+
+ ICEEndpointSeq* endpoints = [adapter getEndpoints];
+ test([endpoints count] == 2);
+ ICEEndpointSeq* publishedEndpoints = [adapter getPublishedEndpoints];
+ test([endpoints isEqualToArray:publishedEndpoints]);
+
+ id<ICEEndpoint> endpoint = [endpoints objectAtIndex:0];
+ ICEIPEndpointInfo* ipEndpoint = (ICEIPEndpointInfo*)[endpoint getInfo];
+ test([ipEndpoint isKindOfClass:[ICEIPEndpointInfo class]]);
+ test([ipEndpoint type] == ICETCPEndpointType || [ipEndpoint type] == ICESSLEndpointType);
+ test([ipEndpoint.host isEqualToString:defaultHost]);
+ test(ipEndpoint.port > 0);
+ test(ipEndpoint.timeout == 15000);
+
+ endpoint = [endpoints objectAtIndex:1];
+ ICEUDPEndpointInfo* udpEndpoint = (ICEUDPEndpointInfo*)[endpoint getInfo];
+ test([udpEndpoint isKindOfClass:[ICEUDPEndpointInfo class]]);
+ test([udpEndpoint.host isEqualToString:defaultHost]);
+ test([udpEndpoint datagram]);
+ test(udpEndpoint.port > 0);
+
+ [adapter destroy];
+
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -h * -p 12020"];
+ [[communicator getProperties] setProperty:@"TestAdapter.PublishedEndpoints" value:@"default -h 127.0.0.1 -p 12020"];
+ adapter = [communicator createObjectAdapter:@"TestAdapter"];
+
+ endpoints = [adapter getEndpoints];
+ test([endpoints count] >= 1);
+ publishedEndpoints = [adapter getPublishedEndpoints];
+ test([publishedEndpoints count] == 1);
+
+ for(id object in endpoints)
+ {
+ endpoint = (id<ICEEndpoint>)object;
+ ipEndpoint = (ICEIPEndpointInfo*)[endpoint getInfo];
+ test(ipEndpoint.port == 12020);
+ }
+
+ ipEndpoint = (ICEIPEndpointInfo*)[[publishedEndpoints objectAtIndex:0] getInfo];
+ test([ipEndpoint.host isEqualToString:@"127.0.0.1"]);
+ test(ipEndpoint.port == 12020);
+
+ [adapter destroy];
+ }
+ tprintf("ok\n");
+
+ ICEObjectPrx* base = [communicator stringToProxy:@"test:default -p 12010:udp -p 12010"];
+ TestInfoTestIntfPrx* testIntf = [TestInfoTestIntfPrx checkedCast:base];
+
+ tprintf("test connection endpoint information... ");
+ {
+ ICEEndpointInfo* info = [[[base ice_getConnection] getEndpoint] getInfo];
+ ICEIPEndpointInfo* ipinfo = (ICEIPEndpointInfo*)info;
+ test([ipinfo isKindOfClass:[ICEIPEndpointInfo class]]);
+ test(ipinfo.port == 12010);
+ test(!ipinfo.compress);
+ test([ipinfo.host isEqualToString:defaultHost]);
+
+ ICEContext* ctx = [testIntf getEndpointInfoAsContext];
+ test([[ctx objectForKey:@"host"] isEqualToString:ipinfo.host]);
+ test([[ctx objectForKey:@"compress"] isEqualToString:@"false"]);
+ test([[ctx objectForKey:@"port"] intValue] > 0);
+
+ info = [[[[base ice_datagram] ice_getConnection] getEndpoint] getInfo];
+ ICEUDPEndpointInfo* udp = (ICEUDPEndpointInfo*)info;
+ test([udp isKindOfClass:[ICEUDPEndpointInfo class]]);
+ test(udp.port == 12010);
+ test([udp.host isEqualToString:defaultHost]);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing connection information... ");
+ {
+ ICEIPConnectionInfo* info = (ICEIPConnectionInfo*)[[base ice_getConnection] getInfo];
+ test([info isKindOfClass:[ICEIPConnectionInfo class]]);
+ test(!info.incoming);
+ test([info.adapterName isEqualToString:@""]);
+ test(info.localPort > 0);
+ test(info.remotePort == 12010);
+ test([info.remoteAddress isEqualToString:defaultHost]);
+ test([info.localAddress isEqualToString:defaultHost]);
+
+
+ ICEContext* ctx = [testIntf getConnectionInfoAsContext];
+ test([[ctx objectForKey:@"incoming"] isEqualToString:@"true"]);
+ test([[ctx objectForKey:@"adapterName"] isEqualToString:@"TestAdapter"]);
+ test([[ctx objectForKey:@"remoteAddress"] isEqualToString:info.remoteAddress]);
+ test([[ctx objectForKey:@"localAddress"] isEqualToString:info.localAddress]);
+ test([[ctx objectForKey:@"remotePort"] intValue] == info.localPort);
+ test([[ctx objectForKey:@"localPort"] intValue] == info.remotePort);
+
+ info = (ICEIPConnectionInfo*)[[[base ice_datagram] ice_getConnection] getInfo];
+ test([info isKindOfClass:[ICEIPConnectionInfo class]]);
+ test(!info.incoming);
+ test([info.adapterName isEqualToString:@""]);
+ test(info.localPort > 0);
+ test(info.remotePort == 12010);
+ test([info.remoteAddress isEqualToString:defaultHost]);
+ test([info.localAddress isEqualToString:defaultHost]);
+ }
+ tprintf("ok\n");
+
+ return testIntf;
+}
diff --git a/objc/test/Ice/info/Client.m b/objc/test/Ice/info/Client.m
new file mode 100644
index 00000000000..85dfcb28eb5
--- /dev/null
+++ b/objc/test/Ice/info/Client.m
@@ -0,0 +1,79 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <InfoTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ TestInfoTestIntfPrx* infoAllTests(id<ICECommunicator>);
+ TestInfoTestIntfPrx* intf = infoAllTests(communicator);
+
+ [intf shutdown];
+
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main infoClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestInfo", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/info/InfoTest.ice b/objc/test/Ice/info/InfoTest.ice
new file mode 100644
index 00000000000..dfeb7fc62e4
--- /dev/null
+++ b/objc/test/Ice/info/InfoTest.ice
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/Current.ice>
+
+["objc:prefix:TestInfo"]
+module Test
+{
+
+interface TestIntf
+{
+ void shutdown();
+
+ Ice::Context getEndpointInfoAsContext();
+
+ Ice::Context getConnectionInfoAsContext();
+};
+
+};
diff --git a/objc/test/Ice/info/Makefile b/objc/test/Ice/info/Makefile
new file mode 100644
index 00000000000..3156167470a
--- /dev/null
+++ b/objc/test/Ice/info/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = InfoTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/info/Server.m b/objc/test/Ice/info/Server.m
new file mode 100644
index 00000000000..408b98a85ff
--- /dev/null
+++ b/objc/test/Ice/info/Server.m
@@ -0,0 +1,83 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <info/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adapter add:[[[TestInfoTestIntfI alloc] init] autorelease]
+ identity:[communicator stringToIdentity:@"test"]];
+#else
+ [adapter add:[[TestInfoTestIntfI alloc] init] identity:[communicator stringToIdentity:@"test"]];
+#endif
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main infoServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestProxy", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/info/TestI.h b/objc/test/Ice/info/TestI.h
new file mode 100644
index 00000000000..295eb601ab2
--- /dev/null
+++ b/objc/test/Ice/info/TestI.h
@@ -0,0 +1,19 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <InfoTest.h>
+
+@interface TestInfoTestIntfI : TestInfoTestIntf<TestInfoTestIntf>
+{
+}
+
+-(void) shutdown:(ICECurrent*)current;
+-(ICEContext*) getEndpointInfoAsContext:(ICECurrent*)current;
+-(ICEContext*) getConnectionInfoAsContext:(ICECurrent*)current;
+@end
diff --git a/objc/test/Ice/info/TestI.m b/objc/test/Ice/info/TestI.m
new file mode 100644
index 00000000000..16c44bf48fc
--- /dev/null
+++ b/objc/test/Ice/info/TestI.m
@@ -0,0 +1,60 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <info/TestI.h>
+#import <TestCommon.h>
+
+@implementation TestInfoTestIntfI
+
+
+-(void) shutdown:(ICECurrent*)c
+{
+ [[[c adapter] getCommunicator] shutdown];
+}
+
+-(ICEContext*) getEndpointInfoAsContext:(ICECurrent*)current
+{
+ id<ICEEndpoint> endpoint = [current.con getEndpoint];
+ ICEEndpointInfo* info = [endpoint getInfo];
+
+ ICEMutableContext* ctx = [ICEMutableContext dictionaryWithObject:[NSString stringWithFormat:@"%d", [info timeout]]
+ forKey:@"timeout"];
+
+ [ctx setObject:info.compress ? @"true" : @"false" forKey:@"compress"];
+ [ctx setObject:[info datagram] ? @"true" : @"false" forKey:@"datagram"];
+ [ctx setObject:[info secure] ? @"true" : @"false" forKey:@"secure"];
+ [ctx setObject:[NSString stringWithFormat:@"%d", [info type]] forKey:@"type"];
+
+ ICEIPEndpointInfo* ipinfo = (ICEIPEndpointInfo*)info;
+ [ctx setObject:ipinfo.host forKey:@"host"];
+ [ctx setObject:[NSString stringWithFormat:@"%d", ipinfo.port] forKey:@"port"];
+
+ if([ipinfo isKindOfClass:[ICEUDPEndpointInfo class]])
+ {
+ ICEUDPEndpointInfo* udp = (ICEUDPEndpointInfo*)ipinfo;
+ [ctx setObject:udp.mcastInterface forKey:@"mcastInterface"];
+ [ctx setObject:[NSString stringWithFormat:@"%d", udp.mcastTtl] forKey:@"mcastTtl"];
+ }
+ return ctx;
+}
+
+-(ICEContext*) getConnectionInfoAsContext:(ICECurrent*)current
+{
+ ICEConnectionInfo* info = [[current con] getInfo];
+ ICEMutableContext* ctx = [ICEMutableContext dictionaryWithObject:[info adapterName] forKey:@"adapterName"];
+ [ctx setObject:info.incoming ? @"true" : @"false" forKey:@"incoming"];
+ ICEIPConnectionInfo* ipinfo = (ICEIPConnectionInfo*)info;
+ [ctx setObject:ipinfo.localAddress forKey:@"localAddress"];
+ [ctx setObject:[NSString stringWithFormat:@"%d", ipinfo.localPort] forKey:@"localPort"];
+ [ctx setObject:ipinfo.remoteAddress forKey:@"remoteAddress"];
+ [ctx setObject:[NSString stringWithFormat:@"%d", ipinfo.remotePort] forKey:@"remotePort"];
+ return ctx;
+}
+@end
diff --git a/objc/test/Ice/info/run.py b/objc/test/Ice/info/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/info/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/inheritance/.gitignore b/objc/test/Ice/inheritance/.gitignore
new file mode 100644
index 00000000000..54661118c80
--- /dev/null
+++ b/objc/test/Ice/inheritance/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+InheritanceTest.m
+InheritanceTest.h
diff --git a/objc/test/Ice/inheritance/AllTests.m b/objc/test/Ice/inheritance/AllTests.m
new file mode 100644
index 00000000000..f55588b0b64
--- /dev/null
+++ b/objc/test/Ice/inheritance/AllTests.m
@@ -0,0 +1,222 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <InheritanceTest.h>
+
+
+id<TestInheritanceInitialPrx>
+inheritanceAllTests(id<ICECommunicator> communicator)
+{
+ tprintf("testing stringToProxy... ");
+ NSString* ref = @"initial:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ test(base);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestInheritanceInitialPrx> initial = [TestInheritanceInitialPrx checkedCast:base];
+ test(initial);
+ test([initial isEqual:base]);
+ tprintf("ok\n");
+
+ tprintf("getting proxies for class hierarchy... ");
+ id<TestInheritanceMACAPrx> ca = [initial caop];
+ id<TestInheritanceMBCBPrx> cb = [initial cbop];
+ id<TestInheritanceMACCPrx> cc = [initial ccop];
+ id<TestInheritanceMACDPrx> cd = [initial cdop];
+ test(ca != cb);
+ test(ca != cc);
+ test(ca != cd);
+ test(cb != cc);
+ test(cb != cd);
+ test(cc != cd);
+ tprintf("ok\n");
+
+ tprintf("getting proxies for interface hierarchy... ");
+ id<TestInheritanceMAIAPrx> ia = [initial iaop];
+ id<TestInheritanceMBIB1Prx> ib1 = [initial ib1op];
+ id<TestInheritanceMBIB2Prx> ib2 = [initial ib2op];
+ id<TestInheritanceMAICPrx> ic = [initial icop];
+ test(ia != ib1);
+ test(ia != ib2);
+ test(ia != ic);
+ test(ib1 != ic);
+ test(ib2 != ic);
+ tprintf("ok\n");
+
+ tprintf("invoking proxy operations on class hierarchy... ");
+ id<TestInheritanceMACAPrx> cao;
+ id<TestInheritanceMBCBPrx> cbo;
+ id<TestInheritanceMACCPrx> cco;
+
+ cao = [ca caop:ca];
+ test([cao isEqual:ca]);
+ cao = [ca caop:cb];
+ test([cao isEqual:cb]);
+ cao = [ca caop:cc];
+ test([cao isEqual:cc]);
+ cao = [cb caop:ca];
+ test([cao isEqual:ca]);
+ cao = [cb caop:cb];
+ test([cao isEqual:cb]);
+ cao = [cb caop:cc];
+ test([cao isEqual:cc]);
+ cao = [cc caop:ca];
+ test([cao isEqual:ca]);
+ cao = [cc caop:cb];
+ test([cao isEqual:cb]);
+ cao = [cc caop:cc];
+ test([cao isEqual:cc]);
+
+ cao = [cb cbop:cb];
+ test([cao isEqual:cb]);
+ cbo = [cb cbop:cb];
+ test([cbo isEqual:cb]);
+ cao = [cb cbop:cc];
+ test([cao isEqual:cc]);
+ cbo = [cb cbop:cc];
+ test([cbo isEqual:cc]);
+ cao = [cc cbop:cb];
+ test([cao isEqual:cb]);
+ cbo = [cc cbop:cb];
+ test([cbo isEqual:cb]);
+ cao = [cc cbop:cc];
+ test([cao isEqual:cc]);
+ cbo = [cc cbop:cc];
+ test([cbo isEqual:cc]);
+
+ cao = [cc ccop:cc];
+ test([cao isEqual:cc]);
+ cbo = [cc ccop:cc];
+ test([cbo isEqual:cc]);
+ cco = [cc ccop:cc];
+ test([cco isEqual:cc]);
+ tprintf("ok\n");
+
+ tprintf("ditto, but for interface hierarchy... ");
+ id<TestInheritanceMAIAPrx> iao;
+ id<TestInheritanceMBIB1Prx> ib1o;
+ id<TestInheritanceMBIB2Prx> ib2o;
+ id<TestInheritanceMAICPrx> ico;
+
+ iao = [ia iaop:ia];
+ test([iao isEqual:ia]);
+ iao = [ia iaop:ib1];
+ test([iao isEqual:ib1]);
+ iao = [ia iaop:ib2];
+ test([iao isEqual:ib2]);
+ iao = [ia iaop:ic];
+ test([iao isEqual:ic]);
+ iao = [ib1 iaop:ia];
+ test([iao isEqual:ia]);
+ iao = [ib1 iaop:ib1];
+ test([iao isEqual:ib1]);
+ iao = [ib1 iaop:ib2];
+ test([iao isEqual:ib2]);
+ iao = [ib1 iaop:ic];
+ test([iao isEqual:ic]);
+ iao = [ib2 iaop:ia];
+ test([iao isEqual:ia]);
+ iao = [ib2 iaop:ib1];
+ test([iao isEqual:ib1]);
+ iao = [ib2 iaop:ib2];
+ test([iao isEqual:ib2]);
+ iao = [ib2 iaop:ic];
+ test([iao isEqual:ic]);
+ iao = [ic iaop:ia];
+ test([iao isEqual:ia]);
+ iao = [ic iaop:ib1];
+ test([iao isEqual:ib1]);
+ iao = [ic iaop:ib2];
+ test([iao isEqual:ib2]);
+ iao = [ic iaop:ic];
+ test([iao isEqual:ic]);
+
+ iao = [ib1 ib1op:ib1];
+ test([iao isEqual:ib1]);
+ ib1o = [ib1 ib1op:ib1];
+ test([ib1o isEqual:ib1]);
+ iao = [ib1 ib1op:ic];
+ test([iao isEqual:ic]);
+ ib1o = [ib1 ib1op:ic];
+ test([ib1o isEqual:ic]);
+ iao = [ic ib1op:ib1];
+ test([iao isEqual:ib1]);
+ ib1o = [ic ib1op:ib1];
+ test([ib1o isEqual:ib1]);
+ iao = [ic ib1op:ic];
+ test([iao isEqual:ic]);
+ ib1o = [ic ib1op:ic];
+ test([ib1o isEqual:ic]);
+
+ iao = [ib2 ib2op:ib2];
+ test([iao isEqual:ib2]);
+ ib2o = [ib2 ib2op:ib2];
+ test([ib2o isEqual:ib2]);
+ iao = [ib2 ib2op:ic];
+ test([iao isEqual:ic]);
+ ib2o = [ib2 ib2op:ic];
+ test([ib2o isEqual:ic]);
+ iao = [ic ib2op:ib2];
+ test([iao isEqual:ib2]);
+ ib2o = [ic ib2op:ib2];
+ test([ib2o isEqual:ib2]);
+ iao = [ic ib2op:ic];
+ test([iao isEqual:ic]);
+ ib2o = [ic ib2op:ic];
+ test([ib2o isEqual:ic]);
+
+ iao = [ic icop:ic];
+ test([iao isEqual:ic]);
+ ib1o = [ic icop:ic];
+ test([ib1o isEqual:ic]);
+ ib2o = [ic icop:ic];
+ test([ib2o isEqual:ic]);
+ ico = [ic icop:ic];
+ test([ico isEqual:ic]);
+
+ tprintf("ok\n");
+
+ tprintf("ditto, but for class implementing interfaces... ");
+// id<TestInheritanceMACDPrx> cdo;
+
+ cao = [cd caop:cd];
+ test([cao isEqual:cd]);
+ cbo = [cd cbop:cd];
+ test([cbo isEqual:cd]);
+ cco = [cd ccop:cd];
+ test([cco isEqual:cd]);
+
+ iao = [cd iaop:cd];
+ test([iao isEqual:cd]);
+ ib1o = [cd ib1op:cd];
+ test([ib1o isEqual:cd]);
+ ib2o = [cd ib2op:cd];
+ test([ib2o isEqual:cd]);
+
+ cao = [cd cdop:cd];
+ test([cao isEqual:cd]);
+ cbo = [cd cdop:cd];
+ test([cbo isEqual:cd]);
+ cco = [cd cdop:cd];
+ test([cco isEqual:cd]);
+
+ iao = [cd cdop:cd];
+ test([iao isEqual:cd]);
+ ib1o = [cd cdop:cd];
+ test([ib1o isEqual:cd]);
+ ib2o = [cd cdop:cd];
+ test([ib2o isEqual:cd]);
+
+ tprintf("ok\n");
+
+ return initial;
+}
diff --git a/objc/test/Ice/inheritance/Client.m b/objc/test/Ice/inheritance/Client.m
new file mode 100644
index 00000000000..684b462f80b
--- /dev/null
+++ b/objc/test/Ice/inheritance/Client.m
@@ -0,0 +1,77 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <InheritanceTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestInheritanceInitialPrx> inheritanceAllTests(id<ICECommunicator>);
+ id<TestInheritanceInitialPrx> initial = inheritanceAllTests(communicator);
+ [initial shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main inheritanceClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestInheritance", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/inheritance/InheritanceTest.ice b/objc/test/Ice/inheritance/InheritanceTest.ice
new file mode 100644
index 00000000000..aa5c59b2171
--- /dev/null
+++ b/objc/test/Ice/inheritance/InheritanceTest.ice
@@ -0,0 +1,87 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestInheritance"]
+module Test
+{
+
+["objc:prefix:TestInheritanceMA"]
+module MA
+{
+
+interface IA
+{
+ IA* iaop(IA* p);
+};
+
+class CA
+{
+ CA* caop(CA* p);
+};
+
+};
+
+["objc:prefix:TestInheritanceMB"]
+module MB
+{
+
+interface IB1 extends MA::IA
+{
+ IB1* ib1op(IB1* p);
+};
+
+interface IB2 extends MA::IA
+{
+ IB2* ib2op(IB2* p);
+};
+
+class CB extends MA::CA
+{
+ CB* cbop(CB* p);
+};
+
+};
+
+["objc:prefix:TestInheritanceMA"]
+module MA
+{
+
+interface IC extends MB::IB1, MB::IB2
+{
+ IC* icop(IC* p);
+};
+
+class CC extends MB::CB
+{
+ CC* ccop(CC* p);
+};
+
+class CD extends CC implements MB::IB1, MB::IB2
+{
+ CD* cdop(CD* p);
+};
+
+};
+
+interface Initial
+{
+ void shutdown();
+ MA::CA* caop();
+ MB::CB* cbop();
+ MA::CC* ccop();
+ MA::CD* cdop();
+ MA::IA* iaop();
+ MB::IB1* ib1op();
+ MB::IB2* ib2op();
+ MA::IC* icop();
+};
+
+};
diff --git a/objc/test/Ice/inheritance/Makefile b/objc/test/Ice/inheritance/Makefile
new file mode 100644
index 00000000000..eb5f28651d7
--- /dev/null
+++ b/objc/test/Ice/inheritance/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = InheritanceTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/inheritance/Server.m b/objc/test/Ice/inheritance/Server.m
new file mode 100644
index 00000000000..b105154f4a1
--- /dev/null
+++ b/objc/test/Ice/inheritance/Server.m
@@ -0,0 +1,83 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <inheritance/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* object = [[[TestInheritanceInitialI alloc] initWithAdapter:adapter] autorelease];
+#else
+ ICEObject* object = [[TestInheritanceInitialI alloc] initWithAdapter:adapter];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"initial"]];
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main inheritanceServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestInheritance", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/inheritance/TestI.h b/objc/test/Ice/inheritance/TestI.h
new file mode 100644
index 00000000000..8ade1ba0402
--- /dev/null
+++ b/objc/test/Ice/inheritance/TestI.h
@@ -0,0 +1,50 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <InheritanceTest.h>
+
+@interface TestInheritanceInitialI : TestInheritanceInitial<TestInheritanceInitial>
+{
+ id<ICEObjectAdapter> adapter_;
+ id<TestInheritanceMACAPrx> ca_;
+ id<TestInheritanceMBCBPrx> cb_;
+ id<TestInheritanceMACCPrx> cc_;
+ id<TestInheritanceMACDPrx> cd_;
+ id<TestInheritanceMAIAPrx> ia_;
+ id<TestInheritanceMBIB1Prx> ib1_;
+ id<TestInheritanceMBIB2Prx> ib2_;
+ id<TestInheritanceMAICPrx> ic_;
+}
+-(id)initWithAdapter:(id<ICEObjectAdapter>) adapter;
+@end
+
+@interface CAI : TestInheritanceMACA<TestInheritanceMACA>
+@end
+
+@interface CBI : TestInheritanceMBCB<TestInheritanceMBCB>
+@end
+
+@interface CCI : TestInheritanceMACC<TestInheritanceMACC>
+@end
+
+@interface IAI : TestInheritanceMAIA<TestInheritanceMAIA>
+@end
+
+@interface IB1I : TestInheritanceMBIB1<TestInheritanceMBIB1>
+@end
+
+@interface IB2I : TestInheritanceMBIB2<TestInheritanceMBIB2>
+@end
+
+@interface ICI : TestInheritanceMAIC<TestInheritanceMAIC>
+@end
+
+@interface CDI : TestInheritanceMACD<TestInheritanceMACD>
+@end
+
diff --git a/objc/test/Ice/inheritance/TestI.m b/objc/test/Ice/inheritance/TestI.m
new file mode 100644
index 00000000000..b1e981d0fce
--- /dev/null
+++ b/objc/test/Ice/inheritance/TestI.m
@@ -0,0 +1,198 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <inheritance/TestI.h>
+
+@implementation CAI
+-(id<TestInheritanceMACAPrx>) caop:(id<TestInheritanceMACAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+@end
+
+@implementation CBI
+-(id<TestInheritanceMACAPrx>) caop:(id<TestInheritanceMACAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBCBPrx>) cbop:(id<TestInheritanceMBCBPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+@end
+
+@implementation CCI
+-(id<TestInheritanceMACAPrx>) caop:(id<TestInheritanceMACAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBCBPrx>) cbop:(id<TestInheritanceMBCBPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMACCPrx>) ccop:(id<TestInheritanceMACCPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+@end
+
+@implementation IAI
+-(id<TestInheritanceMAIAPrx>) iaop:(id<TestInheritanceMAIAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+@end
+
+@implementation IB1I
+-(id<TestInheritanceMAIAPrx>) iaop:(id<TestInheritanceMAIAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBIB1Prx>) ib1op:(id<TestInheritanceMBIB1Prx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+@end
+
+@implementation IB2I
+-(id<TestInheritanceMAIAPrx>) iaop:(id<TestInheritanceMAIAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBIB2Prx>) ib2op:(id<TestInheritanceMBIB2Prx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+@end
+
+@implementation ICI
+-(id<TestInheritanceMAIAPrx>) iaop:(id<TestInheritanceMAIAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBIB1Prx>) ib1op:(id<TestInheritanceMBIB1Prx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBIB2Prx>) ib2op:(id<TestInheritanceMBIB2Prx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMAICPrx>) icop:(id<TestInheritanceMAICPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+@end
+
+@implementation CDI
+-(id<TestInheritanceMACAPrx>) caop:(id<TestInheritanceMACAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBCBPrx>) cbop:(id<TestInheritanceMBCBPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMACCPrx>) ccop:(id<TestInheritanceMACCPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMACDPrx>) cdop:(id<TestInheritanceMACDPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMAIAPrx>) iaop:(id<TestInheritanceMAIAPrx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBIB1Prx>) ib1op:(id<TestInheritanceMBIB1Prx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+-(id<TestInheritanceMBIB2Prx>) ib2op:(id<TestInheritanceMBIB2Prx>)p current:(ICECurrent*)current
+{
+ return p;
+}
+@end
+
+@implementation TestInheritanceInitialI
+-(id) initWithAdapter:(id<ICEObjectAdapter>)adapter
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ca_ = [TestInheritanceMACAPrx uncheckedCast:[adapter addWithUUID:[[[CAI alloc] init] autorelease]]];
+ cb_ = [TestInheritanceMBCBPrx uncheckedCast:[adapter addWithUUID:[[[CBI alloc] init] autorelease]]];
+ cc_ = [TestInheritanceMACCPrx uncheckedCast:[adapter addWithUUID:[[[CCI alloc] init] autorelease]]];
+ cd_ = [TestInheritanceMACDPrx uncheckedCast:[adapter addWithUUID:[[[CDI alloc] init] autorelease]]];
+ ia_ = [TestInheritanceMAIAPrx uncheckedCast:[adapter addWithUUID:[[[IAI alloc] init] autorelease]]];
+ ib1_ = [TestInheritanceMBIB1Prx uncheckedCast:[adapter addWithUUID:[[[IB1I alloc] init] autorelease]]];
+ ib2_ = [TestInheritanceMBIB2Prx uncheckedCast:[adapter addWithUUID:[[[IB2I alloc] init] autorelease]]];
+ ic_ = [TestInheritanceMAICPrx uncheckedCast:[adapter addWithUUID:[[[ICI alloc] init] autorelease]]];
+#else
+ ca_ = [TestInheritanceMACAPrx uncheckedCast:[adapter addWithUUID:[[CAI alloc] init]]];
+ cb_ = [TestInheritanceMBCBPrx uncheckedCast:[adapter addWithUUID:[[CBI alloc] init]]];
+ cc_ = [TestInheritanceMACCPrx uncheckedCast:[adapter addWithUUID:[[CCI alloc] init]]];
+ cd_ = [TestInheritanceMACDPrx uncheckedCast:[adapter addWithUUID:[[CDI alloc] init]]];
+ ia_ = [TestInheritanceMAIAPrx uncheckedCast:[adapter addWithUUID:[[IAI alloc] init]]];
+ ib1_ = [TestInheritanceMBIB1Prx uncheckedCast:[adapter addWithUUID:[[IB1I alloc] init]]];
+ ib2_ = [TestInheritanceMBIB2Prx uncheckedCast:[adapter addWithUUID:[[IB2I alloc] init]]];
+ ic_ = [TestInheritanceMAICPrx uncheckedCast:[adapter addWithUUID:[[ICI alloc] init]]];
+#endif
+ return self;
+}
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+
+-(id<TestInheritanceMACAPrx>) caop:(ICECurrent*)current
+{
+ return ca_;
+}
+
+-(id<TestInheritanceMBCBPrx>) cbop:(ICECurrent*)current
+{
+ return cb_;
+}
+
+-(id<TestInheritanceMACCPrx>) ccop:(ICECurrent*)current
+{
+ return cc_;
+}
+
+-(id<TestInheritanceMACDPrx>) cdop:(ICECurrent*)current
+{
+ return cd_;
+}
+
+-(id<TestInheritanceMAIAPrx>) iaop:(ICECurrent*)current
+{
+ return ia_;
+}
+
+-(id<TestInheritanceMBIB1Prx>) ib1op:(ICECurrent*)current
+{
+ return ib1_;
+}
+
+-(id<TestInheritanceMBIB2Prx>) ib2op:(ICECurrent*)current
+{
+ return ib2_;
+}
+
+-(id<TestInheritanceMAICPrx>) icop:(ICECurrent*)current
+{
+ return ic_;
+}
+@end
diff --git a/objc/test/Ice/inheritance/run.py b/objc/test/Ice/inheritance/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/inheritance/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/interceptor/.gitignore b/objc/test/Ice/interceptor/.gitignore
new file mode 100644
index 00000000000..a7aee74ccef
--- /dev/null
+++ b/objc/test/Ice/interceptor/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+InterceptorTest.m
+InterceptorTest.h
diff --git a/objc/test/Ice/interceptor/Client.m b/objc/test/Ice/interceptor/Client.m
new file mode 100644
index 00000000000..fc426770700
--- /dev/null
+++ b/objc/test/Ice/interceptor/Client.m
@@ -0,0 +1,166 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <InterceptorTest.h>
+#import <interceptor/MyObjectI.h>
+#import <interceptor/InterceptorI.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ //
+ // Create OA and servants
+ //
+ id<ICEObjectAdapter> oa = [communicator createObjectAdapterWithEndpoints:@"MyOA" endpoints:@"tcp -h localhost"];
+ ICEObject* servant = [[TestInterceptorMyObjectI alloc] init];
+ InterceptorI* interceptor = [[InterceptorI alloc] init:servant];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [servant autorelease];
+ [interceptor autorelease];
+#endif
+ id<TestInterceptorMyObjectPrx> prx = [TestInterceptorMyObjectPrx uncheckedCast:[oa addWithUUID:interceptor]];
+
+ [oa activate];
+
+ tprintf("testing simple interceptor... ");
+ test([[interceptor getLastOperation] length] == 0);
+ [prx ice_ping];
+ test([[interceptor getLastOperation] isEqualToString:@"ice_ping"]);
+ test([interceptor getLastStatus]);
+ NSString* typeId = [prx ice_id];
+ test([[interceptor getLastOperation] isEqualToString:@"ice_id"]);
+ test([interceptor getLastStatus]);
+ test([prx ice_isA:typeId]);
+ test([[interceptor getLastOperation] isEqualToString:@"ice_isA"]);
+ test([interceptor getLastStatus]);
+ test([prx add:33 y:12] == 45);
+ test([[interceptor getLastOperation] isEqualToString:@"add"]);
+ test([interceptor getLastStatus]);
+ tprintf("ok\n");
+
+ tprintf("testing retry... ");
+ test([prx addWithRetry:33 y:12] == 45);
+ test([[interceptor getLastOperation] isEqualToString:@"addWithRetry"]);
+ test([interceptor getLastStatus]);
+ tprintf("ok\n");
+
+ tprintf("testing user exception... ");
+ @try
+ {
+ [prx badAdd:33 y:12];
+ test(NO);
+ }
+ @catch(TestInterceptorInvalidInputException*)
+ {
+ // expected
+ }
+ test([[interceptor getLastOperation] isEqualToString:@"badAdd"]);
+ test([interceptor getLastStatus] == NO);
+ tprintf("ok\n");
+ tprintf("testing ONE... ");
+
+ [interceptor clear];
+ @try
+ {
+ [prx notExistAdd:33 y:12];
+ test(NO);
+ }
+ @catch(ICEObjectNotExistException*)
+ {
+ // expected
+ }
+ test([[interceptor getLastOperation] isEqualToString:@"notExistAdd"]);
+ tprintf("ok\n");
+ tprintf("testing system exception... ");
+ [interceptor clear];
+ @try
+ {
+ [prx badSystemAdd:33 y:12];
+ test(NO);
+ }
+ @catch(ICEUnknownLocalException*)
+ {
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ test([[interceptor getLastOperation] isEqualToString:@"badSystemAdd"]);
+ tprintf("ok\n");
+
+ return 0;
+}
+
+#if TARGET_OS_IPHONE
+# define main interceptorClient
+
+int
+interceptorServer(int argc, char* argv[])
+{
+ serverReady(nil);
+ return 0;
+}
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+ [initData.properties setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestInterceptor", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
+
diff --git a/objc/test/Ice/interceptor/InterceptorI.h b/objc/test/Ice/interceptor/InterceptorI.h
new file mode 100644
index 00000000000..6557d12a7cf
--- /dev/null
+++ b/objc/test/Ice/interceptor/InterceptorI.h
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+
+@interface InterceptorI : ICEDispatchInterceptor <ICEDispatchInterceptor>
+{
+ ICEObject* servant;
+ NSString* lastOperation;
+ BOOL lastStatus;
+}
+
+-(id) init:(ICEObject*)servant;
+-(BOOL) getLastStatus;
+-(NSString*) getLastOperation;
+-(void) clear;
+
+@end
+
diff --git a/objc/test/Ice/interceptor/InterceptorI.m b/objc/test/Ice/interceptor/InterceptorI.m
new file mode 100644
index 00000000000..66897f07a81
--- /dev/null
+++ b/objc/test/Ice/interceptor/InterceptorI.m
@@ -0,0 +1,100 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <interceptor/InterceptorI.h>
+#import <InterceptorTest.h>
+#import <TestCommon.h>
+
+@implementation InterceptorI
+
+-(id) init:(ICEObject*) servant_
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+#if defined(__clang__) && !__has_feature(objc_arc)
+ servant = [servant_ retain];
+#else
+ servant = servant_;
+#endif
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [lastOperation release];
+ [servant release];
+ [super dealloc];
+}
+#endif
+
+-(BOOL) dispatch:(id<ICERequest>) request
+{
+ ICECurrent* current = [request getCurrent];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [lastOperation release];
+ lastOperation = [current.operation retain];
+#else
+ lastOperation = current.operation;
+#endif
+
+ if([lastOperation isEqualToString:@"addWithRetry"])
+ {
+ int i = 0;
+ for(i = 0; i < 10; ++i)
+ {
+ @try
+ {
+ [servant ice_dispatch:request];
+ test(NO);
+ }
+ @catch(TestInterceptorRetryException*)
+ {
+ //
+ // Expected, retry
+ //
+ }
+ }
+
+ [(NSMutableDictionary*)current.ctx setObject:@"no" forKey:@"retry"];
+
+ //
+ // A successful dispatch that writes a result we discard
+ //
+ [servant ice_dispatch:request];
+ }
+
+ lastStatus = [servant ice_dispatch:request];
+ return lastStatus;
+}
+
+-(BOOL) getLastStatus
+{
+ return lastStatus;
+}
+
+-(NSString*) getLastOperation
+{
+ return lastOperation;
+}
+
+-(void) clear
+{
+ lastStatus = NO;
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [lastOperation release];
+#endif
+ lastOperation = nil;
+}
+
+@end
diff --git a/objc/test/Ice/interceptor/InterceptorTest.ice b/objc/test/Ice/interceptor/InterceptorTest.ice
new file mode 100644
index 00000000000..b2a0776e804
--- /dev/null
+++ b/objc/test/Ice/interceptor/InterceptorTest.ice
@@ -0,0 +1,53 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestInterceptor"]
+module Test
+{
+
+exception InvalidInputException
+{
+ string reason;
+};
+
+local exception RetryException
+{
+};
+
+interface MyObject
+{
+ //
+ // A simple addition
+ //
+ int add(int x, int y);
+
+ //
+ // Will throw RetryException until current.ctx["retry"] is "no"
+ //
+ int addWithRetry(int x, int y);
+
+ //
+ // Raise user exception
+ //
+ int badAdd(int x, int y) throws InvalidInputException;
+
+ //
+ // Raise ONE
+ //
+ int notExistAdd(int x, int y);
+
+ //
+ // Raise system exception
+ //
+ int badSystemAdd(int x, int y);
+};
+
+};
diff --git a/objc/test/Ice/interceptor/Makefile b/objc/test/Ice/interceptor/Makefile
new file mode 100644
index 00000000000..80dde2f1048
--- /dev/null
+++ b/objc/test/Ice/interceptor/Makefile
@@ -0,0 +1,30 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = InterceptorTest.o
+
+COBJS = Client.o \
+ InterceptorI.o \
+ MyObjectI.o \
+
+OBJS = $(COBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/interceptor/MyObjectI.h b/objc/test/Ice/interceptor/MyObjectI.h
new file mode 100644
index 00000000000..a3e9b33ee1d
--- /dev/null
+++ b/objc/test/Ice/interceptor/MyObjectI.h
@@ -0,0 +1,13 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <InterceptorTest.h>
+
+@interface TestInterceptorMyObjectI : TestInterceptorMyObject<TestInterceptorMyObject>
+@end
diff --git a/objc/test/Ice/interceptor/MyObjectI.m b/objc/test/Ice/interceptor/MyObjectI.m
new file mode 100644
index 00000000000..2725890c1fd
--- /dev/null
+++ b/objc/test/Ice/interceptor/MyObjectI.m
@@ -0,0 +1,46 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <interceptor/MyObjectI.h>
+#import <TestCommon.h>
+
+@implementation TestInterceptorMyObjectI
+-(int) add:(int)x y:(int)y current:(ICECurrent*)current
+{
+ return x + y;
+}
+
+-(int) addWithRetry:(int)x y:(int)y current:(ICECurrent*)current
+{
+ id val = [current.ctx objectForKey:@"retry"];
+
+ if(val == nil || ![(NSString*)val isEqualToString:@"no"])
+ {
+ @throw [TestInterceptorRetryException retryException:__FILE__ line:__LINE__];
+ }
+ return x + y;
+}
+
+-(int) badAdd:(int)x y:(int)y current:(ICECurrent*)current
+{
+ @throw [TestInterceptorInvalidInputException invalidInputException];
+}
+
+-(int) notExistAdd:(int)x y:(int)y current:(ICECurrent*)current
+{
+ @throw [ICEObjectNotExistException objectNotExistException:__FILE__ line:__LINE__];
+}
+
+-(int) badSystemAdd:(int)x y:(int)y current:(ICECurrent*)current
+{
+ @throw [ICEInitializationException initializationException:__FILE__ line:__LINE__ reason_:@"testing"];
+}
+
+@end
diff --git a/objc/test/Ice/interceptor/run.py b/objc/test/Ice/interceptor/run.py
new file mode 100755
index 00000000000..7f9e0ba78f4
--- /dev/null
+++ b/objc/test/Ice/interceptor/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+client = os.path.join(os.getcwd(), "client")
+
+TestUtil.simpleTest(client, " --Ice.Warn.Dispatch=0")
diff --git a/objc/test/Ice/invoke/.gitignore b/objc/test/Ice/invoke/.gitignore
new file mode 100644
index 00000000000..76608e6287a
--- /dev/null
+++ b/objc/test/Ice/invoke/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+InvokeTest.m
+InvokeTest.h
diff --git a/objc/test/Ice/invoke/AllTests.m b/objc/test/Ice/invoke/AllTests.m
new file mode 100644
index 00000000000..ab3757e9e73
--- /dev/null
+++ b/objc/test/Ice/invoke/AllTests.m
@@ -0,0 +1,278 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <InvokeTest.h>
+
+#import <Foundation/Foundation.h>
+
+static NSString* testString = @"This is a test string";
+
+@interface TestInvokeCallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+ id<ICECommunicator> communicator;
+}
+-(BOOL) check;
+-(void) called;
+@end
+
+@implementation TestInvokeCallback
+-(id) initWithCommunicator:(id<ICECommunicator>)c
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ communicator = c;
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(BOOL) check
+{
+ [cond lock];
+ while(!called)
+ {
+ if(![cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:50]])
+ {
+ return NO;
+ }
+ }
+ called = NO;
+ [cond unlock];
+ return YES;
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) opString:(BOOL)ok outEncaps:(NSMutableData*)outEncaps
+{
+ if(ok)
+ {
+ id<ICEInputStream> inS = [ICEUtil createInputStream:communicator data:outEncaps];
+ [inS startEncapsulation];
+ NSString* s;
+ s = [inS readString];
+ test([s isEqualToString:testString]);
+ s = [inS readString];
+ test([s isEqualToString:testString]);
+ [inS endEncapsulation];
+ [self called];
+ }
+ else
+ {
+ test(NO);
+ }
+}
+
+-(void) opException:(BOOL)ok outEncaps:(NSMutableData*)outEncaps
+{
+ if(ok)
+ {
+ test(NO);
+ }
+ else
+ {
+ id<ICEInputStream> inS = [ICEUtil createInputStream:communicator data:outEncaps];
+ [inS startEncapsulation];
+ @try
+ {
+ [inS throwException];
+ }
+ @catch(TestInvokeMyException*)
+ {
+ [inS endEncapsulation];
+ [self called];
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ }
+}
+@end
+
+id<TestInvokeMyClassPrx>
+invokeAllTests(id<ICECommunicator> communicator)
+{
+ NSString* ref = @"test:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ test(base);
+
+ id<TestInvokeMyClassPrx> cl = [TestInvokeMyClassPrx checkedCast:base];
+ test(cl);
+
+ id<TestInvokeMyClassPrx> onewayCl = [cl ice_oneway];
+
+ tprintf("testing ice_invoke... ");
+
+ {
+ NSData* inEncaps = [NSData data];
+ NSMutableData* outEncaps;
+ if(![onewayCl ice_invoke:@"opOneway" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps])
+ {
+ test(NO);
+ }
+
+ id<ICEOutputStream> outS = [ICEUtil createOutputStream:communicator];
+ [outS startEncapsulation];
+ [outS writeString:testString];
+ [outS endEncapsulation];
+ inEncaps = [outS finished];
+ // ice_invoke
+ if([cl ice_invoke:@"opString" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps])
+ {
+ id<ICEInputStream> inS = [ICEUtil createInputStream:communicator data:outEncaps];
+ [inS startEncapsulation];
+ NSString* s;
+ s = [inS readString];
+ test([s isEqualToString:testString]);
+ s = [inS readString];
+ test([s isEqualToString:testString]);
+ [inS endEncapsulation];
+ }
+ else
+ {
+ test(NO);
+ }
+ }
+
+ {
+ NSData* inEncaps = [NSData data];
+ NSMutableData* outEncaps;
+ if([cl ice_invoke:@"opException" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps])
+ {
+ test(NO);
+ }
+ else
+ {
+ id<ICEInputStream> inS = [ICEUtil createInputStream:communicator data:outEncaps];
+ [inS startEncapsulation];
+ @try
+ {
+ [inS throwException];
+ }
+ @catch(TestInvokeMyException*)
+ {
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ [inS endEncapsulation];
+ }
+ }
+
+ tprintf("ok\n");
+
+ tprintf("testing asynchronous ice_invoke... ");
+
+ {
+ NSData* inEncaps = [NSData data];
+ NSMutableData* outEncaps;
+ id<ICEAsyncResult> result = [onewayCl begin_ice_invoke:@"opOneway" mode:ICENormal inEncaps:inEncaps];
+ if(![onewayCl end_ice_invoke:&outEncaps result:result])
+ {
+ test(NO);
+ }
+
+ id<ICEOutputStream> outS = [ICEUtil createOutputStream:communicator];
+ [outS startEncapsulation];
+ [outS writeString:testString];
+ [outS endEncapsulation];
+ inEncaps = [outS finished];
+
+ // begin_ice_invoke with no callback
+ result = [cl begin_ice_invoke:@"opString" mode:ICENormal inEncaps:inEncaps];
+ if([cl end_ice_invoke:&outEncaps result:result])
+ {
+ id<ICEInputStream> inS = [ICEUtil createInputStream:communicator data:outEncaps];
+ [inS startEncapsulation];
+ NSString* s;
+ s = [inS readString];
+ test([s isEqualToString:testString]);
+ s = [inS readString];
+ test([s isEqualToString:testString]);
+ [inS endEncapsulation];
+ }
+ else
+ {
+ test(NO);
+ };
+
+ TestInvokeCallback* cb = [[TestInvokeCallback alloc] initWithCommunicator:communicator];
+ [cl begin_ice_invoke:@"opString" mode:ICENormal inEncaps:inEncaps
+ response:^(BOOL ok, NSMutableData* outEncaps) { [cb opString:ok outEncaps:outEncaps]; }
+ exception:^(ICEException* ex) { test(NO); }];
+ [cb check];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [cb release];
+#endif
+ }
+
+ {
+ NSData* inEncaps = [NSData data];
+ NSMutableData* outEncaps;
+
+ // begin_ice_invoke with no callback
+ id<ICEAsyncResult> result = [cl begin_ice_invoke:@"opException" mode:ICENormal inEncaps:inEncaps];
+ if([cl end_ice_invoke:&outEncaps result:result])
+ {
+ test(NO);
+ }
+ else
+ {
+ id<ICEInputStream> inS = [ICEUtil createInputStream:communicator data:outEncaps];
+ [inS startEncapsulation];
+ @try
+ {
+ [inS throwException];
+ }
+ @catch(TestInvokeMyException*)
+ {
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ [inS endEncapsulation];
+ }
+
+ // begin_ice_invoke with Callback_Object_ice_invoke
+ TestInvokeCallback* cb = [[TestInvokeCallback alloc] initWithCommunicator:communicator];
+ [cl begin_ice_invoke:@"opException" mode:ICENormal inEncaps:inEncaps
+ response:^(BOOL ok, NSMutableData* outP) { [cb opException:ok outEncaps:outP]; }
+ exception:^(ICEException* ex) { test(NO); }];
+ [cb check];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [cb release];
+#endif
+ }
+
+ tprintf("ok\n");
+
+ return cl;
+
+}
diff --git a/objc/test/Ice/invoke/BlobjectI.h b/objc/test/Ice/invoke/BlobjectI.h
new file mode 100644
index 00000000000..ae45836eb31
--- /dev/null
+++ b/objc/test/Ice/invoke/BlobjectI.h
@@ -0,0 +1,14 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <InvokeTest.h>
+
+@interface BlobjectI : ICEBlobject<ICEBlobject>
+-(BOOL) ice_invoke:(NSData*)inEncaps outEncaps:(NSMutableData**)outEncaps current:(ICECurrent*)current;
+@end
diff --git a/objc/test/Ice/invoke/BlobjectI.m b/objc/test/Ice/invoke/BlobjectI.m
new file mode 100644
index 00000000000..8d768aa5b1f
--- /dev/null
+++ b/objc/test/Ice/invoke/BlobjectI.m
@@ -0,0 +1,76 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <invoke/BlobjectI.h>
+
+@implementation BlobjectI
+-(BOOL) ice_invoke:(NSData*)inEncaps outEncaps:(NSMutableData**)outEncaps current:(ICECurrent*)current
+{
+ id<ICECommunicator> communicator = [current.adapter getCommunicator];
+ id<ICEInputStream> inS = [ICEUtil createInputStream:communicator data:inEncaps];
+ id<ICEOutputStream> outS = [ICEUtil createOutputStream:communicator];
+ [outS startEncapsulation];
+ if([current.operation isEqualToString:@"opOneway"])
+ {
+ return YES;
+ }
+ else if([current.operation isEqualToString:@"opString"])
+ {
+ [inS startEncapsulation];
+ NSString* s = [inS readString];
+ [inS endEncapsulation];
+ [outS writeString:s];
+ [outS writeString:s];
+ [outS endEncapsulation];
+ *outEncaps = [outS finished];
+ return YES;
+ }
+ else if([current.operation isEqualToString:@"opException"])
+ {
+ TestInvokeMyException* ex = [TestInvokeMyException myException];
+ [outS writeException:ex];
+ [outS endEncapsulation];
+ *outEncaps = [outS finished];
+ return NO;
+ }
+ else if([current.operation isEqualToString:@"shutdown"])
+ {
+ [outS endEncapsulation];
+ *outEncaps = [outS finished];
+ [communicator shutdown];
+ return YES;
+ }
+ else if([current.operation isEqualToString:@"ice_isA"])
+ {
+ [inS startEncapsulation];
+ NSString* s = [inS readString];
+ [inS endEncapsulation];
+ if([s isEqualToString:[TestInvokeMyClass ice_staticId]])
+ {
+ [outS writeBool:YES];
+ }
+ else
+ {
+ [outS writeBool:NO];
+ }
+ [outS endEncapsulation];
+ *outEncaps = [outS finished];
+ return YES;
+ }
+ else
+ {
+ @throw [ICEOperationNotExistException operationNotExistException:__FILE__
+ line:__LINE__
+ id_:current.id_
+ facet:current.facet
+ operation:current.operation];
+ }
+}
+@end
diff --git a/objc/test/Ice/invoke/Client.m b/objc/test/Ice/invoke/Client.m
new file mode 100644
index 00000000000..c3055182a33
--- /dev/null
+++ b/objc/test/Ice/invoke/Client.m
@@ -0,0 +1,77 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <InvokeTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ TestInvokeMyClassPrx* invokeAllTests(id<ICECommunicator>);
+ TestInvokeMyClassPrx* invoke = invokeAllTests(communicator);
+ [invoke shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main invokeClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestInvoke", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/invoke/InvokeTest.ice b/objc/test/Ice/invoke/InvokeTest.ice
new file mode 100644
index 00000000000..d7391b9799d
--- /dev/null
+++ b/objc/test/Ice/invoke/InvokeTest.ice
@@ -0,0 +1,31 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestInvoke"]
+module Test
+{
+
+exception MyException
+{
+};
+
+class MyClass
+{
+ void opOneway();
+
+ string opString(string s1, out string s2);
+
+ void opException() throws MyException;
+
+ void shutdown();
+};
+
+};
diff --git a/objc/test/Ice/invoke/Makefile b/objc/test/Ice/invoke/Makefile
new file mode 100644
index 00000000000..a955fa552de
--- /dev/null
+++ b/objc/test/Ice/invoke/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = InvokeTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = BlobjectI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/invoke/Server.m b/objc/test/Ice/invoke/Server.m
new file mode 100644
index 00000000000..25e2a50e75b
--- /dev/null
+++ b/objc/test/Ice/invoke/Server.m
@@ -0,0 +1,81 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <invoke/BlobjectI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adapter addDefaultServant:[[[BlobjectI alloc] init] autorelease] category:@""];
+#else
+ [adapter addDefaultServant:[[BlobjectI alloc] init] category:@""];
+#endif
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main invokeServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestInvoke", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/invoke/run.py b/objc/test/Ice/invoke/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/invoke/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/location/.gitignore b/objc/test/Ice/location/.gitignore
new file mode 100644
index 00000000000..cd321e6c61d
--- /dev/null
+++ b/objc/test/Ice/location/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+LocationTest.m
+LocationTest.h
diff --git a/objc/test/Ice/location/AllTests.m b/objc/test/Ice/location/AllTests.m
new file mode 100644
index 00000000000..c79090cb5dd
--- /dev/null
+++ b/objc/test/Ice/location/AllTests.m
@@ -0,0 +1,479 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <LocationTest.h>
+
+#include <Foundation/NSThread.h>
+
+@interface DummyHelloI : TestLocationHello
+@end
+
+@implementation DummyHelloI
+-(void) sayHello:(ICECurrent*)current
+{
+ // Do nothing, this is just a dummy servant.
+}
+@end
+
+void
+locationAllTests(id<ICECommunicator> communicator, NSString* ref)
+{
+ id<TestLocationServerManagerPrx> manager =
+ [TestLocationServerManagerPrx checkedCast:[communicator stringToProxy:ref]];
+ id<TestLocationTestLocatorPrx> locator =
+ [TestLocationTestLocatorPrx uncheckedCast:[communicator getDefaultLocator]];
+ test(manager);
+
+ id<TestLocationTestLocatorRegistryPrx> registry =
+ [TestLocationTestLocatorRegistryPrx checkedCast:[locator getRegistry]];
+ test(registry);
+
+ tprintf("testing stringToProxy... ");
+ id<ICEObjectPrx> base = [communicator stringToProxy:@"test @ TestAdapter"];
+ id<ICEObjectPrx> base2 = [communicator stringToProxy:@"test @ TestAdapter"];
+ id<ICEObjectPrx> base3 = [communicator stringToProxy:@"test"];
+ id<ICEObjectPrx> base4 = [communicator stringToProxy:@"ServerManager"];
+ id<ICEObjectPrx> base5 = [communicator stringToProxy:@"test2"];
+ id<ICEObjectPrx> base6 = [communicator stringToProxy:@"test @ ReplicatedAdapter"];
+ tprintf("ok\n");
+
+ tprintf("testing ice_locator and ice_getLocator... ");
+ test([[base ice_getLocator] compareIdentity:[communicator getDefaultLocator]] == NSOrderedSame);
+ id<ICELocatorPrx> anotherLocator = [ICELocatorPrx uncheckedCast:[communicator stringToProxy:@"anotherLocator"]];
+ base = [base ice_locator:anotherLocator];
+ test([[base ice_getLocator] compareIdentity:anotherLocator] == NSOrderedSame);
+ [communicator setDefaultLocator:0];
+ base = [communicator stringToProxy:@"test @ TestAdapter"];
+ test(![base ice_getLocator]);
+ base = [base ice_locator:anotherLocator];
+ test([[base ice_getLocator] compareIdentity:anotherLocator] == NSOrderedSame);
+ [communicator setDefaultLocator:locator];
+ base = [communicator stringToProxy:@"test @ TestAdapter"];
+ test([[base ice_getLocator] compareIdentity:[communicator getDefaultLocator]] == NSOrderedSame);
+
+ //
+ // We also test ice_router/ice_getRouter (perhaps we should add a
+ // test/Ice/router test?)
+ //
+ test(![base ice_getRouter]);
+ id<ICERouterPrx> anotherRouter = [ICERouterPrx uncheckedCast:[communicator stringToProxy:@"anotherRouter"]];
+ base = [base ice_router:anotherRouter];
+ test([[base ice_getRouter] compareIdentity:anotherRouter] == NSOrderedSame);
+ id<ICERouterPrx> router = [ICERouterPrx uncheckedCast:[communicator stringToProxy:@"dummyrouter"]];
+ [communicator setDefaultRouter:router];
+ base = [communicator stringToProxy:@"test @ TestAdapter"];
+ test([[base ice_getRouter] compareIdentity:[communicator getDefaultRouter]] == NSOrderedSame);
+ [communicator setDefaultRouter:0];
+ base = [communicator stringToProxy:@"test @ TestAdapter"];
+ test(![base ice_getRouter]);
+ tprintf("ok\n");
+
+ tprintf("starting server... ");
+ [manager startServer];
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestLocationTestIntfPrx> obj = [TestLocationTestIntfPrx checkedCast:base];
+ obj = [TestLocationTestIntfPrx checkedCast:[communicator stringToProxy:@"test@TestAdapter"]];
+ obj = [TestLocationTestIntfPrx checkedCast:[communicator stringToProxy:@"test @TestAdapter"]];
+ obj = [TestLocationTestIntfPrx checkedCast:[communicator stringToProxy:@"test@ TestAdapter"]];
+ test(obj);
+ id<TestLocationTestIntfPrx> obj2 = [TestLocationTestIntfPrx checkedCast:base2];
+ test(obj2);
+ id<TestLocationTestIntfPrx> obj3 = [TestLocationTestIntfPrx checkedCast:base3];
+ test(obj3);
+ id<TestLocationServerManagerPrx> obj4 = [TestLocationServerManagerPrx checkedCast:base4];
+ test(obj4);
+ id<TestLocationTestIntfPrx> obj5 = [TestLocationTestIntfPrx checkedCast:base5];
+ test(obj5);
+ id<TestLocationTestIntfPrx> obj6 = [TestLocationTestIntfPrx checkedCast:base6];
+ test(obj6);
+ tprintf("ok\n");
+
+ tprintf("testing id@AdapterId indirect proxy... ");
+ [obj shutdown];
+ [manager startServer];
+ @try
+ {
+ obj2 = [TestLocationTestIntfPrx checkedCast:base2];
+ [obj2 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing id@ReplicaGroupId indirect proxy... ");
+ [obj shutdown];
+ [manager startServer];
+ @try
+ {
+ obj6 = [TestLocationTestIntfPrx checkedCast:base6];
+ [obj6 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing identity indirect proxy... ");
+ [obj shutdown];
+ [manager startServer];
+ @try
+ {
+ obj3 = [TestLocationTestIntfPrx checkedCast:base3];
+ [obj3 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ @try
+ {
+ obj2 = [TestLocationTestIntfPrx checkedCast:base2];
+ [obj2 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ [obj shutdown];
+ [manager startServer];
+ @try
+ {
+ obj2 = [TestLocationTestIntfPrx checkedCast:base2];
+ [obj2 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ @try
+ {
+ obj3 = [TestLocationTestIntfPrx checkedCast:base3];
+ [obj3 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ [obj shutdown];
+ [manager startServer];
+
+ @try
+ {
+ obj2 = [TestLocationTestIntfPrx checkedCast:base2];
+ [obj2 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ [obj shutdown];
+ [manager startServer];
+ @try
+ {
+ obj3 = [TestLocationTestIntfPrx checkedCast:base3];
+ [obj3 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ [obj shutdown];
+ [manager startServer];
+ @try
+ {
+ obj2 = [TestLocationTestIntfPrx checkedCast:base2];
+ [obj2 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ [obj shutdown];
+ [manager startServer];
+
+ @try
+ {
+ obj5 = [TestLocationTestIntfPrx checkedCast:base5];
+ [obj5 ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ NSLog(@"%@", ex);
+ test(NO);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing proxy with unknown identity... ");
+ @try
+ {
+ base = [communicator stringToProxy:@"unknown/unknown"];
+ [base ice_ping];
+ test(NO);
+ }
+ @catch(ICENotRegisteredException* ex)
+ {
+ test([ex.kindOfObject isEqualToString:@"object"]);
+ test([ex.id_ isEqualToString:@"unknown/unknown"]);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing proxy with unknown adapter... ");
+ @try
+ {
+ base = [communicator stringToProxy:@"test @ TestAdapterUnknown"];
+ [base ice_ping];
+ test(NO);
+ }
+ @catch(ICENotRegisteredException* ex)
+ {
+ test([ex.kindOfObject isEqualToString:@"object adapter"]);
+ test([ex.id_ isEqualToString:@"TestAdapterUnknown"]);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing locator cache timeout... ");
+
+ int count = [locator getRequestCount];
+ [[[communicator stringToProxy:@"test@TestAdapter"] ice_locatorCacheTimeout:0] ice_ping]; // No locator cache.
+ test(++count == [locator getRequestCount]);
+ [[[communicator stringToProxy:@"test@TestAdapter"] ice_locatorCacheTimeout:0] ice_ping]; // No locator cache.
+ test(++count == [locator getRequestCount]);
+ [[[communicator stringToProxy:@"test@TestAdapter"] ice_locatorCacheTimeout:1] ice_ping]; // 1s timeout.
+ test(count == [locator getRequestCount]);
+ [NSThread sleepForTimeInterval:1.2];
+ [[[communicator stringToProxy:@"test@TestAdapter"] ice_locatorCacheTimeout:1] ice_ping]; // 1s timeout.
+ test(++count == [locator getRequestCount]);
+
+ [[[communicator stringToProxy:@"test"] ice_locatorCacheTimeout:0] ice_ping]; // No locator cache.
+ count += 2;
+ test(count == [locator getRequestCount]);
+ [[[communicator stringToProxy:@"test"] ice_locatorCacheTimeout:1] ice_ping]; // 1s timeout
+ test(count == [locator getRequestCount]);
+ [NSThread sleepForTimeInterval:1.2];
+ [[[communicator stringToProxy:@"test"] ice_locatorCacheTimeout:1] ice_ping]; // 1s timeout
+ count += 2;
+ test(count == [locator getRequestCount]);
+
+ [[[communicator stringToProxy:@"test@TestAdapter"] ice_locatorCacheTimeout:-1] ice_ping];
+ test(count == [locator getRequestCount]);
+ [[[communicator stringToProxy:@"test"] ice_locatorCacheTimeout:-1] ice_ping];
+ test(count == [locator getRequestCount]);
+ [[communicator stringToProxy:@"test@TestAdapter"] ice_ping];
+ test(count == [locator getRequestCount]);
+ [[communicator stringToProxy:@"test"] ice_ping];
+ test(count == [locator getRequestCount]);
+
+ test([[[communicator stringToProxy:@"test"] ice_locatorCacheTimeout:99] ice_getLocatorCacheTimeout] == 99);
+
+ tprintf("ok\n");
+
+ tprintf("testing proxy from server... ");
+ id<TestLocationHelloPrx> hello = [obj getHello];
+ test([[hello ice_getAdapterId] isEqualToString:@"TestAdapter"]);
+ [hello sayHello];
+ hello = [obj getReplicatedHello];
+ test([[hello ice_getAdapterId] isEqualToString:@"ReplicatedAdapter"]);
+ [hello sayHello];
+ tprintf("ok\n");
+
+ tprintf("testing well-known object locator cache... ");
+
+ [registry addObject:[communicator stringToProxy:@"test3@TestUnknown"]];
+ @try
+ {
+ [[communicator stringToProxy:@"test3"] ice_ping];
+ test(NO);
+ }
+ @catch(ICENotRegisteredException* ex)
+ {
+ test([ex.kindOfObject isEqualToString:@"object adapter"]);
+ test([ex.id_ isEqualToString:@"TestUnknown"]);
+ }
+ [registry addObject:[communicator stringToProxy:@"test3@TestAdapter4"]]; // Update
+ [registry setAdapterDirectProxy:@"TestAdapter4" proxy:[communicator stringToProxy:@"dummy:tcp"]];
+ @try
+ {
+ [[communicator stringToProxy:@"test3"] ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException* ex)
+ {
+ }
+ [registry setAdapterDirectProxy:@"TestAdapter4" proxy:[locator findAdapterById:@"TestAdapter"]];
+ @try
+ {
+ [[communicator stringToProxy:@"test3"] ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ test(NO);
+ }
+
+ [registry setAdapterDirectProxy:@"TestAdapter4" proxy:[communicator stringToProxy:@"dummy:tcp"]];
+ @try
+ {
+ [[communicator stringToProxy:@"test3"] ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ test(NO);
+ }
+
+ @try
+ {
+ [[[communicator stringToProxy:@"test@TestAdapter4"] ice_locatorCacheTimeout:0] ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException* ex)
+ {
+ }
+ @try
+ {
+ [[communicator stringToProxy:@"test@TestAdapter4"] ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException* ex)
+ {
+ }
+ @try
+ {
+ [[communicator stringToProxy:@"test3"] ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException* ex)
+ {
+ }
+ [registry addObject:[communicator stringToProxy:@"test3@TestAdapter"]];
+ @try
+ {
+ [[communicator stringToProxy:@"test3"] ice_ping];
+ }
+ @catch(ICELocalException* ex)
+ {
+ test(NO);
+ }
+
+ [registry addObject:[communicator stringToProxy:@"test4"]];
+ @try
+ {
+ [[communicator stringToProxy:@"test4"] ice_ping];
+ test(NO);
+ }
+ @catch(ICENoEndpointException* ex)
+ {
+ }
+ tprintf("ok\n");
+
+ tprintf("testing proxy from server after shutdown... ");
+ [obj shutdown];
+ [manager startServer];
+ [hello sayHello];
+ tprintf("ok\n");
+
+ tprintf("testing object migration... ");
+ hello = [TestLocationHelloPrx checkedCast:[communicator stringToProxy:@"hello"]];
+ [obj migrateHello];
+ [hello sayHello];
+ [obj migrateHello];
+ [hello sayHello];
+ [obj migrateHello];
+ [hello sayHello];
+ tprintf("ok\n");
+
+ tprintf("testing locator encoding resolution... ");
+ hello = [TestLocationHelloPrx checkedCast:[communicator stringToProxy:@"hello"]];
+ count = [locator getRequestCount];
+ [[[communicator stringToProxy:@"test@TestAdapter"] ice_encodingVersion:ICEEncoding_1_1] ice_ping];
+ test(count == [locator getRequestCount]);
+ [[[communicator stringToProxy:@"test@TestAdapter10"] ice_encodingVersion:ICEEncoding_1_0] ice_ping];
+ test(++count == [locator getRequestCount]);
+ [[communicator stringToProxy:@"test -e 1.0@TestAdapter10-2"] ice_ping];
+ test(++count == [locator getRequestCount]);
+ tprintf("ok\n");
+
+ tprintf("shutdown server... ");
+ [obj shutdown];
+ tprintf("ok\n");
+
+ tprintf("testing whether server is gone... ");
+ @try
+ {
+ [obj2 ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ @try
+ {
+ [obj3 ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ @try
+ {
+ [obj5 ice_ping];
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ tprintf("ok\n");
+
+// tprintf("testing indirect proxies to collocated objects... ");
+// //
+// // Set up test for calling a collocated object through an indirect, adapterless reference.
+// //
+// id<ICEProperties> properties = [communicator getProperties];
+// [properties setProperty:@"Ice.PrintAdapterReady" value:@"0"];
+// id<ICEObjectAdapter> adapter = [communicator createObjectAdapterWithEndpoints:@"Hello" endpoints:@"default"];
+// [adapter setLocator:locator];
+
+// id<TestLocationTestLocatorRegistryPrx> registry = [TestLocationTestLocatorRegistryPrx checkedCast:[locator getRegistry]];
+// test(registry);
+
+// ICEIdentity* ident = [ICEIdentity identity:[ICEUtil generateUUID] category:@""];
+// [registry addObject:[adapter add:[[DummyHelloI alloc] init] identity:ident]];
+// [adapter activate];
+
+// @try
+// {
+// id<TestLocationHelloPrx> helloPrx = [TestLocationHelloPrx checkedCast:[communicator stringToProxy:
+// [communicator identityToString:ident]]];
+// [helloPrx ice_getConnection];
+// test(NO);
+// }
+// @catch(ICECollocationOptimizationException*)
+// {
+// }
+// [adapter deactivate];
+// tprintf("ok\n");
+
+ tprintf("shutdown server manager... ");
+ [manager shutdown];
+ tprintf("ok\n");
+}
diff --git a/objc/test/Ice/location/Client.m b/objc/test/Ice/location/Client.m
new file mode 100644
index 00000000000..f39de979383
--- /dev/null
+++ b/objc/test/Ice/location/Client.m
@@ -0,0 +1,78 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <LocationTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ void locationAllTests(id<ICECommunicator>, NSString*);
+ locationAllTests(communicator, @"ServerManager:default -p 12010");
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main locationClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+ [initData.properties setProperty:@"Ice.Default.Locator" value:@"locator:default -p 12010"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestLocation", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/location/LocationTest.ice b/objc/test/Ice/location/LocationTest.ice
new file mode 100644
index 00000000000..02ed275861d
--- /dev/null
+++ b/objc/test/Ice/location/LocationTest.ice
@@ -0,0 +1,56 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/Locator.ice>
+
+["objc:prefix:TestLocation"]
+module Test
+{
+
+interface TestLocatorRegistry extends ::Ice::LocatorRegistry
+{
+ //
+ // Allow remote addition of objects to the locator registry.
+ //
+ void addObject(Object* obj);
+};
+
+interface TestLocator extends ::Ice::Locator
+{
+ //
+ // Returns the number of request on the locator interface.
+ //
+ ["cpp:const"] idempotent int getRequestCount();
+};
+
+interface ServerManager
+{
+ void startServer();
+ void shutdown();
+};
+
+interface Hello
+{
+ void sayHello();
+};
+
+interface TestIntf
+{
+ void shutdown();
+
+ Hello* getHello();
+
+ Hello* getReplicatedHello();
+
+ void migrateHello();
+};
+
+};
diff --git a/objc/test/Ice/location/Makefile b/objc/test/Ice/location/Makefile
new file mode 100644
index 00000000000..2794d0a627f
--- /dev/null
+++ b/objc/test/Ice/location/Makefile
@@ -0,0 +1,38 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = LocationTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ ServerLocator.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/location/Server.m b/objc/test/Ice/location/Server.m
new file mode 100644
index 00000000000..7436a6ea25e
--- /dev/null
+++ b/objc/test/Ice/location/Server.m
@@ -0,0 +1,113 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <location/ServerLocator.h>
+#import <location/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator, ICEInitializationData* initData)
+{
+ //
+ // Register the server manager. The server manager creates a new
+ // 'server' (a server isn't a different process, it's just a new
+ // communicator and object adapter).
+ //
+ [[communicator getProperties] setProperty:@"Ice.ThreadPool.Server.Size" value:@"2"];
+ [[communicator getProperties] setProperty:@"ServerManager.Endpoints" value:@"default -p 12010:udp"];
+
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"ServerManager"];
+
+ //
+ // We also register a sample server locator which implements the
+ // locator interface, this locator is used by the clients and the
+ // 'servers' created with the server manager interface.
+ //
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ServerLocatorRegistry* registry = [[[ServerLocatorRegistry alloc] init] autorelease];
+ ServerManagerI* serverManager = [[[ServerManagerI alloc] init:registry initData:initData] autorelease];
+#else
+ ServerLocatorRegistry* registry = [[ServerLocatorRegistry alloc] init];
+ ServerManagerI* serverManager = [[ServerManagerI alloc] init:registry initData:initData];
+#endif
+ [registry addObject:[adapter createProxy:[communicator stringToIdentity:@"ServerManager"]]];
+ [adapter add:serverManager identity:[communicator stringToIdentity:@"ServerManager"]];
+
+ id<ICELocatorRegistryPrx> registryPrx =
+ [ICELocatorRegistryPrx uncheckedCast:[adapter add:registry
+ identity:[communicator stringToIdentity:@"registry"]]];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ServerLocator* locator = [[[ServerLocator alloc] init:registry proxy:registryPrx] autorelease];
+#else
+ ServerLocator* locator = [[ServerLocator alloc] init:registry proxy:registryPrx];
+#endif
+ [adapter add:locator identity:[communicator stringToIdentity:@"locator"]];
+
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ [serverManager terminate];
+
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main locationServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestLocation", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator, initData);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/location/ServerLocator.h b/objc/test/Ice/location/ServerLocator.h
new file mode 100644
index 00000000000..9f830f829dd
--- /dev/null
+++ b/objc/test/Ice/location/ServerLocator.h
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <LocationTest.h>
+
+@interface ServerLocatorRegistry : TestLocationTestLocatorRegistry<TestLocationTestLocatorRegistry>
+{
+ NSMutableDictionary* adapters_;
+ NSMutableDictionary* objects_;
+}
+-(id<ICEObjectPrx>) getAdapter:(NSString*)adapterId;
+-(id<ICEObjectPrx>) getObject:(ICEIdentity*)ident;
+-(void) addObject:(id<ICEObjectPrx>)prx;
+@end
+
+@interface ServerLocator : TestLocationTestLocator<TestLocationTestLocator>
+{
+ ServerLocatorRegistry* registry_;
+ id<ICELocatorRegistryPrx> registryPrx_;
+ int requestCount_;
+}
+-(id) init:(ServerLocatorRegistry*)registry proxy:(id<ICELocatorRegistryPrx>)proxy;
+@end
diff --git a/objc/test/Ice/location/ServerLocator.m b/objc/test/Ice/location/ServerLocator.m
new file mode 100644
index 00000000000..5e7e146a105
--- /dev/null
+++ b/objc/test/Ice/location/ServerLocator.m
@@ -0,0 +1,129 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <location/ServerLocator.h>
+
+@implementation ServerLocatorRegistry
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ adapters_ = [[NSMutableDictionary alloc] init];
+ objects_ = [[NSMutableDictionary alloc] init];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [adapters_ release];
+ [objects_ release];
+ [super dealloc];
+}
+#endif
+
+-(void) setAdapterDirectProxy:(NSMutableString *)adapter proxy:(id<ICEObjectPrx>)proxy current:(ICECurrent *)current
+{
+ if(proxy == nil)
+ {
+ [adapters_ removeObjectForKey:adapter];
+ }
+ else
+ {
+ [adapters_ setObject:proxy forKey:adapter];
+ }
+}
+-(void) setReplicatedAdapterDirectProxy:(NSMutableString *)adapterId
+ replicaGroupId:(NSMutableString *)replicaGroupId
+ p:(id<ICEObjectPrx>)p
+ current:(ICECurrent *)current
+{
+ if(p == nil)
+ {
+ [adapters_ removeObjectForKey:adapterId];
+ [adapters_ removeObjectForKey:replicaGroupId];
+ }
+ else
+ {
+ [adapters_ setObject:p forKey:adapterId];
+ [adapters_ setObject:p forKey:replicaGroupId];
+ }
+}
+-(void) setServerProcessProxy:(NSMutableString *)id_ proxy:(id<ICEProcessPrx>)proxy current:(ICECurrent *)current
+{
+}
+-(void) addObject:(id<ICEObjectPrx>)object current:(ICECurrent*)current
+{
+ [self addObject:object];
+}
+-(id<ICEObjectPrx>) getAdapter:(NSString*)adapterId
+{
+ id<ICEObjectPrx> proxy = [adapters_ objectForKey:adapterId];
+ if(proxy == nil)
+ {
+ @throw [ICEAdapterNotFoundException adapterNotFoundException];
+ }
+ return proxy;
+}
+-(id<ICEObjectPrx>) getObject:(ICEIdentity*)ident
+{
+ id<ICEObjectPrx> proxy = [objects_ objectForKey:ident];
+ if(proxy == nil)
+ {
+ @throw [ICEObjectNotFoundException objectNotFoundException];
+ }
+ return proxy;
+}
+-(void) addObject:(id<ICEObjectPrx>)object
+{
+ [objects_ setObject:object forKey:[object ice_getIdentity]];
+}
+@end
+
+@implementation ServerLocator
+-(id) init:(ServerLocatorRegistry*)registry proxy:(id<ICELocatorRegistryPrx>)registryPrx
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ registry_ = registry;
+ registryPrx_ = registryPrx;
+ requestCount_ = 0;
+ return self;
+}
+-(id<ICEObjectPrx>) findObjectById:(ICEIdentity *)id_ current:(ICECurrent *)current
+{
+ ++requestCount_;
+ return [registry_ getObject:id_];
+}
+-(id<ICEObjectPrx>) findAdapterById:(NSMutableString *)id_ current:(ICECurrent *)current
+{
+ ++requestCount_;
+ if([id_ isEqualToString:@"TestAdapter10"] || [id_ isEqualToString:@"TestAdapter10-2"])
+ {
+ NSAssert([current.encoding isEqual:ICEEncoding_1_0], @"unexpected encoding");
+ return [registry_ getAdapter:@"TestAdapter"];
+ }
+ return [registry_ getAdapter:id_];
+}
+-(id<ICELocatorRegistryPrx>) getRegistry:(ICECurrent *)current
+{
+ return registryPrx_;
+}
+-(int) getRequestCount:(ICECurrent*)current
+{
+ return requestCount_;
+}
+@end
diff --git a/objc/test/Ice/location/TestI.h b/objc/test/Ice/location/TestI.h
new file mode 100644
index 00000000000..2f96f71e092
--- /dev/null
+++ b/objc/test/Ice/location/TestI.h
@@ -0,0 +1,34 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <LocationTest.h>
+#import <location/ServerLocator.h>
+
+@interface ServerManagerI : TestLocationServerManager<TestLocationServerManager>
+{
+ NSMutableArray* communicators_;
+ ServerLocatorRegistry* registry_;
+ ICEInitializationData* initData_;
+}
+-(id)init:(ServerLocatorRegistry*)registry initData:(ICEInitializationData*)d;
+
+-(void)terminate;
+@end
+
+@interface HelloI : TestLocationHello<TestLocationHello>
+@end
+
+@interface TestLocationI : TestLocationTestIntf<TestLocationTestIntf>
+{
+ id<ICEObjectAdapter> adapter1_;
+ id<ICEObjectAdapter> adapter2_;
+ ServerLocatorRegistry* registry_;
+}
+-(id) init:(id<ICEObjectAdapter>)adapter1 adapter2:(id<ICEObjectAdapter>)adpt2 registry:(ServerLocatorRegistry*)r;
+@end
diff --git a/objc/test/Ice/location/TestI.m b/objc/test/Ice/location/TestI.m
new file mode 100644
index 00000000000..ba32fa0c9fe
--- /dev/null
+++ b/objc/test/Ice/location/TestI.m
@@ -0,0 +1,176 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <location/TestI.h>
+
+@implementation ServerManagerI
+-(id) init:(ServerLocatorRegistry*)registry initData:(ICEInitializationData*)initData
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ registry_ = registry;
+ initData_ = initData;
+
+ [initData_.properties setProperty:@"TestAdapter.Endpoints" value:@"default"];
+ [initData_.properties setProperty:@"TestAdapter.AdapterId" value:@"TestAdapter"];
+ [initData_.properties setProperty:@"TestAdapter.ReplicaGroupId" value:@"ReplicatedAdapter"];
+
+ [initData_.properties setProperty:@"TestAdapter2.Endpoints" value:@"default"];
+ [initData_.properties setProperty:@"TestAdapter2.AdapterId" value:@"TestAdapter2"];
+
+ [initData_.properties setProperty:@"Ice.PrintAdapterReady" value:@"0"];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [communicators_ release];
+ [super dealloc];
+}
+#endif
+
+-(void) startServer:(ICECurrent*)current
+{
+ for(id<ICECommunicator> c in communicators_)
+ {
+ [c waitForShutdown];
+ [c destroy];
+ }
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [communicators_ release];
+#endif
+ communicators_ = [[NSMutableArray alloc] init];
+
+ //
+ // Simulate a server: create a [[communicator alloc] init] and object
+ // adapter. The object adapter is started on a system allocated
+ // port. The configuration used here contains the Ice.Locator
+ // configuration variable. The [[object alloc] init] adapter will register
+ // its endpoints with the locator and create references containing
+ // the adapter id instead of the endpoints.
+ //
+
+ id<ICECommunicator> serverCommunicator = [ICEUtil createCommunicator:initData_];
+ [communicators_ addObject:serverCommunicator];
+
+ id<ICEObjectAdapter> adapter = [serverCommunicator createObjectAdapter:@"TestAdapter"];
+ id<ICEObjectAdapter> adapter2 = [serverCommunicator createObjectAdapter:@"TestAdapter2"];
+
+ id<ICEObjectPrx> locator = [serverCommunicator stringToProxy:@"locator:default -p 12010"];
+ [adapter setLocator:[ICELocatorPrx uncheckedCast:locator]];
+ [adapter2 setLocator:[ICELocatorPrx uncheckedCast:locator]];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* object = [[[TestLocationI alloc] init:adapter adapter2:adapter2 registry:registry_] autorelease];
+#else
+ ICEObject* object = [[TestLocationI alloc] init:adapter adapter2:adapter2 registry:registry_];
+#endif
+ [registry_ addObject:[adapter add:object identity:[serverCommunicator stringToIdentity:@"test"]]];
+ [registry_ addObject:[adapter add:object identity:[serverCommunicator stringToIdentity:@"test2"]]];
+ [adapter add:object identity:[serverCommunicator stringToIdentity:@"test3"]];
+
+ [adapter activate];
+ [adapter2 activate];
+}
+
+-(void) shutdown:(ICECurrent*)current
+{
+ for(id<ICECommunicator> c in communicators_)
+ {
+ [c destroy];
+ }
+ [communicators_ removeAllObjects];
+ [[current.adapter getCommunicator] shutdown];
+}
+
+-(void) terminate
+{
+ for(id<ICECommunicator> c in communicators_)
+ {
+ [c destroy];
+ }
+ [communicators_ removeAllObjects];
+}
+@end
+
+@implementation TestLocationI
+-(id) init:(id<ICEObjectAdapter>)adapter
+ adapter2:(id<ICEObjectAdapter>)adapter2
+ registry:(ServerLocatorRegistry*)registry
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+#if defined(__clang__) && !__has_feature(objc_arc)
+ adapter1_ = [adapter retain];
+ adapter2_ = [adapter2 retain];
+ registry_ = registry;
+ [registry_ addObject:[adapter1_ add:[[[HelloI alloc] init] autorelease]
+ identity:[[adapter1_ getCommunicator] stringToIdentity:@"hello"]]];
+#else
+ adapter1_ = adapter;
+ adapter2_ = adapter2;
+ registry_ = registry;
+ [registry_ addObject:[adapter1_ add:[[HelloI alloc] init]
+ identity:[[adapter1_ getCommunicator] stringToIdentity:@"hello"]]];
+#endif
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [adapter1_ release];
+ [adapter2_ release];
+ [super dealloc];
+}
+#endif
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[adapter1_ getCommunicator] shutdown];
+}
+
+-(id<TestLocationHelloPrx>) getHello:(ICECurrent*)current
+{
+ return [TestLocationHelloPrx uncheckedCast:[adapter1_ createIndirectProxy:[[adapter1_ getCommunicator]
+ stringToIdentity:@"hello"]]];
+}
+
+-(id<TestLocationHelloPrx>) getReplicatedHello:(ICECurrent*)current
+{
+ return [TestLocationHelloPrx uncheckedCast:[adapter1_ createProxy:[[adapter1_ getCommunicator] stringToIdentity:@"hello"]]];
+}
+
+-(void) migrateHello:(ICECurrent*)current
+{
+ ICEIdentity* ident = [[adapter1_ getCommunicator] stringToIdentity:@"hello"];
+ @try
+ {
+ [registry_ addObject:[adapter2_ add:[adapter1_ remove:ident] identity:ident]];
+ }
+ @catch(ICENotRegisteredException*)
+ {
+ [registry_ addObject:[adapter1_ add:[adapter2_ remove:ident] identity:ident]];
+ }
+}
+@end
+
+@implementation HelloI
+-(void) sayHello:(ICECurrent*)current
+{
+}
+@end
diff --git a/objc/test/Ice/location/run.py b/objc/test/Ice/location/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/location/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/metrics/.gitignore b/objc/test/Ice/metrics/.gitignore
new file mode 100644
index 00000000000..919d41acc0f
--- /dev/null
+++ b/objc/test/Ice/metrics/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+MetricsTest.m
+MetricsTest.h
diff --git a/objc/test/Ice/metrics/AllTests.m b/objc/test/Ice/metrics/AllTests.m
new file mode 100644
index 00000000000..4bd1f1a0301
--- /dev/null
+++ b/objc/test/Ice/metrics/AllTests.m
@@ -0,0 +1,1192 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <MetricsTest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface UpdateCallbackI : ICEPropertiesAdminUpdateCallback<ICEPropertiesAdminUpdateCallback>
+{
+@private
+BOOL updated;
+id<ICEPropertiesAdminPrx> serverProps;
+NSCondition* cond;
+}
+-(id) initWithServerProps:(id<ICEPropertiesAdminPrx>)serverProps;
+-(void) waitForUpdate;
+-(void) updated:(ICEMutablePropertyDict*)properties;
+@end
+
+@implementation UpdateCallbackI
+-(id) initWithServerProps:(id<ICEPropertiesAdminPrx>)serverProps_
+{
+ self = [super init];
+ if(self)
+ {
+#if defined(__clang__) && !__has_feature(objc_arc)
+ self->serverProps = [serverProps_ retain];
+#else
+ self->serverProps = serverProps_;
+#endif
+ self->cond = [[NSCondition alloc] init];
+ }
+ return self;
+}
+
+-(void) waitForUpdate
+{
+ [cond lock];
+ while(!updated)
+ {
+ [cond wait];
+ }
+ // Ensure that the previous updates were committed, the setProperties call returns before
+ // notifying the callbacks so to ensure all the update callbacks have be notified we call
+ // a second time, this will block until all the notifications from the first update have
+ // completed.
+ [serverProps setProperties:[ICEPropertyDict dictionary]];
+ updated = NO;
+ [cond unlock];
+}
+
+-(void) updated:(ICEMutablePropertyDict*)properties
+{
+ [cond lock];
+ updated = YES;
+ [cond signal];
+ [cond unlock];
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [serverProps release];
+ [cond release];
+ [super dealloc];
+}
+#endif
+@end
+
+@interface Callback : NSObject
+{
+BOOL wait;
+NSCondition* cond;
+}
+
+-(id) init;
++(id) callback;
+
+-(void) response;
+-(void) exception:(ICEException*)exception;
+-(void) waitForResponse;
+@end
+
+@implementation Callback
+-(id) init
+{
+ self = [super init];
+ if(self)
+ {
+ wait = true;
+ cond = [[NSCondition alloc] init];
+ }
+ return self;
+}
+
++(id) callback
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[[Callback alloc] init] autorelease];
+#else
+ return [[Callback alloc] init];
+#endif
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) response
+{
+ [cond lock];
+ wait = false;
+ [cond signal];
+ [cond unlock];
+}
+
+-(void) exception:(ICEException*)exception
+{
+ [self response];
+}
+
+-(void) waitForResponse
+{
+ [cond lock];
+ while(wait)
+ {
+ [cond wait];
+ }
+ wait = true;
+ [cond unlock];
+}
+@end
+
+@interface Operation : NSObject
+{
+@protected
+ ICEObjectPrx* proxy;
+}
+-(id) init:(ICEObjectPrx*)proxy_;
+@end
+
+@implementation Operation
+-(id) init:(ICEObjectPrx*)proxy_
+{
+ self = [super init];
+ if(self)
+ {
+#if defined(__clang__) && !__has_feature(objc_arc)
+ self->proxy = [proxy_ retain];
+#else
+ self->proxy = proxy_;
+#endif
+ }
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [self->proxy release];
+ [super dealloc];
+}
+#endif
+@end
+
+@interface Connect : Operation
+-(id) init:(ICEObjectPrx*)proxy_;
++(id) connect:(ICEObjectPrx*)proxy_;
+-(void) run;
+@end
+
+@implementation Connect
+-(id) init:(ICEObjectPrx*)proxy_
+{
+ self = [super init:proxy_];
+ return self;
+}
+
++(id) connect:(ICEObjectPrx*)proxy_
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[[Connect alloc] init:proxy_] autorelease];
+#else
+ return [[Connect alloc] init:proxy_];
+#endif
+}
+
+-(void) run
+{
+ if([proxy ice_getCachedConnection])
+ {
+ [[proxy ice_getCachedConnection] close:NO];
+ }
+ @try
+ {
+ [proxy ice_ping];
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ if([proxy ice_getCachedConnection])
+ {
+ [[proxy ice_getCachedConnection] close:NO];
+ }
+}
+@end
+
+
+@interface InvokeOp : Operation
+-(id) init:(ICEObjectPrx*)proxy_;
++(id) invokeOp:(ICEObjectPrx*)proxy_;
+-(void) run;
+@end
+
+@implementation InvokeOp
+-(id) init:(ICEObjectPrx*)proxy_
+{
+ self = [super init:proxy_];
+ return self;
+}
+
++(id) invokeOp:(ICEObjectPrx*)proxy_
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[[InvokeOp alloc] init:proxy_] autorelease];
+#else
+ return [[InvokeOp alloc] init:proxy_];
+#endif
+}
+
+-(void) run
+{
+ ICEMutableContext* ctx = [ICEMutableContext dictionary];
+ [ctx setObject:@"test" forKey:@"entry1"];
+ [ctx setObject:@"" forKey:@"entry2"];
+ TestMetricsMetricsPrx* metrics = [TestMetricsMetricsPrx uncheckedCast:proxy];
+ [metrics op:ctx];
+}
+@end
+
+void
+waitForCurrent(ICEMXMetricsAdminPrx* metrics, NSString* viewName, NSString* map, int value)
+{
+ while(true)
+ {
+ ICELong timestamp;
+ ICEMXMetricsView* view = [metrics getMetricsView:viewName timestamp:&timestamp];
+ test([view objectForKey:map] != nil);
+
+ bool ok = true;
+ ICEMXMetricsMap* mmap = [view objectForKey:map];
+ for(ICEMXMetrics* m in mmap)
+ {
+ if(m.current != value)
+ {
+ ok = false;
+ break;
+ }
+ }
+
+ if(ok)
+ {
+ break;
+ }
+ [NSThread sleepForTimeInterval:50 / 1000.0];
+ }
+}
+
+ICEMutablePropertyDict*
+getClientProps(id<ICEPropertiesAdminPrx> p, ICEMutablePropertyDict* orig, NSString* m)
+{
+ ICEMutablePropertyDict* props = [p getPropertiesForPrefix:@"IceMX.Metrics"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEPropertyDict* cprops = [[props copy] autorelease];
+#else
+ ICEPropertyDict* cprops = [props copy];
+#endif
+ [cprops enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop)
+ {
+ [props setObject:@"" forKey:key];
+ }];
+
+ [orig enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop)
+ {
+ [props setObject:obj forKey:key];
+ }];
+
+ NSString* map = @"";
+ if(![m isEqualToString:@""])
+ {
+ map = [map stringByAppendingFormat:@"Map.%@.", m];
+ }
+ [props setObject:@"Ice\\.Admin"
+ forKey:[NSString stringWithFormat:@"IceMX.Metrics.View.%@Reject.parent", map]];
+
+ [props setObject:@"12010"
+ forKey:[NSString stringWithFormat:@"IceMX.Metrics.View.%@Accept.endpointPort", map] ];
+
+ [props setObject:@".*/admin|controller"
+ forKey:[NSString stringWithFormat:@"IceMX.Metrics.View.%@Reject.identity", map]];
+ return props;
+}
+
+ICEMutablePropertyDict*
+getServerProps(id<ICEPropertiesAdminPrx> p, ICEMutablePropertyDict* orig, NSString* m)
+{
+ ICEMutablePropertyDict* props = [p getPropertiesForPrefix:@"IceMX.Metrics"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEPropertyDict* sprops = [[props copy] autorelease];
+#else
+ ICEPropertyDict* sprops = [props copy];
+#endif
+ [sprops enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop)
+ {
+ [props setObject:@"" forKey:key];
+ }];
+
+ [orig enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop)
+ {
+ [props setObject:obj forKey:key];
+ }];
+
+ NSString* map = @"";
+ if(![m isEqualToString:@""])
+ {
+ map = [map stringByAppendingFormat:@"Map.%@.", m];
+ }
+ [props setObject:@"Ice\\.Admin|Controller"
+ forKey:[NSString stringWithFormat:@"IceMX.Metrics.View.%@Reject.parent", map]];
+
+ [props setObject:@"12010"
+ forKey:[NSString stringWithFormat:@"IceMX.Metrics.View.%@Accept.endpointPort", map]];
+
+ [props setObject:@".*/admin|controller"
+ forKey:[NSString stringWithFormat:@"IceMX.Metrics.View.%@Reject.identity", map]];
+ return props;
+}
+
+ICEMXConnectionMetrics*
+getServerConnectionMetrics(ICEMXMetricsAdminPrx* metrics, ICELong expected)
+{
+ ICEMXConnectionMetrics* s;
+ int nRetry = 30;
+ ICELong timestamp;
+ s = (ICEMXConnectionMetrics*)
+ [[[metrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+ while(s.sentBytes != expected && nRetry-- > 0)
+ {
+ // On some platforms, it's necessary to wait a little before obtaining the server metrics
+ // to get an accurate sentBytes metric. The sentBytes metric is updated before the response
+ // to the operation is sent and getMetricsView can be dispatched before the metric is really
+ // updated.
+ [NSThread sleepForTimeInterval:100 / 1000.0];
+ s = (ICEMXConnectionMetrics*)
+ [[[metrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+ }
+ return s;
+}
+
+void
+updateProps(id<ICEPropertiesAdminPrx> cprops,
+ id<ICEPropertiesAdminPrx> sprops,
+ UpdateCallbackI* callback,
+ ICEMutablePropertyDict* props,
+ NSString* map)
+{
+ [cprops setProperties:getClientProps(cprops, props, map)];
+ [sprops setProperties:getServerProps(sprops, props, map)];
+ [callback waitForUpdate];
+}
+
+void
+testAttribute(ICEMXMetricsAdminPrx* metrics,
+ ICEPropertiesAdminPrx* props,
+ UpdateCallbackI* update,
+ NSString* map,
+ NSString* attr,
+ NSString* value,
+ id func)
+{
+ ICEMutablePropertyDict* dict = [ICEMutablePropertyDict dictionary];
+ [dict setObject:attr forKey:[NSString stringWithFormat:@"IceMX.Metrics.View.Map.%@.GroupBy", map]];
+ if([[props ice_getIdentity].category isEqualToString:@"client"])
+ {
+ [props setProperties:getClientProps(props, dict, map)];
+ [update waitForUpdate];
+ }
+ else
+ {
+ [props setProperties:getServerProps(props, dict, map)];
+ [props setProperties:[ICEPropertyDict dictionary]];
+ }
+ [func run];
+ ICELong timestamp;
+ ICEMXMetricsView* view = [metrics getMetricsView:@"View" timestamp:&timestamp];
+ if([view objectForKey:map] == nil || [[view objectForKey:map] count] == 0)
+ {
+ if(![value isEqualToString:@""])
+ {
+ test(NO);
+ }
+ }
+ else if([[view objectForKey:map] count] != 1 ||
+ ![((ICEMXMetrics*)[[view objectForKey:map] objectAtIndex:0]).id_ isEqualToString:value])
+ {
+ test(NO);
+ }
+
+ [dict removeAllObjects];
+ if([[props ice_getIdentity].category isEqualToString:@"client"])
+ {
+ [props setProperties:getClientProps(props, dict, map)];
+ [update waitForUpdate];
+ }
+ else
+ {
+ [props setProperties:getServerProps(props, dict, map)];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [props setProperties:[ICEPropertyDict dictionary]];
+#else
+ [props setProperties:[ICEPropertyDict dictionary]];
+#endif
+ }
+}
+
+void
+clearView(ICEPropertiesAdminPrx* cprops, ICEPropertiesAdminPrx* sprops, UpdateCallbackI* callback)
+{
+ ICEMutablePropertyDict* dict = [cprops getPropertiesForPrefix:@"IceMX.Metrics"];
+ [dict setObject:@"1" forKey:@"IceMX.Metrics.View.Disabled"];
+ [cprops setProperties:dict];
+
+ dict = [sprops getPropertiesForPrefix:@"IceMX.Metrics"];
+ [dict setObject:@"1" forKey:@"IceMX.Metrics.View.Disabled"];
+ [sprops setProperties:dict];
+
+ [callback waitForUpdate];
+
+ dict = [cprops getPropertiesForPrefix:@"IceMX.Metrics"];
+ [dict setObject:@"" forKey:@"IceMX.Metrics.View.Disabled"];
+ [cprops setProperties:dict];
+
+ dict = [sprops getPropertiesForPrefix:@"IceMX.Metrics"];
+ [dict setObject:@"" forKey:@"IceMX.Metrics.View.Disabled"];
+ [sprops setProperties:dict];
+
+ [callback waitForUpdate];
+}
+
+void
+checkFailure(ICEMXMetricsAdminPrx* m, NSString* map, NSString* id_, NSString* failure, int count)
+{
+ ICEMXMetricsFailures* f = [m getMetricsFailures:@"View" map:map id_:id_];
+ if([f.failures objectForKey:failure] == nil)
+ {
+ NSLog(@"couldn't find failure `%@' for `%@'", failure, id_);
+ test(NO);
+ }
+ if(count > 0 && [[f.failures objectForKey:failure] intValue] != count)
+ {
+ NSLog(@"count for failure `%@' of `%@' is different from expected: ", failure, id_);
+ NSLog(@"%i != %@", count, [f.failures objectForKey:failure]);
+ test(NO);
+ }
+}
+
+NSMutableDictionary*
+toMap(ICEMXMetricsMap* mmap)
+{
+ NSMutableDictionary* m = [NSMutableDictionary dictionary];
+ for(ICEMXMetrics* metrics in mmap)
+ {
+ [m setObject:metrics forKey:metrics.id_];
+ }
+ return m;
+}
+
+id<TestMetricsMetricsPrx>
+metricsAllTests(id<ICECommunicator> communicator)
+{
+ id<TestMetricsMetricsPrx> metrics = [TestMetricsMetricsPrx checkedCast:
+ [communicator stringToProxy:@"metrics:default -p 12010"]];
+
+ tprintf("testing metrics admin facet checkedCast... ");
+ id<ICEObjectPrx> admin = [communicator getAdmin];
+ id<ICEPropertiesAdminPrx> clientProps = [ICEPropertiesAdminPrx checkedCast:admin facet:@"Properties"];
+
+ id<ICEMXMetricsAdminPrx> clientMetrics = [ICEMXMetricsAdminPrx checkedCast:admin facet:@"Metrics"];
+ test(clientProps && clientMetrics);
+
+ admin = [metrics getAdmin];
+ id<ICEPropertiesAdminPrx> serverProps = [ICEPropertiesAdminPrx checkedCast:admin facet:@"Properties"];
+ id<ICEMXMetricsAdminPrx> serverMetrics = [ICEMXMetricsAdminPrx checkedCast:admin facet:@"Metrics"];
+ test(serverProps && serverMetrics);
+
+ UpdateCallbackI* update = [[UpdateCallbackI alloc] initWithServerProps:serverProps];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [update autorelease];
+#endif
+ id<ICENativePropertiesAdmin> nativePropertiesAdmin =
+ (id<ICENativePropertiesAdmin>)[communicator findAdminFacet:@"Properties"];
+ [nativePropertiesAdmin addUpdateCallback:update];
+ tprintf("ok\n");
+
+ ICEMutablePropertyDict* props = [ICEMutablePropertyDict dictionary];
+ tprintf("testing group by none...");
+
+ [props setObject:@"none" forKey:@"IceMX.Metrics.View.GroupBy"];
+
+ updateProps(clientProps, serverProps, update, props, @"");
+
+#if !TARGET_OS_IPHONE
+ int threadCount = 4;
+#else
+ int threadCount = 3; // No endpoint host resolver thread with iOS.
+#endif
+
+ ICELong timestamp = 0;
+ ICEMXMetricsView* view = [clientMetrics getMetricsView:@"View" timestamp:&timestamp];
+
+ test([[view objectForKey:@"Connection"] count] == 1 &&
+ [[[view objectForKey:@"Connection"] objectAtIndex:0] current] == 1 &&
+ [[[view objectForKey:@"Connection"] objectAtIndex:0] total] == 1);
+
+ test([[view objectForKey:@"Thread"] count] == 1);
+ test([[[view objectForKey:@"Thread"] objectAtIndex:0] current] == threadCount);
+ test([[[view objectForKey:@"Thread"] objectAtIndex:0] total] == threadCount);
+
+ tprintf("ok\n");
+
+ tprintf("testing connection metrics... ");
+
+ [props setObject:@"none" forKey:@"IceMX.Metrics.View.Map.Connection.GroupBy"];
+ updateProps(clientProps, serverProps, update, props, @"Connection");
+
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] count] == 1);
+ test([[[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] count] == 1);
+
+ [metrics ice_ping];
+
+ ICEMXConnectionMetrics *cm1, *sm1, *cm2, *sm2;
+ cm1 = (ICEMXConnectionMetrics*)
+ [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+
+ sm1 = (ICEMXConnectionMetrics*)
+ [[[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+
+ sm1 = getServerConnectionMetrics(serverMetrics, 25);
+
+ test(cm1.total == 1 && sm1.total == 1);
+
+ [metrics ice_ping];
+
+ cm2 = (ICEMXConnectionMetrics*)
+ [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+ sm2 = getServerConnectionMetrics(serverMetrics, 50);
+
+ test(cm2.sentBytes - cm1.sentBytes == 45); // 45 for ice_ping request
+ test(cm2.receivedBytes - cm1.receivedBytes == 25); // 25 bytes for ice_ping response
+ test(sm2.receivedBytes - sm1.receivedBytes == 45);
+ test(sm2.sentBytes - sm1.sentBytes == 25);
+
+ cm1 = cm2;
+ sm1 = sm2;
+
+ TestMetricsMutableByteSeq* bs = [TestMetricsMutableByteSeq dataWithLength:0];
+ [metrics opByteS:bs];
+
+ cm2 = (ICEMXConnectionMetrics*)
+ [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+
+ sm2 = getServerConnectionMetrics(serverMetrics, sm1.sentBytes + cm2.receivedBytes - cm1.receivedBytes);
+ ICELong requestSz = cm2.sentBytes - cm1.sentBytes;
+ ICELong replySz = cm2.receivedBytes - cm1.receivedBytes;
+
+ cm1 = cm2;
+ sm1 = sm2;
+
+ [bs setLength:456];
+ [metrics opByteS:bs];
+
+ cm2 = (ICEMXConnectionMetrics*)
+ [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+ sm2 = getServerConnectionMetrics(serverMetrics, sm1.sentBytes + replySz);
+
+ // 4 is for the seq variable size
+ test(cm2.sentBytes - cm1.sentBytes == requestSz + [bs length] + 4);
+ test(cm2.receivedBytes - cm1.receivedBytes == replySz);
+ test(sm2.receivedBytes - sm1.receivedBytes == requestSz + [bs length] + 4);
+ test(sm2.sentBytes - sm1.sentBytes == replySz);
+
+ cm1 = cm2;
+ sm1 = sm2;
+
+ [bs setLength:(1024 * 1024 * 10)]; // Try with large amount of data which should be sent in several chunks
+ [metrics opByteS:bs];
+
+ cm2 = (ICEMXConnectionMetrics*)
+ [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+ sm2 = getServerConnectionMetrics(serverMetrics, sm1.sentBytes + replySz);
+
+ // 4 is for the seq variable size
+ test(cm2.sentBytes - cm1.sentBytes == requestSz + [bs length] + 4);
+ test(cm2.receivedBytes - cm1.receivedBytes == replySz);
+ test(sm2.receivedBytes - sm1.receivedBytes == requestSz + [bs length] + 4);
+ test(sm2.sentBytes - sm1.sentBytes == replySz);
+
+ [props setObject:@"state" forKey:@"IceMX.Metrics.View.Map.Connection.GroupBy"];
+ updateProps(clientProps, serverProps, update, props, @"Connection");
+
+ NSMutableDictionary* map =
+ toMap([[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"]);
+
+ test([[map objectForKey:@"active"] current] == 1);
+
+ TestMetricsControllerPrx* controller =
+ [TestMetricsControllerPrx checkedCast:[communicator stringToProxy:@"controller:default -p 12011"]];
+
+ [controller hold];
+
+ map = toMap([[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"]);
+ test([[map objectForKey:@"active"] current] == 1);
+ map = toMap([[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"]);
+ test([[map objectForKey:@"holding"] current] == 1);
+
+ [[metrics ice_getConnection] close:false];
+
+ map = toMap([[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"]);
+ test([[map objectForKey:@"closing"] current] == 1);
+ map = toMap([[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"]);
+ test([[map objectForKey:@"holding"] current] == 1);
+
+ [controller resume];
+
+ map = toMap([[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"]);
+ test([[map objectForKey:@"holding"] current] == 0);
+
+ [props setObject:@"none" forKey:@"IceMX.Metrics.View.Map.Connection.GroupBy"];
+ updateProps(clientProps, serverProps, update, props, @"Connection");
+
+ [[metrics ice_getConnection] close:false];
+
+ [[metrics ice_timeout:500] ice_ping];
+ [controller hold];
+ @try
+ {
+ [[metrics ice_timeout:500] opByteS:[NSMutableData dataWithLength:10000000]];
+ test(NO);
+ }
+ @catch(const ICETimeoutException*)
+ {
+ }
+ [controller resume];
+
+ cm1 = (ICEMXConnectionMetrics*)
+ [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+ while(true)
+ {
+ sm1 = (ICEMXConnectionMetrics*)
+ [[[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Connection"] objectAtIndex:0];
+ if(sm1.failures >= 2)
+ {
+ break;
+ }
+ [NSThread sleepForTimeInterval:10 / 1000.0];
+ }
+
+ test(cm1.failures == 2 && sm1.failures >= 1);
+
+ checkFailure(clientMetrics, @"Connection", cm1.id_, @"Ice::TimeoutException", 1);
+ checkFailure(clientMetrics, @"Connection", cm1.id_, @"Ice::ConnectTimeoutException", 1);
+ checkFailure(serverMetrics, @"Connection", sm1.id_, @"Ice::ConnectionLostException", 0);
+
+ ICEMXMetricsPrx* m = [[metrics ice_timeout:500] ice_connectionId:@"Con1"];
+ [m ice_ping];
+
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"parent", @"Communicator", nil);
+ //testAttribute(clientMetrics, clientProps, update, "Connection", "id", "");
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"endpoint", @"tcp -h 127.0.0.1 -p 12010 -t 500", nil);
+
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"endpointType", @"1", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"endpointIsDatagram", @"false", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"endpointIsSecure", @"false", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"endpointTimeout", @"500", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"endpointCompress", @"false", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"endpointHost", @"127.0.0.1", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"endpointPort", @"12010", nil);
+
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"incoming", @"false", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"adapterName", @"", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"connectionId", @"Con1", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"localHost", @"127.0.0.1", nil);
+ //testAttribute(clientMetrics, clientProps, update, "Connection", "localPort", "");
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"remoteHost", @"127.0.0.1", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"remotePort", @"12010", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"mcastHost", @"", nil);
+ testAttribute(clientMetrics, clientProps, update, @"Connection", @"mcastPort", @"", nil);
+
+ [[m ice_getConnection] close:false];
+
+ waitForCurrent(clientMetrics, @"View", @"Connection", 0);
+ waitForCurrent(serverMetrics, @"View", @"Connection", 0);
+
+ tprintf("ok\n");
+
+ tprintf("testing connection establishment metrics... ");
+
+ [props setObject:@"id" forKey:@"IceMX.Metrics.View.Map.ConnectionEstablishment.GroupBy"];
+ updateProps(clientProps, serverProps, update, props, @"ConnectionEstablishment");
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp]
+ objectForKey:@"ConnectionEstablishment"] count] == 0);
+
+ [metrics ice_ping];
+
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp]
+ objectForKey:@"ConnectionEstablishment"] count] == 1);
+ ICEMXMetrics* m1 = [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp]
+ objectForKey:@"ConnectionEstablishment"] objectAtIndex:0];
+
+ test(m1.current == 0 && m1.total == 1 && [m1.id_ isEqualToString:@"127.0.0.1:12010"]);
+
+ [[metrics ice_getConnection] close:NO];
+ [controller hold];
+ @try
+ {
+ [[[communicator stringToProxy:@"test:tcp -p 12010 -h 127.0.0.1"] ice_timeout:10] ice_ping];
+ test(NO);
+ }
+ @catch(ICEConnectTimeoutException*)
+ {
+ }
+ @catch(const ICELocalException*)
+ {
+ test(NO);
+ }
+ [controller resume];
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp]
+ objectForKey:@"ConnectionEstablishment"] count] == 1);
+ m1 = [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp]
+ objectForKey:@"ConnectionEstablishment"] objectAtIndex:0];
+ test([m1.id_ isEqualToString:@"127.0.0.1:12010"] && m1.total == 3 && m1.failures == 2);
+
+ checkFailure(clientMetrics, @"ConnectionEstablishment", m1.id_, @"Ice::ConnectTimeoutException", 2);
+
+ Connect* c = [Connect connect:metrics];
+
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"parent", @"Communicator", c);
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"id", @"127.0.0.1:12010", c);
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"endpoint",
+ @"tcp -h 127.0.0.1 -p 12010 -t 60000", c);
+
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"endpointType", @"1", c);
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"endpointIsDatagram", @"false", c);
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"endpointIsSecure", @"false", c);
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"endpointTimeout", @"60000", c);
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"endpointCompress", @"false", c);
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"endpointHost", @"127.0.0.1", c);
+ testAttribute(clientMetrics, clientProps, update, @"ConnectionEstablishment", @"endpointPort", @"12010", c);
+
+ tprintf("ok\n");
+
+ //
+ // Ice doesn't do any endpoint lookup with WinRT, the WinRT
+ // runtime takes care of if.
+ //
+ // In iOS we use CFStream transports that doesn't do any enpoint
+ // lookup.
+ //
+#if !defined(ICE_OS_WINRT) && (!defined(__APPLE__) || (defined(__APPLE__) && !TARGET_OS_IPHONE))
+ tprintf("testing endpoint lookup metrics... ");
+
+ [props setObject:@"id" forKey:@"IceMX.Metrics.View.Map.EndpointLookup.GroupBy"];
+ updateProps(clientProps, serverProps, update, props, @"EndpointLookup");
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"EndpointLookup"] count] == 0);
+
+ ICEObjectPrx* prx = [communicator stringToProxy:@"metrics:default -p 12010 -h localhost -t infinite"];
+ [prx ice_ping];
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"EndpointLookup"] count] == 1);
+ m1 = [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"EndpointLookup"] objectAtIndex:0];
+
+ test(m1.current <= 1 && m1.total == 1 && [m1.id_ isEqualToString:@"tcp -h localhost -p 12010 -t infinite"]);
+
+ [[prx ice_getConnection] close:NO];
+
+ BOOL dnsException = NO;
+ @try
+ {
+ [[communicator stringToProxy:@"test:tcp -t 500 -p 12010 -h unknownfoo.zeroc.com"] ice_ping];
+ test(NO);
+ }
+ @catch(const ICEDNSException*)
+ {
+ dnsException = YES;
+ }
+ @catch(ICELocalException*)
+ {
+ // Some DNS servers don't fail on unknown DNS names.
+ }
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"EndpointLookup"] count] == 2);
+ m1 = [[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"EndpointLookup"] objectAtIndex:1];
+ test([m1.id_ isEqualToString:@"tcp -h unknownfoo.zeroc.com -p 12010 -t 500"] && m1.total == 2 &&
+ (!dnsException || m1.failures == 2));
+ if(dnsException)
+ {
+ checkFailure(clientMetrics, @"EndpointLookup", m1.id_, @"Ice::DNSException", 2);
+ }
+
+ c = [Connect connect:prx];
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"parent", @"Communicator", c);
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"id",
+ @"tcp -h localhost -p 12010 -t infinite", c);
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"endpoint",
+ @"tcp -h localhost -p 12010 -t infinite", c);
+
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"endpointType", @"1", c);
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"endpointIsDatagram", @"false", c);
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"endpointIsSecure", @"false", c);
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"endpointTimeout", @"-1", c);
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"endpointCompress", @"false", c);
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"endpointHost", @"localhost", c);
+ testAttribute(clientMetrics, clientProps, update, @"EndpointLookup", @"endpointPort", @"12010", c);
+
+ tprintf("ok\n");
+#endif
+
+ tprintf("testing dispatch metrics... ");
+
+ [props setObject:@"operation" forKey:@"IceMX.Metrics.View.Map.Dispatch.GroupBy"];
+ updateProps(clientProps, serverProps, update, props, @"Dispatch");
+ test([[[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Dispatch"] count] == 0);
+
+ [metrics op];
+ @try
+ {
+ [metrics opWithUserException];
+ test(NO);
+ }
+ @catch(TestMetricsUserEx*)
+ {
+ }
+ @try
+ {
+ [metrics opWithRequestFailedException];
+ test(NO);
+ }
+ @catch(ICERequestFailedException*)
+ {
+ }
+ @try
+ {
+ [metrics opWithLocalException];
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ @try
+ {
+ [metrics opWithUnknownException];
+ test(NO);
+ }
+ @catch(ICEUnknownException*)
+ {
+ }
+ @try
+ {
+ [metrics fail];
+ test(NO);
+ }
+ @catch(ICEConnectionLostException*)
+ {
+ }
+
+ map = toMap([[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Dispatch"]);
+ test([map count] == 6);
+
+ ICEMXDispatchMetrics* dm1 = (ICEMXDispatchMetrics*)[map objectForKey:@"op"];
+ test(dm1.current <= 1 && dm1.total == 1 && dm1.failures == 0 && dm1.userException == 0);
+ test(dm1.size == 21 && dm1.replySize == 7);
+
+ dm1 = (ICEMXDispatchMetrics*)[map objectForKey:@"opWithUserException"];
+ test(dm1.current <= 1 && dm1.total == 1 && dm1.failures == 0 && dm1.userException == 1);
+ test(dm1.size == 38 && dm1.replySize == 23);
+
+ dm1 = (ICEMXDispatchMetrics*)[map objectForKey:@"opWithLocalException"];
+ test(dm1.current <= 1 && dm1.total == 1 && dm1.failures == 1 && dm1.userException == 0);
+ checkFailure(serverMetrics, @"Dispatch", dm1.id_, @"Ice::SyscallException", 1);
+ test(dm1.size == 39 && dm1.replySize > 7); // Reply contains the exception stack depending on the OS.
+
+ dm1 = (ICEMXDispatchMetrics*)[map objectForKey:@"opWithRequestFailedException"];
+ test(dm1.current <= 1 && dm1.total == 1 && dm1.failures == 1 && dm1.userException == 0);
+ checkFailure(serverMetrics, @"Dispatch", dm1.id_, @"Ice::ObjectNotExistException", 1);
+ test(dm1.size == 47 && dm1.replySize == 40);
+
+ dm1 = (ICEMXDispatchMetrics*)[map objectForKey:@"opWithUnknownException"];
+ test(dm1.current <= 1 && dm1.total == 1 && dm1.failures == 1 && dm1.userException == 0);
+ checkFailure(serverMetrics, @"Dispatch", dm1.id_, @"IceObjC::Exception", 1);
+ test(dm1.size == 41 && dm1.replySize > 7); // Reply contains the exception stack depending on the OS.
+
+ InvokeOp* op = [InvokeOp invokeOp:metrics];
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"parent", @"TestAdapter", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"id", @"metrics [op]", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"endpoint",
+ @"tcp -h 127.0.0.1 -p 12010 -t 60000", op);
+ //testAttribute(serverMetrics, serverProps, update, "Dispatch", "connection", "", op);
+
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"endpointType", @"1", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"endpointIsDatagram", @"false", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"endpointIsSecure", @"false", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"endpointTimeout", @"60000", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"endpointCompress", @"false", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"endpointHost", @"127.0.0.1", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"endpointPort", @"12010", op);
+
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"incoming", @"true", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"adapterName", @"TestAdapter", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"connectionId", @"", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"localHost", @"127.0.0.1", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"localPort", @"12010", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"remoteHost", @"127.0.0.1", op);
+ //testAttribute(serverMetrics, serverProps, update, "Dispatch", "remotePort", "12010", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"mcastHost", @"", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"mcastPort", @"", op);
+
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"operation", @"op", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"identity", @"metrics", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"facet", @"", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"mode", @"twoway", op);
+
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"context.entry1", @"test", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"context.entry2", @"", op);
+ testAttribute(serverMetrics, serverProps, update, @"Dispatch", @"context.entry3", @"", op);
+
+ tprintf("ok\n");
+
+ tprintf("testing invocation metrics... ");
+
+ [props setObject:@"operation" forKey:@"IceMX.Metrics.View.Map.Invocation.GroupBy"];
+ [props setObject:@"localPort" forKey:@"IceMX.Metrics.View.Map.Invocation.Map.Remote.GroupBy"];
+ updateProps(clientProps, serverProps, update, props, @"Invocation");
+ test([[[serverMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Invocation"] count] == 0);
+
+ Callback* cb = [Callback callback];
+
+ void(^responseCB)() = ^()
+ {
+ [cb response];
+ };
+
+ void(^exceptionCB)(ICEException*) = ^(ICEException* ex)
+ {
+ [cb exception:ex];
+ };
+
+ [metrics op];
+ [metrics end_op:[metrics begin_op]];
+ [metrics begin_op:responseCB exception:exceptionCB];
+ [cb waitForResponse];
+
+ // User exception
+ @try
+ {
+ [metrics opWithUserException];
+ test(NO);
+ }
+ @catch(TestMetricsUserEx*)
+ {
+ }
+ @try
+ {
+ [metrics end_opWithUserException:[metrics begin_opWithUserException]];
+ test(NO);
+ }
+ @catch(const TestMetricsUserEx*)
+ {
+ }
+ [metrics begin_opWithUserException:responseCB exception:exceptionCB];
+ [cb waitForResponse];
+
+ // Request failed exception
+ @try
+ {
+ [metrics opWithRequestFailedException];
+ test(NO);
+ }
+ @catch(ICERequestFailedException*)
+ {
+ }
+ @try
+ {
+ [metrics end_opWithRequestFailedException:[metrics begin_opWithRequestFailedException]];
+ test(NO);
+ }
+ @catch(const ICERequestFailedException*)
+ {
+ }
+ [metrics begin_opWithRequestFailedException:responseCB exception:exceptionCB];
+ [cb waitForResponse];
+
+ // Local exception
+ @try
+ {
+ [metrics opWithLocalException];
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ @try
+ {
+ [metrics end_opWithLocalException:[metrics begin_opWithLocalException]];
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ [metrics begin_opWithLocalException:responseCB exception:exceptionCB];
+ [cb waitForResponse];
+
+ // Unknown exception
+ @try
+ {
+ [metrics opWithUnknownException];
+ test(NO);
+ }
+ @catch(ICEUnknownException*)
+ {
+ }
+ @try
+ {
+ [metrics end_opWithUnknownException:[metrics begin_opWithUnknownException]];
+ test(NO);
+ }
+ @catch(ICEUnknownException*)
+ {
+ }
+ [metrics begin_opWithUnknownException:responseCB exception:exceptionCB];
+ [cb waitForResponse];
+
+ // Fail
+ @try
+ {
+ [metrics fail];
+ test(NO);
+ }
+ @catch(ICEConnectionLostException*)
+ {
+ }
+ @try
+ {
+ [metrics end_fail:[metrics begin_fail]];
+ test(NO);
+ }
+ @catch(ICEConnectionLostException*)
+ {
+ }
+ [metrics begin_fail:responseCB exception:exceptionCB];
+ [cb waitForResponse];
+
+ map = toMap([[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Invocation"]);
+ test([map count] == 6);
+
+ ICEMXInvocationMetrics* im1;
+ ICEMXRemoteMetrics* rim1;
+ im1 = (ICEMXInvocationMetrics*)[map objectForKey:@"op"];
+ test(im1.current <= 1 && im1.total == 3 && im1.failures == 0 && im1.retry == 0 && [im1.remotes count] == 1);
+ rim1 = (ICEMXRemoteMetrics*)[im1.remotes objectAtIndex:0];
+ test(rim1.current == 0 && rim1.total == 3 && rim1.failures == 0);
+ test(rim1.size == 63 && rim1.replySize == 21);
+
+ im1 = (ICEMXInvocationMetrics*)[map objectForKey:@"opWithUserException"];
+ test(im1.current <= 1 && im1.total == 3 && im1.failures == 0 && im1.retry == 0 && [im1.remotes count] == 1);
+ rim1 = (ICEMXRemoteMetrics*)[im1.remotes objectAtIndex:0];
+ test(rim1.current == 0 && rim1.total == 3 && rim1.failures == 0);
+ test(rim1.size == 114 && rim1.replySize == 69);
+ test(im1.userException == 3);
+
+ im1 = (ICEMXInvocationMetrics*)[map objectForKey:@"opWithLocalException"];
+ test(im1.current <= 1 && im1.total == 3 && im1.failures == 3 && im1.retry == 0 && [im1.remotes count] == 1);
+ rim1 = (ICEMXRemoteMetrics*)[im1.remotes objectAtIndex:0];
+ test(rim1.current == 0 && rim1.total == 3 && rim1.failures == 0);
+ test(rim1.size == 117 && rim1.replySize > 7);
+ checkFailure(clientMetrics, @"Invocation", im1.id_, @"Ice::UnknownLocalException", 3);
+
+ im1 = (ICEMXInvocationMetrics*)[map objectForKey:@"opWithRequestFailedException"];
+ test(im1.current <= 1 && im1.total == 3 && im1.failures == 3 && im1.retry == 0 && [im1.remotes count] == 1);
+ rim1 = (ICEMXRemoteMetrics*)[im1.remotes objectAtIndex:0];
+ test(rim1.current == 0 && rim1.total == 3 && rim1.failures == 0);
+ test(rim1.size == 141 && rim1.replySize == 120);
+ checkFailure(clientMetrics, @"Invocation", im1.id_, @"Ice::ObjectNotExistException", 3);
+
+ im1 = (ICEMXInvocationMetrics*)[map objectForKey:@"opWithUnknownException"];
+ test(im1.current <= 1 && im1.total == 3 && im1.failures == 3 && im1.retry == 0 && [im1.remotes count] == 1);
+ rim1 = (ICEMXRemoteMetrics*)[im1.remotes objectAtIndex:0];
+ test(rim1.current == 0 && rim1.total == 3 && rim1.failures == 0);
+ checkFailure(clientMetrics, @"Invocation", im1.id_, @"Ice::UnknownException", 3);
+
+ im1 = (ICEMXInvocationMetrics*)[map objectForKey:@"fail"];
+ test(im1.current <= 1 && im1.total == 3 && im1.failures == 3 && im1.retry == 3 && [im1.remotes count] == 6);
+
+ test(((ICEMXMetrics*)[im1.remotes objectAtIndex:0]).current == 0 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:0]).total == 1 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:0]).failures == 1);
+
+ test(((ICEMXMetrics*)[im1.remotes objectAtIndex:1]).current == 0 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:1]).total == 1 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:1]).failures == 1);
+
+ test(((ICEMXMetrics*)[im1.remotes objectAtIndex:2]).current == 0 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:2]).total == 1 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:2]).failures == 1);
+
+ test(((ICEMXMetrics*)[im1.remotes objectAtIndex:3]).current == 0 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:3]).total == 1 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:3]).failures == 1);
+
+ test(((ICEMXMetrics*)[im1.remotes objectAtIndex:4]).current == 0 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:4]).total == 1 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:4]).failures == 1);
+
+ test(((ICEMXMetrics*)[im1.remotes objectAtIndex:5]).current == 0 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:5]).total == 1 &&
+ ((ICEMXMetrics*)[im1.remotes objectAtIndex:5]).failures == 1);
+
+ checkFailure(clientMetrics, @"Invocation", im1.id_, @"Ice::ConnectionLostException", 3);
+
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"parent", @"Communicator", op);
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"id", @"metrics -t -e 1.1 [op]", op);
+
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"operation", @"op", op);
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"identity", @"metrics", op);
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"facet", @"", op);
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"encoding", @"1.1", op);
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"mode", @"twoway", op);
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"proxy",
+ @"metrics -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 60000", op);
+
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"context.entry1", @"test", op);
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"context.entry2", @"", op);
+ testAttribute(clientMetrics, clientProps, update, @"Invocation", @"context.entry3", @"", op);
+
+ tprintf("ok\n");
+
+ tprintf("testing metrics view enable/disable...");
+
+
+ [props setObject:@"none" forKey:@"IceMX.Metrics.View.GroupBy"];
+ [props setObject:@"0" forKey:@"IceMX.Metrics.View.Disabled"];
+ updateProps(clientProps, serverProps, update, props, @"Thread");
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Thread"] count] > 0);
+
+ ICEMutableStringSeq* disabledViews;
+ ICEMutableStringSeq* names = [clientMetrics getMetricsViewNames:&disabledViews];
+ test([names count] == 1 && [disabledViews count] == 0);
+
+ [props setObject:@"1" forKey:@"IceMX.Metrics.View.Disabled"];
+ updateProps(clientProps, serverProps, update, props, @"Thread");
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Thread"] count] == 0);
+ test([[clientMetrics getMetricsViewNames:&disabledViews] count] == 0 && [disabledViews count] == 1);
+
+ [clientMetrics enableMetricsView:@"View"];
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Thread"] count] > 0);
+ test([[clientMetrics getMetricsViewNames:&disabledViews] count] == 1 && [disabledViews count] == 0);
+
+ [clientMetrics disableMetricsView:@"View"];
+ test([[[clientMetrics getMetricsView:@"View" timestamp:&timestamp] objectForKey:@"Thread"] count] == 0);
+ test([[clientMetrics getMetricsViewNames:&disabledViews] count] == 0 && [disabledViews count] == 1);
+
+ @try
+ {
+ [clientMetrics enableMetricsView:@"UnknownView"];
+ }
+ @catch(ICEMXUnknownMetricsView*)
+ {
+ }
+
+ tprintf("ok\n");
+
+ return metrics;
+}
diff --git a/objc/test/Ice/metrics/Client.m b/objc/test/Ice/metrics/Client.m
new file mode 100644
index 00000000000..02bf2733872
--- /dev/null
+++ b/objc/test/Ice/metrics/Client.m
@@ -0,0 +1,87 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <MetricsTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestMetricsMetricsPrx> metricsAllTests(id<ICECommunicator>);
+ id<TestMetricsMetricsPrx> metrics = metricsAllTests(communicator);
+ [metrics shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main metricsClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+ [initData.properties setProperty:@"Ice.Admin.Endpoints" value:@"tcp"];
+ [initData.properties setProperty:@"Ice.Admin.InstanceName" value:@"client"];
+ [initData.properties setProperty:@"Ice.Admin.DelayCreation" value:@"1"];
+ [initData.properties setProperty:@"Ice.Warn.Connections" value:@"0"];
+ [initData.properties setProperty:@"Ice.MessageSizeMax" value:@"50000"];
+
+ [initData.properties setProperty:@"IceMX.Metrics.Debug.GroupBy" value:@"id"];
+ [initData.properties setProperty:@"IceMX.Metrics.Parent.GroupBy" value:@"parent"];
+ [initData.properties setProperty:@"IceMX.Metrics.All.GroupBy" value:@"none"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestMetrics", @"::Test",
+ @"ICEMX", @"::IceMX",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/metrics/Makefile b/objc/test/Ice/metrics/Makefile
new file mode 100644
index 00000000000..5cb7680df69
--- /dev/null
+++ b/objc/test/Ice/metrics/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = MetricsTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/metrics/MetricsTest.ice b/objc/test/Ice/metrics/MetricsTest.ice
new file mode 100644
index 00000000000..690eef9c1da
--- /dev/null
+++ b/objc/test/Ice/metrics/MetricsTest.ice
@@ -0,0 +1,51 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestMetrics"]
+module Test
+{
+
+exception UserEx
+{
+};
+
+sequence<byte> ByteSeq;
+
+interface Metrics
+{
+ void op();
+
+ idempotent void fail();
+
+ void opWithUserException()
+ throws UserEx;
+
+ void opWithRequestFailedException();
+
+ void opWithLocalException();
+
+ void opWithUnknownException();
+
+ void opByteS(ByteSeq bs);
+
+ Object* getAdmin();
+
+ void shutdown();
+};
+
+interface Controller
+{
+ void hold();
+
+ void resume();
+};
+
+};
diff --git a/objc/test/Ice/metrics/Server.m b/objc/test/Ice/metrics/Server.m
new file mode 100644
index 00000000000..908ed2710ad
--- /dev/null
+++ b/objc/test/Ice/metrics/Server.m
@@ -0,0 +1,103 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <metrics/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+
+ ICEObject* object = [[MetricsI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [object autorelease];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"metrics"]];
+ [adapter activate];
+
+ [[communicator getProperties] setProperty:@"ControllerAdapter.Endpoints" value:@"default -p 12011"];
+ id<ICEObjectAdapter> controllerAdapter = [communicator createObjectAdapter:@"ControllerAdapter"];
+
+ ICEObject* controller = [[ControllerI alloc] init:adapter];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [controller autorelease];
+#endif
+ [controllerAdapter add:controller identity:[communicator stringToIdentity:@"controller"]];
+ [controllerAdapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main metricsServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+ [initData.properties setProperty:@"Ice.Admin.Endpoints" value:@"tcp"];
+ [initData.properties setProperty:@"Ice.Admin.InstanceName" value:@"server"];
+ [initData.properties setProperty:@"Ice.Warn.Connections" value:@"0"];
+ [initData.properties setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+ [initData.properties setProperty:@"Ice.MessageSizeMax" value:@"50000"];
+
+ [initData.properties setProperty:@"IceMX.Metrics.Debug.GroupBy" value:@"id"];
+ [initData.properties setProperty:@"IceMX.Metrics.Parent.GroupBy" value:@"parent"];
+ [initData.properties setProperty:@"IceMX.Metrics.All.GroupBy" value:@"none"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestMetrics", @"::Test",
+ @"ICEMX", @"::IceMX",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/metrics/TestI.h b/objc/test/Ice/metrics/TestI.h
new file mode 100644
index 00000000000..ca0f891a535
--- /dev/null
+++ b/objc/test/Ice/metrics/TestI.h
@@ -0,0 +1,33 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <MetricsTest.h>
+
+@interface MetricsI : TestMetricsMetrics<TestMetricsMetrics>
+-(id) init;
+-(void) op:(ICECurrent*)current;
+-(void) fail:(ICECurrent*)current;
+-(void) opWithUserException:(ICECurrent*)current;
+-(void) opWithRequestFailedException:(ICECurrent*)current;
+-(void) opWithLocalException:(ICECurrent*)current;
+-(void) opWithUnknownException:(ICECurrent*)current;
+-(void) opByteS:(ICEByteSeq*)bs current:(ICECurrent*)current;
+-(ICEObjectPrx*) getAdmin:(ICECurrent*)current;
+-(void) shutdown:(ICECurrent*)current;
+@end
+
+@interface ControllerI : TestMetricsController<TestMetricsController>
+{
+@private
+ id<ICEObjectAdapter> adapter;
+}
+-(id) init:(id<ICEObjectAdapter>)adapter_p;
+-(void) hold:(ICECurrent*)current;
+-(void) resume:(ICECurrent*)current;
+@end \ No newline at end of file
diff --git a/objc/test/Ice/metrics/TestI.m b/objc/test/Ice/metrics/TestI.m
new file mode 100644
index 00000000000..5ec6252138d
--- /dev/null
+++ b/objc/test/Ice/metrics/TestI.m
@@ -0,0 +1,98 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <metrics/TestI.h>
+
+@implementation MetricsI
+
+-(id) init
+{
+ self = [super init];
+ return self;
+}
+
+-(void) op:(ICECurrent*)current
+{
+}
+
+-(void) fail:(ICECurrent*)current
+{
+ [current.con close:YES];
+}
+
+-(void) opWithUserException:(ICECurrent*)current
+{
+ @throw [TestMetricsUserEx userEx];
+}
+
+-(void) opWithRequestFailedException:(ICECurrent*)current
+{
+ @throw [ICEObjectNotExistException objectNotExistException:__FILE__ line:__LINE__];
+}
+
+-(void) opWithLocalException:(ICECurrent*)current
+{
+ @throw [ICESyscallException syscallException:__FILE__ line:__LINE__];
+}
+
+-(void) opWithUnknownException:(ICECurrent*)current
+{
+ @throw @"TEST";
+}
+
+-(void) opByteS:(ICEByteSeq*)bs current:(ICECurrent*)current
+{
+}
+
+-(ICEObjectPrx*) getAdmin:(ICECurrent*)current
+{
+ return [[current.adapter getCommunicator] getAdmin];
+}
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
+
+@implementation ControllerI
+-(id) init:(id<ICEObjectAdapter>)adapter_p
+{
+ self = [super init];
+ if(self)
+ {
+#if defined(__clang__) && !__has_feature(objc_arc)
+ self->adapter = [adapter_p retain];
+#else
+ self->adapter = adapter_p;
+#endif
+ }
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [self->adapter release];
+ [super dealloc];
+}
+#endif
+
+-(void) hold:(ICECurrent*)current
+{
+ [adapter hold];
+ [adapter waitForHold];
+}
+
+-(void) resume:(ICECurrent*)current
+{
+ [adapter activate];
+}
+@end
diff --git a/objc/test/Ice/metrics/run.py b/objc/test/Ice/metrics/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/metrics/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/objects/.gitignore b/objc/test/Ice/objects/.gitignore
new file mode 100644
index 00000000000..6f8684420f8
--- /dev/null
+++ b/objc/test/Ice/objects/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+ObjectsTest.m
+ObjectsTest.h
diff --git a/objc/test/Ice/objects/AllTests.m b/objc/test/Ice/objects/AllTests.m
new file mode 100644
index 00000000000..775ec995650
--- /dev/null
+++ b/objc/test/Ice/objects/AllTests.m
@@ -0,0 +1,517 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <ObjectsTest.h>
+
+void breakRetainCycleB();
+void breakRetainCycleC();
+void breakRetainCycleD();
+
+void breakRetainCycleB(TestObjectsB* b1)
+{
+ if([b1.theA isKindOfClass:[TestObjectsB class]])
+ {
+ TestObjectsB* b2 = (TestObjectsB*)b1.theA;
+ b2.theA = nil;
+ b2.theB.theA = nil;
+ b2.theB.theB = nil;
+ b2.theB.theC = nil;
+ b2.theB = nil;
+ b2.theC = nil;
+ b2 = nil;
+ }
+ b1.theA = nil;
+ b1.theB = nil;
+ b1.theC = nil;
+}
+
+void breakRetainCycleC(TestObjectsC* c1)
+{
+ breakRetainCycleB(c1.theB);
+ c1.theB = nil;
+
+}
+
+void breakRetainCycleD(TestObjectsD* d1)
+{
+ breakRetainCycleB((TestObjectsB*)d1.theA);
+ breakRetainCycleB(d1.theB);
+}
+
+id<TestObjectsInitialPrx>
+objectsAllTests(id<ICECommunicator> communicator, BOOL collocated)
+{
+ tprintf("testing stringToProxy... ");
+ NSString* ref = @"initial:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ test(base);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestObjectsInitialPrx> initial = [TestObjectsInitialPrx checkedCast:base];
+ test(initial);
+ test([initial isEqual:base]);
+ tprintf("ok\n");
+
+ tprintf("testing constructor, convenience constructor, and copy... ");
+
+ TestObjectsBase* ba1 = [TestObjectsBase base];
+
+ test(ba1.theS.str == nil);
+ test(ba1.str == nil);
+ ba1.theS = nil;
+
+ TestObjectsS* s = [TestObjectsS s];
+ s.str = @"hello";
+ TestObjectsBase* ba2 = [TestObjectsBase base:s str:@"hi"];
+ test(ba2.theS == s);
+ test([ba2.str isEqualToString:@"hi"]);
+ ba2.theS = nil;
+
+ TestObjectsBase* ba3 = [ba2 copy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [ba3 autorelease];
+#endif
+ test(ba3 != ba2);
+ test(ba3.theS == ba2.theS);
+ test(ba3.str == ba2.str);
+ ba3.theS = nil;
+
+#if 0
+ // Can't override assignment operator in Objective-C.
+ *ba1 = *ba2;
+ test([ba1.theS.str isEqualToString:@"hello"]);
+ test([ba1.str isEqualToString:@"hi"]);
+
+ TestObjectsBase* bp1 = [TestObjectsBase base];
+ *bp1 = *ba2;
+ test([bp1.theS.str isEqualToString:@"hello"]);
+ test([bp1.str isEqualToString:@"hi"]);
+#endif
+
+ tprintf("ok\n");
+
+ tprintf("getting B1... ");
+ TestObjectsB* b1 = [initial getB1];
+ test(b1);
+ tprintf("ok\n");
+
+ tprintf("getting B2... ");
+ TestObjectsB* b2 = [initial getB2];
+ test(b2);
+ tprintf("ok\n");
+
+ tprintf("getting C... ");
+ TestObjectsC* c = [initial getC];
+ test(c);
+ tprintf("ok\n");
+
+ tprintf("getting D... ");
+ TestObjectsD* d = [initial getD];
+ test(d);
+ tprintf("ok\n");
+
+ tprintf("checking consistency... ");
+ test(b1 != b2);
+ test(b1 != (TestObjectsB*)c);
+ test(b1 != (TestObjectsB*)d);
+ test(b2 != (TestObjectsB*)c);
+ test(b2 != (TestObjectsB*)d);
+ test(c != (TestObjectsC*)d);
+ test(b1.theB == b1);
+ test(b1.theC == 0);
+ test([b1.theA isKindOfClass:[TestObjectsB class]]);
+ test(((TestObjectsB*)b1.theA).theA == b1.theA);
+ test(((TestObjectsB*)b1.theA).theB == b1);
+ test([((TestObjectsB*)b1.theA).theC isKindOfClass:[TestObjectsC class]]);
+ test(((TestObjectsC*)((TestObjectsB*)b1.theA).theC).theB == b1.theA);
+ test(b1.preMarshalInvoked);
+ test([(id<TestObjectsB>)b1 postUnmarshalInvoked:nil]);
+ test(b1.theA.preMarshalInvoked);
+ test([(id<TestObjectsA>)b1.theA postUnmarshalInvoked:nil]);
+ test(((TestObjectsB*)b1.theA).theC.preMarshalInvoked);
+ test([(id<TestObjectsC>)((TestObjectsB*)b1.theA).theC postUnmarshalInvoked:nil]);
+
+ // More tests possible for b2 and d, but I think this is already sufficient.
+ test(b2.theA == b2);
+ test(d.theC == 0);
+
+ breakRetainCycleB(b1);
+ breakRetainCycleB(b2);
+ breakRetainCycleC(c);
+ breakRetainCycleD(d);
+
+ tprintf("ok\n");
+
+ tprintf("getting B1, B2, C, and D all at once... ");
+ [initial getAll:&b1 b2:&b2 theC:&c theD:&d];
+ test(b1);
+ test(b2);
+ test(c);
+ test(d);
+ tprintf("ok\n");
+
+ tprintf("checking consistency... ");
+ test(b1 != b2);
+ test(b1 != (TestObjectsB*)c);
+ test(b1 != (TestObjectsB*)d);
+ test(b2 != (TestObjectsB*)c);
+ test(b2 != (TestObjectsB*)d);
+ test(c != (TestObjectsC*)d);
+ test(b1.theA == b2);
+ test(b1.theB == b1);
+ //test(b1.theC == 0);
+ test(b2.theA == b2);
+ test(b2.theB == b1);
+ test(b2.theC == c);
+ test(c.theB == b2);
+ test(d.theA == b1);
+ test(d.theB == b2);
+ //test(d.theC == 0);
+// if(!collocated)
+// {
+ test(d.preMarshalInvoked);
+ test([(id<TestObjectsD>)d postUnmarshalInvoked:nil]);
+ test(d.theA.preMarshalInvoked);
+ test([(id<TestObjectsA>)d.theA postUnmarshalInvoked:nil]);
+ test(d.theB.preMarshalInvoked);
+ test([(id<TestObjectsA>)d.theB postUnmarshalInvoked:nil]);
+ test(d.theB.theC.preMarshalInvoked);
+ test([(id<TestObjectsC>)d.theB.theC postUnmarshalInvoked:nil]);
+// }
+
+ breakRetainCycleB(b1);
+ breakRetainCycleB(b2);
+ breakRetainCycleC(c);
+ breakRetainCycleD(d);
+
+ tprintf("ok\n");
+
+ tprintf("testing protected members... ");
+ TestObjectsE* e = [initial getE];
+ test([(id<TestObjectsE>)e checkValues:nil]);
+ TestObjectsF* f = [initial getF];
+ test([(id<TestObjectsF>)f checkValues:nil]);
+ test([(id<TestObjectsE>)f.e2 checkValues:nil]);
+ tprintf("ok\n");
+
+ tprintf("getting I, J and H... ");
+ TestObjectsI* i = (TestObjectsI*)[initial getI];
+ test(i);
+ TestObjectsI* j = (TestObjectsI*)[initial getJ];
+ test(j && [j isKindOfClass:[TestObjectsJ class]]);
+ TestObjectsI* h = (TestObjectsI*)[initial getH];
+ test(h && [h isKindOfClass:[TestObjectsH class]]);
+ tprintf("ok\n");
+
+ tprintf("setting I... ");
+ [initial setI:i];
+ [initial setI:j];
+ [initial setI:h];
+ tprintf("ok\n");
+
+ tprintf("testing sequences... ");
+ TestObjectsMutableBaseSeq* inS = [TestObjectsMutableBaseSeq array];
+ TestObjectsMutableBaseSeq* outS;
+ TestObjectsMutableBaseSeq* retS = [initial opBaseSeq:inS outSeq:&outS];
+
+ [inS addObject:[TestObjectsBase base]];
+ retS = [initial opBaseSeq:inS outSeq:&outS];
+ test([retS count] == 1 && [outS count] == 1);
+ tprintf("ok\n");
+
+ tprintf("testing compact ID...");
+ @try
+ {
+ test([initial getCompact]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+ tprintf("ok\n");
+
+// if(!collocated)
+// {
+ tprintf("testing UnexpectedObjectException... ");
+ ref = @"uoet:default -p 12010";
+ base = [communicator stringToProxy:ref];
+ test(base);
+ id<TestObjectsUnexpectedObjectExceptionTestPrx> uoet = [TestObjectsUnexpectedObjectExceptionTestPrx uncheckedCast:base];
+ test(uoet);
+ @try
+ {
+ [uoet op];
+ test(NO);
+ }
+ @catch(ICEUnexpectedObjectException* ex)
+ {
+ test([ex.type isEqualToString:@"::Test::AlsoEmpty"]);
+ test([ex.expectedType isEqualToString:@"::Test::Empty"]);
+ }
+ @catch(ICEException* ex)
+ {
+ test(NO);
+ }
+ tprintf("ok\n");
+// }
+
+ //
+ // TestObjectss specific to Objective-C.
+ //
+ {
+ tprintf("setting Object sequence... ");
+ TestObjectsMutableObjectSeq* seq = [TestObjectsMutableObjectSeq array];
+
+ [seq addObject:[NSNull null]];
+
+ TestObjectsBase* b = [TestObjectsBase base];
+ b.theS = [TestObjectsS s];
+ b.theS.str = @"Hello";
+ b.str = @"World";
+ [seq addObject:b];
+
+ @try
+ {
+ TestObjectsObjectSeq* r = [initial getObjectSeq:seq];
+ test([r objectAtIndex:0 == [NSNull null]]);
+ TestObjectsBase* br = [r objectAtIndex:1];
+ test([br.theS.str isEqualToString:@"Hello"]);
+ test([br.str isEqualToString:@"World"]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Expected if we are testing against a non-Objective-C server.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("setting Object proxy sequence... ");
+ TestObjectsMutableObjectPrxSeq* seq = [TestObjectsMutableObjectPrxSeq array];
+
+ [seq addObject:[NSNull null]];
+ [seq addObject:initial];
+
+ @try
+ {
+ TestObjectsObjectPrxSeq* r = [initial getObjectPrxSeq:seq];
+ test([r objectAtIndex:0 == [NSNull null]]);
+ test([[r objectAtIndex:1] isEqual:initial]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Expected if we are testing against a non-Objective-C server.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("setting Base sequence... ");
+ TestObjectsMutableBaseSeq* seq = [TestObjectsMutableBaseSeq array];
+
+ [seq addObject:[NSNull null]];
+
+ TestObjectsBase* b = [TestObjectsBase base];
+ b.theS = [TestObjectsS s];
+ b.theS.str = @"Hello";
+ b.str = @"World";
+ [seq addObject:b];
+
+ @try
+ {
+ TestObjectsBaseSeq* r = [initial getBaseSeq:seq];
+ test([r objectAtIndex:0 == [NSNull null]]);
+ TestObjectsBase* br = [r objectAtIndex:1];
+ test([br.theS.str isEqualToString:@"Hello"]);
+ test([br.str isEqualToString:@"World"]);
+ br.theS = nil;
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Expected if we are testing against a non-Objective-C server.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+
+ {
+ TestObjectsBase* br = [seq objectAtIndex:1];
+ br.theS = nil;
+ b.theS = nil;
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("setting Base proxy sequence... ");
+ TestObjectsMutableBasePrxSeq* seq = [TestObjectsMutableBasePrxSeq array];
+
+ [seq addObject:[NSNull null]];
+ NSString* ref = @"base:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ id<TestObjectsBasePrx> b = [TestObjectsBasePrx uncheckedCast:base];
+ [seq addObject:b];
+
+ @try
+ {
+ TestObjectsBasePrxSeq* r = [initial getBasePrxSeq:seq];
+ test([r objectAtIndex:0 == [NSNull null]]);
+ test([[r objectAtIndex:1] isEqual:b]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Expected if we are testing against a non-Objective-C server.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("setting Object dictionary... ");
+ TestObjectsMutableObjectDict* dict = [TestObjectsMutableObjectDict dictionary];
+
+ [dict setObject:[NSNull null] forKey:@"zero"];
+
+ TestObjectsBase* b = [TestObjectsBase base];
+ b.theS = [TestObjectsS s];
+ b.theS.str = @"Hello";
+ b.str = @"World";
+ [dict setObject:b forKey:@"one"];
+
+ @try
+ {
+ TestObjectsObjectDict* r = [initial getObjectDict:dict];
+ test([r objectForKey:@"zero"] == [NSNull null]);
+ TestObjectsBase* br = [r objectForKey:@"one"];
+ test([br.theS.str isEqualToString:@"Hello"]);
+ test([br.str isEqualToString:@"World"]);
+ br.theS = nil;
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Expected if we are testing against a non-Objective-C server.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ {
+ TestObjectsBase* br = [dict objectForKey:@"one"];
+ br.theS = nil;
+ b.theS = nil;
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("setting Object proxy dictionary... ");
+ TestObjectsMutableObjectPrxDict* dict = [TestObjectsMutableObjectPrxDict dictionary];
+
+ [dict setObject:[NSNull null] forKey:@"zero"];
+ NSString* ref = @"object:default -p 12010";
+ id<ICEObjectPrx> o = [communicator stringToProxy:ref];
+ [dict setObject:o forKey:@"one"];
+
+ @try
+ {
+ TestObjectsObjectPrxDict* r = [initial getObjectPrxDict:dict];
+ test([r objectForKey:@"zero"] == [NSNull null]);
+ test([[r objectForKey:@"one"] isEqual:o]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Expected if we are testing against a non-Objective-C server.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("setting Base dictionary... ");
+ TestObjectsMutableBaseDict* dict = [TestObjectsMutableBaseDict dictionary];
+
+ [dict setObject:[NSNull null] forKey:@"zero"];
+
+ TestObjectsBase* b = [TestObjectsBase base];
+ b.theS = [TestObjectsS s];
+ b.theS.str = @"Hello";
+ b.str = @"World";
+ [dict setObject:b forKey:@"one"];
+
+ @try
+ {
+ TestObjectsBaseDict* r = [initial getBaseDict:dict];
+ test([r objectForKey:@"zero"] == [NSNull null]);
+ TestObjectsBase* br = [r objectForKey:@"one"];
+ test([br.theS.str isEqualToString:@"Hello"]);
+ test([br.str isEqualToString:@"World"]);
+ br.theS = nil;
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Expected if we are testing against a non-Objective-C server.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ {
+ TestObjectsBase* br = [dict objectForKey:@"one"];
+ br.theS = nil;
+ b.theS = nil;
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("setting Base proxy dictionary... ");
+ TestObjectsMutableBasePrxDict* dict = [TestObjectsMutableBasePrxDict dictionary];
+
+ [dict setObject:[NSNull null] forKey:@"zero"];
+ NSString* ref = @"base:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ id<TestObjectsBasePrx> b = [TestObjectsBasePrx uncheckedCast:base];
+ [dict setObject:b forKey:@"one"];
+
+ @try
+ {
+ TestObjectsObjectPrxDict* r = [initial getObjectPrxDict:dict];
+ test([r objectForKey:@"zero"] == [NSNull null]);
+ test([[r objectForKey:@"one"] isEqual:b]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Expected if we are testing against a non-Objective-C server.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ tprintf("ok\n");
+ }
+
+ return initial;
+}
diff --git a/objc/test/Ice/objects/Client.m b/objc/test/Ice/objects/Client.m
new file mode 100644
index 00000000000..83c5575def0
--- /dev/null
+++ b/objc/test/Ice/objects/Client.m
@@ -0,0 +1,146 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <objects/TestI.h>
+
+#if !TARGET_OS_IPHONE
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+@interface ClientMyObjectFactory : NSObject<ICEObjectFactory>
+@end
+
+@implementation ClientMyObjectFactory
+
+// Note that the object factory must not autorelease the
+// returned objects.
+-(ICEObject*) create:(NSString*)type
+{
+ if([type isEqualToString:@"::Test::B"])
+ {
+ return [[TestObjectsBI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::C"])
+ {
+ return [[TestObjectsCI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::D"])
+ {
+ return [[TestObjectsDI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::E"])
+ {
+ return [[TestObjectsEI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::F"])
+ {
+ return [[TestObjectsFI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::I"])
+ {
+ return [[TestObjectsI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::J"])
+ {
+ return [[TestObjectsJI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::H"])
+ {
+ return [[TestObjectsHI alloc] init];
+ }
+ else
+ {
+ test(NO);
+ }
+ return nil;
+}
+
+-(void) destroy
+{
+ // Nothing to do
+}
+@end
+
+static int
+run(id<ICECommunicator> communicator)
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ id<ICEObjectFactory> factory = [[[ClientMyObjectFactory alloc] init] autorelease];
+#else
+ id<ICEObjectFactory> factory = [[ClientMyObjectFactory alloc] init];
+#endif
+
+ [communicator addObjectFactory:factory sliceId:@"::Test::B"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::C"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::D"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::E"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::F"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::I"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::J"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::H"];
+
+ id<TestObjectsInitialPrx> objectsAllTests(id<ICECommunicator>, bool);
+ id<TestObjectsInitialPrx> initial = objectsAllTests(communicator, NO);
+ [initial shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main objectsClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestObjects", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/objects/Makefile b/objc/test/Ice/objects/Makefile
new file mode 100644
index 00000000000..2590019cf26
--- /dev/null
+++ b/objc/test/Ice/objects/Makefile
@@ -0,0 +1,38 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = ObjectsTest.o
+
+COBJS = Client.o \
+ TestI.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/objects/ObjectsTest.ice b/objc/test/Ice/objects/ObjectsTest.ice
new file mode 100644
index 00000000000..eddf50986c7
--- /dev/null
+++ b/objc/test/Ice/objects/ObjectsTest.ice
@@ -0,0 +1,201 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestObjects"]
+module Test
+{
+
+struct S
+{
+ string str;
+};
+
+class Base
+{
+ S theS;
+ string str;
+};
+
+class B;
+class C;
+
+class A
+{
+ B theB;
+ C theC;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
+};
+
+class B extends A
+{
+ A theA;
+};
+
+class C
+{
+ B theB;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
+};
+
+class D
+{
+ A theA;
+ B theB;
+ C theC;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
+};
+
+["protected"] class E
+{
+ int i;
+ string s;
+
+ bool checkValues();
+};
+
+class F
+{
+ ["protected"] E e1;
+ E e2;
+
+ bool checkValues();
+};
+
+interface I
+{
+};
+
+interface J extends I
+{
+};
+
+class H implements I
+{
+};
+
+class CompactExt;
+
+class Compact(1)
+{
+};
+
+const int CompactExtId = 789;
+
+class CompactExt(CompactExtId) extends Compact
+{
+};
+
+sequence<Object> ObjectSeq; // For Objective-C only
+sequence<Object*> ObjectPrxSeq; // For Objective-C only
+sequence<Base> BaseSeq; // For Objective-C only
+sequence<Base*> BasePrxSeq; // For Objective-C only
+
+dictionary<string, Object> ObjectDict; // For Objective-C only
+dictionary<string, Object*> ObjectPrxDict; // For Objective-C only
+dictionary<string, Base> BaseDict; // For Objective-C only
+dictionary<string, Base*> BasePrxDict; // For Objective-C only
+
+class Initial
+{
+ void shutdown();
+ B getB1();
+ B getB2();
+ C getC();
+ D getD();
+ E getE();
+ F getF();
+
+ void getAll(out B b1, out B b2, out C theC, out D theD);
+
+ I getI();
+ I getJ();
+ I getH();
+
+ void setI(I theI);
+
+ BaseSeq opBaseSeq(BaseSeq inSeq, out BaseSeq outSeq);
+
+ Compact getCompact();
+
+ //
+ // Remaining operations are here only for Objective-C and are not implemented by other language mappings.
+ //
+ ObjectSeq getObjectSeq(ObjectSeq s);
+ ObjectPrxSeq getObjectPrxSeq(ObjectPrxSeq s);
+ BaseSeq getBaseSeq(BaseSeq s);
+ BasePrxSeq getBasePrxSeq(BasePrxSeq s);
+
+ ObjectDict getObjectDict(ObjectDict d);
+ ObjectPrxDict getObjectPrxDict(ObjectPrxDict d);
+ BaseDict getBaseDict(BaseDict d);
+ BasePrxDict getBasePrxDict(BasePrxDict d);
+};
+
+class Empty
+{
+};
+
+class AlsoEmpty
+{
+};
+
+interface UnexpectedObjectExceptionTest
+{
+ Empty op();
+};
+
+//
+// Remaining definitions are here to ensure that the generated code compiles.
+//
+
+class COneMember
+{
+ Empty e;
+};
+
+class CTwoMembers
+{
+ Empty e1;
+ Empty e2;
+};
+
+exception EOneMember
+{
+ Empty e;
+};
+
+exception ETwoMembers
+{
+ Empty e1;
+ Empty e2;
+};
+
+struct SOneMember
+{
+ Empty e;
+};
+
+struct STwoMembers
+{
+ Empty e1;
+ Empty e2;
+};
+
+dictionary<int, COneMember> DOneMember;
+dictionary<int, CTwoMembers> DTwoMembers;
+
+};
diff --git a/objc/test/Ice/objects/Server.m b/objc/test/Ice/objects/Server.m
new file mode 100644
index 00000000000..8705df09ab9
--- /dev/null
+++ b/objc/test/Ice/objects/Server.m
@@ -0,0 +1,131 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <objects/TestI.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+@interface ServerMyObjectFactory : NSObject<ICEObjectFactory>
+@end
+
+@implementation ServerMyObjectFactory
+// Note that the object factory must not autorelease the
+// returned objects.
+-(ICEObject*) create:(NSString*)type
+{
+ if([type isEqualToString:@"::Test::I"])
+ {
+ return [[TestObjectsI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::J"])
+ {
+ return [[TestObjectsJI alloc] init];
+ }
+ else if([type isEqualToString:@"::Test::H"])
+ {
+ return [[TestObjectsHI alloc] init];
+ }
+ else
+ {
+ test(NO); // Should never be reached
+ }
+ return nil;
+}
+
+-(void) destroy
+{
+ // Nothing to do
+}
+@end
+
+static int
+run(id<ICECommunicator> communicator)
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ id<ICEObjectFactory> factory = [[[ServerMyObjectFactory alloc] init] autorelease];
+#else
+ id<ICEObjectFactory> factory = [[ServerMyObjectFactory alloc] init];
+#endif
+ [communicator addObjectFactory:factory sliceId:@"::Test::I"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::J"];
+ [communicator addObjectFactory:factory sliceId:@"::Test::H"];
+
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* initial = [[[TestObjectsInitialI alloc] init] autorelease];
+#else
+ ICEObject* initial = [[TestObjectsInitialI alloc] init];
+#endif
+ [adapter add:initial identity:[communicator stringToIdentity:@"initial"]];
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* uoet = [[[UnexpectedObjectExceptionTestI alloc] init] autorelease];
+#else
+ ICEObject* uoet = [[UnexpectedObjectExceptionTestI alloc] init];
+#endif
+ [adapter add:uoet identity:[communicator stringToIdentity:@"uoet"]];
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main objectsServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestObjects", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/objects/TestI.h b/objc/test/Ice/objects/TestI.h
new file mode 100644
index 00000000000..cfbf2b39567
--- /dev/null
+++ b/objc/test/Ice/objects/TestI.h
@@ -0,0 +1,79 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ObjectsTest.h>
+
+@interface TestObjectsBI : TestObjectsB<TestObjectsB>
+{
+ BOOL _postUnmarshalInvoked;
+}
+@end
+
+@interface TestObjectsCI : TestObjectsC<TestObjectsC>
+{
+ BOOL _postUnmarshalInvoked;
+}
+@end
+
+@interface TestObjectsDI : TestObjectsD<TestObjectsD>
+{
+ BOOL _postUnmarshalInvoked;
+}
+@end
+
+@interface TestObjectsEI : TestObjectsE<TestObjectsE>
+@end
+
+@interface TestObjectsFI : TestObjectsF<TestObjectsF>
+@end
+
+//@interface TestObjectsII : TestObjectsI<TestObjectsI>
+//@end
+
+@interface TestObjectsJI : TestObjectsJ<TestObjectsJ>
+@end
+
+@interface TestObjectsHI : TestObjectsH<TestObjectsH>
+@end
+
+@interface TestObjectsInitialI : TestObjectsInitial<TestObjectsInitial>
+{
+ TestObjectsB* _b1;
+ TestObjectsB* _b2;
+ TestObjectsC* _c;
+ TestObjectsD* _d;
+ TestObjectsE* _e;
+ TestObjectsF* _f;
+}
+-(id) init;
+-(void) shutdown:(ICECurrent*)current;
+-(TestObjectsB *) getB1:(ICECurrent *)current;
+-(TestObjectsB *) getB2:(ICECurrent *)current;
+-(TestObjectsC *) getC:(ICECurrent *)current;
+-(TestObjectsD *) getD:(ICECurrent *)current;
+-(TestObjectsE *) getE:(ICECurrent *)current;
+-(TestObjectsF *) getF:(ICECurrent *)current;
+-(void) getAll:(TestObjectsB **)b1 b2:(TestObjectsB **)b2 theC:(TestObjectsC **)theC theD:(TestObjectsD **)theD current:(ICECurrent *)current;
+-(TestObjectsI *) getI:(ICECurrent *)current;
+-(TestObjectsI *) getJ:(ICECurrent *)current;
+-(TestObjectsI *) getH:(ICECurrent *)current;
+-(TestObjectsCompact*) getCompact:(ICECurrent*)current;
+-(void) setI:(TestObjectsI *)theI current:(ICECurrent *)current;
+-(TestObjectsObjectSeq *) getObjectSeq:(TestObjectsMutableObjectSeq *)s current:(ICECurrent *)current;
+-(TestObjectsObjectPrxSeq *) getObjectPrxSeq:(TestObjectsMutableObjectPrxSeq *)s current:(ICECurrent *)current;
+-(TestObjectsBaseSeq *) getBaseSeq:(TestObjectsMutableBaseSeq *)s current:(ICECurrent *)current;
+-(TestObjectsBasePrxSeq *) getBasePrxSeq:(TestObjectsMutableBasePrxSeq *)s current:(ICECurrent *)current;
+-(TestObjectsObjectDict *) getObjectDict:(TestObjectsMutableObjectDict *)d current:(ICECurrent *)current;
+-(TestObjectsObjectPrxDict *) getObjectPrxDict:(TestObjectsMutableObjectPrxDict *)d current:(ICECurrent *)current;
+-(TestObjectsBaseDict *) getBaseDict:(TestObjectsMutableBaseDict *)d current:(ICECurrent *)current;
+-(TestObjectsBasePrxDict *) getBasePrxDict:(TestObjectsMutableBasePrxDict *)d current:(ICECurrent *)current;
+@end
+
+@interface UnexpectedObjectExceptionTestI : ICEBlobject<ICEBlobject>
+@end
diff --git a/objc/test/Ice/objects/TestI.m b/objc/test/Ice/objects/TestI.m
new file mode 100644
index 00000000000..006885a56fd
--- /dev/null
+++ b/objc/test/Ice/objects/TestI.m
@@ -0,0 +1,328 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <objects/TestI.h>
+
+@implementation TestObjectsBI
+-(BOOL) postUnmarshalInvoked:(ICECurrent*)current
+{
+ return _postUnmarshalInvoked;
+}
+-(void) ice_preMarshal
+{
+ preMarshalInvoked = YES;
+}
+-(void) ice_postUnmarshal
+{
+ _postUnmarshalInvoked = YES;
+}
+
+@end
+
+@implementation TestObjectsCI
+-(BOOL) postUnmarshalInvoked:(ICECurrent*)current
+{
+ return _postUnmarshalInvoked;
+}
+-(void) ice_preMarshal
+{
+ preMarshalInvoked = YES;
+}
+-(void) ice_postUnmarshal
+{
+ _postUnmarshalInvoked = YES;
+}
+
+@end
+
+@implementation TestObjectsDI
+-(BOOL) postUnmarshalInvoked:(ICECurrent*)current
+{
+ return _postUnmarshalInvoked;
+}
+-(void) ice_preMarshal
+{
+ preMarshalInvoked = YES;
+}
+-(void) ice_postUnmarshal
+{
+ _postUnmarshalInvoked = YES;
+}
+@end
+
+@implementation TestObjectsEI
+-(id) init
+{
+ return [super init:1 s:@"hello"];
+}
+-(BOOL) checkValues:(ICECurrent*)current
+{
+ return i == 1 && [s isEqualToString:@"hello"];
+}
+@end
+
+@implementation TestObjectsFI
+-(id) init:(TestObjectsE*)e1_ e2:(TestObjectsE*)e2_
+{
+ self = [super init:e1_ e2:e2_];
+ if(!self)
+ {
+ return nil;
+ }
+ return self;
+}
+-(BOOL) checkValues:(ICECurrent*)current
+{
+ return e1 && e1 == e2;
+}
+@end
+
+@implementation TestObjectsHI
+@end
+
+/*@implementation TestObjectsII
+-(void) dealloc
+{
+ printf("Deallocating Object");
+}
+@end*/
+
+@implementation TestObjectsJI
+@end
+
+@implementation TestObjectsInitialI
+
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+
+ _b1 = [[TestObjectsBI alloc] init];
+ _b2 = [[TestObjectsBI alloc] init];
+ _c = [[TestObjectsCI alloc] init];
+ _d = [[TestObjectsDI alloc] init];
+ _e = [[TestObjectsEI alloc] init];
+ _f = [[TestObjectsFI alloc] init:_e e2:_e];
+
+ _b1.theA = _b2; // Cyclic reference to another B
+ _b1.theB = _b1; // Self reference.
+ _b1.theC = nil; // Null reference.
+
+ _b2.theA = _b2; // Self reference, using base.
+ _b2.theB = _b1; // Cyclic reference to another B
+ _b2.theC = _c; // Cyclic reference to a C.
+
+ _c.theB = _b2; // Cyclic reference to a B.
+
+ _d.theA = _b1; // Reference to a B.
+ _d.theB = _b2; // Reference to a B.
+ _d.theC = nil; // Reference to a C.
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [_b1 release];
+ [_b2 release];
+ [_c release];
+ [_d release];
+ [_e release];
+ [_f release];
+ [super dealloc];
+}
+#endif
+
+-(void) shutdown:(ICECurrent*)current
+{
+ _b1.theA = nil; // Break cyclic reference.
+ _b1.theB = nil; // Break cyclic reference.
+
+ _b2.theA = nil; // Break cyclic reference.
+ _b2.theB = nil; // Break cyclic reference.
+ _b2.theC = nil; // Break cyclic reference.
+
+ _c.theB = nil; // Break cyclic reference.
+
+ _d.theA = nil; // Break cyclic reference.
+ _d.theB = nil; // Break cyclic reference.
+ _d.theC = nil; // Break cyclic reference.
+ [[current.adapter getCommunicator] shutdown];
+}
+
+-(TestObjectsB*) getB1:(ICECurrent*)current
+{
+ _b1.preMarshalInvoked = NO;
+ _b2.preMarshalInvoked = NO;
+ _c.preMarshalInvoked = NO;
+ return _b1;
+}
+
+-(TestObjectsB*) getB2:(ICECurrent*)current
+{
+ _b1.preMarshalInvoked = NO;
+ _b2.preMarshalInvoked = NO;
+ _c.preMarshalInvoked = NO;
+ return _b2;
+}
+
+
+-(TestObjectsC*) getC:(ICECurrent*)current
+{
+ _b1.preMarshalInvoked = NO;
+ _b2.preMarshalInvoked = NO;
+ _c.preMarshalInvoked = NO;
+ return _c;
+}
+
+
+-(TestObjectsD*) getD:(ICECurrent*)current
+{
+ _b1.preMarshalInvoked = NO;
+ _b2.preMarshalInvoked = NO;
+ _c.preMarshalInvoked = NO;
+ _d.preMarshalInvoked = NO;
+ return _d;
+}
+
+
+-(TestObjectsE*) getE:(ICECurrent*)current
+{
+ return _e;
+}
+
+
+-(TestObjectsF*) getF:(ICECurrent*)current
+{
+ return _f;
+}
+
+
+-(void) getAll:(TestObjectsB **)b1 b2:(TestObjectsB **)b2 theC:(TestObjectsC **)theC theD:(TestObjectsD **)theD current:(ICECurrent *)current;
+{
+ _b1.preMarshalInvoked = NO;
+ _b2.preMarshalInvoked = NO;
+ _c.preMarshalInvoked = NO;
+ _d.preMarshalInvoked = NO;
+ *b1 = _b1;
+ *b2 = _b2;
+ *theC = _c;
+ *theD = _d;
+}
+
+-(TestObjectsI*) getI:(ICECurrent*)current
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[[TestObjectsI alloc] init] autorelease];
+#else
+ return [[TestObjectsI alloc] init];
+#endif
+}
+
+-(TestObjectsI*) getJ:(ICECurrent*)current
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return (TestObjectsI*)[[[TestObjectsJ alloc] init] autorelease];
+#else
+ return (TestObjectsI*)[[TestObjectsJ alloc] init];
+#endif
+}
+
+-(TestObjectsI*) getH:(ICECurrent*)current
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return (TestObjectsI*)[[[TestObjectsH alloc] init] autorelease];
+#else
+ return (TestObjectsI*)[[TestObjectsH alloc] init];
+#endif
+}
+
+-(TestObjectsBaseSeq*) opBaseSeq:(TestObjectsMutableBaseSeq*)inSeq outSeq:(TestObjectsBaseSeq**)outSeq
+ current:(ICECurrent*)current
+{
+ *outSeq = inSeq;
+ return inSeq;
+}
+
+-(TestObjectsCompact*) getCompact:(ICECurrent*)current
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return (TestObjectsCompact*)[[[TestObjectsCompactExt alloc] init] autorelease];
+#else
+ return (TestObjectsCompact*)[[TestObjectsCompactExt alloc] init];
+#endif
+}
+
+-(void) setI:(TestObjectsI*)i current:(ICECurrent*)current
+{
+}
+
+-(TestObjectsObjectSeq *) getObjectSeq:(TestObjectsMutableObjectSeq *)s current:(ICECurrent*)current
+{
+ return s;
+}
+
+-(TestObjectsObjectPrxSeq *) getObjectPrxSeq:(TestObjectsMutableObjectPrxSeq *)s current:(ICECurrent*)current
+{
+ return s;
+}
+
+-(TestObjectsBaseSeq *) getBaseSeq:(TestObjectsMutableBaseSeq *)s current:(ICECurrent*)current
+{
+ return s;
+}
+
+-(TestObjectsBasePrxSeq *) getBasePrxSeq:(TestObjectsMutableBasePrxSeq *)s current:(ICECurrent*)current
+{
+ return s;
+}
+
+-(TestObjectsObjectDict *) getObjectDict:(TestObjectsMutableObjectDict *)d current:(ICECurrent*)current
+{
+ return d;
+}
+
+-(TestObjectsObjectPrxDict *) getObjectPrxDict:(TestObjectsMutableObjectPrxDict *)d current:(ICECurrent*)current
+{
+ return d;
+}
+
+-(TestObjectsBaseDict *) getBaseDict:(TestObjectsMutableBaseDict *)d current:(ICECurrent*)current
+{
+ return d;
+}
+
+-(TestObjectsBasePrxDict *) getBasePrxDict:(TestObjectsMutableBasePrxDict *)d current:(ICECurrent*)current
+{
+ return d;
+}
+@end
+
+@implementation UnexpectedObjectExceptionTestI
+-(BOOL)ice_invoke:(NSData*)inEncaps outEncaps:(NSMutableData**)outEncaps current:(ICECurrent*)current
+{
+ id<ICECommunicator> communicator = [current.adapter getCommunicator];
+ id<ICEOutputStream> o = [ICEUtil createOutputStream:communicator];
+ [o startEncapsulation];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ TestObjectsAlsoEmpty* ae = [[[TestObjectsAlsoEmpty alloc] init] autorelease];
+#else
+ TestObjectsAlsoEmpty* ae = [[TestObjectsAlsoEmpty alloc] init];
+#endif
+ [o writeObject:ae];
+ [o writePendingObjects];
+ [o endEncapsulation];
+ *outEncaps = [o finished];
+ return YES;
+}
+@end
diff --git a/objc/test/Ice/objects/run.py b/objc/test/Ice/objects/run.py
new file mode 100755
index 00000000000..37acea1668c
--- /dev/null
+++ b/objc/test/Ice/objects/run.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+print("Running test with compact (default) format.")
+TestUtil.clientServerTest()
+
+print("Running test with sliced format.")
+TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.SlicedFormat",
+ additionalServerOptions="--Ice.Default.SlicedFormat")
+
+print("Running test with 1.0 encoding.")
+TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0",
+ additionalServerOptions="--Ice.Default.EncodingVersion=1.0")
diff --git a/objc/test/Ice/objects/test.log b/objc/test/Ice/objects/test.log
new file mode 100644
index 00000000000..3150beca6c7
--- /dev/null
+++ b/objc/test/Ice/objects/test.log
@@ -0,0 +1,1399 @@
+testing stringToProxy... ok
+testing checked cast... ok
+testing constructor, copy constructor, and assignment operator... ok
+getting B1... starting server... ok
+starting client... ok
+2008-09-05 18:27:29.095 server[74756:2403] write Test::B
+2008-09-05 18:27:29.098 client[74758:10b] read Test::B
+2008-09-05 18:27:29.100 client[74758:10b] read Test::A
+2008-09-05 18:27:29.101 client[74758:10b] readPendingObject
+ok
+getting B2... 2008-09-05 18:27:29.096 server[74756:2403] write Test::A
+2008-09-05 18:27:29.102 server[74756:2203] write Test::B
+2008-09-05 18:27:29.102 server[74756:2203] write Test::A
+2008-09-05 18:27:29.103 server[74756:2203] write Test::B
+2008-09-05 18:27:29.103 server[74756:2203] write Test::A
+2008-09-05 18:27:29.104 server[74756:2203] write Test::B
+2008-09-05 18:27:29.104 server[74756:2203] write Test::A
+2008-09-05 18:27:29.105 server[74756:2203] write Test::B
+2008-09-05 18:27:29.105 server[74756:2203] write Test::A
+2008-09-05 18:27:29.105 server[74756:2203] write Test::B
+2008-09-05 18:27:29.106 server[74756:2203] write Test::A
+2008-09-05 18:27:29.106 server[74756:2203] write Test::B
+2008-09-05 18:27:29.106 server[74756:2203] write Test::A
+2008-09-05 18:27:29.107 server[74756:2203] write Test::B
+2008-09-05 18:27:29.107 server[74756:2203] write Test::A
+2008-09-05 18:27:29.108 server[74756:2203] write Test::B
+2008-09-05 18:27:29.108 server[74756:2203] write Test::A
+2008-09-05 18:27:29.108 server[74756:2203] write Test::B
+2008-09-05 18:27:29.109 server[74756:2203] write Test::A
+2008-09-05 18:27:29.109 server[74756:2203] write Test::B
+2008-09-05 18:27:29.109 server[74756:2203] write Test::A
+2008-09-05 18:27:29.110 server[74756:2203] write Test::B
+2008-09-05 18:27:29.110 server[74756:2203] write Test::A
+2008-09-05 18:27:29.110 server[74756:2203] write Test::B
+2008-09-05 18:27:29.111 server[74756:2203] write Test::A
+2008-09-05 18:27:29.111 server[74756:2203] write Test::B
+2008-09-05 18:27:29.111 server[74756:2203] write Test::A
+2008-09-05 18:27:29.112 server[74756:2203] write Test::B
+2008-09-05 18:27:29.112 server[74756:2203] write Test::A
+2008-09-05 18:27:29.113 server[74756:2203] write Test::B
+2008-09-05 18:27:29.113 server[74756:2203] write Test::A
+2008-09-05 18:27:29.113 server[74756:2203] write Test::B
+2008-09-05 18:27:29.114 server[74756:2203] write Test::A
+2008-09-05 18:27:29.114 server[74756:2203] write Test::B
+2008-09-05 18:27:29.114 server[74756:2203] write Test::A
+2008-09-05 18:27:29.115 server[74756:2203] write Test::B
+2008-09-05 18:27:29.115 server[74756:2203] write Test::A
+2008-09-05 18:27:29.115 server[74756:2203] write Test::B
+2008-09-05 18:27:29.116 server[74756:2203] write Test::A
+2008-09-05 18:27:29.116 server[74756:2203] write Test::B
+2008-09-05 18:27:29.117 server[74756:2203] write Test::A
+2008-09-05 18:27:29.117 server[74756:2203] write Test::B
+2008-09-05 18:27:29.117 server[74756:2203] write Test::A
+2008-09-05 18:27:29.118 server[74756:2203] write Test::B
+2008-09-05 18:27:29.118 server[74756:2203] write Test::A
+2008-09-05 18:27:29.118 server[74756:2203] write Test::B
+2008-09-05 18:27:29.119 server[74756:2203] write Test::A
+2008-09-05 18:27:29.119 server[74756:2203] write Test::B
+2008-09-05 18:27:29.119 server[74756:2203] write Test::A
+2008-09-05 18:27:29.120 server[74756:2203] write Test::B
+2008-09-05 18:27:29.120 server[74756:2203] write Test::A
+2008-09-05 18:27:29.120 server[74756:2203] write Test::B
+2008-09-05 18:27:29.121 server[74756:2203] write Test::A
+2008-09-05 18:27:29.121 server[74756:2203] write Test::B
+2008-09-05 18:27:29.122 server[74756:2203] write Test::A
+2008-09-05 18:27:29.122 server[74756:2203] write Test::B
+2008-09-05 18:27:29.122 server[74756:2203] write Test::A
+2008-09-05 18:27:29.123 server[74756:2203] write Test::B
+2008-09-05 18:27:29.123 server[74756:2203] write Test::A
+2008-09-05 18:27:29.123 server[74756:2203] write Test::B
+2008-09-05 18:27:29.124 server[74756:2203] write Test::A
+2008-09-05 18:27:29.124 server[74756:2203] write Test::B
+2008-09-05 18:27:29.124 server[74756:2203] write Test::A
+2008-09-05 18:27:29.125 server[74756:2203] write Test::B
+2008-09-05 18:27:29.125 server[74756:2203] write Test::A
+2008-09-05 18:27:29.126 server[74756:2203] write Test::B
+2008-09-05 18:27:29.126 server[74756:2203] write Test::A
+2008-09-05 18:27:29.126 server[74756:2203] write Test::B
+2008-09-05 18:27:29.127 server[74756:2203] write Test::A
+2008-09-05 18:27:29.127 server[74756:2203] write Test::B
+2008-09-05 18:27:29.127 server[74756:2203] write Test::A
+2008-09-05 18:27:29.128 server[74756:2203] write Test::B
+2008-09-05 18:27:29.128 server[74756:2203] write Test::A
+2008-09-05 18:27:29.128 server[74756:2203] write Test::B
+2008-09-05 18:27:29.129 server[74756:2203] write Test::A
+2008-09-05 18:27:29.129 server[74756:2203] write Test::B
+2008-09-05 18:27:29.130 server[74756:2203] write Test::A
+2008-09-05 18:27:29.130 server[74756:2203] write Test::B
+2008-09-05 18:27:29.130 server[74756:2203] write Test::A
+2008-09-05 18:27:29.131 server[74756:2203] write Test::B
+2008-09-05 18:27:29.131 server[74756:2203] write Test::A
+2008-09-05 18:27:29.131 server[74756:2203] write Test::B
+2008-09-05 18:27:29.132 server[74756:2203] write Test::A
+2008-09-05 18:27:29.132 server[74756:2203] write Test::B
+2008-09-05 18:27:29.133 server[74756:2203] write Test::A
+2008-09-05 18:27:29.133 server[74756:2203] write Test::B
+2008-09-05 18:27:29.133 server[74756:2203] write Test::A
+2008-09-05 18:27:29.134 server[74756:2203] write Test::B
+2008-09-05 18:27:29.134 server[74756:2203] write Test::A
+2008-09-05 18:27:29.134 server[74756:2203] write Test::B
+2008-09-05 18:27:29.135 server[74756:2203] write Test::A
+2008-09-05 18:27:29.135 server[74756:2203] write Test::B
+2008-09-05 18:27:29.135 server[74756:2203] write Test::A
+2008-09-05 18:27:29.136 server[74756:2203] write Test::B
+2008-09-05 18:27:29.136 server[74756:2203] write Test::A
+2008-09-05 18:27:29.137 server[74756:2203] write Test::B
+2008-09-05 18:27:29.137 server[74756:2203] write Test::A
+2008-09-05 18:27:29.137 server[74756:2203] write Test::B
+2008-09-05 18:27:29.138 server[74756:2203] write Test::A
+2008-09-05 18:27:29.138 server[74756:2203] write Test::B
+2008-09-05 18:27:29.138 server[74756:2203] write Test::A
+2008-09-05 18:27:29.139 server[74756:2203] write Test::B
+2008-09-05 18:27:29.139 server[74756:2203] write Test::A
+2008-09-05 18:27:29.140 server[74756:2203] write Test::B
+2008-09-05 18:27:29.140 server[74756:2203] write Test::A
+2008-09-05 18:27:29.140 server[74756:2203] write Test::B
+2008-09-05 18:27:29.141 server[74756:2203] write Test::A
+2008-09-05 18:27:29.141 server[74756:2203] write Test::B
+2008-09-05 18:27:29.142 server[74756:2203] write Test::A
+2008-09-05 18:27:29.142 server[74756:2203] write Test::B
+2008-09-05 18:27:29.142 server[74756:2203] write Test::A
+2008-09-05 18:27:29.143 server[74756:2203] write Test::B
+2008-09-05 18:27:29.143 server[74756:2203] write Test::A
+2008-09-05 18:27:29.144 server[74756:2203] write Test::B
+2008-09-05 18:27:29.144 server[74756:2203] write Test::A
+2008-09-05 18:27:29.144 server[74756:2203] write Test::B
+2008-09-05 18:27:29.145 server[74756:2203] write Test::A
+2008-09-05 18:27:29.145 server[74756:2203] write Test::B
+2008-09-05 18:27:29.145 server[74756:2203] write Test::A
+2008-09-05 18:27:29.146 server[74756:2203] write Test::B
+2008-09-05 18:27:29.146 server[74756:2203] write Test::A
+2008-09-05 18:27:29.147 server[74756:2203] write Test::B
+2008-09-05 18:27:29.147 server[74756:2203] write Test::A
+2008-09-05 18:27:29.147 server[74756:2203] write Test::B
+2008-09-05 18:27:29.148 server[74756:2203] write Test::A
+2008-09-05 18:27:29.148 server[74756:2203] write Test::B
+2008-09-05 18:27:29.148 server[74756:2203] write Test::A
+2008-09-05 18:27:29.149 server[74756:2203] write Test::B
+2008-09-05 18:27:29.149 server[74756:2203] write Test::A
+2008-09-05 18:27:29.150 server[74756:2203] write Test::B
+2008-09-05 18:27:29.150 server[74756:2203] write Test::A
+2008-09-05 18:27:29.150 server[74756:2203] write Test::B
+2008-09-05 18:27:29.151 server[74756:2203] write Test::A
+2008-09-05 18:27:29.151 server[74756:2203] write Test::B
+2008-09-05 18:27:29.151 server[74756:2203] write Test::A
+2008-09-05 18:27:29.152 server[74756:2203] write Test::B
+2008-09-05 18:27:29.152 server[74756:2203] write Test::A
+2008-09-05 18:27:29.152 server[74756:2203] write Test::B
+2008-09-05 18:27:29.153 server[74756:2203] write Test::A
+2008-09-05 18:27:29.153 server[74756:2203] write Test::B
+2008-09-05 18:27:29.153 server[74756:2203] write Test::A
+2008-09-05 18:27:29.154 server[74756:2203] write Test::B
+2008-09-05 18:27:29.154 server[74756:2203] write Test::A
+2008-09-05 18:27:29.155 server[74756:2203] write Test::B
+2008-09-05 18:27:29.155 server[74756:2203] write Test::A
+2008-09-05 18:27:29.155 server[74756:2203] write Test::B
+2008-09-05 18:27:29.156 server[74756:2203] write Test::A
+2008-09-05 18:27:29.156 server[74756:2203] write Test::B
+2008-09-05 18:27:29.156 server[74756:2203] write Test::A
+2008-09-05 18:27:29.157 server[74756:2203] write Test::B
+2008-09-05 18:27:29.157 server[74756:2203] write Test::A
+2008-09-05 18:27:29.157 server[74756:2203] write Test::B
+2008-09-05 18:27:29.158 server[74756:2203] write Test::A
+2008-09-05 18:27:29.158 server[74756:2203] write Test::B
+2008-09-05 18:27:29.159 server[74756:2203] write Test::A
+2008-09-05 18:27:29.159 server[74756:2203] write Test::B
+2008-09-05 18:27:29.159 server[74756:2203] write Test::A
+2008-09-05 18:27:29.160 server[74756:2203] write Test::B
+2008-09-05 18:27:29.160 server[74756:2203] write Test::A
+2008-09-05 18:27:29.160 server[74756:2203] write Test::B
+2008-09-05 18:27:29.161 server[74756:2203] write Test::A
+2008-09-05 18:27:29.161 server[74756:2203] write Test::B
+2008-09-05 18:27:29.162 server[74756:2203] write Test::A
+2008-09-05 18:27:29.162 server[74756:2203] write Test::B
+2008-09-05 18:27:29.162 server[74756:2203] write Test::A
+2008-09-05 18:27:29.163 server[74756:2203] write Test::B
+2008-09-05 18:27:29.163 server[74756:2203] write Test::A
+2008-09-05 18:27:29.164 server[74756:2203] write Test::B
+2008-09-05 18:27:29.165 server[74756:2203] write Test::A
+2008-09-05 18:27:29.165 server[74756:2203] write Test::B
+2008-09-05 18:27:29.166 server[74756:2203] write Test::A
+2008-09-05 18:27:29.166 server[74756:2203] write Test::B
+2008-09-05 18:27:29.166 server[74756:2203] write Test::A
+2008-09-05 18:27:29.167 server[74756:2203] write Test::B
+2008-09-05 18:27:29.167 server[74756:2203] write Test::A
+2008-09-05 18:27:29.168 server[74756:2203] write Test::B
+2008-09-05 18:27:29.170 server[74756:2203] write Test::A
+2008-09-05 18:27:29.170 server[74756:2203] write Test::B
+2008-09-05 18:27:29.170 server[74756:2203] write Test::A
+2008-09-05 18:27:29.171 server[74756:2203] write Test::B
+2008-09-05 18:27:29.171 server[74756:2203] write Test::A
+2008-09-05 18:27:29.171 server[74756:2203] write Test::B
+2008-09-05 18:27:29.172 server[74756:2203] write Test::A
+2008-09-05 18:27:29.172 server[74756:2203] write Test::B
+2008-09-05 18:27:29.173 server[74756:2203] write Test::A
+2008-09-05 18:27:29.173 server[74756:2203] write Test::B
+2008-09-05 18:27:29.173 server[74756:2203] write Test::A
+2008-09-05 18:27:29.174 server[74756:2203] write Test::B
+2008-09-05 18:27:29.174 server[74756:2203] write Test::A
+2008-09-05 18:27:29.174 server[74756:2203] write Test::B
+2008-09-05 18:27:29.175 server[74756:2203] write Test::A
+2008-09-05 18:27:29.175 server[74756:2203] write Test::B
+2008-09-05 18:27:29.176 server[74756:2203] write Test::A
+2008-09-05 18:27:29.176 server[74756:2203] write Test::B
+2008-09-05 18:27:29.176 server[74756:2203] write Test::A
+2008-09-05 18:27:29.177 server[74756:2203] write Test::B
+2008-09-05 18:27:29.177 server[74756:2203] write Test::A
+2008-09-05 18:27:29.178 server[74756:2203] write Test::B
+2008-09-05 18:27:29.178 server[74756:2203] write Test::A
+2008-09-05 18:27:29.178 server[74756:2203] write Test::B
+2008-09-05 18:27:29.179 server[74756:2203] write Test::A
+2008-09-05 18:27:29.179 server[74756:2203] write Test::B
+2008-09-05 18:27:29.179 server[74756:2203] write Test::A
+2008-09-05 18:27:29.180 server[74756:2203] write Test::B
+2008-09-05 18:27:29.180 server[74756:2203] write Test::A
+2008-09-05 18:27:29.181 server[74756:2203] write Test::B
+2008-09-05 18:27:29.181 server[74756:2203] write Test::A
+2008-09-05 18:27:29.181 server[74756:2203] write Test::B
+2008-09-05 18:27:29.182 server[74756:2203] write Test::A
+2008-09-05 18:27:29.182 server[74756:2203] write Test::B
+2008-09-05 18:27:29.182 server[74756:2203] write Test::A
+2008-09-05 18:27:29.183 server[74756:2203] write Test::B
+2008-09-05 18:27:29.183 server[74756:2203] write Test::A
+2008-09-05 18:27:29.184 server[74756:2203] write Test::B
+2008-09-05 18:27:29.184 server[74756:2203] write Test::A
+2008-09-05 18:27:29.184 server[74756:2203] write Test::B
+2008-09-05 18:27:29.185 server[74756:2203] write Test::A
+2008-09-05 18:27:29.185 server[74756:2203] write Test::B
+2008-09-05 18:27:29.186 server[74756:2203] write Test::A
+2008-09-05 18:27:29.186 server[74756:2203] write Test::B
+2008-09-05 18:27:29.186 server[74756:2203] write Test::A
+2008-09-05 18:27:29.187 server[74756:2203] write Test::B
+2008-09-05 18:27:29.187 server[74756:2203] write Test::A
+2008-09-05 18:27:29.187 server[74756:2203] write Test::B
+2008-09-05 18:27:29.188 server[74756:2203] write Test::A
+2008-09-05 18:27:29.188 server[74756:2203] write Test::B
+2008-09-05 18:27:29.189 server[74756:2203] write Test::A
+2008-09-05 18:27:29.189 server[74756:2203] write Test::B
+2008-09-05 18:27:29.189 server[74756:2203] write Test::A
+2008-09-05 18:27:29.190 server[74756:2203] write Test::B
+2008-09-05 18:27:29.190 server[74756:2203] write Test::A
+2008-09-05 18:27:29.191 server[74756:2203] write Test::B
+2008-09-05 18:27:29.191 server[74756:2203] write Test::A
+2008-09-05 18:27:29.191 server[74756:2203] write Test::B
+2008-09-05 18:27:29.192 server[74756:2203] write Test::A
+2008-09-05 18:27:29.192 server[74756:2203] write Test::B
+2008-09-05 18:27:29.192 server[74756:2203] write Test::A
+2008-09-05 18:27:29.193 server[74756:2203] write Test::B
+2008-09-05 18:27:29.193 server[74756:2203] write Test::A
+2008-09-05 18:27:29.194 server[74756:2203] write Test::B
+2008-09-05 18:27:29.194 server[74756:2203] write Test::A
+2008-09-05 18:27:29.194 server[74756:2203] write Test::B
+2008-09-05 18:27:29.195 server[74756:2203] write Test::A
+2008-09-05 18:27:29.196 server[74756:2203] write Test::B
+2008-09-05 18:27:29.197 server[74756:2203] write Test::A
+2008-09-05 18:27:29.198 server[74756:2203] write Test::B
+2008-09-05 18:27:29.198 server[74756:2203] write Test::A
+2008-09-05 18:27:29.199 server[74756:2203] write Test::B
+2008-09-05 18:27:29.199 server[74756:2203] write Test::A
+2008-09-05 18:27:29.199 server[74756:2203] write Test::B
+2008-09-05 18:27:29.200 server[74756:2203] write Test::A
+2008-09-05 18:27:29.200 server[74756:2203] write Test::B
+2008-09-05 18:27:29.200 server[74756:2203] write Test::A
+2008-09-05 18:27:29.201 server[74756:2203] write Test::B
+2008-09-05 18:27:29.201 server[74756:2203] write Test::A
+2008-09-05 18:27:29.202 server[74756:2203] write Test::B
+2008-09-05 18:27:29.202 server[74756:2203] write Test::A
+2008-09-05 18:27:29.202 server[74756:2203] write Test::B
+2008-09-05 18:27:29.203 server[74756:2203] write Test::A
+2008-09-05 18:27:29.203 server[74756:2203] write Test::B
+2008-09-05 18:27:29.204 server[74756:2203] write Test::A
+2008-09-05 18:27:29.204 server[74756:2203] write Test::B
+2008-09-05 18:27:29.204 server[74756:2203] write Test::A
+2008-09-05 18:27:29.205 server[74756:2203] write Test::B
+2008-09-05 18:27:29.205 server[74756:2203] write Test::A
+2008-09-05 18:27:29.205 server[74756:2203] write Test::B
+2008-09-05 18:27:29.206 server[74756:2203] write Test::A
+2008-09-05 18:27:29.206 server[74756:2203] write Test::B
+2008-09-05 18:27:29.207 server[74756:2203] write Test::A
+2008-09-05 18:27:29.207 server[74756:2203] write Test::B
+2008-09-05 18:27:29.207 server[74756:2203] write Test::A
+2008-09-05 18:27:29.208 server[74756:2203] write Test::B
+2008-09-05 18:27:29.208 server[74756:2203] write Test::A
+2008-09-05 18:27:29.209 server[74756:2203] write Test::B
+2008-09-05 18:27:29.209 server[74756:2203] write Test::A
+2008-09-05 18:27:29.209 server[74756:2203] write Test::B
+2008-09-05 18:27:29.210 server[74756:2203] write Test::A
+2008-09-05 18:27:29.210 server[74756:2203] write Test::B
+2008-09-05 18:27:29.211 server[74756:2203] write Test::A
+2008-09-05 18:27:29.211 server[74756:2203] write Test::B
+2008-09-05 18:27:29.212 server[74756:2203] write Test::A
+2008-09-05 18:27:29.213 server[74756:2203] write Test::B
+2008-09-05 18:27:29.213 server[74756:2203] write Test::A
+2008-09-05 18:27:29.214 server[74756:2203] write Test::B
+2008-09-05 18:27:29.214 server[74756:2203] write Test::A
+2008-09-05 18:27:29.215 server[74756:2203] write Test::B
+2008-09-05 18:27:29.215 server[74756:2203] write Test::A
+2008-09-05 18:27:29.216 server[74756:2203] write Test::B
+2008-09-05 18:27:29.216 server[74756:2203] write Test::A
+2008-09-05 18:27:29.216 server[74756:2203] write Test::B
+2008-09-05 18:27:29.217 server[74756:2203] write Test::A
+2008-09-05 18:27:29.217 server[74756:2203] write Test::B
+2008-09-05 18:27:29.217 server[74756:2203] write Test::A
+2008-09-05 18:27:29.218 server[74756:2203] write Test::B
+2008-09-05 18:27:29.218 server[74756:2203] write Test::A
+2008-09-05 18:27:29.219 server[74756:2203] write Test::B
+2008-09-05 18:27:29.219 server[74756:2203] write Test::A
+2008-09-05 18:27:29.219 server[74756:2203] write Test::B
+2008-09-05 18:27:29.220 server[74756:2203] write Test::A
+2008-09-05 18:27:29.220 server[74756:2203] write Test::B
+2008-09-05 18:27:29.221 server[74756:2203] write Test::A
+2008-09-05 18:27:29.221 server[74756:2203] write Test::B
+2008-09-05 18:27:29.221 server[74756:2203] write Test::A
+2008-09-05 18:27:29.222 server[74756:2203] write Test::B
+2008-09-05 18:27:29.222 server[74756:2203] write Test::A
+2008-09-05 18:27:29.222 server[74756:2203] write Test::B
+2008-09-05 18:27:29.223 server[74756:2203] write Test::A
+2008-09-05 18:27:29.223 server[74756:2203] write Test::B
+2008-09-05 18:27:29.224 server[74756:2203] write Test::A
+2008-09-05 18:27:29.224 server[74756:2203] write Test::B
+2008-09-05 18:27:29.224 server[74756:2203] write Test::A
+2008-09-05 18:27:29.225 server[74756:2203] write Test::B
+2008-09-05 18:27:29.225 server[74756:2203] write Test::A
+2008-09-05 18:27:29.226 server[74756:2203] write Test::B
+2008-09-05 18:27:29.226 server[74756:2203] write Test::A
+2008-09-05 18:27:29.226 server[74756:2203] write Test::B
+2008-09-05 18:27:29.227 server[74756:2203] write Test::A
+2008-09-05 18:27:29.227 server[74756:2203] write Test::B
+2008-09-05 18:27:29.228 server[74756:2203] write Test::A
+2008-09-05 18:27:29.228 server[74756:2203] write Test::B
+2008-09-05 18:27:29.228 server[74756:2203] write Test::A
+2008-09-05 18:27:29.229 server[74756:2203] write Test::B
+2008-09-05 18:27:29.229 server[74756:2203] write Test::A
+2008-09-05 18:27:29.230 server[74756:2203] write Test::B
+2008-09-05 18:27:29.230 server[74756:2203] write Test::A
+2008-09-05 18:27:29.230 server[74756:2203] write Test::B
+2008-09-05 18:27:29.231 server[74756:2203] write Test::A
+2008-09-05 18:27:29.233 server[74756:2203] write Test::B
+2008-09-05 18:27:29.233 server[74756:2203] write Test::A
+2008-09-05 18:27:29.233 server[74756:2203] write Test::B
+2008-09-05 18:27:29.234 server[74756:2203] write Test::A
+2008-09-05 18:27:29.234 server[74756:2203] write Test::B
+2008-09-05 18:27:29.235 server[74756:2203] write Test::A
+2008-09-05 18:27:29.235 server[74756:2203] write Test::B
+2008-09-05 18:27:29.235 server[74756:2203] write Test::A
+2008-09-05 18:27:29.236 server[74756:2203] write Test::B
+2008-09-05 18:27:29.236 server[74756:2203] write Test::A
+2008-09-05 18:27:29.236 server[74756:2203] write Test::B
+2008-09-05 18:27:29.237 server[74756:2203] write Test::A
+2008-09-05 18:27:29.237 server[74756:2203] write Test::B
+2008-09-05 18:27:29.238 server[74756:2203] write Test::A
+2008-09-05 18:27:29.238 server[74756:2203] write Test::B
+2008-09-05 18:27:29.238 server[74756:2203] write Test::A
+2008-09-05 18:27:29.239 server[74756:2203] write Test::B
+2008-09-05 18:27:29.239 server[74756:2203] write Test::A
+2008-09-05 18:27:29.239 server[74756:2203] write Test::B
+2008-09-05 18:27:29.240 server[74756:2203] write Test::A
+2008-09-05 18:27:29.240 server[74756:2203] write Test::B
+2008-09-05 18:27:29.240 server[74756:2203] write Test::A
+2008-09-05 18:27:29.241 server[74756:2203] write Test::B
+2008-09-05 18:27:29.241 server[74756:2203] write Test::A
+2008-09-05 18:27:29.241 server[74756:2203] write Test::B
+2008-09-05 18:27:29.242 server[74756:2203] write Test::A
+2008-09-05 18:27:29.242 server[74756:2203] write Test::B
+2008-09-05 18:27:29.242 server[74756:2203] write Test::A
+2008-09-05 18:27:29.243 server[74756:2203] write Test::B
+2008-09-05 18:27:29.243 server[74756:2203] write Test::A
+2008-09-05 18:27:29.244 server[74756:2203] write Test::B
+2008-09-05 18:27:29.244 server[74756:2203] write Test::A
+2008-09-05 18:27:29.244 server[74756:2203] write Test::B
+2008-09-05 18:27:29.245 server[74756:2203] write Test::A
+2008-09-05 18:27:29.245 server[74756:2203] write Test::B
+2008-09-05 18:27:29.246 server[74756:2203] write Test::A
+2008-09-05 18:27:29.246 server[74756:2203] write Test::B
+2008-09-05 18:27:29.246 server[74756:2203] write Test::A
+2008-09-05 18:27:29.247 server[74756:2203] write Test::B
+2008-09-05 18:27:29.247 server[74756:2203] write Test::A
+2008-09-05 18:27:29.247 server[74756:2203] write Test::B
+2008-09-05 18:27:29.248 server[74756:2203] write Test::A
+2008-09-05 18:27:29.248 server[74756:2203] write Test::B
+2008-09-05 18:27:29.249 server[74756:2203] write Test::A
+2008-09-05 18:27:29.249 server[74756:2203] write Test::B
+2008-09-05 18:27:29.249 server[74756:2203] write Test::A
+2008-09-05 18:27:29.250 server[74756:2203] write Test::B
+2008-09-05 18:27:29.250 server[74756:2203] write Test::A
+2008-09-05 18:27:29.250 server[74756:2203] write Test::B
+2008-09-05 18:27:29.251 server[74756:2203] write Test::A
+2008-09-05 18:27:29.251 server[74756:2203] write Test::B
+2008-09-05 18:27:29.252 server[74756:2203] write Test::A
+2008-09-05 18:27:29.252 server[74756:2203] write Test::B
+2008-09-05 18:27:29.252 server[74756:2203] write Test::A
+2008-09-05 18:27:29.253 server[74756:2203] write Test::B
+2008-09-05 18:27:29.253 server[74756:2203] write Test::A
+2008-09-05 18:27:29.254 server[74756:2203] write Test::B
+2008-09-05 18:27:29.255 server[74756:2203] write Test::A
+2008-09-05 18:27:29.255 server[74756:2203] write Test::B
+2008-09-05 18:27:29.255 server[74756:2203] write Test::A
+2008-09-05 18:27:29.256 server[74756:2203] write Test::B
+2008-09-05 18:27:29.256 server[74756:2203] write Test::A
+2008-09-05 18:27:29.257 server[74756:2203] write Test::B
+2008-09-05 18:27:29.257 server[74756:2203] write Test::A
+2008-09-05 18:27:29.257 server[74756:2203] write Test::B
+2008-09-05 18:27:29.258 server[74756:2203] write Test::A
+2008-09-05 18:27:29.258 server[74756:2203] write Test::B
+2008-09-05 18:27:29.259 server[74756:2203] write Test::A
+2008-09-05 18:27:29.259 server[74756:2203] write Test::B
+2008-09-05 18:27:29.259 server[74756:2203] write Test::A
+2008-09-05 18:27:29.260 server[74756:2203] write Test::B
+2008-09-05 18:27:29.260 server[74756:2203] write Test::A
+2008-09-05 18:27:29.261 server[74756:2203] write Test::B
+2008-09-05 18:27:29.261 server[74756:2203] write Test::A
+2008-09-05 18:27:29.261 server[74756:2203] write Test::B
+2008-09-05 18:27:29.262 server[74756:2203] write Test::A
+2008-09-05 18:27:29.262 server[74756:2203] write Test::B
+2008-09-05 18:27:29.263 server[74756:2203] write Test::A
+2008-09-05 18:27:29.263 server[74756:2203] write Test::B
+2008-09-05 18:27:29.264 server[74756:2203] write Test::A
+2008-09-05 18:27:29.264 server[74756:2203] write Test::B
+2008-09-05 18:27:29.265 server[74756:2203] write Test::A
+2008-09-05 18:27:29.265 server[74756:2203] write Test::B
+2008-09-05 18:27:29.265 server[74756:2203] write Test::A
+2008-09-05 18:27:29.266 server[74756:2203] write Test::B
+2008-09-05 18:27:29.266 server[74756:2203] write Test::A
+2008-09-05 18:27:29.267 server[74756:2203] write Test::B
+2008-09-05 18:27:29.267 server[74756:2203] write Test::A
+2008-09-05 18:27:29.268 server[74756:2203] write Test::B
+2008-09-05 18:27:29.268 server[74756:2203] write Test::A
+2008-09-05 18:27:29.268 server[74756:2203] write Test::B
+2008-09-05 18:27:29.269 server[74756:2203] write Test::A
+2008-09-05 18:27:29.270 server[74756:2203] write Test::B
+2008-09-05 18:27:29.270 server[74756:2203] write Test::A
+2008-09-05 18:27:29.271 server[74756:2203] write Test::B
+2008-09-05 18:27:29.271 server[74756:2203] write Test::A
+2008-09-05 18:27:29.271 server[74756:2203] write Test::B
+2008-09-05 18:27:29.272 server[74756:2203] write Test::A
+2008-09-05 18:27:29.272 server[74756:2203] write Test::B
+2008-09-05 18:27:29.273 server[74756:2203] write Test::A
+2008-09-05 18:27:29.273 server[74756:2203] write Test::B
+2008-09-05 18:27:29.273 server[74756:2203] write Test::A
+2008-09-05 18:27:29.274 server[74756:2203] write Test::B
+2008-09-05 18:27:29.274 server[74756:2203] write Test::A
+2008-09-05 18:27:29.275 server[74756:2203] write Test::B
+2008-09-05 18:27:29.275 server[74756:2203] write Test::A
+2008-09-05 18:27:29.275 server[74756:2203] write Test::B
+2008-09-05 18:27:29.276 server[74756:2203] write Test::A
+2008-09-05 18:27:29.276 server[74756:2203] write Test::B
+2008-09-05 18:27:29.277 server[74756:2203] write Test::A
+2008-09-05 18:27:29.277 server[74756:2203] write Test::B
+2008-09-05 18:27:29.278 server[74756:2203] write Test::A
+2008-09-05 18:27:29.278 server[74756:2203] write Test::B
+2008-09-05 18:27:29.278 server[74756:2203] write Test::A
+2008-09-05 18:27:29.279 server[74756:2203] write Test::B
+2008-09-05 18:27:29.279 server[74756:2203] write Test::A
+2008-09-05 18:27:29.281 server[74756:2203] write Test::B
+2008-09-05 18:27:29.282 server[74756:2203] write Test::A
+2008-09-05 18:27:29.283 server[74756:2203] write Test::B
+2008-09-05 18:27:29.283 server[74756:2203] write Test::A
+2008-09-05 18:27:29.283 server[74756:2203] write Test::B
+2008-09-05 18:27:29.284 server[74756:2203] write Test::A
+2008-09-05 18:27:29.284 server[74756:2203] write Test::B
+2008-09-05 18:27:29.285 server[74756:2203] write Test::A
+2008-09-05 18:27:29.285 server[74756:2203] write Test::B
+2008-09-05 18:27:29.286 server[74756:2203] write Test::A
+2008-09-05 18:27:29.286 server[74756:2203] write Test::B
+2008-09-05 18:27:29.286 server[74756:2203] write Test::A
+2008-09-05 18:27:29.287 server[74756:2203] write Test::B
+2008-09-05 18:27:29.287 server[74756:2203] write Test::A
+2008-09-05 18:27:29.288 server[74756:2203] write Test::B
+2008-09-05 18:27:29.288 server[74756:2203] write Test::A
+2008-09-05 18:27:29.288 server[74756:2203] write Test::B
+2008-09-05 18:27:29.289 server[74756:2203] write Test::A
+2008-09-05 18:27:29.289 server[74756:2203] write Test::B
+2008-09-05 18:27:29.290 server[74756:2203] write Test::A
+2008-09-05 18:27:29.291 server[74756:2203] write Test::B
+2008-09-05 18:27:29.291 server[74756:2203] write Test::A
+2008-09-05 18:27:29.291 server[74756:2203] write Test::B
+2008-09-05 18:27:29.292 server[74756:2203] write Test::A
+2008-09-05 18:27:29.292 server[74756:2203] write Test::B
+2008-09-05 18:27:29.293 server[74756:2203] write Test::A
+2008-09-05 18:27:29.293 server[74756:2203] write Test::B
+2008-09-05 18:27:29.293 server[74756:2203] write Test::A
+2008-09-05 18:27:29.295 server[74756:2203] write Test::B
+2008-09-05 18:27:29.295 server[74756:2203] write Test::A
+2008-09-05 18:27:29.295 server[74756:2203] write Test::B
+2008-09-05 18:27:29.296 server[74756:2203] write Test::A
+2008-09-05 18:27:29.299 server[74756:2203] write Test::B
+2008-09-05 18:27:29.299 server[74756:2203] write Test::A
+2008-09-05 18:27:29.300 server[74756:2203] write Test::B
+2008-09-05 18:27:29.300 server[74756:2203] write Test::A
+2008-09-05 18:27:29.300 server[74756:2203] write Test::B
+2008-09-05 18:27:29.301 server[74756:2203] write Test::A
+2008-09-05 18:27:29.301 server[74756:2203] write Test::B
+2008-09-05 18:27:29.301 server[74756:2203] write Test::A
+2008-09-05 18:27:29.302 server[74756:2203] write Test::B
+2008-09-05 18:27:29.302 server[74756:2203] write Test::A
+2008-09-05 18:27:29.302 server[74756:2203] write Test::B
+2008-09-05 18:27:29.303 server[74756:2203] write Test::A
+2008-09-05 18:27:29.303 server[74756:2203] write Test::B
+2008-09-05 18:27:29.303 server[74756:2203] write Test::A
+2008-09-05 18:27:29.304 server[74756:2203] write Test::B
+2008-09-05 18:27:29.304 server[74756:2203] write Test::A
+2008-09-05 18:27:29.305 server[74756:2203] write Test::B
+2008-09-05 18:27:29.305 server[74756:2203] write Test::A
+2008-09-05 18:27:29.305 server[74756:2203] write Test::B
+2008-09-05 18:27:29.306 server[74756:2203] write Test::A
+2008-09-05 18:27:29.306 server[74756:2203] write Test::B
+2008-09-05 18:27:29.306 server[74756:2203] write Test::A
+2008-09-05 18:27:29.307 server[74756:2203] write Test::B
+2008-09-05 18:27:29.307 server[74756:2203] write Test::A
+2008-09-05 18:27:29.307 server[74756:2203] write Test::B
+2008-09-05 18:27:29.308 server[74756:2203] write Test::A
+2008-09-05 18:27:29.308 server[74756:2203] write Test::B
+2008-09-05 18:27:29.308 server[74756:2203] write Test::A
+2008-09-05 18:27:29.309 server[74756:2203] write Test::B
+2008-09-05 18:27:29.309 server[74756:2203] write Test::A
+2008-09-05 18:27:29.309 server[74756:2203] write Test::B
+2008-09-05 18:27:29.310 server[74756:2203] write Test::A
+2008-09-05 18:27:29.311 server[74756:2203] write Test::B
+2008-09-05 18:27:29.311 server[74756:2203] write Test::A
+2008-09-05 18:27:29.311 server[74756:2203] write Test::B
+2008-09-05 18:27:29.312 server[74756:2203] write Test::A
+2008-09-05 18:27:29.312 server[74756:2203] write Test::B
+2008-09-05 18:27:29.312 server[74756:2203] write Test::A
+2008-09-05 18:27:29.313 server[74756:2203] write Test::B
+2008-09-05 18:27:29.313 server[74756:2203] write Test::A
+2008-09-05 18:27:29.314 server[74756:2203] write Test::B
+2008-09-05 18:27:29.314 server[74756:2203] write Test::A
+2008-09-05 18:27:29.314 server[74756:2203] write Test::B
+2008-09-05 18:27:29.315 server[74756:2203] write Test::A
+2008-09-05 18:27:29.315 server[74756:2203] write Test::B
+2008-09-05 18:27:29.315 server[74756:2203] write Test::A
+2008-09-05 18:27:29.316 server[74756:2203] write Test::B
+2008-09-05 18:27:29.316 server[74756:2203] write Test::A
+2008-09-05 18:27:29.316 server[74756:2203] write Test::B
+2008-09-05 18:27:29.317 server[74756:2203] write Test::A
+2008-09-05 18:27:29.317 server[74756:2203] write Test::B
+2008-09-05 18:27:29.317 server[74756:2203] write Test::A
+2008-09-05 18:27:29.318 server[74756:2203] write Test::B
+2008-09-05 18:27:29.318 server[74756:2203] write Test::A
+2008-09-05 18:27:29.318 server[74756:2203] write Test::B
+2008-09-05 18:27:29.319 server[74756:2203] write Test::A
+2008-09-05 18:27:29.319 server[74756:2203] write Test::B
+2008-09-05 18:27:29.320 server[74756:2203] write Test::A
+2008-09-05 18:27:29.320 server[74756:2203] write Test::B
+2008-09-05 18:27:29.320 server[74756:2203] write Test::A
+2008-09-05 18:27:29.321 server[74756:2203] write Test::B
+2008-09-05 18:27:29.321 server[74756:2203] write Test::A
+2008-09-05 18:27:29.321 server[74756:2203] write Test::B
+2008-09-05 18:27:29.322 server[74756:2203] write Test::A
+2008-09-05 18:27:29.322 server[74756:2203] write Test::B
+2008-09-05 18:27:29.322 server[74756:2203] write Test::A
+2008-09-05 18:27:29.323 server[74756:2203] write Test::B
+2008-09-05 18:27:29.323 server[74756:2203] write Test::A
+2008-09-05 18:27:29.323 server[74756:2203] write Test::B
+2008-09-05 18:27:29.324 server[74756:2203] write Test::A
+2008-09-05 18:27:29.324 server[74756:2203] write Test::B
+2008-09-05 18:27:29.324 server[74756:2203] write Test::A
+2008-09-05 18:27:29.325 server[74756:2203] write Test::B
+2008-09-05 18:27:29.325 server[74756:2203] write Test::A
+2008-09-05 18:27:29.326 server[74756:2203] write Test::B
+2008-09-05 18:27:29.326 server[74756:2203] write Test::A
+2008-09-05 18:27:29.326 server[74756:2203] write Test::B
+2008-09-05 18:27:29.327 server[74756:2203] write Test::A
+2008-09-05 18:27:29.327 server[74756:2203] write Test::B
+2008-09-05 18:27:29.327 server[74756:2203] write Test::A
+2008-09-05 18:27:29.328 server[74756:2203] write Test::B
+2008-09-05 18:27:29.328 server[74756:2203] write Test::A
+2008-09-05 18:27:29.328 server[74756:2203] write Test::B
+2008-09-05 18:27:29.329 server[74756:2203] write Test::A
+2008-09-05 18:27:29.329 server[74756:2203] write Test::B
+2008-09-05 18:27:29.329 server[74756:2203] write Test::A
+2008-09-05 18:27:29.330 server[74756:2203] write Test::B
+2008-09-05 18:27:29.330 server[74756:2203] write Test::A
+2008-09-05 18:27:29.331 server[74756:2203] write Test::B
+2008-09-05 18:27:29.331 server[74756:2203] write Test::A
+2008-09-05 18:27:29.331 server[74756:2203] write Test::B
+2008-09-05 18:27:29.332 server[74756:2203] write Test::A
+2008-09-05 18:27:29.332 server[74756:2203] write Test::B
+2008-09-05 18:27:29.332 server[74756:2203] write Test::A
+2008-09-05 18:27:29.333 server[74756:2203] write Test::B
+2008-09-05 18:27:29.333 server[74756:2203] write Test::A
+2008-09-05 18:27:29.333 server[74756:2203] write Test::B
+2008-09-05 18:27:29.334 server[74756:2203] write Test::A
+2008-09-05 18:27:29.334 server[74756:2203] write Test::B
+2008-09-05 18:27:29.334 server[74756:2203] write Test::A
+2008-09-05 18:27:29.335 server[74756:2203] write Test::B
+2008-09-05 18:27:29.335 server[74756:2203] write Test::A
+2008-09-05 18:27:29.336 server[74756:2203] write Test::B
+2008-09-05 18:27:29.336 server[74756:2203] write Test::A
+2008-09-05 18:27:29.336 server[74756:2203] write Test::B
+2008-09-05 18:27:29.338 server[74756:2203] write Test::A
+2008-09-05 18:27:29.339 server[74756:2203] write Test::B
+2008-09-05 18:27:29.339 server[74756:2203] write Test::A
+2008-09-05 18:27:29.339 server[74756:2203] write Test::B
+2008-09-05 18:27:29.340 server[74756:2203] write Test::A
+2008-09-05 18:27:29.340 server[74756:2203] write Test::B
+2008-09-05 18:27:29.341 server[74756:2203] write Test::A
+2008-09-05 18:27:29.341 server[74756:2203] write Test::B
+2008-09-05 18:27:29.341 server[74756:2203] write Test::A
+2008-09-05 18:27:29.342 server[74756:2203] write Test::B
+2008-09-05 18:27:29.342 server[74756:2203] write Test::A
+2008-09-05 18:27:29.343 server[74756:2203] write Test::B
+2008-09-05 18:27:29.343 server[74756:2203] write Test::A
+2008-09-05 18:27:29.343 server[74756:2203] write Test::B
+2008-09-05 18:27:29.344 server[74756:2203] write Test::A
+2008-09-05 18:27:29.344 server[74756:2203] write Test::B
+2008-09-05 18:27:29.344 server[74756:2203] write Test::A
+2008-09-05 18:27:29.345 server[74756:2203] write Test::B
+2008-09-05 18:27:29.345 server[74756:2203] write Test::A
+2008-09-05 18:27:29.346 server[74756:2203] write Test::B
+2008-09-05 18:27:29.346 server[74756:2203] write Test::A
+2008-09-05 18:27:29.346 server[74756:2203] write Test::B
+2008-09-05 18:27:29.347 server[74756:2203] write Test::A
+2008-09-05 18:27:29.347 server[74756:2203] write Test::B
+2008-09-05 18:27:29.348 server[74756:2203] write Test::A
+2008-09-05 18:27:29.348 server[74756:2203] write Test::B
+2008-09-05 18:27:29.348 server[74756:2203] write Test::A
+2008-09-05 18:27:29.349 server[74756:2203] write Test::B
+2008-09-05 18:27:29.349 server[74756:2203] write Test::A
+2008-09-05 18:27:29.350 server[74756:2203] write Test::B
+2008-09-05 18:27:29.350 server[74756:2203] write Test::A
+2008-09-05 18:27:29.350 server[74756:2203] write Test::B
+2008-09-05 18:27:29.351 server[74756:2203] write Test::A
+2008-09-05 18:27:29.351 server[74756:2203] write Test::B
+2008-09-05 18:27:29.352 server[74756:2203] write Test::A
+2008-09-05 18:27:29.352 server[74756:2203] write Test::B
+2008-09-05 18:27:29.352 server[74756:2203] write Test::A
+2008-09-05 18:27:29.353 server[74756:2203] write Test::B
+2008-09-05 18:27:29.353 server[74756:2203] write Test::A
+2008-09-05 18:27:29.354 server[74756:2203] write Test::B
+2008-09-05 18:27:29.354 server[74756:2203] write Test::A
+2008-09-05 18:27:29.354 server[74756:2203] write Test::B
+2008-09-05 18:27:29.355 server[74756:2203] write Test::A
+2008-09-05 18:27:29.355 server[74756:2203] write Test::B
+2008-09-05 18:27:29.355 server[74756:2203] write Test::A
+2008-09-05 18:27:29.356 server[74756:2203] write Test::B
+2008-09-05 18:27:29.356 server[74756:2203] write Test::A
+2008-09-05 18:27:29.357 server[74756:2203] write Test::B
+2008-09-05 18:27:29.357 server[74756:2203] write Test::A
+2008-09-05 18:27:29.357 server[74756:2203] write Test::B
+2008-09-05 18:27:29.358 server[74756:2203] write Test::A
+2008-09-05 18:27:29.359 server[74756:2203] write Test::B
+2008-09-05 18:27:29.359 server[74756:2203] write Test::A
+2008-09-05 18:27:29.359 server[74756:2203] write Test::B
+2008-09-05 18:27:29.360 server[74756:2203] write Test::A
+2008-09-05 18:27:29.360 server[74756:2203] write Test::B
+2008-09-05 18:27:29.361 server[74756:2203] write Test::A
+2008-09-05 18:27:29.362 server[74756:2203] write Test::B
+2008-09-05 18:27:29.362 server[74756:2203] write Test::A
+2008-09-05 18:27:29.362 server[74756:2203] write Test::B
+2008-09-05 18:27:29.363 server[74756:2203] write Test::A
+2008-09-05 18:27:29.363 server[74756:2203] write Test::B
+2008-09-05 18:27:29.364 server[74756:2203] write Test::A
+2008-09-05 18:27:29.364 server[74756:2203] write Test::B
+2008-09-05 18:27:29.364 server[74756:2203] write Test::A
+2008-09-05 18:27:29.366 server[74756:2203] write Test::B
+2008-09-05 18:27:29.366 server[74756:2203] write Test::A
+2008-09-05 18:27:29.367 server[74756:2203] write Test::B
+2008-09-05 18:27:29.367 server[74756:2203] write Test::A
+2008-09-05 18:27:29.368 server[74756:2203] write Test::B
+2008-09-05 18:27:29.368 server[74756:2203] write Test::A
+2008-09-05 18:27:29.368 server[74756:2203] write Test::B
+2008-09-05 18:27:29.369 server[74756:2203] write Test::A
+2008-09-05 18:27:29.369 server[74756:2203] write Test::B
+2008-09-05 18:27:29.370 server[74756:2203] write Test::A
+2008-09-05 18:27:29.370 server[74756:2203] write Test::B
+2008-09-05 18:27:29.370 server[74756:2203] write Test::A
+2008-09-05 18:27:29.371 server[74756:2203] write Test::B
+2008-09-05 18:27:29.371 server[74756:2203] write Test::A
+2008-09-05 18:27:29.371 server[74756:2203] write Test::B
+2008-09-05 18:27:29.372 server[74756:2203] write Test::A
+2008-09-05 18:27:29.372 server[74756:2203] write Test::B
+2008-09-05 18:27:29.373 server[74756:2203] write Test::A
+2008-09-05 18:27:29.373 server[74756:2203] write Test::B
+2008-09-05 18:27:29.373 server[74756:2203] write Test::A
+2008-09-05 18:27:29.374 server[74756:2203] write Test::B
+2008-09-05 18:27:29.374 server[74756:2203] write Test::A
+2008-09-05 18:27:29.375 server[74756:2203] write Test::B
+2008-09-05 18:27:29.375 server[74756:2203] write Test::A
+2008-09-05 18:27:29.375 server[74756:2203] write Test::B
+2008-09-05 18:27:29.376 server[74756:2203] write Test::A
+2008-09-05 18:27:29.376 server[74756:2203] write Test::B
+2008-09-05 18:27:29.377 server[74756:2203] write Test::A
+2008-09-05 18:27:29.377 server[74756:2203] write Test::B
+2008-09-05 18:27:29.377 server[74756:2203] write Test::A
+2008-09-05 18:27:29.378 server[74756:2203] write Test::B
+2008-09-05 18:27:29.378 server[74756:2203] write Test::A
+2008-09-05 18:27:29.379 server[74756:2203] write Test::B
+2008-09-05 18:27:29.379 server[74756:2203] write Test::A
+2008-09-05 18:27:29.379 server[74756:2203] write Test::B
+2008-09-05 18:27:29.380 server[74756:2203] write Test::A
+2008-09-05 18:27:29.380 server[74756:2203] write Test::B
+2008-09-05 18:27:29.381 server[74756:2203] write Test::A
+2008-09-05 18:27:29.381 server[74756:2203] write Test::B
+2008-09-05 18:27:29.381 server[74756:2203] write Test::A
+2008-09-05 18:27:29.382 server[74756:2203] write Test::B
+2008-09-05 18:27:29.382 server[74756:2203] write Test::A
+2008-09-05 18:27:29.382 server[74756:2203] write Test::B
+2008-09-05 18:27:29.383 server[74756:2203] write Test::A
+2008-09-05 18:27:29.383 server[74756:2203] write Test::B
+2008-09-05 18:27:29.384 server[74756:2203] write Test::A
+2008-09-05 18:27:29.384 server[74756:2203] write Test::B
+2008-09-05 18:27:29.384 server[74756:2203] write Test::A
+2008-09-05 18:27:29.385 server[74756:2203] write Test::B
+2008-09-05 18:27:29.385 server[74756:2203] write Test::A
+2008-09-05 18:27:29.386 server[74756:2203] write Test::B
+2008-09-05 18:27:29.386 server[74756:2203] write Test::A
+2008-09-05 18:27:29.386 server[74756:2203] write Test::B
+2008-09-05 18:27:29.387 server[74756:2203] write Test::A
+2008-09-05 18:27:29.388 server[74756:2203] write Test::B
+2008-09-05 18:27:29.388 server[74756:2203] write Test::A
+2008-09-05 18:27:29.388 server[74756:2203] write Test::B
+2008-09-05 18:27:29.389 server[74756:2203] write Test::A
+2008-09-05 18:27:29.389 server[74756:2203] write Test::B
+2008-09-05 18:27:29.389 server[74756:2203] write Test::A
+2008-09-05 18:27:29.390 server[74756:2203] write Test::B
+2008-09-05 18:27:29.390 server[74756:2203] write Test::A
+2008-09-05 18:27:29.391 server[74756:2203] write Test::B
+2008-09-05 18:27:29.391 server[74756:2203] write Test::A
+2008-09-05 18:27:29.391 server[74756:2203] write Test::B
+2008-09-05 18:27:29.392 server[74756:2203] write Test::A
+2008-09-05 18:27:29.392 server[74756:2203] write Test::B
+2008-09-05 18:27:29.393 server[74756:2203] write Test::A
+2008-09-05 18:27:29.393 server[74756:2203] write Test::B
+2008-09-05 18:27:29.393 server[74756:2203] write Test::A
+2008-09-05 18:27:29.394 server[74756:2203] write Test::B
+2008-09-05 18:27:29.394 server[74756:2203] write Test::A
+2008-09-05 18:27:29.395 server[74756:2203] write Test::B
+2008-09-05 18:27:29.395 server[74756:2203] write Test::A
+2008-09-05 18:27:29.395 server[74756:2203] write Test::B
+2008-09-05 18:27:29.396 server[74756:2203] write Test::A
+2008-09-05 18:27:29.396 server[74756:2203] write Test::B
+2008-09-05 18:27:29.396 server[74756:2203] write Test::A
+2008-09-05 18:27:29.397 server[74756:2203] write Test::B
+2008-09-05 18:27:29.397 server[74756:2203] write Test::A
+2008-09-05 18:27:29.398 server[74756:2203] write Test::B
+2008-09-05 18:27:29.398 server[74756:2203] write Test::A
+2008-09-05 18:27:29.398 server[74756:2203] write Test::B
+2008-09-05 18:27:29.399 server[74756:2203] write Test::A
+2008-09-05 18:27:29.399 server[74756:2203] write Test::B
+2008-09-05 18:27:29.399 server[74756:2203] write Test::A
+2008-09-05 18:27:29.400 server[74756:2203] write Test::B
+2008-09-05 18:27:29.400 server[74756:2203] write Test::A
+2008-09-05 18:27:29.401 server[74756:2203] write Test::B
+2008-09-05 18:27:29.401 server[74756:2203] write Test::A
+2008-09-05 18:27:29.401 server[74756:2203] write Test::B
+2008-09-05 18:27:29.402 server[74756:2203] write Test::A
+2008-09-05 18:27:29.402 server[74756:2203] write Test::B
+2008-09-05 18:27:29.402 server[74756:2203] write Test::A
+2008-09-05 18:27:29.403 server[74756:2203] write Test::B
+2008-09-05 18:27:29.403 server[74756:2203] write Test::A
+2008-09-05 18:27:29.403 server[74756:2203] write Test::B
+2008-09-05 18:27:29.404 server[74756:2203] write Test::A
+2008-09-05 18:27:29.404 server[74756:2203] write Test::B
+2008-09-05 18:27:29.405 server[74756:2203] write Test::A
+2008-09-05 18:27:29.405 server[74756:2203] write Test::B
+2008-09-05 18:27:29.405 server[74756:2203] write Test::A
+2008-09-05 18:27:29.406 server[74756:2203] write Test::B
+2008-09-05 18:27:29.406 server[74756:2203] write Test::A
+2008-09-05 18:27:29.406 server[74756:2203] write Test::B
+2008-09-05 18:27:29.407 server[74756:2203] write Test::A
+2008-09-05 18:27:29.408 server[74756:2203] write Test::B
+2008-09-05 18:27:29.408 server[74756:2203] write Test::A
+2008-09-05 18:27:29.409 server[74756:2203] write Test::B
+2008-09-05 18:27:29.409 server[74756:2203] write Test::A
+2008-09-05 18:27:29.409 server[74756:2203] write Test::B
+2008-09-05 18:27:29.410 server[74756:2203] write Test::A
+2008-09-05 18:27:29.410 server[74756:2203] write Test::B
+2008-09-05 18:27:29.411 server[74756:2203] write Test::A
+2008-09-05 18:27:29.411 server[74756:2203] write Test::B
+2008-09-05 18:27:29.411 server[74756:2203] write Test::A
+2008-09-05 18:27:29.412 server[74756:2203] write Test::B
+2008-09-05 18:27:29.412 server[74756:2203] write Test::A
+2008-09-05 18:27:29.413 server[74756:2203] write Test::B
+2008-09-05 18:27:29.413 server[74756:2203] write Test::A
+2008-09-05 18:27:29.413 server[74756:2203] write Test::B
+2008-09-05 18:27:29.414 server[74756:2203] write Test::A
+2008-09-05 18:27:29.414 server[74756:2203] write Test::B
+2008-09-05 18:27:29.415 server[74756:2203] write Test::A
+2008-09-05 18:27:29.415 server[74756:2203] write Test::B
+2008-09-05 18:27:29.415 server[74756:2203] write Test::A
+2008-09-05 18:27:29.416 server[74756:2203] write Test::B
+2008-09-05 18:27:29.416 server[74756:2203] write Test::A
+2008-09-05 18:27:29.416 server[74756:2203] write Test::B
+2008-09-05 18:27:29.417 server[74756:2203] write Test::A
+2008-09-05 18:27:29.417 server[74756:2203] write Test::B
+2008-09-05 18:27:29.418 server[74756:2203] write Test::A
+2008-09-05 18:27:29.418 server[74756:2203] write Test::B
+2008-09-05 18:27:29.418 server[74756:2203] write Test::A
+2008-09-05 18:27:29.419 server[74756:2203] write Test::B
+2008-09-05 18:27:29.419 server[74756:2203] write Test::A
+2008-09-05 18:27:29.419 server[74756:2203] write Test::B
+2008-09-05 18:27:29.420 server[74756:2203] write Test::A
+2008-09-05 18:27:29.420 server[74756:2203] write Test::B
+2008-09-05 18:27:29.420 server[74756:2203] write Test::A
+2008-09-05 18:27:29.421 server[74756:2203] write Test::B
+2008-09-05 18:27:29.421 server[74756:2203] write Test::A
+2008-09-05 18:27:29.421 server[74756:2203] write Test::B
+2008-09-05 18:27:29.422 server[74756:2203] write Test::A
+2008-09-05 18:27:29.422 server[74756:2203] write Test::B
+2008-09-05 18:27:29.423 server[74756:2203] write Test::A
+2008-09-05 18:27:29.423 server[74756:2203] write Test::B
+2008-09-05 18:27:29.423 server[74756:2203] write Test::A
+2008-09-05 18:27:29.424 server[74756:2203] write Test::B
+2008-09-05 18:27:29.424 server[74756:2203] write Test::A
+2008-09-05 18:27:29.424 server[74756:2203] write Test::B
+2008-09-05 18:27:29.425 server[74756:2203] write Test::A
+2008-09-05 18:27:29.425 server[74756:2203] write Test::B
+2008-09-05 18:27:29.425 server[74756:2203] write Test::A
+2008-09-05 18:27:29.426 server[74756:2203] write Test::B
+2008-09-05 18:27:29.426 server[74756:2203] write Test::A
+2008-09-05 18:27:29.427 server[74756:2203] write Test::B
+2008-09-05 18:27:29.427 server[74756:2203] write Test::A
+2008-09-05 18:27:29.427 server[74756:2203] write Test::B
+2008-09-05 18:27:29.428 server[74756:2203] write Test::A
+2008-09-05 18:27:29.428 server[74756:2203] write Test::B
+2008-09-05 18:27:29.428 server[74756:2203] write Test::A
+2008-09-05 18:27:29.429 server[74756:2203] write Test::B
+2008-09-05 18:27:29.429 server[74756:2203] write Test::A
+2008-09-05 18:27:29.430 server[74756:2203] write Test::B
+2008-09-05 18:27:29.430 server[74756:2203] write Test::A
+2008-09-05 18:27:29.431 server[74756:2203] write Test::B
+2008-09-05 18:27:29.431 server[74756:2203] write Test::A
+2008-09-05 18:27:29.431 server[74756:2203] write Test::B
+2008-09-05 18:27:29.432 server[74756:2203] write Test::A
+2008-09-05 18:27:29.432 server[74756:2203] write Test::B
+2008-09-05 18:27:29.432 server[74756:2203] write Test::A
+2008-09-05 18:27:29.433 server[74756:2203] write Test::B
+2008-09-05 18:27:29.433 server[74756:2203] write Test::A
+2008-09-05 18:27:29.433 server[74756:2203] write Test::B
+2008-09-05 18:27:29.434 server[74756:2203] write Test::A
+2008-09-05 18:27:29.434 server[74756:2203] write Test::B
+2008-09-05 18:27:29.434 server[74756:2203] write Test::A
+2008-09-05 18:27:29.435 server[74756:2203] write Test::B
+2008-09-05 18:27:29.435 server[74756:2203] write Test::A
+2008-09-05 18:27:29.436 server[74756:2203] write Test::B
+2008-09-05 18:27:29.436 server[74756:2203] write Test::A
+2008-09-05 18:27:29.436 server[74756:2203] write Test::B
+2008-09-05 18:27:29.437 server[74756:2203] write Test::A
+2008-09-05 18:27:29.437 server[74756:2203] write Test::B
+2008-09-05 18:27:29.438 server[74756:2203] write Test::A
+2008-09-05 18:27:29.438 server[74756:2203] write Test::B
+2008-09-05 18:27:29.438 server[74756:2203] write Test::A
+2008-09-05 18:27:29.439 server[74756:2203] write Test::B
+2008-09-05 18:27:29.439 server[74756:2203] write Test::A
+2008-09-05 18:27:29.439 server[74756:2203] write Test::B
+2008-09-05 18:27:29.440 server[74756:2203] write Test::A
+2008-09-05 18:27:29.440 server[74756:2203] write Test::B
+2008-09-05 18:27:29.441 server[74756:2203] write Test::A
+2008-09-05 18:27:29.441 server[74756:2203] write Test::B
+2008-09-05 18:27:29.441 server[74756:2203] write Test::A
+2008-09-05 18:27:29.442 server[74756:2203] write Test::B
+2008-09-05 18:27:29.442 server[74756:2203] write Test::A
+2008-09-05 18:27:29.442 server[74756:2203] write Test::B
+2008-09-05 18:27:29.443 server[74756:2203] write Test::A
+2008-09-05 18:27:29.443 server[74756:2203] write Test::B
+2008-09-05 18:27:29.443 server[74756:2203] write Test::A
+2008-09-05 18:27:29.444 server[74756:2203] write Test::B
+2008-09-05 18:27:29.444 server[74756:2203] write Test::A
+2008-09-05 18:27:29.445 server[74756:2203] write Test::B
+2008-09-05 18:27:29.445 server[74756:2203] write Test::A
+2008-09-05 18:27:29.445 server[74756:2203] write Test::B
+2008-09-05 18:27:29.446 server[74756:2203] write Test::A
+2008-09-05 18:27:29.446 server[74756:2203] write Test::B
+2008-09-05 18:27:29.446 server[74756:2203] write Test::A
+2008-09-05 18:27:29.447 server[74756:2203] write Test::B
+2008-09-05 18:27:29.447 server[74756:2203] write Test::A
+2008-09-05 18:27:29.448 server[74756:2203] write Test::B
+2008-09-05 18:27:29.448 server[74756:2203] write Test::A
+2008-09-05 18:27:29.448 server[74756:2203] write Test::B
+2008-09-05 18:27:29.449 server[74756:2203] write Test::A
+2008-09-05 18:27:29.449 server[74756:2203] write Test::B
+2008-09-05 18:27:29.449 server[74756:2203] write Test::A
+2008-09-05 18:27:29.450 server[74756:2203] write Test::B
+2008-09-05 18:27:29.450 server[74756:2203] write Test::A
+2008-09-05 18:27:29.450 server[74756:2203] write Test::B
+2008-09-05 18:27:29.451 server[74756:2203] write Test::A
+2008-09-05 18:27:29.451 server[74756:2203] write Test::B
+2008-09-05 18:27:29.452 server[74756:2203] write Test::A
+2008-09-05 18:27:29.452 server[74756:2203] write Test::B
+2008-09-05 18:27:29.452 server[74756:2203] write Test::A
+2008-09-05 18:27:29.453 server[74756:2203] write Test::B
+2008-09-05 18:27:29.453 server[74756:2203] write Test::A
+2008-09-05 18:27:29.453 server[74756:2203] write Test::B
+2008-09-05 18:27:29.454 server[74756:2203] write Test::A
+2008-09-05 18:27:29.454 server[74756:2203] write Test::B
+2008-09-05 18:27:29.454 server[74756:2203] write Test::A
+2008-09-05 18:27:29.455 server[74756:2203] write Test::B
+2008-09-05 18:27:29.455 server[74756:2203] write Test::A
+2008-09-05 18:27:29.456 server[74756:2203] write Test::B
+2008-09-05 18:27:29.456 server[74756:2203] write Test::A
+2008-09-05 18:27:29.457 server[74756:2203] write Test::B
+2008-09-05 18:27:29.457 server[74756:2203] write Test::A
+2008-09-05 18:27:29.457 server[74756:2203] write Test::B
+2008-09-05 18:27:29.458 server[74756:2203] write Test::A
+2008-09-05 18:27:29.458 server[74756:2203] write Test::B
+2008-09-05 18:27:29.460 server[74756:2203] write Test::A
+2008-09-05 18:27:29.460 server[74756:2203] write Test::B
+2008-09-05 18:27:29.461 server[74756:2203] write Test::A
+2008-09-05 18:27:29.461 server[74756:2203] write Test::B
+2008-09-05 18:27:29.462 server[74756:2203] write Test::A
+2008-09-05 18:27:29.462 server[74756:2203] write Test::B
+2008-09-05 18:27:29.462 server[74756:2203] write Test::A
+2008-09-05 18:27:29.463 server[74756:2203] write Test::B
+2008-09-05 18:27:29.463 server[74756:2203] write Test::A
+2008-09-05 18:27:29.463 server[74756:2203] write Test::B
+2008-09-05 18:27:29.464 server[74756:2203] write Test::A
+2008-09-05 18:27:29.464 server[74756:2203] write Test::B
+2008-09-05 18:27:29.465 server[74756:2203] write Test::A
+2008-09-05 18:27:29.465 server[74756:2203] write Test::B
+2008-09-05 18:27:29.465 server[74756:2203] write Test::A
+2008-09-05 18:27:29.466 server[74756:2203] write Test::B
+2008-09-05 18:27:29.466 server[74756:2203] write Test::A
+2008-09-05 18:27:29.467 server[74756:2203] write Test::B
+2008-09-05 18:27:29.467 server[74756:2203] write Test::A
+2008-09-05 18:27:29.467 server[74756:2203] write Test::B
+2008-09-05 18:27:29.468 server[74756:2203] write Test::A
+2008-09-05 18:27:29.468 server[74756:2203] write Test::B
+2008-09-05 18:27:29.468 server[74756:2203] write Test::A
+2008-09-05 18:27:29.469 server[74756:2203] write Test::B
+2008-09-05 18:27:29.469 server[74756:2203] write Test::A
+2008-09-05 18:27:29.470 server[74756:2203] write Test::B
+2008-09-05 18:27:29.470 server[74756:2203] write Test::A
+2008-09-05 18:27:29.470 server[74756:2203] write Test::B
+2008-09-05 18:27:29.471 server[74756:2203] write Test::A
+2008-09-05 18:27:29.471 server[74756:2203] write Test::B
+2008-09-05 18:27:29.472 server[74756:2203] write Test::A
+2008-09-05 18:27:29.472 server[74756:2203] write Test::B
+2008-09-05 18:27:29.472 server[74756:2203] write Test::A
+2008-09-05 18:27:29.473 server[74756:2203] write Test::B
+2008-09-05 18:27:29.473 server[74756:2203] write Test::A
+2008-09-05 18:27:29.473 server[74756:2203] write Test::B
+2008-09-05 18:27:29.474 server[74756:2203] write Test::A
+2008-09-05 18:27:29.474 server[74756:2203] write Test::B
+2008-09-05 18:27:29.475 server[74756:2203] write Test::A
+2008-09-05 18:27:29.475 server[74756:2203] write Test::B
+2008-09-05 18:27:29.475 server[74756:2203] write Test::A
+2008-09-05 18:27:29.476 server[74756:2203] write Test::B
+2008-09-05 18:27:29.476 server[74756:2203] write Test::A
+2008-09-05 18:27:29.476 server[74756:2203] write Test::B
+2008-09-05 18:27:29.477 server[74756:2203] write Test::A
+2008-09-05 18:27:29.477 server[74756:2203] write Test::B
+2008-09-05 18:27:29.478 server[74756:2203] write Test::A
+2008-09-05 18:27:29.478 server[74756:2203] write Test::B
+2008-09-05 18:27:29.479 server[74756:2203] write Test::A
+2008-09-05 18:27:29.479 server[74756:2203] write Test::B
+2008-09-05 18:27:29.479 server[74756:2203] write Test::A
+2008-09-05 18:27:29.480 server[74756:2203] write Test::B
+2008-09-05 18:27:29.480 server[74756:2203] write Test::A
+2008-09-05 18:27:29.480 server[74756:2203] write Test::B
+2008-09-05 18:27:29.481 server[74756:2203] write Test::A
+2008-09-05 18:27:29.481 server[74756:2203] write Test::B
+2008-09-05 18:27:29.482 server[74756:2203] write Test::A
+2008-09-05 18:27:29.482 server[74756:2203] write Test::B
+2008-09-05 18:27:29.482 server[74756:2203] write Test::A
+2008-09-05 18:27:29.483 server[74756:2203] write Test::B
+2008-09-05 18:27:29.483 server[74756:2203] write Test::A
+2008-09-05 18:27:29.483 server[74756:2203] write Test::B
+2008-09-05 18:27:29.484 server[74756:2203] write Test::A
+2008-09-05 18:27:29.484 server[74756:2203] write Test::B
+2008-09-05 18:27:29.485 server[74756:2203] write Test::A
+2008-09-05 18:27:29.485 server[74756:2203] write Test::B
+2008-09-05 18:27:29.485 server[74756:2203] write Test::A
+2008-09-05 18:27:29.486 server[74756:2203] write Test::B
+2008-09-05 18:27:29.486 server[74756:2203] write Test::A
+2008-09-05 18:27:29.486 server[74756:2203] write Test::B
+2008-09-05 18:27:29.487 server[74756:2203] write Test::A
+2008-09-05 18:27:29.487 server[74756:2203] write Test::B
+2008-09-05 18:27:29.488 server[74756:2203] write Test::A
+2008-09-05 18:27:29.488 server[74756:2203] write Test::B
+2008-09-05 18:27:29.488 server[74756:2203] write Test::A
+2008-09-05 18:27:29.489 server[74756:2203] write Test::B
+2008-09-05 18:27:29.489 server[74756:2203] write Test::A
+2008-09-05 18:27:29.490 server[74756:2203] write Test::B
+2008-09-05 18:27:29.491 server[74756:2203] write Test::A
+2008-09-05 18:27:29.491 server[74756:2203] write Test::B
+2008-09-05 18:27:29.491 server[74756:2203] write Test::A
+2008-09-05 18:27:29.492 server[74756:2203] write Test::B
+2008-09-05 18:27:29.492 server[74756:2203] write Test::A
+2008-09-05 18:27:29.492 server[74756:2203] write Test::B
+2008-09-05 18:27:29.493 server[74756:2203] write Test::A
+2008-09-05 18:27:29.493 server[74756:2203] write Test::B
+2008-09-05 18:27:29.494 server[74756:2203] write Test::A
+2008-09-05 18:27:29.494 server[74756:2203] write Test::B
+2008-09-05 18:27:29.494 server[74756:2203] write Test::A
+2008-09-05 18:27:29.495 server[74756:2203] write Test::B
+2008-09-05 18:27:29.495 server[74756:2203] write Test::A
+2008-09-05 18:27:29.496 server[74756:2203] write Test::B
+2008-09-05 18:27:29.496 server[74756:2203] write Test::A
+2008-09-05 18:27:29.496 server[74756:2203] write Test::B
+2008-09-05 18:27:29.497 server[74756:2203] write Test::A
+2008-09-05 18:27:29.497 server[74756:2203] write Test::B
+2008-09-05 18:27:29.497 server[74756:2203] write Test::A
+2008-09-05 18:27:29.498 server[74756:2203] write Test::B
+2008-09-05 18:27:29.498 server[74756:2203] write Test::A
+2008-09-05 18:27:29.499 server[74756:2203] write Test::B
+2008-09-05 18:27:29.499 server[74756:2203] write Test::A
+2008-09-05 18:27:29.499 server[74756:2203] write Test::B
+2008-09-05 18:27:29.500 server[74756:2203] write Test::A
+2008-09-05 18:27:29.500 server[74756:2203] write Test::B
+2008-09-05 18:27:29.501 server[74756:2203] write Test::A
+2008-09-05 18:27:29.501 server[74756:2203] write Test::B
+2008-09-05 18:27:29.501 server[74756:2203] write Test::A
+2008-09-05 18:27:29.502 server[74756:2203] write Test::B
+2008-09-05 18:27:29.502 server[74756:2203] write Test::A
+2008-09-05 18:27:29.502 server[74756:2203] write Test::B
+2008-09-05 18:27:29.503 server[74756:2203] write Test::A
+2008-09-05 18:27:29.503 server[74756:2203] write Test::B
+2008-09-05 18:27:29.504 server[74756:2203] write Test::A
+2008-09-05 18:27:29.504 server[74756:2203] write Test::B
+2008-09-05 18:27:29.504 server[74756:2203] write Test::A
+2008-09-05 18:27:29.505 server[74756:2203] write Test::B
+2008-09-05 18:27:29.505 server[74756:2203] write Test::A
+2008-09-05 18:27:29.505 server[74756:2203] write Test::B
+2008-09-05 18:27:29.506 server[74756:2203] write Test::A
+2008-09-05 18:27:29.506 server[74756:2203] write Test::B
+2008-09-05 18:27:29.507 server[74756:2203] write Test::A
+2008-09-05 18:27:29.507 server[74756:2203] write Test::B
+2008-09-05 18:27:29.507 server[74756:2203] write Test::A
+2008-09-05 18:27:29.509 server[74756:2203] write Test::B
+2008-09-05 18:27:29.511 server[74756:2203] write Test::A
+2008-09-05 18:27:29.512 server[74756:2203] write Test::B
+2008-09-05 18:27:29.512 server[74756:2203] write Test::A
+2008-09-05 18:27:29.513 server[74756:2203] write Test::B
+2008-09-05 18:27:29.513 server[74756:2203] write Test::A
+2008-09-05 18:27:29.516 server[74756:2203] write Test::B
+2008-09-05 18:27:29.518 server[74756:2203] write Test::A
+2008-09-05 18:27:29.520 server[74756:2203] write Test::B
+2008-09-05 18:27:29.523 server[74756:2203] write Test::A
+2008-09-05 18:27:29.524 server[74756:2203] write Test::B
+2008-09-05 18:27:29.526 server[74756:2203] write Test::A
+2008-09-05 18:27:29.528 server[74756:2203] write Test::B
+2008-09-05 18:27:29.528 server[74756:2203] write Test::A
+2008-09-05 18:27:29.530 server[74756:2203] write Test::B
+2008-09-05 18:27:29.530 server[74756:2203] write Test::A
+2008-09-05 18:27:29.531 server[74756:2203] write Test::B
+2008-09-05 18:27:29.531 server[74756:2203] write Test::A
+2008-09-05 18:27:29.532 server[74756:2203] write Test::B
+2008-09-05 18:27:29.532 server[74756:2203] write Test::A
+2008-09-05 18:27:29.533 server[74756:2203] write Test::B
+2008-09-05 18:27:29.534 server[74756:2203] write Test::A
+2008-09-05 18:27:29.535 server[74756:2203] write Test::B
+2008-09-05 18:27:29.538 server[74756:2203] write Test::A
+2008-09-05 18:27:29.540 server[74756:2203] write Test::B
+2008-09-05 18:27:29.540 server[74756:2203] write Test::A
+2008-09-05 18:27:29.540 server[74756:2203] write Test::B
+2008-09-05 18:27:29.541 server[74756:2203] write Test::A
+2008-09-05 18:27:29.541 server[74756:2203] write Test::B
+2008-09-05 18:27:29.541 server[74756:2203] write Test::A
+2008-09-05 18:27:29.542 server[74756:2203] write Test::B
+2008-09-05 18:27:29.543 server[74756:2203] write Test::A
+2008-09-05 18:27:29.544 server[74756:2203] write Test::B
+2008-09-05 18:27:29.544 server[74756:2203] write Test::A
+2008-09-05 18:27:29.546 server[74756:2203] write Test::B
+2008-09-05 18:27:29.546 server[74756:2203] write Test::A
+2008-09-05 18:27:29.548 server[74756:2203] write Test::B
+2008-09-05 18:27:29.549 server[74756:2203] write Test::A
+2008-09-05 18:27:29.549 server[74756:2203] write Test::B
+2008-09-05 18:27:29.549 server[74756:2203] write Test::A
+2008-09-05 18:27:29.550 server[74756:2203] write Test::B
+2008-09-05 18:27:29.550 server[74756:2203] write Test::A
+2008-09-05 18:27:29.551 server[74756:2203] write Test::B
+2008-09-05 18:27:29.551 server[74756:2203] write Test::A
+2008-09-05 18:27:29.552 server[74756:2203] write Test::B
+2008-09-05 18:27:29.553 server[74756:2203] write Test::A
+2008-09-05 18:27:29.553 server[74756:2203] write Test::B
+2008-09-05 18:27:29.554 server[74756:2203] write Test::A
+2008-09-05 18:27:29.555 server[74756:2203] write Test::B
+2008-09-05 18:27:29.556 server[74756:2203] write Test::A
+2008-09-05 18:27:29.558 server[74756:2203] write Test::B
+2008-09-05 18:27:29.558 server[74756:2203] write Test::A
+2008-09-05 18:27:29.558 server[74756:2203] write Test::B
+2008-09-05 18:27:29.559 server[74756:2203] write Test::A
+2008-09-05 18:27:29.559 server[74756:2203] write Test::B
+2008-09-05 18:27:29.560 server[74756:2203] write Test::A
+2008-09-05 18:27:29.562 server[74756:2203] write Test::B
+2008-09-05 18:27:29.562 server[74756:2203] write Test::A
+2008-09-05 18:27:29.563 server[74756:2203] write Test::B
+2008-09-05 18:27:29.563 server[74756:2203] write Test::A
+2008-09-05 18:27:29.564 server[74756:2203] write Test::B
+2008-09-05 18:27:29.564 server[74756:2203] write Test::A
+2008-09-05 18:27:29.565 server[74756:2203] write Test::B
+2008-09-05 18:27:29.566 server[74756:2203] write Test::A
+2008-09-05 18:27:29.567 server[74756:2203] write Test::B
+2008-09-05 18:27:29.567 server[74756:2203] write Test::A
+2008-09-05 18:27:29.568 server[74756:2203] write Test::B
+2008-09-05 18:27:29.570 server[74756:2203] write Test::A
+2008-09-05 18:27:29.570 server[74756:2203] write Test::B
+2008-09-05 18:27:29.571 server[74756:2203] write Test::A
+2008-09-05 18:27:29.571 server[74756:2203] write Test::B
+2008-09-05 18:27:29.571 server[74756:2203] write Test::A
+2008-09-05 18:27:29.572 server[74756:2203] write Test::B
+2008-09-05 18:27:29.573 server[74756:2203] write Test::A
+2008-09-05 18:27:29.573 server[74756:2203] write Test::B
+2008-09-05 18:27:29.573 server[74756:2203] write Test::A
+2008-09-05 18:27:29.574 server[74756:2203] write Test::B
+2008-09-05 18:27:29.574 server[74756:2203] write Test::A
+2008-09-05 18:27:29.575 server[74756:2203] write Test::B
+2008-09-05 18:27:29.576 server[74756:2203] write Test::A
+2008-09-05 18:27:29.576 server[74756:2203] write Test::B
+2008-09-05 18:27:29.577 server[74756:2203] write Test::A
+2008-09-05 18:27:29.578 server[74756:2203] write Test::B
+2008-09-05 18:27:29.578 server[74756:2203] write Test::A
+2008-09-05 18:27:29.579 server[74756:2203] write Test::B
+2008-09-05 18:27:29.580 server[74756:2203] write Test::A
+2008-09-05 18:27:29.581 server[74756:2203] write Test::B
+2008-09-05 18:27:29.581 server[74756:2203] write Test::A
+2008-09-05 18:27:29.582 server[74756:2203] write Test::B
+2008-09-05 18:27:29.582 server[74756:2203] write Test::A
+2008-09-05 18:27:29.583 server[74756:2203] write Test::B
+2008-09-05 18:27:29.583 server[74756:2203] write Test::A
+2008-09-05 18:27:29.584 server[74756:2203] write Test::B
+2008-09-05 18:27:29.584 server[74756:2203] write Test::A
+2008-09-05 18:27:29.585 server[74756:2203] write Test::B
+2008-09-05 18:27:29.585 server[74756:2203] write Test::A
+2008-09-05 18:27:29.586 server[74756:2203] write Test::B
+2008-09-05 18:27:29.587 server[74756:2203] write Test::A
+2008-09-05 18:27:29.587 server[74756:2203] write Test::B
+2008-09-05 18:27:29.588 server[74756:2203] write Test::A
+2008-09-05 18:27:29.588 server[74756:2203] write Test::B
+2008-09-05 18:27:29.589 server[74756:2203] write Test::A
+2008-09-05 18:27:29.589 server[74756:2203] write Test::B
+2008-09-05 18:27:29.590 server[74756:2203] write Test::A
+2008-09-05 18:27:29.590 server[74756:2203] write Test::B
+2008-09-05 18:27:29.591 server[74756:2203] write Test::A
+2008-09-05 18:27:29.591 server[74756:2203] write Test::B
+2008-09-05 18:27:29.592 server[74756:2203] write Test::A
+2008-09-05 18:27:29.592 server[74756:2203] write Test::B
+2008-09-05 18:27:29.593 server[74756:2203] write Test::A
+2008-09-05 18:27:29.593 server[74756:2203] write Test::B
+2008-09-05 18:27:29.594 server[74756:2203] write Test::A
+2008-09-05 18:27:29.594 server[74756:2203] write Test::B
+2008-09-05 18:27:29.595 server[74756:2203] write Test::A
+2008-09-05 18:27:29.595 server[74756:2203] write Test::B
+2008-09-05 18:27:29.596 server[74756:2203] write Test::A
+2008-09-05 18:27:29.596 server[74756:2203] write Test::B
+2008-09-05 18:27:29.597 server[74756:2203] write Test::A
+2008-09-05 18:27:29.597 server[74756:2203] write Test::B
+2008-09-05 18:27:29.598 server[74756:2203] write Test::A
+2008-09-05 18:27:29.598 server[74756:2203] write Test::B
+2008-09-05 18:27:29.599 server[74756:2203] write Test::A
+2008-09-05 18:27:29.599 server[74756:2203] write Test::B
+2008-09-05 18:27:29.600 server[74756:2203] write Test::A
+2008-09-05 18:27:29.600 server[74756:2203] write Test::B
+2008-09-05 18:27:29.601 server[74756:2203] write Test::A
+2008-09-05 18:27:29.601 server[74756:2203] write Test::B
+2008-09-05 18:27:29.602 server[74756:2203] write Test::A
+2008-09-05 18:27:29.602 server[74756:2203] write Test::B
+2008-09-05 18:27:29.603 server[74756:2203] write Test::A
+2008-09-05 18:27:29.603 server[74756:2203] write Test::B
+2008-09-05 18:27:29.604 server[74756:2203] write Test::A
+2008-09-05 18:27:29.604 server[74756:2203] write Test::B
+2008-09-05 18:27:29.605 server[74756:2203] write Test::A
+2008-09-05 18:27:29.605 server[74756:2203] write Test::B
+2008-09-05 18:27:29.606 server[74756:2203] write Test::A
+2008-09-05 18:27:29.607 server[74756:2203] write Test::B
+2008-09-05 18:27:29.607 server[74756:2203] write Test::A
+2008-09-05 18:27:29.608 server[74756:2203] write Test::B
+2008-09-05 18:27:29.608 server[74756:2203] write Test::A
+2008-09-05 18:27:29.609 server[74756:2203] write Test::B
+2008-09-05 18:27:29.609 server[74756:2203] write Test::A
+2008-09-05 18:27:29.610 server[74756:2203] write Test::B
+2008-09-05 18:27:29.611 server[74756:2203] write Test::A
+2008-09-05 18:27:29.611 server[74756:2203] write Test::B
+2008-09-05 18:27:29.612 server[74756:2203] write Test::A
+2008-09-05 18:27:29.612 server[74756:2203] write Test::B
+2008-09-05 18:27:29.613 server[74756:2203] write Test::A
+2008-09-05 18:27:29.613 server[74756:2203] write Test::B
+2008-09-05 18:27:29.614 server[74756:2203] write Test::A
+2008-09-05 18:27:29.614 server[74756:2203] write Test::B
+2008-09-05 18:27:29.615 server[74756:2203] write Test::A
+2008-09-05 18:27:29.615 server[74756:2203] write Test::B
+2008-09-05 18:27:29.616 server[74756:2203] write Test::A
+2008-09-05 18:27:29.616 server[74756:2203] write Test::B
+2008-09-05 18:27:29.617 server[74756:2203] write Test::A
+2008-09-05 18:27:29.617 server[74756:2203] write Test::B
+2008-09-05 18:27:29.618 server[74756:2203] write Test::A
+2008-09-05 18:27:29.618 server[74756:2203] write Test::B
+2008-09-05 18:27:29.619 server[74756:2203] write Test::A
+2008-09-05 18:27:29.619 server[74756:2203] write Test::B
+2008-09-05 18:27:29.620 server[74756:2203] write Test::A
+2008-09-05 18:27:29.620 server[74756:2203] write Test::B
+2008-09-05 18:27:29.621 server[74756:2203] write Test::A
+2008-09-05 18:27:29.621 server[74756:2203] write Test::B
+2008-09-05 18:27:29.622 server[74756:2203] write Test::A
+2008-09-05 18:27:29.622 server[74756:2203] write Test::B
+2008-09-05 18:27:29.623 server[74756:2203] write Test::A
+2008-09-05 18:27:29.623 server[74756:2203] write Test::B
+2008-09-05 18:27:29.624 server[74756:2203] write Test::A
+2008-09-05 18:27:29.624 server[74756:2203] write Test::B
+2008-09-05 18:27:29.625 server[74756:2203] write Test::A
+2008-09-05 18:27:29.625 server[74756:2203] write Test::B
+2008-09-05 18:27:29.626 server[74756:2203] write Test::A
+2008-09-05 18:27:29.626 server[74756:2203] write Test::B
+2008-09-05 18:27:29.627 server[74756:2203] write Test::A
+2008-09-05 18:27:29.627 server[74756:2203] write Test::B
+2008-09-05 18:27:29.628 server[74756:2203] write Test::A
+2008-09-05 18:27:29.628 server[74756:2203] write Test::B
+2008-09-05 18:27:29.629 server[74756:2203] write Test::A
+2008-09-05 18:27:29.629 server[74756:2203] write Test::B
+2008-09-05 18:27:29.630 server[74756:2203] write Test::A
+2008-09-05 18:27:29.630 server[74756:2203] write Test::B
+2008-09-05 18:27:29.631 server[74756:2203] write Test::A
+2008-09-05 18:27:29.631 server[74756:2203] write Test::B
+2008-09-05 18:27:29.632 server[74756:2203] write Test::A
+2008-09-05 18:27:29.632 server[74756:2203] write Test::B
+2008-09-05 18:27:29.633 server[74756:2203] write Test::A
+2008-09-05 18:27:29.633 server[74756:2203] write Test::B
+2008-09-05 18:27:29.634 server[74756:2203] write Test::A
+2008-09-05 18:27:29.635 server[74756:2203] write Test::B
+2008-09-05 18:27:29.635 server[74756:2203] write Test::A
+2008-09-05 18:27:29.636 server[74756:2203] write Test::B
+2008-09-05 18:27:29.636 server[74756:2203] write Test::A
+2008-09-05 18:27:29.637 server[74756:2203] write Test::B
+2008-09-05 18:27:29.637 server[74756:2203] write Test::A
+2008-09-05 18:27:29.638 server[74756:2203] write Test::B
+2008-09-05 18:27:29.638 server[74756:2203] write Test::A
+2008-09-05 18:27:29.639 server[74756:2203] write Test::B
+2008-09-05 18:27:29.639 server[74756:2203] write Test::A
+2008-09-05 18:27:29.640 server[74756:2203] write Test::B
+2008-09-05 18:27:29.640 server[74756:2203] write Test::A
+2008-09-05 18:27:29.641 server[74756:2203] write Test::B
+2008-09-05 18:27:29.641 server[74756:2203] write Test::A
+2008-09-05 18:27:29.642 server[74756:2203] write Test::B
+2008-09-05 18:27:29.642 server[74756:2203] write Test::A
+2008-09-05 18:27:29.642 server[74756:2203] write Test::B
+2008-09-05 18:27:29.643 server[74756:2203] write Test::A
+2008-09-05 18:27:29.645 server[74756:2203] write Test::B
+2008-09-05 18:27:29.645 server[74756:2203] write Test::A
+2008-09-05 18:27:29.646 server[74756:2203] write Test::B
+2008-09-05 18:27:29.646 server[74756:2203] write Test::A
+2008-09-05 18:27:29.647 server[74756:2203] write Test::B
+2008-09-05 18:27:29.647 server[74756:2203] write Test::A
+2008-09-05 18:27:29.648 server[74756:2203] write Test::B
+2008-09-05 18:27:29.648 server[74756:2203] write Test::A
+2008-09-05 18:27:29.649 server[74756:2203] write Test::B
+2008-09-05 18:27:29.649 server[74756:2203] write Test::A
+2008-09-05 18:27:29.650 server[74756:2203] write Test::B
+2008-09-05 18:27:29.650 server[74756:2203] write Test::A
+2008-09-05 18:27:29.651 server[74756:2203] write Test::B
+2008-09-05 18:27:29.651 server[74756:2203] write Test::A
+2008-09-05 18:27:29.651 server[74756:2203] write Test::B
+2008-09-05 18:27:29.652 server[74756:2203] write Test::A
+2008-09-05 18:27:29.652 server[74756:2203] write Test::B
+2008-09-05 18:27:29.653 server[74756:2203] write Test::A
+2008-09-05 18:27:29.653 server[74756:2203] write Test::B
+2008-09-05 18:27:29.654 server[74756:2203] write Test::A
+2008-09-05 18:27:29.654 server[74756:2203] write Test::B
+2008-09-05 18:27:29.655 server[74756:2203] write Test::A
+2008-09-05 18:27:29.655 server[74756:2203] write Test::B
+2008-09-05 18:27:29.656 server[74756:2203] write Test::A
+2008-09-05 18:27:29.656 server[74756:2203] write Test::B
+2008-09-05 18:27:29.657 server[74756:2203] write Test::A
+2008-09-05 18:27:29.657 server[74756:2203] write Test::B
+2008-09-05 18:27:29.658 server[74756:2203] write Test::A
+2008-09-05 18:27:29.658 server[74756:2203] write Test::B
+2008-09-05 18:27:29.659 server[74756:2203] write Test::A
+2008-09-05 18:27:29.659 server[74756:2203] write Test::B
+2008-09-05 18:27:29.660 server[74756:2203] write Test::A
+2008-09-05 18:27:29.660 server[74756:2203] write Test::B
+2008-09-05 18:27:29.661 server[74756:2203] write Test::A
+2008-09-05 18:27:29.661 server[74756:2203] write Test::B
+2008-09-05 18:27:29.662 server[74756:2203] write Test::A
+2008-09-05 18:27:29.662 server[74756:2203] write Test::B
+2008-09-05 18:27:29.663 server[74756:2203] write Test::A
+2008-09-05 18:27:29.663 server[74756:2203] write Test::B
+2008-09-05 18:27:29.664 server[74756:2203] write Test::A
+2008-09-05 18:27:29.664 server[74756:2203] write Test::B
+2008-09-05 18:27:29.664 server[74756:2203] write Test::A
+2008-09-05 18:27:29.665 server[74756:2203] write Test::B
+2008-09-05 18:27:29.665 server[74756:2203] write Test::A
+2008-09-05 18:27:29.666 server[74756:2203] write Test::B
+2008-09-05 18:27:29.666 server[74756:2203] write Test::A
+2008-09-05 18:27:29.667 server[74756:2203] write Test::B
+2008-09-05 18:27:29.667 server[74756:2203] write Test::A
+2008-09-05 18:27:29.668 server[74756:2203] write Test::B
+2008-09-05 18:27:29.668 server[74756:2203] write Test::A
+2008-09-05 18:27:29.669 server[74756:2203] write Test::B
+2008-09-05 18:27:29.669 server[74756:2203] write Test::A
+2008-09-05 18:27:29.670 server[74756:2203] write Test::B
+2008-09-05 18:27:29.670 server[74756:2203] write Test::A
+2008-09-05 18:27:29.671 server[74756:2203] write Test::B
+2008-09-05 18:27:29.671 server[74756:2203] write Test::A
+2008-09-05 18:27:29.672 server[74756:2203] write Test::B
+2008-09-05 18:27:29.672 server[74756:2203] write Test::A
+2008-09-05 18:27:29.673 server[74756:2203] write Test::B
+2008-09-05 18:27:29.673 server[74756:2203] write Test::A
+2008-09-05 18:27:29.674 server[74756:2203] write Test::B
+2008-09-05 18:27:29.674 server[74756:2203] write Test::A
+2008-09-05 18:27:29.675 server[74756:2203] write Test::B
+2008-09-05 18:27:29.675 server[74756:2203] write Test::A
+2008-09-05 18:27:29.675 server[74756:2203] write Test::B
+2008-09-05 18:27:29.676 server[74756:2203] write Test::A
+2008-09-05 18:27:29.676 server[74756:2203] write Test::B
+2008-09-05 18:27:29.677 server[74756:2203] write Test::A
+2008-09-05 18:27:29.677 server[74756:2203] write Test::B
+2008-09-05 18:27:29.678 server[74756:2203] write Test::A
+2008-09-05 18:27:29.678 server[74756:2203] write Test::B
+2008-09-05 18:27:29.679 server[74756:2203] write Test::A
+2008-09-05 18:27:29.680 server[74756:2203] write Test::B
+2008-09-05 18:27:29.680 server[74756:2203] write Test::A
+2008-09-05 18:27:29.681 server[74756:2203] write Test::B
+2008-09-05 18:27:29.681 server[74756:2203] write Test::A
+2008-09-05 18:27:29.682 server[74756:2203] write Test::B
+2008-09-05 18:27:29.682 server[74756:2203] write Test::A
+2008-09-05 18:27:29.683 server[74756:2203] write Test::B
+2008-09-05 18:27:29.683 server[74756:2203] write Test::A
+2008-09-05 18:27:29.684 server[74756:2203] write Test::B
+2008-09-05 18:27:29.684 server[74756:2203] write Test::A
+2008-09-05 18:27:29.685 server[74756:2203] write Test::B
+2008-09-05 18:27:29.685 server[74756:2203] write Test::A
+2008-09-05 18:27:29.686 server[74756:2203] write Test::B
+2008-09-05 18:27:29.686 server[74756:2203] write Test::A
+2008-09-05 18:27:29.687 server[74756:2203] write Test::B
+2008-09-05 18:27:29.688 server[74756:2203] write Test::A
+2008-09-05 18:27:29.688 server[74756:2203] write Test::B
+2008-09-05 18:27:29.689 server[74756:2203] write Test::A
+2008-09-05 18:27:29.689 server[74756:2203] write Test::B
+2008-09-05 18:27:29.690 server[74756:2203] write Test::A
+2008-09-05 18:27:29.690 server[74756:2203] write Test::B
+2008-09-05 18:27:29.691 server[74756:2203] write Test::A
+2008-09-05 18:27:29.691 server[74756:2203] write Test::B
+2008-09-05 18:27:29.692 server[74756:2203] write Test::A
+2008-09-05 18:27:29.693 server[74756:2203] write Test::B
+2008-09-05 18:27:29.693 server[74756:2203] write Test::A
+2008-09-05 18:27:29.694 server[74756:2203] write Test::B
+2008-09-05 18:27:29.694 server[74756:2203] write Test::A
+2008-09-05 18:27:29.695 server[74756:2203] write Test::B
+2008-09-05 18:27:29.695 server[74756:2203] write Test::A
+2008-09-05 18:27:29.696 server[74756:2203] write Test::B
+2008-09-05 18:27:29.696 server[74756:2203] write Test::A
+2008-09-05 18:27:29.697 server[74756:2203] write Test::B
+2008-09-05 18:27:29.697 server[74756:2203] write Test::A
+2008-09-05 18:27:29.698 server[74756:2203] write Test::B
+2008-09-05 18:27:29.698 server[74756:2203] write Test::A
+2008-09-05 18:27:29.699 server[74756:2203] write Test::B
+2008-09-05 18:27:29.699 server[74756:2203] write Test::A
+2008-09-05 18:27:29.700 server[74756:2203] write Test::B
+2008-09-05 18:27:29.700 server[74756:2203] write Test::A
+2008-09-05 18:27:29.701 server[74756:2203] write Test::B
+2008-09-05 18:27:29.701 server[74756:2203] write Test::A
+2008-09-05 18:27:29.702 server[74756:2203] write Test::B
+2008-09-05 18:27:29.702 server[74756:2203] write Test::A
+2008-09-05 18:27:29.702 server[74756:2203] write Test::B
+2008-09-05 18:27:29.703 server[74756:2203] write Test::A
+2008-09-05 18:27:29.703 server[74756:2203] write Test::B
+2008-09-05 18:27:29.704 server[74756:2203] write Test::A
+2008-09-05 18:27:29.704 server[74756:2203] write Test::B
+2008-09-05 18:27:29.705 server[74756:2203] write Test::A
+2008-09-05 18:27:29.705 server[74756:2203] write Test::B
+2008-09-05 18:27:29.706 server[74756:2203] write Test::A
+2008-09-05 18:27:29.706 server[74756:2203] write Test::B
+2008-09-05 18:27:29.707 server[74756:2203] write Test::A
+2008-09-05 18:27:29.707 server[74756:2203] write Test::B
+2008-09-05 18:27:29.708 server[74756:2203] write Test::A
+2008-09-05 18:27:29.708 server[74756:2203] write Test::B
+2008-09-05 18:27:29.709 server[74756:2203] write Test::A
+2008-09-05 18:27:29.709 server[74756:2203] write Test::B
+2008-09-05 18:27:29.710 server[74756:2203] write Test::A
+2008-09-05 18:27:29.710 server[74756:2203] write Test::B
+2008-09-05 18:27:29.711 server[74756:2203] write Test::A
+2008-09-05 18:27:29.711 server[74756:2203] write Test::B
+2008-09-05 18:27:29.712 server[74756:2203] write Test::A
+2008-09-05 18:27:29.712 server[74756:2203] write Test::B
+2008-09-05 18:27:29.712 server[74756:2203] write Test::A
+2008-09-05 18:27:29.713 server[74756:2203] write Test::B
+2008-09-05 18:27:29.713 server[74756:2203] write Test::A
+2008-09-05 18:27:29.714 server[74756:2203] write Test::B
+2008-09-05 18:27:29.714 server[74756:2203] write Test::A
+2008-09-05 18:27:29.715 server[74756:2203] write Test::B
+2008-09-05 18:27:29.715 server[74756:2203] write Test::A
+2008-09-05 18:27:29.716 server[74756:2203] write Test::B
+2008-09-05 18:27:29.716 server[74756:2203] write Test::A
+2008-09-05 18:27:29.717 server[74756:2203] write Test::B
+2008-09-05 18:27:29.717 server[74756:2203] write Test::A
+2008-09-05 18:27:29.718 server[74756:2203] write Test::B
+2008-09-05 18:27:29.718 server[74756:2203] write Test::A
+2008-09-05 18:27:29.719 server[74756:2203] write Test::B
+2008-09-05 18:27:29.719 server[74756:2203] write Test::A
+2008-09-05 18:27:29.720 server[74756:2203] write Test::B
+2008-09-05 18:27:29.721 server[74756:2203] write Test::A
+2008-09-05 18:27:29.721 server[74756:2203] write Test::B
+2008-09-05 18:27:29.722 server[74756:2203] write Test::A
+Traceback (most recent call last):
+ File "./run.py", line 26, in <module>
+ TestUtil.clientServerTest(name)
+ File "../../../../config/TestUtil.py", line 1067, in clientServerTest
+ clientServerTestWithOptions(name, "", "")
+ File "../../../../config/TestUtil.py", line 1063, in clientServerTestWithOptions
+ getDefaultClientFile())
+ File "../../../../config/TestUtil.py", line 1044, in clientServerTestWithOptionsAndNames
+ printOutputFromPipe(clientPipe)
+ File "../../../../config/TestUtil.py", line 657, in printOutputFromPipe
+ c = pipe.read(1)
+KeyboardInterrupt
+2008-09-05 18:27:29.722 server[74756:2203] write Test::B
+2008-09-05 18:27:29.724 server[74756:2203] write Test::A
+2008-09-05 18:27:29.725 server[74756:2203] write Test::B
+2008-09-05 18:27:29.725 server[74756:2203] write Test::A
diff --git a/objc/test/Ice/operations/.gitignore b/objc/test/Ice/operations/.gitignore
new file mode 100644
index 00000000000..cf5529b05c8
--- /dev/null
+++ b/objc/test/Ice/operations/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+OperationsTest.m
+OperationsTest.h
diff --git a/objc/test/Ice/operations/AllTests.m b/objc/test/Ice/operations/AllTests.m
new file mode 100644
index 00000000000..6313aec5f18
--- /dev/null
+++ b/objc/test/Ice/operations/AllTests.m
@@ -0,0 +1,52 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OperationsTest.h>
+
+id<TestOperationsMyClassPrx>
+operationsAllTests(id<ICECommunicator> communicator, BOOL collocated)
+{
+ NSString* ref = @"test:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:(ref)];
+ id<TestOperationsMyClassPrx> cl = [TestOperationsMyClassPrx checkedCast:base];
+ id<TestOperationsMyDerivedClassPrx> derived = [TestOperationsMyDerivedClassPrx checkedCast:cl];
+
+ tprintf("testing twoway operations... ");
+ void twoways(id<ICECommunicator>, id<TestOperationsMyClassPrx>);
+ twoways(communicator, cl);
+ twoways(communicator, derived);
+ [derived opDerived];
+ tprintf("ok\n");
+
+ tprintf("testing oneway operations... ");
+ void oneways(id<ICECommunicator>, id<TestOperationsMyClassPrx>);
+ oneways(communicator, cl);
+ tprintf("ok\n");
+
+ tprintf("testing twoway operations with AMI... ");
+ void twowaysNewAMI(id<ICECommunicator>, id<TestOperationsMyClassPrx>);
+ twowaysNewAMI(communicator, cl);
+ twowaysNewAMI(communicator, derived);
+ tprintf("ok\n");
+
+ tprintf("testing oneway operations with AMI... ");
+ void onewaysNewAMI(id<ICECommunicator>, id<TestOperationsMyClassPrx>);
+ onewaysNewAMI(communicator, cl);
+ tprintf("ok\n");
+
+ tprintf("testing batch oneway operations... ");
+ void batchOneways(id<TestOperationsMyClassPrx>);
+ batchOneways(cl);
+ batchOneways(derived);
+ tprintf("ok\n");
+
+ return cl;
+}
diff --git a/objc/test/Ice/operations/BatchOneways.m b/objc/test/Ice/operations/BatchOneways.m
new file mode 100644
index 00000000000..8c7aa0185ec
--- /dev/null
+++ b/objc/test/Ice/operations/BatchOneways.m
@@ -0,0 +1,58 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OperationsTest.h>
+
+void
+batchOneways(id<TestOperationsMyClassPrx> p)
+{
+ ICEByte buf1[10 * 1024];
+ ICEByte buf2[99 * 1024];
+ TestOperationsMutableByteS *bs1 = [TestOperationsMutableByteS dataWithBytes:buf1 length:sizeof(buf1)];
+ TestOperationsMutableByteS *bs2 = [TestOperationsMutableByteS dataWithBytes:buf2 length:sizeof(buf2)];
+
+ @try
+ {
+ [p opByteSOneway:bs1];
+ }
+ @catch(ICEMemoryLimitException*)
+ {
+ test(NO);
+ }
+
+ @try
+ {
+ [p opByteSOneway:bs2];
+ }
+ @catch(ICEMemoryLimitException*)
+ {
+ test(NO);
+ }
+
+ id<TestOperationsMyClassPrx> batch = [TestOperationsMyClassPrx uncheckedCast:[p ice_batchOneway]];
+ int i;
+
+ for(i = 0 ; i < 30 ; ++i)
+ {
+ @try
+ {
+ [batch opByteSOneway:bs1];
+ }
+ @catch(ICEMemoryLimitException*)
+ {
+ test(NO);
+ }
+ }
+
+ // TODO: XXX: port 3.6b changes
+
+ [[batch ice_getConnection] flushBatchRequests];
+}
diff --git a/objc/test/Ice/operations/Client.m b/objc/test/Ice/operations/Client.m
new file mode 100644
index 00000000000..9d9b81fd2d1
--- /dev/null
+++ b/objc/test/Ice/operations/Client.m
@@ -0,0 +1,102 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OperationsTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestOperationsMyClassPrx> operationsAllTests(id<ICECommunicator>, BOOL);
+ id<TestOperationsMyClassPrx> myClass = operationsAllTests(communicator, NO);
+ tprintf("testing server shutdown... ");
+ [myClass shutdown];
+ @try
+ {
+ [myClass opVoid];
+ test(false);
+ }
+ @catch(ICELocalException*)
+ {
+ tprintf("ok\n");
+ }
+
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main operationsClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+ //
+ // In this test, we need at least two threads in the
+ // client side thread pool for nested AMI.
+ //
+ [initData.properties setProperty:@"Ice.ThreadPool.Client.Size" value:@"2"];
+ [initData.properties setProperty:@"Ice.ThreadPool.Client.SizeWarn" value:@"0"];
+
+ //
+ // We must set MessageSizeMax to an explicit values, because
+ // we run tests to check whether Ice.MemoryLimitException is
+ // raised as expected.
+ //
+ [initData.properties setProperty:@"Ice.MessageSizeMax" value:@"100"];
+
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestOperations", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/operations/Makefile b/objc/test/Ice/operations/Makefile
new file mode 100644
index 00000000000..525dc8b30c7
--- /dev/null
+++ b/objc/test/Ice/operations/Makefile
@@ -0,0 +1,42 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = OperationsTest.o
+
+COBJS = Client.o \
+ AllTests.o \
+ Twoways.o \
+ TwowaysNewAMI.o \
+ Oneways.o \
+ OnewaysNewAMI.o \
+ BatchOneways.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/operations/Oneways.m b/objc/test/Ice/operations/Oneways.m
new file mode 100644
index 00000000000..68957ea6f0d
--- /dev/null
+++ b/objc/test/Ice/operations/Oneways.m
@@ -0,0 +1,37 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OperationsTest.h>
+
+void
+oneways(id<ICECommunicator> communicator, id<TestOperationsMyClassPrx> proxy)
+{
+ id<TestOperationsMyClassPrx> p = [TestOperationsMyClassPrx uncheckedCast:[proxy ice_oneway]];
+
+ {
+ [p opVoid];
+ }
+
+ {
+ ICEByte b;
+ ICEByte r;
+
+ @try
+ {
+ r = [p opByte:(ICEByte)0xff p2:(ICEByte)0x0f p3:&b];
+ test(NO);
+ }
+ @catch(ICETwowayOnlyException*)
+ {
+ }
+ }
+
+}
diff --git a/objc/test/Ice/operations/OnewaysNewAMI.m b/objc/test/Ice/operations/OnewaysNewAMI.m
new file mode 100644
index 00000000000..dfd2c476d01
--- /dev/null
+++ b/objc/test/Ice/operations/OnewaysNewAMI.m
@@ -0,0 +1,125 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OperationsTest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface OnewayNewAMICallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+}
+-(void) check;
+-(void) called;
+@end
+
+@implementation OnewayNewAMICallback
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
++(id) create
+{
+#if defined(__clang__) && __has_feature(objc_arc)
+ return [[OnewayNewAMICallback alloc] init];
+#else
+ return [[[OnewayNewAMICallback alloc] init] autorelease];
+#endif
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) check
+{
+ [cond lock];
+ while(!called)
+ {
+ [cond wait];
+ }
+ called = NO;
+ [cond unlock];
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) opVoidResponse
+{
+ [self called];
+}
+-(void) opVoidException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opVoidExResponse
+{
+ test(NO);
+}
+-(void) opVoidExException:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICENoEndpointException class]]);
+ [self called];
+}
+-(void) opByteExResponse
+{
+ test(NO);
+}
+-(void) opByteEx:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opByteExException:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICETwowayOnlyException class]]);
+ [self called];
+}
+@end
+
+void
+onewaysNewAMI(id<ICECommunicator> communicator, id<TestOperationsMyClassPrx> proxy)
+{
+ id<TestOperationsMyClassPrx> p = [TestOperationsMyClassPrx uncheckedCast:[proxy ice_oneway]];
+
+ {
+ OnewayNewAMICallback* cb = [OnewayNewAMICallback create];
+ [p begin_opVoid:^() { [cb opVoidResponse]; } exception:^(ICEException* ex) { [cb opVoidException:ex]; }];
+ }
+
+ {
+ OnewayNewAMICallback* cb = [OnewayNewAMICallback create];
+ @try
+ {
+ [p begin_opByte:0 p2:0 response:^(ICEByte r, ICEByte p3) { [cb opByteExResponse]; } exception:^(ICEException* ex) { [cb opByteExException:ex]; }];
+ [cb check];
+ }
+ @catch(NSException* ex)
+ {
+ test([ex name] == NSInvalidArgumentException);
+ }
+ }
+}
diff --git a/objc/test/Ice/operations/OperationsTest.ice b/objc/test/Ice/operations/OperationsTest.ice
new file mode 100644
index 00000000000..51e2df76ab6
--- /dev/null
+++ b/objc/test/Ice/operations/OperationsTest.ice
@@ -0,0 +1,221 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/Current.ice>
+
+["objc:prefix:TestOperations"]
+module Test
+{
+
+enum MyEnum
+{
+ enum1,
+ enum2,
+ enum3
+};
+
+class MyClass;
+
+struct AnotherStruct
+{
+ string s;
+};
+
+struct Structure
+{
+ MyClass* p;
+ MyEnum e;
+ AnotherStruct s;
+};
+
+sequence<byte> ByteS;
+sequence<bool> BoolS;
+sequence<short> ShortS;
+sequence<int> IntS;
+sequence<long> LongS;
+sequence<float> FloatS;
+sequence<double> DoubleS;
+sequence<string> StringS;
+sequence<MyEnum> MyEnumS;
+sequence<MyClass*> MyClassS;
+
+sequence<ByteS> ByteSS;
+sequence<BoolS> BoolSS;
+sequence<ShortS> ShortSS;
+sequence<IntS> IntSS;
+sequence<LongS> LongSS;
+sequence<FloatS> FloatSS;
+sequence<DoubleS> DoubleSS;
+sequence<StringS> StringSS;
+sequence<MyEnumS> MyEnumSS;
+sequence<MyClassS> MyClassSS;
+
+sequence<StringSS> StringSSS;
+
+struct MyStruct
+{
+ int i;
+ int j;
+};
+
+dictionary<byte, bool> ByteBoolD;
+dictionary<short, int> ShortIntD;
+dictionary<long, float> LongFloatD;
+dictionary<string, string> StringStringD;
+dictionary<string, MyEnum> StringMyEnumD;
+dictionary<MyEnum, string> MyEnumStringD;
+dictionary<MyStruct, MyEnum> MyStructMyEnumD;
+
+sequence<Structure> StructS; // Used by Objective-C test only.
+
+struct Struct2 // Ensures the generated code for this struct compiles
+{
+ bool b;
+ int i;
+ float f;
+ double d;
+ byte by;
+ short sh;
+ long l;
+ StructS ss;
+ ByteBoolD dict;
+ MyEnumSS seq;
+};
+
+class A // Used Objective-C test only.
+{
+ int i;
+};
+
+sequence<A> AS; // Used by Objective-C test only.
+
+class MyClass
+{
+ void shutdown();
+
+ void opVoid();
+
+ byte opByte(byte p1, byte p2,
+ out byte p3);
+
+ bool opBool(bool p1, bool p2,
+ out bool p3);
+
+ long opShortIntLong(short p1, int p2, long p3,
+ out short p4, out int p5, out long p6);
+
+ double opFloatDouble(float p1, double p2,
+ out float p3, out double p4);
+
+ string opString(string p1, string p2,
+ out string p3);
+
+ MyEnum opMyEnum(MyEnum p1, out MyEnum p2);
+
+ MyClass* opMyClass(MyClass* p1, out MyClass* p2, out MyClass* p3);
+
+ Structure opStruct(Structure p1, Structure p2,
+ out Structure p3);
+
+ ByteS opByteS(ByteS p1, ByteS p2,
+ out ByteS p3);
+
+ BoolS opBoolS(BoolS p1, BoolS p2,
+ out BoolS p3);
+
+ LongS opShortIntLongS(Test::ShortS p1, IntS p2, LongS p3,
+ out ::Test::ShortS p4, out IntS p5, out LongS p6);
+
+ DoubleS opFloatDoubleS(FloatS p1, DoubleS p2,
+ out FloatS p3, out DoubleS p4);
+
+ StringS opStringS(StringS p1, StringS p2,
+ out StringS p3);
+
+ MyEnumS opMyEnumS(MyEnumS p1, MyEnumS p2,
+ out MyEnumS p3);
+
+ MyClassS opMyClassS(MyClassS p1, MyClassS p2,
+ out MyClassS p3);
+
+ ByteSS opByteSS(ByteSS p1, ByteSS p2,
+ out ByteSS p3);
+
+ BoolSS opBoolSS(BoolSS p1, BoolSS p2,
+ out BoolSS p3);
+
+ LongSS opShortIntLongSS(ShortSS p1, IntSS p2, LongSS p3,
+ out ShortSS p4, out IntSS p5, out LongSS p6);
+
+
+ DoubleSS opFloatDoubleSS(FloatSS p1, DoubleSS p2,
+ out FloatSS p3, out DoubleSS p4);
+
+ StringSS opStringSS(StringSS p1, StringSS p2,
+ out StringSS p3);
+
+ StringSSS opStringSSS(StringSSS p1, StringSSS p2,
+ out StringSSS p3);
+
+ ByteBoolD opByteBoolD(ByteBoolD p1, ByteBoolD p2,
+ out ByteBoolD p3);
+
+ ShortIntD opShortIntD(ShortIntD p1, ShortIntD p2,
+ out ShortIntD p3);
+
+ LongFloatD opLongFloatD(LongFloatD p1, LongFloatD p2,
+ out LongFloatD p3);
+
+ StringStringD opStringStringD(StringStringD p1, StringStringD p2,
+ out StringStringD p3);
+
+ StringMyEnumD opStringMyEnumD(StringMyEnumD p1, StringMyEnumD p2,
+ out StringMyEnumD p3);
+
+ MyEnumStringD opMyEnumStringD(MyEnumStringD p1, MyEnumStringD p2,
+ out MyEnumStringD p3);
+
+ MyStructMyEnumD opMyStructMyEnumD(MyStructMyEnumD p1, MyStructMyEnumD p2,
+ out MyStructMyEnumD p3);
+
+ IntS opIntS(IntS s);
+
+ void opByteSOneway(ByteS s);
+
+ Ice::Context opContext();
+
+ void opDoubleMarshaling(double p1, DoubleS p2);
+
+ idempotent void opIdempotent();
+
+ ["nonmutating"] idempotent void opNonmutating();
+
+ //
+ // Operations below are specific to Objective-C
+ //
+
+ StringS getNSNullStringSeq();
+ AS getNSNullASeq();
+ StructS getNSNullStructSeq();
+ StringSS getNSNullStringSeqSeq();
+
+ StringStringD getNSNullStringStringDict();
+ void putNSNullStringStringDict(StringStringD d);
+ void putNSNullShortIntDict(ShortIntD d);
+ void putNSNullStringMyEnumDict(StringMyEnumD d);
+};
+
+class MyDerivedClass extends MyClass
+{
+ void opDerived();
+};
+
+};
diff --git a/objc/test/Ice/operations/Server.m b/objc/test/Ice/operations/Server.m
new file mode 100644
index 00000000000..48bd4314ba5
--- /dev/null
+++ b/objc/test/Ice/operations/Server.m
@@ -0,0 +1,93 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <operations/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestOperationsAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestOperationsAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adapter add:[[[TestOperationsMyDerivedClassI alloc] init] autorelease]
+ identity:[communicator stringToIdentity:@"test"]];
+#else
+ [adapter add:[[TestOperationsMyDerivedClassI alloc] init]
+ identity:[communicator stringToIdentity:@"test"]];
+
+#endif
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main operationsServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+
+ //
+ // Its possible to have batch oneway requests dispatched after
+ // the adapter is deactivated due to thread scheduling so we
+ // supress this warning.
+ //
+ [initData.properties setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestOperations", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/operations/TestI.h b/objc/test/Ice/operations/TestI.h
new file mode 100644
index 00000000000..9dad65b8578
--- /dev/null
+++ b/objc/test/Ice/operations/TestI.h
@@ -0,0 +1,16 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <OperationsTest.h>
+
+//
+// Servant implementation
+//
+@interface TestOperationsMyDerivedClassI : TestOperationsMyDerivedClass<TestOperationsMyDerivedClass>
+@end
diff --git a/objc/test/Ice/operations/TestI.m b/objc/test/Ice/operations/TestI.m
new file mode 100644
index 00000000000..58ae709ae10
--- /dev/null
+++ b/objc/test/Ice/operations/TestI.m
@@ -0,0 +1,470 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+
+#import <operations/TestI.h>
+#import <TestCommon.h>
+
+@implementation TestOperationsMyDerivedClassI
+-(void) opVoid:(ICECurrent*)current
+{
+}
+
+-(void) opDerived:(ICECurrent*)current
+{
+}
+
+-(ICEByte) opByte:(ICEByte)p1 p2:(ICEByte)p2 p3:(ICEByte *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1 ^ p2;
+ return p1;
+}
+
+-(BOOL) opBool:(BOOL)p1 p2:(BOOL)p2 p3:(BOOL *)p3 current:(ICECurrent*)current
+{
+ *p3 = p1;
+ return p2;
+}
+
+-(ICELong) opShortIntLong:(ICEShort)p1 p2:(ICEInt)p2 p3:(ICELong)p3
+ p4:(ICEShort *)p4 p5:(ICEInt *)p5 p6:(ICELong *)p6
+ current:(ICECurrent *)current
+{
+ *p4 = p1;
+ *p5 = p2;
+ *p6 = p3;
+ return p3;
+}
+
+-(ICEDouble) opFloatDouble:(ICEFloat)p1 p2:(ICEDouble)p2 p3:(ICEFloat *)p3 p4:(ICEDouble *)p4
+ current:(ICECurrent *)current
+{
+ *p3 = p1;
+ *p4 = p2;
+ return p2;
+}
+
+-(NSString *) opString:(NSMutableString *)p1 p2:(NSMutableString *)p2 p3:(NSString **)p3 current:(ICECurrent *)current
+{
+ NSMutableString *sout = [NSMutableString stringWithCapacity:([p2 length] + 1 + [p1 length])];
+ [sout appendString:p2];
+ [sout appendString:@" "];
+ [sout appendString:p1];
+ *p3 = sout;
+
+ NSMutableString *ret = [NSMutableString stringWithCapacity:([p1 length] + 1 + [p2 length])];
+ [ret appendString:p1];
+ [ret appendString:@" "];
+ [ret appendString:p2];
+ return ret;
+}
+
+-(TestOperationsMyEnum) opMyEnum:(TestOperationsMyEnum)p1 p2:(TestOperationsMyEnum *)p2 current:(ICECurrent *)current
+{
+ *p2 = p1;
+ return TestOperationsenum3;
+}
+
+-(id<TestOperationsMyClassPrx>) opMyClass:(id<TestOperationsMyClassPrx>)p1 p2:(id<TestOperationsMyClassPrx> *)p2 p3:(id<TestOperationsMyClassPrx> *)p3
+ current:(ICECurrent *)current
+{
+ *p2 = p1;
+ *p3 = [TestOperationsMyClassPrx uncheckedCast:[current.adapter
+ createProxy:[[current.adapter getCommunicator]
+ stringToIdentity:@"noSuchIdentity"]]];
+ return [TestOperationsMyClassPrx uncheckedCast:[current.adapter createProxy:[current id_]]];
+}
+
+-(TestOperationsStructure *) opStruct:(TestOperationsStructure *)p1 p2:(TestOperationsStructure *)p2 p3:(TestOperationsStructure **)p3
+ current:(ICECurrent *)current;
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ *p3 = [[p1 copy] autorelease];
+#else
+ *p3 = [p1 copy];
+#endif
+ (*p3).s.s = @"a new string";
+ return p2;
+}
+
+-(TestOperationsByteS *) opByteS:(TestOperationsMutableByteS *)p1 p2:(TestOperationsMutableByteS *)p2 p3:(TestOperationsByteS **)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableByteS dataWithLength:[p1 length]];
+ ICEByte *target = (ICEByte *)[*p3 bytes];
+ ICEByte *src = (ICEByte *)[p1 bytes] + [p1 length];
+ int i;
+ for(i = 0; i != [p1 length]; ++i)
+ {
+ *target++ = *--src;
+ }
+ TestOperationsMutableByteS *r = [TestOperationsMutableByteS dataWithData:p1];
+ [r appendData:p2];
+ return r;
+}
+
+-(TestOperationsBoolS *) opBoolS:(TestOperationsMutableBoolS *)p1 p2:(TestOperationsMutableBoolS *)p2 p3:(TestOperationsBoolS **)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableBoolS dataWithData:p1];
+ [(TestOperationsMutableBoolS *)*p3 appendData:p2];
+
+ TestOperationsMutableBoolS *r = [TestOperationsMutableBoolS dataWithLength:[p1 length] * sizeof(BOOL)];
+ BOOL *target = (BOOL *)[r bytes];
+ BOOL *src = (BOOL *)([p1 bytes] + [p1 length]);
+ int i;
+ for(i = 0; i != [p1 length]; ++i)
+ {
+ *target++ = *--src;
+ }
+ return r;
+}
+
+-(TestOperationsLongS *) opShortIntLongS:(TestOperationsMutableShortS *)p1 p2:(TestOperationsMutableIntS *)p2 p3:(TestOperationsMutableLongS *)p3
+ p4:(TestOperationsShortS **)p4 p5:(TestOperationsIntS **)p5 p6:(TestOperationsLongS **)p6
+ current:(ICECurrent *)current
+{
+ *p4 = [TestOperationsMutableShortS dataWithData:p1];
+ *p5 = [TestOperationsMutableIntS dataWithLength:[p2 length]];
+ ICEInt *target = (ICEInt *)[*p5 bytes];
+ ICEInt *src = (ICEInt *)([p2 bytes] + [p2 length]);
+ int i;
+ for(i = 0; i != [p2 length] / sizeof(ICEInt); ++i)
+ {
+ *target++ = *--src;
+ }
+ *p6 = [TestOperationsMutableLongS dataWithData:p3];
+ [(TestOperationsMutableLongS *)*p6 appendData:p3];
+ return p3;
+}
+
+-(TestOperationsDoubleS *) opFloatDoubleS:(TestOperationsMutableFloatS *)p1 p2:(TestOperationsMutableDoubleS *)p2
+ p3:(TestOperationsFloatS **)p3 p4:(TestOperationsDoubleS **)p4 current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableFloatS dataWithData:p1];
+ *p4 = [TestOperationsMutableDoubleS dataWithLength:[p2 length]];
+ ICEDouble *target = (ICEDouble *)[*p4 bytes];
+ ICEDouble *src = (ICEDouble *)([p2 bytes] + [p2 length]);
+ int i;
+ for(i = 0; i != [p2 length] / sizeof(ICEDouble); ++i)
+ {
+ *target++ = *--src;
+ }
+ TestOperationsDoubleS *r = [TestOperationsMutableDoubleS dataWithLength:([p2 length]
+ + ([p1 length] / sizeof(ICEFloat) * sizeof(ICEDouble)))];
+ ICEDouble *rp = (ICEDouble *)[r bytes];
+ ICEDouble *p2p = (ICEDouble *)[p2 bytes];
+ for(i = 0; i < [p2 length] / sizeof(ICEDouble); ++i)
+ {
+ *rp++ = *p2p++;
+ }
+ ICEFloat *bp1 = (ICEFloat *)[p1 bytes];
+ for(i = 0; i < [p1 length] / sizeof(ICEFloat); ++i)
+ {
+ *rp++ = bp1[i];
+ }
+ return r;
+}
+
+-(TestOperationsStringS *) opStringS:(TestOperationsMutableStringS *)p1 p2:(TestOperationsMutableStringS *)p2
+ p3:(TestOperationsStringS **)p3 current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableStringS arrayWithArray:p1];
+ [(TestOperationsMutableStringS *)*p3 addObjectsFromArray:p2];
+ TestOperationsMutableStringS *r = [TestOperationsMutableStringS arrayWithCapacity:[p1 count]];
+ NSEnumerator *enumerator = [p1 reverseObjectEnumerator];
+ for(NSString *element in enumerator)
+ {
+ [r addObject:element];
+ }
+ return r;
+}
+
+-(TestOperationsMyEnumS *) opMyEnumS:(TestOperationsMutableMyEnumS *)p1 p2:(TestOperationsMutableMyEnumS *)p2
+ p3:(TestOperationsMyEnumS **)p3 current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableMyEnumS dataWithLength:[p1 length]];
+ TestOperationsMyEnum *target = (TestOperationsMyEnum *)[*p3 bytes];
+ TestOperationsMyEnum *src = (TestOperationsMyEnum *)([p1 bytes] + [p1 length]);
+ int i;
+ for(i = 0; i != [p1 length] / sizeof(TestOperationsMyEnum); ++i)
+ {
+ *target++ = *--src;
+ }
+ TestOperationsMutableMyEnumS *r = [TestOperationsMutableMyEnumS dataWithData:p1];
+ [r appendData:p2];
+ return r;
+}
+
+-(TestOperationsMyClassS *) opMyClassS:(TestOperationsMutableMyClassS *)p1 p2:(TestOperationsMutableMyClassS *)p2
+ p3:(TestOperationsMyClassS **)p3 current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableMyClassS arrayWithArray:p1];
+ [(TestOperationsMutableMyClassS *)*p3 addObjectsFromArray:p2];
+ TestOperationsMutableMyClassS *r = [TestOperationsMutableMyClassS arrayWithCapacity:[p1 count]];
+ NSEnumerator *enumerator = [p1 reverseObjectEnumerator];
+ for(NSString *element in enumerator)
+ {
+ [r addObject:element];
+ }
+ return r;
+}
+
+-(TestOperationsByteSS *) opByteSS:(TestOperationsMutableByteSS *)p1 p2:(TestOperationsMutableByteSS *)p2 p3:(TestOperationsByteSS * *)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableByteSS array];
+ NSEnumerator *enumerator = [p1 reverseObjectEnumerator];
+ for(TestOperationsByteS *element in enumerator)
+ {
+ [(TestOperationsMutableByteSS *)*p3 addObject:element];
+ }
+
+ TestOperationsMutableByteSS *r = [TestOperationsMutableByteSS arrayWithArray:p1];
+ [r addObjectsFromArray:p2];
+ return r;
+}
+
+-(TestOperationsBoolSS *) opBoolSS:(TestOperationsMutableBoolSS *)p1 p2:(TestOperationsMutableBoolSS *)p2 p3:(TestOperationsBoolSS * *)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableBoolSS arrayWithArray:p1];
+ [(TestOperationsMutableBoolSS *)*p3 addObjectsFromArray:p2];
+
+ TestOperationsMutableBoolSS *r = [TestOperationsMutableBoolSS array];
+ NSEnumerator *enumerator = [p1 reverseObjectEnumerator];
+ for(TestOperationsBoolS *element in enumerator)
+ {
+ [r addObject:element];
+ }
+ return r;
+}
+
+-(TestOperationsLongSS *) opShortIntLongSS:(TestOperationsMutableShortSS *)p1 p2:(TestOperationsMutableIntSS *)p2 p3:(TestOperationsMutableLongSS *)p3
+ p4:(TestOperationsShortSS **)p4 p5:(TestOperationsIntSS **)p5 p6:(TestOperationsLongSS **)p6
+ current:(ICECurrent *)current
+{
+ *p4 = [TestOperationsShortSS arrayWithArray:p1];
+ *p5 = [TestOperationsMutableIntSS array];
+ NSEnumerator *enumerator = [p2 reverseObjectEnumerator];
+ for(TestOperationsIntS *element in enumerator)
+ {
+ [(TestOperationsMutableIntSS *)*p5 addObject:element];
+ }
+ *p6 = [TestOperationsMutableLongSS arrayWithArray:p3];
+ [(TestOperationsMutableLongSS *)*p6 addObjectsFromArray:p3];
+ return p3;
+}
+
+-(TestOperationsDoubleSS *) opFloatDoubleSS:(TestOperationsMutableFloatSS *)p1 p2:(TestOperationsMutableDoubleSS *)p2
+ p3:(TestOperationsFloatSS **)p3 p4:(TestOperationsDoubleSS **)p4 current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsFloatSS arrayWithArray:p1];
+ *p4 = [TestOperationsMutableDoubleSS array];
+ NSEnumerator *enumerator = [p2 reverseObjectEnumerator];
+ for(TestOperationsDoubleS *element in enumerator)
+ {
+ [(TestOperationsMutableDoubleSS *)*p4 addObject:element];
+ }
+ TestOperationsMutableDoubleSS *r = [TestOperationsMutableDoubleSS arrayWithArray:p2];
+ [r addObjectsFromArray:p2];
+ return r;
+}
+
+-(TestOperationsStringSS *) opStringSS:(TestOperationsMutableStringSS *)p1 p2:(TestOperationsMutableStringSS *)p2 p3:(TestOperationsStringSS **)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableStringSS arrayWithArray:p1];
+ [(TestOperationsMutableStringSS *)*p3 addObjectsFromArray:p2];
+ TestOperationsMutableStringSS *r = [TestOperationsMutableStringSS array];
+ NSEnumerator *enumerator = [p2 reverseObjectEnumerator];
+ for(TestOperationsStringS *element in enumerator)
+ {
+ [r addObject:element];
+ }
+ return r;
+}
+
+-(TestOperationsStringSSS *) opStringSSS:(TestOperationsMutableStringSSS *)p1 p2:(TestOperationsMutableStringSSS *)p2 p3:(TestOperationsStringSSS **)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableStringSSS arrayWithArray:p1];
+ [(TestOperationsMutableStringSSS *)*p3 addObjectsFromArray:p2];
+ TestOperationsMutableStringSSS *r = [TestOperationsMutableStringSSS array];
+ NSEnumerator *enumerator = [p2 reverseObjectEnumerator];
+ for(TestOperationsStringSS *element in enumerator)
+ {
+ [r addObject:element];
+ }
+ return r;
+}
+
+-(TestOperationsByteBoolD *) opByteBoolD:(TestOperationsMutableByteBoolD *)p1 p2:(TestOperationsMutableByteBoolD *)p2 p3:(TestOperationsByteBoolD **)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableByteBoolD dictionaryWithDictionary:p1];
+ TestOperationsMutableByteBoolD *r = [TestOperationsMutableByteBoolD dictionaryWithDictionary:p1];
+ [r addEntriesFromDictionary:p2];
+ return r;
+}
+
+-(TestOperationsShortIntD *) opShortIntD:(TestOperationsMutableShortIntD *)p1 p2:(TestOperationsMutableShortIntD *)p2 p3:(TestOperationsShortIntD **)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableShortIntD dictionaryWithDictionary:p1];
+ TestOperationsMutableShortIntD *r = [TestOperationsMutableShortIntD dictionaryWithDictionary:p1];
+ [r addEntriesFromDictionary:p2];
+ return r;
+}
+
+-(TestOperationsLongFloatD *) opLongFloatD:(TestOperationsMutableLongFloatD *)p1 p2:(TestOperationsMutableLongFloatD *)p2 p3:(TestOperationsLongFloatD **)p3
+ current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableLongFloatD dictionaryWithDictionary:p1];
+ TestOperationsMutableLongFloatD *r = [TestOperationsMutableLongFloatD dictionaryWithDictionary:p1];
+ [r addEntriesFromDictionary:p2];
+ return r;
+}
+
+-(TestOperationsStringStringD *) opStringStringD:(TestOperationsMutableStringStringD *)p1 p2:(TestOperationsMutableStringStringD *)p2
+ p3:(TestOperationsStringStringD **)p3 current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableStringStringD dictionaryWithDictionary:p1];
+ TestOperationsMutableStringStringD *r = [TestOperationsMutableStringStringD dictionaryWithDictionary:p1];
+ [r addEntriesFromDictionary:p2];
+ return r;
+}
+
+-(TestOperationsStringMyEnumD *) opStringMyEnumD:(TestOperationsMutableStringMyEnumD *)p1
+ p2:(TestOperationsMutableStringMyEnumD *)p2
+ p3:(TestOperationsStringMyEnumD **)p3 current:(ICECurrent *)current
+{
+ *p3 = [TestOperationsMutableStringMyEnumD dictionaryWithDictionary:p1];
+ TestOperationsMutableStringMyEnumD *r = [TestOperationsMutableStringMyEnumD dictionaryWithDictionary:p1];
+ [r addEntriesFromDictionary:p2];
+ return r;
+}
+
+-(TestOperationsMyEnumStringD *) opMyEnumStringD:(TestOperationsMyEnumStringD*)p1
+ p2:(TestOperationsMyEnumStringD*)p2
+ p3:(TestOperationsMyEnumStringD**)p3
+ current:(ICECurrent*)current
+{
+ *p3 = [TestOperationsMutableMyEnumStringD dictionaryWithDictionary:p1];
+ TestOperationsMutableMyEnumStringD *r = [TestOperationsMutableMyEnumStringD dictionaryWithDictionary:p1];
+ [r addEntriesFromDictionary:p2];
+ return r;
+}
+
+-(TestOperationsMyStructMyEnumD *) opMyStructMyEnumD:(TestOperationsMyStructMyEnumD*)p1
+ p2:(TestOperationsMyStructMyEnumD*)p2
+ p3:(TestOperationsMyStructMyEnumD**)p3
+ current:(ICECurrent*)current
+{
+ *p3 = [TestOperationsMutableMyStructMyEnumD dictionaryWithDictionary:p1];
+ TestOperationsMutableMyStructMyEnumD *r = [TestOperationsMutableMyStructMyEnumD dictionaryWithDictionary:p1];
+ [r addEntriesFromDictionary:p2];
+ return r;
+}
+
+-(TestOperationsIntS *) opIntS:(TestOperationsMutableIntS *)p1 current:(ICECurrent *)current
+{
+ NSUInteger count = [p1 length] / sizeof(ICEInt);
+ TestOperationsMutableIntS *r = [TestOperationsMutableIntS dataWithLength:[p1 length]];
+ const int *src = [p1 bytes];
+ int *target = (int *)[r bytes];
+ while(count-- > 0)
+ {
+ *target++ = -*src++;
+ }
+ return r;
+}
+
+-(void) opByteSOneway:(TestOperationsMutableByteS *)p1 current:(ICECurrent *)current
+{
+}
+
+-(ICEContext *) opContext:(ICECurrent *)current
+{
+ return current.ctx;
+}
+
+-(void) opDoubleMarshaling:(ICEDouble)p1 p2:(TestOperationsMutableDoubleS *)p2 current:(ICECurrent *)current
+{
+ ICEDouble d = 1278312346.0 / 13.0;
+ test(p1 == d);
+ const ICEDouble *p = [p2 bytes];
+ int i;
+ for(i = 0; i < [p2 length] / sizeof(ICEDouble); ++i)
+ {
+ test(p[i] == d);
+ }
+}
+
+-(void) opIdempotent:(ICECurrent*)current
+{
+ test([current mode] == ICEIdempotent);
+}
+
+-(void) opNonmutating:(ICECurrent*)current
+{
+ test([current mode] == ICENonmutating);
+}
+
+-(TestOperationsStringS *) getNSNullStringSeq:(ICECurrent *)current
+{
+ return [NSArray arrayWithObjects:@"first", [NSNull null], nil];
+}
+
+-(TestOperationsMyClassS *) getNSNullASeq:(ICECurrent *)current
+{
+ return [NSArray arrayWithObjects:[TestOperationsA a:99], [NSNull null], nil];
+}
+
+-(TestOperationsStructS *) getNSNullStructSeq:(ICECurrent *)current
+{
+ TestOperationsStructure *s = [TestOperationsStructure structure:nil e:TestOperationsenum2 s:[TestOperationsAnotherStruct anotherStruct:@"Hello"]];
+ return [NSArray arrayWithObjects:s, [NSNull null], nil];
+}
+
+-(TestOperationsStringSS *) getNSNullStringSeqSeq:(ICECurrent *)current
+{
+ TestOperationsStringSS *s = [NSArray arrayWithObjects:@"first", nil];
+ return [NSArray arrayWithObjects:s, [NSNull null], nil];
+}
+
+-(TestOperationsStringStringD *) getNSNullStringStringDict:(ICECurrent *)current
+{
+ TestOperationsMutableStringStringD *d = [TestOperationsMutableStringStringD dictionary];
+ [d setObject:@"ONE" forKey:@"one"];
+ [d setObject:[NSNull null] forKey:@"two"];
+ return d;
+}
+
+-(void) putNSNullStringStringDict:(TestOperationsMutableStringStringD *)d current:(ICECurrent *)current
+{
+ // Nothing to do because this tests that an exception is thrown on the client side.
+}
+
+-(void) putNSNullShortIntDict:(TestOperationsMutableShortIntD *)d current:(ICECurrent *)current
+{
+ // Nothing to do because this tests that an exception is thrown on the client side.
+}
+
+-(void) putNSNullStringMyEnumDict:(TestOperationsMutableStringMyEnumD *)d current:(ICECurrent *)current
+{
+ // Nothing to do because this tests that an exception is thrown on the client side.
+}
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
diff --git a/objc/test/Ice/operations/Twoways.m b/objc/test/Ice/operations/Twoways.m
new file mode 100644
index 00000000000..8eddf1ab753
--- /dev/null
+++ b/objc/test/Ice/operations/Twoways.m
@@ -0,0 +1,1094 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OperationsTest.h>
+#import <limits.h>
+#import <float.h>
+
+#import <Foundation/Foundation.h>
+
+@interface PerThreadContextInvokeThread : NSThread
+{
+ id<TestOperationsMyClassPrx> proxy;
+ NSCondition* cond;
+ BOOL called;
+}
+-(id) init:(id<TestOperationsMyClassPrx>)proxy_;
++(id) create:(id<TestOperationsMyClassPrx>)proxy_;
+-(void) join;
+-(void) run;
+@end
+
+@implementation PerThreadContextInvokeThread
+-(id) init:(id<TestOperationsMyClassPrx>)proxy_
+{
+ self = [super initWithTarget:self selector:@selector(run) object:nil];
+ if(self)
+ {
+ self->called = NO;
+#if defined(__clang__) && !__has_feature(objc_arc)
+ self->proxy = [proxy_ retain];
+#else
+ self->proxy = proxy_;
+#endif
+ cond = [[NSCondition alloc] init];
+ }
+ return self;
+}
+
++(id) create:(id<TestOperationsMyClassPrx>)proxy_
+{
+#if defined(__clang__) && __has_feature(objc_arc)
+ return [[PerThreadContextInvokeThread alloc] init:proxy_];
+#else
+ return [[[PerThreadContextInvokeThread alloc] init:proxy_] autorelease];
+#endif
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [proxy release];
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) run
+{
+ [cond lock];
+ ICEMutableContext* ctx = [[[proxy ice_getCommunicator] getImplicitContext] getContext];
+ test([ctx count] == 0);
+ [ctx setObject:@"UN" forKey:@"one" ];
+ [[[proxy ice_getCommunicator] getImplicitContext] setContext:ctx];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+
+-(void) join
+{
+ [cond lock];
+ while(!called)
+ {
+ [cond wait];
+ }
+ [cond unlock];
+}
+@end
+
+void
+twoways(id<ICECommunicator> communicator, id<TestOperationsMyClassPrx> p)
+{
+ {
+ [p opVoid];
+ }
+
+ {
+ ICEByte b;
+ ICEByte r;
+
+ r = [p opByte:(ICEByte)0xff p2:(ICEByte)0x0f p3:&b];
+ test(b == (ICEByte)0xf0);
+ test(r == (ICEByte)0xff);
+ }
+
+ {
+ BOOL b;
+ BOOL r;
+
+ r = [p opBool:YES p2:NO p3:&b];
+ test(b);
+ test(!r);
+ }
+
+ {
+ ICEShort s;
+ ICEInt i;
+ ICELong l;
+ ICELong r;
+
+ r = [p opShortIntLong:10 p2:11 p3:12 p4:&s p5:&i p6:&l];
+ test(s == 10);
+ test(i == 11);
+ test(l == 12);
+ test(r == 12);
+
+#ifndef SHORT_MIN
+#define SHORT_MIN (-0x7fff)
+#endif
+ r = [p opShortIntLong:SHORT_MIN p2:INT_MIN p3:LONG_MIN p4:&s p5:&i p6:&l];
+ test(s == SHORT_MIN);
+ test(i == INT_MIN);
+ test(l == LONG_MIN);
+ test(r == LONG_MIN);
+
+#ifndef SHORT_MAX
+#define SHORT_MAX 0x7fff
+#endif
+ r = [p opShortIntLong:SHORT_MAX p2:INT_MAX p3:LONG_MAX p4:&s p5:&i p6:&l];
+ test(s == SHORT_MAX);
+ test(i == INT_MAX);
+ test(l == LONG_MAX);
+ test(r == LONG_MAX);
+ }
+
+ {
+ ICEFloat f;
+ ICEDouble d;
+ ICEDouble r;
+
+ r = [p opFloatDouble:3.14f p2:1.1E10 p3:&f p4:&d];
+ test(f == 3.14f);
+ test(d == 1.1E10);
+ test(r == 1.1E10);
+
+ r = [p opFloatDouble:FLT_MIN p2:DBL_MIN p3:&f p4:&d];
+ test(f == FLT_MIN);
+ test(d == DBL_MIN);
+ test(r == DBL_MIN);
+
+ r = [p opFloatDouble:FLT_MAX p2:DBL_MAX p3:&f p4:&d];
+ test(f == FLT_MAX);
+ test(d == DBL_MAX);
+ test(r == DBL_MAX);
+ }
+
+ {
+ NSMutableString *s = nil;
+ NSMutableString *r;
+
+ r = [p opString:@"hello" p2:@"world" p3:&s];
+ r = [p opString:@"hello" p2:@"world" p3:&s];
+ r = [p opString:@"hello" p2:@"world" p3:&s];
+ r = [p opString:@"hello" p2:@"world" p3:&s];
+ test([s isEqualToString:@"world hello"]);
+ test([r isEqualToString:@"hello world"]);
+ }
+
+ {
+ TestOperationsMyEnum e;
+ TestOperationsMyEnum r;
+
+ r = [p opMyEnum:TestOperationsenum2 p2:&e];
+ test(e == TestOperationsenum2);
+ test(r == TestOperationsenum3);
+ }
+
+ {
+ id<TestOperationsMyClassPrx> c1;
+ id<TestOperationsMyClassPrx> c2;
+ id<TestOperationsMyClassPrx> r;
+
+ r = [p opMyClass:p p2:&c1 p3:&c2];
+ test([c1 compareIdentityAndFacet:p] == NSOrderedSame);
+ test([c2 compareIdentityAndFacet:p] != NSOrderedSame);
+ test([r compareIdentityAndFacet:p] == NSOrderedSame);
+ test([[c1 ice_getIdentity] isEqual:[communicator stringToIdentity:@"test"]]);
+ test([[c2 ice_getIdentity]isEqual:[communicator stringToIdentity:@"noSuchIdentity"]]);
+ test([[r ice_getIdentity] isEqual:[communicator stringToIdentity:@"test"]]);
+ [r opVoid];
+ [c1 opVoid];
+ @try
+ {
+ [c2 opVoid];
+ test(NO);
+ }
+ @catch(ICEObjectNotExistException*)
+ {
+ }
+
+ r = [p opMyClass:0 p2:&c1 p3:&c2];
+ test(c1 == nil);
+ test(c2 != nil);
+ test([r compareIdentityAndFacet:p] == NSOrderedSame);
+ [r opVoid];
+ }
+
+ {
+ TestOperationsStructure *si1 = [TestOperationsStructure structure];
+ si1.p = p;
+ si1.e = TestOperationsenum3;
+ si1.s = [TestOperationsAnotherStruct anotherStruct];
+ si1.s.s = @"abc";
+ TestOperationsStructure *si2 = [TestOperationsStructure structure];
+ si2.p = nil;
+ si2.e = TestOperationsenum2;
+ si2.s = [TestOperationsAnotherStruct anotherStruct];
+ si2.s.s = @"def";
+
+ TestOperationsStructure *so;
+ TestOperationsStructure *rso = [p opStruct:si1 p2:si2 p3:&so];
+
+ test(rso.p == nil);
+ test(rso.e == TestOperationsenum2);
+ test([rso.s.s isEqualToString:@"def"]);
+ test(so.p != nil);
+ test([so.p isEqual:p]);
+ test(so.e == TestOperationsenum3);
+ test([so.s.s isEqualToString:@"a new string"]);
+ [so.p opVoid];
+ }
+
+ {
+ ICEByte buf1[] = { 0x01, 0x11, 0x12, 0x22 };
+ ICEByte buf2[] = { 0xf1, 0xf2, 0xf3, 0xf4 };
+
+ TestOperationsMutableByteS *bsi1 = [TestOperationsMutableByteS data];
+ TestOperationsMutableByteS *bsi2 = [TestOperationsMutableByteS data];
+
+ [bsi1 appendBytes:buf1 length:sizeof(buf1)];
+ [bsi2 appendBytes:buf2 length:sizeof(buf2)];
+
+ TestOperationsMutableByteS *bso;
+ TestOperationsByteS *rso;
+
+ rso = [p opByteS:bsi1 p2:bsi2 p3:&bso];
+
+ test([bso length] == 4);
+ ICEByte *bbso = (ICEByte *)[bso bytes];
+ test(bbso[0] == 0x22);
+ test(bbso[1] == 0x12);
+ test(bbso[2] == 0x11);
+ test(bbso[3] == 0x01);
+ test([rso length] == 8);
+ ICEByte *brso = (ICEByte *)[rso bytes];
+ test(brso[0] == 0x01);
+ test(brso[1] == 0x11);
+ test(brso[2] == 0x12);
+ test(brso[3] == 0x22);
+ test(brso[4] == 0xf1);
+ test(brso[5] == 0xf2);
+ test(brso[6] == 0xf3);
+ test(brso[7] == 0xf4);
+ }
+
+ {
+ BOOL buf1[] = { YES, YES, NO };
+ BOOL buf2[] = { NO };
+
+ TestOperationsMutableBoolS *bsi1 = [TestOperationsMutableBoolS data];
+ TestOperationsMutableBoolS *bsi2 = [TestOperationsMutableBoolS data];
+
+ [bsi1 appendBytes:buf1 length:sizeof(buf1)];
+ [bsi2 appendBytes:buf2 length:sizeof(buf2)];
+
+ TestOperationsMutableBoolS *bso;
+ TestOperationsBoolS *rso;
+
+ rso = [p opBoolS:bsi1 p2:bsi2 p3:&bso];
+
+ test([bso length] == 4 * sizeof(BOOL));
+ BOOL *bbso = (BOOL *)[bso bytes];
+ test(bbso[0]);
+ test(bbso[1]);
+ test(!bbso[2]);
+ test(!bbso[3]);
+ test([rso length] == 3 * sizeof(BOOL));
+ BOOL *brso = (BOOL *)[rso bytes];
+ test(!brso[0]);
+ test(brso[1]);
+ test(brso[2]);
+ }
+
+ {
+ ICEShort buf1[] = { 1, 2, 3 };
+ ICEInt buf2[] = { 5, 6, 7, 8 };
+ ICELong buf3[] = { 10, 30, 20 };
+
+ TestOperationsMutableShortS *ssi = [TestOperationsMutableShortS data];
+ TestOperationsMutableIntS *isi = [TestOperationsMutableIntS data];
+ TestOperationsMutableLongS *lsi = [TestOperationsMutableLongS data];
+
+ [ssi appendBytes:buf1 length:sizeof(buf1)];
+ [isi appendBytes:buf2 length:sizeof(buf2)];
+ [lsi appendBytes:buf3 length:sizeof(buf3)];
+
+ TestOperationsMutableShortS *sso;
+ TestOperationsMutableIntS *iso;
+ TestOperationsMutableLongS *lso;
+ TestOperationsLongS *rso;
+
+ rso = [p opShortIntLongS:ssi p2:isi p3:lsi p4:&sso p5:&iso p6:&lso];
+
+ test([sso length] == 3 * sizeof(ICEShort));
+ ICEShort *bsso = (ICEShort *)[sso bytes];
+ test(bsso[0] == 1);
+ test(bsso[1] == 2);
+ test(bsso[2] == 3);
+ test([iso length] == 4 * sizeof(ICEInt));
+ ICEInt *biso = (ICEInt *)[iso bytes];
+ test(biso[0] == 8);
+ test(biso[1] == 7);
+ test(biso[2] == 6);
+ test(biso[3] == 5);
+ test([lso length] == 6 * sizeof(ICELong));
+ ICELong *blso = (ICELong *)[lso bytes];
+ test(blso[0] == 10);
+ test(blso[1] == 30);
+ test(blso[2] == 20);
+ test(blso[3] == 10);
+ test(blso[4] == 30);
+ test(blso[5] == 20);
+ test([rso length] == 3 * sizeof(ICELong));
+ ICELong *brso = (ICELong *)[rso bytes];
+ test(brso[0] == 10);
+ test(brso[1] == 30);
+ test(brso[2] == 20);
+ }
+
+ {
+ ICEFloat buf1[] = { 3.14f, 1.11f };
+ ICEDouble buf2[] = { 1.1E10, 1.2E10, 1.3E10 };
+
+ TestOperationsMutableFloatS *fsi = [TestOperationsMutableFloatS data];
+ TestOperationsMutableDoubleS *dsi = [TestOperationsMutableDoubleS data];
+
+ [fsi appendBytes:buf1 length:sizeof(buf1)];
+ [dsi appendBytes:buf2 length:sizeof(buf2)];
+
+ TestOperationsMutableFloatS *fso;
+ TestOperationsMutableDoubleS *dso;
+ TestOperationsDoubleS *rso;
+
+ rso = [p opFloatDoubleS:fsi p2:dsi p3:&fso p4:&dso];
+
+ test([fso length] == 2 * sizeof(ICEFloat));
+ ICEFloat *bfso = (ICEFloat *)[fso bytes];
+ test(bfso[0] == 3.14f);
+ test(bfso[1] == 1.11f);
+ test([dso length] == 3 * sizeof(ICEDouble));
+ ICEDouble *bdso = (ICEDouble *)[dso bytes];
+ test(bdso[0] == 1.3E10);
+ test(bdso[1] == 1.2E10);
+ test(bdso[2] == 1.1E10);
+ test([rso length] == 5 * sizeof(ICEDouble));
+ ICEDouble *brso = (ICEDouble *)[rso bytes];
+ test(brso[0] == 1.1E10);
+ test(brso[1] == 1.2E10);
+ test(brso[2] == 1.3E10);
+ test((ICEFloat)brso[3] == 3.14f);
+ test((ICEFloat)brso[4] == 1.11f);
+ }
+
+ {
+ TestOperationsMutableStringS *ssi1 = [TestOperationsMutableStringS arrayWithCapacity:3];
+ TestOperationsMutableStringS *ssi2 = [TestOperationsMutableStringS arrayWithCapacity:1];
+
+ [ssi1 addObject:@"abc"];
+ [ssi1 addObject:@"de"];
+ [ssi1 addObject:@"fghi"];
+
+ [ssi2 addObject:@"xyz"];
+
+ TestOperationsMutableStringS *sso;
+ TestOperationsStringS *rso;
+
+ rso = [p opStringS:ssi1 p2:ssi2 p3:&sso];
+
+ test([sso count] == 4);
+ test([[sso objectAtIndex:0] isEqualToString:@"abc"]);
+ test([[sso objectAtIndex:1] isEqualToString:@"de"]);
+ test([[sso objectAtIndex:2] isEqualToString:@"fghi"]);
+ test([[sso objectAtIndex:3] isEqualToString:@"xyz"]);
+ test([rso count] == 3);
+ test([[rso objectAtIndex:0] isEqualToString:@"fghi"]);
+ test([[rso objectAtIndex:1] isEqualToString:@"de"]);
+ test([[rso objectAtIndex:2] isEqualToString:@"abc"]);
+ }
+
+ @try
+ {
+ TestOperationsMutableMyClassS *ssi1 = [TestOperationsMutableMyClassS arrayWithCapacity:3];
+ TestOperationsMutableMyClassS *ssi2 = [TestOperationsMutableMyClassS arrayWithCapacity:1];
+
+ ICEIdentity *i1 = [ICEIdentity identity:@"abc" category:@""];
+ ICEIdentity *i2 = [ICEIdentity identity:@"de" category:@""];
+ ICEIdentity *i3 = [ICEIdentity identity:@"fhgi" category:@""];
+ ICEIdentity *i4 = [ICEIdentity identity:@"xyz" category:@""];
+
+ [ssi1 addObject:[p ice_identity:i1]];
+ [ssi1 addObject:[p ice_identity:i2]];
+ [ssi1 addObject:[p ice_identity:i3]];
+
+ [ssi2 addObject:[p ice_identity:i4]];
+
+ TestOperationsMutableMyClassS *sso;
+ TestOperationsMyClassS *rso;
+
+ rso = [p opMyClassS:ssi1 p2:ssi2 p3:&sso];
+
+ test([sso count] == 4);
+ test([[[sso objectAtIndex:0] ice_getIdentity] isEqual:i1]);
+ test([[[sso objectAtIndex:1] ice_getIdentity] isEqual:i2]);
+ test([[[sso objectAtIndex:2] ice_getIdentity] isEqual:i3]);
+ test([[[sso objectAtIndex:3] ice_getIdentity] isEqual:i4]);
+ test([rso count] == 3);
+ test([[[rso objectAtIndex:0] ice_getIdentity] isEqual:i3]);
+ test([[[rso objectAtIndex:1] ice_getIdentity] isEqual:i2]);
+ test([[[rso objectAtIndex:2] ice_getIdentity] isEqual:i1]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Some mapping don't implement this method.
+ }
+
+ @try
+ {
+ TestOperationsMyEnum buf1[] = { TestOperationsenum2, TestOperationsenum3, TestOperationsenum3 };
+ TestOperationsMyEnum buf2[] = { TestOperationsenum1 };
+
+ TestOperationsMutableMyEnumS *esi1 = [TestOperationsMutableMyEnumS data];
+ TestOperationsMutableMyEnumS *esi2 = [TestOperationsMutableMyEnumS data];
+
+ [esi1 appendBytes:buf1 length:sizeof(buf1)];
+ [esi2 appendBytes:buf2 length:sizeof(buf2)];
+
+ TestOperationsMutableMyEnumS *eso;
+ TestOperationsMyEnumS *rso;
+
+ rso = [p opMyEnumS:esi1 p2:esi2 p3:&eso];
+
+ test([eso length] / sizeof(TestOperationsMyEnum) == 3);
+ const TestOperationsMyEnum *beso = (const TestOperationsMyEnum *)[eso bytes];
+ test(beso[0] == TestOperationsenum3);
+ test(beso[1] == TestOperationsenum3);
+ test(beso[2] == TestOperationsenum2);
+ test([rso length] / sizeof(TestOperationsMyEnum) == 4);
+ const TestOperationsMyEnum *brso = (const TestOperationsMyEnum *)[rso bytes];
+ test(brso[0] == TestOperationsenum2);
+ test(brso[1] == TestOperationsenum3);
+ test(brso[2] == TestOperationsenum3);
+ test(brso[3] == TestOperationsenum1);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ // Some mapping don't implement this method.
+ }
+
+ {
+ TestOperationsMutableByteSS *bsi1 = [TestOperationsMutableByteSS array];
+ TestOperationsMutableByteSS *bsi2 = [TestOperationsMutableByteSS array];
+
+ ICEByte b;
+ TestOperationsMutableByteS *tmp = [TestOperationsMutableByteS data];
+
+ b = 0x01;
+ [tmp appendBytes:&b length:sizeof(b)];
+ b = 0x11;
+ [tmp appendBytes:&b length:sizeof(b)];
+ b = 0x12;
+ [tmp appendBytes:&b length:sizeof(b)];
+ [bsi1 addObject:tmp];
+
+ tmp = [TestOperationsMutableByteS data];
+ b = 0xff;
+ [tmp appendBytes:&b length:sizeof(b)];
+ [bsi1 addObject:tmp];
+
+ tmp = [TestOperationsMutableByteS data];
+ b = 0x0e;
+ [tmp appendBytes:&b length:sizeof(b)];
+ [bsi2 addObject:tmp];
+
+ tmp = [TestOperationsMutableByteS data];
+ b = 0xf2;
+ [tmp appendBytes:&b length:sizeof(b)];
+ b = 0xf1;
+ [tmp appendBytes:&b length:sizeof(b)];
+ [bsi2 addObject:tmp];
+
+ TestOperationsMutableByteSS *bso;
+ TestOperationsByteSS *rso;
+
+ rso = [p opByteSS:bsi1 p2:bsi2 p3:&bso];
+
+ const ICEByte *p;
+ test([bso count] == 2);
+ test([[bso objectAtIndex:0] length] / sizeof(ICEByte) == 1);
+ p = [[bso objectAtIndex:0] bytes];
+ test(p[0] == (ICEByte)0x0ff);
+ test([[bso objectAtIndex:1] length] / sizeof(ICEByte) == 3);
+ p = [[bso objectAtIndex:1] bytes];
+ test(p[0] == (ICEByte)0x01);
+ test(p[1] == (ICEByte)0x11);
+ test(p[2] == (ICEByte)0x12);
+ test([rso count] == 4);
+ test([[rso objectAtIndex:0] length] / sizeof(ICEByte) == 3);
+ p = [[rso objectAtIndex:0] bytes];
+ test(p[0] == (ICEByte)0x01);
+ test(p[1] == (ICEByte)0x11);
+ test(p[2] == (ICEByte)0x12);
+ test([[rso objectAtIndex:1] length] / sizeof(ICEByte) == 1);
+ p = [[rso objectAtIndex:1] bytes];
+ test(p[0] == (ICEByte)0xff);
+ test([[rso objectAtIndex:2] length] / sizeof(ICEByte) == 1);
+ p = [[rso objectAtIndex:2] bytes];
+ test(p[0] == (ICEByte)0x0e);
+ test([[rso objectAtIndex:3] length] / sizeof(ICEByte) == 2);
+ p = [[rso objectAtIndex:3] bytes];
+ test(p[0] == (ICEByte)0xf2);
+ test(p[1] == (ICEByte)0xf1);
+ }
+
+ {
+ TestOperationsMutableFloatSS *fsi = [TestOperationsMutableFloatSS array];
+ TestOperationsMutableDoubleSS *dsi = [TestOperationsMutableDoubleSS array];
+
+ ICEFloat f;
+ TestOperationsMutableFloatS *ftmp;
+
+ ftmp = [TestOperationsMutableFloatS data];
+ f = 3.14f;
+ [ftmp appendBytes:&f length:sizeof(f)];
+ [fsi addObject:ftmp];
+ ftmp = [TestOperationsMutableFloatS data];
+ f = 1.11f;
+ [ftmp appendBytes:&f length:sizeof(f)];
+ [fsi addObject:ftmp];
+ ftmp = [TestOperationsMutableFloatS data];
+ [fsi addObject:ftmp];
+
+ ICEDouble d;
+ TestOperationsMutableDoubleS *dtmp;
+
+ dtmp = [TestOperationsMutableDoubleS data];
+ d = 1.1E10;
+ [dtmp appendBytes:&d length:sizeof(d)];
+ d = 1.2E10;
+ [dtmp appendBytes:&d length:sizeof(d)];
+ d = 1.3E10;
+ [dtmp appendBytes:&d length:sizeof(d)];
+ [dsi addObject:dtmp];
+
+ TestOperationsMutableFloatSS *fso;
+ TestOperationsMutableDoubleSS *dso;
+ TestOperationsDoubleSS *rso;
+
+ rso = [p opFloatDoubleSS:fsi p2:dsi p3:&fso p4:&dso];
+
+ const ICEFloat *fp;
+ const ICEDouble *dp;
+
+ test([fso count] == 3);
+ test([[fso objectAtIndex:0] length] / sizeof(ICEFloat) == 1);
+ fp = [[fso objectAtIndex:0] bytes];
+ test(fp[0] == 3.14f);
+ test([[fso objectAtIndex:1] length] / sizeof(ICEFloat) == 1);
+ fp = [[fso objectAtIndex:1] bytes];
+ test(fp[0] == 1.11f);
+ test([[fso objectAtIndex:2] length] / sizeof(ICEFloat) == 0);
+ test([dso count] == 1);
+ test([[dso objectAtIndex:0] length] / sizeof(ICEDouble) == 3);
+ dp = [[dso objectAtIndex:0] bytes];
+ test(dp[0] == 1.1E10);
+ test(dp[1] == 1.2E10);
+ test(dp[2] == 1.3E10);
+ test([rso count] == 2);
+ test([[rso objectAtIndex:0] length] / sizeof(ICEDouble) == 3);
+ dp = [[rso objectAtIndex:0] bytes];
+ test(dp[0] == 1.1E10);
+ test(dp[1] == 1.2E10);
+ test(dp[2] == 1.3E10);
+ test([[rso objectAtIndex:1] length] / sizeof(ICEDouble) == 3);
+ dp = [[rso objectAtIndex:1] bytes];
+ test(dp[0] == 1.1E10);
+ test(dp[1] == 1.2E10);
+ test(dp[2] == 1.3E10);
+ }
+
+ {
+ TestOperationsMutableStringSS * ssi1 = [TestOperationsMutableStringSS array];
+ TestOperationsMutableStringSS * ssi2 = [TestOperationsMutableStringSS array];
+
+ TestOperationsMutableStringS *tmp;
+
+ tmp = [TestOperationsMutableStringS array];
+ [tmp addObject:@"abc"];
+ [ssi1 addObject:tmp];
+ tmp = [TestOperationsMutableStringS array];
+ [tmp addObject:@"de"];
+ [tmp addObject:@"fghi"];
+ [ssi1 addObject:tmp];
+
+ [ssi2 addObject:[TestOperationsStringS array]];
+ [ssi2 addObject:[TestOperationsStringS array]];
+ tmp = [TestOperationsMutableStringS array];
+ [tmp addObject:@"xyz"];
+ [ssi2 addObject:tmp];
+
+ TestOperationsMutableStringSS *sso;
+ TestOperationsStringSS *rso;
+
+ rso = [p opStringSS:ssi1 p2:ssi2 p3:&sso];
+
+ test([sso count] == 5);
+ test([[sso objectAtIndex:0] count] == 1);
+ test([[[sso objectAtIndex:0] objectAtIndex:0] isEqualToString:@"abc"]);
+ test([[sso objectAtIndex:1] count] == 2);
+ test([[[sso objectAtIndex:1] objectAtIndex:0] isEqualToString:@"de"]);
+ test([[[sso objectAtIndex:1] objectAtIndex:1] isEqualToString:@"fghi"]);
+ test([[sso objectAtIndex:2] count] == 0);
+ test([[sso objectAtIndex:3] count] == 0);
+ test([[sso objectAtIndex:4] count] == 1);
+ test([[[sso objectAtIndex:4] objectAtIndex:0] isEqualToString:@"xyz"]);
+ test([rso count] == 3);
+ test([[rso objectAtIndex:0] count] == 1);
+ test([[[rso objectAtIndex:0] objectAtIndex:0] isEqualToString:@"xyz"]);
+ test([[rso objectAtIndex:1] count] == 0);
+ test([[rso objectAtIndex:2] count] == 0);
+ }
+
+ {
+ TestOperationsMutableStringSSS *sssi1 = [TestOperationsMutableStringSSS array];
+ TestOperationsMutableStringSSS *sssi2 = [TestOperationsMutableStringSSS array];
+
+ TestOperationsMutableStringSS *tmpss;
+ TestOperationsMutableStringS *tmps;
+
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@"abc"];
+ [tmps addObject:@"de"];
+ tmpss = [TestOperationsMutableStringSS array];
+ [tmpss addObject:tmps];
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@"xyz"];
+ [tmpss addObject:tmps];
+ [sssi1 addObject:tmpss];
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@"hello"];
+ tmpss = [TestOperationsMutableStringSS array];
+ [tmpss addObject:tmps];
+ [sssi1 addObject:tmpss];
+
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@""];
+ [tmps addObject:@""];
+ tmpss = [TestOperationsMutableStringSS array];
+ [tmpss addObject:tmps];
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@"abcd"];
+ [tmpss addObject:tmps];
+ [sssi2 addObject:tmpss];
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@""];
+ tmpss = [TestOperationsMutableStringSS array];
+ [tmpss addObject:tmps];
+ [sssi2 addObject:tmpss];
+ tmpss = [TestOperationsMutableStringSS array];
+ [sssi2 addObject:tmpss];
+
+ TestOperationsMutableStringSSS *ssso;
+ TestOperationsStringSSS *rsso;
+
+ rsso = [p opStringSSS:sssi1 p2:sssi2 p3:&ssso];
+
+ test([ssso count] == 5);
+ test([[ssso objectAtIndex:0] count] == 2);
+ test([[[ssso objectAtIndex:0] objectAtIndex:0] count] == 2);
+ test([[[ssso objectAtIndex:0] objectAtIndex:1] count] == 1);
+ test([[ssso objectAtIndex:1] count] == 1);
+ test([[[ssso objectAtIndex:1] objectAtIndex:0] count] == 1);
+ test([[ssso objectAtIndex:2] count] == 2);
+ test([[[ssso objectAtIndex:2] objectAtIndex:0] count] == 2);
+ test([[[ssso objectAtIndex:2] objectAtIndex:1] count] == 1);
+ test([[ssso objectAtIndex:3] count] == 1);
+ test([[[ssso objectAtIndex:3] objectAtIndex:0] count] == 1);
+ test([[ssso objectAtIndex:4] count] == 0);
+ test([[[[ssso objectAtIndex:0] objectAtIndex:0] objectAtIndex:0] isEqualToString:@"abc"]);
+ test([[[[ssso objectAtIndex:0] objectAtIndex:0] objectAtIndex:1] isEqualToString:@"de"]);
+ test([[[[ssso objectAtIndex:0] objectAtIndex:1] objectAtIndex:0] isEqualToString:@"xyz"]);
+ test([[[[ssso objectAtIndex:1] objectAtIndex:0] objectAtIndex:0] isEqualToString:@"hello"]);
+ test([[[[ssso objectAtIndex:2] objectAtIndex:0] objectAtIndex:0] isEqualToString:@""]);
+ test([[[[ssso objectAtIndex:2] objectAtIndex:0] objectAtIndex:1] isEqualToString:@""]);
+ test([[[[ssso objectAtIndex:2] objectAtIndex:1] objectAtIndex:0] isEqualToString:@"abcd"]);
+ test([[[[ssso objectAtIndex:3] objectAtIndex:0] objectAtIndex:0] isEqualToString:@""]);
+
+ test([rsso count] == 3);
+ test([[rsso objectAtIndex:0] count] == 0);
+ test([[rsso objectAtIndex:1] count] == 1);
+ test([[[rsso objectAtIndex:1] objectAtIndex:0] count] == 1);
+ test([[rsso objectAtIndex:2] count] == 2);
+ test([[[rsso objectAtIndex:2] objectAtIndex:0] count] == 2);
+ test([[[rsso objectAtIndex:2] objectAtIndex:1] count] == 1);
+ test([[[[rsso objectAtIndex:1] objectAtIndex:0] objectAtIndex:0] isEqualToString:@""]);
+ test([[[[rsso objectAtIndex:2] objectAtIndex:0] objectAtIndex:0] isEqualToString:@""]);
+ test([[[[rsso objectAtIndex:2] objectAtIndex:0] objectAtIndex:1] isEqualToString:@""]);
+ test([[[[rsso objectAtIndex:2] objectAtIndex:1] objectAtIndex:0] isEqualToString:@"abcd"]);
+ }
+
+ {
+ TestOperationsMutableByteBoolD *di1 = [TestOperationsMutableByteBoolD dictionary];
+ [di1 setObject:[NSNumber numberWithBool:YES] forKey:[NSNumber numberWithUnsignedChar:10]];
+ [di1 setObject:[NSNumber numberWithBool:NO] forKey:[NSNumber numberWithUnsignedChar:100]];
+ TestOperationsMutableByteBoolD *di2 = [TestOperationsMutableByteBoolD dictionary];
+ [di2 setObject:[NSNumber numberWithBool:YES] forKey:[NSNumber numberWithUnsignedChar:10]];
+ [di2 setObject:[NSNumber numberWithBool:NO] forKey:[NSNumber numberWithUnsignedChar:11]];
+ [di2 setObject:[NSNumber numberWithBool:TRUE] forKey:[NSNumber numberWithUnsignedChar:101]];
+
+ TestOperationsMutableByteBoolD *_do;
+ TestOperationsMutableByteBoolD *ro = [p opByteBoolD:di1 p2:di2 p3:&_do];
+
+ test([_do isEqualToDictionary:di1]);
+ test([ro count] == 4);
+ test([[ro objectForKey:[NSNumber numberWithUnsignedChar:10]] boolValue] == YES);
+ test([[ro objectForKey:[NSNumber numberWithUnsignedChar:11]] boolValue] == NO);
+ test([[ro objectForKey:[NSNumber numberWithUnsignedChar:100]] boolValue] == NO);
+ test([[ro objectForKey:[NSNumber numberWithUnsignedChar:101]] boolValue] == YES);
+ }
+
+ {
+ TestOperationsMutableShortIntD *di1 = [TestOperationsMutableShortIntD dictionary];
+ [di1 setObject:[NSNumber numberWithInt:-1] forKey:[NSNumber numberWithShort:110]];
+ [di1 setObject:[NSNumber numberWithInt:123123] forKey:[NSNumber numberWithShort:1100]];
+ TestOperationsMutableShortIntD *di2 = [TestOperationsMutableShortIntD dictionary];
+ [di2 setObject:[NSNumber numberWithInt:-1] forKey:[NSNumber numberWithShort:110]];
+ [di2 setObject:[NSNumber numberWithInt:-100] forKey:[NSNumber numberWithShort:111]];
+ [di2 setObject:[NSNumber numberWithInt:0] forKey:[NSNumber numberWithShort:1101]];
+
+ TestOperationsMutableShortIntD *_do;
+ TestOperationsMutableShortIntD *ro = [p opShortIntD:di1 p2:di2 p3:&_do];
+
+ test([_do isEqualToDictionary:di1]);
+ test([ro count] == 4);
+ test([[ro objectForKey:[NSNumber numberWithShort:110]] intValue] == -1);
+ test([[ro objectForKey:[NSNumber numberWithShort:111]] intValue] == -100);
+ test([[ro objectForKey:[NSNumber numberWithShort:1100]] intValue] == 123123);
+ test([[ro objectForKey:[NSNumber numberWithShort:1101]] intValue] == 0);
+ }
+
+ {
+ TestOperationsMutableLongFloatD *di1 = [TestOperationsMutableLongFloatD dictionary];
+ [di1 setObject:[NSNumber numberWithFloat:-1.1f] forKey:[NSNumber numberWithLong:999999110]];
+ [di1 setObject:[NSNumber numberWithFloat:123123.2f] forKey:[NSNumber numberWithLong:999999111]];
+ TestOperationsMutableLongFloatD *di2 = [TestOperationsMutableLongFloatD dictionary];
+ [di2 setObject:[NSNumber numberWithFloat:-1.1f] forKey:[NSNumber numberWithLong:999999110]];
+ [di2 setObject:[NSNumber numberWithFloat:-100.4f] forKey:[NSNumber numberWithLong:999999120]];
+ [di2 setObject:[NSNumber numberWithFloat:0.5f] forKey:[NSNumber numberWithLong:999999130]];
+
+ TestOperationsMutableLongFloatD *_do;
+ TestOperationsMutableLongFloatD *ro = [p opLongFloatD:di1 p2:di2 p3:&_do];
+
+ test([_do isEqualToDictionary:di1]);
+ test([ro count] == 4);
+ test((ICEFloat)[[ro objectForKey:[NSNumber numberWithLong:999999110]] floatValue] == -1.1f);
+ test((ICEFloat)[[ro objectForKey:[NSNumber numberWithLong:999999120]] floatValue] == -100.4f);
+ test((ICEFloat)[[ro objectForKey:[NSNumber numberWithLong:999999111]] floatValue] == 123123.2f);
+ test((ICEFloat)[[ro objectForKey:[NSNumber numberWithLong:999999130]] floatValue] == 0.5f);
+ }
+
+ {
+ TestOperationsMutableStringStringD *di1 = [TestOperationsMutableStringStringD dictionary];
+ [di1 setObject:@"abc -1.1" forKey:@"foo"];
+ [di1 setObject:@"abc 123123.2" forKey:@"bar"];
+ TestOperationsMutableStringStringD *di2 = [TestOperationsMutableStringStringD dictionary];
+ [di2 setObject:@"abc -1.1" forKey:@"foo"];
+ [di2 setObject:@"abc -100.4" forKey:@"FOO"];
+ [di2 setObject:@"abc 0.5" forKey:@"BAR"];
+
+ TestOperationsMutableStringStringD *_do;
+ TestOperationsMutableStringStringD *ro = [p opStringStringD:di1 p2:di2 p3:&_do];
+
+ test([_do isEqualToDictionary:di1]);
+ test([ro count] == 4);
+ test([[ro objectForKey:@"foo"] isEqualToString:@"abc -1.1"]);
+ test([[ro objectForKey:@"FOO"] isEqualToString:@"abc -100.4"]);
+ test([[ro objectForKey:@"bar"] isEqualToString:@"abc 123123.2"]);
+ test([[ro objectForKey:@"BAR"] isEqualToString:@"abc 0.5"]);
+ }
+
+ {
+ TestOperationsMutableStringMyEnumD *di1 = [TestOperationsMutableStringMyEnumD dictionary];
+ [di1 setObject:[NSNumber numberWithInt:TestOperationsenum1] forKey:@"abc"];
+ [di1 setObject:[NSNumber numberWithInt:TestOperationsenum2] forKey:@""];
+ TestOperationsMutableStringMyEnumD *di2 = [TestOperationsMutableStringMyEnumD dictionary];
+ [di2 setObject:[NSNumber numberWithInt:TestOperationsenum1] forKey:@"abc"];
+ [di2 setObject:[NSNumber numberWithInt:TestOperationsenum3] forKey:@"querty"];
+ [di2 setObject:[NSNumber numberWithInt:TestOperationsenum2] forKey:@"Hello!!"];
+
+ TestOperationsMutableStringMyEnumD *_do;
+ TestOperationsMutableStringMyEnumD *ro = [p opStringMyEnumD:di1 p2:di2 p3:&_do];
+
+ test([_do isEqualToDictionary:di1]);
+ test([ro count] == 4);
+ test([[ro objectForKey:@"abc"] intValue] == TestOperationsenum1);
+ test([[ro objectForKey:@"querty"] intValue] == TestOperationsenum3);
+ test([[ro objectForKey:@""] intValue] == TestOperationsenum2);
+ test([[ro objectForKey:@"Hello!!"] intValue] == TestOperationsenum2);
+ }
+
+ {
+ TestOperationsMutableMyEnumStringD *di1 = [TestOperationsMutableMyEnumStringD dictionary];
+ [di1 setObject:@"abc" forKey:@(TestOperationsenum1)];
+ TestOperationsMutableMyEnumStringD *di2 = [TestOperationsMutableMyEnumStringD dictionary];
+ [di2 setObject:@"Hello!!" forKey:@(TestOperationsenum2)];
+ [di2 setObject:@"querty" forKey:@(TestOperationsenum3)];
+
+ TestOperationsMutableMyEnumStringD *_do;
+ TestOperationsMutableMyEnumStringD *ro = [p opMyEnumStringD:di1 p2:di2 p3:&_do];
+
+ test([_do isEqualToDictionary:di1]);
+ test([ro count] == 3);
+ test([[ro objectForKey:@(TestOperationsenum1)] isEqualToString:@"abc"]);
+ test([[ro objectForKey:@(TestOperationsenum3)] isEqualToString:@"querty"]);
+ test([[ro objectForKey:@(TestOperationsenum2)] isEqualToString:@"Hello!!"]);
+ }
+
+ {
+ TestOperationsMyStruct* s11 = [TestOperationsMyStruct myStruct:1 j:1];
+ TestOperationsMyStruct* s12 = [TestOperationsMyStruct myStruct:1 j:2];
+ TestOperationsMutableMyStructMyEnumD* di1 = [TestOperationsMutableMyStructMyEnumD dictionary];
+ [di1 setObject:@(TestOperationsenum1) forKey:s11];
+ [di1 setObject:@(TestOperationsenum2) forKey:s12];
+
+ TestOperationsMyStruct* s22 = [TestOperationsMyStruct myStruct:2 j:2];
+ TestOperationsMyStruct* s23 = [TestOperationsMyStruct myStruct:2 j:3];
+ TestOperationsMutableMyStructMyEnumD* di2 = [TestOperationsMutableMyStructMyEnumD dictionary];
+ [di2 setObject:@(TestOperationsenum1) forKey:s11];
+ [di2 setObject:@(TestOperationsenum3) forKey:s22];
+ [di2 setObject:@(TestOperationsenum2) forKey:s23];
+
+ TestOperationsMutableMyStructMyEnumD* _do;
+ TestOperationsMyStructMyEnumD* ro = [p opMyStructMyEnumD:di1 p2:di2 p3:&_do];
+
+ test([_do isEqual:di1]);
+ test([ro count] == 4);
+ test([[ro objectForKey:s11] isEqual:@(TestOperationsenum1)]);
+ test([[ro objectForKey:s12] isEqual:@(TestOperationsenum2)]);
+ test([[ro objectForKey:s22] isEqual:@(TestOperationsenum3)]);
+ test([[ro objectForKey:s23] isEqual:@(TestOperationsenum2)]);
+ }
+
+ {
+ const int lengths[] = { 0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000 };
+
+ int l;
+ for(l = 0; l != sizeof(lengths) / sizeof(*lengths); ++l)
+ {
+ TestOperationsMutableIntS *s = [TestOperationsMutableIntS dataWithLength:(lengths[l] * sizeof(ICEInt))];
+ ICEInt *ip = (ICEInt *)[s bytes];
+ int i;
+ for(i = 0; i < lengths[l]; ++i)
+ {
+ *ip++ = i;
+ }
+ TestOperationsIntS *r = [p opIntS:s];
+ test([r length] == lengths[l] * sizeof(ICEInt));
+ const ICEInt *rp = [r bytes];
+ int j;
+ for(j = 0; j < [r length] / sizeof(ICEInt); ++j)
+ {
+ test(rp[j] == -j);
+ }
+ }
+ }
+
+ {
+ ICEMutableContext *ctx = [ICEMutableContext dictionary];
+ [ctx setObject:@"ONE" forKey:@"one"];
+ [ctx setObject:@"TWO" forKey:@"two"];
+ [ctx setObject:@"THREE" forKey:@"three"];
+ {
+ ICEContext *r = [p opContext];
+ test([[p ice_getContext] count] == 0);
+ test(![r isEqual:ctx]);
+ }
+ {
+ ICEContext *r = [p opContext:ctx];
+ test([[p ice_getContext] count] == 0);
+ test([r isEqual:ctx]);
+ }
+ {
+ id<TestOperationsMyClassPrx> p2 = [TestOperationsMyClassPrx checkedCast:[p ice_context:ctx]];
+ test([[p2 ice_getContext] isEqual:ctx]);
+ ICEContext *r = [p2 opContext];
+ test([r isEqual:ctx]);
+ r = [p2 opContext:ctx];
+ test([r isEqual:ctx]);
+ }
+ }
+
+
+ {
+ //
+ // TestOperations implicit context propagation
+ //
+ NSString *impls[] = { @"Shared", @"PerThread" };
+ int i;
+ for(i = 0; i < 2; i++)
+ {
+ ICEInitializationData *initData = [ICEInitializationData initializationData];
+ initData.properties = [[communicator getProperties] clone];
+ [initData.properties setProperty:@"Ice.ImplicitContext" value:impls[i]];
+
+ id<ICECommunicator> ic = [ICEUtil createCommunicator:initData];
+
+ ICEMutableContext *ctx = [ICEMutableContext dictionary];
+ [ctx setObject:@"ONE" forKey:@"one" ];
+ [ctx setObject:@"TWO" forKey:@"two" ];
+ [ctx setObject:@"THREE" forKey:@"three"];
+
+ id<TestOperationsMyClassPrx> p = [TestOperationsMyClassPrx uncheckedCast:[ic stringToProxy:@"test:default -p 12010"]];
+
+ [[ic getImplicitContext] setContext:ctx];
+ test([[[ic getImplicitContext] getContext] isEqual:ctx]);
+ test([[p opContext] isEqual:ctx]);
+
+ test([[ic getImplicitContext] get:@"zero"] == nil);
+ [[ic getImplicitContext] put:@"zero" value:@"ZERO"];
+ test([[[ic getImplicitContext] get:@"zero"] isEqualToString:@"ZERO"]);
+
+ ctx = [[ic getImplicitContext] getContext];
+ test([[p opContext] isEqual:ctx]);
+
+ ICEMutableContext *prxContext = [ICEMutableContext dictionary];
+ [prxContext setObject:@"UN" forKey:@"one"];
+ [prxContext setObject:@"QUATRE" forKey:@"four"];
+
+ ICEMutableContext *combined = [ICEMutableContext dictionaryWithDictionary:ctx];
+ [combined addEntriesFromDictionary:prxContext];
+
+ p = [TestOperationsMyClassPrx uncheckedCast:[p ice_context:prxContext]];
+
+ [[ic getImplicitContext] setContext:[ICEContext dictionary]];
+ test([[p opContext] isEqualToDictionary:prxContext]);
+
+ [[ic getImplicitContext] setContext:ctx];
+ test([[p opContext] isEqualToDictionary:combined]);
+
+ test([[[ic getImplicitContext] get:@"one"] isEqualToString:@"ONE"]);
+ [[ic getImplicitContext] remove:@"one"];
+
+ if([impls[i] isEqualToString:@"PerThread"])
+ {
+ PerThreadContextInvokeThread* thread = [PerThreadContextInvokeThread create:[p ice_context:[ICEMutableContext dictionary]]];
+ [thread start];
+ [thread join];
+ }
+
+ [[ic getImplicitContext] setContext:[ICEContext dictionary]];
+ [ic destroy];
+ }
+ }
+
+ {
+ ICEDouble d = 1278312346.0 / 13.0;
+ TestOperationsMutableDoubleS *ds = [TestOperationsMutableDoubleS dataWithLength:(5 * sizeof(ICEDouble))];
+ ICEDouble *pb = (ICEDouble *)[ds bytes];
+ int i = 5;
+ while(i-- > 0)
+ {
+ *pb++ = d;
+ }
+ [p opDoubleMarshaling:d p2:ds];
+ }
+
+ [p opIdempotent];
+
+ [p opNonmutating];
+
+ //
+ // TestOperationss below are for Objective-C only. They test that we do the right thing if NSNull
+ // is passed as part of the sequence or dictionary.
+ //
+ @try
+ {
+ {
+ TestOperationsStringS *s = [p getNSNullStringSeq];
+ test([s count] == 2);
+ test([[s objectAtIndex:0] isEqualToString:@"first"]);
+ test([[s objectAtIndex:1] isEqualToString:@""]);
+ }
+
+ {
+ TestOperationsAS *s = [p getNSNullASeq];
+ test([s count] == 2);
+ test(((TestOperationsA *)[s objectAtIndex:0]).i == 99);
+ test([s objectAtIndex:1] == [NSNull null]);
+ }
+
+ {
+ TestOperationsStructS *seq = [p getNSNullStructSeq];
+ test([seq count] == 2);
+ TestOperationsStructure *s = [seq objectAtIndex:0];
+ test(s.p == nil);
+ test(s.e == TestOperationsenum2);
+ test([s.s.s isEqualToString:@"Hello"]);
+ s = [seq objectAtIndex:1];
+ test(s.p == nil);
+ test(s.e == TestOperationsenum1);
+ test([s.s.s isEqualToString:@""]);
+ }
+
+ {
+ TestOperationsStringSS *seq = [p getNSNullStringSeqSeq];
+ test([seq count] == 2);
+ TestOperationsStringS *s = [seq objectAtIndex:0];
+ test([s count] == 1);
+ test([(NSString *)[s objectAtIndex:0] isEqualToString:@"first"]);
+ s = [seq objectAtIndex:1];
+ test([s count] == 0);
+ }
+
+ {
+ TestOperationsStringStringD *d = [p getNSNullStringStringDict];
+ test([d count] == 2);
+ test([(NSString *)[d objectForKey:@"one"] isEqualToString:@"ONE"]);
+ test([(NSString *)[d objectForKey:@"two"] isEqualToString:@""]);
+ }
+
+ {
+ @try
+ {
+ TestOperationsMutableStringStringD *d = [TestOperationsMutableStringStringD dictionary];
+ [d setObject:@"bad key" forKey:[NSNull null]];
+ [p putNSNullStringStringDict:d];
+ test(NO);
+ }
+ @catch(ICEMarshalException *)
+ {
+ // Expected
+ }
+ }
+
+ {
+ @try
+ {
+ TestOperationsMutableShortIntD *d = [TestOperationsMutableShortIntD dictionary];
+ [d setObject:[NSNull null] forKey:[NSNumber numberWithInt:1]];
+ [p putNSNullShortIntDict:d];
+ test(NO);
+ }
+ @catch(ICEMarshalException *)
+ {
+ // Expected
+ }
+ }
+
+ {
+ @try
+ {
+ TestOperationsMutableStringMyEnumD *d = [TestOperationsMutableStringMyEnumD dictionary];
+ [d setObject:[NSNull null] forKey:@"key"];
+ [p putNSNullStringMyEnumDict:d];
+ test(NO);
+ }
+ @catch(ICEMarshalException *)
+ {
+ // Expected
+ }
+ }
+ }
+ @catch(ICEOperationNotExistException *)
+ {
+ // Client is talking to non-Objective-C server.
+ }
+}
diff --git a/objc/test/Ice/operations/TwowaysNewAMI.m b/objc/test/Ice/operations/TwowaysNewAMI.m
new file mode 100644
index 00000000000..4a097985de3
--- /dev/null
+++ b/objc/test/Ice/operations/TwowaysNewAMI.m
@@ -0,0 +1,1186 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OperationsTest.h>
+#import <limits.h>
+#import <float.h>
+
+#import <Foundation/Foundation.h>
+
+@interface TestNewAMIOperationsCallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+}
+-(BOOL) check;
+-(void) called;
+@end
+
+@implementation TestNewAMIOperationsCallback
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
++(id) create
+{
+#if defined(__clang__) && __has_feature(objc_arc)
+ return [[TestNewAMIOperationsCallback alloc] init];
+#else
+ return [[[TestNewAMIOperationsCallback alloc] init] autorelease];
+#endif
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(BOOL) check
+{
+ [cond lock];
+ while(!called)
+ {
+ if(![cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:50]])
+ {
+ return NO;
+ }
+ }
+ called = NO;
+ [cond unlock];
+ return YES;
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) opVoidExResponse
+{
+ test(NO);
+}
+-(void) opVoidExException:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICENoEndpointException class]]);
+ [self called];
+}
+-(void) opVoidResponse
+{
+ [self called];
+}
+-(void) opVoidException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opByteExResponse:(ICEByte)ret p3:(ICEByte)p3
+{
+ test(NO);
+}
+-(void) opByteExException:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICENoEndpointException class]]);
+ [self called];
+}
+-(void) opByteResponse:(ICEByte)ret p3:(ICEByte)p3
+{
+ [self called];
+}
+-(void) opByteException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opBoolResponse:(BOOL)r p3:(BOOL)b
+{
+ test(b);
+ test(!r);
+ [self called];
+}
+-(void) opBoolException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opShortIntLongResponse:(ICELong)r p4:(ICEShort)s p5:(ICEInt)i p6:(ICELong)l
+{
+ test(s == 10);
+ test(i == 11);
+ test(l == 12);
+ test(r == 12);
+ [self called];
+}
+-(void) opShortIntLongException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opFloatDoubleResponse:(ICEDouble)r p3:(ICEFloat)f p4:(ICEDouble)d
+{
+ test(f == 3.14f);
+ test(d == 1.1E10);
+ test(r == 1.1E10);
+ [self called];
+}
+-(void) opFloatDoubleException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opStringResponse:(NSString*)r p3:(NSString*)s
+{
+ test([s isEqualToString:@"world hello"]);
+ test([r isEqualToString:@"hello world"]);
+ [self called];
+}
+
+-(void) opStringException:(ICEException*)ex
+{
+ test(NO);
+};
+
+-(void) opMyEnumResponse:(TestOperationsMyEnum)r p2:(TestOperationsMyEnum)e
+{
+ test(e == TestOperationsenum2);
+ test(r == TestOperationsenum3);
+ [self called];
+}
+
+-(void) opMyEnumException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opMyClassResponse:(id<TestOperationsMyClassPrx>)r p2:(id<TestOperationsMyClassPrx>)c1 p3:(id<TestOperationsMyClassPrx>)c2
+{
+ test([[c1 ice_getIdentity] isEqual:[[c1 ice_getCommunicator] stringToIdentity:@"test"]]);
+ test([[c2 ice_getIdentity] isEqual:[[c1 ice_getCommunicator] stringToIdentity:@"noSuchIdentity"]]);
+ test([[r ice_getIdentity] isEqual:[[c1 ice_getCommunicator] stringToIdentity:@"test"]]);
+ // We can't do the callbacks below in connection serialization mode.
+ if([[[c1 ice_getCommunicator] getProperties] getPropertyAsInt:@"Ice.ThreadPool.Client.Serialize"])
+ {
+ [r opVoid];
+ [c1 opVoid];
+ @try
+ {
+ [c2 opVoid];
+ test(NO);
+ }
+ @catch(ICEObjectNotExistException*)
+ {
+ }
+ }
+ [self called];
+}
+
+-(void) opMyClassException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opStructResponse:(TestOperationsStructure*)rso p3:(TestOperationsStructure*)so
+{
+ test(rso.p == nil);
+ test(rso.e == TestOperationsenum2);
+ test([rso.s.s isEqualToString:@"def"]);
+ test([so e] == TestOperationsenum3);
+ test(so.p != nil);
+ test([so.s.s isEqualToString:@"a new string"]);
+ // We can't do the callbacks below in connection serialization mode.
+ if([[[so.p ice_getCommunicator] getProperties] getPropertyAsInt:@"Ice.ThreadPool.Client.Serialize"])
+ {
+ [so.p opVoid];
+ }
+ [self called];
+}
+
+-(void) opStructException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opByteSResponse:(TestOperationsByteS*)rso p3:(TestOperationsByteS*)bso
+{
+ test([bso length] == 4);
+ ICEByte *bbso = (ICEByte *)[bso bytes];
+ test(bbso[0] == 0x22);
+ test(bbso[1] == 0x12);
+ test(bbso[2] == 0x11);
+ test(bbso[3] == 0x01);
+ test([rso length] == 8);
+ ICEByte *brso = (ICEByte *)[rso bytes];
+ test(brso[0] == 0x01);
+ test(brso[1] == 0x11);
+ test(brso[2] == 0x12);
+ test(brso[3] == 0x22);
+ test(brso[4] == 0xf1);
+ test(brso[5] == 0xf2);
+ test(brso[6] == 0xf3);
+ test(brso[7] == 0xf4);
+ [self called];
+}
+
+-(void) opByteSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opBoolSResponse:(TestOperationsBoolS*)rso p3:(TestOperationsBoolS*)bso
+{
+ test([bso length] == 4 * sizeof(BOOL));
+ BOOL *bbso = (BOOL *)[bso bytes];
+ test(bbso[0]);
+ test(bbso[1]);
+ test(!bbso[2]);
+ test(!bbso[3]);
+ test([rso length] == 3 * sizeof(BOOL));
+ BOOL *brso = (BOOL *)[rso bytes];
+ test(!brso[0]);
+ test(brso[1]);
+ test(brso[2]);
+ [self called];
+}
+
+-(void) opBoolSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opShortIntLongSResponse:(TestOperationsLongS*)rso p4:(TestOperationsShortS*)sso p5:(TestOperationsIntS*)iso p6:(TestOperationsLongS*)lso
+{
+ test([sso length] == 3 * sizeof(ICEShort));
+ ICEShort *bsso = (ICEShort *)[sso bytes];
+ test(bsso[0] == 1);
+ test(bsso[1] == 2);
+ test(bsso[2] == 3);
+ test([iso length] == 4 * sizeof(ICEInt));
+ ICEInt *biso = (ICEInt *)[iso bytes];
+ test(biso[0] == 8);
+ test(biso[1] == 7);
+ test(biso[2] == 6);
+ test(biso[3] == 5);
+ test([lso length] == 6 * sizeof(ICELong));
+ ICELong *blso = (ICELong *)[lso bytes];
+ test(blso[0] == 10);
+ test(blso[1] == 30);
+ test(blso[2] == 20);
+ test(blso[3] == 10);
+ test(blso[4] == 30);
+ test(blso[5] == 20);
+ test([rso length] == 3 * sizeof(ICELong));
+ ICELong *brso = (ICELong *)[rso bytes];
+ test(brso[0] == 10);
+ test(brso[1] == 30);
+ test(brso[2] == 20);
+ [self called];
+}
+
+-(void) opShortIntLongSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opFloatDoubleSResponse:(TestOperationsDoubleS*)rso p3:(TestOperationsFloatS*)fso p4:(TestOperationsDoubleS*)dso
+{
+ test([fso length] == 2 * sizeof(ICEFloat));
+ ICEFloat *bfso = (ICEFloat *)[fso bytes];
+ test(bfso[0] == 3.14f);
+ test(bfso[1] == 1.11f);
+ test([dso length] == 3 * sizeof(ICEDouble));
+ ICEDouble *bdso = (ICEDouble *)[dso bytes];
+ test(bdso[0] == 1.3E10);
+ test(bdso[1] == 1.2E10);
+ test(bdso[2] == 1.1E10);
+ test([rso length] == 5 * sizeof(ICEDouble));
+ ICEDouble *brso = (ICEDouble *)[rso bytes];
+ test(brso[0] == 1.1E10);
+ test(brso[1] == 1.2E10);
+ test(brso[2] == 1.3E10);
+ test((ICEFloat)brso[3] == 3.14f);
+ test((ICEFloat)brso[4] == 1.11f);
+ [self called];
+}
+
+-(void) opFloatDoubleSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opStringSResponse:(TestOperationsStringS*)rso p3:(TestOperationsStringS*)sso
+{
+ test([sso count] == 4);
+ test([[sso objectAtIndex:0] isEqualToString:@"abc"]);
+ test([[sso objectAtIndex:1] isEqualToString:@"de"]);
+ test([[sso objectAtIndex:2] isEqualToString:@"fghi"]);
+ test([[sso objectAtIndex:3] isEqualToString:@"xyz"]);
+ test([rso count] == 3);
+ test([[rso objectAtIndex:0] isEqualToString:@"fghi"]);
+ test([[rso objectAtIndex:1] isEqualToString:@"de"]);
+ test([[rso objectAtIndex:2] isEqualToString:@"abc"]);
+ [self called];
+}
+
+-(void) opStringSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opByteSSResponse:(TestOperationsByteSS*)rso p3:(TestOperationsByteSS*)bso
+{
+ const ICEByte *p;
+ test([bso count] == 2);
+ test([[bso objectAtIndex:0] length] / sizeof(ICEByte) == 1);
+ p = [[bso objectAtIndex:0] bytes];
+ test(p[0] == (ICEByte)0x0ff);
+ test([[bso objectAtIndex:1] length] / sizeof(ICEByte) == 3);
+ p = [[bso objectAtIndex:1] bytes];
+ test(p[0] == (ICEByte)0x01);
+ test(p[1] == (ICEByte)0x11);
+ test(p[2] == (ICEByte)0x12);
+ test([rso count] == 4);
+ test([[rso objectAtIndex:0] length] / sizeof(ICEByte) == 3);
+ p = [[rso objectAtIndex:0] bytes];
+ test(p[0] == (ICEByte)0x01);
+ test(p[1] == (ICEByte)0x11);
+ test(p[2] == (ICEByte)0x12);
+ test([[rso objectAtIndex:1] length] / sizeof(ICEByte) == 1);
+ p = [[rso objectAtIndex:1] bytes];
+ test(p[0] == (ICEByte)0xff);
+ test([[rso objectAtIndex:2] length] / sizeof(ICEByte) == 1);
+ p = [[rso objectAtIndex:2] bytes];
+ test(p[0] == (ICEByte)0x0e);
+ test([[rso objectAtIndex:3] length] / sizeof(ICEByte) == 2);
+ p = [[rso objectAtIndex:3] bytes];
+ test(p[0] == (ICEByte)0xf2);
+ test(p[1] == (ICEByte)0xf1);
+ [self called];
+}
+
+-(void) opByteSSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opBoolSSResponse:(TestOperationsBoolSS*)sso p3:(TestOperationsBoolSS*)bso
+{
+ [self called];
+}
+
+-(void) opBoolSSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opShortIntLongSSResponse:(TestOperationsLongSS*)a p4:(TestOperationsShortSS*)p4 p5:(TestOperationsIntSS*)p5 p6:(TestOperationsLongSS*)p6
+{
+ [self called];
+}
+
+-(void) opShortIntLongSSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opFloatDoubleSSResponse:(TestOperationsDoubleSS*)rso p3:(TestOperationsFloatSS*)fso p4:(TestOperationsDoubleSS*)dso
+{
+ const ICEFloat *fp;
+ const ICEDouble *dp;
+
+ test([fso count] == 3);
+ test([[fso objectAtIndex:0] length] / sizeof(ICEFloat) == 1);
+ fp = [[fso objectAtIndex:0] bytes];
+ test(fp[0] == 3.14f);
+ test([[fso objectAtIndex:1] length] / sizeof(ICEFloat) == 1);
+ fp = [[fso objectAtIndex:1] bytes];
+ test(fp[0] == 1.11f);
+ test([[fso objectAtIndex:2] length] / sizeof(ICEFloat) == 0);
+ test([dso count] == 1);
+ test([[dso objectAtIndex:0] length] / sizeof(ICEDouble) == 3);
+ dp = [[dso objectAtIndex:0] bytes];
+ test(dp[0] == 1.1E10);
+ test(dp[1] == 1.2E10);
+ test(dp[2] == 1.3E10);
+ test([rso count] == 2);
+ test([[rso objectAtIndex:0] length] / sizeof(ICEDouble) == 3);
+ dp = [[rso objectAtIndex:0] bytes];
+ test(dp[0] == 1.1E10);
+ test(dp[1] == 1.2E10);
+ test(dp[2] == 1.3E10);
+ test([[rso objectAtIndex:1] length] / sizeof(ICEDouble) == 3);
+ dp = [[rso objectAtIndex:1] bytes];
+ test(dp[0] == 1.1E10);
+ test(dp[1] == 1.2E10);
+ test(dp[2] == 1.3E10);
+ [self called];
+}
+
+-(void) opFloatDoubleSSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opStringSSResponse:(TestOperationsStringSS*)rso p3:(TestOperationsStringSS*)sso
+{
+ test([sso count] == 5);
+ test([[sso objectAtIndex:0] count] == 1);
+ test([[[sso objectAtIndex:0] objectAtIndex:0] isEqualToString:@"abc"]);
+ test([[sso objectAtIndex:1] count] == 2);
+ test([[[sso objectAtIndex:1] objectAtIndex:0] isEqualToString:@"de"]);
+ test([[[sso objectAtIndex:1] objectAtIndex:1] isEqualToString:@"fghi"]);
+ test([[sso objectAtIndex:2] count] == 0);
+ test([[sso objectAtIndex:3] count] == 0);
+ test([[sso objectAtIndex:4] count] == 1);
+ test([[[sso objectAtIndex:4] objectAtIndex:0] isEqualToString:@"xyz"]);
+ test([rso count] == 3);
+ test([[rso objectAtIndex:0] count] == 1);
+ test([[[rso objectAtIndex:0] objectAtIndex:0] isEqualToString:@"xyz"]);
+ test([[rso objectAtIndex:1] count] == 0);
+ test([[rso objectAtIndex:2] count] == 0);
+ [self called];
+}
+
+-(void) opStringSSException:(ICEException*)ex
+{
+ test(NO);
+}
+
+-(void) opStringSSSResponse:(TestOperationsStringSS*)rsso p3:(TestOperationsStringSS*)ssso
+{
+ test([ssso count] == 5);
+ test([[ssso objectAtIndex:0] count] == 2);
+ test([[[ssso objectAtIndex:0] objectAtIndex:0] count] == 2);
+ test([[[ssso objectAtIndex:0] objectAtIndex:1] count] == 1);
+ test([[ssso objectAtIndex:1] count] == 1);
+ test([[[ssso objectAtIndex:1] objectAtIndex:0] count] == 1);
+ test([[ssso objectAtIndex:2] count] == 2);
+ test([[[ssso objectAtIndex:2] objectAtIndex:0] count] == 2);
+ test([[[ssso objectAtIndex:2] objectAtIndex:1] count] == 1);
+ test([[ssso objectAtIndex:3] count] == 1);
+ test([[[ssso objectAtIndex:3] objectAtIndex:0] count] == 1);
+ test([[ssso objectAtIndex:4] count] == 0);
+ test([[[[ssso objectAtIndex:0] objectAtIndex:0] objectAtIndex:0] isEqualToString:@"abc"]);
+ test([[[[ssso objectAtIndex:0] objectAtIndex:0] objectAtIndex:1] isEqualToString:@"de"]);
+ test([[[[ssso objectAtIndex:0] objectAtIndex:1] objectAtIndex:0] isEqualToString:@"xyz"]);
+ test([[[[ssso objectAtIndex:1] objectAtIndex:0] objectAtIndex:0] isEqualToString:@"hello"]);
+ test([[[[ssso objectAtIndex:2] objectAtIndex:0] objectAtIndex:0] isEqualToString:@""]);
+ test([[[[ssso objectAtIndex:2] objectAtIndex:0] objectAtIndex:1] isEqualToString:@""]);
+ test([[[[ssso objectAtIndex:2] objectAtIndex:1] objectAtIndex:0] isEqualToString:@"abcd"]);
+ test([[[[ssso objectAtIndex:3] objectAtIndex:0] objectAtIndex:0] isEqualToString:@""]);
+
+ test([rsso count] == 3);
+ test([[rsso objectAtIndex:0] count] == 0);
+ test([[rsso objectAtIndex:1] count] == 1);
+ test([[[rsso objectAtIndex:1] objectAtIndex:0] count] == 1);
+ test([[rsso objectAtIndex:2] count] == 2);
+ test([[[rsso objectAtIndex:2] objectAtIndex:0] count] == 2);
+ test([[[rsso objectAtIndex:2] objectAtIndex:1] count] == 1);
+ test([[[[rsso objectAtIndex:1] objectAtIndex:0] objectAtIndex:0] isEqualToString:@""]);
+ test([[[[rsso objectAtIndex:2] objectAtIndex:0] objectAtIndex:0] isEqualToString:@""]);
+ test([[[[rsso objectAtIndex:2] objectAtIndex:0] objectAtIndex:1] isEqualToString:@""]);
+ test([[[[rsso objectAtIndex:2] objectAtIndex:1] objectAtIndex:0] isEqualToString:@"abcd"]);
+ [self called];
+}
+-(void) opStringSSSException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opByteBoolDResponse:(TestOperationsMutableByteBoolD*)ro p3:(TestOperationsMutableByteBoolD*)_do
+{
+ test([_do count] == 2);
+ test([[_do objectForKey:[NSNumber numberWithUnsignedChar:10]] boolValue] == YES);
+ test([[_do objectForKey:[NSNumber numberWithUnsignedChar:100]] boolValue] == NO);
+ test([ro count] == 4);
+ test([[ro objectForKey:[NSNumber numberWithUnsignedChar:10]] boolValue] == YES);
+ test([[ro objectForKey:[NSNumber numberWithUnsignedChar:11]] boolValue] == NO);
+ test([[ro objectForKey:[NSNumber numberWithUnsignedChar:100]] boolValue] == NO);
+ test([[ro objectForKey:[NSNumber numberWithUnsignedChar:101]] boolValue] == YES);
+ [self called];
+}
+-(void) opByteBoolDException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opShortIntDResponse:(TestOperationsShortIntD*)ro p3:(TestOperationsShortIntD*)_do
+{
+ test([_do count] == 2);
+ test([[_do objectForKey:[NSNumber numberWithShort:110]] intValue] == -1);
+ test([[_do objectForKey:[NSNumber numberWithShort:1100]] intValue] == 123123);
+ test([ro count] == 4);
+ test([[ro objectForKey:[NSNumber numberWithShort:110]] intValue] == -1);
+ test([[ro objectForKey:[NSNumber numberWithShort:111]] intValue] == -100);
+ test([[ro objectForKey:[NSNumber numberWithShort:1100]] intValue] == 123123);
+ test([[ro objectForKey:[NSNumber numberWithShort:1101]] intValue] == 0);
+ [self called];
+}
+-(void) opShortIntDException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opLongFloatDResponse:(TestOperationsLongFloatD*)ro p3:(TestOperationsLongFloatD*)_do
+{
+ test([_do count] == 2);
+ test((ICEFloat)[[_do objectForKey:[NSNumber numberWithLong:999999110]] floatValue] == -1.1f);
+ test((ICEFloat)[[_do objectForKey:[NSNumber numberWithLong:999999111]] floatValue] == 123123.2f);
+ test([ro count] == 4);
+ test((ICEFloat)[[ro objectForKey:[NSNumber numberWithLong:999999110]] floatValue] == -1.1f);
+ test((ICEFloat)[[ro objectForKey:[NSNumber numberWithLong:999999120]] floatValue] == -100.4f);
+ test((ICEFloat)[[ro objectForKey:[NSNumber numberWithLong:999999111]] floatValue] == 123123.2f);
+ test((ICEFloat)[[ro objectForKey:[NSNumber numberWithLong:999999130]] floatValue] == 0.5f);
+ [self called];
+}
+-(void) opLongFloatDException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opStringStringDResponse:(TestOperationsStringStringD*)ro p3:(TestOperationsStringStringD*)_do
+{
+ test([_do count] == 2);
+ test([[_do objectForKey:@"foo"] isEqualToString:@"abc -1.1"]);
+ test([[_do objectForKey:@"bar"] isEqualToString:@"abc 123123.2"]);
+ test([ro count] == 4);
+ test([[ro objectForKey:@"foo"] isEqualToString:@"abc -1.1"]);
+ test([[ro objectForKey:@"FOO"] isEqualToString:@"abc -100.4"]);
+ test([[ro objectForKey:@"bar"] isEqualToString:@"abc 123123.2"]);
+ test([[ro objectForKey:@"BAR"] isEqualToString:@"abc 0.5"]);
+ [self called];
+}
+-(void) opStringStringDException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opStringMyEnumDResponse:(TestOperationsStringMyEnumD*)ro p3:(TestOperationsStringMyEnumD*)_do
+{
+ test([_do count] == 2);
+ test([[_do objectForKey:@"abc"] intValue] == TestOperationsenum1);
+ test([[_do objectForKey:@""] intValue] == TestOperationsenum2);
+ test([ro count] == 4);
+ test([[ro objectForKey:@"abc"] intValue] == TestOperationsenum1);
+ test([[ro objectForKey:@"querty"] intValue] == TestOperationsenum3);
+ test([[ro objectForKey:@""] intValue] == TestOperationsenum2);
+ test([[ro objectForKey:@"Hello!!"] intValue] == TestOperationsenum2);
+ [self called];
+}
+-(void) opStringMyEnumDException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opMyEnumStringDResponse:(TestOperationsMyEnumStringD*)ro p3:(TestOperationsMyEnumStringD*)_do
+{
+ test([_do count] == 1);
+ test([ro count] == 3);
+ test([[ro objectForKey:@(TestOperationsenum1)] isEqualToString:@"abc"]);
+ test([[ro objectForKey:@(TestOperationsenum2)] isEqualToString:@"Hello!!"]);
+ test([[ro objectForKey:@(TestOperationsenum3)] isEqualToString:@"querty"]);
+ [self called];
+}
+-(void) opMyEnumStringDException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opMyStructMyEnumDResponse:(TestOperationsMyStructMyEnumD*)ro p3:(TestOperationsMyStructMyEnumD*)_do
+ s11:(TestOperationsMyStruct*)s11 s12:(TestOperationsMyStruct*)s12
+ s22:(TestOperationsMyStruct*)s22 s23:(TestOperationsMyStruct*)s23
+{
+ test([_do count] == 2);
+ test([ro count] == 4);
+ test([[ro objectForKey:s11] isEqual:@(TestOperationsenum1)]);
+ test([[ro objectForKey:s12] isEqual:@(TestOperationsenum2)]);
+ test([[ro objectForKey:s22] isEqual:@(TestOperationsenum3)]);
+ test([[ro objectForKey:s23] isEqual:@(TestOperationsenum2)]);
+ [self called];
+}
+-(void) opMyStructMyEnumDException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opIntSResponse:(TestOperationsIntS*)r
+{
+ const ICEInt *rp = [r bytes];
+ int j;
+ for(j = 0; j < [r length] / sizeof(ICEInt); ++j)
+ {
+ test(rp[j] == -j);
+ }
+ [self called];
+}
+-(void) opIntSException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opEmptyContextResponse:(ICEContext*)ctx
+{
+ test([ctx count] == 0);
+ [self called];
+}
+-(void) opNonEmptyContextResponse:(ICEContext*)ctx
+{
+ test([ctx count] == 3);
+ test([[ctx objectForKey:@"one"] isEqualToString:@"ONE"]);
+ test([[ctx objectForKey:@"two"] isEqualToString:@"TWO"]);
+ test([[ctx objectForKey:@"three"] isEqualToString:@"THREE"]);
+ [self called];
+}
+-(void) opContextException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) opDoubleMarshalingResponse
+{
+ [self called];
+}
+-(void) opDoubleMarshalingException:(ICEException*)ex
+{
+ test(NO);
+}
+@end
+
+void
+twowaysNewAMI(id<ICECommunicator> communicator, id<TestOperationsMyClassPrx> p)
+{
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opByte:(ICEByte)0xff p2:(ICEByte)0x0f response:^(ICEByte ret, ICEByte p3) { [cb opByteResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opByteException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opBool:YES p2:NO response:^(BOOL ret, BOOL p3) { [cb opBoolResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opBoolException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opShortIntLong:10 p2:11 p3:12 response:^(ICELong ret, ICEShort p4, ICEInt p5, ICELong p6) { [cb opShortIntLongResponse:ret p4:p4 p5:p5 p6:p6]; } exception:^(ICEException* ex) { [cb opShortIntLongException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opFloatDouble:3.14f p2:1.1E10 response:^(ICEDouble ret, ICEFloat p3, ICEDouble p4) { [cb opFloatDoubleResponse:ret p3:p3 p4:p4]; } exception:^(ICEException* ex) { [cb opFloatDoubleException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opString:@"hello" p2:@"world" response:^(NSMutableString* ret, NSMutableString* p3) { [cb opStringResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opStringException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opMyEnum:TestOperationsenum2 response:^(TestOperationsMyEnum ret, TestOperationsMyEnum p2) { [cb opMyEnumResponse:ret p2:p2]; } exception:^(ICEException* ex) { [cb opMyEnumException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opMyClass:p response:^(id<TestOperationsMyClassPrx> ret, id<TestOperationsMyClassPrx>p2, id<TestOperationsMyClassPrx> p3) { [cb opMyClassResponse:ret p2:p2 p3:p3]; } exception:^(ICEException* ex) { [cb opMyClassException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsStructure *si1 = [TestOperationsStructure structure];
+ si1.p = p;
+ si1.e = TestOperationsenum3;
+ si1.s = [TestOperationsAnotherStruct anotherStruct];
+ si1.s.s = @"abc";
+ TestOperationsStructure *si2 = [TestOperationsStructure structure];
+ si2.p = nil;
+ si2.e = TestOperationsenum2;
+ si2.s = [TestOperationsAnotherStruct anotherStruct];
+ si2.s.s = @"def";
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opStruct:si1 p2:si2 response:^(TestOperationsStructure* ret, TestOperationsStructure* p3) { [cb opStructResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opStructException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ ICEByte buf1[] = { 0x01, 0x11, 0x12, 0x22 };
+ ICEByte buf2[] = { 0xf1, 0xf2, 0xf3, 0xf4 };
+
+ TestOperationsMutableByteS *bsi1 = [TestOperationsMutableByteS data];
+ TestOperationsMutableByteS *bsi2 = [TestOperationsMutableByteS data];
+
+ [bsi1 appendBytes:buf1 length:sizeof(buf1)];
+ [bsi2 appendBytes:buf2 length:sizeof(buf2)];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opByteS:bsi1 p2:bsi2 response:^(TestOperationsMutableByteS* ret, TestOperationsMutableByteS* p3) { [cb opByteSResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opByteSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ BOOL buf1[] = { YES, YES, NO };
+ BOOL buf2[] = { NO };
+
+ TestOperationsMutableBoolS *bsi1 = [TestOperationsMutableBoolS data];
+ TestOperationsMutableBoolS *bsi2 = [TestOperationsMutableBoolS data];
+
+ [bsi1 appendBytes:buf1 length:sizeof(buf1)];
+ [bsi2 appendBytes:buf2 length:sizeof(buf2)];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opBoolS:bsi1 p2:bsi2 response:^(TestOperationsMutableBoolS* ret, TestOperationsMutableBoolS* p3) { [cb opBoolSResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opBoolSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ ICEShort buf1[] = { 1, 2, 3 };
+ ICEInt buf2[] = { 5, 6, 7, 8 };
+ ICELong buf3[] = { 10, 30, 20 };
+
+ TestOperationsMutableShortS *ssi = [TestOperationsMutableShortS data];
+ TestOperationsMutableIntS *isi = [TestOperationsMutableIntS data];
+ TestOperationsMutableLongS *lsi = [TestOperationsMutableLongS data];
+
+ [ssi appendBytes:buf1 length:sizeof(buf1)];
+ [isi appendBytes:buf2 length:sizeof(buf2)];
+ [lsi appendBytes:buf3 length:sizeof(buf3)];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opShortIntLongS:ssi p2:isi p3:lsi response:^(TestOperationsMutableLongS* ret, TestOperationsMutableShortS* p4, TestOperationsMutableIntS* p5, TestOperationsMutableLongS* p6) { [cb opShortIntLongSResponse:ret p4:p4 p5:p5 p6:p6]; } exception:^(ICEException* ex) { [cb opShortIntLongSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ ICEFloat buf1[] = { 3.14f, 1.11f };
+ ICEDouble buf2[] = { 1.1E10, 1.2E10, 1.3E10 };
+
+ TestOperationsMutableFloatS *fsi = [TestOperationsMutableFloatS data];
+ TestOperationsMutableDoubleS *dsi = [TestOperationsMutableDoubleS data];
+
+ [fsi appendBytes:buf1 length:sizeof(buf1)];
+ [dsi appendBytes:buf2 length:sizeof(buf2)];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opFloatDoubleS:fsi p2:dsi response:^(TestOperationsMutableDoubleS* ret, TestOperationsMutableFloatS* p3, TestOperationsMutableDoubleS* p4) { [cb opFloatDoubleSResponse:ret p3:p3 p4:p4]; } exception:^(ICEException* ex) { [cb opFloatDoubleSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableStringS *ssi1 = [TestOperationsMutableStringS arrayWithCapacity:3];
+ TestOperationsMutableStringS *ssi2 = [TestOperationsMutableStringS arrayWithCapacity:1];
+
+ [ssi1 addObject:@"abc"];
+ [ssi1 addObject:@"de"];
+ [ssi1 addObject:@"fghi"];
+
+ [ssi2 addObject:@"xyz"];
+
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opStringS:ssi1 p2:ssi2 response:^(TestOperationsMutableStringS* ret, TestOperationsMutableStringS* p3) { [cb opStringSResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opStringSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableByteSS *bsi1 = [TestOperationsMutableByteSS array];
+ TestOperationsMutableByteSS *bsi2 = [TestOperationsMutableByteSS array];
+
+ ICEByte b;
+ TestOperationsMutableByteS *tmp = [TestOperationsMutableByteS data];
+
+ b = 0x01;
+ [tmp appendBytes:&b length:sizeof(b)];
+ b = 0x11;
+ [tmp appendBytes:&b length:sizeof(b)];
+ b = 0x12;
+ [tmp appendBytes:&b length:sizeof(b)];
+ [bsi1 addObject:tmp];
+
+ tmp = [TestOperationsMutableByteS data];
+ b = 0xff;
+ [tmp appendBytes:&b length:sizeof(b)];
+ [bsi1 addObject:tmp];
+
+ tmp = [TestOperationsMutableByteS data];
+ b = 0x0e;
+ [tmp appendBytes:&b length:sizeof(b)];
+ [bsi2 addObject:tmp];
+
+ tmp = [TestOperationsMutableByteS data];
+ b = 0xf2;
+ [tmp appendBytes:&b length:sizeof(b)];
+ b = 0xf1;
+ [tmp appendBytes:&b length:sizeof(b)];
+ [bsi2 addObject:tmp];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opByteSS:bsi1 p2:bsi2 response:^(TestOperationsMutableByteSS* ret, TestOperationsMutableByteSS* p3) { [cb opByteSSResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opByteSSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableFloatSS *fsi = [TestOperationsMutableFloatSS array];
+ TestOperationsMutableDoubleSS *dsi = [TestOperationsMutableDoubleSS array];
+
+ ICEFloat f;
+ TestOperationsMutableFloatS *ftmp;
+
+ ftmp = [TestOperationsMutableFloatS data];
+ f = 3.14f;
+ [ftmp appendBytes:&f length:sizeof(f)];
+ [fsi addObject:ftmp];
+ ftmp = [TestOperationsMutableFloatS data];
+ f = 1.11f;
+ [ftmp appendBytes:&f length:sizeof(f)];
+ [fsi addObject:ftmp];
+ ftmp = [TestOperationsMutableFloatS data];
+ [fsi addObject:ftmp];
+
+ ICEDouble d;
+ TestOperationsMutableDoubleS *dtmp;
+
+ dtmp = [TestOperationsMutableDoubleS data];
+ d = 1.1E10;
+ [dtmp appendBytes:&d length:sizeof(d)];
+ d = 1.2E10;
+ [dtmp appendBytes:&d length:sizeof(d)];
+ d = 1.3E10;
+ [dtmp appendBytes:&d length:sizeof(d)];
+ [dsi addObject:dtmp];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opFloatDoubleSS:fsi p2:dsi response:^(TestOperationsMutableDoubleSS* ret, TestOperationsMutableFloatSS* p3, TestOperationsMutableDoubleSS* p4) { [cb opFloatDoubleSSResponse:ret p3:p3 p4:p4]; } exception:^(ICEException* ex) { [cb opFloatDoubleSSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableStringSS * ssi1 = [TestOperationsMutableStringSS array];
+ TestOperationsMutableStringSS * ssi2 = [TestOperationsMutableStringSS array];
+
+ TestOperationsMutableStringS *tmp;
+
+ tmp = [TestOperationsMutableStringS array];
+ [tmp addObject:@"abc"];
+ [ssi1 addObject:tmp];
+ tmp = [TestOperationsMutableStringS array];
+ [tmp addObject:@"de"];
+ [tmp addObject:@"fghi"];
+ [ssi1 addObject:tmp];
+
+ [ssi2 addObject:[TestOperationsStringS array]];
+ [ssi2 addObject:[TestOperationsStringS array]];
+ tmp = [TestOperationsMutableStringS array];
+ [tmp addObject:@"xyz"];
+ [ssi2 addObject:tmp];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opStringSS:ssi1 p2:ssi2 response:^(TestOperationsMutableStringSS* ret, TestOperationsMutableStringSS* p3) { [cb opStringSSResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opStringSSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableStringSSS *sssi1 = [TestOperationsMutableStringSSS array];
+ TestOperationsMutableStringSSS *sssi2 = [TestOperationsMutableStringSSS array];
+
+ TestOperationsMutableStringSS *tmpss;
+ TestOperationsMutableStringS *tmps;
+
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@"abc"];
+ [tmps addObject:@"de"];
+ tmpss = [TestOperationsMutableStringSS array];
+ [tmpss addObject:tmps];
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@"xyz"];
+ [tmpss addObject:tmps];
+ [sssi1 addObject:tmpss];
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@"hello"];
+ tmpss = [TestOperationsMutableStringSS array];
+ [tmpss addObject:tmps];
+ [sssi1 addObject:tmpss];
+
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@""];
+ [tmps addObject:@""];
+ tmpss = [TestOperationsMutableStringSS array];
+ [tmpss addObject:tmps];
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@"abcd"];
+ [tmpss addObject:tmps];
+ [sssi2 addObject:tmpss];
+ tmps = [TestOperationsMutableStringS array];
+ [tmps addObject:@""];
+ tmpss = [TestOperationsMutableStringSS array];
+ [tmpss addObject:tmps];
+ [sssi2 addObject:tmpss];
+ tmpss = [TestOperationsMutableStringSS array];
+ [sssi2 addObject:tmpss];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opStringSSS:sssi1 p2:sssi2 response:^(TestOperationsMutableStringSS* ret, TestOperationsMutableStringSS* p3) { [cb opStringSSSResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opStringSSSException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableByteBoolD *di1 = [TestOperationsMutableByteBoolD dictionary];
+ [di1 setObject:[NSNumber numberWithBool:YES] forKey:[NSNumber numberWithUnsignedChar:10]];
+ [di1 setObject:[NSNumber numberWithBool:NO] forKey:[NSNumber numberWithUnsignedChar:100]];
+ TestOperationsMutableByteBoolD *di2 = [TestOperationsMutableByteBoolD dictionary];
+ [di2 setObject:[NSNumber numberWithBool:YES] forKey:[NSNumber numberWithUnsignedChar:10]];
+ [di2 setObject:[NSNumber numberWithBool:NO] forKey:[NSNumber numberWithUnsignedChar:11]];
+ [di2 setObject:[NSNumber numberWithBool:TRUE] forKey:[NSNumber numberWithUnsignedChar:101]];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opByteBoolD:di1 p2:di2 response:^(TestOperationsMutableByteBoolD* ret, TestOperationsMutableByteBoolD* p3) { [cb opByteBoolDResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opByteBoolDException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableShortIntD *di1 = [TestOperationsMutableShortIntD dictionary];
+ [di1 setObject:[NSNumber numberWithInt:-1] forKey:[NSNumber numberWithShort:110]];
+ [di1 setObject:[NSNumber numberWithInt:123123] forKey:[NSNumber numberWithShort:1100]];
+ TestOperationsMutableShortIntD *di2 = [TestOperationsMutableShortIntD dictionary];
+ [di2 setObject:[NSNumber numberWithInt:-1] forKey:[NSNumber numberWithShort:110]];
+ [di2 setObject:[NSNumber numberWithInt:-100] forKey:[NSNumber numberWithShort:111]];
+ [di2 setObject:[NSNumber numberWithInt:0] forKey:[NSNumber numberWithShort:1101]];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opShortIntD:di1 p2:di2 response:^(TestOperationsMutableShortIntD* ret, TestOperationsMutableShortIntD* p3) { [cb opShortIntDResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opShortIntDException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableLongFloatD *di1 = [TestOperationsMutableLongFloatD dictionary];
+ [di1 setObject:[NSNumber numberWithFloat:-1.1f] forKey:[NSNumber numberWithLong:999999110]];
+ [di1 setObject:[NSNumber numberWithFloat:123123.2f] forKey:[NSNumber numberWithLong:999999111]];
+ TestOperationsMutableLongFloatD *di2 = [TestOperationsMutableLongFloatD dictionary];
+ [di2 setObject:[NSNumber numberWithFloat:-1.1f] forKey:[NSNumber numberWithLong:999999110]];
+ [di2 setObject:[NSNumber numberWithFloat:-100.4f] forKey:[NSNumber numberWithLong:999999120]];
+ [di2 setObject:[NSNumber numberWithFloat:0.5f] forKey:[NSNumber numberWithLong:999999130]];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opLongFloatD:di1 p2:di2 response:^(TestOperationsMutableLongFloatD* ret, TestOperationsMutableLongFloatD* p3) { [cb opLongFloatDResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opLongFloatDException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableStringStringD *di1 = [TestOperationsMutableStringStringD dictionary];
+ [di1 setObject:@"abc -1.1" forKey:@"foo"];
+ [di1 setObject:@"abc 123123.2" forKey:@"bar"];
+ TestOperationsMutableStringStringD *di2 = [TestOperationsMutableStringStringD dictionary];
+ [di2 setObject:@"abc -1.1" forKey:@"foo"];
+ [di2 setObject:@"abc -100.4" forKey:@"FOO"];
+ [di2 setObject:@"abc 0.5" forKey:@"BAR"];
+
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opStringStringD:di1 p2:di2 response:^(TestOperationsMutableStringStringD* ret, TestOperationsMutableStringStringD* p3) { [cb opStringStringDResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opStringStringDException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableStringMyEnumD *di1 = [TestOperationsMutableStringMyEnumD dictionary];
+ [di1 setObject:[NSNumber numberWithInt:TestOperationsenum1] forKey:@"abc"];
+ [di1 setObject:[NSNumber numberWithInt:TestOperationsenum2] forKey:@""];
+ TestOperationsMutableStringMyEnumD *di2 = [TestOperationsMutableStringMyEnumD dictionary];
+ [di2 setObject:[NSNumber numberWithInt:TestOperationsenum1] forKey:@"abc"];
+ [di2 setObject:[NSNumber numberWithInt:TestOperationsenum3] forKey:@"querty"];
+ [di2 setObject:[NSNumber numberWithInt:TestOperationsenum2] forKey:@"Hello!!"];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opStringMyEnumD:di1 p2:di2 response:^(TestOperationsMutableStringMyEnumD* ret, TestOperationsMutableStringMyEnumD* p3) { [cb opStringMyEnumDResponse:ret p3:p3]; } exception:^(ICEException* ex) { [cb opStringMyEnumDException:ex]; }];
+ test([cb check]);
+ }
+
+ {
+ TestOperationsMutableMyEnumStringD *di1 = [TestOperationsMutableMyEnumStringD dictionary];
+ [di1 setObject:@"abc" forKey:@(TestOperationsenum1)];
+ TestOperationsMutableMyEnumStringD *di2 = [TestOperationsMutableMyEnumStringD dictionary];
+ [di2 setObject:@"Hello!!" forKey:@(TestOperationsenum2)];
+ [di2 setObject:@"querty" forKey:@(TestOperationsenum3)];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opMyEnumStringD:di1
+ p2:di2
+ response:^(TestOperationsMutableMyEnumStringD* ret,
+ TestOperationsMutableMyEnumStringD* p3) { [cb opMyEnumStringDResponse:ret
+ p3:p3]; }
+ exception:^(ICEException* ex) { [cb opMyEnumStringDException:ex]; }];
+ [cb check];
+ }
+
+ {
+ TestOperationsMyStruct* s11 = [TestOperationsMyStruct myStruct:1 j:1];
+ TestOperationsMyStruct* s12 = [TestOperationsMyStruct myStruct:1 j:2];
+ TestOperationsMutableMyStructMyEnumD* di1 = [TestOperationsMutableMyStructMyEnumD dictionary];
+ [di1 setObject:@(TestOperationsenum1) forKey:s11];
+ [di1 setObject:@(TestOperationsenum2) forKey:s12];
+
+ TestOperationsMyStruct* s22 = [TestOperationsMyStruct myStruct:2 j:2];
+ TestOperationsMyStruct* s23 = [TestOperationsMyStruct myStruct:2 j:3];
+ TestOperationsMutableMyStructMyEnumD* di2 = [TestOperationsMutableMyStructMyEnumD dictionary];
+ [di2 setObject:@(TestOperationsenum1) forKey:s11];
+ [di2 setObject:@(TestOperationsenum3) forKey:s22];
+ [di2 setObject:@(TestOperationsenum2) forKey:s23];
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opMyStructMyEnumD:di1
+ p2:di2
+ response:^(TestOperationsMutableMyStructMyEnumD* ret,
+ TestOperationsMutableMyStructMyEnumD* p3) { [cb opMyStructMyEnumDResponse:ret
+ p3:p3
+ s11:s11
+ s12:s12
+ s22:s22
+ s23:s23]; }
+ exception:^(ICEException* ex) { [cb opMyStructMyEnumDException:ex]; }];
+ [cb check];
+ }
+
+ {
+ const int lengths[] = { 0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000 };
+
+ int l;
+ for(l = 0; l != sizeof(lengths) / sizeof(*lengths); ++l)
+ {
+ TestOperationsMutableIntS *s = [TestOperationsMutableIntS dataWithLength:(lengths[l] * sizeof(ICEInt))];
+ ICEInt *ip = (ICEInt *)[s bytes];
+ int i;
+ for(i = 0; i < lengths[l]; ++i)
+ {
+ *ip++ = i;
+ }
+
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opIntS:s response:^(TestOperationsMutableIntS* ret) { [cb opIntSResponse:ret]; } exception:^(ICEException* ex) { [cb opIntSException:ex]; }];
+ test([cb check]);
+ }
+ }
+
+ {
+ ICEMutableContext *ctx = [ICEMutableContext dictionary];
+ [ctx setObject:@"ONE" forKey:@"one"];
+ [ctx setObject:@"TWO" forKey:@"two"];
+ [ctx setObject:@"THREE" forKey:@"three"];
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opContext:^(ICEMutableContext* ctx) { [cb opEmptyContextResponse:ctx]; } exception:^(ICEException* ex) { [cb opContextException:ex]; }];
+ test([cb check]);
+ }
+ {
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opContext:ctx response:^(ICEMutableContext* ctx) { [cb opNonEmptyContextResponse:ctx]; } exception:^(ICEException* ex) { [cb opContextException:ex]; }];
+ test([cb check]);
+ }
+ {
+ id<TestOperationsMyClassPrx> p2 = [TestOperationsMyClassPrx checkedCast:[p ice_context:ctx]];
+ test([[p2 ice_getContext] isEqual:ctx]);
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p2 begin_opContext:^(ICEMutableContext* ctx) { [cb opNonEmptyContextResponse:ctx]; } exception:^(ICEException* ex) { [cb opContextException:ex]; }];
+ test([cb check]);
+
+
+ cb = [TestNewAMIOperationsCallback create];
+ [p2 begin_opContext:ctx response:^(ICEMutableContext* ctx) { [cb opNonEmptyContextResponse:ctx]; } exception:^(ICEException* ex) { [cb opContextException:ex]; }];
+ test([cb check]);
+ }
+ }
+
+ {
+ //
+ // TestOperations implicit context propagation
+ //
+
+ NSString *impls[] = {@"Shared", @"PerThread"};
+ for(int i = 0; i < 2; i++)
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ [initData setProperties:[[communicator getProperties] clone]];
+ [initData.properties setProperty:@"Ice.ImplicitContext" value:impls[i]];
+
+ id<ICECommunicator> ic = [ICEUtil createCommunicator:initData];
+
+ ICEMutableContext *ctx = [ICEMutableContext dictionary];
+ [ctx setObject:@"ONE" forKey:@"one" ];
+ [ctx setObject:@"TWO" forKey:@"two" ];
+ [ctx setObject:@"THREE" forKey:@"three"];
+
+ id<TestOperationsMyClassPrx> p = [TestOperationsMyClassPrx uncheckedCast:
+ [ic stringToProxy:@"test:default -p 12010"]];
+
+ [[ic getImplicitContext] setContext:(ctx)];
+ test([[[ic getImplicitContext] getContext] isEqualToDictionary:ctx]);
+ {
+ id<ICEAsyncResult> r = [p begin_opContext];
+ ICEContext* c = [p end_opContext:r];
+ test([c isEqualToDictionary:ctx]);
+ }
+
+ test([[ic getImplicitContext] get:@"zero"] == nil);
+ [[ic getImplicitContext] put:@"zero" value:@"ZERO"];
+ test([[[ic getImplicitContext] get:@"zero"] isEqualToString:@"ZERO"]);
+
+ ctx = [[ic getImplicitContext] getContext];
+ {
+ id<ICEAsyncResult> r = [p begin_opContext];
+ ICEContext* c = [p end_opContext:r];
+ test([c isEqualToDictionary:ctx]);
+ }
+
+ ICEMutableContext *prxContext = [ICEMutableContext dictionary];
+ [prxContext setObject:@"UN" forKey:@"one"];
+ [prxContext setObject:@"QUATRE" forKey:@"four"];
+
+ ICEMutableContext *combined = [ICEMutableContext dictionaryWithDictionary:ctx];
+ [combined addEntriesFromDictionary:prxContext];
+
+ p = [TestOperationsMyClassPrx uncheckedCast:[p ice_context:prxContext]];
+
+ [[ic getImplicitContext] setContext:[ICEMutableContext dictionary]];
+ {
+ id<ICEAsyncResult> r = [p begin_opContext];
+ ICEContext* c = [p end_opContext:r];
+ test([c isEqualToDictionary:prxContext]);
+ }
+
+ [[ic getImplicitContext] setContext:ctx];
+ {
+ id<ICEAsyncResult> r = [p begin_opContext];
+ ICEContext* c = [p end_opContext:r];
+ test([c isEqualToDictionary:combined]);
+ }
+
+ [[ic getImplicitContext] setContext:[ICEContext dictionary]];
+ [ic destroy];
+ }
+ }
+
+
+
+ {
+ ICEDouble d = 1278312346.0 / 13.0;
+ TestOperationsMutableDoubleS *ds = [TestOperationsMutableDoubleS dataWithLength:(5 * sizeof(ICEDouble))];
+ ICEDouble *pb = (ICEDouble *)[ds bytes];
+ int i = 5;
+ while(i-- > 0)
+ {
+ *pb++ = d;
+ }
+ TestNewAMIOperationsCallback* cb = [TestNewAMIOperationsCallback create];
+ [p begin_opDoubleMarshaling:d p2:ds response:^() { [cb opDoubleMarshalingResponse]; } exception:^(ICEException* ex) { [cb opDoubleMarshalingException:ex]; }];
+ test([cb check]);
+ }
+
+ // Marshaling tests for NSNull are present only in synchronous test because testing asynchronously
+ // would only test the same marshaling code that's been tested already.
+}
+
diff --git a/objc/test/Ice/operations/run.py b/objc/test/Ice/operations/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/operations/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/optional/.gitignore b/objc/test/Ice/optional/.gitignore
new file mode 100644
index 00000000000..7096f056538
--- /dev/null
+++ b/objc/test/Ice/optional/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+OptionalTest.m
+OptionalTest.h
diff --git a/objc/test/Ice/optional/AllTests.m b/objc/test/Ice/optional/AllTests.m
new file mode 100644
index 00000000000..4f785390e61
--- /dev/null
+++ b/objc/test/Ice/optional/AllTests.m
@@ -0,0 +1,1448 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OptionalTest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface TestObjectReader : ICEObject
+{
+}
+@end
+
+@implementation TestObjectReader
+-(void) read__:(id<ICEInputStream>)is
+{
+ [is startObject];
+ [is startSlice];
+ [is endSlice];
+ [is endObject:NO];
+}
+@end
+
+@interface BObjectReader : ICEObject
+{
+}
+@end
+
+@implementation BObjectReader
+-(void) read__:(id<ICEInputStream>)is
+{
+ [is startObject];
+ // ::Test::B
+ [is startSlice];
+ [is readInt];
+ [is endSlice];
+ // ::Test::A
+ [is startSlice];
+ [is readInt];
+ [is endSlice];
+ [is endObject:NO];
+};
+@end
+
+@interface CObjectReader : ICEObject
+{
+}
+@end
+
+@implementation CObjectReader
+-(void) read__:(id<ICEInputStream>)is
+{
+ [is startObject];
+ // ::Test::C
+ [is startSlice];
+ [is skipSlice];
+ // ::Test::B
+ [is startSlice];
+ [is readInt];
+ [is endSlice];
+ // ::Test::A
+ [is startSlice];
+ [is readInt];
+ [is endSlice];
+ [is endObject:NO];
+};
+@end
+
+@interface DObjectWriter : ICEObject
+{
+}
+@end
+
+@implementation DObjectWriter
+-(void) write__:(id<ICEOutputStream>)os
+{
+ [os startObject:0];
+ // ::Test::D
+ [os startSlice:@"::Test::D" compactId:-1 lastSlice:NO];
+ [os writeString:@"test"];
+ if([os writeOptional:1 format:ICEOptionalFormatVSize])
+ {
+ ICEMutableStringSeq* o = [ICEMutableStringSeq array];
+ [o addObject:@"test1"];
+ [o addObject:@"test2"];
+ [o addObject:@"test3"];
+ [o addObject:@"test4"];
+ [ICEStringSeqHelper write:o stream:os];
+ }
+ if([os writeOptional:1000 format:ICEOptionalFormatClass])
+ {
+ TestOptionalA* a = [TestOptionalA a];
+ a.mc = 18;
+ [os writeObject:a];
+ }
+ [os endSlice];
+ // ::Test::B
+ [os startSlice:@"::Test::B" compactId:-1 lastSlice:NO];
+ [os writeInt:14];
+ [os endSlice];
+ // ::Test::A
+ [os startSlice:@"::Test::A" compactId:-1 lastSlice:YES];
+ [os writeInt:14];
+ [os endSlice];
+ [os endObject];
+}
+@end
+
+@interface DObjectReader : ICEObject
+{
+ TestOptionalA* a_;
+}
+@end
+
+@implementation DObjectReader
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [a_ release];
+ [super dealloc];
+}
+#endif
+-(void) read__:(id<ICEInputStream>)is
+{
+ [is startObject];
+ // ::Test::D
+ [is startSlice];
+ NSString* s = [is readString];
+ test([s isEqualToString:@"test"]);
+ test([is readOptional:1 format:ICEOptionalFormatVSize]);
+ NSMutableArray* o = [ICEStringSeqHelper read:is];
+ test(o != nil && [o count] == 4 &&
+ [[o objectAtIndex:0] isEqualToString:@"test1"] &&
+ [[o objectAtIndex:1] isEqualToString:@"test2"] &&
+ [[o objectAtIndex:2] isEqualToString:@"test3"] &&
+ [[o objectAtIndex:3] isEqualToString:@"test4"]);
+ test([is readOptional:1000 format:ICEOptionalFormatClass]);
+ [is newObject:(ICEObject**)&a_ expectedType:[TestOptionalA class]];
+ [is endSlice];
+
+ // ::Test::B
+ [is startSlice];
+ [is readInt];
+ [is endSlice];
+ // ::Test::A
+ [is startSlice];
+ [is readInt];
+ [is endSlice];
+ [is endObject:NO];
+}
+-(void) check
+{
+ test(a_.mc == 18);
+}
+@end
+
+@interface FObjectReader : ICEObject
+{
+ TestOptionalF* f_;
+}
+@end
+
+@implementation FObjectReader
+-(id) init
+{
+ self = [super init];
+ if(self)
+ {
+ f_ = nil;
+ }
+ return self;
+}
+
+-(void) read__:(id<ICEInputStream>)is
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ if(f_ != nil)
+ {
+ [f_ release];
+ }
+#endif
+ f_ = [TestOptionalF new];
+ [is startObject];
+ [is startSlice];
+ // Don't read optional af on purpose
+ //[is_ readObject:(ICEObject**)&self->af expectedType:[TestOptionalA class]];
+ [is endSlice];
+ [is startSlice];
+ TestOptionalA* ICE_AUTORELEASING_QUALIFIER ae;
+ [is readObject:(ICEObject**)&ae expectedType:[TestOptionalA class]];
+ [is endSlice];
+ [is endObject:NO];
+ f_.ae = ae;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [f_ release];
+ [super dealloc];
+}
+#endif
+
+-(TestOptionalF*) getF
+{
+ return f_;
+}
+@end
+
+@interface FactoryI : NSObject<ICEObjectFactory>
+{
+ BOOL enabled_;
+}
++(FactoryI*) factoryI;
+-(void) setEnabled:(BOOL)enabled;
+@end
+
+@implementation FactoryI
++(FactoryI*) factoryI
+{
+#if defined(__clang__) && __has_feature(objc_arc)
+ return [[FactoryI alloc] init];
+#else
+ return [[[FactoryI alloc] init] autorelease];
+#endif
+}
+-(id) init
+{
+ self = [super init];
+ if(self)
+ {
+ self->enabled_ = NO;
+ }
+ return self;
+}
+-(ICEObject*) create:(NSString*)typeId
+{
+ if(!enabled_)
+ {
+ return nil;
+ }
+ if([typeId isEqualToString:@"::Test::OneOptional"])
+ {
+ return [TestObjectReader new];
+ }
+ else if([typeId isEqualToString:@"::Test::MultiOptional"])
+ {
+ return [TestObjectReader new];
+ }
+ else if([typeId isEqualToString:@"::Test::B"])
+ {
+ return [BObjectReader new];
+ }
+ else if([typeId isEqualToString:@"::Test::C"])
+ {
+ return [CObjectReader new];
+ }
+ else if([typeId isEqualToString:@"::Test::D"])
+ {
+ return [DObjectReader new];
+ }
+ else if([typeId isEqualToString:@"::Test::F"])
+ {
+ return [FObjectReader new];
+ }
+
+ return nil;
+}
+-(void) destroy
+{
+}
+-(void) setEnabled:(BOOL)enabled
+{
+ self->enabled_ = enabled;
+}
+@end
+
+id<TestOptionalInitialPrx>
+optionalAllTests(id<ICECommunicator> communicator)
+{
+ FactoryI* factory = [FactoryI factoryI];
+ [communicator addObjectFactory:factory sliceId:@""];
+
+ tprintf("testing stringToProxy... ");
+ NSString* sref = @"initial:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:sref];
+ test(base);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestOptionalInitialPrx> initial = [TestOptionalInitialPrx checkedCast:base];
+ test(initial != nil);
+ test([initial isEqual:base]);
+ tprintf("ok\n");
+
+ tprintf("testing constructor, copy constructor, and assignment operator... ");
+
+ TestOptionalOneOptional* oo1 = [TestOptionalOneOptional oneOptional];
+ test(![oo1 hasA]);
+ oo1.a = 15;
+ test([oo1 hasA] && oo1.a == 15);
+
+ TestOptionalOneOptional* oo2 = [TestOptionalOneOptional oneOptional:@16];
+ test([oo2 hasA] && oo2.a == 16);
+
+ TestOptionalOneOptional* oon = [TestOptionalOneOptional oneOptional:ICENone];
+ test(![oon hasA]);
+
+ TestOptionalMultiOptional* mo1 = [TestOptionalMultiOptional multiOptional];
+ mo1.a = 15;
+ mo1.b = true;
+ mo1.c = 19;
+ mo1.d = 78;
+ mo1.e = 99;
+ mo1.f = 5.5f;
+ mo1.g = 1.0;
+ mo1.h = @"test";
+ mo1.i = TestOptionalMyEnumMember;
+ mo1.j = [TestOptionalMultiOptionalPrx uncheckedCast:[communicator stringToProxy:@"test"]];
+ //mo1.k = mo1;
+ ICEByte bsa[] = { 0x05 };
+ mo1.bs = [TestOptionalByteSeq dataWithBytes:bsa length:1];
+ mo1.ss = [TestOptionalStringSeq arrayWithObjects:@"test", @"test2", nil];
+ mo1.iid = [TestOptionalIntIntDict dictionaryWithObjectsAndKeys:@3, @4, nil];
+ mo1.sid = [TestOptionalStringIntDict dictionaryWithObjectsAndKeys:@10, @"test", nil];
+ TestOptionalFixedStruct* fs = [TestOptionalFixedStruct fixedStruct];
+ fs.m = 78;
+ mo1.fs = fs;
+ TestOptionalVarStruct* vs = [TestOptionalVarStruct varStruct];
+ vs.m = @"hello";
+ mo1.vs = vs;
+
+ ICEShort shs[] = { 1 };
+ mo1.shs = [TestOptionalShortSeq dataWithBytes:shs length:sizeof(shs)];
+
+ TestOptionalMyEnum es[] = { TestOptionalMyEnumMember, TestOptionalMyEnumMember };
+ mo1.es = [TestOptionalMyEnumSeq dataWithBytes:es length:sizeof(es)];
+ mo1.fss = [TestOptionalFixedStructSeq arrayWithObject:fs];
+ mo1.vss = [TestOptionalVarStructSeq arrayWithObject:vs];
+ mo1.oos = [TestOptionalOneOptionalSeq arrayWithObject:oo1];
+ id<TestOptionalOneOptionalPrx> oneOptionalProxy =
+ [TestOptionalOneOptionalPrx uncheckedCast:[communicator stringToProxy:@"test"]];
+ mo1.oops = [TestOptionalOneOptionalPrxSeq arrayWithObject:oneOptionalProxy];
+ mo1.ied = [TestOptionalIntEnumDict dictionaryWithObjectsAndKeys:@(TestOptionalMyEnumMember), @4, nil];
+ mo1.ifsd = [TestOptionalIntFixedStructDict dictionaryWithObjectsAndKeys:fs, @4, nil];
+ mo1.ivsd = [TestOptionalIntVarStructDict dictionaryWithObjectsAndKeys:vs, @4, nil];
+ mo1.iood = [TestOptionalIntOneOptionalDict dictionaryWithObjectsAndKeys:[TestOptionalOneOptional oneOptional:@15],
+ @5, nil];
+ mo1.ioopd = [TestOptionalIntOneOptionalPrxDict dictionaryWithObjectsAndKeys:oneOptionalProxy, @5, nil];
+ BOOL bos[] = { NO, YES, NO };
+ mo1.bos = [TestOptionalBoolSeq dataWithBytes:bos length:sizeof(bos)];
+
+ TestOptionalMultiOptional* mo3 = [mo1 copy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [mo3 autorelease];
+#endif
+ test(mo3.a == 15);
+ test(mo3.b == YES);
+ test(mo3.c == 19);
+ test(mo3.d == 78);
+ test(mo3.e == 99);
+ test(mo3.f == 5.5f);
+ test(mo3.g == 1.0);
+ test([mo3.h isEqualToString:@"test"]);
+ test(mo3.i == TestOptionalMyEnumMember);
+ test([mo3.j isEqual:[TestOptionalMultiOptionalPrx uncheckedCast:[communicator stringToProxy:@"test"]]]);
+ //test(mo3.k == mo1);
+ test(mo3.bs == mo1.bs);
+ test(mo3.ss == mo1.ss);
+ test(mo3.iid == mo1.iid);
+ test(mo3.sid == mo1.sid);
+ test(mo3.fs == mo1.fs);
+ test(mo3.vs == mo1.vs);
+
+ test(mo3.shs == mo1.shs);
+ test(mo3.es == mo1.es);
+ test(mo3.fss == mo1.fss);
+ test(mo3.vss == mo1.vss);
+ test(mo3.oos == mo1.oos);
+ test(mo3.oops == mo1.oops);
+
+ test(mo3.ied == mo1.ied);
+ test(mo3.ifsd == mo1.ifsd);
+ test(mo3.ivsd == mo1.ivsd);
+ test(mo3.iood == mo1.iood);
+ test(mo3.ioopd == mo1.ioopd);
+
+ test(mo3.bos == mo1.bos);
+
+ tprintf("ok\n");
+
+// tprintf("testing comparison operators... ");
+
+// test(mo1->a == 15 && 15 == mo1->a && mo1->a != 16 && 16 != mo1->a);
+// test(mo1->a < 16 && mo1->a > 14 && mo1->a <= 15 && mo1->a >= 15 && mo1->a <= 16 && mo1->a >= 14);
+// test(mo1->a > IceUtil::Optional<int>() && IceUtil::Optional<int>() < mo1->a);
+// test(14 > IceUtil::Optional<int>() && IceUtil::Optional<int>() < 14);
+
+// test(mo1->h == "test" && "test" == mo1->h && mo1->h != "testa" && "testa" != mo1->h);
+// test(mo1->h < "test1" && mo1->h > "tesa" && mo1->h <= "test");
+// test(mo1->h >= "test" && mo1->h <= "test1" && mo1->h >= "tesa");
+// test(mo1->h > IceUtil::Optional<string>() && IceUtil::Optional<string>() < mo1->h);
+// test("test1" > IceUtil::Optional<string>() && IceUtil::Optional<string>() < "test1");
+
+// tprintf("ok\n");
+
+ tprintf("testing marshalling... ");
+ TestOptionalOneOptional* oo4 = (TestOptionalOneOptional*)[initial pingPong:[TestOptionalOneOptional oneOptional]];
+ test(![oo4 hasA]);
+
+ TestOptionalOneOptional* oo5 = (TestOptionalOneOptional*)[initial pingPong:oo1];
+ test(oo1.a == oo5.a);
+
+ TestOptionalMultiOptional* mo4 = (TestOptionalMultiOptional*)
+ [initial pingPong:[TestOptionalMultiOptional multiOptional]];
+ test(![mo4 hasA]);
+ test(![mo4 hasB]);
+ test(![mo4 hasC]);
+ test(![mo4 hasD]);
+ test(![mo4 hasE]);
+ test(![mo4 hasF]);
+ test(![mo4 hasG]);
+ test(![mo4 hasH]);
+ test(![mo4 hasI]);
+ test(![mo4 hasJ]);
+ test(![mo4 hasK]);
+ test(![mo4 hasBs]);
+ test(![mo4 hasSs]);
+ test(![mo4 hasIid]);
+ test(![mo4 hasSid]);
+ test(![mo4 hasFs]);
+ test(![mo4 hasVs]);
+
+ test(![mo4 hasShs]);
+ test(![mo4 hasEs]);
+ test(![mo4 hasFss]);
+ test(![mo4 hasVss]);
+ test(![mo4 hasOos]);
+ test(![mo4 hasOops]);
+
+ test(![mo4 hasIed]);
+ test(![mo4 hasIfsd]);
+ test(![mo4 hasIvsd]);
+ test(![mo4 hasIood]);
+ test(![mo4 hasIoopd]);
+
+ test(![mo4 hasBos]);
+
+ //mo1.k = mo1;
+ TestOptionalMultiOptional* mo5 = (TestOptionalMultiOptional*)[initial pingPong:mo1];
+ test(mo5.a == mo1.a);
+ test(mo5.b == mo1.b);
+ test(mo5.c == mo1.c);
+ test(mo5.d == mo1.d);
+ test(mo5.e == mo1.e);
+ test(mo5.f == mo1.f);
+ test(mo5.g == mo1.g);
+ test([mo5.h isEqualToString:mo1.h]);
+ test(mo5.i == mo1.i);
+ test([mo5.j isEqual:mo1.j]);
+ //test(mo5.k == mo5);
+ test([mo5.bs isEqual:mo1.bs]);
+ test([mo5.ss isEqual:mo1.ss]);
+ test([mo5.iid isEqual: mo1.iid]);
+ test([mo5.sid isEqual:mo1.sid]);
+ test([mo5.fs isEqual:mo1.fs]);
+ test([mo5.vs isEqual:mo1.vs]);
+
+ test([mo5.shs isEqual:mo1.shs]);
+ test([mo5.es isEqual:mo1.es]);
+ test([mo5.fss isEqual:mo1.fss]);
+ test([mo5.vss isEqual:mo1.vss]);
+ test([mo5.oos count] > 0 && ((TestOptionalOneOptional*)[mo5.oos objectAtIndex:0]).a == oo1.a);
+ test([mo5.oops isEqual:mo1.oops]);
+
+ test([mo5.ied isEqual:mo1.ied]);
+ test([mo5.ifsd isEqual:mo1.ifsd]);
+ test([mo5.ivsd isEqual:mo1.ivsd]);
+ test([mo5.iood count] > 0 && ((TestOptionalOneOptional*)[mo5.iood objectForKey:@5]).a == 15);
+ test([mo5.ioopd isEqual:mo1.ioopd]);
+
+ test([mo5.bos isEqual:mo1.bos]);
+
+ // Clear the first half of the optional parameters
+ TestOptionalMultiOptional* mo6 = [mo5 copy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [mo6 autorelease];
+#endif
+ [mo6 clearA];
+ [mo6 clearC];
+ [mo6 clearE];
+ [mo6 clearG];
+ [mo6 clearI];
+ [mo6 clearK];
+ [mo6 clearSs];
+ [mo6 clearSid];
+ [mo6 clearVs];
+
+ [mo6 clearEs];
+ [mo6 clearVss];
+ [mo6 clearOops];
+
+ [mo6 clearIed];
+ [mo6 clearIvsd];
+ [mo6 clearIoopd];
+
+ TestOptionalMultiOptional* mo7 = (TestOptionalMultiOptional*)[initial pingPong:mo6];
+ test(![mo7 hasA]);
+ test(mo7.b == mo1.b);
+ test(![mo7 hasC]);
+ test(mo7.d == mo1.d);
+ test(![mo7 hasE]);
+ test(mo7.f == mo1.f);
+ test(![mo7 hasG]);
+ test([mo7.h isEqual:mo1.h]);
+ test(![mo7 hasI]);
+ test([mo7.j isEqual:mo1.j]);
+ test(![mo7 hasK]);
+ test([mo7.bs isEqual:mo1.bs]);
+ test(![mo7 hasSs]);
+ test([mo7.iid isEqual:mo1.iid]);
+ test(![mo7 hasSid]);
+ test([mo7.fs isEqual:mo1.fs]);
+ test(![mo7 hasVs]);
+
+ test([mo7.shs isEqual:mo1.shs]);
+ test(![mo7 hasEs]);
+ test([mo7.fss isEqual:mo1.fss]);
+ test(![mo7 hasVss]);
+ test([mo7.oos count] > 0 && ((TestOptionalOneOptional*)[mo7.oos objectAtIndex:0]).a == oo1.a);
+ test(![mo7 hasOops]);
+
+ test(![mo7 hasIed]);
+ test([mo7.ifsd isEqual:mo1.ifsd]);
+ test(![mo7 hasIvsd]);
+ test([mo7.iood count] > 0 && ((TestOptionalOneOptional*)[mo7.iood objectForKey:@5]).a == 15);
+ test(![mo7 hasIoopd]);
+
+ // Clear the second half of the optional parameters
+ TestOptionalMultiOptional* mo8 = [mo5 copy];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [mo8 autorelease];
+#endif
+ [mo8 clearB];
+ [mo8 clearD];
+ [mo8 clearF];
+ [mo8 clearH];
+ [mo8 clearJ];
+ [mo8 clearBs];
+ [mo8 clearIid];
+ [mo8 clearFs];
+
+ [mo8 clearShs];
+ [mo8 clearFss];
+ [mo8 clearOos];
+
+ [mo8 clearIfsd];
+ [mo8 clearIood];
+
+ TestOptionalMultiOptional* mo9 = (TestOptionalMultiOptional*)[initial pingPong:mo8];
+ test(mo9.a == mo1.a);
+ test(![mo9 hasB]);
+ test(mo9.c == mo1.c);
+ test(![mo9 hasD]);
+ test(mo9.e == mo1.e);
+ test(![mo9 hasF]);
+ test(mo9.g == mo1.g);
+ test(![mo9 hasH]);
+ test(mo9.i == mo1.i);
+ test(![mo9 hasJ]);
+ //test(mo9.k == mo9.k);
+ test(![mo9 hasBs]);
+ test([mo9.ss isEqual:mo1.ss]);
+ test(![mo9 hasIid]);
+ test([mo9.sid isEqual:mo1.sid]);
+ test(![mo9 hasFs]);
+ test([mo9.vs isEqual:mo1.vs]);
+
+ test(![mo8 hasShs]);
+ test([mo8.es isEqual:mo1.es]);
+ test(![mo8 hasFss]);
+ test([mo8.vss isEqual:mo1.vss]);
+ test(![mo8 hasOos]);
+ test([mo8.oops isEqual:mo1.oops]);
+
+ test([mo8.ied isEqual:mo1.ied]);
+ test(![mo8 hasIfsd]);
+ test([mo8.ivsd isEqual:mo1.ivsd]);
+ test(![mo8 hasIood]);
+
+ //
+ // Send a request using blobjects. Upon receival, we don't read
+ // any of the optional members. This ensures the optional members
+ // are skipped even if the receiver knows nothing about them.
+ //
+ [factory setEnabled:YES];
+ id<ICEOutputStream> os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [os writeObject:oo1];
+ [os endEncapsulation];
+ ICEByteSeq* inEncaps = [os finished];
+ ICEMutableByteSeq* outEncaps;
+ test([initial ice_invoke:@"pingPong" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps]);
+ id<ICEInputStream> is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ ICEObject* obj;
+ [is readObject:&obj];
+ [is endEncapsulation];
+ test(obj != nil && [obj isKindOfClass:[TestObjectReader class]]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [os writeObject:mo1];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ test([initial ice_invoke:@"pingPong" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps]);
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is readObject:&obj];
+ [is endEncapsulation];
+ test(obj != nil && [obj isKindOfClass:[TestObjectReader class]]);
+ [factory setEnabled:false];
+
+ //
+ // Use the 1.0 encoding with operations whose only class parameters are optional.
+ //
+ id oo = [TestOptionalOneOptional oneOptional:@53];
+ [initial sendOptionalClass:YES o:oo];
+ [[initial ice_encodingVersion:ICEEncoding_1_0] sendOptionalClass:YES o:oo];
+
+ [initial returnOptionalClass:YES o:&oo];
+ test(oo != nil && oo != ICENone);
+ [[initial ice_encodingVersion:ICEEncoding_1_0] returnOptionalClass:YES o:&oo];
+ test(oo == ICENone);
+
+ tprintf("ok\n");
+
+ tprintf("testing marshalling of large containers with fixed size elements...");
+ TestOptionalMultiOptional* mc = [TestOptionalMultiOptional multiOptional];
+
+ mc.bs = [TestOptionalMutableByteSeq dataWithLength:1000];
+ mc.shs = [TestOptionalMutableShortSeq dataWithLength:300 * sizeof(ICEShort)];
+ mc.fss = [TestOptionalMutableFixedStructSeq array];
+ for(int i = 0; i < 300; ++i)
+ {
+ [(TestOptionalMutableFixedStructSeq*)mc.fss addObject:[TestOptionalFixedStruct fixedStruct]];
+ }
+
+ mc.ifsd = [TestOptionalMutableIntFixedStructDict dictionary];
+ for(int i = 0; i < 300; ++i)
+ {
+ [(TestOptionalMutableIntFixedStructDict*)mc.ifsd setObject:[TestOptionalFixedStruct fixedStruct] forKey:@(i)];
+ }
+
+ mc = (TestOptionalMultiOptional*)[initial pingPong:mc];
+ test([mc.bs length] == 1000);
+ test([mc.shs length] == 300 * sizeof(ICEShort));
+ test([mc.fss count] == 300);
+ test([mc.ifsd count] == 300);
+
+ [factory setEnabled:YES];
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [os writeObject:mc];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+
+ test([initial ice_invoke:@"pingPong" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps]);
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is readObject:&obj];
+ [is endEncapsulation];
+ test(obj != nil && [obj isKindOfClass:[TestObjectReader class]]);
+ [factory setEnabled:NO];
+
+ tprintf("ok\n");
+
+ tprintf("testing tag marshalling... ");
+ TestOptionalB* b = [TestOptionalB b];
+ TestOptionalB* b2 = (TestOptionalB*)[initial pingPong:b];
+ test(![b2 hasMa]);
+ test(![b2 hasMb]);
+ test(![b2 hasMc]);
+
+ b.ma = 10;
+ b.mb = 11;
+ b.mc = 12;
+ b.md = 13;
+
+ b2 = (TestOptionalB*)[initial pingPong:b];
+ test(b2.ma == 10);
+ test(b2.mb == 11);
+ test(b2.mc == 12);
+ test(b2.md == 13);
+
+ [factory setEnabled:YES];
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [os writeObject:b];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ test([initial ice_invoke:@"pingPong" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps]);
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is readObject:&obj];
+ [is endEncapsulation];
+ test(obj != nil);
+ [factory setEnabled:NO];
+
+ tprintf("ok\n");
+
+ tprintf("testing marshalling of objects with optional objects...");
+ {
+ TestOptionalF* f = [TestOptionalF f];
+
+ f.af = [TestOptionalA a];
+ f.ae = f.af;
+
+ TestOptionalF* rf = (TestOptionalF*)[initial pingPong:f];
+ test(rf.ae == rf.af);
+
+ [factory setEnabled:YES];
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [os writeObject:f];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ is = [ICEUtil createInputStream:communicator data:inEncaps];
+ [is startEncapsulation];
+ [is readObject:&obj];
+ [is endEncapsulation];
+ [factory setEnabled:NO];
+
+ test(obj != nil && [obj isKindOfClass:[FObjectReader class]]);
+ rf = [(FObjectReader*)obj getF];
+ test(rf.ae != nil && ![rf hasAf]);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing optional with default values... ");
+ TestOptionalWD* wd = (TestOptionalWD*)[initial pingPong:[TestOptionalWD wD]];
+ test(wd.a == 5);
+ test([wd.s isEqualToString:@"test"]);
+ [wd clearA];
+ [wd clearS];
+ wd = (TestOptionalWD*)[initial pingPong:wd];
+ test(![wd hasA]);
+ test(![wd hasS]);
+ tprintf("ok\n");
+
+ if([[communicator getProperties] getPropertyAsInt:@"Ice.Default.SlicedFormat"] > 0)
+ {
+ tprintf("testing marshalling with unknown class slices... ");
+ {
+ TestOptionalC* c = [TestOptionalC c];
+ c.ss = @"test";
+ c.ms = @"testms";
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [os writeObject:c];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [factory setEnabled:YES];
+ test([initial ice_invoke:@"pingPong" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps]);
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is readObject:&obj];
+ [is endEncapsulation];
+ test(obj != nil && [obj isKindOfClass:[CObjectReader class]]);
+ [factory setEnabled:NO];
+
+ [factory setEnabled:YES];
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ ICEObject* d = [DObjectWriter new];
+ [os writeObject:d];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d release];
+#endif
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ test([initial ice_invoke:@"pingPong" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps]);
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is readObject:&obj];
+ [is endEncapsulation];
+ test(obj != nil && [obj isKindOfClass:[DObjectReader class]]);
+ [(DObjectReader*)obj check];
+ [factory setEnabled:NO];
+ }
+ tprintf("ok\n");
+
+ tprintf("testing optionals with unknown classes...");
+ {
+ TestOptionalA* a = [TestOptionalA a];
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [os writeObject:a];
+ DObjectWriter* writer = [DObjectWriter new];
+ [ICEObjectHelper writeOpt:writer stream:os tag:1];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [writer release];
+#endif
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ test([initial ice_invoke:@"opClassAndUnknownOptional" mode:ICENormal inEncaps:inEncaps
+ outEncaps:&outEncaps]);
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+ tprintf("ok\n");
+ }
+
+ tprintf("testing optional parameters... ");
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opByte:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ p1 = @0x56;
+ p2 = [initial opByte:p1 p3:&p3];
+ test([p2 isEqual:@0x56] && [p3 isEqual:@0x56]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [ICEByteHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opByte" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [ICEByteHelper readOpt:is tag:1];
+ p3 = [ICEByteHelper readOpt:is tag:3];
+
+ id p4 = @0x08;
+ p4 = [ICEByteHelper readOpt:is tag:89];
+
+ [is endEncapsulation];
+ test([p2 isEqual:@0x56] && [p3 isEqual:@0x56] && [p4 isEqual:ICENone]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opLong:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ p1 = @56;
+ p2 = [initial opLong:p1 p3:&p3];
+ test([p2 isEqual:@56] && [p3 isEqual:@56]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [ICELongHelper writeOpt:p1 stream:os tag:1];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opLong" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p3 = [ICELongHelper readOpt:is tag:2];
+ p2 = [ICELongHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:@56] && [p3 isEqual:@56]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opString:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ p1 = @"test";
+ p2 = [initial opString:p1 p3:&p3];
+ test([p2 isEqualToString:@"test"] && [p3 isEqualToString:@"test"]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [ICEStringHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opString" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [ICEStringHelper readOpt:is tag:1];
+ p3 = [ICEStringHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqualToString:@"test"] && [p3 isEqualToString:@"test"]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opOneOptional:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ p1 = [TestOptionalOneOptional oneOptional:@58];
+ p2 = [initial opOneOptional:p1 p3:&p3];
+ test([p2 isKindOfClass:[TestOptionalOneOptional class]] && [p3 isKindOfClass:[TestOptionalOneOptional class]]);
+ test(((TestOptionalOneOptional*)p2).a == 58 && ((TestOptionalOneOptional*)p3).a == 58);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [ICEObjectHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opOneOptional" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [ICEObjectHelper readOpt:&p2 stream:is tag:1];
+ [ICEObjectHelper readOpt:&p3 stream:is tag:3];
+ [is endEncapsulation];
+ test([p2 isKindOfClass:[TestOptionalOneOptional class]] && [p3 isKindOfClass:[TestOptionalOneOptional class]]);
+ test(((TestOptionalOneOptional*)p2).a == 58 && ((TestOptionalOneOptional*)p3).a == 58);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opOneOptionalProxy:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ p1 = [TestOptionalOneOptionalPrx uncheckedCast:[communicator stringToProxy:@"test"]];
+ p2 = [initial opOneOptionalProxy:p1 p3:&p3];
+ test([p2 isKindOfClass:[TestOptionalOneOptionalPrx class]] &&
+ [p3 isKindOfClass:[TestOptionalOneOptionalPrx class]]);
+ test([p2 isEqual:p1] && [p3 isEqual:p1]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [ICEProxyHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opOneOptionalProxy" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalOneOptionalPrxHelper readOpt:is tag:1];
+ p3 = [TestOptionalOneOptionalPrxHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isKindOfClass:[TestOptionalOneOptionalPrx class]] &&
+ [p3 isKindOfClass:[TestOptionalOneOptionalPrx class]]);
+ test([p2 isEqual:p1] && [p3 isEqual:p1]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ TestOptionalF* f = [TestOptionalF f];
+ f.af = [TestOptionalA a];
+ f.af.requiredA = 56;
+ f.ae = f.af;
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalFHelper writeOpt:f stream:os tag:1];
+ [TestOptionalFHelper writeOpt:f.ae stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+
+ is = [ICEUtil createInputStream:communicator data:inEncaps];
+ [is startEncapsulation];
+ id a;
+ [TestOptionalAHelper readOpt:&a stream:is tag:2];
+ [is endEncapsulation];
+ test(a != nil && [a isKindOfClass:[TestOptionalA class]] && ((TestOptionalA*)a).requiredA == 56);
+ }
+ tprintf("ok\n");
+
+ tprintf("testing optional parameters and sequences... ");
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opByteSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ TestOptionalByteSeq* bs = [TestOptionalMutableByteSeq dataWithLength:100];
+ p1 = bs;
+ p2 = [initial opByteSeq:p1 p3:&p3];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalByteSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opByteSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalByteSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalByteSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opBoolSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ TestOptionalBoolSeq* bs = [TestOptionalMutableBoolSeq dataWithLength:100];
+ p1 = bs;
+ p2 = [initial opBoolSeq:p1 p3:&p3];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalBoolSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opBoolSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalBoolSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalBoolSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opShortSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ TestOptionalShortSeq* bs = [TestOptionalMutableShortSeq dataWithLength:100 * sizeof(ICEShort)];
+ p1 = bs;
+ p2 = [initial opShortSeq:p1 p3:&p3];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalShortSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opShortSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalShortSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalShortSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opIntSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ TestOptionalIntSeq* bs = [TestOptionalMutableIntSeq dataWithLength:100 * sizeof(ICEInt)];
+ p1 = bs;
+ p2 = [initial opIntSeq:p1 p3:&p3];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalIntSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opIntSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalIntSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalIntSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opLongSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ TestOptionalLongSeq* bs = [TestOptionalMutableLongSeq dataWithLength:100 * sizeof(ICELong)];
+ p1 = bs;
+ p2 = [initial opLongSeq:p1 p3:&p3];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalLongSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opLongSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalLongSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalLongSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opFloatSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ TestOptionalFloatSeq* bs = [TestOptionalMutableFloatSeq dataWithLength:100 * sizeof(ICEFloat)];
+ p1 = bs;
+ p2 = [initial opFloatSeq:p1 p3:&p3];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalFloatSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opFloatSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalFloatSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalFloatSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opDoubleSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ TestOptionalDoubleSeq* bs = [TestOptionalMutableDoubleSeq dataWithLength:100 * sizeof(ICEDouble)];
+ p1 = bs;
+ p2 = [initial opDoubleSeq:p1 p3:&p3];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalDoubleSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opDoubleSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalDoubleSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalDoubleSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:bs] && [p3 isEqual:bs]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opStringSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ TestOptionalMutableStringSeq* ss = [TestOptionalMutableStringSeq array];
+ [ss addObject:@"test1"];
+ p1 = ss;
+ p2 = [initial opStringSeq:p1 p3:&p3];
+ test([p2 isEqual:ss] && [p3 isEqual:ss]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalStringSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opStringSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalStringSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalStringSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test([p2 isEqual:ss] && [p3 isEqual:ss]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opFixedStructSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ p2 = [initial opFixedStructSeq:[TestOptionalMutableFixedStructSeq array] p3:&p3];
+ test(p2 != nil && p3 != nil && [p2 count] == 0 && [p3 count] == 0);
+
+ TestOptionalMutableFixedStructSeq* fss = [TestOptionalMutableFixedStructSeq array];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:1]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:2]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:3]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:4]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:5]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:6]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:7]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:8]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:9]];
+ [fss addObject:[TestOptionalFixedStruct fixedStruct:10]];
+ p1 = fss;
+ p2 = [initial opFixedStructSeq:p1 p3:&p3];
+ test(p2 != nil && p3 != nil);
+ test([p2 isEqual:fss] && [p3 isEqual:fss]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalFixedStructSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opFixedStructSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalFixedStructSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalFixedStructSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test(p2 != nil && p3 != nil);
+ test([p2 isEqual:fss] && [p3 isEqual:fss]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ {
+ id p1 = ICENone;
+ id p3 = ICENone;
+ id p2 = [initial opVarStructSeq:p1 p3:&p3];
+ test(p2 == ICENone && p3 == ICENone);
+
+ p2 = [initial opVarStructSeq:[TestOptionalMutableVarStructSeq array] p3:&p3];
+ test(p2 != nil && p3 != nil && [p2 count] == 0 && [p3 count] == 0);
+
+ TestOptionalMutableVarStructSeq* fss = [TestOptionalMutableVarStructSeq array];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"1"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"2"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"3"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"4"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"5"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"6"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"7"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"8"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"9"]];
+ [fss addObject:[TestOptionalVarStruct varStruct:@"10"]];
+ p1 = fss;
+ p2 = [initial opVarStructSeq:p1 p3:&p3];
+ test(p2 != nil && p3 != nil);
+ test([p2 isEqual:fss] && [p3 isEqual:fss]);
+
+ os = [ICEUtil createOutputStream:communicator];
+ [os startEncapsulation];
+ [TestOptionalVarStructSeqHelper writeOpt:p1 stream:os tag:2];
+ [os endEncapsulation];
+ inEncaps = [os finished];
+ [initial ice_invoke:@"opVarStructSeq" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ p2 = [TestOptionalVarStructSeqHelper readOpt:is tag:1];
+ p3 = [TestOptionalVarStructSeqHelper readOpt:is tag:3];
+ [is endEncapsulation];
+ test(p2 != nil && p3 != nil);
+ test([p2 isEqual:fss] && [p3 isEqual:fss]);
+
+ is = [ICEUtil createInputStream:communicator data:outEncaps];
+ [is startEncapsulation];
+ [is endEncapsulation];
+ }
+
+ tprintf("ok\n");
+
+ tprintf("testing exception optionals... ");
+ {
+ @try
+ {
+ [initial opOptionalException:ICENone b:ICENone o:ICENone];
+ test(NO);
+ }
+ @catch(TestOptionalOptionalException* ex)
+ {
+ test(![ex hasA]);
+ test(![ex hasB]);
+ test(![ex hasO]);
+ }
+
+ @try
+ {
+ [initial opOptionalException:@30 b:@"test" o:[TestOptionalOneOptional oneOptional:@53]];
+ test(NO);
+ }
+ @catch(TestOptionalOptionalException* ex)
+ {
+ test(ex.a == 30);
+ test([ex.b isEqualToString:@"test"]);
+ test(ex.o.a == 53);
+ }
+
+ @try
+ {
+ //
+ // Use the 1.0 encoding with an exception whose only class members are optional.
+ //
+ [[initial ice_encodingVersion:ICEEncoding_1_0]
+ opOptionalException:@30 b:@"test" o:[TestOptionalOneOptional oneOptional:@53]];
+ test(NO);
+ }
+ @catch(TestOptionalOptionalException* ex)
+ {
+ test(![ex hasA]);
+ test(![ex hasB]);
+ test(![ex hasO]);
+ }
+
+ @try
+ {
+ id a = ICENone;
+ id b = ICENone;
+ id o = ICENone;
+ [initial opDerivedException:a b:b o:o];
+ test(NO);
+ }
+ @catch(TestOptionalDerivedException* ex)
+ {
+ test(![ex hasA]);
+ test(![ex hasB]);
+ test(![ex hasO]);
+ test(![ex hasSs]);
+ test(![ex hasO2]);
+ }
+ @catch(TestOptionalOptionalException* ex)
+ {
+ test(NO);
+ }
+
+ @try
+ {
+ id a = @30;
+ id b = @"test2";
+ TestOptionalOneOptional* o = [TestOptionalOneOptional oneOptional:@53];
+ [initial opDerivedException:a b:b o:o];
+ test(NO);
+ }
+ @catch(TestOptionalDerivedException* ex)
+ {
+ test(ex.a == 30);
+ test([ex.b isEqualToString:@"test2"]);
+ test(ex.o.a == 53);
+ test([ex.ss isEqualToString:@"test2"]);
+ test(ex.o2.a == 53);
+ }
+ @catch(TestOptionalOptionalException* ex)
+ {
+ test(NO);
+ }
+
+ @try
+ {
+ id a = ICENone;
+ id b = ICENone;
+ id o = ICENone;
+ [initial opRequiredException:a b:b o:o];
+ test(NO);
+ }
+ @catch(TestOptionalRequiredException* ex)
+ {
+ test(![ex hasA]);
+ test(![ex hasB]);
+ test(![ex hasO]);
+ test([ex.ss isEqualToString:@"test"]);
+ }
+ @catch(TestOptionalOptionalException* ex)
+ {
+ test(NO);
+ }
+
+ @try
+ {
+ id a = @30;
+ id b = @"test2";
+ id o = [TestOptionalOneOptional oneOptional:@53];
+ [initial opRequiredException:a b:b o:o];
+ test(NO);
+ }
+ @catch(TestOptionalRequiredException* ex)
+ {
+ test(ex.a == 30);
+ test([ex.b isEqualToString:@"test2"]);
+ test(ex.o.a == 53);
+ test([ex.ss isEqualToString:@"test2"]);
+ test(ex.o2.a == 53);
+ }
+ @catch(TestOptionalOptionalException* ex)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ return initial;
+}
diff --git a/objc/test/Ice/optional/Client.m b/objc/test/Ice/optional/Client.m
new file mode 100644
index 00000000000..78a1566d3f0
--- /dev/null
+++ b/objc/test/Ice/optional/Client.m
@@ -0,0 +1,76 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <OptionalTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestOptionalInitialPrx> optionalAllTests(id<ICECommunicator>);
+ id<TestOptionalInitialPrx> optional = optionalAllTests(communicator);
+ [optional shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main optionalClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestOptional", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/optional/Makefile b/objc/test/Ice/optional/Makefile
new file mode 100644
index 00000000000..6a109d52841
--- /dev/null
+++ b/objc/test/Ice/optional/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = OptionalTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/optional/OptionalTest.ice b/objc/test/Ice/optional/OptionalTest.ice
new file mode 100644
index 00000000000..0d7bf921f37
--- /dev/null
+++ b/objc/test/Ice/optional/OptionalTest.ice
@@ -0,0 +1,279 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+[["cpp:include:list"]]
+
+["objc:prefix:TestOptional"]
+module Test
+{
+
+class OneOptional
+{
+ optional(1) int a;
+};
+
+enum MyEnum
+{
+ MyEnumMember
+};
+
+struct SmallStruct
+{
+ byte m;
+};
+
+struct FixedStruct
+{
+ int m;
+};
+
+struct VarStruct
+{
+ string m;
+};
+
+["cpp:class"] struct ClassVarStruct
+{
+ int a;
+};
+
+sequence<byte> ByteSeq;
+sequence<bool> BoolSeq;
+sequence<short> ShortSeq;
+sequence<int> IntSeq;
+sequence<long> LongSeq;
+sequence<float> FloatSeq;
+sequence<double> DoubleSeq;
+sequence<string> StringSeq;
+sequence<MyEnum> MyEnumSeq;
+sequence<SmallStruct> SmallStructSeq;
+["cpp:type:std::list< ::Test::SmallStruct>"] sequence<SmallStruct> SmallStructList;
+sequence<FixedStruct> FixedStructSeq;
+["cpp:type:std::list< ::Test::FixedStruct>"] sequence<FixedStruct> FixedStructList;
+sequence<VarStruct> VarStructSeq;
+sequence<OneOptional> OneOptionalSeq;
+sequence<OneOptional*> OneOptionalPrxSeq;
+
+sequence<byte> Serializable;
+
+dictionary<int, int> IntIntDict;
+dictionary<string, int> StringIntDict;
+dictionary<int, MyEnum> IntEnumDict;
+dictionary<int, FixedStruct> IntFixedStructDict;
+dictionary<int, VarStruct> IntVarStructDict;
+dictionary<int, OneOptional> IntOneOptionalDict;
+dictionary<int, OneOptional*> IntOneOptionalPrxDict;
+
+class MultiOptional
+{
+ optional(1) byte a;
+ optional(2) bool b;
+ optional(3) short c;
+ optional(4) int d;
+ optional(5) long e;
+ optional(6) float f;
+ optional(7) double g;
+ optional(8) string h;
+ optional(9) MyEnum i;
+ optional(10) MultiOptional* j;
+ optional(11) MultiOptional k;
+ optional(12) ByteSeq bs;
+ optional(13) StringSeq ss;
+ optional(14) IntIntDict iid;
+ optional(15) StringIntDict sid;
+ optional(16) FixedStruct fs;
+ optional(17) VarStruct vs;
+
+ optional(18) ShortSeq shs;
+ optional(19) MyEnumSeq es;
+ optional(20) FixedStructSeq fss;
+ optional(21) VarStructSeq vss;
+ optional(22) OneOptionalSeq oos;
+ optional(23) OneOptionalPrxSeq oops;
+
+ optional(24) IntEnumDict ied;
+ optional(25) IntFixedStructDict ifsd;
+ optional(26) IntVarStructDict ivsd;
+ optional(27) IntOneOptionalDict iood;
+ optional(28) IntOneOptionalPrxDict ioopd;
+
+ optional(29) BoolSeq bos;
+
+ optional(30) Serializable ser;
+};
+
+class A
+{
+ int requiredA = 0;
+ optional(500) int mc;
+ optional(50) int mb;
+ optional(1) int ma;
+};
+
+["preserve-slice"]
+class B extends A
+{
+ int requiredB = 0;
+ optional(10) int md;
+};
+
+class C extends B
+{
+ string ss;
+ optional(890) string ms;
+};
+
+class WD
+{
+ optional(1) int a = 5;
+ optional(2) string s = "test";
+};
+
+exception OptionalException
+{
+ bool req = false;
+ optional(1) int a = 5;
+ optional(2) string b;
+ optional(50) OneOptional o;
+};
+
+exception DerivedException extends OptionalException
+{
+ optional(600) string ss = "test";
+ optional(601) OneOptional o2;
+};
+
+exception RequiredException extends OptionalException
+{
+ string ss = "test";
+ OneOptional o2;
+};
+
+class OptionalWithCustom
+{
+ optional(1) SmallStructList l;
+ ["protected"] optional(2) SmallStructList lp;
+ optional(3) ClassVarStruct s;
+};
+
+class E
+{
+ A ae;
+};
+
+class F extends E
+{
+ optional(1) A af;
+};
+
+class Initial
+{
+ void shutdown();
+
+ Object pingPong(Object o);
+
+ void opOptionalException(optional(1) int a, optional(2) string b, optional(3) OneOptional o)
+ throws OptionalException;
+
+ void opDerivedException(optional(1) int a, optional(2) string b, optional(3) OneOptional o)
+ throws OptionalException;
+
+ void opRequiredException(optional(1) int a, optional(2) string b, optional(3) OneOptional o)
+ throws OptionalException;
+
+ optional(1) byte opByte(optional(2) byte p1, out optional(3) byte p3);
+
+ optional(1) bool opBool(optional(2) bool p1, out optional(3) bool p3);
+
+ optional(1) short opShort(optional(2) short p1, out optional(3) short p3);
+
+ optional(1) int opInt(optional(2) int p1, out optional(3) int p3);
+
+ optional(3) long opLong(optional(1) long p1, out optional(2) long p3);
+
+ optional(1) float opFloat(optional(2) float p1, out optional(3) float p3);
+
+ optional(1) double opDouble(optional(2) double p1, out optional(3) double p3);
+
+ optional(1) string opString(optional(2) string p1, out optional(3) string p3);
+
+ optional(1) MyEnum opMyEnum(optional(2) MyEnum p1, out optional(3) MyEnum p3);
+
+ optional(1) SmallStruct opSmallStruct(optional(2) SmallStruct p1, out optional(3) SmallStruct p3);
+
+ optional(1) FixedStruct opFixedStruct(optional(2) FixedStruct p1, out optional(3) FixedStruct p3);
+
+ optional(1) VarStruct opVarStruct(optional(2) VarStruct p1, out optional(3) VarStruct p3);
+
+ optional(1) OneOptional opOneOptional(optional(2) OneOptional p1, out optional(3) OneOptional p3);
+
+ optional(1) OneOptional* opOneOptionalProxy(optional(2) OneOptional* p1, out optional(3) OneOptional* p3);
+
+ // Custom mapping operations
+ ["cpp:array"] optional(1) ByteSeq opByteSeq(["cpp:array"] optional(2) ByteSeq p1,
+ out ["cpp:array"] optional(3) ByteSeq p3);
+
+ ["cpp:array"] optional(1) BoolSeq opBoolSeq(["cpp:array"] optional(2) BoolSeq p1,
+ out ["cpp:array"] optional(3) BoolSeq p3);
+
+ ["cpp:array"] optional(1) ShortSeq opShortSeq(["cpp:array"] optional(2) ShortSeq p1,
+ out ["cpp:array"] optional(3) ShortSeq p3);
+
+ ["cpp:range:array"] optional(1) IntSeq opIntSeq(["cpp:range:array"] optional(2) IntSeq p1,
+ out ["cpp:range:array"] optional(3) IntSeq p3);
+
+ ["cpp:range:array"] optional(1) LongSeq opLongSeq(["cpp:range:array"] optional(2) LongSeq p1,
+ out ["cpp:range:array"] optional(3) LongSeq p3);
+
+ ["cpp:range:array"] optional(1) FloatSeq opFloatSeq(["cpp:range:array"] optional(2) FloatSeq p1,
+ out ["cpp:range:array"] optional(3) FloatSeq p3);
+
+ ["cpp:range:array"] optional(1) DoubleSeq opDoubleSeq(["cpp:range:array"] optional(2) DoubleSeq p1,
+ out ["cpp:range:array"] optional(3) DoubleSeq p3);
+
+ ["cpp:range"] optional(1) StringSeq opStringSeq(["cpp:range"] optional(2) StringSeq p1,
+ out ["cpp:range"] optional(3) StringSeq p3);
+
+ ["cpp:array"] optional(1) SmallStructSeq opSmallStructSeq(["cpp:array"] optional(2) SmallStructSeq p1,
+ out ["cpp:array"] optional(3) SmallStructSeq p3);
+
+ ["cpp:array"] optional(1) SmallStructList opSmallStructList(["cpp:array"] optional(2) SmallStructList p1,
+ out ["cpp:array"] optional(3) SmallStructList p3);
+
+ ["cpp:array"] optional(1) FixedStructSeq opFixedStructSeq(["cpp:array"] optional(2) FixedStructSeq p1,
+ out ["cpp:array"] optional(3) FixedStructSeq p3);
+
+ ["cpp:array"] optional(1) FixedStructList opFixedStructList(["cpp:array"] optional(2) FixedStructList p1,
+ out ["cpp:array"] optional(3) FixedStructList p3);
+
+ ["cpp:range"] optional(1) VarStructSeq opVarStructSeq(["cpp:range"] optional(2) VarStructSeq p1,
+ out ["cpp:range"] optional(3) VarStructSeq p3);
+
+ optional(1) Serializable opSerializable(optional(2) Serializable p1, out optional(3) Serializable p3);
+
+ optional(1) IntIntDict opIntIntDict(optional(2) IntIntDict p1, out optional(3) IntIntDict p3);
+
+ optional(1) StringIntDict opStringIntDict(optional(2) StringIntDict p1, out optional(3) StringIntDict p3);
+
+ void opClassAndUnknownOptional(A p);
+
+ void sendOptionalClass(bool req, optional(1) OneOptional o);
+
+ void returnOptionalClass(bool req, out optional(1) OneOptional o);
+
+ bool supportsRequiredParams();
+
+ bool supportsJavaSerializable();
+
+ bool supportsCsharpSerializable();
+};
+
+};
diff --git a/objc/test/Ice/optional/Server.m b/objc/test/Ice/optional/Server.m
new file mode 100644
index 00000000000..6062cd44604
--- /dev/null
+++ b/objc/test/Ice/optional/Server.m
@@ -0,0 +1,82 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <optional/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* object = [[[InitialI alloc] init] autorelease];
+#else
+ ICEObject* object = [[InitialI alloc] init];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"initial"]];
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main optionalServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestOptional", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/optional/TestI.h b/objc/test/Ice/optional/TestI.h
new file mode 100644
index 00000000000..e4aa3497d7e
--- /dev/null
+++ b/objc/test/Ice/optional/TestI.h
@@ -0,0 +1,18 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <OptionalTest.h>
+
+@interface InitialI : TestOptionalInitial<TestOptionalInitial>
+-(void) shutdown:(ICECurrent *)current;
+-(ICEObject*) pingPong:(ICEObject*)obj current:(ICECurrent*)current;
+-(BOOL) supportsRequiredParams:(ICECurrent*)current;
+-(BOOL) supportsJavaSerializable:(ICECurrent*)current;
+-(BOOL) supportsCsharpSerializable:(ICECurrent*)current;
+@end
diff --git a/objc/test/Ice/optional/TestI.m b/objc/test/Ice/optional/TestI.m
new file mode 100644
index 00000000000..17e22e5a471
--- /dev/null
+++ b/objc/test/Ice/optional/TestI.m
@@ -0,0 +1,239 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <optional/TestI.h>
+#import <objc/Ice.h>
+
+#import <Foundation/NSThread.h>
+
+@implementation InitialI
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+-(ICEObject*) pingPong:(ICEObject*)obj current:(ICECurrent*)current
+{
+ return obj;
+}
+-(void) opOptionalException:(id)a b:(id)b o:(id)o current:(ICECurrent *)current
+{
+ @throw [TestOptionalOptionalException optionalException:NO a:a b:b o:o];
+}
+-(void) opDerivedException:(id)a b:(id)b o:(id)o current:(ICECurrent *)current
+{
+ @throw [TestOptionalDerivedException derivedException:NO a:a b:b o:o ss:b o2:o];
+}
+-(void) opRequiredException:(id)a b:(id)b o:(id)o current:(ICECurrent *)current
+{
+ TestOptionalRequiredException* ex = [TestOptionalRequiredException requiredException];
+ if(a != ICENone)
+ {
+ ex.a = [a intValue];
+ }
+ else
+ {
+ [ex clearA];
+ }
+ if(b != ICENone)
+ {
+ ex.b = b;
+ }
+ else
+ {
+ [ex clearB];
+ }
+ if(o != ICENone)
+ {
+ ex.o = o;
+ ex.o2 = o;
+ }
+ else
+ {
+ [ex clearO];
+ }
+ if(b != ICENone)
+ {
+ ex.ss = b;
+ }
+ @throw ex;
+}
+-(id) opByte:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opBool:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opShort:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opInt:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opLong:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opFloat:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opDouble:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opString:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opMyEnum:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opSmallStruct:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opFixedStruct:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opVarStruct:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opOneOptional:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opOneOptionalProxy:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opByteSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opBoolSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opShortSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opIntSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opLongSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opFloatSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opDoubleSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opStringSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opSmallStructSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opSmallStructList:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opFixedStructSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opFixedStructList:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opVarStructSeq:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opSerializable:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opIntIntDict:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(id) opStringIntDict:(id)p1 p3:(id *)p3 current:(ICECurrent *)current
+{
+ *p3 = p1;
+ return p1;
+}
+-(void) opClassAndUnknownOptional:(TestOptionalA *)p current:(ICECurrent *)current
+{
+}
+-(void) sendOptionalClass:(BOOL)req o:(id)o current:(ICECurrent *)current
+{
+}
+-(void) returnOptionalClass:(BOOL)req o:(id *)o current:(ICECurrent *)current
+{
+ *o = [TestOptionalOneOptional oneOptional:@53];
+}
+-(BOOL) supportsRequiredParams:(ICECurrent*)current
+{
+ return NO;
+}
+-(BOOL) supportsJavaSerializable:(ICECurrent*)current
+{
+ return NO;
+}
+-(BOOL) supportsCsharpSerializable:(ICECurrent*)current
+{
+ return NO;
+}
+
+@end
diff --git a/objc/test/Ice/optional/run.py b/objc/test/Ice/optional/run.py
new file mode 100755
index 00000000000..a46b2e38375
--- /dev/null
+++ b/objc/test/Ice/optional/run.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+print("Running test with compact (default) format.")
+TestUtil.clientServerTest()
+print("Running test with sliced format.")
+TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.SlicedFormat", additionalServerOptions="--Ice.Default.SlicedFormat")
diff --git a/objc/test/Ice/proxy/.gitignore b/objc/test/Ice/proxy/.gitignore
new file mode 100644
index 00000000000..c2defa1d701
--- /dev/null
+++ b/objc/test/Ice/proxy/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+ProxyTest.m
+ProxyTest.h
diff --git a/objc/test/Ice/proxy/AllTests.m b/objc/test/Ice/proxy/AllTests.m
new file mode 100644
index 00000000000..a2760b729eb
--- /dev/null
+++ b/objc/test/Ice/proxy/AllTests.m
@@ -0,0 +1,869 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <ProxyTest.h>
+
+
+TestProxyMyClassPrx*
+proxyAllTests(id<ICECommunicator> communicator)
+{
+ tprintf("testing stringToProxy... ");
+ NSString* ref = @"test:default -p 12010";
+ id<ICEObjectPrx> base = [communicator stringToProxy:ref];
+ test(base);
+
+ id<ICEObjectPrx> b1 = [communicator stringToProxy:@"test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getAdapterId] length] == 0 && [[b1 ice_getFacet] length] == 0);
+ b1 = [communicator stringToProxy:@"test "];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] length] == 0);
+ b1 = [communicator stringToProxy:@" test "];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] length] == 0);
+ b1 = [communicator stringToProxy:@" test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] length] == 0);
+ b1 = [communicator stringToProxy:@"'test -f facet'"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test -f facet"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] length] == 0);
+ @try
+ {
+ b1 = [communicator stringToProxy:@"\"test -f facet'"];
+ test(NO);
+ }
+ @catch(ICEProxyParseException*)
+ {
+ }
+ b1 = [communicator stringToProxy:@"\"test -f facet\""];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test -f facet"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] length] == 0);
+ b1 = [communicator stringToProxy:@"\"test -f facet@test\""];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test -f facet@test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] length] == 0);
+ b1 = [communicator stringToProxy:@"\"test -f facet@test @test\""];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test -f facet@test @test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] length] == 0);
+ @try
+ {
+ b1 = [communicator stringToProxy:@"test test"];
+ test(NO);
+ }
+ @catch(ICEProxyParseException*)
+ {
+ }
+ b1 = [communicator stringToProxy:@"test\\040test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0);
+ @try
+ {
+ b1 = [communicator stringToProxy:@"test\\777"];
+ test(NO);
+ }
+ @catch(ICEIdentityParseException*)
+ {
+ }
+ b1 = [communicator stringToProxy:@"test\\40test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test test"]);
+
+ // TestProxy some octal and hex corner cases.
+ b1 = [communicator stringToProxy:@"test\\4test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test\4test"]);
+ b1 = [communicator stringToProxy:@"test\\04test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test\4test"]);
+ b1 = [communicator stringToProxy:@"test\\004test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test\4test"]);
+ b1 = [communicator stringToProxy:@"test\\1114test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test\1114test"]);
+
+ b1 = [communicator stringToProxy:@"test\\b\\f\\n\\r\\t\\'\\\"\\\\test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test\b\f\n\r\t\'\"\\test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0);
+
+ b1 = [communicator stringToProxy:@"category/test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] isEqualToString:@"category"] &&
+ [[b1 ice_getAdapterId] length] == 0);
+
+ b1 = [communicator stringToProxy:@"test@adapter"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getAdapterId] isEqualToString:@"adapter"]);
+ @try
+ {
+ b1 = [communicator stringToProxy:@"id@adapter test"];
+ test(NO);
+ }
+ @catch(ICEProxyParseException*)
+ {
+ }
+ b1 = [communicator stringToProxy:@"category/test@adapter"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] isEqualToString:@"category"] &&
+ [[b1 ice_getAdapterId] isEqualToString:@"adapter"]);
+ b1 = [communicator stringToProxy:@"category/test@adapter:tcp"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] isEqualToString:@"category"] &&
+ [[b1 ice_getAdapterId] isEqualToString:@"adapter:tcp"]);
+ b1 = [communicator stringToProxy:@"'category 1/test'@adapter"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] isEqualToString:@"category 1"] &&
+ [[b1 ice_getAdapterId] isEqualToString:@"adapter"]);
+ b1 = [communicator stringToProxy:@"'category/test 1'@adapter"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test 1"] &&
+ [[[b1 ice_getIdentity] category] isEqualToString:@"category"] &&
+ [[b1 ice_getAdapterId] isEqualToString:@"adapter"]);
+ b1 = [communicator stringToProxy:@"'category/test'@'adapter 1'"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] isEqualToString:@"category"] &&
+ [[b1 ice_getAdapterId] isEqualToString:@"adapter 1"]);
+ b1 = [communicator stringToProxy:@"\"category \\/test@foo/test\"@adapter"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] isEqualToString:@"category /test@foo"] &&
+ [[b1 ice_getAdapterId] isEqualToString:@"adapter"]);
+ b1 = [communicator stringToProxy:@"\"category \\/test@foo/test\"@\"adapter:tcp\""];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] &&
+ [[[b1 ice_getIdentity] category] isEqualToString:@"category /test@foo"] &&
+ [[b1 ice_getAdapterId] isEqualToString:@"adapter:tcp"]);
+
+ b1 = [communicator stringToProxy:@"id -f facet"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"id"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] isEqualToString:@"facet"]);
+ b1 = [communicator stringToProxy:@"id -f 'facet x'"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"id"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] isEqualToString:@"facet x"]);
+ b1 = [communicator stringToProxy:@"id -f \"facet x\""];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"id"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] isEqualToString:@"facet x"]);
+ @try
+ {
+ b1 = [communicator stringToProxy:@"id -f \"facet x"];
+ test(NO);
+ }
+ @catch(ICEProxyParseException*)
+ {
+ }
+ @try
+ {
+ b1 = [communicator stringToProxy:@"id -f \'facet x"];
+ test(NO);
+ }
+ @catch(ICEProxyParseException*)
+ {
+ }
+ b1 = [communicator stringToProxy:@"test -f facet:tcp"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] isEqualToString:@"facet"] && [[b1 ice_getAdapterId] length] == 0);
+ b1 = [communicator stringToProxy:@"test -f \"facet:tcp\""];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] isEqualToString:@"facet:tcp"] && [[b1 ice_getAdapterId] length] == 0);
+ b1 = [communicator stringToProxy:@"test -f facet@test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] isEqualToString:@"facet"] && [[b1 ice_getAdapterId] isEqualToString:@"test"]);
+ b1 = [communicator stringToProxy:@"test -f 'facet@test'"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] isEqualToString:@"facet@test"] && [[b1 ice_getAdapterId] length] == 0);
+ b1 = [communicator stringToProxy:@"test -f 'facet@test'@test"];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getFacet] isEqualToString:@"facet@test"] && [[b1 ice_getAdapterId] isEqualToString:@"test"]);
+ @try
+ {
+ b1 = [communicator stringToProxy:@"test -f facet@test @test"];
+ test(NO);
+ }
+ @catch(ICEProxyParseException*)
+ {
+ }
+ b1 = [communicator stringToProxy:@"test"];
+ test([b1 ice_isTwoway]);
+ b1 = [communicator stringToProxy:@"test -t"];
+ test([b1 ice_isTwoway]);
+ b1 = [communicator stringToProxy:@"test -o"];
+ test([b1 ice_isOneway]);
+ b1 = [communicator stringToProxy:@"test -O"];
+ test([b1 ice_isBatchOneway]);
+ b1 = [communicator stringToProxy:@"test -d"];
+ test([b1 ice_isDatagram]);
+ b1 = [communicator stringToProxy:@"test -D"];
+ test([b1 ice_isBatchDatagram]);
+ b1 = [communicator stringToProxy:@"test"];
+ test(![b1 ice_isSecure]);
+ b1 = [communicator stringToProxy:@"test -s"];
+ test([b1 ice_isSecure]);
+
+ test([[b1 ice_getEncodingVersion] isEqual:ICECurrentEncoding]);
+
+ b1 = [communicator stringToProxy:@"test -e 1.0"];
+ test([b1 ice_getEncodingVersion].major == 1 && [b1 ice_getEncodingVersion].minor == 0);
+
+ b1 = [communicator stringToProxy:@"test -e 6.5"];
+ test([b1 ice_getEncodingVersion].major == 6 && [b1 ice_getEncodingVersion].minor == 5);
+
+ b1 = [communicator stringToProxy:@"test -p 1.0 -e 1.0"];
+ test([[b1 ice_toString] isEqualToString:@"test -t -e 1.0"]);
+
+ b1 = [communicator stringToProxy:@"test -p 6.5 -e 1.0"];
+ test([[b1 ice_toString] isEqualToString:@"test -t -p 6.5 -e 1.0"]);
+
+ @try
+ {
+ b1 = [communicator stringToProxy:@"test:tcp@adapterId"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+ // This is an unknown endpoint warning, not a parse exception.
+ //
+ //try
+ //{
+ // b1 = [communicator stringToProxy:@"test -f the:facet:tcp"];
+ // test(NO);
+ //}
+ //catch(ICEEndpointParseException*)
+ //{
+ //}
+ @try
+ {
+ b1 = [communicator stringToProxy:@"test::tcp"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+ tprintf("ok\n");
+
+ tprintf("testing propertyToProxy... ");
+ id<ICEProperties> prop = [communicator getProperties];
+ NSString* propertyPrefix = @"Foo.Proxy";
+ [prop setProperty:propertyPrefix value:@"test:default -p 12010"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([[[b1 ice_getIdentity] name] isEqualToString:@"test"] && [[[b1 ice_getIdentity] category] length] == 0 &&
+ [[b1 ice_getAdapterId] length] == 0 && [[b1 ice_getFacet] length] == 0);
+
+ NSString* property;
+
+ property = [propertyPrefix stringByAppendingString:@".Locator"];
+ test(![b1 ice_getLocator]);
+ [prop setProperty:property value:@"locator:default -p 10000"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([b1 ice_getLocator] && [[[[b1 ice_getLocator] ice_getIdentity] name] isEqualToString:@"locator"]);
+ [prop setProperty:property value:@""];
+
+ property = [propertyPrefix stringByAppendingString:@".LocatorCacheTimeout"];
+ test([b1 ice_getLocatorCacheTimeout] == -1);
+ [prop setProperty:property value:@"1"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([b1 ice_getLocatorCacheTimeout] == 1);
+ [prop setProperty:property value:@""];
+
+ // Now retest with an indirect proxy.
+ [prop setProperty:propertyPrefix value:@"test"];
+ property = [propertyPrefix stringByAppendingString:@".Locator"];
+ [prop setProperty:property value:@"locator:default -p 10000"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([b1 ice_getLocator] && [[[[b1 ice_getLocator] ice_getIdentity] name] isEqualToString:@"locator"]);
+ [prop setProperty:property value:@""];
+
+ property = [propertyPrefix stringByAppendingString:@".LocatorCacheTimeout"];
+ test([b1 ice_getLocatorCacheTimeout] == -1);
+ [prop setProperty:property value:@"1"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([b1 ice_getLocatorCacheTimeout] == 1);
+ [prop setProperty:property value:@""];
+
+ // This cannot be tested so easily because the property is cached
+ // on communicator initialization.
+ //
+ //prop->setProperty:"Ice.Default.LocatorCacheTimeout" :@"60");
+ //b1 = [communicator propertyToProxy:propertyPrefix];
+ //test([b1 ice_getLocatorCacheTimeout] == 60);
+ //prop->setProperty("Ice.Default.LocatorCacheTimeout" :@"");
+
+ [prop setProperty:propertyPrefix value:@"test:default -p 12010"];
+
+ property = [propertyPrefix stringByAppendingString:@".Router"];
+ test(![b1 ice_getRouter]);
+ [prop setProperty:property value:@"router:default -p 10000"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([b1 ice_getRouter] && [[[[b1 ice_getRouter] ice_getIdentity] name] isEqualToString:@"router"]);
+ [prop setProperty:property value:@""];
+
+ property = [propertyPrefix stringByAppendingString:@".PreferSecure"];
+ test(![b1 ice_isPreferSecure]);
+ [prop setProperty:property value:@"1"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([b1 ice_isPreferSecure]);
+ [prop setProperty:property value:@""];
+
+ property = [propertyPrefix stringByAppendingString:@".ConnectionCached"];
+ test([b1 ice_isConnectionCached]);
+ [prop setProperty:property value:@"0"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test(![b1 ice_isConnectionCached]);
+ [prop setProperty:property value:@""];
+
+ property = [propertyPrefix stringByAppendingString:@".EndpointSelection"];
+ test([b1 ice_getEndpointSelection] == ICERandom);
+ [prop setProperty:property value:@"Random"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([b1 ice_getEndpointSelection] == ICERandom);
+ [prop setProperty:property value:@"Ordered"];
+ b1 = [communicator propertyToProxy:propertyPrefix];
+ test([b1 ice_getEndpointSelection] == ICEOrdered);
+ [prop setProperty:property value:@""];
+
+// property = [propertyPrefix stringByAppendingString:@".CollocationOptimized"];
+// test([b1 ice_isCollocationOptimized]);
+// [prop setProperty:property value:@"0"];
+// b1 = [communicator propertyToProxy:propertyPrefix];
+// test(![b1 ice_isCollocationOptimized]);
+// [prop setProperty:property value:@""];
+
+ tprintf("ok\n");
+
+ tprintf("testing proxyToProperty... ");
+
+ b1 = [communicator stringToProxy:@"test"];
+ //b1 = [b1 ice_collocationOptimized:YES];
+ b1 = [b1 ice_connectionCached:YES];
+ b1 = [b1 ice_preferSecure:false];
+ b1 = [b1 ice_endpointSelection:ICEOrdered];
+ b1 = [b1 ice_locatorCacheTimeout:100];
+ ICEEncodingVersion* v = [ICEEncodingVersion encodingVersion:1 minor:0];
+ b1 = [b1 ice_encodingVersion:v];
+ id<ICEObjectPrx> router = [communicator stringToProxy:@"router"];
+ //router = [router ice_collocationOptimized:false];
+ router = [router ice_connectionCached:YES];
+ router = [router ice_preferSecure:YES];
+ router = [router ice_endpointSelection:ICERandom];
+ router = [router ice_locatorCacheTimeout:200];
+
+ id<ICEObjectPrx> locator = [communicator stringToProxy:@"locator"];
+ //locator = [locator ice_collocationOptimized:YES];
+ locator = [locator ice_connectionCached:false];
+ locator = [locator ice_preferSecure:YES];
+ locator = [locator ice_endpointSelection:ICERandom];
+ locator = [locator ice_locatorCacheTimeout:300];
+
+ locator = [locator ice_router:[ICERouterPrx uncheckedCast:router]];
+ b1 = [b1 ice_locator:[ICELocatorPrx uncheckedCast:locator]];
+
+ ICEMutablePropertyDict* proxyProps = [communicator proxyToProperty:b1 property:@"Test"];
+ test([proxyProps count] == 21);
+
+ test([[proxyProps objectForKey:@"Test"] isEqualToString:@"test -t -e 1.0"]);
+ //test([[proxyProps[ objectForKey:@"Test.CollocationOptimized"] isEqualToString:@"1"]);
+ test([[proxyProps objectForKey:@"Test.ConnectionCached"] isEqualToString:@"1"]);
+ test([[proxyProps objectForKey:@"Test.PreferSecure"] isEqualToString:@"0"]);
+ test([[proxyProps objectForKey:@"Test.EndpointSelection"] isEqualToString:@"Ordered"]);
+ test([[proxyProps objectForKey:@"Test.LocatorCacheTimeout"] isEqualToString:@"100"]);
+
+ NSString* sl = [NSString stringWithFormat:@"locator -t -e %@", [ICECurrentEncoding description]];
+ test([[proxyProps objectForKey:@"Test.Locator"] isEqualToString:sl]);
+ //test([[proxyProps objectForKey:@"Test.Locator.CollocationOptimized"] isEqualToString:@"1"]);
+ test([[proxyProps objectForKey:@"Test.Locator.ConnectionCached"] isEqualToString:@"0"]);
+ test([[proxyProps objectForKey:@"Test.Locator.PreferSecure"] isEqualToString:@"1"]);
+ test([[proxyProps objectForKey:@"Test.Locator.EndpointSelection"] isEqualToString:@"Random"]);
+ test([[proxyProps objectForKey:@"Test.Locator.LocatorCacheTimeout"] isEqualToString:@"300"]);
+
+ NSString* sr = [NSString stringWithFormat:@"router -t -e %@", [ICECurrentEncoding description]];
+ test([[proxyProps objectForKey:@"Test.Locator.Router"] isEqualToString:sr]);
+ //test([proxyProps objectForKey:@"Test.Locator.Router.CollocationOptimized"] isEqualToString:@"0"]);
+ test([[proxyProps objectForKey:@"Test.Locator.Router.ConnectionCached"] isEqualToString:@"1"]);
+ test([[proxyProps objectForKey:@"Test.Locator.Router.PreferSecure"] isEqualToString:@"1"]);
+ test([[proxyProps objectForKey:@"Test.Locator.Router.EndpointSelection"] isEqualToString:@"Random"]);
+ test([[proxyProps objectForKey:@"Test.Locator.Router.LocatorCacheTimeout"] isEqualToString:@"200"]);
+
+ tprintf("ok\n");
+
+ tprintf("testing ice_getCommunicator... ");
+ test([base ice_getCommunicator] == communicator);
+ tprintf("ok\n");
+
+ tprintf("testing proxy methods... ");
+ test([[communicator identityToString:[[base ice_identity:[communicator stringToIdentity:@"other"]] ice_getIdentity]]
+ isEqualToString:@"other"]);
+ test([[[base ice_facet:@"facet"] ice_getFacet] isEqualToString:@"facet"]);
+ test([[[base ice_adapterId:@"id"] ice_getAdapterId] isEqualToString:@"id"]);
+ test([[base ice_twoway] ice_isTwoway]);
+ test([[base ice_oneway] ice_isOneway]);
+ test([[base ice_batchOneway] ice_isBatchOneway]);
+ test([[base ice_datagram] ice_isDatagram]);
+ test([[base ice_batchDatagram] ice_isBatchDatagram]);
+ test([[base ice_secure:YES] ice_isSecure]);
+ test(![[base ice_secure:NO] ice_isSecure]);
+// test([[base ice_collocationOptimized:YES] ice_isCollocationOptimized]);
+// test(![[base ice_collocationOptimized:NO] ice_isCollocationOptimized]);
+ test([[base ice_preferSecure:YES] ice_isPreferSecure]);
+ test(![[base ice_preferSecure:NO] ice_isPreferSecure]);
+
+ test([[[base ice_encodingVersion:ICEEncoding_1_0] ice_getEncodingVersion] isEqual:ICEEncoding_1_0]);
+ test([[[base ice_encodingVersion:ICEEncoding_1_1] ice_getEncodingVersion] isEqual:ICEEncoding_1_1]);
+ test(![[[base ice_encodingVersion:ICEEncoding_1_0] ice_getEncodingVersion] isEqual:ICEEncoding_1_1]);
+
+ tprintf("ok\n");
+
+ tprintf("testing proxy comparison... ");
+
+ test([[communicator stringToProxy:@"foo"] isEqual:[communicator stringToProxy:@"foo"]]);
+ test(![[communicator stringToProxy:@"foo"] isEqual:[communicator stringToProxy:@"foo2"]]);
+// test([communicator stringToProxy:@"foo"]] < [communicator stringToProxy:@"foo2"]);
+// test(!([communicator stringToProxy:@"foo2"]] < [communicator stringToProxy:@"foo"]);
+
+ id<ICEObjectPrx> compObj = [communicator stringToProxy:@"foo"];
+
+ test([[compObj ice_facet:@"facet"] isEqual:[compObj ice_facet:@"facet"]]);
+ test(![[compObj ice_facet:@"facet"] isEqual:[compObj ice_facet:@"facet1"]]);
+// test([compObj ice_facet:@"facet"] < [compObj ice_facet:"facet1"]);
+// test(!([compObj ice_facet:@"facet"] < [compObj ice_facet:"facet"]));
+
+ test([[compObj ice_oneway] isEqual:[compObj ice_oneway]]);
+ test(![[compObj ice_oneway] isEqual:[compObj ice_twoway]]);
+// test([compObj ice_twoway] < [compObj ice_oneway]);
+// test(!([compObj ice_oneway] < [compObj ice_twoway]));
+
+ test([[compObj ice_secure:YES] isEqual:[compObj ice_secure:YES]]);
+ test(![[compObj ice_secure:NO] isEqual:[compObj ice_secure:YES]]);
+// test([compObj ice_secure:NO] < [compObj ice_secure:YES]);
+// test(!([compObj ice_secure:YES] < [compObj ice_secure:NO]));
+
+// test([[compObj ice_collocationOptimized:YES] isEqual:[compObj ice_collocationOptimized:YES]]);
+// test(![[compObj ice_collocationOptimized:NO] isEqual:[compObj ice_collocationOptimized:YES]]);
+// test([compObj ice_collocationOptimized:NO] < [compObj ice_collocationOptimized:YES]);
+// test(!([compObj ice_collocationOptimized:YES] < [compObj ice_collocationOptimized:NO]));
+
+ test([[compObj ice_connectionCached:YES] isEqual:[compObj ice_connectionCached:YES]]);
+ test(![[compObj ice_connectionCached:NO] isEqual:[compObj ice_connectionCached:YES]]);
+// test([compObj ice_connectionCached:NO] < [compObj ice_connectionCached:YES]);
+// test(!([compObj ice_connectionCached:YES] < [compObj ice_connectionCached:NO]));
+
+ test([[compObj ice_endpointSelection:ICERandom] isEqual:[compObj ice_endpointSelection:ICERandom]]);
+ test(![[compObj ice_endpointSelection:ICERandom] isEqual:[compObj ice_endpointSelection:ICEOrdered]]);
+// test([compObj ice_endpointSelection:ICERandom] < [compObj ice_endpointSelection:ICEOrdered]);
+// test(!([compObj ice_endpointSelection:ICEOrdered] < [compObj ice_endpointSelection:ICERandom]));
+
+// test([[compObj ice_connectionId:@"id2"] isEqual:[compObj ice_connectionId:@"id2"]]);
+// test(![[compObj ice_connectionId:@"id1"] isEqual:[compObj ice_connectionId:@"id2"]]);
+// test([compObj ice_connectionId:@"id1"] < [compObj ice_connectionId:"id2"]);
+// test(!([compObj ice_connectionId:@"id2"] < [compObj ice_connectionId:"id1"]));
+
+ test([[compObj ice_compress:YES] isEqual:[compObj ice_compress:YES]]);
+ test(![[compObj ice_compress:NO] isEqual:[compObj ice_compress:YES]]);
+// test([compObj ice_compress:NO] < [compObj ice_compress:YES]);
+// test(!([compObj ice_compress:YES] < [compObj ice_compress:NO]));
+
+ test([[compObj ice_timeout:20] isEqual:[compObj ice_timeout:20]]);
+ test(![[compObj ice_timeout:10] isEqual:[compObj ice_timeout:20]]);
+// test([compObj ice_timeout:10] < [compObj ice_timeout:20]);
+// test(!([compObj ice_timeout:20] < [compObj ice_timeout:10]));
+
+ id<ICELocatorPrx> loc1 = [ICELocatorPrx uncheckedCast:[communicator stringToProxy:@"loc1:default -p 10000"]];
+ id<ICELocatorPrx> loc2 = [ICELocatorPrx uncheckedCast:[communicator stringToProxy:@"loc2:default -p 10000"]];
+ test([[compObj ice_locator:0] isEqual:[compObj ice_locator:0]]);
+ test([[compObj ice_locator:loc1] isEqual:[compObj ice_locator:loc1]]);
+ test(![[compObj ice_locator:loc1] isEqual:[compObj ice_locator:0]]);
+ test(![[compObj ice_locator:0] isEqual:[compObj ice_locator:loc2]]);
+ test(![[compObj ice_locator:loc1] isEqual:[compObj ice_locator:loc2]]);
+// test([compObj ice_locator:0] < [compObj ice_locator:loc1]);
+// test(!([compObj ice_locator:loc1] < [compObj ice_locator:0]));
+// test([compObj ice_locator:loc1] < [compObj ice_locator:loc2]);
+// test(!([compObj ice_locator:loc2] < [compObj ice_locator:loc1]));
+
+ id<ICERouterPrx> rtr1 = [ICERouterPrx uncheckedCast:[communicator stringToProxy:@"rtr1:default -p 10000"]];
+ id<ICERouterPrx> rtr2 = [ICERouterPrx uncheckedCast:[communicator stringToProxy:@"rtr2:default -p 10000"]];
+ test([[compObj ice_router:0] isEqual:[compObj ice_router:0]]);
+ test([[compObj ice_router:rtr1] isEqual:[compObj ice_router:rtr1]]);
+ test(![[compObj ice_router:rtr1] isEqual:[compObj ice_router:0]]);
+ test(![[compObj ice_router:0] isEqual:[compObj ice_router:rtr2]]);
+ test(![[compObj ice_router:rtr1] isEqual:[compObj ice_router:rtr2]]);
+// test([compObj ice_router:0] < [compObj ice_router:rtr1]);
+// test(!([compObj ice_router:rtr1] < [compObj ice_router:0]));
+// test([compObj ice_router:rtr1] < [compObj ice_router:rtr2]);
+// test(!([compObj ice_router:rtr2] < [compObj ice_router:rtr1]));
+
+ ICEMutableContext* ctx1 = [ICEMutableContext dictionary];
+ [ctx1 setObject:@"v1" forKey:@"ctx1"];
+ ICEMutableContext* ctx2 = [ICEMutableContext dictionary];
+ [ctx2 setObject:@"v2" forKey:@"ctx2"];
+ test([[compObj ice_context:nil] isEqual:[compObj ice_context:nil]]);
+ test([[compObj ice_context:ctx1] isEqual:[compObj ice_context:ctx1]]);
+ test(![[compObj ice_context:ctx1] isEqual:[compObj ice_context:nil]]);
+ test(![[compObj ice_context:nil] isEqual:[compObj ice_context:ctx2]]);
+ test(![[compObj ice_context:ctx1] isEqual:[compObj ice_context:ctx2]]);
+// test([compObj ice_context:ctx1] < [compObj ice_context:ctx2]);
+// test(!([compObj ice_context:ctx2] < [compObj ice_context:ctx1]));
+
+ test([[compObj ice_preferSecure:YES] isEqual:[compObj ice_preferSecure:YES]]);
+ test(![[compObj ice_preferSecure:YES] isEqual:[compObj ice_preferSecure:NO]]);
+// test([compObj ice_preferSecure:NO] < [compObj ice_preferSecure:YES]);
+// test(!([compObj ice_preferSecure:YES] < [compObj ice_preferSecure:NO]));
+
+ id<ICEObjectPrx> compObj1 = [communicator stringToProxy:@"foo:tcp -h 127.0.0.1 -p 10000"];
+ id<ICEObjectPrx> compObj2 = [communicator stringToProxy:@"foo:tcp -h 127.0.0.1 -p 10001"];
+ test(![compObj isEqual:compObj2]);
+// test(compObj1 < compObj2);
+// test(!(compObj2 < compObj1));
+
+ compObj1 = [communicator stringToProxy:@"foo@MyAdapter1"];
+ compObj2 = [communicator stringToProxy:@"foo@MyAdapter2"];
+ test(![compObj isEqual:compObj2]);
+// test(compObj1 < compObj2);
+// test(!(compObj2 < compObj1));
+
+ test([[compObj1 ice_locatorCacheTimeout:20] isEqual:[compObj1 ice_locatorCacheTimeout:20]]);
+ test(![[compObj1 ice_locatorCacheTimeout:10] isEqual:[compObj1 ice_locatorCacheTimeout:20]]);
+// test([compObj1 ice_locatorCacheTimeout:10] < [compObj1 ice_locatorCacheTimeout:20]);
+// test(!([compObj1 ice_locatorCacheTimeout:20] < [compObj1 ice_locatorCacheTimeout:10]));
+
+ compObj1 = [communicator stringToProxy:@"foo:tcp -h 127.0.0.1 -p 1000"];
+ compObj2 = [communicator stringToProxy:@"foo@MyAdapter1"];
+ test(![compObj isEqual:compObj2]);
+// test(compObj1 < compObj2);
+// test(!(compObj2 < compObj1));
+
+ test([[compObj1 ice_encodingVersion:ICEEncoding_1_0] isEqual:[compObj1 ice_encodingVersion:ICEEncoding_1_0]]);
+ test(![[compObj1 ice_encodingVersion:ICEEncoding_1_0] isEqual:[compObj1 ice_encodingVersion:ICEEncoding_1_1]]);
+
+// test(compObj ice_encodingVersion:Ice::Encoding_1_0] < compObj->ice_encodingVersion(Ice::Encoding_1_1));
+// test(!(compObj->ice_encodingVersion(Ice::Encoding_1_1) < compObj->ice_encodingVersion(Ice::Encoding_1_0)));
+ //
+ // TODO: Ideally we should also test comparison of fixed proxies.
+ //
+
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestProxyMyClassPrx> cl = [TestProxyMyClassPrx checkedCast:base];
+ test(cl);
+
+ id<TestProxyMyDerivedClassPrx> derived = [TestProxyMyDerivedClassPrx checkedCast:cl];
+ test(derived);
+ test([cl isEqual:base]);
+ test([derived isEqual:base]);
+ test([cl isEqual:derived]);
+
+ id<ICELocatorPrx> loc = [ICELocatorPrx checkedCast:base];
+ test(loc == nil);
+
+ //
+ // Upcasting
+ //
+ id<TestProxyMyClassPrx> cl2 = [TestProxyMyClassPrx checkedCast:derived];
+ id<ICEObjectPrx> obj = [ICEObjectPrx checkedCast:derived];
+ test(cl2);
+ test(obj);
+ test([cl2 isEqual:obj]);
+ test([cl2 isEqual:derived]);
+
+ tprintf("ok\n");
+
+ tprintf("testing checked cast with context... ");
+ ICEMutableContext* c = [cl getContext];
+ test([c count] == 0);
+
+ [c setObject:@"hello" forKey:@"one"];
+ [c setObject:@"world" forKey:@"two"];
+ cl = [TestProxyMyClassPrx checkedCast:base context:c];
+ ICEContext* c2 = [cl getContext];
+ test([c isEqual:c2]);
+
+ tprintf("ok\n");
+
+ tprintf("testing encoding versioning... ");
+ TestProxyMyClassPrx* cl20 = [TestProxyMyClassPrx uncheckedCast:
+ [communicator stringToProxy:@"test -e 2.0:default -p 12010"]];
+ @try
+ {
+ [cl20 ice_ping];
+ test(NO);
+ }
+ @catch(ICEUnsupportedEncodingException*)
+ {
+ // Server 2.0 endpoint doesn't support 1.1 version.
+ }
+
+ TestProxyMyClassPrx* cl10 = [TestProxyMyClassPrx uncheckedCast:
+ [communicator stringToProxy:@"test -e 1.0:default -p 12010"]];
+ [cl10 ice_ping];
+ [[cl10 ice_encodingVersion:ICEEncoding_1_0] ice_ping];
+ //cl->ice_collocationOptimized(false)->ice_encodingVersion(Ice::Encoding_1_0)->ice_ping();
+
+ // 1.3 isn't supported but since a 1.3 proxy supports 1.1, the
+ // call will use the 1.1 encoding
+ TestProxyMyClassPrx* cl13 = [TestProxyMyClassPrx uncheckedCast:
+ [communicator stringToProxy:@"test -e 1.3:default -p 12010"]];
+ [cl13 ice_ping];
+ [cl13 end_ice_ping:[cl13 begin_ice_ping]];
+
+ @try
+ {
+ // Send request with bogus 1.2 encoding.
+ ICEEncodingVersion* version = [ICEEncodingVersion encodingVersion:1 minor:2];
+ id<ICEOutputStream> out = [ICEUtil createOutputStream:communicator];
+ [out startEncapsulation];
+ [out endEncapsulation];
+ NSMutableData* inEncaps = [out finished];
+ ((ICEByte*)[inEncaps mutableBytes])[4] = version.major;
+ ((ICEByte*)[inEncaps mutableBytes])[5] = version.minor;
+ NSMutableData* outEncaps;
+ [cl ice_invoke:@"ice_ping" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ test(NO);
+ }
+ @catch(ICEUnknownLocalException* ex)
+ {
+ // The server threw an UnsupportedEncodingException
+ test([ex.unknown rangeOfString:@"UnsupportedEncodingException"].location != NSNotFound);
+ }
+
+ @try
+ {
+ // Send request with bogus 2.0 encoding.
+ ICEEncodingVersion* version = [ICEEncodingVersion encodingVersion:2 minor:0];
+ id<ICEOutputStream> out = [ICEUtil createOutputStream:communicator];
+ [out startEncapsulation];
+ [out endEncapsulation];
+ NSMutableData* inEncaps = [out finished];
+ ((ICEByte*)[inEncaps mutableBytes])[4] = version.major;
+ ((ICEByte*)[inEncaps mutableBytes])[5] = version.minor;
+ NSMutableData* outEncaps;
+ [cl ice_invoke:@"ice_ping" mode:ICENormal inEncaps:inEncaps outEncaps:&outEncaps];
+ test(NO);
+ }
+ @catch(ICEUnknownLocalException* ex)
+ {
+ // The server thrown an UnsupportedEncodingException
+ test([ex.unknown rangeOfString:@"UnsupportedEncodingException"].location != NSNotFound);
+ }
+
+ tprintf("ok\n");
+
+ tprintf("testing protocol versioning... ");
+
+ cl20 = [TestProxyMyClassPrx uncheckedCast:[communicator stringToProxy:@"test -p 2.0:default -p 12010"]];
+ @try
+ {
+ [cl20 ice_ping];
+ test(NO);
+ }
+ @catch(ICEUnsupportedProtocolException*)
+ {
+ // Server 2.0 proxy doesn't support 1.0 version.
+ }
+
+ cl10 = [TestProxyMyClassPrx uncheckedCast:[communicator stringToProxy:@"test -p 1.0:default -p 12010"]];
+ [cl10 ice_ping];
+
+ // 1.3 isn't supported but since a 1.3 proxy supports 1.0, the
+ // call will use the 1.0 encoding
+ cl13 = [TestProxyMyClassPrx uncheckedCast:[communicator stringToProxy:@"test -p 1.3:default -p 12010"]];
+ [cl13 ice_ping];
+ [cl13 end_ice_ping:[cl13 begin_ice_ping]];
+
+ tprintf("ok\n");
+
+ tprintf("testing opaque endpoints... ");
+
+ @try
+ {
+ // Invalid -x option
+ [communicator stringToProxy:@"id:opaque -t 99 -v abc -x abc"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Missing -t and -v
+ [communicator stringToProxy:@"id:opaque"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Repeated -t
+ [communicator stringToProxy:@"id:opaque -t 1 -t 1 -v abc"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Repeated -v
+ [communicator stringToProxy:@"id:opaque -t 1 -v abc -v abc"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Missing -t
+ [communicator stringToProxy:@"id:opaque -v abc"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Missing -v
+ [communicator stringToProxy:@"id:opaque -t 1"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Missing arg for -t
+ [communicator stringToProxy:@"id:opaque -t -v abc"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Missing arg for -v
+ [communicator stringToProxy:@"id:opaque -t 1 -v"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Not a number for -t
+ [communicator stringToProxy:@"id:opaque -t x -v abc"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // < 0 for -t
+ [communicator stringToProxy:@"id:opaque -t -1 -v abc"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ @try
+ {
+ // Invalid char for -v
+ [communicator stringToProxy:@"id:opaque -t 99 -v x?c"];
+ test(NO);
+ }
+ @catch(ICEEndpointParseException*)
+ {
+ }
+
+ // Legal TCP endpoint expressed as opaque endpoint
+ id<ICEObjectPrx> p1 = [communicator stringToProxy:@"test -e 1.1:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA=="];
+ NSString* pstr = [communicator proxyToString:p1];
+ test([pstr isEqualToString:@"test -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 10000"]);
+
+ if([[communicator getProperties] getPropertyAsInt:@"Ice.IPv6"] == 0)
+ {
+ // Working?
+ BOOL ssl = [[[communicator getProperties] getProperty:@"Ice.Default.Protocol"] isEqualToString:@"ssl"];
+ if(!ssl)
+ {
+ [p1 ice_ping];
+ }
+
+ // Two legal TCP endpoints expressed as opaque endpoints
+ p1 = [communicator stringToProxy:@"test -e 1.0:opaque -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==:opaque -e 1.0 -t 1 -v CTEyNy4wLjAuMusuAAAQJwAAAA=="];
+ pstr = [communicator proxyToString:p1];
+ test([pstr isEqualToString:@"test -t -e 1.0:tcp -h 127.0.0.1 -p 12010 -t 10000:tcp -h 127.0.0.2 -p 12011 -t 10000"]);
+
+#if 0 // SSL is always enabled
+ //
+ // TestProxy that an SSL endpoint and a nonsense endpoint get written
+ // back out as an opaque endpoint.
+ //
+ p1 = [communicator stringToProxy:@"test:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch"];
+ pstr = [communicator proxyToString:p1];
+ if(!ssl)
+ {
+ test([pstr isEqualToString:@"test -t:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch"]);
+ }
+ else
+ {
+ test([pstr isEqualToString:@"test -t:ssl -h 127.0.0.1 -p 10001:opaque -t 99 -v abch"]);
+ }
+
+ //
+ // Try to invoke on the SSL endpoint to verify that we get a
+ // NoEndpointException (or ConnectionRefusedException when
+ // running with SSL).
+ //
+ @try
+ {
+ [p1 ice_ping];
+ test(NO);
+ }
+ @catch(ICENoEndpointException*)
+ {
+ test(!ssl);
+ }
+ @catch(ICEConnectionRefusedException*)
+ {
+ test(ssl);
+ }
+
+ //
+ // TestProxy that the proxy with an SSL endpoint and a nonsense
+ // endpoint (which the server doesn't understand either) can be
+ // sent over the wire and returned by the server without losing
+ // the opaque endpoints.
+ //
+ id<ICEObjectPrx> p2 = [derived echo:p1];
+ pstr = [communicator proxyToString:p2];
+ if(!ssl)
+ {
+ test([pstr isEqualToString:@"test -t:opaque -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -v abch"]);
+ }
+ else
+ {
+ test([pstr isEqualToString:@"test -t:ssl -h 127.0.0.1 -p 10001:opaque -t 99 -v abch"]);
+ }
+#endif
+ }
+
+ tprintf("ok\n");
+
+ return cl;
+}
diff --git a/objc/test/Ice/proxy/Client.m b/objc/test/Ice/proxy/Client.m
new file mode 100644
index 00000000000..a1854dc6bdb
--- /dev/null
+++ b/objc/test/Ice/proxy/Client.m
@@ -0,0 +1,79 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <ProxyTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ TestProxyMyClassPrx* proxyAllTests(id<ICECommunicator>);
+ TestProxyMyClassPrx* myClass = proxyAllTests(communicator);
+
+ [myClass shutdown];
+
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main proxyClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestProxy", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/proxy/Makefile b/objc/test/Ice/proxy/Makefile
new file mode 100644
index 00000000000..86fab9f027d
--- /dev/null
+++ b/objc/test/Ice/proxy/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = ProxyTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/proxy/ProxyTest.ice b/objc/test/Ice/proxy/ProxyTest.ice
new file mode 100644
index 00000000000..5a915876920
--- /dev/null
+++ b/objc/test/Ice/proxy/ProxyTest.ice
@@ -0,0 +1,30 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/Current.ice>
+
+["objc:prefix:TestProxy"]
+module Test
+{
+
+class MyClass
+{
+ void shutdown();
+
+ Ice::Context getContext();
+};
+
+class MyDerivedClass extends MyClass
+{
+ Object* echo(Object* obj);
+};
+
+};
diff --git a/objc/test/Ice/proxy/Server.m b/objc/test/Ice/proxy/Server.m
new file mode 100644
index 00000000000..cc2fd0fb1ee
--- /dev/null
+++ b/objc/test/Ice/proxy/Server.m
@@ -0,0 +1,84 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <proxy/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [adapter add:[[[TestProxyMyDerivedClassI alloc] init] autorelease]
+ identity:[communicator stringToIdentity:@"test"]];
+#else
+ [adapter add:[[TestProxyMyDerivedClassI alloc] init] identity:[communicator stringToIdentity:@"test"]];
+#endif
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main proxyServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+ [initData.properties setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestProxy", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/proxy/TestI.h b/objc/test/Ice/proxy/TestI.h
new file mode 100644
index 00000000000..02b6cbcea1b
--- /dev/null
+++ b/objc/test/Ice/proxy/TestI.h
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <ProxyTest.h>
+
+@interface TestProxyMyDerivedClassI : TestProxyMyDerivedClass<TestProxyMyDerivedClass>
+{
+@private
+ ICEContext *_ctx;
+}
+-(id<ICEObjectPrx>) echo:(id<ICEObjectPrx>)proxy current:(ICECurrent*)current;
+-(void) shutdown:(ICECurrent*)current;
+-(ICEContext*) getContext:(ICECurrent*)current;
+-(BOOL) ice_isA:(NSString*)typeId current:(ICECurrent*)current;
+@end
diff --git a/objc/test/Ice/proxy/TestI.m b/objc/test/Ice/proxy/TestI.m
new file mode 100644
index 00000000000..0ed9e270219
--- /dev/null
+++ b/objc/test/Ice/proxy/TestI.m
@@ -0,0 +1,53 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <proxy/TestI.h>
+#import <TestCommon.h>
+
+@implementation TestProxyMyDerivedClassI
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [_ctx release];
+ [super dealloc];
+}
+#endif
+
+-(id<ICEObjectPrx>) echo:(id<ICEObjectPrx>)obj current:(ICECurrent*)current
+{
+ return obj;
+}
+
+-(void) shutdown:(ICECurrent*)c
+{
+ [[[c adapter] getCommunicator] shutdown];
+}
+
+-(ICEContext*) getContext:(ICECurrent*)c
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[_ctx retain] autorelease];
+#else
+ return _ctx;
+#endif
+}
+
+-(BOOL) ice_isA:(NSString*)s current:(ICECurrent*)current
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [_ctx release];
+ _ctx = [[current ctx] retain];
+#else
+ _ctx = [current ctx];
+#endif
+ return [super ice_isA:s current:current];
+}
+
+@end
diff --git a/objc/test/Ice/proxy/run.py b/objc/test/Ice/proxy/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/proxy/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/retry/.gitignore b/objc/test/Ice/retry/.gitignore
new file mode 100644
index 00000000000..c69a35a62bd
--- /dev/null
+++ b/objc/test/Ice/retry/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+RetryTest.m
+RetryTest.h
diff --git a/objc/test/Ice/retry/AllTests.m b/objc/test/Ice/retry/AllTests.m
new file mode 100644
index 00000000000..3b47e02f7cd
--- /dev/null
+++ b/objc/test/Ice/retry/AllTests.m
@@ -0,0 +1,147 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <RetryTest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface TestRetryCallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+}
+-(void) check;
+-(void) called;
+@end
+
+@implementation TestRetryCallback
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) check
+{
+ [cond lock];
+ while(!called)
+ {
+ [cond wait];
+ }
+ called = NO;
+ [cond unlock];
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) retryOpResponse
+{
+ [self called];
+}
+-(void) retryOpException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) killRetryOpResponse
+{
+ test(NO);
+}
+
+-(void) killRetryOpException:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICEConnectionLostException class]]);
+ [self called];
+};
+@end
+
+id<TestRetryRetryPrx>
+retryAllTests(id<ICECommunicator> communicator)
+{
+ tprintf("testing stringToProxy... ");
+ NSString* ref = @"retry:default -p 12010";
+ id<ICEObjectPrx> base1 = [communicator stringToProxy:ref];
+ test(base1);
+ id<ICEObjectPrx> base2 = [communicator stringToProxy:ref];
+ test(base2);
+ tprintf("ok\n");
+
+ tprintf("testing checked cast... ");
+ id<TestRetryRetryPrx> retry1 = [TestRetryRetryPrx checkedCast:base1];
+ test(retry1);
+ test([retry1 isEqual:base1]);
+ id<TestRetryRetryPrx> retry2 = [TestRetryRetryPrx checkedCast:base2];
+ test(retry2);
+ test([retry2 isEqual:base2]);
+ tprintf("ok\n");
+
+ tprintf("calling regular operation with first proxy... ");
+ [retry1 op:NO];
+ tprintf("ok\n");
+
+ tprintf("calling operation to kill connection with second proxy... ");
+ @try
+ {
+ [retry2 op:YES];
+ test(NO);
+ }
+ @catch(ICEConnectionLostException*)
+ {
+ tprintf("ok\n");
+ }
+
+ tprintf("calling regular operation with first proxy again... ");
+ [retry1 op:NO];
+ tprintf("ok\n");
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+ TestRetryCallback* cb1 = [[[TestRetryCallback alloc] init] autorelease];
+ TestRetryCallback* cb2 = [[[TestRetryCallback alloc] init] autorelease];
+#else
+ TestRetryCallback* cb1 = [[TestRetryCallback alloc] init];
+ TestRetryCallback* cb2 = [[TestRetryCallback alloc] init];
+#endif
+ tprintf("calling regular AMI operation with first proxy... ");
+ [retry1 begin_op:NO response:^{ [cb1 retryOpResponse]; }
+ exception:^(ICEException* ex) { [cb1 retryOpException:ex]; }];
+ [cb1 check];
+ tprintf("ok\n");
+
+ tprintf("calling AMI operation to kill connection with second proxy... ");
+ [retry2 begin_op:YES response:^{ [cb2 killRetryOpResponse]; }
+ exception:^(ICEException* ex) { [cb2 killRetryOpException:ex]; }];
+ [cb2 check];
+ tprintf("ok\n");
+
+ tprintf("calling regular AMI operation with first proxy again... ");
+ [retry1 begin_op:NO response:^{ [cb1 retryOpResponse]; }
+ exception:^(ICEException* ex) { [cb1 retryOpException:ex]; }];
+ [cb1 check];
+ tprintf("ok\n");
+
+ return retry1;
+}
diff --git a/objc/test/Ice/retry/Client.m b/objc/test/Ice/retry/Client.m
new file mode 100644
index 00000000000..1f7be1dc7d6
--- /dev/null
+++ b/objc/test/Ice/retry/Client.m
@@ -0,0 +1,89 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <RetryTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ TestRetryRetryPrx* retryAllTests(id<ICECommunicator>);
+ TestRetryRetryPrx* retry = retryAllTests(communicator);
+ [retry shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main retryClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+
+ //
+ // For this test, we want to disable retries.
+ //
+ [initData.properties setProperty:@"Ice.RetryIntervals" value:@"-1"];
+
+ //
+ // This test kills connections, so we don't want warnings.
+ //
+ [initData.properties setProperty:@"Ice.Warn.Connections" value:@"0"];
+
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestRetry", @"::Test",
+ nil];
+#endif
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/retry/Makefile b/objc/test/Ice/retry/Makefile
new file mode 100644
index 00000000000..2f09fea4047
--- /dev/null
+++ b/objc/test/Ice/retry/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = RetryTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/retry/RetryTest.ice b/objc/test/Ice/retry/RetryTest.ice
new file mode 100644
index 00000000000..39cb6c534a8
--- /dev/null
+++ b/objc/test/Ice/retry/RetryTest.ice
@@ -0,0 +1,22 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestRetry"]
+module Test
+{
+
+interface Retry
+{
+ void op(bool kill);
+ void shutdown();
+};
+
+};
diff --git a/objc/test/Ice/retry/Server.m b/objc/test/Ice/retry/Server.m
new file mode 100644
index 00000000000..5b506b36912
--- /dev/null
+++ b/objc/test/Ice/retry/Server.m
@@ -0,0 +1,83 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <retry/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* object = [[[TestRetryRetryI alloc] init] autorelease];
+#else
+ ICEObject* object = [[TestRetryRetryI alloc] init];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"retry"]];
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main retryServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestRetry", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/retry/TestI.h b/objc/test/Ice/retry/TestI.h
new file mode 100644
index 00000000000..fe4cdc61d67
--- /dev/null
+++ b/objc/test/Ice/retry/TestI.h
@@ -0,0 +1,15 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <RetryTest.h>
+
+@interface TestRetryRetryI : TestRetryRetry
+-(void) op:(BOOL)kill current:(ICECurrent *)current;
+-(void) shutdown:(ICECurrent *)current;
+@end
diff --git a/objc/test/Ice/retry/TestI.m b/objc/test/Ice/retry/TestI.m
new file mode 100644
index 00000000000..ab507218653
--- /dev/null
+++ b/objc/test/Ice/retry/TestI.m
@@ -0,0 +1,26 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <retry/TestI.h>
+
+@implementation TestRetryRetryI
+-(void) op:(BOOL)kill current:(ICECurrent*)current
+{
+ if(kill)
+ {
+ [[current con] close:YES];
+ }
+}
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
diff --git a/objc/test/Ice/retry/run.py b/objc/test/Ice/retry/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/retry/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Ice/services/.gitignore b/objc/test/Ice/services/.gitignore
new file mode 100644
index 00000000000..67ac8b78837
--- /dev/null
+++ b/objc/test/Ice/services/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+ServicesTest.m
+ServicesTest.h
diff --git a/objc/test/Ice/services/AllTests.m b/objc/test/Ice/services/AllTests.m
new file mode 100644
index 00000000000..823aa5b8692
--- /dev/null
+++ b/objc/test/Ice/services/AllTests.m
@@ -0,0 +1,116 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <objc/Glacier2.h>
+#import <objc/IceStorm.h>
+#import <objc/IceGrid.h>
+#import <TestCommon.h>
+#import <ServicesTest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface ClockI : TestServicesClock<TestServicesClock>
+-(id) init;
++(id) cloki;
+-(void)tick:(NSString*)time current:(ICECurrent*)current;
+@end
+
+@implementation ClockI
+-(id) init
+{
+ self = [super init];
+ return self;
+}
++(id) cloki
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[[ClockI alloc] init] autorelease];
+#else
+ return [[ClockI alloc] init];
+#endif
+}
+
+-(void)tick:(NSString*)time current:(ICECurrent*)current
+{
+ NSLog(@"%@", time);
+}
+@end
+
+void
+servicesAllTests(id<ICECommunicator> communicator)
+{
+ {
+ tprintf("testing Glacier2 stub... ");
+ @try
+ {
+ id<GLACIER2RouterPrx> router = [GLACIER2RouterPrx checkedCast:[communicator getDefaultRouter]];
+ [router createSession:@"" password:@""];
+ }
+ @catch(ICEException* ex)
+ {
+ test(NO);
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("testing IceStorm stub... ");
+ ICESTORMTopicManagerPrx* manager =
+ [ICESTORMTopicManagerPrx uncheckedCast:[communicator stringToProxy:@"test:default -p 12010"]];
+
+ ICESTORMQoS* qos;
+ ICESTORMTopicPrx* topic;
+ NSString* topicName = @"time";
+
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapterWithEndpoints:@"subscriber" endpoints:@"tcp"];
+ ICEObjectPrx* subscriber = [adapter addWithUUID:[ClockI cloki]];
+ [adapter activate];
+
+ @try
+ {
+ topic = [manager retrieve:topicName];
+ [topic subscribeAndGetPublisher:qos subscriber:subscriber];
+ }
+ @catch(ICESTORMNoSuchTopic*)
+ {
+ test(NO);
+ }
+ @catch(ICESTORMAlreadySubscribed*)
+ {
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ tprintf("ok\n");
+ }
+
+ {
+ tprintf("testing IceGrid stub... ");
+ ICEObjectPrx* base = [communicator stringToProxy:@"test:default -p 12010"];
+ ICEGRIDRegistryPrx* registry = [ICEGRIDRegistryPrx uncheckedCast:base];
+ ICEGRIDAdminSessionPrx* session;
+ ICEGRIDAdminPrx* admin;
+ @try
+ {
+ session = [registry createAdminSession:@"username" password:@"password"];
+ test(NO);
+ admin = [session getAdmin];
+ }
+ @catch(ICEGRIDPermissionDeniedException*)
+ {
+ test(NO);
+ }
+ @catch(ICELocalException*)
+ {
+ }
+ tprintf("ok\n");
+ }
+}
diff --git a/objc/test/Ice/services/Client.m b/objc/test/Ice/services/Client.m
new file mode 100644
index 00000000000..fa46df374ae
--- /dev/null
+++ b/objc/test/Ice/services/Client.m
@@ -0,0 +1,76 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <ServicesTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ void servicesAllTests(id<ICECommunicator>);
+ servicesAllTests(communicator);
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main servicesClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestServices", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/services/Makefile b/objc/test/Ice/services/Makefile
new file mode 100644
index 00000000000..1cf284bceaf
--- /dev/null
+++ b/objc/test/Ice/services/Makefile
@@ -0,0 +1,30 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = ServicesTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+OBJS = $(COBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../../include $(CPPFLAGS)
+LIBS := -lGlacier2ObjC$(libsuffix) -lIceStormObjC$(libsuffix) -lIceGridObjC$(libsuffix) $(TEST_LIBS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/services/ServicesTest.ice b/objc/test/Ice/services/ServicesTest.ice
new file mode 100644
index 00000000000..3fea6f9d73b
--- /dev/null
+++ b/objc/test/Ice/services/ServicesTest.ice
@@ -0,0 +1,21 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestServices"]
+module Test
+{
+
+interface Clock
+{
+ void tick(string time);
+};
+
+};
diff --git a/objc/test/Ice/services/run.py b/objc/test/Ice/services/run.py
new file mode 100755
index 00000000000..ac32c445572
--- /dev/null
+++ b/objc/test/Ice/services/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+client = os.path.join(os.getcwd(), "client")
+TestUtil.simpleTest(client)
+
diff --git a/objc/test/Ice/slicing/Makefile b/objc/test/Ice/slicing/Makefile
new file mode 100644
index 00000000000..b458725f9f6
--- /dev/null
+++ b/objc/test/Ice/slicing/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = exceptions objects
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/test/Ice/slicing/exceptions/.gitignore b/objc/test/Ice/slicing/exceptions/.gitignore
new file mode 100644
index 00000000000..0962671d892
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/.gitignore
@@ -0,0 +1,10 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+SlicingExceptionsTestClient.m
+SlicingExceptionsTestServer.m
+SlicingExceptionsTestClient.h
+SlicingExceptionsTestServer.h
diff --git a/objc/test/Ice/slicing/exceptions/AllTests.m b/objc/test/Ice/slicing/exceptions/AllTests.m
new file mode 100644
index 00000000000..0516781f124
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/AllTests.m
@@ -0,0 +1,826 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <SlicingExceptionsTestClient.h>
+
+#import <Foundation/Foundation.h>
+
+@interface RelayI : TestSlicingExceptionsClientRelay<TestSlicingExceptionsClientRelay>
++(id) relayi;
+@end
+
+@implementation RelayI
+
++(id) relayi
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[[RelayI alloc] init] autorelease];
+#else
+ return [[RelayI alloc] init];
+#endif
+}
+
+-(void) knownPreservedAsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsClientKnownPreservedDerived knownPreservedDerived:@"base"
+ kp:@"preserved"
+ kpd:@"derived"];
+}
+
+-(void) knownPreservedAsKnownPreserved:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsClientKnownPreservedDerived knownPreservedDerived:@"base"
+ kp:@"preserved"
+ kpd:@"derived"];
+}
+
+-(void) unknownPreservedAsBase:(ICECurrent*)current
+{
+ TestSlicingExceptionsClientPreserved2* ex = [TestSlicingExceptionsClientPreserved2 alloc];
+ ex.b = @"base";
+ ex.kp = @"preserved";
+ ex.kpd = @"derived";
+ ex.p1 = [TestSlicingExceptionsClientPreservedClass preservedClass:@"bc" pc:@"pc"];
+ ex.p2 = ex.p1;
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [ex autorelease];
+#endif
+ @throw ex;
+}
+
+-(void) unknownPreservedAsKnownPreserved:(ICECurrent*)current
+{
+ TestSlicingExceptionsClientPreserved2* ex = [TestSlicingExceptionsClientPreserved2 alloc];
+ ex.b = @"base";
+ ex.kp = @"preserved";
+ ex.kpd = @"derived";
+ ex.p1 = [TestSlicingExceptionsClientPreservedClass preservedClass:@"bc" pc:@"pc"];
+ ex.p2 = ex.p1;
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [ex autorelease];
+#endif
+ @throw ex;
+}
+
+@end
+
+@interface TestSlicingExceptionsClientCallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+}
+-(void) check;
+-(void) called;
+@end
+
+@implementation TestSlicingExceptionsClientCallback
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
++(id) create
+{
+#if defined(__clang__) && __has_feature(objc_arc)
+ return [[TestSlicingExceptionsClientCallback alloc] init];
+#else
+ return [[[TestSlicingExceptionsClientCallback alloc] init] autorelease];
+#endif
+}
+
+-(void) check
+{
+ [cond lock];
+ while(!called)
+ {
+ [cond wait];
+ }
+ called = NO;
+ [cond unlock];
+}
+
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+
+-(void) response
+{
+ test(NO);
+}
+
+-(void) baseAsBaseException:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientBase* b)
+ {
+ test([b.b isEqualToString:@"Base.b"]);
+ test([[b ice_name] isEqualToString:@"Test::Base"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+
+-(void) unknownDerivedAsBaseException:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientBase* b)
+ {
+ test([b.b isEqualToString:@"UnknownDerived.b"]);
+ test([[b ice_name] isEqualToString:@"Test::Base"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+
+-(void) knownDerivedException:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientKnownDerived* k)
+ {
+ test([k.b isEqualToString:@"KnownDerived.b"]);
+ test([k.kd isEqualToString:@"KnownDerived.kd"]);
+ test([[k ice_name] isEqualToString:@"Test::KnownDerived"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+
+-(void) unknownIntermediateAsBaseException:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientBase* b)
+ {
+ test([b.b isEqualToString:@"UnknownIntermediate.b"]);
+ test([[b ice_name] isEqualToString:@"Test::Base"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+
+-(void) knownIntermediateAsBaseException:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientKnownIntermediate* ki)
+ {
+ test([ki.b isEqualToString:@"KnownIntermediate.b"]);
+ test([ki.ki isEqualToString:@"KnownIntermediate.ki"]);
+ test([[ki ice_name] isEqualToString:@"Test::KnownIntermediate"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+
+-(void) knownMostDerivedException:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientKnownMostDerived* kmd)
+ {
+ test([kmd.b isEqualToString:@"KnownMostDerived.b"]);
+ test([kmd.ki isEqualToString:@"KnownMostDerived.ki"]);
+ test([kmd.kmd isEqualToString:@"KnownMostDerived.kmd"]);
+ test([[kmd ice_name] isEqualToString:@"Test::KnownMostDerived"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+
+-(void) knownIntermediateAsKnownIntermediateException:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientKnownIntermediate* ki)
+ {
+ test([ki.b isEqualToString:@"KnownIntermediate.b"]);
+ test([ki.ki isEqualToString:@"KnownIntermediate.ki"]);
+ test([[ki ice_name] isEqualToString:@"Test::KnownIntermediate"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+
+-(void) unknownMostDerived1Exception:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientKnownIntermediate* ki)
+ {
+ test([ki.b isEqualToString:@"UnknownMostDerived1.b"]);
+ test([ki.ki isEqualToString:@"UnknownMostDerived1.ki"]);
+ test([[ki ice_name] isEqualToString:@"Test::KnownIntermediate"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+
+-(void) unknownMostDerived2Exception:(ICEException*)exc
+{
+ @try
+ {
+ @throw exc;
+ }
+ @catch(TestSlicingExceptionsClientBase* b)
+ {
+ test([b.b isEqualToString:@"UnknownMostDerived2.b"]);
+ test([[b ice_name] isEqualToString:@"Test::Base"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ [self called];
+}
+@end
+
+id<TestSlicingExceptionsClientTestIntfPrx>
+slicingExceptionsAllTests(id<ICECommunicator> communicator)
+{
+ id<ICEObjectPrx> obj = [communicator stringToProxy:@"Test:default -p 12010"];
+ id<TestSlicingExceptionsClientTestIntfPrx> test = [TestSlicingExceptionsClientTestIntfPrx checkedCast:obj];
+ tprintf("base... ");
+ {
+ @try
+ {
+ [test baseAsBase];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientBase* b)
+ {
+ test([b.b isEqual:@"Base.b"]);
+ test([[b ice_name] isEqualToString:@"Test::Base"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("base (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback *cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_baseAsBase:^ { test(NO); } exception:^(ICEException* e) { [cb baseAsBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown derived... ");
+ {
+ @try
+ {
+ [test unknownDerivedAsBase];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientBase* b)
+ {
+ test([b.b isEqualToString:@"UnknownDerived.b"]);
+ test([[b ice_name] isEqualToString:@"Test::Base"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown derived (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_unknownDerivedAsBase:^ { test(NO); } exception:^(ICEException* e) { [cb unknownDerivedAsBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known derived as base... ");
+ {
+ @try
+ {
+ [test knownDerivedAsBase];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownDerived* k)
+ {
+ test([k.b isEqualToString:@"KnownDerived.b"]);
+ test([k.kd isEqualToString:@"KnownDerived.kd"]);
+ test([[k ice_name] isEqualToString:@"Test::KnownDerived"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known derived as base (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_knownDerivedAsBase:^ { test(NO); } exception:^(ICEException* e) { [cb knownDerivedException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known derived as derived... ");
+ {
+ @try
+ {
+ [test knownDerivedAsKnownDerived];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownDerived* k)
+ {
+ test([k.b isEqualToString:@"KnownDerived.b"]);
+ test([k.kd isEqualToString:@"KnownDerived.kd"]);
+ test([[k ice_name] isEqualToString:@"Test::KnownDerived"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known derived as derived (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_knownDerivedAsKnownDerived:^ { test(NO); } exception:^(ICEException* e) { [cb knownDerivedException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown intermediate as base... ");
+ {
+ @try
+ {
+ [test unknownIntermediateAsBase];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientBase* b)
+ {
+ test([b.b isEqualToString:@"UnknownIntermediate.b"]);
+ test([[b ice_name] isEqualToString:@"Test::Base"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown intermediate as base (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_unknownIntermediateAsBase:^ { test(NO); } exception:^(ICEException* e) { [cb unknownIntermediateAsBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of known intermediate as base... ");
+ {
+ @try
+ {
+ [test knownIntermediateAsBase];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownIntermediate* ki)
+ {
+ test([ki.b isEqualToString:@"KnownIntermediate.b"]);
+ test([ki.ki isEqualToString:@"KnownIntermediate.ki"]);
+ test([[ki ice_name] isEqualToString:@"Test::KnownIntermediate"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of known intermediate as base (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_knownIntermediateAsBase:^ { test(NO); } exception:^(ICEException* e) { [cb knownIntermediateAsBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of known most derived as base... ");
+ {
+ @try
+ {
+ [test knownMostDerivedAsBase];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownMostDerived* kmd)
+ {
+ test([kmd.b isEqualToString:@"KnownMostDerived.b"]);
+ test([kmd.ki isEqualToString:@"KnownMostDerived.ki"]);
+ test([kmd.kmd isEqualToString:@"KnownMostDerived.kmd"]);
+ test([[kmd ice_name] isEqualToString:@"Test::KnownMostDerived"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of known most derived as base (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_knownMostDerivedAsBase:^ { test(NO); } exception:^(ICEException* e) { [cb knownMostDerivedException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known intermediate as intermediate... ");
+ {
+ @try
+ {
+ [test knownIntermediateAsKnownIntermediate];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownIntermediate* ki)
+ {
+ test([ki.b isEqualToString:@"KnownIntermediate.b"]);
+ test([ki.ki isEqualToString:@"KnownIntermediate.ki"]);
+ test([[ki ice_name] isEqualToString:@"Test::KnownIntermediate"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known intermediate as intermediate (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_knownIntermediateAsKnownIntermediate:^ { test(NO); } exception:^(ICEException* e) { [cb knownIntermediateAsKnownIntermediateException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known most derived exception as intermediate... ");
+ {
+ @try
+ {
+ [test knownMostDerivedAsKnownIntermediate];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownMostDerived* kmd)
+ {
+ test([kmd.b isEqualToString:@"KnownMostDerived.b"]);
+ test([kmd.ki isEqualToString:@"KnownMostDerived.ki"]);
+ test([kmd.kmd isEqualToString:@"KnownMostDerived.kmd"]);
+ test([[kmd ice_name] isEqualToString:@"Test::KnownMostDerived"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known most derived as intermediate (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_knownMostDerivedAsKnownIntermediate:^ { test(NO); } exception:^(ICEException* e) { [cb knownMostDerivedException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known most derived as most derived... ");
+ {
+ @try
+ {
+ [test knownMostDerivedAsKnownMostDerived];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownMostDerived* kmd)
+ {
+ test([kmd.b isEqualToString:@"KnownMostDerived.b"]);
+ test([kmd.ki isEqualToString:@"KnownMostDerived.ki"]);
+ test([kmd.kmd isEqualToString:@"KnownMostDerived.kmd"]);
+ test([[kmd ice_name] isEqualToString:@"Test::KnownMostDerived"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("non-slicing of known most derived as most derived (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_knownMostDerivedAsKnownMostDerived:^ { test(NO); } exception:^(ICEException* e) { [cb knownMostDerivedException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown most derived, known intermediate as base... ");
+ {
+ @try
+ {
+ [test unknownMostDerived1AsBase];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownIntermediate* ki)
+ {
+ test([ki.b isEqualToString:@"UnknownMostDerived1.b"]);
+ test([ki.ki isEqualToString:@"UnknownMostDerived1.ki"]);
+ test([[ki ice_name] isEqualToString:@"Test::KnownIntermediate"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown most derived, known intermediate as base (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_unknownMostDerived1AsBase:^ { test(NO); } exception:^(ICEException* e) { [cb unknownMostDerived1Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown most derived, known intermediate as intermediate... ");
+ {
+ @try
+ {
+ [test unknownMostDerived1AsKnownIntermediate];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownIntermediate* ki)
+ {
+ test([ki.b isEqualToString:@"UnknownMostDerived1.b"]);
+ test([ki.ki isEqualToString:@"UnknownMostDerived1.ki"]);
+ test([[ki ice_name] isEqualToString:@"Test::KnownIntermediate"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown most derived, known intermediate as intermediate (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_unknownMostDerived1AsKnownIntermediate:^ { test(NO); } exception:^(ICEException* e) { [cb unknownMostDerived1Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown most derived, unknown intermediate as base... ");
+ {
+ @try
+ {
+ [test unknownMostDerived2AsBase];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientBase* b)
+ {
+ test([b.b isEqualToString:@"UnknownMostDerived2.b"]);
+ test([[b ice_name] isEqualToString:@"Test::Base"]);
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("slicing of unknown most derived, unknown intermediate as base (AMI)... ");
+ {
+ TestSlicingExceptionsClientCallback* cb = [TestSlicingExceptionsClientCallback create];
+ [test begin_unknownMostDerived2AsBase:^ { test(NO); } exception:^(ICEException* e) { [cb unknownMostDerived2Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("unknown most derived in compact format... ");
+ {
+ @try
+ {
+ [test unknownMostDerived2AsBaseCompact];
+ test(false);
+ }
+ @catch(TestSlicingExceptionsClientBase*)
+ {
+ //
+ // For the 1.0 encoding, the unknown exception is sliced to Base.
+ //
+ test([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0]);
+ }
+ @catch(ICEUnknownUserException*)
+ {
+ //
+ // An UnknownUserException is raised for the compact format because the
+ // most-derived type is unknown and the exception cannot be sliced.
+ //
+ test(![[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("preserved exceptions... ");
+ {
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapterWithEndpoints:@"Relay" endpoints:@"default"];
+ TestSlicingExceptionsClientRelayPrx* relay =
+ [TestSlicingExceptionsClientRelayPrx uncheckedCast:[adapter addWithUUID:[RelayI relayi]]];
+ [adapter activate];
+
+ @try
+ {
+ [test relayKnownPreservedAsBase:relay];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownPreservedDerived* ex)
+ {
+ test([ex.b isEqualToString:@"base"]);
+ test([ex.kp isEqualToString:@"preserved"]);
+ test([ex.kpd isEqualToString:@"derived"]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+
+ @try
+ {
+ [test relayKnownPreservedAsKnownPreserved:relay];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientKnownPreservedDerived* ex)
+ {
+ test([ex.b isEqualToString:@"base"]);
+ test([ex.kp isEqualToString:@"preserved"]);
+ test([ex.kpd isEqualToString:@"derived"]);
+ }
+ @catch(const ICEOperationNotExistException*)
+ {
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+
+ @try
+ {
+ [test relayUnknownPreservedAsBase:relay];
+ test(NO);
+ }
+ @catch(TestSlicingExceptionsClientPreserved2* ex)
+ {
+ test([ex.b isEqualToString:@"base"]);
+ test([ex.kp isEqualToString:@"preserved"]);
+ test([ex.kpd isEqualToString:@"derived"]);
+ test([[ex.p1 ice_id] isEqualToString:[TestSlicingExceptionsClientPreservedClass ice_staticId]]);
+
+ test([ex.p1 isKindOfClass:[TestSlicingExceptionsClientPreservedClass class]]);
+ TestSlicingExceptionsClientPreservedClass* pc = (TestSlicingExceptionsClientPreservedClass*)ex.p1;
+ test([pc.bc isEqualToString:@"bc"]);
+ test([pc.pc isEqualToString:@"pc"]);
+ test([ex.p2 isEqual:ex.p1]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+ @catch(TestSlicingExceptionsClientKnownPreservedDerived* ex)
+ {
+ //
+ // For the 1.0 encoding, the unknown exception is sliced to KnownPreserved.
+ //
+ test([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0]);
+ test([ex.b isEqualToString:@"base"]);
+ test([ex.kp isEqualToString:@"preserved"]);
+ test([ex.kpd isEqualToString:@"derived"]);
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+
+ @try
+ {
+ [test relayUnknownPreservedAsKnownPreserved:relay];
+ test(NO);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+ @catch(TestSlicingExceptionsClientPreserved2* ex)
+ {
+ test([ex.b isEqualToString:@"base"]);
+ test([ex.kp isEqualToString:@"preserved"]);
+ test([ex.kpd isEqualToString:@"derived"]);
+ test([[ex.p1 ice_id] isEqualToString:[TestSlicingExceptionsClientPreservedClass ice_staticId]]);
+ test([ex.p1 isKindOfClass:[TestSlicingExceptionsClientPreservedClass class]]);
+ TestSlicingExceptionsClientPreservedClass* pc = (TestSlicingExceptionsClientPreservedClass*)ex.p1;
+ test([pc.bc isEqualToString:@"bc"]);
+ test([pc.pc isEqualToString:@"pc"]);
+ test([ex.p2 isEqual:ex.p1]);
+ }
+ @catch(TestSlicingExceptionsClientKnownPreservedDerived* ex)
+ {
+ //
+ // For the 1.0 encoding, the unknown exception is sliced to KnownPreserved.
+ //
+ test([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0]);
+ test([ex.b isEqualToString:@"base"]);
+ test([ex.kp isEqualToString:@"preserved"]);
+ test([ex.kpd isEqualToString:@"derived"]);
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+
+ [adapter destroy];
+ }
+ tprintf("ok\n");
+ return test;
+}
diff --git a/objc/test/Ice/slicing/exceptions/Client.m b/objc/test/Ice/slicing/exceptions/Client.m
new file mode 100644
index 00000000000..4c99f94b915
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/Client.m
@@ -0,0 +1,76 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <SlicingExceptionsTestClient.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestSlicingExceptionsClientTestIntfPrx> slicingExceptionsAllTests(id<ICECommunicator>);
+ id<TestSlicingExceptionsClientTestIntfPrx> thrower = slicingExceptionsAllTests(communicator);
+ [thrower shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main slicingExceptionsClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestSlicingExceptionsClient", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/slicing/exceptions/Makefile b/objc/test/Ice/slicing/exceptions/Makefile
new file mode 100644
index 00000000000..a34f5ba1506
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/Makefile
@@ -0,0 +1,40 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = SlicingExceptionsTestClient.o \
+ SlicingExceptionsTestServer.o
+
+COBJS = Client.o \
+ AllTests.o \
+ SlicingExceptionsTestClient.o
+
+SOBJS = TestI.o \
+ Server.o \
+ SlicingExceptionsTestServer.o
+
+OBJS = $(COBJS) $(SOBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../.. -I../../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/slicing/exceptions/Server.m b/objc/test/Ice/slicing/exceptions/Server.m
new file mode 100644
index 00000000000..054f8354816
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/Server.m
@@ -0,0 +1,84 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <slicing/exceptions/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* object = [[[TestSlicingExceptionsServerI alloc] init] autorelease];
+#else
+ ICEObject* object = [[TestSlicingExceptionsServerI alloc] init];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"Test"]];
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main slicingExceptionsServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestSlicingExceptionsServer", @"::Test",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/slicing/exceptions/SlicingExceptionsTestClient.ice b/objc/test/Ice/slicing/exceptions/SlicingExceptionsTestClient.ice
new file mode 100644
index 00000000000..fd7aa0cb695
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/SlicingExceptionsTestClient.ice
@@ -0,0 +1,113 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestSlicingExceptionsClient"]
+module Test
+{
+
+exception Base
+{
+ string b;
+};
+
+exception KnownDerived extends Base
+{
+ string kd;
+};
+
+exception KnownIntermediate extends Base
+{
+ string ki;
+};
+
+exception KnownMostDerived extends KnownIntermediate
+{
+ string kmd;
+};
+
+["preserve-slice"]
+exception KnownPreserved extends Base
+{
+ string kp;
+};
+
+exception KnownPreservedDerived extends KnownPreserved
+{
+ string kpd;
+};
+
+["preserve-slice"]
+class BaseClass
+{
+ string bc;
+};
+
+class PreservedClass extends BaseClass
+{
+ string pc;
+};
+
+exception Preserved1 extends KnownPreservedDerived
+{
+ BaseClass p1;
+};
+
+exception Preserved2 extends Preserved1
+{
+ BaseClass p2;
+};
+
+["format:sliced"]
+interface Relay
+{
+ void knownPreservedAsBase() throws Base;
+ void knownPreservedAsKnownPreserved() throws KnownPreserved;
+
+ void unknownPreservedAsBase() throws Base;
+ void unknownPreservedAsKnownPreserved() throws KnownPreserved;
+};
+
+["format:sliced"] interface TestIntf
+{
+ void baseAsBase() throws Base;
+ void unknownDerivedAsBase() throws Base;
+ void knownDerivedAsBase() throws Base;
+ void knownDerivedAsKnownDerived() throws KnownDerived;
+
+ void unknownIntermediateAsBase() throws Base;
+ void knownIntermediateAsBase() throws Base;
+ void knownMostDerivedAsBase() throws Base;
+ void knownIntermediateAsKnownIntermediate() throws KnownIntermediate;
+ void knownMostDerivedAsKnownIntermediate() throws KnownIntermediate;
+ void knownMostDerivedAsKnownMostDerived() throws KnownMostDerived;
+
+ void unknownMostDerived1AsBase() throws Base;
+ void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate;
+ void unknownMostDerived2AsBase() throws Base;
+
+ ["format:compact"] void unknownMostDerived2AsBaseCompact() throws Base;
+
+ void knownPreservedAsBase() throws Base;
+ void knownPreservedAsKnownPreserved() throws KnownPreserved;
+
+ void relayKnownPreservedAsBase(Relay* r) throws Base;
+ void relayKnownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved;
+
+ void unknownPreservedAsBase() throws Base;
+ void unknownPreservedAsKnownPreserved() throws KnownPreserved;
+
+ void relayUnknownPreservedAsBase(Relay* r) throws Base;
+ void relayUnknownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved;
+
+ void shutdown();
+};
+
+};
diff --git a/objc/test/Ice/slicing/exceptions/SlicingExceptionsTestServer.ice b/objc/test/Ice/slicing/exceptions/SlicingExceptionsTestServer.ice
new file mode 100644
index 00000000000..322a6e1c7f0
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/SlicingExceptionsTestServer.ice
@@ -0,0 +1,134 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestSlicingExceptionsServer"]
+module Test
+{
+
+exception Base
+{
+ string b;
+};
+
+exception KnownDerived extends Base
+{
+ string kd;
+};
+
+exception KnownIntermediate extends Base
+{
+ string ki;
+};
+
+exception KnownMostDerived extends KnownIntermediate
+{
+ string kmd;
+};
+
+["preserve-slice"]
+exception KnownPreserved extends Base
+{
+ string kp;
+};
+
+exception KnownPreservedDerived extends KnownPreserved
+{
+ string kpd;
+};
+
+["preserve-slice"]
+class BaseClass
+{
+ string bc;
+};
+
+["format:sliced"]
+interface Relay
+{
+ void knownPreservedAsBase() throws Base;
+ void knownPreservedAsKnownPreserved() throws KnownPreserved;
+
+ void unknownPreservedAsBase() throws Base;
+ void unknownPreservedAsKnownPreserved() throws KnownPreserved;
+};
+
+["format:sliced"] interface TestIntf
+{
+ void baseAsBase() throws Base;
+ void unknownDerivedAsBase() throws Base;
+ void knownDerivedAsBase() throws Base;
+ void knownDerivedAsKnownDerived() throws KnownDerived;
+
+ void unknownIntermediateAsBase() throws Base;
+ void knownIntermediateAsBase() throws Base;
+ void knownMostDerivedAsBase() throws Base;
+ void knownIntermediateAsKnownIntermediate() throws KnownIntermediate;
+ void knownMostDerivedAsKnownIntermediate() throws KnownIntermediate;
+ void knownMostDerivedAsKnownMostDerived() throws KnownMostDerived;
+
+ void unknownMostDerived1AsBase() throws Base;
+ void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate;
+ void unknownMostDerived2AsBase() throws Base;
+
+ ["format:compact"] void unknownMostDerived2AsBaseCompact() throws Base;
+
+ void knownPreservedAsBase() throws Base;
+ void knownPreservedAsKnownPreserved() throws KnownPreserved;
+
+ void relayKnownPreservedAsBase(Relay* r) throws Base;
+ void relayKnownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved;
+
+ void unknownPreservedAsBase() throws Base;
+ void unknownPreservedAsKnownPreserved() throws KnownPreserved;
+
+ void relayUnknownPreservedAsBase(Relay* r) throws Base;
+ void relayUnknownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved;
+
+ void shutdown();
+};
+
+// Stuff present in the server, not present in the client.
+exception UnknownDerived extends Base
+{
+ string ud;
+};
+
+exception UnknownIntermediate extends Base
+{
+ string ui;
+};
+
+exception UnknownMostDerived1 extends KnownIntermediate
+{
+ string umd1;
+};
+
+exception UnknownMostDerived2 extends UnknownIntermediate
+{
+ string umd2;
+};
+
+class SPreservedClass extends BaseClass
+{
+ string spc;
+};
+
+exception SPreserved1 extends KnownPreservedDerived
+{
+ BaseClass p1;
+};
+
+exception SPreserved2 extends SPreserved1
+{
+ BaseClass p2;
+};
+
+};
diff --git a/objc/test/Ice/slicing/exceptions/TestI.h b/objc/test/Ice/slicing/exceptions/TestI.h
new file mode 100644
index 00000000000..674328d7b21
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/TestI.h
@@ -0,0 +1,13 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <SlicingExceptionsTestServer.h>
+
+@interface TestSlicingExceptionsServerI : TestSlicingExceptionsServerTestIntf<TestSlicingExceptionsServerTestIntf>
+@end
diff --git a/objc/test/Ice/slicing/exceptions/TestI.m b/objc/test/Ice/slicing/exceptions/TestI.m
new file mode 100644
index 00000000000..b9628d0cdee
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/TestI.m
@@ -0,0 +1,156 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <slicing/exceptions/TestI.h>
+#import <TestCommon.h>
+#import <objc/Ice.h>
+
+@implementation TestSlicingExceptionsServerI
+-(void) baseAsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerBase base:@"Base.b"];
+}
+
+-(void) unknownDerivedAsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerUnknownDerived unknownDerived:@"UnknownDerived.b" ud:@"UnknownDerived.ud"];
+}
+
+-(void) knownDerivedAsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownDerived knownDerived:@"KnownDerived.b" kd:@"KnownDerived.kd"];
+}
+
+-(void) knownDerivedAsKnownDerived:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownDerived knownDerived:@"KnownDerived.b" kd:@"KnownDerived.kd"];
+}
+
+-(void) unknownIntermediateAsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerUnknownIntermediate unknownIntermediate:@"UnknownIntermediate.b" ui:@"UnknownIntermediate.ui"];
+}
+
+-(void) knownIntermediateAsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownIntermediate knownIntermediate:@"KnownIntermediate.b" ki:@"KnownIntermediate.ki"];
+}
+
+-(void) knownMostDerivedAsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownMostDerived knownMostDerived:@"KnownMostDerived.b" ki:@"KnownMostDerived.ki" kmd:@"KnownMostDerived.kmd"];
+}
+
+-(void) knownIntermediateAsKnownIntermediate:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownIntermediate knownIntermediate:@"KnownIntermediate.b" ki:@"KnownIntermediate.ki"];
+}
+
+-(void) knownMostDerivedAsKnownIntermediate:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownMostDerived knownMostDerived:@"KnownMostDerived.b" ki:@"KnownMostDerived.ki" kmd:@"KnownMostDerived.kmd"];
+}
+
+-(void) knownMostDerivedAsKnownMostDerived:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownMostDerived knownMostDerived:@"KnownMostDerived.b" ki:@"KnownMostDerived.ki" kmd:@"KnownMostDerived.kmd"];
+}
+
+-(void) unknownMostDerived1AsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerUnknownMostDerived1 unknownMostDerived1:@"UnknownMostDerived1.b" ki:@"UnknownMostDerived1.ki" umd1:@"UnknownMostDerived1.umd1"];
+}
+
+-(void) unknownMostDerived1AsKnownIntermediate:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerUnknownMostDerived1 unknownMostDerived1:@"UnknownMostDerived1.b"
+ ki:@"UnknownMostDerived1.ki"
+ umd1:@"UnknownMostDerived1.umd1"];
+}
+
+-(void) unknownMostDerived2AsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerUnknownMostDerived2 unknownMostDerived2:@"UnknownMostDerived2.b"
+ ui:@"UnknownMostDerived2.ui"
+ umd2:@"UnknownMostDerived2.umd2"];
+}
+
+-(void) unknownMostDerived2AsBaseCompact:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerUnknownMostDerived2 unknownMostDerived2:@"UnknownMostDerived2.b"
+ ui:@"UnknownMostDerived2.ui"
+ umd2:@"UnknownMostDerived2.umd2"];
+}
+
+-(void) knownPreservedAsBase:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownPreservedDerived knownPreservedDerived:@"base"
+ kp:@"preserved"
+ kpd:@"derived"];
+}
+
+-(void) knownPreservedAsKnownPreserved:(ICECurrent*)current
+{
+ @throw [TestSlicingExceptionsServerKnownPreservedDerived knownPreservedDerived:@"base"
+ kp:@"preserved"
+ kpd:@"derived"];
+}
+
+-(void) relayKnownPreservedAsBase:(TestSlicingExceptionsServerRelayPrx*)relay current:(ICECurrent*)current
+{
+ [relay knownPreservedAsBase];
+ test(NO);
+}
+
+-(void) relayKnownPreservedAsKnownPreserved:(TestSlicingExceptionsServerRelayPrx*)relay current:(ICECurrent*)current
+{
+ [relay knownPreservedAsKnownPreserved];
+ test(NO);
+}
+
+-(void) unknownPreservedAsBase:(ICECurrent*)current
+{
+ TestSlicingExceptionsServerSPreserved2* ex = [TestSlicingExceptionsServerSPreserved2 alloc];
+ ex.b = @"base";
+ ex.kp = @"preserved";
+ ex.kpd = @"derived";
+ ex.p1 = [TestSlicingExceptionsServerSPreservedClass sPreservedClass:@"bc" spc:@"spc"];
+ ex.p2 = ex.p1;
+ @throw ex;
+}
+
+-(void) unknownPreservedAsKnownPreserved:(ICECurrent*)current
+{
+ TestSlicingExceptionsServerSPreserved2* ex = [TestSlicingExceptionsServerSPreserved2 alloc];
+ ex.b = @"base";
+ ex.kp = @"preserved";
+ ex.kpd = @"derived";
+ ex.p1 = [TestSlicingExceptionsServerSPreservedClass sPreservedClass:@"bc" spc:@"spc"];
+ ex.p2 = ex.p1;
+ @throw ex;
+}
+
+-(void) relayUnknownPreservedAsBase:(TestSlicingExceptionsServerRelayPrx*)relay current:(ICECurrent*)current
+{
+ [relay unknownPreservedAsBase];
+ test(NO);
+}
+
+-(void) relayUnknownPreservedAsKnownPreserved:(TestSlicingExceptionsServerRelayPrx*)relay current:(ICECurrent*)current
+{
+ [relay unknownPreservedAsKnownPreserved];
+ test(NO);
+}
+
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
diff --git a/objc/test/Ice/slicing/exceptions/run.py b/objc/test/Ice/slicing/exceptions/run.py
new file mode 100755
index 00000000000..8e41f17c1be
--- /dev/null
+++ b/objc/test/Ice/slicing/exceptions/run.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+print("Running test with sliced format.")
+TestUtil.clientServerTest()
+
+print("Running test with 1.0 encoding.")
+TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0",
+ additionalServerOptions="--Ice.Default.EncodingVersion=1.0")
diff --git a/objc/test/Ice/slicing/objects/.gitignore b/objc/test/Ice/slicing/objects/.gitignore
new file mode 100644
index 00000000000..a2c2a1c0974
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/.gitignore
@@ -0,0 +1,14 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+SlicingObjectsTestClient.m
+SlicingObjectsForwardClient.m
+SlicingObjectsTestServer.m
+SlicingObjectsForwardServer.m
+SlicingObjectsTestClient.h
+SlicingObjectsForwardClient.h
+SlicingObjectsTestServer.h
+SlicingObjectsForwardServer.h
diff --git a/objc/test/Ice/slicing/objects/AllTests.m b/objc/test/Ice/slicing/objects/AllTests.m
new file mode 100644
index 00000000000..efc0edf3ae7
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/AllTests.m
@@ -0,0 +1,2232 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <SlicingObjectsTestClient.h>
+#import <SlicingObjectsForwardClient.h>
+
+#import <Foundation/Foundation.h>
+
+@interface TestSlicingObjectsClientCallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+@public
+ id r;
+ id bout;
+}
+@property(nonatomic, retain) id r;
+@property(nonatomic, retain) id bout;
+-(void) check;
+-(void) called;
+@end
+
+@implementation TestSlicingObjectsClientCallback
+@synthesize r;
+@synthesize bout;
+-(id) init
+{
+ if(![super init])
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
++(id) create
+{
+#if defined(__clang__) && __has_feature(objc_arc)
+ return [[TestSlicingObjectsClientCallback alloc] init];
+#else
+ return [[[TestSlicingObjectsClientCallback alloc] init] autorelease];
+#endif
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) check
+{
+ [cond lock];
+ while(!called)
+ {
+ [cond wait];
+ }
+ called = NO;
+ [cond unlock];
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) SBaseAsObjectResponse:(ICEObject*)o
+{
+ test(o);
+ test([[o ice_id:nil] isEqualToString:@"::Test::SBase"]);
+ test([o isKindOfClass:[TestSlicingObjectsClientSBase class]]);
+ TestSlicingObjectsClientSBase* sb = (TestSlicingObjectsClientSBase*)o;
+ test([sb.sb isEqualToString:@"SBase.sb"]);
+ [self called];
+}
+
+-(void) SBaseAsObjectException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) SBaseAsSBaseResponse:(TestSlicingObjectsClientSBase*)sb
+{
+ test([sb.sb isEqualToString:@"SBase.sb"]);
+ [self called];
+}
+
+-(void) SBaseAsSBaseException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) SBSKnownDerivedAsSBaseResponse:(TestSlicingObjectsClientSBase*)sb
+{
+ test([sb isKindOfClass:[TestSlicingObjectsClientSBSKnownDerived class]]);
+ TestSlicingObjectsClientSBSKnownDerived* sbskd = (TestSlicingObjectsClientSBSKnownDerived*)sb;
+ test([sbskd.sbskd isEqualToString:@"SBSKnownDerived.sbskd"]);
+ [self called];
+}
+
+-(void) SBSKnownDerivedAsSBaseException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) SBSKnownDerivedAsSBSKnownDerivedResponse:(TestSlicingObjectsClientSBSKnownDerived*)sbskd
+{
+ test([sbskd.sbskd isEqualToString:@"SBSKnownDerived.sbskd"]);
+ [self called];
+}
+
+-(void) SBSKnownDerivedAsSBSKnownDerivedException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) SBSUnknownDerivedAsSBaseResponse:(TestSlicingObjectsClientSBase*)sb
+{
+ test([sb.sb isEqualToString:@"SBSUnknownDerived.sb"]);
+ [self called];
+}
+
+-(void) SBSUnknownDerivedAsSBaseException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) SBSUnknownDerivedAsSBaseCompactResponse:(TestSlicingObjectsClientSBase*)sb
+{
+ test(NO);
+}
+
+-(void) SBSUnknownDerivedAsSBaseCompactException:(ICEException*)exc
+{
+ test([[exc ice_name] isEqualToString:@"Ice::NoObjectFactoryException"]);
+ [self called];
+}
+
+-(void) SUnknownAsObjectResponse10:(ICEObject*)o
+{
+ test(NO);
+}
+
+-(void) SUnknownAsObjectException10:(ICEException*)exc
+{
+ test([[exc ice_name] isEqualToString:@"Ice::NoObjectFactoryException"]);
+ [self called];
+}
+
+-(void) SUnknownAsObjectResponse11:(ICEObject*)o
+{
+ [self called];
+}
+
+-(void) SUnknownAsObjectException11:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) oneElementCycleResponse:(TestSlicingObjectsClientB*)b
+{
+ test(b);
+ test([[b ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([b.sb isEqualToString:@"B1.sb"]);
+ test(b.pb == b);
+ [self called];
+}
+
+-(void) oneElementCycleException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) twoElementCycleResponse:(TestSlicingObjectsClientB*)b1
+{
+ test(b1);
+ test([[b1 ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([b1.sb isEqualToString:@"B1.sb"]);
+
+ TestSlicingObjectsClientB* b2 = b1.pb;
+ test(b2);
+ test([[b2 ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([b2.sb isEqualToString:@"B2.sb"]);
+ test(b2.pb == b1);
+ [self called];
+}
+
+-(void) twoElementCycleException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) D1AsBResponse:(TestSlicingObjectsClientB*)b1
+{
+ test(b1);
+ test([[b1 ice_id:nil] isEqualToString:@"::Test::D1"]);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test(b1.pb);
+ test(b1.pb != b1);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b1;
+ test([d1.sd1 isEqualToString:@"D1.sd1"]);
+ test(d1.pd1);
+ test(d1.pd1 != b1);
+ test(b1.pb == d1.pd1);
+
+ TestSlicingObjectsClientB* b2 = b1.pb;
+ test(b2);
+ test(b2.pb == b1);
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test([[b2 ice_id:nil] isEqualToString:@"::Test::B"]);
+ [self called];
+}
+
+-(void) D1AsBException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) D1AsD1Response:(TestSlicingObjectsClientD1*)d1
+{
+ test(d1);
+ test([[d1 ice_id:nil] isEqualToString:@"::Test::D1"]);
+ test([d1.sb isEqualToString:@"D1.sb"]);
+ test(d1.pb);
+ test(d1.pb != d1);
+
+ TestSlicingObjectsClientB* b2 = d1.pb;
+ test(b2);
+ test([[b2 ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test(b2.pb == d1);
+ [self called];
+}
+
+-(void) D1AsD1Exception:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) D2AsBResponse:(TestSlicingObjectsClientB*)b2
+{
+ test(b2);
+ test([[b2 ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test(b2.pb);
+ test(b2.pb != b2);
+
+ TestSlicingObjectsClientB* b1 = b2.pb;
+ test(b1);
+ test([[b1 ice_id:nil] isEqualToString:@"::Test::D1"]);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test(b1.pb == b2);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b1;
+ test([d1.sd1 isEqualToString:@"D1.sd1"]);
+ test(d1.pd1 == b2);
+ [self called];
+}
+
+-(void) D2AsBException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) paramTest1Response:(TestSlicingObjectsClientB*)b1 p2:(TestSlicingObjectsClientB*)b2
+{
+ test(b1);
+ test([[b1 ice_id:nil] isEqualToString:@"::Test::D1"]);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test(b1.pb == b2);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b1;
+ test([d1.sd1 isEqualToString:@"D1.sd1"]);
+ test(d1.pd1 == b2);
+
+ test(b2);
+ test([[b2 ice_id:nil] isEqualToString:@"::Test::B"]); // No factory, must be sliced
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test(b2.pb == b1);
+ [self called];
+}
+
+-(void) paramTest1Exception:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) returnTest1Response:(TestSlicingObjectsClientB*)r_ p1:(TestSlicingObjectsClientB*)p1 p2:(TestSlicingObjectsClientB*)p2
+{
+ test(r_ == p1);
+ [self called];
+}
+
+-(void) returnTest1Exception:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) returnTest2Response:(TestSlicingObjectsClientB*)r_ p1:(TestSlicingObjectsClientB*)p1 p2:(TestSlicingObjectsClientB*)p2
+{
+ test(r_ == p1);
+ [self called];
+}
+
+-(void) returnTest2Exception:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) returnTest3Response:(TestSlicingObjectsClientB*)b
+{
+ self.r = b;
+ [self called];
+}
+
+-(void) returnTest3Exception:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) paramTest3Response:(TestSlicingObjectsClientB*)ret p1:(TestSlicingObjectsClientB*)p1 p2:(TestSlicingObjectsClientB*)p2
+{
+ test(p1);
+ test([p1.sb isEqualToString:@"D2.sb (p1 1)"]);
+ test(p1.pb == 0);
+ test([[p1 ice_id:nil] isEqualToString:@"::Test::B"]);
+
+ test(p2);
+ test([p2.sb isEqualToString:@"D2.sb (p2 1)"]);
+ test(p2.pb == 0);
+ test([[p2 ice_id:nil] isEqualToString:@"::Test::B"]);
+
+ test(ret);
+ test([ret.sb isEqualToString:@"D1.sb (p2 2)"]);
+ test(ret.pb == 0);
+ test([[ret ice_id:nil] isEqualToString:@"::Test::D1"]);
+ [self called];
+}
+
+-(void) paramTest3Exception:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) paramTest4Response:(TestSlicingObjectsClientB*)ret p1:(TestSlicingObjectsClientB*)b
+{
+ test(b);
+ test([b.sb isEqualToString:@"D4.sb (1)"]);
+ test(b.pb == 0);
+ test([[b ice_id:nil] isEqualToString:@"::Test::B"]);
+
+ test(ret);
+ test([ret.sb isEqualToString:@"B.sb (2)"]);
+ test(ret.pb == 0);
+ test([[ret ice_id:nil] isEqualToString:@"::Test::B"]);
+ [self called];
+}
+
+-(void) paramTest4Exception:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) sequenceTestResponse:(TestSlicingObjectsClientSS*)ss
+{
+ self.r = ss;
+ [self called];
+}
+
+-(void) sequenceTestException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) dictionaryTestResponse:(TestSlicingObjectsClientBDict*)r_ bout:(TestSlicingObjectsClientBDict*)bout_
+{
+ self.r = r_;
+ self.bout = bout_;
+ [self called];
+}
+
+-(void) dictionaryTestException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) throwBaseAsBaseResponse
+{
+ test(NO);
+}
+
+-(void) throwBaseAsBaseException:(ICEException*)ex
+{
+ test([[ex ice_name] isEqualToString:@"Test::BaseException"]);
+ TestSlicingObjectsClientBaseException* e = (TestSlicingObjectsClientBaseException*)ex;
+ test([e.sbe isEqualToString:@"sbe"]);
+ test(e.pb);
+ test([e.pb.sb isEqualToString:@"sb"]);
+ test(e.pb.pb == e.pb);
+ [self called];
+}
+
+-(void) throwDerivedAsBaseResponse
+{
+ test(NO);
+}
+
+-(void) throwDerivedAsBaseException:(ICEException*)ex
+{
+ test([[ex ice_name] isEqualToString:@"Test::DerivedException"]);
+ TestSlicingObjectsClientDerivedException* e = (TestSlicingObjectsClientDerivedException*)ex;
+ test([e.sbe isEqualToString:@"sbe"]);
+ test(e.pb);
+ test([e.pb.sb isEqualToString:@"sb1"]);
+ test(e.pb.pb == e.pb);
+ test([e.sde isEqualToString:@"sde1"]);
+ test(e.pd1);
+ test([e.pd1.sb isEqualToString:@"sb2"]);
+ test(e.pd1.pb == e.pd1);
+ test([e.pd1.sd1 isEqualToString:@"sd2"]);
+ test(e.pd1.pd1 == e.pd1);
+ [self called];
+}
+
+-(void) throwDerivedAsDerivedResponse
+{
+ test(NO);
+}
+
+-(void) throwDerivedAsDerivedException:(ICEException*)ex
+{
+ test([[ex ice_name] isEqualToString:@"Test::DerivedException"]);
+ TestSlicingObjectsClientDerivedException* e = (TestSlicingObjectsClientDerivedException*)ex;
+ test([e.sbe isEqualToString:@"sbe"]);
+ test(e.pb);
+ test([e.pb.sb isEqualToString:@"sb1"]);
+ test(e.pb.pb == e.pb);
+ test([e.sde isEqualToString:@"sde1"]);
+ test(e.pd1);
+ test([e.pd1.sb isEqualToString:@"sb2"]);
+ test(e.pd1.pb == e.pd1);
+ test([e.pd1.sd1 isEqualToString:@"sd2"]);
+ test(e.pd1.pd1 == e.pd1);
+ [self called];
+}
+
+-(void) throwUnknownDerivedAsBaseResponse
+{
+ test(NO);
+}
+
+-(void) throwUnknownDerivedAsBaseException:(ICEException*)ex
+{
+ test([[ex ice_name] isEqualToString:@"Test::BaseException"]);
+ TestSlicingObjectsClientBaseException* e = (TestSlicingObjectsClientBaseException*)ex;
+ test([e.sbe isEqualToString:@"sbe"]);
+ test(e.pb);
+ test([e.pb.sb isEqualToString:@"sb d2"]);
+ test(e.pb.pb == e.pb);
+ [self called];
+}
+
+-(void) useForwardResponse:(TestSlicingObjectsClientForward*)f
+{
+ test(f);
+ [self called];
+}
+
+-(void) useForwardException:(ICEException*)exc
+{
+ test(NO);
+}
+
+-(void) responsePreserved1:(TestSlicingObjectsClientPBase*)res
+{
+ test([res isKindOfClass:[TestSlicingObjectsClientPDerived class]]);
+ TestSlicingObjectsClientPDerived* pd = (TestSlicingObjectsClientPDerived*)res;
+ test(pd);
+ test(pd.pi == 3);
+ test([pd.ps isEqualToString:@"preserved"]);
+ test([pd.pb isEqual:pd]);
+ [self called];
+}
+
+-(void) responsePreserved2:(TestSlicingObjectsClientPBase*)res
+{
+ test(![res isKindOfClass:[TestSlicingObjectsClientPCUnknown class]]);
+ test(res.pi == 3);
+ [self called];
+}
+
+-(void) responsePreserved3:(TestSlicingObjectsClientPBase*)res
+{
+ //
+ // Encoding 1.0
+ //
+ test(![res isKindOfClass:[TestSlicingObjectsClientPCDerived class]]);
+ test(res.pi == 3);
+ [self called];
+}
+
+-(void) responsePreserved4:(TestSlicingObjectsClientPBase*)res
+{
+ //
+ // Encoding > 1.0
+ //
+ test([res isKindOfClass:[TestSlicingObjectsClientPCDerived class]]);
+ TestSlicingObjectsClientPCDerived* p2 = (TestSlicingObjectsClientPCDerived*)res;
+ test(p2.pi == 3);
+ test([[p2.pbs objectAtIndex:0] isEqual:p2]);
+ [self called];
+}
+
+-(void) responsePreserved5:(TestSlicingObjectsClientPBase*)res
+{
+ test([res isKindOfClass:[TestSlicingObjectsClientPCDerived3 class]]);
+ TestSlicingObjectsClientPCDerived3* p3 = (TestSlicingObjectsClientPCDerived3*)res;
+ test(p3.pi == 3);
+ for(int i = 0; i < 300; ++i)
+ {
+ TestSlicingObjectsClientPCDerived2* p2 = (TestSlicingObjectsClientPCDerived2*)[p3.pbs objectAtIndex:i];
+ test(p2.pi == i);
+ test([p2.pbs count] == 1);
+ test([[p2.pbs objectAtIndex:0] isEqual:[NSNull null]]);
+ test(p2.pcd2 == i);
+ }
+ test(p3.pcd2 == p3.pi);
+ test([p3.pcd3 isEqual:[p3.pbs objectAtIndex:10]]);
+ [self called];
+}
+
+-(void) responseCompactPreserved1:(TestSlicingObjectsClientPBase*)res
+{
+ //
+ // Encoding 1.0
+ //
+ test(![res isKindOfClass:[TestSlicingObjectsClientCompactPCDerived class]]);
+ test(res.pi == 3);
+ [self called];
+}
+
+-(void) responseCompactPreserved2:(TestSlicingObjectsClientPBase*)res
+{
+ //
+ // Encoding > 1.0
+ //
+ test([res isKindOfClass:[TestSlicingObjectsClientCompactPCDerived class]]);
+ TestSlicingObjectsClientCompactPCDerived* p2 = (TestSlicingObjectsClientCompactPCDerived*)res;
+ test(p2.pi == 3);
+ test([[p2.pbs objectAtIndex:0] isEqual:p2]);
+ [self called];
+}
+
+-(void) response
+{
+ test(NO);
+}
+
+-(void) exception:(ICEException*)ex
+{
+ if(![ex isKindOfClass:[ICEOperationNotExistException class]])
+ {
+ test(NO);
+ }
+ else
+ {
+ [self called];
+ }
+}
+
+@end
+
+id<TestSlicingObjectsClientTestIntfPrx>
+slicingObjectsAllTests(id<ICECommunicator> communicator)
+{
+ id<ICEObjectPrx> obj = [communicator stringToProxy:@"Test:default -p 12010"];
+ id<TestSlicingObjectsClientTestIntfPrx> test = [TestSlicingObjectsClientTestIntfPrx checkedCast:obj];
+
+ tprintf("base as Object... ");
+ {
+ ICEObject* o = nil;
+ @try
+ {
+ o = [test SBaseAsObject];
+ test(o);
+ test([[o ice_id] isEqualToString:@"::Test::SBase"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+
+ test([o isKindOfClass:[TestSlicingObjectsClientSBase class]]);
+ test([((TestSlicingObjectsClientSBase*)o).sb isEqualToString:@"SBase.sb"]);
+ }
+ tprintf("ok\n");
+
+ tprintf("base as Object (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_SBaseAsObject:^(ICEObject* o) { [cb SBaseAsObjectResponse:o]; }
+ exception:^(ICEException* ex) { [cb SBaseAsObjectException:ex]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("base as base... ");
+ {
+ TestSlicingObjectsClientSBase* sb;
+ @try
+ {
+ sb = [test SBaseAsSBase];
+ test([sb.sb isEqualToString:@"SBase.sb"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("base as base (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_SBaseAsSBase:^(TestSlicingObjectsClientSBase* o) { [cb SBaseAsSBaseResponse:o]; }
+ exception:^(ICEException* e) { [cb SBaseAsSBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("base with known derived as base... ");
+ {
+ TestSlicingObjectsClientSBase* sb = nil;
+ @try
+ {
+ sb = [test SBSKnownDerivedAsSBase];
+ test([sb.sb isEqualToString:@"SBSKnownDerived.sb"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ test([sb isKindOfClass:[TestSlicingObjectsClientSBSKnownDerived class]]);
+ test([((TestSlicingObjectsClientSBSKnownDerived*)sb).sbskd isEqualToString:@"SBSKnownDerived.sbskd"]);
+ }
+ tprintf("ok\n");
+
+ tprintf("base with known derived as base (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_SBSKnownDerivedAsSBase:^(TestSlicingObjectsClientSBase* o) { [cb SBSKnownDerivedAsSBaseResponse:o]; } exception:^(ICEException* e) { [cb SBSKnownDerivedAsSBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("base with known derived as known derived... ");
+ {
+ TestSlicingObjectsClientSBSKnownDerived* sbskd;
+ @try
+ {
+ sbskd = [test SBSKnownDerivedAsSBSKnownDerived];
+ test([sbskd.sbskd isEqualToString:@"SBSKnownDerived.sbskd"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("base with known derived as known derived (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_SBSKnownDerivedAsSBSKnownDerived:^(TestSlicingObjectsClientSBSKnownDerived* o) { [cb SBSKnownDerivedAsSBSKnownDerivedResponse:o]; } exception:^(ICEException* e) { [cb SBSKnownDerivedAsSBSKnownDerivedException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("base with unknown derived as base... ");
+ {
+ TestSlicingObjectsClientSBase* sb;
+ @try
+ {
+ sb = [test SBSUnknownDerivedAsSBase];
+ test([sb.sb isEqualToString:@"SBSUnknownDerived.sb"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ @try
+ {
+ //
+ // This test succeeds for the 1.0 encoding.
+ //
+ sb = [test SBSUnknownDerivedAsSBaseCompact];
+ test([[sb sb] isEqual:@"SBSUnknownDerived.sb"]);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ else
+ {
+ @try
+ {
+ //
+ // This test fails when using the compact format because the instance cannot
+ // be sliced to a known type.
+ //
+ sb = [test SBSUnknownDerivedAsSBaseCompact];
+ test(NO);
+ }
+ @catch(const ICEOperationNotExistException*)
+ {
+ }
+ @catch(const ICENoObjectFactoryException*)
+ {
+ // Expected.
+ }
+ @catch(...)
+ {
+ test(NO);
+ }
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("base with unknown derived as base (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_SBSUnknownDerivedAsSBase:^(TestSlicingObjectsClientSBase* o) { [cb SBSUnknownDerivedAsSBaseResponse:o]; } exception:^(ICEException* e) { [cb SBSUnknownDerivedAsSBaseException:e]; }];
+ [cb check];
+ }
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ //
+ // This test succeeds for the 1.0 encoding.
+ //
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_SBSUnknownDerivedAsSBaseCompact:^(TestSlicingObjectsClientSBase* o) { [cb SBSUnknownDerivedAsSBaseResponse:o]; } exception:^(ICEException* e) { [cb SBSUnknownDerivedAsSBaseException:e]; }];
+ [cb check];
+ }
+ else
+ {
+ //
+ // This test fails when using the compact format because the instance cannot
+ // be sliced to a known type.
+ //
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_SBSUnknownDerivedAsSBaseCompact:^(TestSlicingObjectsClientSBase* o) { [cb SBSUnknownDerivedAsSBaseCompactResponse:o]; } exception:^(ICEException* e) { [cb SBSUnknownDerivedAsSBaseCompactException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("unknown with Object as Object... ");
+ {
+ ICEObject* o;
+ @try
+ {
+ o = [test SUnknownAsObject];
+ test(![[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0]);
+ test([o isKindOfClass:[ICEUnknownSlicedObject class]]);
+ test([[((ICEUnknownSlicedObject*)o) getUnknownTypeId] isEqualToString:@"::Test::SUnknown"]);
+ [test checkSUnknown:o];
+ }
+ @catch(ICENoObjectFactoryException*)
+ {
+ test([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0]);
+ }
+ @catch(NSException* ex)
+ {
+ NSLog(@"exception: %@", ex);
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("unknown with Object as Object (AMI)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ [test begin_SUnknownAsObject:^(ICEObject* o) { [cb SUnknownAsObjectResponse10:o]; }
+ exception:^(ICEException* e) { [cb SUnknownAsObjectException10:e]; }];
+ }
+ else
+ {
+ [test begin_SUnknownAsObject:^(ICEObject* o) { [cb SUnknownAsObjectResponse11:o]; }
+ exception:^(ICEException* e) { [cb SUnknownAsObjectException11:e]; }];
+ }
+ [cb check];
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("one-element cycle... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b = [test oneElementCycle];
+ test(b);
+ test([[b ice_id] isEqualToString:@"::Test::B"]);
+ test([b.sb isEqualToString:@"B1.sb"]);
+ test([b.pb.sb isEqualToString:@"B1.sb"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("one-element cycle (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_oneElementCycle:^(TestSlicingObjectsClientB* o) { [cb oneElementCycleResponse:o]; } exception:^(ICEException* e) { [cb oneElementCycleException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("two-element cycle... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b1 = [test twoElementCycle];
+ test(b1);
+ test([[b1 ice_id] isEqualToString:@"::Test::B"]);
+ test([b1.sb isEqualToString:@"B1.sb"]);
+
+ TestSlicingObjectsClientB* b2 = b1.pb;
+ test(b2);
+ test([[b2 ice_id] isEqualToString:@"::Test::B"]);
+ test([b2.sb isEqualToString:@"B2.sb"]);
+ test(b2.pb == b1);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("two-element cycle (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_twoElementCycle:^(TestSlicingObjectsClientB* o) { [cb twoElementCycleResponse:o]; } exception:^(ICEException* e) { [cb twoElementCycleException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("known derived pointer slicing as base... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b1;
+ b1 = [test D1AsB];
+ test(b1);
+ test([[b1 ice_id] isEqualToString:@"::Test::D1"]);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test(b1.pb);
+ test(b1.pb != b1);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b1;
+ test([d1.sd1 isEqualToString:@"D1.sd1"]);
+ test(d1.pd1);
+ test(d1.pd1 != b1);
+ test(b1.pb == d1.pd1);
+
+ TestSlicingObjectsClientB* b2 = b1.pb;
+ test(b2);
+ test(b2.pb == b1);
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test([[b2 ice_id] isEqualToString:@"::Test::B"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("known derived pointer slicing as base (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_D1AsB:^(TestSlicingObjectsClientB* o) { [cb D1AsBResponse:o]; } exception:^(ICEException* e) { [cb D1AsBException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("known derived pointer slicing as derived... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientD1* d1;
+ d1 = [test D1AsD1];
+ test(d1);
+ test([[d1 ice_id] isEqualToString:@"::Test::D1"]);
+ test([d1.sb isEqualToString:@"D1.sb"]);
+ test(d1.pb);
+ test(d1.pb != d1);
+
+ TestSlicingObjectsClientB* b2 = d1.pb;
+ test(b2);
+ test([[b2 ice_id] isEqualToString:@"::Test::B"]);
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test(b2.pb == d1);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("known derived pointer slicing as derived (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_D1AsD1:^(TestSlicingObjectsClientD1* o) { [cb D1AsD1Response:o]; } exception:^(ICEException* e) { [cb D1AsD1Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("unknown derived pointer slicing as base... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b2;
+ b2 = [test D2AsB];
+ test(b2);
+ test([[b2 ice_id] isEqualToString:@"::Test::B"]);
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test(b2.pb);
+ test(b2.pb != b2);
+
+ TestSlicingObjectsClientB* b1 = b2.pb;
+ test(b1);
+ test([[b1 ice_id] isEqualToString:@"::Test::D1"]);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test(b1.pb == b2);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b1;
+ test([d1.sd1 isEqualToString:@"D1.sd1"]);
+ test(d1.pd1 == b2);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("unknown derived pointer slicing as base (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_D2AsB:^(TestSlicingObjectsClientB* o) { [cb D2AsBResponse:o]; } exception:^(ICEException* e) { [cb D2AsBException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("param ptr slicing with known first... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b1;
+ TestSlicingObjectsClientB* b2;
+ [test paramTest1:&b1 p2:&b2];
+
+ test(b1);
+ test([[b1 ice_id] isEqualToString:@"::Test::D1"]);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test(b1.pb == b2);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b1;
+ test([d1.sd1 isEqualToString:@"D1.sd1"]);
+ test(d1.pd1 == b2);
+
+ test(b2);
+ test([[b2 ice_id] isEqualToString:@"::Test::B"]); // No factory, must be sliced
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test(b2.pb == b1);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("param ptr slicing with known first (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_paramTest1:^(TestSlicingObjectsClientB* o, TestSlicingObjectsClientB* b2) { [cb paramTest1Response:o p2:b2]; } exception:^(ICEException* e) { [cb paramTest1Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("param ptr slicing with unknown first... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b2;
+ TestSlicingObjectsClientB* b1;
+ [test paramTest2:&b2 p1:&b1];
+
+ test(b1);
+ test([[b1 ice_id] isEqualToString:@"::Test::D1"]);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test(b1.pb == b2);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b1;
+ test([d1.sd1 isEqualToString:@"D1.sd1"]);
+ test(d1.pd1 == b2);
+
+ test(b2);
+ test([[b2 ice_id] isEqualToString:@"::Test::B"]); // No factory, must be sliced
+ test([b2.sb isEqualToString:@"D2.sb"]);
+ test(b2.pb == b1);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("return value identity with known first... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* p1;
+ TestSlicingObjectsClientB* p2;
+ TestSlicingObjectsClientB* r = [test returnTest1:&p1 p2:&p2];
+ test(r == p1);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("return value identity with known first (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_returnTest1:^(TestSlicingObjectsClientB* o, TestSlicingObjectsClientB* b1, TestSlicingObjectsClientB* b2) { [cb returnTest1Response:o p1:b1 p2:b2]; } exception:^(ICEException* e) { [cb returnTest1Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("return value identity with unknown first... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* p1;
+ TestSlicingObjectsClientB* p2;
+ TestSlicingObjectsClientB* r = [test returnTest2:&p1 p1:&p2];
+ test(r == p1);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("return value identity with unknown first (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_returnTest2:^(TestSlicingObjectsClientB* o, TestSlicingObjectsClientB* b1, TestSlicingObjectsClientB* b2) { [cb returnTest2Response:o p1:b1 p2:b2]; } exception:^(ICEException* e) { [cb returnTest2Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("return value identity for input params known first... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientD1* d1 = [TestSlicingObjectsClientD1 d1];
+ d1.sb = @"D1.sb";
+ d1.sd1 = @"D1.sd1";
+ TestSlicingObjectsClientD3* d3 = [TestSlicingObjectsClientD3 d3];
+ d3.pb = d1;
+ d3.sb = @"D3.sb";
+ d3.sd3 = @"D3.sd3";
+ d3.pd3 = d1;
+ d1.pb = d3;
+ d1.pd1 = d3;
+
+ TestSlicingObjectsClientB* b1 = [test returnTest3:d1 p2:d3];
+
+ test(b1);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test([[b1 ice_id] isEqualToString:@"::Test::D1"]);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* p1 = (TestSlicingObjectsClientD1*)b1;
+ test([p1.sd1 isEqualToString:@"D1.sd1"]);
+ test(p1.pd1 == b1.pb);
+
+ TestSlicingObjectsClientB* b2 = b1.pb;
+ test(b2);
+ test([b2.sb isEqualToString:@"D3.sb"]);
+ test([[b2 ice_id] isEqualToString:@"::Test::B"]); // Sliced by server
+ test(b2.pb == b1);
+ test(![b2 isKindOfClass:[TestSlicingObjectsClientD3 class]]);
+
+ test(b1 != d1);
+ test(b1 != d3);
+ test(b2 != d1);
+ test(b2 != d3);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("return value identity for input params known first (AMI)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientD1* d1 = [TestSlicingObjectsClientD1 d1];
+ d1.sb = @"D1.sb";
+ d1.sd1 = @"D1.sd1";
+ TestSlicingObjectsClientD3* d3 = [TestSlicingObjectsClientD3 d3];
+ d3.pb = d1;
+ d3.sb = @"D3.sb";
+ d3.sd3 = @"D3.sd3";
+ d3.pd3 = d1;
+ d1.pb = d3;
+ d1.pd1 = d3;
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_returnTest3:d1 p2:d3 response:^(TestSlicingObjectsClientB* o) { [cb returnTest3Response:o]; } exception:^(ICEException* e) { [cb returnTest3Exception:e]; }];
+ [cb check];
+ TestSlicingObjectsClientB* b1 = cb.r;
+
+ test(b1);
+ test([b1.sb isEqualToString:@"D1.sb"]);
+ test([[b1 ice_id:nil] isEqualToString:@"::Test::D1"]);
+ test([b1 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* p1 = (TestSlicingObjectsClientD1*)b1;
+ test([p1.sd1 isEqualToString:@"D1.sd1"]);
+ test(p1.pd1 == b1.pb);
+
+ TestSlicingObjectsClientB* b2 = b1.pb;
+ test(b2);
+ test([b2.sb isEqualToString:@"D3.sb"]);
+ test([[b2 ice_id:nil] isEqualToString:@"::Test::B"]); // Sliced by server
+ test(b2.pb == b1);
+ test(![b2 isKindOfClass:[TestSlicingObjectsClientD3 class]]);
+
+ test(b1 != d1);
+ test(b1 != d3);
+ test(b2 != d1);
+ test(b2 != d3);
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("return value identity for input params unknown first... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientD1* d1 = [TestSlicingObjectsClientD1 d1];
+ d1.sb = @"D1.sb";
+ d1.sd1 = @"D1.sd1";
+ TestSlicingObjectsClientD3* d3 = [TestSlicingObjectsClientD3 d3];
+ d3.pb = d1;
+ d3.sb = @"D3.sb";
+ d3.sd3 = @"D3.sd3";
+ d3.pd3 = d1;
+ d1.pb = d3;
+ d1.pd1 = d3;
+
+ TestSlicingObjectsClientB* b1 = [test returnTest3:d3 p2:d1];
+
+ test(b1);
+ test([b1.sb isEqualToString:@"D3.sb"]);
+ test([[b1 ice_id] isEqualToString:@"::Test::B"]); // Sliced by server
+ test(![b1 isKindOfClass:[TestSlicingObjectsClientD3 class]]);
+
+ TestSlicingObjectsClientB* b2 = b1.pb;
+ test(b2);
+ test([b2.sb isEqualToString:@"D1.sb"]);
+ test([[b2 ice_id] isEqualToString:@"::Test::D1"]);
+ test(b2.pb == b1);
+ test([b2 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* p3 = (TestSlicingObjectsClientD1*)b2;
+ test([p3.sd1 isEqualToString:@"D1.sd1"]);
+ test(p3.pd1 == b1);
+
+ test(b1 != d1);
+ test(b1 != d3);
+ test(b2 != d1);
+ test(b2 != d3);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("return value identity for input params unknown first (AMI)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientD1* d1 = [TestSlicingObjectsClientD1 d1];
+ d1.sb = @"D1.sb";
+ d1.sd1 = @"D1.sd1";
+ TestSlicingObjectsClientD3* d3 = [TestSlicingObjectsClientD3 d3];
+ d3.pb = d1;
+ d3.sb = @"D3.sb";
+ d3.sd3 = @"D3.sd3";
+ d3.pd3 = d1;
+ d1.pb = d3;
+ d1.pd1 = d3;
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_returnTest3:d3 p2:d1 response:^(TestSlicingObjectsClientB* o) { [cb returnTest3Response:o]; } exception:^(ICEException* e) { [cb returnTest3Exception:e]; }];
+ [cb check];
+ TestSlicingObjectsClientB* b1 = cb.r;
+
+ test(b1);
+ test([b1.sb isEqualToString:@"D3.sb"]);
+ test([[b1 ice_id:nil] isEqualToString:@"::Test::B"]); // Sliced by server
+ test(![b1 isKindOfClass:[TestSlicingObjectsClientD3 class]]);
+
+ TestSlicingObjectsClientB* b2 = b1.pb;
+ test(b2);
+ test([b2.sb isEqualToString:@"D1.sb"]);
+ test([[b2 ice_id:nil] isEqualToString:@"::Test::D1"]);
+ test(b2.pb == b1);
+ test([b2 isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* p3 = (TestSlicingObjectsClientD1*)b2;
+ test([p3.sd1 isEqualToString:@"D1.sd1"]);
+ test(p3.pd1 == b1);
+
+ test(b1 != d1);
+ test(b1 != d3);
+ test(b2 != d1);
+ test(b2 != d3);
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("remainder unmarshaling (3 instances)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* p1;
+ TestSlicingObjectsClientB* p2;
+ TestSlicingObjectsClientB* ret = [test paramTest3:&p1 p2:&p2];
+
+ test(p1);
+ test([p1.sb isEqualToString:@"D2.sb (p1 1)"]);
+ test(!p1.pb);
+ test([[p1 ice_id] isEqualToString:@"::Test::B"]);
+
+ test(p2);
+ test([p2.sb isEqualToString:@"D2.sb (p2 1)"]);
+ test(!p2.pb);
+ test([[p2 ice_id] isEqualToString:@"::Test::B"]);
+
+ test(ret);
+ test([ret.sb isEqualToString:@"D1.sb (p2 2)"]);
+ test(!ret.pb);
+ test([[ret ice_id] isEqualToString:@"::Test::D1"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("remainder unmarshaling (3 instances) (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_paramTest3:^(TestSlicingObjectsClientB* o, TestSlicingObjectsClientB* b1, TestSlicingObjectsClientB* b2) { [cb paramTest3Response:o p1:b1 p2:b2]; } exception:^(ICEException* e) { [cb paramTest3Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("remainder unmarshaling (4 instances)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b;
+ TestSlicingObjectsClientB* ret = [test paramTest4:&b];
+
+ test(b);
+ test([b.sb isEqualToString:@"D4.sb (1)"]);
+ test(!b.pb);
+ test([[b ice_id] isEqualToString:@"::Test::B"]);
+
+ test(ret);
+ test([ret.sb isEqualToString:@"B.sb (2)"]);
+ test(!ret.pb);
+ test([[ret ice_id] isEqualToString:@"::Test::B"]);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("remainder unmarshaling (4 instances) (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_paramTest4:^(TestSlicingObjectsClientB* o, TestSlicingObjectsClientB* b) { [cb paramTest4Response:o p1:b]; } exception:^(ICEException* e) { [cb paramTest4Exception:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("param ptr slicing, instance marshaled in unknown derived as base... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b1 = [TestSlicingObjectsClientB b];
+ b1.sb = @"B.sb(1)";
+ b1.pb = b1;
+
+ TestSlicingObjectsClientD3* d3 = [TestSlicingObjectsClientD3 d3];
+ d3.sb = @"D3.sb";
+ d3.pb = d3;
+ d3.sd3 = @"D3.sd3";
+ d3.pd3 = b1;
+
+ TestSlicingObjectsClientB* b2 = [TestSlicingObjectsClientB b];
+ b2.sb = @"B.sb(2)";
+ b2.pb = b1;
+
+ TestSlicingObjectsClientB* r = [test returnTest3:d3 p2:b2];
+
+ test(r);
+ test([[r ice_id] isEqualToString:@"::Test::B"]);
+ test([r.sb isEqualToString:@"D3.sb"]);
+ test(r.pb == r);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("param ptr slicing, instance marshaled in unknown derived as base (AMI)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientB* b1 = [TestSlicingObjectsClientB b];
+ b1.sb = @"B.sb(1)";
+ b1.pb = b1;
+
+ TestSlicingObjectsClientD3* d3 = [TestSlicingObjectsClientD3 d3];
+ d3.sb = @"D3.sb";
+ d3.pb = d3;
+ d3.sd3 = @"D3.sd3";
+ d3.pd3 = b1;
+
+ TestSlicingObjectsClientB* b2 = [TestSlicingObjectsClientB b];
+ b2.sb = @"B.sb(2)";
+ b2.pb = b1;
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_returnTest3:d3 p2:b2 response:^(TestSlicingObjectsClientB* o) { [cb returnTest3Response:o]; } exception:^(ICEException* e) { [cb returnTest3Exception:e]; }];
+ [cb check];
+ TestSlicingObjectsClientB* r = cb.r;
+
+ test(r);
+ test([[r ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([r.sb isEqualToString:@"D3.sb"]);
+ test(r.pb == r);
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("param ptr slicing, instance marshaled in unknown derived as derived... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientD1* d11 = [TestSlicingObjectsClientD1 d1];
+ d11.sb = @"D1.sb(1)";
+ d11.pb = d11;
+ d11.sd1 = @"D1.sd1(1)";
+
+ TestSlicingObjectsClientD3* d3 = [TestSlicingObjectsClientD3 d3];
+ d3.sb = @"D3.sb";
+ d3.pb = d3;
+ d3.sd3 = @"D3.sd3";
+ d3.pd3 = d11;
+
+ TestSlicingObjectsClientD1* d12 = [TestSlicingObjectsClientD1 d1];
+ d12.sb = @"D1.sb(2)";
+ d12.pb = d12;
+ d12.sd1 = @"D1.sd1(2)";
+ d12.pd1 = d11;
+
+ TestSlicingObjectsClientB* r = [test returnTest3:d3 p2:d12];
+ test(r);
+ test([[r ice_id] isEqualToString:@"::Test::B"]);
+ test([r.sb isEqualToString:@"D3.sb"]);
+ test(r.pb == r);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("param ptr slicing, instance marshaled in unknown derived as derived (AMI)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientD1* d11 = [TestSlicingObjectsClientD1 d1];
+ d11.sb = @"D1.sb(1)";
+ d11.pb = d11;
+ d11.sd1 = @"D1.sd1(1)";
+
+ TestSlicingObjectsClientD3* d3 = [TestSlicingObjectsClientD3 d3];
+ d3.sb = @"D3.sb";
+ d3.pb = d3;
+ d3.sd3 = @"D3.sd3";
+ d3.pd3 = d11;
+
+ TestSlicingObjectsClientD1* d12 = [TestSlicingObjectsClientD1 d1];
+ d12.sb = @"D1.sb(2)";
+ d12.pb = d12;
+ d12.sd1 = @"D1.sd1(2)";
+ d12.pd1 = d11;
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_returnTest3:d3 p2:d12 response:^(TestSlicingObjectsClientB* o) { [cb returnTest3Response:o]; } exception:^(ICEException* e) { [cb returnTest3Exception:e]; }];
+ [cb check];
+ TestSlicingObjectsClientB* r = cb.r;
+ test(r);
+ test([[r ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([r.sb isEqualToString:@"D3.sb"]);
+ test(r.pb == r);
+ }
+ @catch(NSException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("sequence slicing... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientSS* ss;
+ {
+ TestSlicingObjectsClientB* ss1b = [TestSlicingObjectsClientB b];
+ ss1b.sb = @"B.sb";
+ ss1b.pb = ss1b;
+
+ TestSlicingObjectsClientD1* ss1d1 = [TestSlicingObjectsClientD1 d1];
+ ss1d1.sb = @"D1.sb";
+ ss1d1.sd1 = @"D1.sd1";
+ ss1d1.pb = ss1b;
+
+ TestSlicingObjectsClientD3* ss1d3 = [TestSlicingObjectsClientD3 d3];
+ ss1d3.sb = @"D3.sb";
+ ss1d3.sd3 = @"D3.sd3";
+ ss1d3.pb = ss1b;
+
+ TestSlicingObjectsClientB* ss2b = [TestSlicingObjectsClientB b];
+ ss2b.sb = @"B.sb";
+ ss2b.pb = ss1b;
+
+ TestSlicingObjectsClientD1* ss2d1 = [TestSlicingObjectsClientD1 d1];
+ ss2d1.sb = @"D1.sb";
+ ss2d1.sd1 = @"D1.sd1";
+ ss2d1.pb = ss2b;
+
+ TestSlicingObjectsClientD3* ss2d3 = [TestSlicingObjectsClientD3 d3];
+ ss2d3.sb = @"D3.sb";
+ ss2d3.sd3 = @"D3.sd3";
+ ss2d3.pb = ss2b;
+
+ ss1d1.pd1 = ss2b;
+ ss1d3.pd3 = ss2d1;
+
+ ss2d1.pd1 = ss1d3;
+ ss2d3.pd3 = ss1d1;
+
+ TestSlicingObjectsClientSS1* ss1 = [TestSlicingObjectsClientSS1 sS1];
+ ss1.s = [TestSlicingObjectsClientMutableBSeq arrayWithCapacity:0];
+ [(TestSlicingObjectsClientMutableBSeq*)ss1.s addObject:ss1b];
+ [(TestSlicingObjectsClientMutableBSeq*)ss1.s addObject:ss1d1];
+ [(TestSlicingObjectsClientMutableBSeq*)ss1.s addObject:ss1d3];
+
+ TestSlicingObjectsClientSS2* ss2 = [TestSlicingObjectsClientSS2 sS2];
+ ss2.s = [TestSlicingObjectsClientMutableBSeq arrayWithCapacity:0];
+ [(TestSlicingObjectsClientMutableBSeq*)ss2.s addObject:ss2b];
+ [(TestSlicingObjectsClientMutableBSeq*)ss2.s addObject:ss2d1];
+ [(TestSlicingObjectsClientMutableBSeq*)ss2.s addObject:ss2d3];
+
+ ss = [test sequenceTest:ss1 p2:ss2];
+ }
+
+ test(ss.c1);
+ TestSlicingObjectsClientB* ss1b = [ss.c1.s objectAtIndex:0];
+ TestSlicingObjectsClientB* ss1d1 = [ss.c1.s objectAtIndex:1];
+ test(ss.c2);
+ TestSlicingObjectsClientB* ss1d3 = [ss.c1.s objectAtIndex:2];
+
+ test(ss.c2);
+ TestSlicingObjectsClientB* ss2b = [ss.c2.s objectAtIndex:0];
+ TestSlicingObjectsClientB* ss2d1 = [ss.c2.s objectAtIndex:1];
+ TestSlicingObjectsClientB* ss2d3 = [ss.c2.s objectAtIndex:2];
+
+ test(ss1b.pb == ss1b);
+ test(ss1d1.pb == ss1b);
+ test(ss1d3.pb == ss1b);
+
+ test(ss2b.pb == ss1b);
+ test(ss2d1.pb == ss2b);
+ test(ss2d3.pb == ss2b);
+
+ test([[ss1b ice_id] isEqualToString:@"::Test::B"]);
+ test([[ss1d1 ice_id] isEqualToString:@"::Test::D1"]);
+ test([[ss1d3 ice_id] isEqualToString:@"::Test::B"]);
+
+ test([[ss2b ice_id] isEqualToString:@"::Test::B"]);
+ test([[ss2d1 ice_id] isEqualToString:@"::Test::D1"]);
+ test([[ss2d3 ice_id] isEqualToString:@"::Test::B"]);
+ }
+ @catch(ICEException*)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("sequence slicing (AMI)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientSS* ss;
+ {
+ TestSlicingObjectsClientB* ss1b = [TestSlicingObjectsClientB b];
+ ss1b.sb = @"B.sb";
+ ss1b.pb = ss1b;
+
+ TestSlicingObjectsClientD1* ss1d1 = [TestSlicingObjectsClientD1 d1];
+ ss1d1.sb = @"D1.sb";
+ ss1d1.sd1 = @"D1.sd1";
+ ss1d1.pb = ss1b;
+
+ TestSlicingObjectsClientD3* ss1d3 = [TestSlicingObjectsClientD3 d3];
+ ss1d3.sb = @"D3.sb";
+ ss1d3.sd3 = @"D3.sd3";
+ ss1d3.pb = ss1b;
+
+ TestSlicingObjectsClientB* ss2b = [TestSlicingObjectsClientB b];
+ ss2b.sb = @"B.sb";
+ ss2b.pb = ss1b;
+
+ TestSlicingObjectsClientD1* ss2d1 = [TestSlicingObjectsClientD1 d1];
+ ss2d1.sb = @"D1.sb";
+ ss2d1.sd1 = @"D1.sd1";
+ ss2d1.pb = ss2b;
+
+ TestSlicingObjectsClientD3* ss2d3 = [TestSlicingObjectsClientD3 d3];
+ ss2d3.sb = @"D3.sb";
+ ss2d3.sd3 = @"D3.sd3";
+ ss2d3.pb = ss2b;
+
+ ss1d1.pd1 = ss2b;
+ ss1d3.pd3 = ss2d1;
+
+ ss2d1.pd1 = ss1d3;
+ ss2d3.pd3 = ss1d1;
+
+ TestSlicingObjectsClientSS1* ss1 = [TestSlicingObjectsClientSS1 sS1];
+ ss1.s = [TestSlicingObjectsClientMutableBSeq array];
+ [(NSMutableArray*)ss1.s addObject:ss1b];
+ [(NSMutableArray*)ss1.s addObject:ss1d1];
+ [(NSMutableArray*)ss1.s addObject:ss1d3];
+
+ TestSlicingObjectsClientSS2* ss2 = [TestSlicingObjectsClientSS2 sS2];
+ ss2.s = [TestSlicingObjectsClientMutableBSeq array];
+ [(NSMutableArray*)ss2.s addObject:ss2b];
+ [(NSMutableArray*)ss2.s addObject:ss2d1];
+ [(NSMutableArray*)ss2.s addObject:ss2d3];
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_sequenceTest:ss1 p2:ss2 response:^(TestSlicingObjectsClientSS* o) { [cb sequenceTestResponse:o]; } exception:^(ICEException* e) { [cb sequenceTestException:e]; }];
+ [cb check];
+ ss = cb.r;
+ }
+
+ test(ss.c1);
+ TestSlicingObjectsClientB* ss1b = [ss.c1.s objectAtIndex:0];
+ TestSlicingObjectsClientB* ss1d1 = [ss.c1.s objectAtIndex:1];
+ test(ss.c2);
+ TestSlicingObjectsClientB* ss1d3 = [ss.c1.s objectAtIndex:2];
+
+ test(ss.c2);
+ TestSlicingObjectsClientB* ss2b = [ss.c2.s objectAtIndex:0];
+ TestSlicingObjectsClientB* ss2d1 = [ss.c2.s objectAtIndex:1];
+ TestSlicingObjectsClientB* ss2d3 = [ss.c2.s objectAtIndex:2];
+
+ test(ss1b.pb == ss1b);
+ test(ss1d1.pb == ss1b);
+ test(ss1d3.pb == ss1b);
+
+ test(ss2b.pb == ss1b);
+ test(ss2d1.pb == ss2b);
+ test(ss2d3.pb == ss2b);
+
+ test([[ss1b ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([[ss1d1 ice_id:nil] isEqualToString:@"::Test::D1"]);
+ test([[ss1d3 ice_id:nil] isEqualToString:@"::Test::B"]);
+
+ test([[ss2b ice_id:nil] isEqualToString:@"::Test::B"]);
+ test([[ss2d1 ice_id:nil] isEqualToString:@"::Test::D1"]);
+ test([[ss2d3 ice_id:nil] isEqualToString:@"::Test::B"]);
+ }
+ @catch(ICEException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("dictionary slicing... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientMutableBDict* bin = [TestSlicingObjectsClientMutableBDict dictionary];
+ TestSlicingObjectsClientMutableBDict* bout;
+ TestSlicingObjectsClientBDict* r;
+ int i;
+ for(i = 0; i < 10; ++i)
+ {
+ TestSlicingObjectsClientD1* d1 = [TestSlicingObjectsClientD1 d1];
+ NSString *s = [@"D1." stringByAppendingString:[NSString stringWithFormat:@"%d", i]];
+ d1.sb = s;
+ d1.pb = d1;
+ d1.sd1 = s;
+ [bin setObject:d1 forKey:[NSNumber numberWithInt:i]];
+ }
+
+ r = [test dictionaryTest:bin bout:&bout];
+
+ test([bout count] == 10);
+ for(i = 0; i < 10; ++i)
+ {
+ TestSlicingObjectsClientB* b = [bout objectForKey:[NSNumber numberWithInt:i * 10]];
+ test(b);
+ NSString *s = [@"D1." stringByAppendingString:[NSString stringWithFormat:@"%d", i]];
+ test([b.sb isEqualToString:s]);
+ test(b.pb);
+ test(b.pb != b);
+ test([b.pb.sb isEqualToString:s]);
+ test(b.pb.pb == b.pb);
+ }
+
+ test([r count] == 10);
+ for(i = 0; i < 10; ++i)
+ {
+ TestSlicingObjectsClientB* b = [r objectForKey:[NSNumber numberWithInt:i * 20]];
+ test(b);
+ NSString *s = [@"D1." stringByAppendingString:[NSString stringWithFormat:@"%d", i * 20]];
+ test([b.sb isEqualToString:s]);
+ test(b.pb == (i == 0 ? nil : [r objectForKey:[NSNumber numberWithInt:(i - 1) * 20]]));
+ test([b isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b;
+ test([d1.sd1 isEqualToString:s]);
+ test(d1.pd1 == d1);
+ }
+ }
+ @catch(ICEException*)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("dictionary slicing (AMI)... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientMutableBDict* bin = [TestSlicingObjectsClientMutableBDict dictionary];
+ TestSlicingObjectsClientMutableBDict* bout;
+ TestSlicingObjectsClientMutableBDict* r;
+ int i;
+ for(i = 0; i < 10; ++i)
+ {
+ TestSlicingObjectsClientD1* d1 = [TestSlicingObjectsClientD1 d1];
+ d1.sb = [NSString stringWithFormat:@"D1.%d",i];
+ d1.pb = d1;
+ d1.sd1 = d1.sb;
+ [bin setObject:d1 forKey:[NSNumber numberWithInt:i]];
+ }
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_dictionaryTest:bin response:^(TestSlicingObjectsClientMutableBDict* o, TestSlicingObjectsClientMutableBDict* bout) { [cb dictionaryTestResponse:o bout:bout]; } exception:^(ICEException* e) { [cb dictionaryTestException:e]; }];
+ [cb check];
+ bout = cb.bout;
+ r = cb.r;
+
+ test([bout count] == 10);
+ for(i = 0; i < 10; ++i)
+ {
+ TestSlicingObjectsClientB* b = [bout objectForKey:[NSNumber numberWithInt:(i * 10)]];
+ test(b);
+ NSString* s = [NSString stringWithFormat:@"D1.%d",i];
+ test([b.sb isEqualToString:s]);
+ test(b.pb);
+ test(b.pb != b);
+ test([b.pb.sb isEqualToString:s]);
+ test(b.pb.pb == b.pb);
+ }
+
+ test([r count] == 10);
+ for(i = 0; i < 10; ++i)
+ {
+ TestSlicingObjectsClientB* b = [r objectForKey:[NSNumber numberWithInt:(i * 20)]];
+ test(b);
+ NSString* s = [NSString stringWithFormat:@"D1.%d",(i * 20)];
+ test([b.sb isEqualToString:s]);
+ test(b.pb == (i == 0 ? nil : [r objectForKey:[NSNumber numberWithInt:((i - 1) * 20)]]));
+ test([b isKindOfClass:[TestSlicingObjectsClientD1 class]]);
+ TestSlicingObjectsClientD1* d1 = (TestSlicingObjectsClientD1*)b;
+ test([d1.sd1 isEqualToString:s]);
+ test(d1.pd1 == d1);
+ }
+ }
+ @catch(ICEException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("base exception thrown as base exception... ");
+ {
+ @try
+ {
+ [test throwBaseAsBase];
+ test(0);
+ }
+ @catch(TestSlicingObjectsClientBaseException* e)
+ {
+ test([[e ice_name] isEqualToString: @"Test::BaseException"]);
+ test([e.sbe isEqualToString:@"sbe"]);
+ test(e.pb);
+ test([e.pb.sb isEqualToString:@"sb"]);
+ test(e.pb.pb == e.pb);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("base exception thrown as base exception (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_throwBaseAsBase:^ { [cb throwBaseAsBaseResponse]; } exception:^(ICEException* e) { [cb throwBaseAsBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("derived exception thrown as base exception... ");
+ {
+ @try
+ {
+ [test throwDerivedAsBase];
+ test(0);
+ }
+ @catch(TestSlicingObjectsClientDerivedException* e)
+ {
+ test([[e ice_name] isEqualToString:@"Test::DerivedException"]);
+ test([e.sbe isEqualToString:@"sbe"]);
+ test(e.pb);
+ test([e.pb.sb isEqualToString:@"sb1"]);
+ test(e.pb.pb == e.pb);
+ test([e.sde isEqualToString:@"sde1"]);
+ test(e.pd1);
+ test([e.pd1.sb isEqualToString:@"sb2"]);
+ test(e.pd1.pb == e.pd1);
+ test([e.pd1.sd1 isEqualToString:@"sd2"]);
+ test(e.pd1.pd1 == e.pd1);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("derived exception thrown as base exception (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_throwDerivedAsBase:^ { [cb throwDerivedAsBaseResponse]; } exception:^(ICEException* e) { [cb throwDerivedAsBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("derived exception thrown as derived exception... ");
+ {
+ @try
+ {
+ [test throwDerivedAsDerived];
+ test(0);
+ }
+ @catch(TestSlicingObjectsClientDerivedException* e)
+ {
+ test([[e ice_name] isEqualToString:@"Test::DerivedException"]);
+ test([e.sbe isEqualToString:@"sbe"]);
+ test(e.pb);
+ test([e.pb.sb isEqualToString:@"sb1"]);
+ test(e.pb.pb == e.pb);
+ test([e.sde isEqualToString:@"sde1"]);
+ test(e.pd1);
+ test([e.pd1.sb isEqualToString:@"sb2"]);
+ test(e.pd1.pb == e.pd1);
+ test([e.pd1.sd1 isEqualToString:@"sd2"]);
+ test(e.pd1.pd1 == e.pd1);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("derived exception thrown as derived exception (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_throwDerivedAsDerived:^ { [cb throwDerivedAsDerivedResponse]; } exception:^(ICEException* e) { [cb throwDerivedAsDerivedException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("unknown derived exception thrown as base exception... ");
+ {
+ @try
+ {
+ [test throwUnknownDerivedAsBase];
+ test(0);
+ }
+ @catch(TestSlicingObjectsClientBaseException* e)
+ {
+ test([[e ice_name] isEqualToString:@"Test::BaseException"]);
+ test([e.sbe isEqualToString:@"sbe"]);
+ test(e.pb);
+ test([e.pb.sb isEqualToString:@"sb d2"]);
+ test(e.pb.pb == e.pb);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("unknown derived exception thrown as base exception (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_throwUnknownDerivedAsBase:^ { [cb throwUnknownDerivedAsBaseResponse]; } exception:^(ICEException* e) { [cb throwUnknownDerivedAsBaseException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("forward-declared class... ");
+ {
+ @try
+ {
+ TestSlicingObjectsClientForward* f;
+ [test useForward:&f];
+ test(f);
+ }
+ @catch(...)
+ {
+ test(0);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("forward-declared class (AMI)... ");
+ {
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_useForward:^(TestSlicingObjectsClientForward* o) { [cb useForwardResponse:o]; } exception:^(ICEException* e) { [cb useForwardException:e]; }];
+ [cb check];
+ }
+ tprintf("ok\n");
+
+ tprintf("preserved classes... ");
+ @try
+ {
+ //
+ // Server knows the most-derived class PDerived.
+ //
+ TestSlicingObjectsClientPDerived* pd = [TestSlicingObjectsClientPDerived pDerived];
+ pd.pi = 3;
+ pd.ps = @"preserved";
+ pd.pb = pd;
+
+ TestSlicingObjectsClientPBase* r = [test exchangePBase:pd];
+ TestSlicingObjectsClientPDerived* p2 = (TestSlicingObjectsClientPDerived*)r;
+ test(p2);
+ test(p2.pi == 3);
+ test([p2.ps isEqual:@"preserved"]);
+ test(p2.pb == p2);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+
+ @try
+ {
+ //
+ // Server only knows the base (non-preserved) type, so the object is sliced.
+ //
+ TestSlicingObjectsClientPCUnknown* pu = [TestSlicingObjectsClientPCUnknown pCUnknown];
+ pu.pi = 3;
+ pu.pu = @"preserved";
+
+ TestSlicingObjectsClientPBase* r = [test exchangePBase:pu];
+ test(![r isKindOfClass:[TestSlicingObjectsClientPCUnknown class]]);
+ test(r.pi == 3);
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+
+ @try
+ {
+ //
+ // Server only knows the intermediate type Preserved. The object will be sliced to
+ // Preserved for the 1.0 encoding; otherwise it should be returned intact.
+ //
+ TestSlicingObjectsClientPCDerived* pcd = [TestSlicingObjectsClientPCDerived pCDerived];
+ pcd.pi = 3;
+ pcd.pbs = [NSArray arrayWithObjects:pcd, nil];
+
+ TestSlicingObjectsClientPBase* r = [test exchangePBase:pcd];
+
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ test(![r isKindOfClass:[TestSlicingObjectsClientPCDerived class]]);
+ test(r.pi == 3);
+ }
+ else
+ {
+ test([r isKindOfClass:[TestSlicingObjectsClientPCDerived class]]);
+ TestSlicingObjectsClientPCDerived* p2 = (TestSlicingObjectsClientPCDerived*)r;
+ test(p2);
+ test(p2.pi == 3);
+ test([[[p2 pbs] objectAtIndex:0] isEqual:p2]);
+ }
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+
+ @try
+ {
+ //
+ // Server only knows the intermediate type CompactPDerived. The object will be sliced to
+ // CompactPDerived for the 1.0 encoding; otherwise it should be returned intact.
+ //
+ TestSlicingObjectsClientCompactPCDerived* pcd = [TestSlicingObjectsClientCompactPCDerived compactPCDerived];
+ pcd.pi = 3;
+ pcd.pbs = [NSArray arrayWithObjects:pcd, nil];
+
+ TestSlicingObjectsClientPBase* r = [test exchangePBase:pcd];
+
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ test(![r isKindOfClass:[TestSlicingObjectsClientCompactPCDerived class]]);
+ test(r.pi == 3);
+ }
+ else
+ {
+ test([r isKindOfClass:[TestSlicingObjectsClientCompactPCDerived class]]);
+ TestSlicingObjectsClientCompactPCDerived* p2 = (TestSlicingObjectsClientCompactPCDerived*)r;
+ test(p2);
+ test(p2.pi == 3);
+ test([p2.pbs objectAtIndex:0] == p2);
+ }
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+
+ @try
+ {
+ //
+ // Send an object that will have multiple preserved slices in the server.
+ // The object will be sliced to Preserved for the 1.0 encoding.
+ //
+ TestSlicingObjectsClientPCDerived3* pcd = [TestSlicingObjectsClientPCDerived3 pCDerived3];
+ pcd.pi = 3;
+ //
+ // Sending more than 254 objects exercises the encoding for object ids.
+ //
+ int i;
+ pcd.pbs = [NSArray array];
+ for(i = 0; i < 300; ++i)
+ {
+ TestSlicingObjectsClientPCDerived2* p2 = [TestSlicingObjectsClientPCDerived2 pCDerived2];
+ p2.pi = i;
+ p2.pbs = [NSArray arrayWithObjects:[NSNull null], nil]; // Nil reference. This slice should not have an indirection table.
+ p2.pcd2 = i;
+ pcd.pbs = [pcd.pbs arrayByAddingObject:p2];
+ }
+ pcd.pcd2 = pcd.pi;
+ pcd.pcd3 = [pcd.pbs objectAtIndex:10];
+
+ TestSlicingObjectsClientPBase* r = [test exchangePBase:pcd];
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ test(![r isKindOfClass:[TestSlicingObjectsClientPCDerived3 class]]);
+ test([r isKindOfClass:[TestSlicingObjectsClientPreserved class]]);
+ test(r.pi == 3);
+ }
+ else
+ {
+ test([r isKindOfClass:[TestSlicingObjectsClientPCDerived3 class]]);
+ TestSlicingObjectsClientPCDerived3* p3 = (TestSlicingObjectsClientPCDerived3*)r;
+ test(p3.pi == 3);
+ for(i = 0; i < 300; ++i)
+ {
+ TestSlicingObjectsClientPCDerived2* p2 = (TestSlicingObjectsClientPCDerived2*)[p3.pbs objectAtIndex:i];
+ test(p2.pi == i);
+ test([p2.pbs count] == 1);
+ test([[p2.pbs objectAtIndex:0] isEqual:[NSNull null]]);
+ test(p2.pcd2 == i);
+ }
+ test(p3.pcd2 == p3.pi);
+ test(p3.pcd3 == [p3.pbs objectAtIndex:10]);
+ }
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+
+ @try
+ {
+ //
+ // Obtain an object with preserved slices and send it back to the server.
+ // The preserved slices should be excluded for the 1.0 encoding, otherwise
+ // they should be included.
+ //
+ TestSlicingObjectsClientPreserved* p = [test PBSUnknownAsPreserved];
+ [test checkPBSUnknown:p];
+ if(![[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ [[test ice_encodingVersion:ICEEncoding_1_0] checkPBSUnknown:p];
+ }
+ }
+ @catch(ICEOperationNotExistException*)
+ {
+ }
+
+ tprintf("ok\n");
+
+ tprintf("preserved classes (AMI)... ");
+ {
+ //
+ // Server knows the most-derived class PDerived.
+ //
+ TestSlicingObjectsClientPDerived* pd = [TestSlicingObjectsClientPDerived pDerived];
+ pd.pi = 3;
+ pd.ps = @"preserved";
+ pd.pb = pd;
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_exchangePBase:pd
+ response:^(TestSlicingObjectsClientPBase* o) { [cb responsePreserved1:o]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ [cb check];
+ }
+
+ {
+ TestSlicingObjectsClientPCUnknown* pu = [TestSlicingObjectsClientPCUnknown pCUnknown];
+ pu.pi = 3;
+ pu.pu = @"preserved";
+
+ //
+ // Server only knows the base (non-preserved) type, so the object is sliced.
+ //
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ [test begin_exchangePBase:pu
+ response:^(TestSlicingObjectsClientPBase* o) { [cb responsePreserved2:o]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ [cb check];
+ }
+
+ {
+ //
+ // Server only knows the intermediate type Preserved. The object will be sliced to
+ // Preserved for the 1.0 encoding; otherwise it should be returned intact.
+ //
+ TestSlicingObjectsClientPCDerived* pcd = [TestSlicingObjectsClientPCDerived pCDerived];
+ pcd.pi = 3;
+ pcd.pbs = [NSArray arrayWithObjects:pcd, nil];
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ [test begin_exchangePBase:pcd
+ response:^(TestSlicingObjectsClientPBase* o) { [cb responsePreserved3:o]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ }
+ else
+ {
+ [test begin_exchangePBase:pcd
+ response:^(TestSlicingObjectsClientPBase* o) { [cb responsePreserved4:o]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ }
+ [cb check];
+ }
+
+ {
+ //
+ // Server only knows the intermediate type CompactPDerived. The object will be sliced to
+ // CompactPDerived for the 1.0 encoding; otherwise it should be returned intact.
+ //
+ TestSlicingObjectsClientCompactPCDerived* pcd = [TestSlicingObjectsClientCompactPCDerived compactPCDerived];
+ pcd.pi = 3;
+ pcd.pbs = [NSArray arrayWithObjects:pcd, nil];
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ [test begin_exchangePBase:pcd
+ response:^(TestSlicingObjectsClientPBase* o) { [cb responseCompactPreserved1:o]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ }
+ else
+ {
+ [test begin_exchangePBase:pcd
+ response:^(TestSlicingObjectsClientPBase* o) { [cb responseCompactPreserved2:o]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ }
+ [cb check];
+ }
+
+ {
+ //
+ // Send an object that will have multiple preserved slices in the server.
+ // The object will be sliced to Preserved for the 1.0 encoding.
+ //
+ TestSlicingObjectsClientPCDerived3* pcd = [TestSlicingObjectsClientPCDerived3 pCDerived3];
+ pcd.pi = 3;
+
+ //
+ // Sending more than 254 objects exercises the encoding for object ids.
+ //
+ int i;
+ pcd.pbs = [NSArray array];
+ for(i = 0; i < 300; ++i)
+ {
+ TestSlicingObjectsClientPCDerived2* p2 = [TestSlicingObjectsClientPCDerived2 pCDerived2];
+ p2.pi = i;
+ p2.pbs = [NSArray arrayWithObjects:[NSNull null], nil]; // Nil reference. This slice should not have an indirection table.
+ p2.pcd2 = i;
+ pcd.pbs = [pcd.pbs arrayByAddingObject:p2];
+ }
+ pcd.pcd2 = pcd.pi;
+ pcd.pcd3 = [pcd.pbs objectAtIndex:10];
+
+ TestSlicingObjectsClientCallback* cb = [TestSlicingObjectsClientCallback create];
+ if([[test ice_getEncodingVersion] isEqual:ICEEncoding_1_0])
+ {
+ [test begin_exchangePBase:pcd
+ response:^(TestSlicingObjectsClientPBase* o) { [cb responsePreserved3:o]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ }
+ else
+ {
+ [test begin_exchangePBase:pcd
+ response:^(TestSlicingObjectsClientPBase* o) { [cb responsePreserved5:o]; }
+ exception:^(ICEException* ex) { [cb exception:ex]; }];
+ }
+ [cb check];
+ }
+
+ tprintf("ok\n");
+
+ return test;
+}
diff --git a/objc/test/Ice/slicing/objects/Client.m b/objc/test/Ice/slicing/objects/Client.m
new file mode 100644
index 00000000000..89fe3a4e165
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/Client.m
@@ -0,0 +1,77 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <SlicingObjectsTestClient.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestSlicingObjectsClientTestIntfPrx> slicingObjectsAllTests(id<ICECommunicator>);
+ id<TestSlicingObjectsClientTestIntfPrx> TestSlicingObjectsClient = slicingObjectsAllTests(communicator);
+ [TestSlicingObjectsClient shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main slicingObjectsClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestSlicingObjectsClient", @"::Test",
+ @"TestSlicingObjectsShared", @"::TestShared",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/slicing/objects/Makefile b/objc/test/Ice/slicing/objects/Makefile
new file mode 100644
index 00000000000..12373f955af
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/Makefile
@@ -0,0 +1,45 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = SlicingObjectsTestClient.o \
+ SlicingObjectsForwardClient.o \
+ SlicingObjectsTestServer.o \
+ SlicingObjectsForwardServer.o
+
+COBJS = SlicingObjectsTestClient.o \
+ SlicingObjectsForwardClient.o \
+ Client.o \
+ AllTests.o
+
+SOBJS = SlicingObjectsTestServer.o \
+ SlicingObjectsForwardServer.o \
+ TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../.. -I../../../include $(CPPFLAGS)
+SLICE2OBJCFLAGS := -I. $(SLICE2OBJCFLAGS)
+
+$(CLIENT): $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/slicing/objects/Server.m b/objc/test/Ice/slicing/objects/Server.m
new file mode 100644
index 00000000000..73d4eb89bf0
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/Server.m
@@ -0,0 +1,85 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <slicing/objects/TestI.h>
+#include <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<ICEProperties> properties = [communicator getProperties];
+ [properties setProperty:@"Ice.Warn.Dispatch" value:@"0"];
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+ ICEObject* object = [[TestSlicingObjectsServerI alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [object autorelease];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"Test"]];
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main slicingObjectsServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestSlicingObjectsServer", @"::Test",
+ @"TestSlicingObjectsShared", @"::TestShared",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/slicing/objects/SlicingObjectsForwardClient.ice b/objc/test/Ice/slicing/objects/SlicingObjectsForwardClient.ice
new file mode 100644
index 00000000000..f472b42ef9e
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/SlicingObjectsForwardClient.ice
@@ -0,0 +1,28 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestSlicingObjectsClient"]
+module Test
+{
+
+class Forward;
+
+class Hidden
+{
+ Forward f;
+};
+
+class Forward
+{
+ Hidden h;
+};
+
+};
diff --git a/objc/test/Ice/slicing/objects/SlicingObjectsForwardServer.ice b/objc/test/Ice/slicing/objects/SlicingObjectsForwardServer.ice
new file mode 100644
index 00000000000..ea21fd37f2d
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/SlicingObjectsForwardServer.ice
@@ -0,0 +1,28 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestSlicingObjectsServer"]
+module Test
+{
+
+class Forward;
+
+class Hidden
+{
+ Forward f;
+};
+
+class Forward
+{
+ Hidden h;
+};
+
+};
diff --git a/objc/test/Ice/slicing/objects/SlicingObjectsTestClient.ice b/objc/test/Ice/slicing/objects/SlicingObjectsTestClient.ice
new file mode 100644
index 00000000000..f8145e5566e
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/SlicingObjectsTestClient.ice
@@ -0,0 +1,196 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestSlicingObjectsClient"]
+module Test
+{
+
+class SBase
+{
+ string sb;
+};
+
+class SBSKnownDerived extends SBase
+{
+ string sbskd;
+};
+
+class B
+{
+ string sb;
+ B pb;
+};
+
+class D1 extends B
+{
+ string sd1;
+ B pd1;
+};
+
+sequence<B> BSeq;
+
+class SS1
+{
+ BSeq s;
+};
+
+class SS2
+{
+ BSeq s;
+};
+
+struct SS
+{
+ SS1 c1;
+ SS2 c2;
+};
+
+dictionary<int, B> BDict;
+
+exception BaseException
+{
+ string sbe;
+ B pb;
+};
+
+exception DerivedException extends BaseException
+{
+ string sde;
+ D1 pd1;
+};
+
+class Forward; /* Forward-declared class defined in another compilation unit */
+
+class PBase
+{
+ int pi;
+};
+
+sequence<PBase> PBaseSeq;
+
+["preserve-slice"]
+class Preserved extends PBase
+{
+ string ps;
+};
+
+class PDerived extends Preserved
+{
+ PBase pb;
+};
+
+class CompactPDerived(56) extends Preserved
+{
+ PBase pb;
+};
+
+["preserve-slice"]
+class PNode
+{
+ PNode next;
+};
+
+["preserve-slice"]
+exception PreservedException
+{
+};
+
+["preserve-slice"]
+class PCUnknown extends PBase
+{
+ string pu;
+};
+
+class PCDerived extends PDerived
+{
+ PBaseSeq pbs;
+};
+
+class PCDerived2 extends PCDerived
+{
+ int pcd2;
+};
+
+class PCDerived3 extends PCDerived2
+{
+ Object pcd3;
+};
+
+class CompactPCDerived(57) extends CompactPDerived
+{
+ PBaseSeq pbs;
+};
+
+["format:sliced"] interface TestIntf
+{
+ Object SBaseAsObject();
+ SBase SBaseAsSBase();
+ SBase SBSKnownDerivedAsSBase();
+ SBSKnownDerived SBSKnownDerivedAsSBSKnownDerived();
+
+ SBase SBSUnknownDerivedAsSBase();
+ ["format:compact"] SBase SBSUnknownDerivedAsSBaseCompact();
+
+ Object SUnknownAsObject();
+ void checkSUnknown(Object o);
+
+ B oneElementCycle();
+ B twoElementCycle();
+ B D1AsB();
+ D1 D1AsD1();
+ B D2AsB();
+
+ void paramTest1(out B p1, out B p2);
+ void paramTest2(out B p2, out B p1);
+ B paramTest3(out B p1, out B p2);
+ B paramTest4(out B p);
+
+ B returnTest1(out B p1, out B p2);
+ B returnTest2(out B p2, out B p1);
+ B returnTest3(B p1, B p2);
+
+ SS sequenceTest(SS1 p1, SS2 p2);
+
+ BDict dictionaryTest(BDict bin, out BDict bout);
+
+ PBase exchangePBase(PBase pb);
+
+ Preserved PBSUnknownAsPreserved();
+ void checkPBSUnknown(Preserved p);
+
+ Preserved PBSUnknownAsPreservedWithGraph();
+ void checkPBSUnknownWithGraph(Preserved p);
+
+ Preserved PBSUnknown2AsPreservedWithGraph();
+ void checkPBSUnknown2WithGraph(Preserved p);
+
+ PNode exchangePNode(PNode pn);
+
+ void throwBaseAsBase() throws BaseException;
+ void throwDerivedAsBase() throws BaseException;
+ void throwDerivedAsDerived() throws DerivedException;
+ void throwUnknownDerivedAsBase() throws BaseException;
+ ["amd"] void throwPreservedException() throws PreservedException;
+
+ void useForward(out Forward f); // Use of forward-declared class to verify that code is generated correctly.
+
+ void shutdown();
+};
+
+// Things private to the client.
+
+class D3 extends B
+{
+ string sd3;
+ B pd3;
+};
+
+};
diff --git a/objc/test/Ice/slicing/objects/SlicingObjectsTestServer.ice b/objc/test/Ice/slicing/objects/SlicingObjectsTestServer.ice
new file mode 100644
index 00000000000..e3e09fa6781
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/SlicingObjectsTestServer.ice
@@ -0,0 +1,215 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestSlicingObjectsServer"]
+module Test
+{
+
+class SBase
+{
+ string sb;
+};
+
+class SBSKnownDerived extends SBase
+{
+ string sbskd;
+};
+
+class B
+{
+ string sb;
+ B pb;
+};
+
+class D1 extends B
+{
+ string sd1;
+ B pd1;
+};
+
+sequence<B> BSeq;
+
+class SS1
+{
+ BSeq s;
+};
+
+class SS2
+{
+ BSeq s;
+};
+
+struct SS
+{
+ SS1 c1;
+ SS2 c2;
+};
+
+dictionary<int, B> BDict;
+
+exception BaseException
+{
+ string sbe;
+ B pb;
+};
+
+exception DerivedException extends BaseException
+{
+ string sde;
+ D1 pd1;
+};
+
+class Forward; /* Forward-declared class defined in another compilation unit */
+
+class PBase
+{
+ int pi;
+};
+
+sequence<PBase> PBaseSeq;
+
+["preserve-slice"]
+class Preserved extends PBase
+{
+ string ps;
+};
+
+class PDerived extends Preserved
+{
+ PBase pb;
+};
+
+class CompactPDerived(56) extends Preserved
+{
+ PBase pb;
+};
+
+["preserve-slice"]
+class PNode
+{
+ PNode next;
+};
+
+class MyClass
+{
+ int i;
+};
+
+class PSUnknown extends Preserved
+{
+ string psu;
+ PNode graph;
+ MyClass cl;
+};
+
+class PSUnknown2 extends Preserved
+{
+ PBase pb;
+};
+
+["preserve-slice"]
+exception PreservedException
+{
+};
+
+exception PSUnknownException extends PreservedException
+{
+ PSUnknown2 p;
+};
+
+["format:sliced"] interface TestIntf
+{
+ Object SBaseAsObject();
+ SBase SBaseAsSBase();
+ SBase SBSKnownDerivedAsSBase();
+ SBSKnownDerived SBSKnownDerivedAsSBSKnownDerived();
+
+ SBase SBSUnknownDerivedAsSBase();
+ ["format:compact"] SBase SBSUnknownDerivedAsSBaseCompact();
+
+ Object SUnknownAsObject();
+ void checkSUnknown(Object o);
+
+ B oneElementCycle();
+ B twoElementCycle();
+ B D1AsB();
+ D1 D1AsD1();
+ B D2AsB();
+
+ void paramTest1(out B p1, out B p2);
+ void paramTest2(out B p2, out B p1);
+ B paramTest3(out B p1, out B p2);
+ B paramTest4(out B p);
+
+ B returnTest1(out B p1, out B p2);
+ B returnTest2(out B p2, out B p1);
+ B returnTest3(B p1, B p2);
+
+ SS sequenceTest(SS1 p1, SS2 p2);
+
+ BDict dictionaryTest(BDict bin, out BDict bout);
+
+ PBase exchangePBase(PBase pb);
+
+ Preserved PBSUnknownAsPreserved();
+ void checkPBSUnknown(Preserved p);
+
+ Preserved PBSUnknownAsPreservedWithGraph();
+ void checkPBSUnknownWithGraph(Preserved p);
+
+ Preserved PBSUnknown2AsPreservedWithGraph();
+ void checkPBSUnknown2WithGraph(Preserved p);
+
+ PNode exchangePNode(PNode pn);
+
+ void throwBaseAsBase() throws BaseException;
+ void throwDerivedAsBase() throws BaseException;
+ void throwDerivedAsDerived() throws DerivedException;
+ void throwUnknownDerivedAsBase() throws BaseException;
+ ["amd"] void throwPreservedException() throws PreservedException;
+
+ void useForward(out Forward f); // Use of forward-declared class to verify that code is generated correctly.
+
+ void shutdown();
+};
+
+
+// Things private to the server.
+
+class SBSUnknownDerived extends SBase
+{
+ string sbsud;
+};
+
+class SUnknown
+{
+ string su;
+};
+
+class D2 extends B
+{
+ string sd2;
+ B pd2;
+};
+
+class D4 extends B
+{
+ B p1;
+ B p2;
+};
+
+exception UnknownDerivedException extends BaseException
+{
+ string sude;
+ D2 pd2;
+};
+
+};
diff --git a/objc/test/Ice/slicing/objects/TestI.h b/objc/test/Ice/slicing/objects/TestI.h
new file mode 100644
index 00000000000..208d8d02c6a
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/TestI.h
@@ -0,0 +1,18 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <SlicingObjectsTestServer.h>
+#import <SlicingObjectsForwardServer.h>
+
+@interface TestSlicingObjectsServerI : TestSlicingObjectsServerTestIntf<TestSlicingObjectsServerTestIntf>
+{
+@private
+ TestSlicingObjectsServerPSUnknownException* ex_;
+}
+@end
diff --git a/objc/test/Ice/slicing/objects/TestI.m b/objc/test/Ice/slicing/objects/TestI.m
new file mode 100644
index 00000000000..8e42d431a92
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/TestI.m
@@ -0,0 +1,539 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <slicing/objects/TestI.h>
+#import <TestCommon.h>
+
+@implementation TestSlicingObjectsServerI
+-(ICEObject*) SBaseAsObject:(ICECurrent*)current
+{
+ return [TestSlicingObjectsServerSBase sBase:@"SBase.sb"];
+}
+
+-(TestSlicingObjectsServerSBase*) SBaseAsSBase:(ICECurrent*)current
+{
+ return [TestSlicingObjectsServerSBase sBase:@"SBase.sb"];
+}
+
+-(TestSlicingObjectsServerSBase*) SBSKnownDerivedAsSBase:(ICECurrent*)current
+{
+ return [TestSlicingObjectsServerSBSKnownDerived sBSKnownDerived:@"SBSKnownDerived.sb"
+ sbskd:@"SBSKnownDerived.sbskd"];
+}
+
+-(TestSlicingObjectsServerSBSKnownDerived*) SBSKnownDerivedAsSBSKnownDerived:(ICECurrent*)current
+{
+ return [TestSlicingObjectsServerSBSKnownDerived sBSKnownDerived:@"SBSKnownDerived.sb"
+ sbskd:@"SBSKnownDerived.sbskd"];
+}
+
+-(TestSlicingObjectsServerSBase*) SBSUnknownDerivedAsSBase:(ICECurrent*)current
+{
+ return [TestSlicingObjectsServerSBSUnknownDerived sBSUnknownDerived:@"SBSUnknownDerived.sb"
+ sbsud:@"SBSUnknownDerived.sbsud"];
+}
+
+-(TestSlicingObjectsServerSBase*) SBSUnknownDerivedAsSBaseCompact:(ICECurrent*)current
+{
+ return [TestSlicingObjectsServerSBSUnknownDerived sBSUnknownDerived:@"SBSUnknownDerived.sb"
+ sbsud:@"SBSUnknownDerived.sbsud"];
+}
+
+-(ICEObject*) SUnknownAsObject:(ICECurrent*)current
+{
+ return [TestSlicingObjectsServerSUnknown sUnknown:@"SUnknown.su"];
+}
+
+-(void) checkSUnknown:(ICEObject*) object current:(ICECurrent*)current
+{
+ if([current encoding] == ICEEncoding_1_0)
+ {
+ test(![object isKindOfClass:[TestSlicingObjectsServerSUnknown class]]);
+ }
+ else
+ {
+ test([object isKindOfClass:[TestSlicingObjectsServerSUnknown class]]);
+ TestSlicingObjectsServerSUnknown* su = (TestSlicingObjectsServerSUnknown*)object;
+ test([[su su] isEqual:@"SUnknown.su"]);
+ }
+}
+
+-(TestSlicingObjectsServerB*) oneElementCycle:(ICECurrent*)current
+{
+ TestSlicingObjectsServerB* b1 = [[TestSlicingObjectsServerB alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [b1 autorelease];
+#endif
+ b1.sb = @"B1.sb";
+ b1.pb = b1;
+ return b1;
+}
+-(TestSlicingObjectsServerB*) twoElementCycle:(ICECurrent*)current
+{
+ TestSlicingObjectsServerB* b1 = [[TestSlicingObjectsServerB alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [b1 autorelease];
+#endif
+ b1.sb = @"B1.sb";
+ TestSlicingObjectsServerB* b2 = [[TestSlicingObjectsServerB alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [b2 autorelease];
+#endif
+ b2.sb = @"B2.sb";
+ b2.pb = b1;
+ b1.pb = b2;
+ return b1;
+}
+-(TestSlicingObjectsServerB*) D1AsB:(ICECurrent*)current
+{
+ TestSlicingObjectsServerD1* d1 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d1 autorelease];
+#endif
+ d1.sb = @"D1.sb";
+ d1.sd1 = @"D1.sd1";
+
+ TestSlicingObjectsServerD2* d2 = [[TestSlicingObjectsServerD2 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d2 autorelease];
+#endif
+ d2.pb = d1;
+ d2.sb = @"D2.sb";
+ d2.sd2 = @"D2.sd2";
+ d2.pd2 = d1;
+ d1.pb = d2;
+ d1.pd1 = d2;
+ return d1;
+}
+-(TestSlicingObjectsServerD1*) D1AsD1:(ICECurrent*)current
+{
+ TestSlicingObjectsServerD1* d1 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d1 autorelease];
+#endif
+ d1.sb = @"D1.sb";
+ d1.sd1 = @"D1.sd1";
+ TestSlicingObjectsServerD2* d2 = [[TestSlicingObjectsServerD2 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d2 autorelease];
+#endif
+ d2.pb = d1;
+ d2.sb = @"D2.sb";
+ d2.sd2 = @"D2.sd2";
+ d2.pd2 = d1;
+ d1.pb = d2;
+ d1.pd1 = d2;
+ return d1;
+}
+-(TestSlicingObjectsServerB*) D2AsB:(ICECurrent*)current
+{
+ TestSlicingObjectsServerD2* d2 = [[TestSlicingObjectsServerD2 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d2 autorelease];
+#endif
+ d2.sb = @"D2.sb";
+ d2.sd2 = @"D2.sd2";
+ TestSlicingObjectsServerD1* d1 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d1 autorelease];
+#endif
+ d1.pb = d2;
+ d1.sb = @"D1.sb";
+ d1.sd1 = @"D1.sd1";
+ d1.pd1 = d2;
+ d2.pb = d1;
+ d2.pd2 = d1;
+ return d2;
+}
+-(void) paramTest1:(TestSlicingObjectsServerB**)p1 p2:(TestSlicingObjectsServerB**)p2 current:(ICECurrent*)current
+{
+ TestSlicingObjectsServerD1* d1 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d1 autorelease];
+#endif
+ d1.sb = @"D1.sb";
+ d1.sd1 = @"D1.sd1";
+ TestSlicingObjectsServerD2* d2 = [[TestSlicingObjectsServerD2 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d2 autorelease];
+#endif
+ d2.pb = d1;
+ d2.sb = @"D2.sb";
+ d2.sd2 = @"D2.sd2";
+ d2.pd2 = d1;
+ d1.pb = d2;
+ d1.pd1 = d2;
+ *p1 = d1;
+ *p2 = d2;
+}
+-(void) paramTest2:(TestSlicingObjectsServerB**)p1 p1:(TestSlicingObjectsServerB**)p2 current:(ICECurrent*)current
+{
+ [self paramTest1:p2 p2:p1 current:current];
+}
+-(TestSlicingObjectsServerB*) paramTest3:(TestSlicingObjectsServerB**)p1 p2:(TestSlicingObjectsServerB**)p2 current:(ICECurrent*)current
+{
+ TestSlicingObjectsServerD2* d2 = [[TestSlicingObjectsServerD2 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d2 autorelease];
+#endif
+ d2.sb = @"D2.sb (p1 1)";
+ d2.pb = 0;
+ d2.sd2 = @"D2.sd2 (p1 1)";
+ *p1 = d2;
+
+ TestSlicingObjectsServerD1* d1 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d1 autorelease];
+#endif
+ d1.sb = @"D1.sb (p1 2)";
+ d1.pb = 0;
+ d1.sd1 = @"D1.sd2 (p1 2)";
+ d1.pd1 = 0;
+ d2.pd2 = d1;
+
+ TestSlicingObjectsServerD2* d4 = [[TestSlicingObjectsServerD2 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d4 autorelease];
+#endif
+ d4.sb = @"D2.sb (p2 1)";
+ d4.pb = 0;
+ d4.sd2 = @"D2.sd2 (p2 1)";
+ *p2 = d4;
+
+ TestSlicingObjectsServerD1* d3 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d3 autorelease];
+#endif
+ d3.sb = @"D1.sb (p2 2)";
+ d3.pb = 0;
+ d3.sd1 = @"D1.sd2 (p2 2)";
+ d3.pd1 = 0;
+ d4.pd2 = d3;
+
+ return d3;
+}
+-(TestSlicingObjectsServerB*) paramTest4:(TestSlicingObjectsServerB**)p1 current:(ICECurrent*)current
+{
+ TestSlicingObjectsServerD4* d4 = [[TestSlicingObjectsServerD4 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d4 autorelease];
+#endif
+ d4.sb = @"D4.sb (1)";
+ d4.pb = 0;
+ d4.p1 = [[TestSlicingObjectsServerB alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d4.p1 autorelease];
+#endif
+ d4.p1.sb = @"B.sb (1)";
+ d4.p2 = [[TestSlicingObjectsServerB alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d4.p2 autorelease];
+#endif
+ d4.p2.sb = @"B.sb (2)";
+ *p1 = d4;
+ return d4.p2;
+}
+-(TestSlicingObjectsServerB*) returnTest1:(TestSlicingObjectsServerB**)p1 p2:(TestSlicingObjectsServerB**)p2 current:(ICECurrent*)current
+{
+ [self paramTest1:p1 p2:p2 current:current];
+ return *p1;
+}
+-(TestSlicingObjectsServerB*) returnTest2:(TestSlicingObjectsServerB**)p1 p1:(TestSlicingObjectsServerB**)p2 current:(ICECurrent*)current
+{
+ [self paramTest1:p2 p2:p1 current:current];
+ return *p1;
+}
+-(TestSlicingObjectsServerB*) returnTest3:(TestSlicingObjectsServerB*)p1 p2:(TestSlicingObjectsServerB*)p2 current:(ICECurrent*)current
+{
+ return p1;
+}
+-(TestSlicingObjectsServerSS*) sequenceTest:(TestSlicingObjectsServerSS1*)p1 p2:(TestSlicingObjectsServerSS2*)p2 current:(ICECurrent*)current
+{
+ TestSlicingObjectsServerSS* ss = [TestSlicingObjectsServerSS sS];
+ ss.c1 = p1;
+ ss.c2 = p2;
+ return ss;
+}
+-(TestSlicingObjectsServerBDict*) dictionaryTest:(TestSlicingObjectsServerMutableBDict*)bin
+ bout:(TestSlicingObjectsServerBDict**)bout current:(ICECurrent*)current
+{
+ int i;
+ *bout = [TestSlicingObjectsServerMutableBDict dictionary];
+ for(i = 0; i < 10; ++i)
+ {
+ TestSlicingObjectsServerB* b = [bin objectForKey:[NSNumber numberWithInt:i]];
+ TestSlicingObjectsServerD2* d2 = [[TestSlicingObjectsServerD2 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d2 autorelease];
+#endif
+ d2.sb = b.sb;
+ d2.pb = b.pb;
+ d2.sd2 = @"D2";
+ d2.pd2 = d2;
+ [(NSMutableDictionary*)*bout setObject:d2 forKey:[NSNumber numberWithInt:(i * 10)]];
+ }
+ TestSlicingObjectsServerMutableBDict* r = [TestSlicingObjectsServerMutableBDict dictionary];
+ for(i = 0; i < 10; ++i)
+ {
+ TestSlicingObjectsServerD1* d1 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d1 autorelease];
+#endif
+ d1.sb = [NSString stringWithFormat:@"D1.%d",(i * 20)];
+ d1.pb = (i == 0 ? nil : [r objectForKey:[NSNumber numberWithInt:((i - 1) * 20)]]);
+ d1.sd1 = d1.sb;
+ d1.pd1 = d1;
+ [r setObject:d1 forKey:[NSNumber numberWithInt:(i * 20)]];
+ }
+ return r;
+}
+
+-(TestSlicingObjectsServerPBase*) exchangePBase:(TestSlicingObjectsServerPBase*)pb
+ current:(ICECurrent*)current
+{
+ return pb;
+}
+
+-(TestSlicingObjectsServerPreserved*) PBSUnknownAsPreserved:(ICECurrent*)current
+{
+ if([current.encoding isEqual:ICEEncoding_1_0])
+ {
+ //
+ // 1.0 encoding doesn't support unmarshaling unknown classes even if referenced
+ // from unread slice.
+ //
+ return [[TestSlicingObjectsServerPSUnknown alloc] init:5
+ ps:@"preserved"
+ psu:@"unknown"
+ graph:0
+ cl:nil];
+ }
+ else
+ {
+ return [[TestSlicingObjectsServerPSUnknown alloc] init:5
+ ps:@"preserved"
+ psu:@"unknown"
+ graph:0
+ cl:[[TestSlicingObjectsServerMyClass alloc] init:15]];
+ }
+}
+
+-(void) checkPBSUnknown:(TestSlicingObjectsServerPreserved*)p current:(ICECurrent*)current
+{
+ if([current.encoding isEqual:ICEEncoding_1_0])
+ {
+ test(![p isKindOfClass:[TestSlicingObjectsServerPSUnknown class]]);
+ test(p.pi == 5);
+ test([p.ps isEqual:@"preserved"]);
+ }
+ else
+ {
+ test([p isKindOfClass:[TestSlicingObjectsServerPSUnknown class]]);
+ TestSlicingObjectsServerPSUnknown* pu = (TestSlicingObjectsServerPSUnknown*)p;
+ test(pu.pi == 5);
+ test([pu.ps isEqual:@"preserved"]);
+ test([pu.psu isEqual:@"unknown"]);
+ test(!pu.graph);
+ test(pu.cl && pu.cl.i == 15);
+ }
+}
+
+-(TestSlicingObjectsServerPreserved*) PBSUnknownAsPreservedWithGraph:(ICECurrent*)current
+{
+ TestSlicingObjectsServerPSUnknown* r = [TestSlicingObjectsServerPSUnknown alloc];
+ r.pi = 5;
+ r.ps = @"preserved";
+ r.psu = @"unknown";
+ r.graph = [TestSlicingObjectsServerPNode alloc];
+ r.graph.next = [TestSlicingObjectsServerPNode alloc];
+ r.graph.next.next = [TestSlicingObjectsServerPNode alloc];
+ r.graph.next.next.next = r.graph;
+ return r;
+}
+
+-(void) checkPBSUnknownWithGraph:(TestSlicingObjectsServerPreserved*) p current:(ICECurrent*)current
+{
+ if([current.encoding isEqual:ICEEncoding_1_0])
+ {
+ test(![p isKindOfClass:[TestSlicingObjectsServerPSUnknown class]]);
+ test(p.pi == 5);
+ test([p.ps isEqual:@"preserved"]);
+ }
+ else
+ {
+ test([p isKindOfClass:[TestSlicingObjectsServerPSUnknown class]]);
+ TestSlicingObjectsServerPSUnknown* pu = (TestSlicingObjectsServerPSUnknown*)p;
+ test(pu.pi == 5);
+ test([pu.ps isEqual:@"preserved"]);
+ test([pu.psu isEqual:@"unknown"]);
+ test(pu.graph != pu.graph.next);
+ test(pu.graph.next != pu.graph.next.next);
+ test(pu.graph.next.next.next == pu.graph);
+ pu.graph.next.next.next = nil; // Break the cycle.
+ }
+}
+
+-(TestSlicingObjectsServerPreserved*) PBSUnknown2AsPreservedWithGraph:(ICECurrent*)current
+{
+ TestSlicingObjectsServerPSUnknown2* r = [TestSlicingObjectsServerPSUnknown2 alloc];
+ r.pi = 5;
+ r.ps = @"preserved";
+ r.pb = r;
+ return r;
+}
+
+-(void) checkPBSUnknown2WithGraph:(TestSlicingObjectsServerPreserved*) p current:(ICECurrent*)current
+{
+ if([current.encoding isEqual:ICEEncoding_1_0])
+ {
+ test(![p isKindOfClass:[TestSlicingObjectsServerPSUnknown2 class]]);
+ test(p.pi == 5);
+ test([p.ps isEqual:@"preserved"]);
+ }
+ else
+ {
+ test([p isKindOfClass:[TestSlicingObjectsServerPSUnknown2 class]]);
+ TestSlicingObjectsServerPSUnknown2* pu = (TestSlicingObjectsServerPSUnknown2*)p;
+ test(pu.pi == 5);
+ test([pu.ps isEqual:@"preserved"]);
+ test(pu.pb == pu);
+ pu.pb = 0; // Break the cycle.
+ }
+}
+
+-(TestSlicingObjectsServerPNode*) exchangePNode:(TestSlicingObjectsServerPNode*)pn current:(ICECurrent*)current
+{
+ return pn;
+}
+
+-(void) throwBaseAsBase:(ICECurrent*)current
+{
+ TestSlicingObjectsServerBaseException* be = [[TestSlicingObjectsServerBaseException alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [be autorelease];
+#endif
+ be.sbe = @"sbe";
+ be.pb = [[TestSlicingObjectsServerB alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [be.pb autorelease];
+#endif
+ be.pb.sb = @"sb";
+ be.pb.pb = be.pb;
+ @throw be;
+}
+-(void) throwDerivedAsBase:(ICECurrent*)current
+{
+ TestSlicingObjectsServerDerivedException* de = [[TestSlicingObjectsServerDerivedException alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [de autorelease];
+#endif
+ de.sbe = @"sbe";
+ de.pb = [[TestSlicingObjectsServerB alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [de.pb autorelease];
+#endif
+ de.pb.sb = @"sb1";
+ de.pb.pb = de.pb;
+ de.sde = @"sde1";
+ de.pd1 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [de.pd1 autorelease];
+#endif
+ de.pd1.sb = @"sb2";
+ de.pd1.pb = de.pd1;
+ de.pd1.sd1 = @"sd2";
+ de.pd1.pd1 = de.pd1;
+ @throw de;
+}
+-(void) throwDerivedAsDerived:(ICECurrent*)current
+{
+ TestSlicingObjectsServerDerivedException* de = [[TestSlicingObjectsServerDerivedException alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [de autorelease];
+#endif
+ de.sbe = @"sbe";
+ de.pb = [[TestSlicingObjectsServerB alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [de.pb autorelease];
+#endif
+ de.pb.sb = @"sb1";
+ de.pb.pb = de.pb;
+ de.sde = @"sde1";
+ de.pd1 = [[TestSlicingObjectsServerD1 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [de.pd1 autorelease];
+#endif
+ de.pd1.sb = @"sb2";
+ de.pd1.pb = de.pd1;
+ de.pd1.sd1 = @"sd2";
+ de.pd1.pd1 = de.pd1;
+ @throw de;
+}
+-(void) throwUnknownDerivedAsBase:(ICECurrent*)current
+{
+ TestSlicingObjectsServerD2* d2 = [[TestSlicingObjectsServerD2 alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [d2 autorelease];
+#endif
+ d2.sb = @"sb d2";
+ d2.pb = d2;
+ d2.sd2 = @"sd2 d2";
+ d2.pd2 = d2;
+
+ TestSlicingObjectsServerUnknownDerivedException* ude = [[TestSlicingObjectsServerUnknownDerivedException alloc] init];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [ude autorelease];
+#endif
+ ude.sbe = @"sbe";
+ ude.pb = d2;
+ ude.sude = @"sude";
+ ude.pd2 = d2;
+ @throw ude;
+}
+-(void) throwPreservedException:(ICECurrent*)current
+{
+ TestSlicingObjectsServerPSUnknownException* ue = [TestSlicingObjectsServerPSUnknownException pSUnknownException];
+ ue.p = [TestSlicingObjectsServerPSUnknown2 pSUnknown2];
+ ue.p.pi = 5;
+ ue.p.ps = @"preserved";
+ ue.p.pb = ue.p;
+#if defined(__clang__) && !__has_feature(objc_arc)
+ if(ex_ != nil)
+ {
+ ex_.p.pb = nil;
+ [ex_ release];
+ }
+ ex_ = [ue retain];
+#else
+ if(ex_ != nil)
+ {
+ ex_.p.pb = nil;
+ }
+#endif
+ @throw ue;
+}
+-(void) useForward:(TestSlicingObjectsServerForward**)f current:(ICECurrent*)current
+{
+ *f = [TestSlicingObjectsServerForward forward];
+ (*f).h = [TestSlicingObjectsServerHidden hidden];
+ (*f).h.f = *f;
+}
+-(void) shutdown:(ICECurrent*)current
+{
+ if(ex_ != nil)
+ {
+ ex_.p.pb = nil;
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [ex_ release];
+#endif
+ }
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
diff --git a/objc/test/Ice/slicing/objects/run.py b/objc/test/Ice/slicing/objects/run.py
new file mode 100755
index 00000000000..bfdb6603e5b
--- /dev/null
+++ b/objc/test/Ice/slicing/objects/run.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+print("Running test with sliced format.")
+TestUtil.clientServerTest()
+
+print("Running test with 1.0 encoding.")
+TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0",
+ additionalServerOptions="--Ice.Default.EncodingVersion=1.0")
diff --git a/objc/test/Ice/stream/.gitignore b/objc/test/Ice/stream/.gitignore
new file mode 100644
index 00000000000..deeebc026e0
--- /dev/null
+++ b/objc/test/Ice/stream/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+StreamTest.m
+StreamTest.h
diff --git a/objc/test/Ice/stream/Client.m b/objc/test/Ice/stream/Client.m
new file mode 100644
index 00000000000..a189fc01e89
--- /dev/null
+++ b/objc/test/Ice/stream/Client.m
@@ -0,0 +1,979 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <StreamTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<ICEInputStream> in;
+ id<ICEOutputStream> out;
+ NSMutableData* data;
+
+ //
+ // Test the stream api.
+ //
+ tprintf("testing primitive types... ");
+
+ {
+ NSData* byte = [NSData data];
+ in = [ICEUtil createInputStream:communicator data:byte];
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out startEncapsulation];
+ [out writeBool:YES];
+ [out endEncapsulation];
+ data = [out finished];
+ NSData* d = [out finishedNoCopy];
+ test([d isEqual:data]);
+ out = nil;
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ [in startEncapsulation];
+ BOOL v;
+ v = [in readBool];
+ test(v);
+ [in endEncapsulation];
+
+ in = [ICEUtil wrapInputStream:communicator data:data];
+ [in startEncapsulation];
+ v = [in readBool];
+ test(v);
+ [in endEncapsulation];
+ }
+
+ {
+ NSData* byte = [NSData data];
+ in = [ICEUtil createInputStream:communicator data:byte];
+ @try
+ {
+ BOOL v;
+ v = [in readBool];
+ test(NO);
+ }
+ @catch(ICEUnmarshalOutOfBoundsException* ex)
+ {
+ }
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out writeBool:YES];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ BOOL v = [in readBool];
+ test(v);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out writeByte:(ICEByte)1];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEByte v = [in readByte];
+ test(v == 1);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out writeShort:(ICEShort)2];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEShort v = [in readShort];
+ test(v == 2);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out writeInt:(ICEInt)3];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEInt v;
+ v = [in readInt];
+ test(v == 3);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out writeLong:(ICELong)4];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICELong v;
+ v = [in readLong];
+ test(v == 4);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out writeFloat:(ICEFloat)5.0];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEFloat v;
+ v = [in readFloat];
+ test(v == 5.0);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out writeDouble:(ICEDouble)6.0];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEDouble v;
+ v = [in readDouble];
+ test(v == 6.0);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [out writeString:@"hello world"];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ NSString* v;
+ v = [in readString];
+ test([v isEqualToString:@"hello world"]);
+ }
+
+ tprintf("ok\n");
+
+ tprintf("testing constructed types... ");
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamMyEnumHelper write:@(TestStreamenum3) stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ id e = [TestStreamMyEnumHelper read:in];
+ test([e isEqual:@(TestStreamenum3)]);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStreamSmallStruct* s = [TestStreamSmallStruct smallStruct];
+ s.bo = YES;
+ s.by = 1;
+ s.sh = 2;
+ s.i = 3;
+ s.l = 4;
+ s.f = 5.0;
+ s.d = 6.0;
+ s.str = @"7";
+ s.e = TestStreamenum2;
+ s.p = [TestStreamMyClassPrx uncheckedCast:[communicator stringToProxy:@"test:default"]];
+ [TestStreamSmallStructHelper write:s stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamSmallStruct* s2 = [TestStreamSmallStructHelper read:in];
+ test([s2 isEqual:s]);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStreamClassStruct* s = [TestStreamClassStruct classStruct];
+ s.i = 10;
+ [TestStreamClassStructHelper write:s stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamClassStruct* s2 = [TestStreamClassStructHelper read:in];
+ test(s2.i == s.i);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStreamOptionalClass* o = [TestStreamOptionalClass optionalClass];
+ o.bo = NO;
+ o.by = 5;
+ o.sh = 4;
+ o.i = 3;
+ [TestStreamOptionalClassHelper write:o stream:out];
+ [out writePendingObjects];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamOptionalClass* ICE_AUTORELEASING_QUALIFIER o2;
+ [TestStreamOptionalClassHelper read:&o2 stream:in];
+ [in readPendingObjects];
+ test(o2.bo == o.bo);
+ test(o2.by == o.by);
+ if([in getEncoding] == ICEEncoding_1_0)
+ {
+ test(![o2 hasSh]);
+ test(![o2 hasI]);
+ }
+ else
+ {
+ test(o2.sh == o.sh);
+ test(o2.i == o.i);
+ }
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator encoding:ICEEncoding_1_0];
+ TestStreamOptionalClass* o = [TestStreamOptionalClass optionalClass];
+ o.bo = NO;
+ o.by = 5;
+ o.sh = 4;
+ o.i = 3;
+ [TestStreamOptionalClassHelper write:o stream:out];
+ [out writePendingObjects];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data encoding:ICEEncoding_1_0];
+ TestStreamOptionalClass* ICE_AUTORELEASING_QUALIFIER o2;
+ [TestStreamOptionalClassHelper read:&o2 stream:in];
+ [in readPendingObjects];
+ test(o2.bo == o.bo);
+ test(o2.by == o.by);
+ test(![o2 hasSh]);
+ test(![o2 hasI]);
+ }
+
+ {
+ BOOL buf[] = { YES, YES, NO, YES };
+ ICEBoolSeq* arr = [ICEBoolSeq dataWithBytes:buf length:sizeof(buf)];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [ICEBoolSeqHelper write:arr stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEBoolSeq* arr2 = [ICEBoolSeqHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableBoolSS* arrS = [TestStreamMutableBoolSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[ICEBoolSeq data]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamBoolSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamBoolSS* arr2S = [TestStreamBoolSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ ICEByte buf[] = { 0x01, 0x11, 0x12, 0x22 };
+ ICEByteSeq* arr = [ICEByteSeq dataWithBytes:buf length:sizeof(buf)];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [ICEByteSeqHelper write:arr stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEByteSeq* arr2 = [ICEByteSeqHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableByteSS* arrS = [TestStreamMutableByteSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[ICEByteSeq data]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamByteSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamByteSS* arr2S = [TestStreamByteSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ ICEShort buf[] = { 1, 11, 12, 22 };
+ ICEShortSeq* arr = [ICEShortSeq dataWithBytes:buf length:sizeof(buf)];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [ICEShortSeqHelper write:arr stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEShortSeq* arr2 = [ICEShortSeqHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableShortSS* arrS = [TestStreamMutableShortSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[ICEShortSeq data]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamShortSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamShortSS* arr2S = [TestStreamShortSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ ICEInt buf[] = { 1, 11, 12, 22 };
+ ICEIntSeq* arr = [ICEIntSeq dataWithBytes:buf length:sizeof(buf)];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [ICEIntSeqHelper write:arr stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEIntSeq* arr2 = [ICEIntSeqHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableIntSS* arrS = [TestStreamMutableIntSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[ICEIntSeq data]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamIntSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamIntSS* arr2S = [TestStreamIntSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ ICELong buf[] = { 1, 11, 12, 22 };
+ ICELongSeq* arr = [ICELongSeq dataWithBytes:buf length:sizeof(buf)];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [ICELongSeqHelper write:arr stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICELongSeq* arr2 = [ICELongSeqHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableLongSS* arrS = [TestStreamMutableLongSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[ICELongSeq data]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamLongSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamLongSS* arr2S = [TestStreamLongSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ ICEFloat buf[] = { 1, 2, 3, 4 };
+ ICEFloatSeq* arr = [ICEFloatSeq dataWithBytes:buf length:sizeof(buf)];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [ICEFloatSeqHelper write:arr stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEFloatSeq* arr2 = [ICEFloatSeqHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableFloatSS* arrS = [TestStreamMutableFloatSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[ICEFloatSeq data]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamFloatSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamFloatSS* arr2S = [TestStreamFloatSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ ICEDouble buf[] = { 1, 2, 3, 4 };
+ ICEDoubleSeq* arr = [ICEDoubleSeq dataWithBytes:buf length:sizeof(buf)];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [ICEDoubleSeqHelper write:arr stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEDoubleSeq* arr2 = [ICEDoubleSeqHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableDoubleSS* arrS = [TestStreamMutableDoubleSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[ICEDoubleSeq data]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamDoubleSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamDoubleSS* arr2S = [TestStreamDoubleSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ ICEMutableStringSeq* arr = [ICEMutableStringSeq array];
+ [arr addObject:@"string1"];
+ [arr addObject:@"string2"];
+ [arr addObject:@"string3"];
+ [arr addObject:@"string4"];
+ out = [ICEUtil createOutputStream:communicator];
+ [ICEStringSeqHelper write:arr stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ ICEStringSeq* arr2 = [ICEStringSeqHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableStringSS* arrS = [TestStreamMutableStringSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[ICEStringSeq array]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamStringSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamStringSS* arr2S = [TestStreamStringSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ TestStreamMyEnum buf[] = { TestStreamenum3, TestStreamenum2, TestStreamenum1, TestStreamenum2 };
+ TestStreamMutableMyEnumS* arr = [TestStreamMutableMyEnumS dataWithBytes:buf length:sizeof(buf)];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamMyEnumSHelper write:arr stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamMyEnumS* arr2 = [TestStreamMyEnumSHelper read:in];
+ test([arr2 isEqual:arr]);
+
+ TestStreamMutableMyEnumSS* arrS = [TestStreamMutableMyEnumSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[TestStreamMyEnumS data]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamMyEnumSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamMyEnumSS* arr2S = [TestStreamMyEnumSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ TestStreamMutableSmallStructS* arr = [TestStreamMutableSmallStructS array];
+ for(int i = 0; i < 4; ++i)
+ {
+ TestStreamSmallStruct* s = [TestStreamSmallStruct smallStruct];
+ s.bo = YES;
+ s.by = 1;
+ s.sh = 2;
+ s.i = 3;
+ s.l = 4;
+ s.f = 5.0;
+ s.d = 6.0;
+ s.str = @"7";
+ s.e = TestStreamenum2;
+ s.p = [TestStreamMyClassPrx uncheckedCast:[communicator stringToProxy:@"test:default"]];
+ [arr addObject:s];
+ }
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamSmallStructSHelper write:arr stream:out];
+ [out writePendingObjects];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamSmallStructS* arr2 = [TestStreamSmallStructSHelper read:in];
+ [in readPendingObjects];
+ test([arr2 count] == [arr count]);
+ for(int j = 0; j < [arr2 count]; ++j)
+ {
+ test([[arr objectAtIndex:j] isEqual:[arr2 objectAtIndex:j]]);
+ }
+
+ TestStreamMutableSmallStructSS* arrS = [TestStreamMutableSmallStructSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[TestStreamSmallStructS array]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamSmallStructSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamSmallStructSS* arr2S = [TestStreamSmallStructSSHelper read:in];
+ test([arr2S isEqual:arrS]);
+ }
+
+ {
+ TestStreamMutableMyClassS* arr = [TestStreamMutableMyClassS array];
+ for(int i = 0; i < 4; ++i)
+ {
+ TestStreamMyClass* c = [TestStreamMyClass myClass];
+ c.c = c;
+ c.o = c;
+ c.s = [TestStreamSmallStruct smallStruct];
+ c.s.e = TestStreamenum2;
+
+ BOOL boolS[] = { YES, NO, YES, NO };
+ c.seq1 = [NSMutableData dataWithBytes:boolS length:sizeof(boolS)];
+
+ ICEByte byteS[] = { 1, 2, 3, 4 };
+ c.seq2 = [NSMutableData dataWithBytes:byteS length:sizeof(byteS)];
+
+ ICEShort shortS[] = { 1, 2, 3, 4 };
+ c.seq3 = [NSMutableData dataWithBytes:shortS length:sizeof(shortS)];
+
+ ICEInt intS[] = { 1, 2, 3, 4 };
+ c.seq4 = [NSMutableData dataWithBytes:intS length:sizeof(intS)];
+
+ ICELong longS[] = { 1, 2, 3, 4 };
+ c.seq5 = [NSMutableData dataWithBytes:longS length:sizeof(longS)];
+
+ ICEFloat floatS[] = { 1, 2, 3, 4 };
+ c.seq6 = [NSMutableData dataWithBytes:floatS length:sizeof(floatS)];
+
+ ICEDouble doubleS[] = { 1, 2, 3, 4 };
+ c.seq7 = [NSMutableData dataWithBytes:doubleS length:sizeof(doubleS)];
+
+ c.seq8 = [ICEMutableStringSeq array];
+ [(ICEMutableStringSeq*)c.seq8 addObject:@"string1"];
+ [(ICEMutableStringSeq*)c.seq8 addObject:@"string2"];
+ [(ICEMutableStringSeq*)c.seq8 addObject:@"string3"];
+ [(ICEMutableStringSeq*)c.seq8 addObject:@"string4"];
+
+ TestStreamMyEnum enumS[] = { TestStreamenum3, TestStreamenum2, TestStreamenum1 };
+ c.seq9 = [NSMutableData dataWithBytes:enumS length:sizeof(enumS)];
+
+ c.d = [NSDictionary dictionaryWithObject:[TestStreamMyClass myClass] forKey:@"hi"];
+ [arr addObject:c];
+ }
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamMyClassSHelper write:arr stream:out];
+ [out writePendingObjects];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamMyClassS* arr2 = [TestStreamMyClassSHelper read:in];
+ [in readPendingObjects];
+ test([arr2 count] > 0);
+ test([arr2 count] == [arr count]);
+ for(int j = 0; j < [arr2 count]; ++j)
+ {
+ TestStreamMyClass* e = [arr2 objectAtIndex:j];
+ TestStreamMyClass* f = [arr objectAtIndex:j];
+ test(e);
+ test(e.c == e);
+ test(e.o == e);
+ test(e.s.e == TestStreamenum2);
+ test([e.seq1 isEqual:f.seq1]);
+ test([e.seq2 isEqual:f.seq2]);
+ test([e.seq3 isEqual:f.seq3]);
+ test([e.seq4 isEqual:f.seq4]);
+ test([e.seq5 isEqual:f.seq5]);
+ test([e.seq6 isEqual:f.seq6]);
+ test([e.seq7 isEqual:f.seq7]);
+ test([e.seq8 isEqual:f.seq8]);
+ test([e.seq9 isEqual:f.seq9]);
+ test([e.d objectForKey:@"hi"] != nil);
+
+ e.c = nil;
+ e.o = nil;
+ f.c = nil;
+ f.o = nil;
+ }
+
+ TestStreamMutableMyClassSS* arrS = [TestStreamMutableMyClassSS array];
+ [arrS addObject:arr];
+ [arrS addObject:[TestStreamMyClassS array]];
+ [arrS addObject:arr];
+
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamMyClassSSHelper write:arrS stream:out];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamMyClassSS* arr2S = [TestStreamMyClassSSHelper read:in];
+ test([arr2S count] == [arrS count]);
+ }
+
+ {
+ TestStreamMyInterface ICE_AUTORELEASING_QUALIFIER * i = [TestStreamMyInterface new];
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamMyInterfaceHelper write:i stream:out];
+ [out writePendingObjects];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ i = nil;
+ [TestStreamMyInterfaceHelper read:&i stream:in];
+ [in readPendingObjects];
+ test(i != nil);
+ }
+
+ //
+ // ObjectWriter/ObjectReader not supported.
+ //
+ // {
+ // out = [ICEUtil createOutputStream:communicator];
+ // TestStreamMyClass* obj = [TestStreamMyClass myClass];
+ // obj.s.e = TestStreamenum2;
+ // TestObjectWriterPtr writer = new TestObjectWriter:obj];
+ // [out writeObject:writer];
+ // [out writePendingObjects];
+ // data = [out finished];
+ // test([writer called);
+ // }
+
+ // {
+ // out = [ICEUtil createOutputStream:communicator];
+ // TestStreamMyClassPtr obj = new TestStreamMyClass;
+ // obj->s.e = TestStreamenum2;
+ // TestObjectWriterPtr writer = new TestObjectWriter:obj];
+ // [out writeObject:writer];
+ // [out writePendingObjects];
+ // data = [out finished];
+ // test([writer called]);
+ // [factoryWrapper setFactory:new TestObjectFactory];
+ // in = [ICEUtil createInputStream:communicator data:data];
+ // TestReadObjectCallbackPtr cb = new TestReadObjectCallback;
+ // [in readObject:cb];
+ // [in readPendingObjects];
+ // test([cb obj]);
+ // TestObjectReaderPtr reader = TestObjectReaderPtr::dynamicCast(cb->obj);
+ // test(reader);
+ // test([reader called]);
+ // test([reader obj]);
+ // test([reader obj]->s.e == TestStreamenum2);
+ // [factoryWrapper setFactory:0];
+ // }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStreamMyException* ex = [TestStreamMyException myException];
+ TestStreamMyClass* c = [TestStreamMyClass myClass];
+ c.c = c;
+ c.o = c;
+ c.s = [TestStreamSmallStruct smallStruct];
+ c.s.e = TestStreamenum2;
+
+ BOOL boolS[] = { YES, NO, YES, NO };
+ c.seq1 = [NSMutableData dataWithBytes:boolS length:sizeof(boolS)];
+
+ ICEByte byteS[] = { 1, 2, 3, 4 };
+ c.seq2 = [NSMutableData dataWithBytes:byteS length:sizeof(byteS)];
+
+ ICEShort shortS[] = { 1, 2, 3, 4 };
+ c.seq3 = [NSMutableData dataWithBytes:shortS length:sizeof(shortS)];
+
+ ICEInt intS[] = { 1, 2, 3, 4 };
+ c.seq4 = [NSMutableData dataWithBytes:intS length:sizeof(intS)];
+
+ ICELong longS[] = { 1, 2, 3, 4 };
+ c.seq5 = [NSMutableData dataWithBytes:longS length:sizeof(longS)];
+
+ ICEFloat floatS[] = { 1, 2, 3, 4 };
+ c.seq6 = [NSMutableData dataWithBytes:floatS length:sizeof(floatS)];
+
+ ICEDouble doubleS[] = { 1, 2, 3, 4 };
+ c.seq7 = [NSMutableData dataWithBytes:doubleS length:sizeof(doubleS)];
+
+ c.seq8 = [ICEMutableStringSeq array];
+ [(ICEMutableStringSeq*)c.seq8 addObject:@"string1"];
+ [(ICEMutableStringSeq*)c.seq8 addObject:@"string2"];
+ [(ICEMutableStringSeq*)c.seq8 addObject:@"string3"];
+ [(ICEMutableStringSeq*)c.seq8 addObject:@"string4"];
+
+ TestStreamMyEnum enumS[] = { TestStreamenum3, TestStreamenum2, TestStreamenum1 };
+ c.seq9 = [NSMutableData dataWithBytes:enumS length:sizeof(enumS)];
+
+ c.d = [NSDictionary dictionaryWithObject:[TestStreamMyClass myClass] forKey:@"hi"];
+
+ ex.c = c;
+
+ [out writeException:ex];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ @try
+ {
+ [in throwException];
+ test(NO);
+ }
+ @catch(TestStreamMyException* ex1)
+ {
+ test(ex1.c);
+ test(ex1.c.c == ex1.c);
+ test(ex1.c.o == ex1.c);
+ test(ex1.c.s.e == TestStreamenum2);
+ test([ex1.c.seq1 isEqual:c.seq1]);
+ test([ex1.c.seq2 isEqual:c.seq2]);
+ test([ex1.c.seq3 isEqual:c.seq3]);
+ test([ex1.c.seq4 isEqual:c.seq4]);
+ test([ex1.c.seq5 isEqual:c.seq5]);
+ test([ex1.c.seq6 isEqual:c.seq6]);
+ test([ex1.c.seq7 isEqual:c.seq7]);
+ test([ex1.c.seq8 isEqual:c.seq8]);
+ test([ex1.c.seq9 isEqual:c.seq9]);
+ test([ex1.c.d objectForKey:@"hi"] != nil);
+
+ ex1.c.c = nil;
+ ex1.c.o = nil;
+ c.c = nil;
+ c.o = nil;
+ }
+ }
+
+ {
+ TestStreamMutableByteBoolD* dict = [TestStreamMutableByteBoolD dictionary];
+ [dict setObject:@YES forKey:@(0x04)];
+ [dict setObject:@NO forKey:@(0x01)];
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamByteBoolDHelper write:dict stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamByteBoolD* dict2 = [TestStreamByteBoolDHelper read:in];
+ test([dict2 isEqual:dict]);
+ }
+
+ {
+ TestStreamMutableShortIntD* dict = [TestStreamMutableShortIntD dictionary];
+ [dict setObject:@9 forKey:@1];
+ [dict setObject:@8 forKey:@4];
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamShortIntDHelper write:dict stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamShortIntD* dict2 = [TestStreamShortIntDHelper read:in];
+ test([dict2 isEqual:dict]);
+ }
+
+ {
+ TestStreamMutableLongFloatD* dict = [TestStreamMutableLongFloatD dictionary];
+ [dict setObject:@0.51f forKey:@123809828];
+ [dict setObject:@0.56f forKey:@123809829];
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamLongFloatDHelper write:dict stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamLongFloatD* dict2 = [TestStreamLongFloatDHelper read:in];
+ test([dict2 isEqual:dict]);
+ }
+
+ {
+ TestStreamMutableStringStringD* dict = [TestStreamMutableStringStringD dictionary];
+ [dict setObject:@"value1" forKey:@"key1"];
+ [dict setObject:@"value2" forKey:@"key2"];
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamStringStringDHelper write:dict stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamStringStringD* dict2 = [TestStreamStringStringDHelper read:in];
+ test([dict2 isEqual:dict]);
+ }
+
+ {
+ TestStreamMutableStringMyClassD* dict = [TestStreamMutableStringMyClassD dictionary];
+ TestStreamMyClass* c = [TestStreamMyClass myClass];
+ c.s = [TestStreamSmallStruct smallStruct];
+ c.s.e = TestStreamenum2;
+ [dict setObject:c forKey:@"key1"];
+ c = [TestStreamMyClass myClass];
+ c.s = [TestStreamSmallStruct smallStruct];
+ c.s.e = TestStreamenum3;
+ [dict setObject:c forKey:@"key2"];
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamStringMyClassDHelper write:dict stream:out];
+ [out writePendingObjects];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamStringMyClassD* dict2 = [TestStreamStringMyClassDHelper read:in];
+ [in readPendingObjects];
+ test([dict2 count] == [dict count]);
+ test([dict2 objectForKey:@"key1"] != nil &&
+ ((TestStreamMyClass*)[dict2 objectForKey:@"key1"]).s.e == TestStreamenum2);
+ test([dict2 objectForKey:@"key2"] != nil &&
+ ((TestStreamMyClass*)[dict2 objectForKey:@"key2"]).s.e == TestStreamenum3);
+
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStreamSubNestedEnumHelper write:@(TestStreamSubnestedEnum3) stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ id e = [TestStreamSubNestedEnumHelper read:in];
+ test([e isEqual:@(TestStreamSubnestedEnum3)]);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStreamSubNestedStruct* s = [TestStreamSubNestedStruct nestedStruct];
+ s.bo = YES;
+ s.by = 1;
+ s.sh = 2;
+ s.i = 3;
+ s.l = 4;
+ s.f = 5.0;
+ s.d = 6.0;
+ s.str = @"7";
+ s.e = TestStreamSubnestedEnum2;
+ [TestStreamSubNestedStructHelper write:s stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamSubNestedStruct* s2 = [TestStreamSubNestedStructHelper read:in];
+ test([s2 isEqual:s]);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStreamSubNestedClassStruct* s = [TestStreamSubNestedClassStruct nestedClassStruct];
+ s.i = 10;
+ [TestStreamSubNestedClassStructHelper write:s stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStreamSubNestedClassStruct* s2 = [TestStreamSubNestedClassStructHelper read:in];
+ test(s2.i == s.i);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStreamSubNestedException* ex = [TestStreamSubNestedException nestedException];
+ ex.str = @"str";
+
+ [out writeException:ex];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ @try
+ {
+ [in throwException];
+ test(NO);
+ }
+ @catch(TestStreamSubNestedException* ex1)
+ {
+ test([ex1.str isEqualToString:ex.str]);
+ }
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ [TestStream2Sub2NestedEnum2Helper write:@(TestStream2Sub2nestedEnum4) stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ id e = [TestStream2Sub2NestedEnum2Helper read:in];
+ test([e isEqual:@(TestStream2Sub2nestedEnum4)]);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStream2Sub2NestedStruct2* s = [TestStream2Sub2NestedStruct2 nestedStruct2];
+ s.bo = YES;
+ s.by = 1;
+ s.sh = 2;
+ s.i = 3;
+ s.l = 4;
+ s.f = 5.0;
+ s.d = 6.0;
+ s.str = @"7";
+ s.e = TestStream2Sub2nestedEnum5;
+ [TestStream2Sub2NestedStruct2Helper write:s stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStream2Sub2NestedStruct2* s2 = [TestStream2Sub2NestedStruct2Helper read:in];
+ test([s2 isEqual:s]);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStream2Sub2NestedClassStruct2* s = [TestStream2Sub2NestedClassStruct2 nestedClassStruct2];
+ s.i = 10;
+ [TestStream2Sub2NestedClassStruct2Helper write:s stream:out];
+ data = [out finished];
+ in = [ICEUtil createInputStream:communicator data:data];
+ TestStream2Sub2NestedClassStruct2* s2 = [TestStream2Sub2NestedClassStruct2Helper read:in];
+ test(s2.i == s.i);
+ }
+
+ {
+ out = [ICEUtil createOutputStream:communicator];
+ TestStream2Sub2NestedException2* ex = [TestStream2Sub2NestedException2 nestedException2];
+ ex.str = @"str";
+
+ [out writeException:ex];
+ data = [out finished];
+
+ in = [ICEUtil createInputStream:communicator data:data];
+ @try
+ {
+ [in throwException];
+ test(NO);
+ }
+ @catch(TestStream2Sub2NestedException2* ex1)
+ {
+ test([ex1.str isEqualToString:ex.str]);
+ }
+ }
+
+ tprintf("ok\n");
+ return 0;
+}
+
+#if TARGET_OS_IPHONE
+# define main streamClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestStream", @"::Test",
+ @"TestStreamSub", @"::Test::Sub",
+ @"TestStream2", @"::Test2",
+ @"TestStream2Sub2", @"::Test2::Sub2",
+ nil];
+#endif
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/stream/Makefile b/objc/test/Ice/stream/Makefile
new file mode 100644
index 00000000000..d3ddfa58783
--- /dev/null
+++ b/objc/test/Ice/stream/Makefile
@@ -0,0 +1,28 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = StreamTest.o
+
+COBJS = Client.o
+
+OBJS = $(COBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/stream/StreamTest.ice b/objc/test/Ice/stream/StreamTest.ice
new file mode 100644
index 00000000000..02cf9905b50
--- /dev/null
+++ b/objc/test/Ice/stream/StreamTest.ice
@@ -0,0 +1,175 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/BuiltinSequences.ice>
+
+["objc:prefix:TestStream"]
+module Test
+{
+
+enum MyEnum
+{
+ enum1,
+ enum2,
+ enum3
+};
+
+class MyClass;
+
+["cpp:comparable"] struct SmallStruct
+{
+ bool bo;
+ byte by;
+ short sh;
+ int i;
+ long l;
+ float f;
+ double d;
+ string str;
+ MyEnum e;
+ MyClass* p;
+};
+
+["cpp:class"] struct ClassStruct
+{
+ int i;
+};
+
+class OptionalClass
+{
+ bool bo;
+ byte by;
+ optional(1) short sh;
+ optional(2) int i;
+};
+
+sequence<MyEnum> MyEnumS;
+sequence<SmallStruct> SmallStructS;
+sequence<MyClass> MyClassS;
+
+sequence<Ice::BoolSeq> BoolSS;
+sequence<Ice::ByteSeq> ByteSS;
+sequence<Ice::ShortSeq> ShortSS;
+sequence<Ice::IntSeq> IntSS;
+sequence<Ice::LongSeq> LongSS;
+sequence<Ice::FloatSeq> FloatSS;
+sequence<Ice::DoubleSeq> DoubleSS;
+sequence<Ice::StringSeq> StringSS;
+sequence<MyEnumS> MyEnumSS;
+sequence<SmallStructS> SmallStructSS;
+sequence<MyClassS> MyClassSS;
+
+dictionary<byte, bool> ByteBoolD;
+dictionary<short, int> ShortIntD;
+dictionary<long, float> LongFloatD;
+dictionary<string, string> StringStringD;
+dictionary<string, MyClass> StringMyClassD;
+
+class MyClass
+{
+ MyClass c;
+ Object o;
+ SmallStruct s;
+ Ice::BoolSeq seq1;
+ Ice::ByteSeq seq2;
+ Ice::ShortSeq seq3;
+ Ice::IntSeq seq4;
+ Ice::LongSeq seq5;
+ Ice::FloatSeq seq6;
+ Ice::DoubleSeq seq7;
+ Ice::StringSeq seq8;
+ MyEnumS seq9;
+ MyClassS seq10;
+ StringMyClassD d;
+};
+
+interface MyInterface
+{
+};
+
+exception MyException
+{
+ MyClass c;
+};
+
+["objc:prefix:TestStreamSub"]
+module Sub
+{
+ enum NestedEnum
+ {
+ nestedEnum1,
+ nestedEnum2,
+ nestedEnum3
+ };
+
+ ["cpp:comparable"] struct NestedStruct
+ {
+ bool bo;
+ byte by;
+ short sh;
+ int i;
+ long l;
+ float f;
+ double d;
+ string str;
+ NestedEnum e;
+ };
+
+ ["cpp:class"] struct NestedClassStruct
+ {
+ int i;
+ };
+
+ exception NestedException
+ {
+ string str;
+ };
+};
+};
+
+["objc:prefix:TestStream2"]
+module Test2
+{
+["objc:prefix:TestStream2Sub2"]
+module Sub2
+{
+ enum NestedEnum2
+ {
+ nestedEnum4,
+ nestedEnum5,
+ nestedEnum6
+ };
+
+ ["cpp:comparable"] struct NestedStruct2
+ {
+ bool bo;
+ byte by;
+ short sh;
+ int i;
+ long l;
+ float f;
+ double d;
+ string str;
+ NestedEnum2 e;
+ };
+
+ ["cpp:class"] struct NestedClassStruct2
+ {
+ int i;
+ };
+
+ exception NestedException2
+ {
+ string str;
+ };
+};
+};
+
diff --git a/objc/test/Ice/stream/run.py b/objc/test/Ice/stream/run.py
new file mode 100755
index 00000000000..70e3812f00b
--- /dev/null
+++ b/objc/test/Ice/stream/run.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+client = os.path.join(os.getcwd(), "client")
+
+print("Running test with default encoding...")
+TestUtil.simpleTest(client)
+
+print("Running test with 1.0 encoding...")
+TestUtil.simpleTest(client, "--Ice.Default.EncodingVersion=1.0")
diff --git a/objc/test/Ice/timeout/.gitignore b/objc/test/Ice/timeout/.gitignore
new file mode 100644
index 00000000000..1c18b9822c2
--- /dev/null
+++ b/objc/test/Ice/timeout/.gitignore
@@ -0,0 +1,8 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+.depend
+TimeoutTest.m
+TimeoutTest.h
diff --git a/objc/test/Ice/timeout/AllTests.m b/objc/test/Ice/timeout/AllTests.m
new file mode 100644
index 00000000000..2dd9e755f78
--- /dev/null
+++ b/objc/test/Ice/timeout/AllTests.m
@@ -0,0 +1,277 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <TimeoutTest.h>
+
+#import <Foundation/Foundation.h>
+
+@interface TestTimeoutCallback : NSObject
+{
+ BOOL called;
+ NSCondition* cond;
+}
+-(void) check;
+-(void) called;
+@end
+
+@implementation TestTimeoutCallback
+-(id) init
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+ cond = [[NSCondition alloc] init];
+ return self;
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [cond release];
+ [super dealloc];
+}
+#endif
+
+-(void) check
+{
+ [cond lock];
+ while(!called)
+ {
+ [cond wait];
+ }
+ called = NO;
+ [cond unlock];
+}
+-(void) called
+{
+ [cond lock];
+ called = YES;
+ [cond signal];
+ [cond unlock];
+}
+-(void) sendDataResponse
+{
+ [self called];
+}
+-(void) sendDataException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) sendDataExResponse
+{
+ test(NO);
+}
+-(void) sendDataExException:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICETimeoutException class]]);
+ [self called];
+}
+-(void) sleepResponse
+{
+ [self called];
+}
+-(void) sleepException:(ICEException*)ex
+{
+ test(NO);
+}
+-(void) sleepExResponse
+{
+ test(NO);
+}
+-(void) sleepExException:(ICEException*)ex
+{
+ test([ex isKindOfClass:[ICETimeoutException class]]);
+ [self called];
+}
+@end
+
+id<TestTimeoutTimeoutPrx>
+timeoutAllTests(id<ICECommunicator> communicator)
+{
+ NSString* sref = @"timeout:default -p 12010";
+ id<ICEObjectPrx> obj = [communicator stringToProxy:sref];
+ test(obj);
+
+ id<TestTimeoutTimeoutPrx> timeout = [TestTimeoutTimeoutPrx checkedCast:obj];
+ test(timeout);
+
+ tprintf("testing connect timeout... ");
+ {
+ //
+ // Expect ConnectTimeoutException.
+ //
+ id<TestTimeoutTimeoutPrx> to = [TestTimeoutTimeoutPrx uncheckedCast:[obj ice_timeout:500]];
+ [to holdAdapter:1000];
+ [[to ice_getConnection] close:YES]; // Force a reconnect.
+ @try
+ {
+ [to op];
+ test(NO);
+ }
+ @catch(ICEConnectTimeoutException*)
+ {
+ // Expected.
+ }
+ }
+ {
+ //
+ // Expect success.
+ //
+ [timeout op]; // Ensure adapter is active.
+ id<TestTimeoutTimeoutPrx> to = [TestTimeoutTimeoutPrx uncheckedCast:[obj ice_timeout:1000]];
+ [to holdAdapter:500];
+ [[to ice_getConnection] close:YES]; // Force a reconnect.
+ @try
+ {
+ [to op];
+ }
+ @catch(ICEConnectTimeoutException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ // The sequence needs to be large enough to fill the write/recv buffers
+ TestTimeoutByteSeq* seq = [TestTimeoutMutableByteSeq dataWithLength:2000000];
+
+ tprintf("testing connection timeout... ");
+ {
+ //
+ // Expect TimeoutException.
+ //
+ id<TestTimeoutTimeoutPrx> to = [TestTimeoutTimeoutPrx uncheckedCast:[obj ice_timeout:100]];
+ [to holdAdapter:500];
+ @try
+ {
+ [to sendData:seq];
+ test(NO);
+ }
+ @catch(ICETimeoutException*)
+ {
+ // Expected.
+ }
+ }
+ {
+ //
+ // Expect success.
+ //
+ [timeout op]; // Ensure adapter is active.
+ id<TestTimeoutTimeoutPrx> to = [TestTimeoutTimeoutPrx uncheckedCast:[obj ice_timeout:1000]];
+ [to holdAdapter:500];
+ @try
+ {
+ TestTimeoutByteSeq* seq = [TestTimeoutMutableByteSeq dataWithLength:1000000];
+ [to sendData:seq];
+ }
+ @catch(ICETimeoutException*)
+ {
+ test(NO);
+ }
+ }
+ tprintf("ok\n");
+
+ tprintf("testing timeout overrides... ");
+ {
+ //
+ // TestTimeout Ice.Override.Timeout. This property overrides all
+ // endpoint timeouts.
+ //
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ [initData setProperties:[[communicator getProperties] clone]];
+ [[initData properties] setProperty:@"Ice.Override.Timeout" value:@"100"];
+ id<ICECommunicator> comm = [ICEUtil createCommunicator:initData];
+ id<TestTimeoutTimeoutPrx> to = [TestTimeoutTimeoutPrx checkedCast:[comm stringToProxy:sref]];
+ [timeout holdAdapter:500];
+ @try
+ {
+ [to sendData:seq];
+ test(NO);
+ }
+ @catch(ICETimeoutException*)
+ {
+ // Expected.
+ }
+ //
+ // Calling ice_timeout() should have no effect.
+ //
+ [timeout op]; // Ensure adapter is active.
+ to = [TestTimeoutTimeoutPrx checkedCast:[to ice_timeout:1000]];
+ [timeout holdAdapter:500];
+ @try
+ {
+ [to sendData:seq];
+ test(NO);
+ }
+ @catch(ICETimeoutException*)
+ {
+ // Expected.
+ }
+ [comm destroy];
+ }
+ {
+ //
+ // TestTimeout Ice.Override.ConnectTimeout.
+ //
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ [initData setProperties:[[communicator getProperties] clone]];
+ [[initData properties] setProperty:@"Ice.Override.ConnectTimeout" value:@"250"];
+ id<ICECommunicator> comm = [ICEUtil createCommunicator:initData];
+ [timeout holdAdapter:750];
+ id<TestTimeoutTimeoutPrx> to = [TestTimeoutTimeoutPrx uncheckedCast:[comm stringToProxy:sref]];
+ @try
+ {
+ [to op];
+ test(NO);
+ }
+ @catch(ICEConnectTimeoutException*)
+ {
+ // Expected.
+ }
+ //
+ // Calling ice_timeout() should have no effect on the connect timeout.
+ //
+ [timeout op]; // Ensure adapter is active.
+ [timeout holdAdapter:750];
+ to = [TestTimeoutTimeoutPrx uncheckedCast:[to ice_timeout:1000]];
+ @try
+ {
+ [to op];
+ test(NO);
+ }
+ @catch(ICEConnectTimeoutException*)
+ {
+ // Expected.
+ }
+ //
+ // Verify that timeout set via ice_timeout() is still used for requests.
+ //
+ [timeout op]; // Ensure adapter is active.
+ to = [TestTimeoutTimeoutPrx uncheckedCast:[to ice_timeout:100]];
+ [to ice_getConnection]; // Establish connection
+ [timeout holdAdapter:750];
+ @try
+ {
+ [to sendData:seq];
+ test(NO);
+ }
+ @catch(ICETimeoutException*)
+ {
+ // Expected.
+ }
+ [comm destroy];
+ }
+ tprintf("ok\n");
+
+ return timeout;
+}
diff --git a/objc/test/Ice/timeout/Client.m b/objc/test/Ice/timeout/Client.m
new file mode 100644
index 00000000000..70cb973c338
--- /dev/null
+++ b/objc/test/Ice/timeout/Client.m
@@ -0,0 +1,93 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <TimeoutTest.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ id<TestTimeoutTimeoutPrx> timeoutAllTests(id<ICECommunicator>);
+ id<TestTimeoutTimeoutPrx> timeout = timeoutAllTests(communicator);
+ [timeout shutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main timeoutClient
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+
+ //
+ // For this test, we want to disable retries.
+ //
+ [initData.properties setProperty:@"Ice.RetryIntervals" value:@"-1"];
+
+ //
+ // COMPILERFIX: Disable connect timeout introduced for
+ // workaround to iOS device hangs when using SSL
+ //
+ [initData.properties setProperty:@"Ice.Override.ConnectTimeout" value:@""];
+
+ //
+ // This test kills connections, so we don't want warnings.
+ //
+ [initData.properties setProperty:@"Ice.Warn.Connections" value:@"0"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestTimeout", @"::Test",
+ nil];
+#endif
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/timeout/Makefile b/objc/test/Ice/timeout/Makefile
new file mode 100644
index 00000000000..f669c19e612
--- /dev/null
+++ b/objc/test/Ice/timeout/Makefile
@@ -0,0 +1,37 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+SLICE_OBJS = TimeoutTest.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+OBJS = $(COBJS) $(SOBJS) $(SLICE_OBJS)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(COBJS) $(SLICE_OBJS) $(TEST_LIBS)
+
+$(SERVER): $(SOBJS) $(SLICE_OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(SOBJS) $(SLICE_OBJS) $(TEST_LIBS)
diff --git a/objc/test/Ice/timeout/Server.m b/objc/test/Ice/timeout/Server.m
new file mode 100644
index 00000000000..48dcd2a311b
--- /dev/null
+++ b/objc/test/Ice/timeout/Server.m
@@ -0,0 +1,94 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <timeout/TestI.h>
+#import <TestCommon.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ [[communicator getProperties] setProperty:@"TestAdapter.Endpoints" value:@"default -p 12010:udp"];
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"TestAdapter"];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ ICEObject* object = [[[TimeoutI alloc] init] autorelease];
+#else
+ ICEObject* object = [[TimeoutI alloc] init];
+#endif
+ [adapter add:object identity:[communicator stringToIdentity:@"timeout"]];
+ [adapter activate];
+
+ serverReady(communicator);
+
+ [communicator waitForShutdown];
+ return EXIT_SUCCESS;
+}
+
+#if TARGET_OS_IPHONE
+# define main timeoutServer
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultServerProperties(&argc, argv);
+
+ //
+ // COMPILERFIX: Disable connect timeout introduced for
+ // workaround to iOS device hangs when using SSL
+ //
+ [initData.properties setProperty:@"Ice.Override.ConnectTimeout" value:@""];
+
+ //
+ // This test kills connections, so we don't want warnings.
+ //
+ [initData.properties setProperty:@"Ice.Warn.Connections" value:@"0"];
+#if TARGET_OS_IPHONE
+ initData.prefixTable__ = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"TestTimeout", @"::Test",
+ nil];
+#endif
+
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
diff --git a/objc/test/Ice/timeout/TestI.h b/objc/test/Ice/timeout/TestI.h
new file mode 100644
index 00000000000..c278f32870b
--- /dev/null
+++ b/objc/test/Ice/timeout/TestI.h
@@ -0,0 +1,18 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <TimeoutTest.h>
+
+@interface TimeoutI : TestTimeoutTimeout<TestTimeoutTimeout>
+-(void) op:(ICECurrent *)current;
+-(void) sendData:(TestTimeoutMutableByteSeq *)seq current:(ICECurrent *)current;
+-(void) sleep:(ICEInt)to current:(ICECurrent *)current;
+-(void) holdAdapter:(ICEInt)to current:(ICECurrent *)current;
+-(void) shutdown:(ICECurrent *)current;
+@end
diff --git a/objc/test/Ice/timeout/TestI.m b/objc/test/Ice/timeout/TestI.m
new file mode 100644
index 00000000000..fff2c216a77
--- /dev/null
+++ b/objc/test/Ice/timeout/TestI.m
@@ -0,0 +1,94 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <timeout/TestI.h>
+#import <objc/Ice.h>
+
+#import <Foundation/NSThread.h>
+
+@interface ActivateAdapterThread : NSThread
+{
+ id<ICEObjectAdapter> adapter_;
+ int timeout_;
+}
+-(id) init:(id<ICEObjectAdapter>)adapter timeout:(int)timeout;
++(id) activateAdapterThread:(id<ICEObjectAdapter>)adapter timeout:(int)timeout;
+-(void) main;
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc;
+#endif
+@end
+
+@implementation ActivateAdapterThread
+-(id) init:(id<ICEObjectAdapter>)adapter timeout:(int)timeout
+{
+ self = [super init];
+ if(!self)
+ {
+ return nil;
+ }
+#if defined(__clang__) && !__has_feature(objc_arc)
+ adapter_ = [adapter retain];
+#else
+ adapter_ = adapter;
+#endif
+ timeout_ = timeout;
+ return self;
+}
+
++(id) activateAdapterThread:(id<ICEObjectAdapter>)adapter timeout:(int)timeout
+{
+#if defined(__clang__) && !__has_feature(objc_arc)
+ return [[[self alloc] init:adapter timeout:timeout] autorelease];
+#else
+ return [[self alloc] init:adapter timeout:timeout];
+#endif
+}
+-(void) main
+{
+ [NSThread sleepForTimeInterval:timeout_ / 1000.0];
+ [adapter_ activate];
+}
+
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
+{
+ [adapter_ release];
+ [super dealloc];
+}
+#endif
+
+@end
+
+@implementation TimeoutI
+-(void) op:(ICECurrent*)current
+{
+}
+
+-(void) sendData:(TestTimeoutMutableByteSeq*)seq current:(ICECurrent*)current
+{
+}
+
+-(void) sleep:(ICEInt)to current:(ICECurrent*)current
+{
+ [NSThread sleepForTimeInterval:to / 1000.0];
+}
+
+-(void) holdAdapter:(ICEInt)to current:(ICECurrent*)current
+{
+ [current.adapter hold];
+ ActivateAdapterThread* thread = [ActivateAdapterThread activateAdapterThread:current.adapter timeout:to];
+ [thread start];
+}
+
+-(void) shutdown:(ICECurrent*)current
+{
+ [[current.adapter getCommunicator] shutdown];
+}
+@end
diff --git a/objc/test/Ice/timeout/TimeoutTest.ice b/objc/test/Ice/timeout/TimeoutTest.ice
new file mode 100644
index 00000000000..6544b216567
--- /dev/null
+++ b/objc/test/Ice/timeout/TimeoutTest.ice
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+["objc:prefix:TestTimeout"]
+module Test
+{
+
+sequence<byte> ByteSeq;
+
+interface Timeout
+{
+ void op();
+ void sendData(ByteSeq seq);
+ void sleep(int to);
+
+ void holdAdapter(int to);
+
+ void shutdown();
+};
+
+};
diff --git a/objc/test/Ice/timeout/run.py b/objc/test/Ice/timeout/run.py
new file mode 100755
index 00000000000..33fc2e8f3ac
--- /dev/null
+++ b/objc/test/Ice/timeout/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()
diff --git a/objc/test/Makefile b/objc/test/Makefile
new file mode 100644
index 00000000000..02aabe19256
--- /dev/null
+++ b/objc/test/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = Common Slice Ice
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/test/Slice/Makefile b/objc/test/Slice/Makefile
new file mode 100644
index 00000000000..f34d7c628bd
--- /dev/null
+++ b/objc/test/Slice/Makefile
@@ -0,0 +1,21 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+SUBDIRS = keyword
+
+$(EVERYTHING)::
+ @for subdir in $(SUBDIRS); \
+ do \
+ echo "making $@ in $$subdir"; \
+ ( cd $$subdir && $(MAKE) $@ ) || exit 1; \
+ done
diff --git a/objc/test/Slice/keyword/.gitignore b/objc/test/Slice/keyword/.gitignore
new file mode 100644
index 00000000000..f5c78eb09c4
--- /dev/null
+++ b/objc/test/Slice/keyword/.gitignore
@@ -0,0 +1,9 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+.depend
+Key.m
+Inherit.m
+Key.h
+Inherit.h
diff --git a/objc/test/Slice/keyword/Client.m b/objc/test/Slice/keyword/Client.m
new file mode 100644
index 00000000000..dbabff1fd55
--- /dev/null
+++ b/objc/test/Slice/keyword/Client.m
@@ -0,0 +1,223 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <objc/Ice.h>
+#import <TestCommon.h>
+#import <Key.h>
+#import <Inherit.h>
+#ifdef ICE_OBJC_GC
+# import <Foundation/NSGarbageCollector.h>
+#endif
+
+// Verify that the expected symbols are present
+@interface andbreakI : andbreak<andbreak>
+@end
+
+@interface andcharI : andchar<andchar>
+@end
+
+@interface andswitchI : andswitch<andswitch>
+@end
+
+@interface anddoI : anddo<anddo>
+@end
+
+@interface andfriendI : andfriend<andfriend>
+@end
+
+//
+// This section of the test is present to ensure that the C++ types
+// are named correctly. It is not expected to run.
+//
+static void
+testSymbols()
+{
+ andbreakPrx* prx1 = 0;
+ [prx1 case_:0 try:0];
+ test(prx1 == 0);
+
+ andcharPrx* prx2 = 0;
+ [prx2 explicit];
+ test(prx2 == 0);
+
+ andswitchPrx* prx3 = 0;
+ [prx3 foo:0 volatile_:0];
+ test(prx3 == 0);
+
+ anddoPrx* prx4 = 0;
+ test(prx4 == 0);
+
+ anddoPrx* prx5 = 0;
+ test(prx5 == 0);
+
+ andfriendPrx* prx6 = 0;
+ test(prx6 == 0);
+
+ andcontinue c1 = andasm;
+ test(c1 == andasm);
+
+ andauto* cl1 = 0;
+ test(cl1 == 0);
+
+ anddelete* cl2 = 0;
+ test(cl2 == 0);
+
+ andswitch* cl3 = 0;
+ test(cl3.if_ == 0);
+ test(cl3 == 0);
+
+ anddo* cl4 = 0;
+ test(cl4 == 0);
+
+ andreturn* ex1 = 0;
+ test(ex1.signed_ == 0);
+ test(ex1 == 0);
+
+ andsizeof* ex2 = 0;
+ test(ex2.signed_ == 0);
+ test(ex2.static_ == 0);
+ test(ex2 == 0);
+
+ test(andtemplate == 0);
+ test(andthis == 0);
+ test(andthrow == 0);
+ test(andtypedef == 0);
+ test(andtypeid == 0);
+ test(andtypename == 0);
+ test(andunion == 0);
+ test(andunsigned == 0);
+ test(andusing == 0);
+ test(andvirtual == 0);
+ test(andwhile == 0);
+ test(andxor == 0);
+
+ TestStruct1* ds1 = 0;
+ test(ds1.retainCount_ == 0);
+
+ TestException1 *dex1 = 0;
+ test(dex1.isa_ == 0);
+ test(dex1.reason_ == 0);
+ test(dex1.raise_ == 0);
+ test(dex1.name_ == 0);
+ test(dex1.callStackReturnAddresses_ == 0);
+ test(dex1.userInfo_ == 0);
+ test(dex1.reserved_ == 0);
+
+ TestClass1* dcl1 = 0;
+ test(dcl1.reason == 0);
+ test(dcl1.autorelease_ == 0);
+ test(dcl1.isa_ == 0);
+ test(dcl1.classForCoder_ == 0);
+ test(dcl1.copy_ == 0);
+ test(dcl1.dealloc_ == 0);
+ test(dcl1.description_ == 0);
+ test(dcl1.hash_ == 0);
+ test(dcl1.init_ == 0);
+ test(dcl1.isProxy_ == 0);
+ test(dcl1.mutableCopy_ == 0);
+ test(dcl1.release_ == 0);
+ test(dcl1.retain_ == 0);
+ test(dcl1.retainCount_ == 0);
+ test(dcl1.self_ == 0);
+ test(dcl1.superclass_ == 0);
+ test(dcl1.zone_ == 0);
+
+ TestIntf1Prx* dif1 = 0;
+ [dif1 reason];
+ [dif1 isa_];
+ [dif1 autorelease_];
+ [dif1 classForCoder_];
+ [dif1 copy_];
+ [dif1 dealloc_];
+ [dif1 description_];
+ [dif1 hash_];
+ [dif1 init_];
+ [dif1 isProxy_];
+ [dif1 mutableCopy_];
+ [dif1 release_];
+ [dif1 retain_];
+ [dif1 retainCount_];
+ [dif1 self_];
+ [dif1 superclass_];
+ [dif1 zone_];
+
+ TestIntf2Prx* dif2 = 0;
+ [dif2 reason:0];
+ [dif2 isa:0];
+ [dif2 autorelease:0];
+ [dif2 classForCoder:0];
+ [dif2 copy:0];
+ [dif2 dealloc:0];
+ [dif2 description:0];
+ [dif2 hash:0];
+ [dif2 init:0];
+ [dif2 isProxy:0];
+ [dif2 mutableCopy:0];
+ [dif2 release:0];
+ [dif2 retain:0];
+ [dif2 retainCount:0];
+ [dif2 self_:0];
+ [dif2 superclass:0];
+ [dif2 zone:0];
+}
+
+static int
+run(id<ICECommunicator> communicator)
+{
+ if(0)
+ {
+ testSymbols();
+ }
+ return 0;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ @autoreleasepool
+ {
+ id<ICECommunicator> communicator = nil;
+
+ @try
+ {
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = defaultClientProperties(&argc, argv);
+ communicator = [ICEUtil createCommunicator:&argc argv:argv initData:initData];
+ status = run(communicator);
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ @catch(TestFailedException* ex)
+ {
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ @try
+ {
+ [communicator destroy];
+ }
+ @catch(ICEException* ex)
+ {
+ tprintf("%@\n", ex);
+ status = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef ICE_OBJC_GC
+ [[NSGarbageCollector defaultCollector] collectExhaustively];
+#endif
+ return status;
+}
+
diff --git a/objc/test/Slice/keyword/Inherit.ice b/objc/test/Slice/keyword/Inherit.ice
new file mode 100644
index 00000000000..3cd8392db10
--- /dev/null
+++ b/objc/test/Slice/keyword/Inherit.ice
@@ -0,0 +1,95 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+// Test overridding interherited names
+module Test
+{
+
+struct Struct1
+{
+ int isa;
+ int retainCount;
+};
+
+exception Exception1
+{
+ int isa;
+ int reason;
+ int raise;
+ int name;
+ int callStackReturnAddresses;
+ int userInfo;
+ int reserved;
+};
+
+class Class1
+{
+ int reason;
+
+ int isa;
+ int autorelease;
+ int classForCoder;
+ int copy;
+ int dealloc;
+ int description;
+ int hash;
+ int init;
+ int isProxy;
+ int mutableCopy;
+ int release;
+ int retain;
+ int retainCount;
+ int self;
+ int superclass;
+ int zone;
+};
+
+interface Intf1
+{
+ void isa();
+ void reason();
+ void autorelease();
+ void classForCoder();
+ void copy();
+ void dealloc();
+ void description();
+ void hash();
+ void init();
+ void isProxy();
+ void mutableCopy();
+ void release();
+ void retain();
+ void retainCount();
+ void self();
+ void superclass();
+ void zone();
+};
+
+interface Intf2
+{
+ void isa(int a);
+ void reason(int a);
+ void autorelease(int a);
+ void classForCoder(int a);
+ void copy(int a);
+ void dealloc(int a);
+ void description(int a);
+ void hash(int a);
+ void init(int a);
+ void isProxy(int a);
+ void mutableCopy(int a);
+ void release(int a);
+ void retain(int a);
+ void retainCount(int a);
+ void self(int a);
+ void superclass(int a);
+ void zone(int a);
+};
+
+};
diff --git a/objc/test/Slice/keyword/Key.ice b/objc/test/Slice/keyword/Key.ice
new file mode 100644
index 00000000000..a45df9f0fa8
--- /dev/null
+++ b/objc/test/Slice/keyword/Key.ice
@@ -0,0 +1,86 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+module and
+{
+
+enum continue
+{
+ asm
+};
+
+struct auto
+{
+ int default;
+};
+
+["cpp:class"] struct delete
+{
+ string else;
+};
+
+interface break
+{
+ void case(int catch, out int try);
+};
+
+interface char
+{
+ void explicit();
+};
+
+class switch
+{
+ int if;
+ void foo(char* export, out int volatile);
+};
+
+class do extends switch implements char, break
+{
+};
+
+sequence<auto> extern;
+
+dictionary<string,auto> for;
+
+exception return
+{
+ int signed;
+};
+
+exception sizeof extends return
+{
+ int static;
+ int switch;
+};
+
+local interface friend
+{
+ auto goto(continue if, auto d, delete inline, switch private, do mutable, break* namespace,
+ char* new, switch* not, do* operator, int or, int protected, int public, int register)
+ throws return, sizeof;
+
+ void objc(int bycopy, int byref, int id, int IMP, int in, int inout, int nil, int NO, int oneway,
+ int SEL, int super, int YES);
+};
+
+const int template = 0;
+const int this = 0;
+const int throw = 0;
+const int typedef = 0;
+const int typeid = 0;
+const int typename = 0;
+const int union = 0;
+const int unsigned = 0;
+const int using = 0;
+const int virtual = 0;
+const int while = 0;
+const int xor = 0;
+
+};
diff --git a/objc/test/Slice/keyword/Makefile b/objc/test/Slice/keyword/Makefile
new file mode 100644
index 00000000000..78ee12943e1
--- /dev/null
+++ b/objc/test/Slice/keyword/Makefile
@@ -0,0 +1,29 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice Touch is licensed to you under the terms described in the
+# ICE_TOUCH_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+SLICE_OBJS = Key.o Inherit.o
+
+OBJS = Key.o \
+ Inherit.o \
+ Client.o
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I.. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(OBJS)
+ rm -f $@
+ $(CC) $(LDFLAGS) $(LDEXEFLAGS) $(STATICLIBSTDFLAG) -o $@ $(OBJS) $(TEST_LIBS)
+
diff --git a/objc/test/Slice/keyword/run.py b/objc/test/Slice/keyword/run.py
new file mode 100755
index 00000000000..eed9bface4f
--- /dev/null
+++ b/objc/test/Slice/keyword/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+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 RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+client = os.path.join(os.getcwd(), "client")
+
+TestUtil.simpleTest(client)
diff --git a/objc/test/include/TestCommon.h b/objc/test/include/TestCommon.h
new file mode 100644
index 00000000000..eeced47cc3d
--- /dev/null
+++ b/objc/test/include/TestCommon.h
@@ -0,0 +1,35 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice Touch is licensed to you under the terms described in the
+// ICE_TOUCH_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#import <Foundation/NSObject.h>
+#import <Foundation/NSException.h>
+
+@interface TestFailedException : NSException
+@end
+
+#if TARGET_OS_IPHONE
+void TestCommonInit(id, SEL);
+void TestCommonTestInit(id, SEL, BOOL, BOOL, BOOL);
+#endif
+
+@protocol ICECommunicator;
+@protocol ICEProperties;
+
+id<ICEProperties> defaultServerProperties();
+id<ICEProperties> defaultClientProperties();
+
+void serverReady(id<ICECommunicator>);
+
+void serverStop();
+
+void tprintf(const char* fmt, ...);
+
+void testFailed(const char*, const char*, unsigned int);
+
+#define test(ex) ((ex) ? ((void)0) : testFailed(#ex, __FILE__, __LINE__))
diff --git a/py/config/Make.rules b/py/config/Make.rules
index 5315160acf9..b142a7ddc48 100644
--- a/py/config/Make.rules
+++ b/py/config/Make.rules
@@ -11,7 +11,6 @@
# Select an installation base directory. The directory will be created
# if it does not exist.
#
-
prefix ?= /opt/Ice-$(VERSION)
#
diff --git a/scripts/TestUtil.py b/scripts/TestUtil.py
index 677f3860ed0..39098029a9b 100755
--- a/scripts/TestUtil.py
+++ b/scripts/TestUtil.py
@@ -492,8 +492,8 @@ def run(tests, root = False):
filters.append((testFilter, False))
elif o == "--cross":
global cross
- if a not in ["cpp", "cs", "java", "js", "py", "rb" ]:
- print("cross must be one of cpp, cs, java, js, py or rb")
+ if a not in ["cpp", "cs", "java", "js", "py", "rb", "objc" ]:
+ print("cross must be one of cpp, cs, java, js, py, rb or objc")
sys.exit(1)
cross.append(a)
elif o == "--all" :
@@ -872,7 +872,7 @@ def getDefaultMapping():
here = os.getcwd().split(os.sep)
here.reverse()
for i in range(0, len(here)):
- if here[i] in ["cpp", "cs", "java", "js", "php", "py", "rb", "cppe", "javae", "tmp"]:
+ if here[i] in ["cpp", "cs", "java", "js", "php", "py", "rb", "objc", "cppe", "javae", "tmp"]:
return here[i]
raise RuntimeError("cannot determine mapping")
@@ -1137,7 +1137,7 @@ def directoryToPackage():
def getDefaultServerFile():
lang = getDefaultMapping()
- if lang in ["js", "rb", "php", "cpp", "cs", "cppe"]:
+ if lang in ["js", "rb", "php", "cpp", "cs", "objc", "cppe"]:
return "server"
if lang == "py":
return "Server.py"
@@ -1155,7 +1155,7 @@ def getDefaultClientFile(lang = None):
return "Client.rb"
if lang == "php":
return "Client.php"
- if lang in ["cpp", "cs", "cppe"]:
+ if lang in ["cpp", "cs", "objc", "cppe"]:
return "client"
if lang == "py":
return "Client.py"
@@ -1807,7 +1807,7 @@ def getTestEnv(lang, testdir):
#
if isWin32():
addLdPath(getCppLibDir(lang), env)
- elif lang in ["py", "rb", "php", "js"]:
+ elif lang in ["py", "rb", "php", "js", "objc"]:
addLdPath(getCppLibDir(lang), env)
if lang == "javae":
@@ -1976,8 +1976,8 @@ def processCmdLine():
elif o == "--cross":
global cross
cross.append(a)
- if not a in ["cpp", "cs", "java", "js", "py", "rb" ]:
- print("cross must be one of cpp, cs, java, js, py or rb")
+ if not a in ["cpp", "cs", "java", "js", "py", "rb", "objc" ]:
+ print("cross must be one of cpp, cs, java, js, py, rb or objc")
sys.exit(1)
if getTestName() not in crossTests:
print("*** This test does not support cross language testing")
diff --git a/slice/Freeze/BackgroundSaveEvictor.ice b/slice/Freeze/BackgroundSaveEvictor.ice
index 31789f613ce..350aeac636e 100644
--- a/slice/Freeze/BackgroundSaveEvictor.ice
+++ b/slice/Freeze/BackgroundSaveEvictor.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Freeze/Evictor.ice>
diff --git a/slice/Freeze/CatalogData.ice b/slice/Freeze/CatalogData.ice
index cbc5eff6885..2495c22459f 100644
--- a/slice/Freeze/CatalogData.ice
+++ b/slice/Freeze/CatalogData.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
module Freeze
{
diff --git a/slice/Freeze/Connection.ice b/slice/Freeze/Connection.ice
index 33112b1e075..23522d67ced 100644
--- a/slice/Freeze/Connection.ice
+++ b/slice/Freeze/Connection.ice
@@ -13,7 +13,7 @@
#include <Ice/Version.ice>
#include <Ice/CommunicatorF.ice>
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
module Freeze
{
diff --git a/slice/Freeze/ConnectionF.ice b/slice/Freeze/ConnectionF.ice
index d45546e9467..fc4bf6d3fdb 100644
--- a/slice/Freeze/ConnectionF.ice
+++ b/slice/Freeze/ConnectionF.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
module Freeze
{
diff --git a/slice/Freeze/DB.ice b/slice/Freeze/DB.ice
index a3163713cee..383917beaba 100644
--- a/slice/Freeze/DB.ice
+++ b/slice/Freeze/DB.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
/**
*
diff --git a/slice/Freeze/Evictor.ice b/slice/Freeze/Evictor.ice
index 99ae80305c9..922ce686af3 100644
--- a/slice/Freeze/Evictor.ice
+++ b/slice/Freeze/Evictor.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/ObjectAdapterF.ice>
#include <Ice/ServantLocator.ice>
diff --git a/slice/Freeze/EvictorF.ice b/slice/Freeze/EvictorF.ice
index 8a6b3094e57..fc6b99d8bce 100644
--- a/slice/Freeze/EvictorF.ice
+++ b/slice/Freeze/EvictorF.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
module Freeze
{
diff --git a/slice/Freeze/EvictorStorage.ice b/slice/Freeze/EvictorStorage.ice
index eadaf120c4d..0458a56f0e7 100644
--- a/slice/Freeze/EvictorStorage.ice
+++ b/slice/Freeze/EvictorStorage.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/Identity.ice>
diff --git a/slice/Freeze/Exception.ice b/slice/Freeze/Exception.ice
index 7fa56ebe9bd..09297cf70e4 100644
--- a/slice/Freeze/Exception.ice
+++ b/slice/Freeze/Exception.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
module Freeze
{
diff --git a/slice/Freeze/Transaction.ice b/slice/Freeze/Transaction.ice
index 58cf6a9170e..37f315068cb 100644
--- a/slice/Freeze/Transaction.ice
+++ b/slice/Freeze/Transaction.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
module Freeze
{
diff --git a/slice/Freeze/TransactionalEvictor.ice b/slice/Freeze/TransactionalEvictor.ice
index f71488660fb..3bd9b5b3933 100644
--- a/slice/Freeze/TransactionalEvictor.ice
+++ b/slice/Freeze/TransactionalEvictor.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Freeze/Evictor.ice>
diff --git a/slice/Glacier2/Metrics.ice b/slice/Glacier2/Metrics.ice
index 9e1d7cefc3f..5554d660a8f 100644
--- a/slice/Glacier2/Metrics.ice
+++ b/slice/Glacier2/Metrics.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:Glacier2/Config.h"]]
#include <Ice/Metrics.ice>
+["objc:prefix:ICEMX"]
module IceMX
{
diff --git a/slice/Glacier2/PermissionsVerifier.ice b/slice/Glacier2/PermissionsVerifier.ice
index 85b2a7d47ee..6a1051989fa 100644
--- a/slice/Glacier2/PermissionsVerifier.ice
+++ b/slice/Glacier2/PermissionsVerifier.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:Glacier2/Config.h"]]
#include <Glacier2/SSLInfo.ice>
+["objc:prefix:GLACIER2"]
module Glacier2
{
diff --git a/slice/Glacier2/PermissionsVerifierF.ice b/slice/Glacier2/PermissionsVerifierF.ice
index 45ad1590d0b..f1bb1d65279 100644
--- a/slice/Glacier2/PermissionsVerifierF.ice
+++ b/slice/Glacier2/PermissionsVerifierF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:GLACIER2"]
module Glacier2
{
diff --git a/slice/Glacier2/Router.ice b/slice/Glacier2/Router.ice
index 4f85e0fd1ff..d1f75b16639 100644
--- a/slice/Glacier2/Router.ice
+++ b/slice/Glacier2/Router.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:Glacier2/Config.h"]]
#include <Ice/Router.ice>
@@ -24,6 +24,7 @@
* security solution that is both non-intrusive and easy to configure.
*
**/
+["objc:prefix:GLACIER2"]
module Glacier2
{
diff --git a/slice/Glacier2/RouterF.ice b/slice/Glacier2/RouterF.ice
index bbaef076ea2..3117d525a1d 100644
--- a/slice/Glacier2/RouterF.ice
+++ b/slice/Glacier2/RouterF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:GLACIER2"]
module Glacier2
{
diff --git a/slice/Glacier2/SSLInfo.ice b/slice/Glacier2/SSLInfo.ice
index 106d76787f5..2c68700a057 100644
--- a/slice/Glacier2/SSLInfo.ice
+++ b/slice/Glacier2/SSLInfo.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:Glacier2/Config.h"]]
#include <Ice/BuiltinSequences.ice>
+["objc:prefix:GLACIER2"]
module Glacier2
{
diff --git a/slice/Glacier2/Session.ice b/slice/Glacier2/Session.ice
index a18badf5e42..404bb5ed47a 100644
--- a/slice/Glacier2/Session.ice
+++ b/slice/Glacier2/Session.ice
@@ -9,13 +9,14 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:Glacier2/Config.h"]]
#include <Ice/BuiltinSequences.ice>
#include <Ice/Identity.ice>
#include <Glacier2/SSLInfo.ice>
+["objc:prefix:GLACIER2"]
module Glacier2
{
diff --git a/slice/Ice/BuiltinSequences.ice b/slice/Ice/BuiltinSequences.ice
index da8a953933b..a2a08cea140 100644
--- a/slice/Ice/BuiltinSequences.ice
+++ b/slice/Ice/BuiltinSequences.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Communicator.ice b/slice/Ice/Communicator.ice
index 7065d5939cc..8038accab63 100644
--- a/slice/Ice/Communicator.ice
+++ b/slice/Ice/Communicator.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/LoggerF.ice>
#include <Ice/InstrumentationF.ice>
@@ -32,6 +32,7 @@
* additional functionality that supports high scalability.
*
**/
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/CommunicatorF.ice b/slice/Ice/CommunicatorF.ice
index 158946e8272..f07c4ddd447 100644
--- a/slice/Ice/CommunicatorF.ice
+++ b/slice/Ice/CommunicatorF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Connection.ice b/slice/Ice/Connection.ice
index 0155b21ac50..87ba30de06b 100644
--- a/slice/Ice/Connection.ice
+++ b/slice/Ice/Connection.ice
@@ -10,12 +10,13 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/ObjectAdapterF.ice>
#include <Ice/Identity.ice>
#include <Ice/Endpoint.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ConnectionF.ice b/slice/Ice/ConnectionF.ice
index 1e09403be7b..9efb4ac85e1 100644
--- a/slice/Ice/ConnectionF.ice
+++ b/slice/Ice/ConnectionF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Current.ice b/slice/Ice/Current.ice
index 5aeec6baa25..b360fc10e7b 100644
--- a/slice/Ice/Current.ice
+++ b/slice/Ice/Current.ice
@@ -9,13 +9,14 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/ObjectAdapterF.ice>
#include <Ice/ConnectionF.ice>
#include <Ice/Identity.ice>
#include <Ice/Version.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Endpoint.ice b/slice/Ice/Endpoint.ice
index 35c06d7725b..1048e1c01ab 100644
--- a/slice/Ice/Endpoint.ice
+++ b/slice/Ice/Endpoint.ice
@@ -13,8 +13,9 @@
#include <Ice/BuiltinSequences.ice>
#include <Ice/EndpointF.ice>
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/EndpointF.ice b/slice/Ice/EndpointF.ice
index 5eb3c8102c0..e3d34d34429 100644
--- a/slice/Ice/EndpointF.ice
+++ b/slice/Ice/EndpointF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/EndpointTypes.ice b/slice/Ice/EndpointTypes.ice
index c12ee281ffa..c989a99fae9 100644
--- a/slice/Ice/EndpointTypes.ice
+++ b/slice/Ice/EndpointTypes.ice
@@ -10,8 +10,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/FacetMap.ice b/slice/Ice/FacetMap.ice
index 0beb04457c8..04db5977215 100644
--- a/slice/Ice/FacetMap.ice
+++ b/slice/Ice/FacetMap.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Identity.ice b/slice/Ice/Identity.ice
index 5ce62a9c179..cf2f0b9b9bd 100644
--- a/slice/Ice/Identity.ice
+++ b/slice/Ice/Identity.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ImplicitContext.ice b/slice/Ice/ImplicitContext.ice
index 83d1016119d..b40ee011237 100644
--- a/slice/Ice/ImplicitContext.ice
+++ b/slice/Ice/ImplicitContext.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/LocalException.ice>
#include <Ice/Current.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ImplicitContextF.ice b/slice/Ice/ImplicitContextF.ice
index d9fa5e9475e..f18fa4c8c7b 100644
--- a/slice/Ice/ImplicitContextF.ice
+++ b/slice/Ice/ImplicitContextF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Instrumentation.ice b/slice/Ice/Instrumentation.ice
index 3e93a1a0c5f..353f1b4671b 100644
--- a/slice/Ice/Instrumentation.ice
+++ b/slice/Ice/Instrumentation.ice
@@ -9,12 +9,13 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/EndpointF.ice>
#include <Ice/ConnectionF.ice>
#include <Ice/Current.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/InstrumentationF.ice b/slice/Ice/InstrumentationF.ice
index 3cbb0048a73..5fe3be61347 100644
--- a/slice/Ice/InstrumentationF.ice
+++ b/slice/Ice/InstrumentationF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/LocalException.ice b/slice/Ice/LocalException.ice
index 81246e29b6c..1c3c9654f5a 100644
--- a/slice/Ice/LocalException.ice
+++ b/slice/Ice/LocalException.ice
@@ -9,12 +9,13 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/Identity.ice>
#include <Ice/Version.ice>
#include <Ice/BuiltinSequences.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Locator.ice b/slice/Ice/Locator.ice
index 15551c6a71a..169e9bb87e0 100644
--- a/slice/Ice/Locator.ice
+++ b/slice/Ice/Locator.ice
@@ -9,11 +9,13 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+
#include <Ice/Identity.ice>
#include <Ice/ProcessF.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/LocatorF.ice b/slice/Ice/LocatorF.ice
index 4a0a8656bed..91260f37e1d 100644
--- a/slice/Ice/LocatorF.ice
+++ b/slice/Ice/LocatorF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Logger.ice b/slice/Ice/Logger.ice
index 626c8825430..2f82c8f576b 100644
--- a/slice/Ice/Logger.ice
+++ b/slice/Ice/Logger.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/LoggerF.ice b/slice/Ice/LoggerF.ice
index 5a3666f721d..2ea22ab611e 100644
--- a/slice/Ice/LoggerF.ice
+++ b/slice/Ice/LoggerF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Metrics.ice b/slice/Ice/Metrics.ice
index 89c5bc5ebe1..d099b212e1b 100644
--- a/slice/Ice/Metrics.ice
+++ b/slice/Ice/Metrics.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/BuiltinSequences.ice>
@@ -20,6 +20,7 @@
* metrics from Ice applications.
*
**/
+["objc:prefix:ICEMX"]
module IceMX
{
diff --git a/slice/Ice/ObjectAdapter.ice b/slice/Ice/ObjectAdapter.ice
index 7b4d4f630ff..439976d85f2 100644
--- a/slice/Ice/ObjectAdapter.ice
+++ b/slice/Ice/ObjectAdapter.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/CommunicatorF.ice>
#include <Ice/ServantLocatorF.ice>
@@ -18,6 +18,7 @@
#include <Ice/FacetMap.ice>
#include <Ice/Endpoint.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ObjectAdapterF.ice b/slice/Ice/ObjectAdapterF.ice
index a322483dd28..aa5a6a1b354 100644
--- a/slice/Ice/ObjectAdapterF.ice
+++ b/slice/Ice/ObjectAdapterF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ObjectFactory.ice b/slice/Ice/ObjectFactory.ice
index ff84d6440eb..0f1ee3a57d5 100644
--- a/slice/Ice/ObjectFactory.ice
+++ b/slice/Ice/ObjectFactory.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ObjectFactoryF.ice b/slice/Ice/ObjectFactoryF.ice
index 284a8032b2e..710b1ee96c5 100644
--- a/slice/Ice/ObjectFactoryF.ice
+++ b/slice/Ice/ObjectFactoryF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Plugin.ice b/slice/Ice/Plugin.ice
index 8dddfc4b042..37d1167e046 100644
--- a/slice/Ice/Plugin.ice
+++ b/slice/Ice/Plugin.ice
@@ -10,11 +10,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/LoggerF.ice>
#include <Ice/BuiltinSequences.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/PluginF.ice b/slice/Ice/PluginF.ice
index 7320c96dcaf..ff570c1526a 100644
--- a/slice/Ice/PluginF.ice
+++ b/slice/Ice/PluginF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Process.ice b/slice/Ice/Process.ice
index 05af33b91b7..08073d39fc2 100644
--- a/slice/Ice/Process.ice
+++ b/slice/Ice/Process.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ProcessF.ice b/slice/Ice/ProcessF.ice
index 2d36ac7a096..b824ab321ec 100644
--- a/slice/Ice/ProcessF.ice
+++ b/slice/Ice/ProcessF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Properties.ice b/slice/Ice/Properties.ice
index d59a6552892..deae17b3747 100644
--- a/slice/Ice/Properties.ice
+++ b/slice/Ice/Properties.ice
@@ -9,10 +9,11 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/PropertiesAdmin.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/PropertiesAdmin.ice b/slice/Ice/PropertiesAdmin.ice
index e379fcc1553..6b8fe6932d9 100644
--- a/slice/Ice/PropertiesAdmin.ice
+++ b/slice/Ice/PropertiesAdmin.ice
@@ -9,10 +9,11 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/BuiltinSequences.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/PropertiesF.ice b/slice/Ice/PropertiesF.ice
index ebf7abb423f..5cc3b3696de 100644
--- a/slice/Ice/PropertiesF.ice
+++ b/slice/Ice/PropertiesF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/RemoteLogger.ice b/slice/Ice/RemoteLogger.ice
index e15851427ac..bd45e81c5f6 100644
--- a/slice/Ice/RemoteLogger.ice
+++ b/slice/Ice/RemoteLogger.ice
@@ -11,9 +11,10 @@
#include <Ice/BuiltinSequences.ice>
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:list"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Router.ice b/slice/Ice/Router.ice
index 796678e6f1c..44c7957402e 100644
--- a/slice/Ice/Router.ice
+++ b/slice/Ice/Router.ice
@@ -9,10 +9,11 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/BuiltinSequences.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/RouterF.ice b/slice/Ice/RouterF.ice
index 4a0d1b3a6e0..3a74071003d 100644
--- a/slice/Ice/RouterF.ice
+++ b/slice/Ice/RouterF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ServantLocator.ice b/slice/Ice/ServantLocator.ice
index 76c51c3b090..c4b24a9d591 100644
--- a/slice/Ice/ServantLocator.ice
+++ b/slice/Ice/ServantLocator.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/ObjectAdapterF.ice>
#include <Ice/Current.ice>
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/ServantLocatorF.ice b/slice/Ice/ServantLocatorF.ice
index f2ab8823195..74f74298b07 100644
--- a/slice/Ice/ServantLocatorF.ice
+++ b/slice/Ice/ServantLocatorF.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/SliceChecksumDict.ice b/slice/Ice/SliceChecksumDict.ice
index 98060d75043..bb4ee67c3e6 100644
--- a/slice/Ice/SliceChecksumDict.ice
+++ b/slice/Ice/SliceChecksumDict.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/Ice/Version.ice b/slice/Ice/Version.ice
index 5dc4c7d820b..7291cc43d78 100644
--- a/slice/Ice/Version.ice
+++ b/slice/Ice/Version.ice
@@ -9,8 +9,9 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
+["objc:prefix:ICE"]
module Ice
{
diff --git a/slice/IceBox/IceBox.ice b/slice/IceBox/IceBox.ice
index 8b01bc14c0a..69f6a816beb 100644
--- a/slice/IceBox/IceBox.ice
+++ b/slice/IceBox/IceBox.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceBox/Config.h"]]
#include <Ice/BuiltinSequences.ice>
diff --git a/slice/IceDiscovery/IceDiscovery.ice b/slice/IceDiscovery/IceDiscovery.ice
index 1d2519a37f9..decd6e95380 100644
--- a/slice/IceDiscovery/IceDiscovery.ice
+++ b/slice/IceDiscovery/IceDiscovery.ice
@@ -8,7 +8,7 @@
// **********************************************************************
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/Identity.ice>
diff --git a/slice/IceGrid/Admin.ice b/slice/IceGrid/Admin.ice
index 77abfba3994..42c11385002 100644
--- a/slice/IceGrid/Admin.ice
+++ b/slice/IceGrid/Admin.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <Ice/Identity.ice>
@@ -20,6 +20,7 @@
#include <IceGrid/Exception.ice>
#include <IceGrid/Descriptor.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/Descriptor.ice b/slice/IceGrid/Descriptor.ice
index ee8501fc844..9c3f35b1825 100644
--- a/slice/IceGrid/Descriptor.ice
+++ b/slice/IceGrid/Descriptor.ice
@@ -9,12 +9,13 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <Ice/Identity.ice>
#include <Ice/BuiltinSequences.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/Discovery.ice b/slice/IceGrid/Discovery.ice
index 6c19c91c7bc..d6c36f0f0b6 100644
--- a/slice/IceGrid/Discovery.ice
+++ b/slice/IceGrid/Discovery.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <IceGrid/Locator.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/Exception.ice b/slice/IceGrid/Exception.ice
index 760c3b72091..98413934a50 100644
--- a/slice/IceGrid/Exception.ice
+++ b/slice/IceGrid/Exception.ice
@@ -9,12 +9,13 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <Ice/Identity.ice>
#include <Ice/BuiltinSequences.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/FileParser.ice b/slice/IceGrid/FileParser.ice
index 846f8e21fc4..3572b0c1e94 100644
--- a/slice/IceGrid/FileParser.ice
+++ b/slice/IceGrid/FileParser.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <IceGrid/Admin.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/Locator.ice b/slice/IceGrid/Locator.ice
index 75f97a9f047..03b3d2328c3 100644
--- a/slice/IceGrid/Locator.ice
+++ b/slice/IceGrid/Locator.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <Ice/Locator.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/Observer.ice b/slice/IceGrid/Observer.ice
index 2ebcec6888a..ad96b7f6aae 100644
--- a/slice/IceGrid/Observer.ice
+++ b/slice/IceGrid/Observer.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <Glacier2/Session.ice>
@@ -17,6 +17,7 @@
#include <IceGrid/Descriptor.ice>
#include <IceGrid/Admin.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/PluginFacade.ice b/slice/IceGrid/PluginFacade.ice
index 60817b555e4..725bac61f10 100644
--- a/slice/IceGrid/PluginFacade.ice
+++ b/slice/IceGrid/PluginFacade.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <Ice/BuiltinSequences.ice>
@@ -17,6 +17,7 @@
#include <IceGrid/Admin.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/Query.ice b/slice/IceGrid/Query.ice
index d055b0c9f75..97c293cd671 100644
--- a/slice/IceGrid/Query.ice
+++ b/slice/IceGrid/Query.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <Ice/Identity.ice>
@@ -24,6 +24,7 @@
* heterogeneous computer network.
*
**/
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/Registry.ice b/slice/IceGrid/Registry.ice
index 2113225193c..1ea91ea27ad 100644
--- a/slice/IceGrid/Registry.ice
+++ b/slice/IceGrid/Registry.ice
@@ -9,13 +9,14 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <IceGrid/Exception.ice>
#include <IceGrid/Session.ice>
#include <IceGrid/Admin.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/Session.ice b/slice/IceGrid/Session.ice
index d9cf21e5eae..585f46f5165 100644
--- a/slice/IceGrid/Session.ice
+++ b/slice/IceGrid/Session.ice
@@ -9,12 +9,13 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
#include <Glacier2/Session.ice>
#include <IceGrid/Exception.ice>
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IceGrid/UserAccountMapper.ice b/slice/IceGrid/UserAccountMapper.ice
index 5c46d994cb0..a7923407b1a 100644
--- a/slice/IceGrid/UserAccountMapper.ice
+++ b/slice/IceGrid/UserAccountMapper.ice
@@ -9,9 +9,10 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceGrid/Config.h"]]
+["objc:prefix:ICEGRID"]
module IceGrid
{
diff --git a/slice/IcePatch2/FileInfo.ice b/slice/IcePatch2/FileInfo.ice
index 99619181403..babae423d79 100644
--- a/slice/IcePatch2/FileInfo.ice
+++ b/slice/IcePatch2/FileInfo.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IcePatch2/Config.h"]]
#include <Ice/BuiltinSequences.ice>
diff --git a/slice/IcePatch2/FileServer.ice b/slice/IcePatch2/FileServer.ice
index 1cd957317a2..d95a0fa9d4b 100644
--- a/slice/IcePatch2/FileServer.ice
+++ b/slice/IcePatch2/FileServer.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IcePatch2/Config.h"]]
#include <IcePatch2/FileInfo.ice>
diff --git a/slice/IceSSL/ConnectionInfo.ice b/slice/IceSSL/ConnectionInfo.ice
index 2ce533ef73f..5a72675b668 100644
--- a/slice/IceSSL/ConnectionInfo.ice
+++ b/slice/IceSSL/ConnectionInfo.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/Connection.ice>
diff --git a/slice/IceSSL/EndpointInfo.ice b/slice/IceSSL/EndpointInfo.ice
index 539b0226cc9..3e70d90d525 100644
--- a/slice/IceSSL/EndpointInfo.ice
+++ b/slice/IceSSL/EndpointInfo.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/Endpoint.ice>
diff --git a/slice/IceStorm/IceStorm.ice b/slice/IceStorm/IceStorm.ice
index b68debe6a4a..271a20c75fe 100644
--- a/slice/IceStorm/IceStorm.ice
+++ b/slice/IceStorm/IceStorm.ice
@@ -9,7 +9,7 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceStorm/Config.h"]]
#include <Ice/Identity.ice>
@@ -25,6 +25,7 @@
* easy as invoking a method on an interface.
*
**/
+["objc:prefix:ICESTORM"]
module IceStorm
{
diff --git a/slice/IceStorm/Metrics.ice b/slice/IceStorm/Metrics.ice
index 208399cb594..0442274298a 100644
--- a/slice/IceStorm/Metrics.ice
+++ b/slice/IceStorm/Metrics.ice
@@ -9,11 +9,12 @@
#pragma once
-[["cpp:header-ext:h"]]
+[["cpp:header-ext:h", "objc:header-dir:objc"]]
[["cpp:include:IceStorm/Config.h"]]
#include <Ice/Metrics.ice>
+["objc:prefix:ICEMX"]
module IceMX
{