summaryrefslogtreecommitdiff
path: root/cpp/demo/Ice/value/Client.cpp
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2003-05-23 08:07:40 +0000
committerMichi Henning <michi@zeroc.com>2003-05-23 08:07:40 +0000
commit5c89803b442f059bd7444b286adb3e0a1c4afeca (patch)
treee79bae21964782dc9a89df7ae2d0985caa822c26 /cpp/demo/Ice/value/Client.cpp
parentVC70 install improvements (diff)
downloadice-5c89803b442f059bd7444b286adb3e0a1c4afeca.tar.bz2
ice-5c89803b442f059bd7444b286adb3e0a1c4afeca.tar.xz
ice-5c89803b442f059bd7444b286adb3e0a1c4afeca.zip
Fixed the bug that Benoit found yesterday in both ice and icej.
(Zero-length sequence containing class elements caused an crash.) :Ice::Object). Obviously, this would cause an assertion failure or a {{{ClassCastException}}}. The solution is simply to force the down-cast in the generated patch function and to check whether the cast failed: if so, the class was sliced too much and we throw a {{{NoObjectFactoryException}}} as we should. (For Java, the exception is thrown from {{{BasicStream.readObject}}}, after catching a {{{ClassCastException}}}. For C++, the exception is thrown directly from the generated patch function.) :Ice::Object}}} and {{{::Printer}}}. Updated the code generator to correctly initialize the {{{type}}} member of a {{{NoObjectFactoryException}}} with the type ID of the type that wasn't found. (Unfortunately, this involved modifying {{{Parser.h}}}, so you will have to rebuild both ice and icej.) Added code generation for custom sequence types for icej. Generated code compiles and looks OK, but I haven't written tests yet, so there may still be a latent bug in this.
Diffstat (limited to 'cpp/demo/Ice/value/Client.cpp')
-rw-r--r--cpp/demo/Ice/value/Client.cpp47
1 files changed, 29 insertions, 18 deletions
diff --git a/cpp/demo/Ice/value/Client.cpp b/cpp/demo/Ice/value/Client.cpp
index 408d810a2c1..4626a5e7690 100644
--- a/cpp/demo/Ice/value/Client.cpp
+++ b/cpp/demo/Ice/value/Client.cpp
@@ -52,13 +52,25 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
cout << '\n'
<< "Ok, this worked. Now let's try to transfer an object for a class\n"
- << "with operations, without installing a factory first. This should\n"
- << "give us a `no factory' exception.\n"
+ << "with operations as type ::Ice::Object. Because no factory is installed,\n"
+ << "the class will be sliced to ::Ice::Object.\n"
+ << "[press enter]\n";
+ cin.getline(&c, 1);
+
+ ::Ice::ObjectPtr obj = initial->getPrinterAsObject();
+ cout << "==> The type ID of the received object is \"" << obj->ice_id() << "\"" << endl;
+ assert(obj->ice_id() == "::Ice::Object");
+
+ cout << '\n'
+ << "Yes, this worked. Now let's try to transfer an object for a class\n"
+ << "with operations as type ::Printer, without installing a factory first.\n"
+ << "This should give us a `no factory' exception.\n"
<< "[press enter]\n";
cin.getline(&c, 1);
PrinterPtr printer;
PrinterPrx printerProxy;
+ bool gotException = false;
try
{
initial->getPrinter(printer, printerProxy);
@@ -66,7 +78,9 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
catch(const Ice::NoObjectFactoryException& ex)
{
cout << "==> " << ex << endl;
+ gotException = true;
}
+ assert(gotException);
cout << '\n'
<< "Yep, that's what we expected. Now let's try again, but with\n"
@@ -99,28 +113,22 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
printerProxy->printBackwards();
cout << '\n'
- << "Next, we transfer a derived object from the server as base\n"
- << "object. Since we didn't install a factory for the derived\n"
- << "class yet, we will get another `no factory' exception.\n"
+ << "Next, we transfer a derived object from the server as a base\n"
+ << "object. Since we haven't yet installed a factory for the derived\n"
+ << "class, the derived class (::DerivedPrinter) is sliced\n"
+ << "to its base class (::Printer).\n"
<< "[press enter]\n";
cin.getline(&c, 1);
PrinterPtr derivedAsBase;
- try
- {
- derivedAsBase = initial->getDerivedPrinter();
- assert(false);
- }
- catch(const Ice::NoObjectFactoryException& ex)
- {
- cout << "==> " << ex << endl;
- }
+ derivedAsBase = initial->getDerivedPrinter();
+ cout << "==> The type ID of the received object is \"" << derivedAsBase->ice_id() << "\"" << endl;
+ assert(derivedAsBase->ice_id() == "::Printer");
cout << '\n'
<< "Now we install a factory for the derived class, and try again.\n"
- << "We won't get a `no factory' exception anymore, but since we\n"
- << "receive the derived object as base object, we need to do a\n"
- << "dynamic_cast<> to get from the base to the derived object.\n"
+ << "Because we receive the derived object as a base object, we\n"
+ << "we need to do a dynamic_cast<> to get from the base to the derived object.\n"
<< "[press enter]\n";
cin.getline(&c, 1);
@@ -129,8 +137,8 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
derivedAsBase = initial->getDerivedPrinter();
DerivedPrinterPtr derived = DerivedPrinterPtr::dynamicCast(derivedAsBase);
assert(derived);
-
cout << "==> dynamic_cast<> to derived object succeded" << endl;
+ cout << "==> The type ID of the received object is \"" << derived->ice_id() << "\"" << endl;
cout << '\n'
<< "Let's print the message contained in the derived object, and\n"
@@ -150,6 +158,7 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
<< "[press enter]\n";
cin.getline(&c, 1);
+ gotException = false;
try
{
initial->throwDerivedPrinter();
@@ -158,7 +167,9 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
{
derived = ex.derived;
assert(derived);
+ gotException = true;
}
+ assert(gotException);
cout << "==> " << derived->derivedMessage << endl;
cout << "==> ";