summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/CHANGES46
-rw-r--r--cpp/src/Slice/PythonUtil.cpp17
-rw-r--r--cpp/src/Slice/RubyUtil.cpp27
-rw-r--r--cpp/src/slice2cpp/Gen.cpp47
-rw-r--r--cpp/src/slice2cpp/Gen.h1
-rwxr-xr-xcpp/src/slice2cs/Gen.cpp20
-rw-r--r--cpp/src/slice2java/Gen.cpp15
-rwxr-xr-xcpp/src/slice2vb/Gen.cpp20
-rw-r--r--cpp/test/Ice/objects/AllTests.cpp8
-rw-r--r--cpp/test/Ice/objects/Client.cpp10
-rw-r--r--cpp/test/Ice/objects/Test.ice18
-rw-r--r--cpp/test/Ice/objects/TestI.cpp42
-rw-r--r--cpp/test/Ice/objects/TestI.h23
13 files changed, 255 insertions, 39 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES
index 6a03aabcd23..abffcdfbfd7 100644
--- a/cpp/CHANGES
+++ b/cpp/CHANGES
@@ -1,18 +1,14 @@
-Changes since version 3.2.X (binary incompabible)
+Changes since version 3.2.X (binary incompatible)
-------------------------------------------------
-- Ice.Default.CollocationOptimization and the <any>.CollocationOptimization
- proxy property have been deprecated and replaced by
- Ice.Default.CollocationOptimized and <any>.CollocationOptimized
- respectively.
-
-- IceGrid now allows defining an object adapter with a replica group
- from an other IceGrid application than the one where the object
- adapter is defined.
+- The property Ice.Default.CollocationOptimization and the
+ proxy property <any>.CollocationOptimization have been deprecated
+ and replaced by Ice.Default.CollocationOptimized and
+ <any>.CollocationOptimized, respectively.
- Added a new method to the ObjectAdapter interface named
refreshPublishedEndpoints(). This method is meant to be used to
- update the published endpoints after change in the available local
+ update the published endpoints after a change in the available local
interfaces or after the PublishedEndpoints object adapter property
has been changed by the user.
@@ -33,11 +29,12 @@ Changes since version 3.2.X (binary incompabible)
- The IceGrid node now unblocks the SIGHUP, SIGINT and SIGTERM signals
from forked servers.
-- Added support for udp multicast. See manual for more information.
+- Added support for UDP multicast. See manual for more information.
-- If a proxy contains a host which is multihomed, the client will now
- try all the available ip addresses. Previously, only the first in the
- address list returned by the DNS was used and others were ignored.
+- If a proxy contains a host that is multihomed, the client will now
+ try all the available IP addresses. Previously, only the first in
+ the address list returned by the DNS was used and others were
+ ignored.
- Added a new property, Ice.Warn.UnusedProperties. If set to 1, when
the communicator is destroyed a warning will be printed listing all
@@ -56,8 +53,8 @@ Changes since version 3.2.X (binary incompabible)
// including Ice exceptions
}
- what() is implemented in terms of ice_print(), so overriding ice_print()
- also changes the string returned by what().
+ what() is implemented in terms of ice_print(), so overriding
+ ice_print() also changes the string returned by what().
- The IceGrid node now prints a warning if it can't reach the IceGrid
registry when it starts. This warning can be disabled with --nowarn.
@@ -65,13 +62,20 @@ Changes since version 3.2.X (binary incompabible)
Changes since version 3.2.0
---------------------------
-- Changed to the throughput demo to better support cross-language
+- Added support for protected class data members using the new
+ metadata tag ["protected"]. The tag can be applied to a Slice class
+ or to individual data members.
+
+- IceGrid now allows you to define an object adapter with a replica
+ group from a different IceGrid application.
+
+- Changed the throughput demo to better support cross-language
testing.
-- Fixed bug with IceUtil::Cond under Windows which could cause a
- deadlock if signal was used in conjunction multiple waiting threads
- where at least one thread is using timedWait. Note that this bug
- also affects IceUtil::Monitor since this uses IceUtil::Cond.
+- Fixed a bug in IceUtil::Cond under Windows that could cause a
+ deadlock if a signal was used in conjunction with multiple waiting
+ threads where at least one thread is using timedWait. Note that this
+ bug also affects IceUtil::Monitor since this uses IceUtil::Cond.
- Fixed throughput performance problem on Windows that would occur
when sending large requests.
diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp
index 9815b210aea..7278922735d 100644
--- a/cpp/src/Slice/PythonUtil.cpp
+++ b/cpp/src/Slice/PythonUtil.cpp
@@ -742,13 +742,19 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
_out.inc();
_out << nl;
}
+ bool isProtected = p->hasMetaData("protected");
for(DataMemberList::iterator r = members.begin(); r != members.end(); ++r)
{
if(r != members.begin())
{
_out << ',' << nl;
}
- _out << "('" << fixIdent((*r)->name()) << "', ";
+ _out << "('";
+ if(isProtected || (*r)->hasMetaData("protected"))
+ {
+ _out << '_';
+ }
+ _out << fixIdent((*r)->name()) << "', ";
writeMetaData((*r)->getMetaData());
_out << ", ";
writeType((*r)->type());
@@ -1703,7 +1709,14 @@ Slice::Python::CodeVisitor::collectClassMembers(const ClassDefPtr& p, MemberInfo
for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
{
MemberInfo m;
- m.fixedName = fixIdent((*q)->name());
+ if(p->hasMetaData("protected") || (*q)->hasMetaData("protected"))
+ {
+ m.fixedName = "_" + fixIdent((*q)->name());
+ }
+ else
+ {
+ m.fixedName = fixIdent((*q)->name());
+ }
m.type = (*q)->type();
m.inherited = inherited;
m.metaData = (*q)->getMetaData();
diff --git a/cpp/src/Slice/RubyUtil.cpp b/cpp/src/Slice/RubyUtil.cpp
index 39fcd879c66..f0c664629f8 100644
--- a/cpp/src/Slice/RubyUtil.cpp
+++ b/cpp/src/Slice/RubyUtil.cpp
@@ -353,14 +353,39 @@ Slice::Ruby::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
DataMemberList members = p->dataMembers();
if(!members.empty())
{
+ bool prot = p->hasMetaData("protected");
+ DataMemberList protectedMembers;
+ DataMemberList::iterator q;
+
_out << sp << nl << "attr_accessor ";
- for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ for(q = members.begin(); q != members.end(); ++q)
{
if(q != members.begin())
{
_out << ", ";
}
_out << ":" << fixIdent((*q)->name(), IdentNormal);
+ if(prot || (*q)->hasMetaData("protected"))
+ {
+ protectedMembers.push_back(*q);
+ }
+ }
+
+ if(!protectedMembers.empty())
+ {
+ _out << nl << "protected ";
+ for(q = protectedMembers.begin(); q != protectedMembers.end(); ++q)
+ {
+ if(q != protectedMembers.begin())
+ {
+ _out << ", ";
+ }
+ //
+ // We need to list the symbols of the reader and the writer (e.g., ":member" and ":member=").
+ //
+ _out << ":" << fixIdent((*q)->name(), IdentNormal) << ", :"
+ << fixIdent((*q)->name(), IdentNormal) << '=';
+ }
}
}
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 539366963ed..dd7ccf7e8d3 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -3345,6 +3345,8 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
}
}
+ bool inProtected = false;
+
if(!p->isAbstract())
{
//
@@ -3359,6 +3361,42 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
{
H << sp << nl << "friend class " << p->name() << "__staticInit;";
}
+
+ inProtected = true;
+ }
+
+ //
+ // Emit data members. Access visibility may be specified by metadata.
+ //
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList::const_iterator q;
+ bool prot = p->hasMetaData("protected");
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if(prot || (*q)->hasMetaData("protected"))
+ {
+ if(!inProtected)
+ {
+ H.dec();
+ H << sp << nl << "protected:";
+ H.inc();
+ inProtected = true;
+ }
+ }
+ else
+ {
+ if(inProtected)
+ {
+ H.dec();
+ H << sp << nl << "public:";
+ H.inc();
+ inProtected = false;
+ }
+ }
+
+ string name = fixKwd((*q)->name());
+ string s = typeToString((*q)->type(), _useWstring, (*q)->getMetaData());
+ H << sp << nl << s << ' ' << name << ';';
}
H << eb << ';';
@@ -3369,6 +3407,7 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
// We need an instance here to trigger initialization if the implementation is in a shared library.
// But we do this only once per source file, because a single instance is sufficient to initialize
// all of the globals in a shared library.
+ //
// For a Slice class Foo, we instantiate a dummy class Foo__staticInit instead of using a static
// Foo instance directly because Foo has a protected destructor.
//
@@ -3678,14 +3717,6 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
}
void
-Slice::Gen::ObjectVisitor::visitDataMember(const DataMemberPtr& p)
-{
- string name = fixKwd(p->name());
- string s = typeToString(p->type(), _useWstring, p->getMetaData());
- H << nl << s << ' ' << name << ';';
-}
-
-void
Slice::Gen::ObjectVisitor::emitGCFunctions(const ClassDefPtr& p)
{
string scoped = fixKwd(p->scoped());
diff --git a/cpp/src/slice2cpp/Gen.h b/cpp/src/slice2cpp/Gen.h
index 11ae44bf575..221ccfd68c4 100644
--- a/cpp/src/slice2cpp/Gen.h
+++ b/cpp/src/slice2cpp/Gen.h
@@ -260,7 +260,6 @@ private:
virtual bool visitExceptionStart(const ExceptionPtr&);
virtual bool visitStructStart(const StructPtr&);
virtual void visitOperation(const OperationPtr&);
- virtual void visitDataMember(const DataMemberPtr&);
private:
diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp
index 93b926534e1..acc531ecd22 100755
--- a/cpp/src/slice2cs/Gen.cpp
+++ b/cpp/src/slice2cs/Gen.cpp
@@ -3031,6 +3031,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
bool isClass = false;
bool propertyMapping = false;
bool isValue = false;
+ bool isProtected = false;
ContainedPtr cont = ContainedPtr::dynamicCast(p->container());
assert(cont);
if(StructPtr::dynamicCast(cont))
@@ -3057,6 +3058,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
{
propertyMapping = true;
}
+ isProtected = cont->hasMetaData("protected") || p->hasMetaData("protected");
}
_out << sp;
@@ -3072,14 +3074,28 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
{
dataMemberName += "_prop";
}
- _out << nl << (propertyMapping ? "private" : "public") << ' ' << type << ' ' << dataMemberName << ';';
+
+ _out << nl;
+ if(propertyMapping)
+ {
+ _out << "private";
+ }
+ else if(isProtected)
+ {
+ _out << "protected";
+ }
+ else
+ {
+ _out << "public";
+ }
+ _out << ' ' << type << ' ' << dataMemberName << ';';
if(!propertyMapping)
{
return;
}
- _out << nl << "public";
+ _out << nl << (isProtected ? "protected" : "public");
if(!isValue)
{
_out << " virtual";
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index fb07de4ca1c..1309eb43c52 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -2596,7 +2596,20 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
out << nl << " * @deprecated " << deprecateReason;
out << nl << " **/";
}
- out << nl << "public " << s << ' ' << name << ';';
+
+ //
+ // Access visibility for class data members can be controlled by metadata.
+ // If none is specified, the default is public.
+ //
+ if(contained->containedType() == Contained::ContainedTypeClass &&
+ (p->hasMetaData("protected") || contained->hasMetaData("protected")))
+ {
+ out << nl << "protected " << s << ' ' << name << ';';
+ }
+ else
+ {
+ out << nl << "public " << s << ' ' << name << ';';
+ }
//
// Getter/Setter.
diff --git a/cpp/src/slice2vb/Gen.cpp b/cpp/src/slice2vb/Gen.cpp
index 2cbb6103d1c..043148e2eac 100755
--- a/cpp/src/slice2vb/Gen.cpp
+++ b/cpp/src/slice2vb/Gen.cpp
@@ -3373,6 +3373,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
bool isClass = false;
bool propertyMapping = false;
bool isValue = false;
+ bool isProtected = false;
ContainedPtr cont = ContainedPtr::dynamicCast(p->container());
assert(cont);
if(StructPtr::dynamicCast(cont))
@@ -3399,6 +3400,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
{
propertyMapping = true;
}
+ isProtected = cont->hasMetaData("protected") || p->hasMetaData("protected");
}
_out << sp;
@@ -3414,14 +3416,28 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
dataMemberName += "_prop";
}
- _out << nl << (propertyMapping ? "Private" : "Public") << ' ' << dataMemberName << " As " << type;
+ _out << nl;
+ if(propertyMapping)
+ {
+ _out << "Private";
+ }
+ else if(isProtected)
+ {
+ _out << "Protected";
+ }
+ else
+ {
+ _out << "Public";
+ }
+
+ _out << ' ' << dataMemberName << " As " << type;
if(!propertyMapping)
{
return;
}
- _out << nl << "Public";
+ _out << nl << (isProtected ? "Protected" : "Public");
if(!isValue)
{
_out << " Overridable";
diff --git a/cpp/test/Ice/objects/AllTests.cpp b/cpp/test/Ice/objects/AllTests.cpp
index e702d1ff35d..2d4a903118a 100644
--- a/cpp/test/Ice/objects/AllTests.cpp
+++ b/cpp/test/Ice/objects/AllTests.cpp
@@ -138,6 +138,14 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
}
cout << "ok" << endl;
+ cout << "testing protected members... " << flush;
+ EPtr e = initial->getE();
+ test(e->checkValues());
+ FPtr f = initial->getF();
+ test(f->checkValues());
+ test(f->e2->checkValues());
+ cout << "ok" << endl;
+
cout << "getting I, J and H... " << flush;
IPtr i = initial->getI();
test(i);
diff --git a/cpp/test/Ice/objects/Client.cpp b/cpp/test/Ice/objects/Client.cpp
index 406a6013275..e4bbce5fd14 100644
--- a/cpp/test/Ice/objects/Client.cpp
+++ b/cpp/test/Ice/objects/Client.cpp
@@ -32,6 +32,14 @@ public:
{
return new DI;
}
+ else if(type == "::Test::E")
+ {
+ return new EI;
+ }
+ else if(type == "::Test::F")
+ {
+ return new FI;
+ }
else if(type == "::Test::I")
{
return new II;
@@ -62,6 +70,8 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
communicator->addObjectFactory(factory, "::Test::B");
communicator->addObjectFactory(factory, "::Test::C");
communicator->addObjectFactory(factory, "::Test::D");
+ communicator->addObjectFactory(factory, "::Test::E");
+ communicator->addObjectFactory(factory, "::Test::F");
communicator->addObjectFactory(factory, "::Test::I");
communicator->addObjectFactory(factory, "::Test::J");
communicator->addObjectFactory(factory, "::Test::H");
diff --git a/cpp/test/Ice/objects/Test.ice b/cpp/test/Ice/objects/Test.ice
index 042150fe3df..6d9726cb7ca 100644
--- a/cpp/test/Ice/objects/Test.ice
+++ b/cpp/test/Ice/objects/Test.ice
@@ -59,6 +59,22 @@ class D
bool postUnmarshalInvoked();
};
+["protected"] class E
+{
+ int i;
+ string s;
+
+ bool checkValues();
+};
+
+class F
+{
+ ["protected"] E e1;
+ E e2;
+
+ bool checkValues();
+};
+
interface I
{
};
@@ -78,6 +94,8 @@ class Initial
B getB2();
C getC();
D getD();
+ E getE();
+ F getF();
void getAll(out B b1, out B b2, out C theC, out D theD);
diff --git a/cpp/test/Ice/objects/TestI.cpp b/cpp/test/Ice/objects/TestI.cpp
index 194e3917737..567a5bface1 100644
--- a/cpp/test/Ice/objects/TestI.cpp
+++ b/cpp/test/Ice/objects/TestI.cpp
@@ -81,12 +81,40 @@ DI::ice_postUnmarshal()
_postUnmarshalInvoked = true;
}
+EI::EI() :
+ E(1, "hello")
+{
+}
+
+bool
+EI::checkValues(const Ice::Current&)
+{
+ return i == 1 && s == "hello";
+}
+
+FI::FI()
+{
+}
+
+FI::FI(const EPtr& e) :
+ F(e, e)
+{
+}
+
+bool
+FI::checkValues(const Ice::Current&)
+{
+ return e1 && e1 == e2;
+}
+
InitialI::InitialI(const Ice::ObjectAdapterPtr& adapter) :
_adapter(adapter),
_b1(new BI),
_b2(new BI),
_c(new CI),
- _d(new DI)
+ _d(new DI),
+ _e(new EI),
+ _f(new FI(_e))
{
_b1->theA = _b2; // Cyclic reference to another B
_b1->theB = _b1; // Self reference.
@@ -146,6 +174,18 @@ InitialI::getD(const Ice::Current&)
return _d;
}
+EPtr
+InitialI::getE(const Ice::Current&)
+{
+ return _e;
+}
+
+FPtr
+InitialI::getF(const Ice::Current&)
+{
+ return _f;
+}
+
void
InitialI::getAll(BPtr& b1, BPtr& b2, CPtr& c, DPtr& d, const Ice::Current&)
{
diff --git a/cpp/test/Ice/objects/TestI.h b/cpp/test/Ice/objects/TestI.h
index f7b110fad89..86b3edbd94e 100644
--- a/cpp/test/Ice/objects/TestI.h
+++ b/cpp/test/Ice/objects/TestI.h
@@ -60,6 +60,25 @@ private:
bool _postUnmarshalInvoked;
};
+class EI : public Test::E
+{
+public:
+
+ EI();
+
+ virtual bool checkValues(const Ice::Current&);
+};
+
+class FI : public Test::F
+{
+public:
+
+ FI();
+ FI(const Test::EPtr&);
+
+ virtual bool checkValues(const Ice::Current&);
+};
+
class II : public Test::I
{
};
@@ -83,6 +102,8 @@ public:
virtual Test::BPtr getB2(const Ice::Current&);
virtual Test::CPtr getC(const Ice::Current&);
virtual Test::DPtr getD(const Ice::Current&);
+ virtual Test::EPtr getE(const Ice::Current&);
+ virtual Test::FPtr getF(const Ice::Current&);
virtual void getAll(Test::BPtr&, Test::BPtr&, Test::CPtr&, Test::DPtr&, const Ice::Current&);
virtual Test::IPtr getI(const Ice::Current&);
virtual Test::IPtr getJ(const Ice::Current&);
@@ -97,6 +118,8 @@ private:
Test::BPtr _b2;
Test::CPtr _c;
Test::DPtr _d;
+ Test::EPtr _e;
+ Test::FPtr _f;
};
class UnexpectedObjectExceptionTestI : public Ice::Blobject