diff --git a/testApp/client/MockClientImpl.cpp b/testApp/client/MockClientImpl.cpp index 5bb0392..e6e6844 100644 --- a/testApp/client/MockClientImpl.cpp +++ b/testApp/client/MockClientImpl.cpp @@ -4,14 +4,196 @@ #include #include +#include +#include using namespace epics::pvData; using namespace epics::pvAccess; + + +static volatile int64 mockChannel_totalConstruct = 0; +static volatile int64 mockChannel_totalDestruct = 0; +static Mutex *mockChannel_globalMutex = 0; + +static int64 mockChannel_getTotalConstruct() +{ + Lock xx(mockChannel_globalMutex); + return mockChannel_totalConstruct; +} + +static int64 mockChannel_getTotalDestruct() +{ + Lock xx(mockChannel_globalMutex); + return mockChannel_totalDestruct; +} + +static ConstructDestructCallback *mockChannel_pConstructDestructCallback; + +static void mockChannel_init() +{ + static Mutex mutex = Mutex(); + Lock xx(&mutex); + if(mockChannel_globalMutex==0) { + mockChannel_globalMutex = new Mutex(); + mockChannel_pConstructDestructCallback = new ConstructDestructCallback( + String("mockChannel"), + mockChannel_getTotalConstruct,mockChannel_getTotalDestruct,0); + } +} + + +class MockChannel : public Channel { + private: + ChannelProvider* m_provider; + ChannelRequester* m_requester; + String m_name; + String m_remoteAddress; + + private: + ~MockChannel() + { + Lock xx(mockChannel_globalMutex); + mockChannel_totalDestruct++; + } + + public: + + MockChannel( + ChannelProvider* provider, + ChannelRequester* requester, + String name, + String remoteAddress) : + m_provider(provider), + m_requester(requester), + m_name(name), + m_remoteAddress(remoteAddress) + { + mockChannel_init(); + + Lock xx(mockChannel_globalMutex); + mockChannel_totalConstruct++; + + // already connected, report state + m_requester->channelStateChange(this, CONNECTED); + } + + virtual void destroy() + { + delete this; + }; + + virtual String getRequesterName() + { + return getChannelName(); + }; + + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl; + } + + virtual ChannelProvider* getProvider() + { + return m_provider; + } + + virtual epics::pvData::String getRemoteAddress() + { + return m_remoteAddress; + } + + virtual epics::pvData::String getChannelName() + { + return m_name; + } + + virtual ChannelRequester* getChannelRequester() + { + return m_requester; + } + + virtual ConnectionState getConnectionState() + { + return CONNECTED; + } + + virtual bool isConnected() + { + return getConnectionState() == CONNECTED; + } + + virtual AccessRights getAccessRights(epics::pvData::PVField *pvField) + { + return readWrite; + } + + virtual void getField(GetFieldRequester *requester,epics::pvData::String subField) + { + // TODO + } + + virtual ChannelProcess* createChannelProcess( + ChannelProcessRequester *channelProcessRequester, + epics::pvData::PVStructure *pvRequest) + { + // TODO + return 0; + } + + virtual ChannelGet* createChannelGet( + ChannelGetRequester *channelGetRequester, + epics::pvData::PVStructure *pvRequest) + { + // TODO + return 0; + } + + virtual ChannelPut* createChannelPut( + ChannelPutRequester *channelPutRequester, + epics::pvData::PVStructure *pvRequest) + { + // TODO + return 0; + } + + virtual ChannelPutGet* createChannelPutGet( + ChannelPutGetRequester *channelPutGetRequester, + epics::pvData::PVStructure *pvRequest) + { + // TODO + return 0; + } + + virtual ChannelRPC* createChannelRPC(ChannelRPCRequester *channelRPCRequester, + epics::pvData::PVStructure *pvRequest) + { + // TODO + return 0; + } + + virtual epics::pvData::Monitor* createMonitor( + epics::pvData::MonitorRequester *monitorRequester, + epics::pvData::PVStructure *pvRequest) + { + // TODO + return 0; + } + + virtual ChannelArray* createChannelArray( + ChannelArrayRequester *channelArrayRequester, + epics::pvData::PVStructure *pvRequest) + { + // TODO + return 0; + } +}; + + class MockChannelProvider : public ChannelProvider { -public: + public: virtual epics::pvData::String getProviderName() { @@ -48,15 +230,15 @@ public: { if (address == "local") { - Channel* channel = 0; + Channel* channel = new MockChannel(this, channelRequester, channelName, address); channelRequester->channelCreated(getStatusCreate()->getStatusOK(), channel); - // TODO state change return channel; } else { Status* errorStatus = getStatusCreate()->createStatus(STATUSTYPE_ERROR, "only local supported", 0); channelRequester->channelCreated(errorStatus, 0); + delete errorStatus; // TODO guard from CB return 0; } } @@ -78,11 +260,11 @@ class MockClientContext : public ClientContext initialize(); } - virtual const Version* getVersion() { + virtual Version* getVersion() { return m_version; } - virtual const ChannelProvider* getProvider() { + virtual ChannelProvider* getProvider() { return m_provider; } @@ -120,12 +302,50 @@ class MockClientContext : public ClientContext }; +class ChannelRequesterImpl : public ChannelRequester +{ + virtual String getRequesterName() + { + return "ChannelRequesterImpl"; + }; + + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl; + } + + virtual void channelCreated(epics::pvData::Status* status, Channel *channel) + { + std::cout << "channelCreated("; + String str; + status->toString(&str); + std::cout << str << ", " << (channel ? channel->getChannelName() : "(null)") << ")" << std::endl; + } + + virtual void channelStateChange(Channel *c, ConnectionState connectionState) + { + std::cout << "channelStateChange(" << c->getChannelName() << ", " << ConnectionStateNames[connectionState] << ")" << std::endl; + } +}; + int main(int argc,char *argv[]) { MockClientContext* context = new MockClientContext(); context->printInfo(); + ChannelRequesterImpl requester; + + /*Channel* noChannel =*/ context->getProvider()->createChannel("test", &requester, ChannelProvider::PRIORITY_DEFAULT, "over the rainbow"); + + Channel* channel = context->getProvider()->createChannel("test", &requester); + std::cout << channel->getChannelName() << std::endl; + channel->destroy(); + + context->destroy(); + + std::cout << "-----------------------------------------------------------------------" << std::endl; + getShowConstructDestruct()->constuctDestructTotals(stdout); return(0); }