#include <boost/test/minimal.hpp>
#include <RCF/Idl.hpp>
#include <RCF/RcfServer.hpp>
#include <RCF/TcpEndpoint.hpp>
#include <RCF/util/CommandLine.hpp>
#include <RCF/util/PortNumbers.hpp>
// interface inheritance hierarchies
//
//A1 <- B1 <- C1 <-
// \
// D
// /
//A2 <- B2 <- C2 <-
//
//A1 <- X <-
// \
// Z
// /
//A1 <- Y <-
//
// I_E <- E
RCF_BEGIN(A1, "A1")
RCF_METHOD_R0(std::string, funcA1)
RCF_END(A1)
namespace N1 {
RCF_BEGIN_INHERITED_1(B1, "B1", A1)
RCF_METHOD_R0(std::string, funcB1)
RCF_END(B1)
namespace N2 {
RCF_BEGIN_INHERITED_1(C1, "C1", B1)
RCF_METHOD_R0(std::string, funcC1)
RCF_END(C1)
} // namespace N2
} // namespace N1
namespace N3 {
RCF_BEGIN(A2,"A2")
RCF_METHOD_R0(std::string, funcA2)
RCF_END(A2)
RCF_BEGIN_INHERITED_1(B2,"B2", A2)
RCF_METHOD_R0(std::string, funcB2)
RCF_END(B2)
RCF_BEGIN_INHERITED_1(C2,"C2", B2)
RCF_METHOD_R0(std::string, funcC2)
RCF_END(C2)
} // namespace N3
RCF_BEGIN_INHERITED_2(D, "D", N1::N2::C1, N3::C2)
RCF_METHOD_R0(std::string, funcD)
RCF_END(D)
RCF_BEGIN_INHERITED_1(X, "X", A1)
RCF_METHOD_R0(std::string, funcX)
RCF_END(X)
RCF_BEGIN_INHERITED_1(Y, "Y", A1)
RCF_METHOD_R0(std::string, funcY)
RCF_END(Y)
RCF_BEGIN_INHERITED_2(Z, "Z", X, Y)
RCF_METHOD_R0(std::string, funcZ)
RCF_END(Z)
class I_E
{
public:
virtual ~I_E() {}
virtual std::string funcE() = 0;
};
RCF_BEGIN_INHERITED_1(E, "E", I_E)
RCF_METHOD_R0(std::string, funcE)
RCF_END(E)
class ServerImpl
{
public:
std::string funcA1() { return "A1"; }
std::string funcB1() { return "B1"; }
std::string funcC1() { return "C1"; }
std::string funcA2() { return "A2"; }
std::string funcB2() { return "B2"; }
std::string funcC2() { return "C2"; }
std::string funcD() { return "D"; }
std::string funcX() { return "X"; }
std::string funcY() { return "Y"; }
std::string funcZ() { return "Z"; }
std::string funcE() { return "E"; }
};
class ClientTask
{
public:
ClientTask(const RCF::TcpEndpoint &clientEndpoint) : mClientEndpoint(clientEndpoint)
{}
void operator()()
{
typedef A1::RcfClient RcfClientA1;
typedef N1::B1::RcfClient RcfClientB1;
typedef N1::N2::C1::RcfClient RcfClientC1;
typedef N3::A2::RcfClient RcfClientA2;
typedef N3::B2::RcfClient RcfClientB2;
typedef N3::C2::RcfClient RcfClientC2;
typedef D::RcfClient RcfClientD;
typedef X::RcfClient RcfClientX;
typedef Y::RcfClient RcfClientY;
typedef Z::RcfClient RcfClientZ;
typedef RcfClient<E> RcfClientE;
std::string s;
s = RcfClientA1(mClientEndpoint).funcA1(); BOOST_CHECK(s == "A1");
s = RcfClientB1(mClientEndpoint).funcA1(); BOOST_CHECK(s == "A1");
s = RcfClientB1(mClientEndpoint).funcB1(); BOOST_CHECK(s == "B1");
s = RcfClientC1(mClientEndpoint).funcA1(); BOOST_CHECK(s == "A1");
s = RcfClientC1(mClientEndpoint).funcB1(); BOOST_CHECK(s == "B1");
s = RcfClientC1(mClientEndpoint).funcC1(); BOOST_CHECK(s == "C1");
s = RcfClientA2(mClientEndpoint).funcA2(); BOOST_CHECK(s == "A2");
s = RcfClientB2(mClientEndpoint).funcA2(); BOOST_CHECK(s == "A2");
s = RcfClientB2(mClientEndpoint).funcB2(); BOOST_CHECK(s == "B2");
s = RcfClientC2(mClientEndpoint).funcA2(); BOOST_CHECK(s == "A2");
s = RcfClientC2(mClientEndpoint).funcB2(); BOOST_CHECK(s == "B2");
s = RcfClientC2(mClientEndpoint).funcC2(); BOOST_CHECK(s == "C2");
s = RcfClientD(mClientEndpoint).funcA1(); BOOST_CHECK(s == "A1");
s = RcfClientD(mClientEndpoint).funcA2(); BOOST_CHECK(s == "A2");
s = RcfClientD(mClientEndpoint).funcB1(); BOOST_CHECK(s == "B1");
s = RcfClientD(mClientEndpoint).funcB2(); BOOST_CHECK(s == "B2");
s = RcfClientD(mClientEndpoint).funcC1(); BOOST_CHECK(s == "C1");
s = RcfClientD(mClientEndpoint).funcC2(); BOOST_CHECK(s == "C2");
s = RcfClientD(mClientEndpoint).funcD(); BOOST_CHECK(s == "D");
s = RcfClientX(mClientEndpoint).funcA1(); BOOST_CHECK(s == "A1");
s = RcfClientX(mClientEndpoint).funcX(); BOOST_CHECK(s == "X");
s = RcfClientY(mClientEndpoint).funcA1(); BOOST_CHECK(s == "A1");
s = RcfClientY(mClientEndpoint).funcY(); BOOST_CHECK(s == "Y");
s = RcfClientZ(mClientEndpoint).RcfClientX::funcA1(); BOOST_CHECK(s == "A1");
s = RcfClientZ(mClientEndpoint).funcX(); BOOST_CHECK(s == "X");
s = RcfClientZ(mClientEndpoint).RcfClientY::funcA1(); BOOST_CHECK(s == "A1");
s = RcfClientZ(mClientEndpoint).funcY(); BOOST_CHECK(s == "Y");
s = RcfClientZ(mClientEndpoint).funcZ(); BOOST_CHECK(s == "Z");
RcfClient<E>(mClientEndpoint).funcE();
std::auto_ptr<I_E> e( new RcfClient<E>(mClientEndpoint) );
s = e->funcE(); BOOST_CHECK(s == "E");
}
private:
const RCF::TcpEndpoint &mClientEndpoint;
};
int test_main(int argc, char **argv)
{
std::string ip = "localhost";
util::CommandLineOption<int> port( "port", util::Ports::getNext(), "TCP port number" );
util::CommandLine::getSingleton().parse(argc, argv);
ServerImpl serverImpl;
RCF::RcfServer server( (RCF::TcpEndpoint(port)) );
server.bind<A1>(serverImpl);
server.bind<N1::B1>(serverImpl);
server.bind<N1::N2::C1>(serverImpl);
server.bind<N3::A2>(serverImpl);
server.bind<N3::B2>(serverImpl);
server.bind<N3::C2>(serverImpl);
server.bind<D>(serverImpl);
server.bind<X>(serverImpl);
server.bind<Y>(serverImpl);
server.bind<Z>(serverImpl);
server.bind<E>(serverImpl);
server.start();
RCF::TcpEndpoint tcpEndpoint(ip, port);
RCF::Thread thread((ClientTask(tcpEndpoint)));
thread.join();
return boost::exit_success;
}