15#include <pv/createRequest.h>
17#define epicsExportSharedSymbols
21using namespace epics::pvData;
22using namespace epics::pvAccess;
25namespace epics {
namespace pvaClient {
28class epicsShareClass PvaClientGetCache
34 if(PvaClient::getDebug()) cout <<
"PvaClientGetCache::~PvaClientGetCache\n";
36 PvaClientGetPtr getGet(
string const & request);
37 void addGet(
string const & request,PvaClientGetPtr
const & pvaClientGet);
41 map<string,PvaClientGetPtr> pvaClientGetMap;
46 map<string,PvaClientGetPtr>::iterator iter = pvaClientGetMap.find(request);
47 if(iter!=pvaClientGetMap.end())
return iter->second;
51void PvaClientGetCache::addGet(
string const & request,
PvaClientGetPtr const & pvaClientGet)
53 map<string,PvaClientGetPtr>::iterator iter = pvaClientGetMap.find(request);
54 if(iter!=pvaClientGetMap.end()) {
55 throw std::runtime_error(
"pvaClientGetCache::addGet pvaClientGet already cached");
57 pvaClientGetMap.insert(std::pair<string,PvaClientGetPtr>(request,pvaClientGet));
60void PvaClientGetCache::showCache()
62 map<string,PvaClientGetPtr>::iterator iter;
63 for(iter = pvaClientGetMap.begin(); iter != pvaClientGetMap.end(); ++iter)
65 cout <<
" " << iter->first << endl;
69size_t PvaClientGetCache::cacheSize()
71 return pvaClientGetMap.size();
75class epicsShareClass PvaClientPutCache
81 if(PvaClient::getDebug()) cout <<
"PvaClientPutCache::~PvaClientPutCache\n";
83 PvaClientPutPtr getPut(
string const & request);
84 void addPut(
string const & request,PvaClientPutPtr
const & pvaClientPut);
88 map<string,PvaClientPutPtr> pvaClientPutMap;
94 map<string,PvaClientPutPtr>::iterator iter = pvaClientPutMap.find(request);
95 if(iter!=pvaClientPutMap.end())
return iter->second;
99void PvaClientPutCache::addPut(
string const & request,
PvaClientPutPtr const & pvaClientPut)
101 map<string,PvaClientPutPtr>::iterator iter = pvaClientPutMap.find(request);
102 if(iter!=pvaClientPutMap.end()) {
103 throw std::runtime_error(
"pvaClientPutCache::addPut pvaClientPut already cached");
105 pvaClientPutMap.insert(std::pair<string,PvaClientPutPtr>(
106 request,pvaClientPut));
109void PvaClientPutCache::showCache()
111 map<string,PvaClientPutPtr>::iterator iter;
112 for(iter = pvaClientPutMap.begin(); iter != pvaClientPutMap.end(); ++iter)
114 cout <<
" " << iter->first << endl;
118size_t PvaClientPutCache::cacheSize()
120 return pvaClientPutMap.size();
126 string const & channelName,
127 string const & providerName)
134PvaClientChannel::PvaClientChannel(
136 string const & channelName,
137 string const & providerName)
138: pvaClient(pvaClient),
139 channelName(channelName),
140 providerName(providerName),
141 connectState(connectIdle),
142 createRequest(CreateRequest::create()),
143 pvaClientGetCache(
new PvaClientGetCache()),
144 pvaClientPutCache(
new PvaClientPutCache())
147 cout <<
"PvaClientChannel::PvaClientChannel channelName " << channelName << endl;
154 cout <<
"PvaClientChannel::~PvaClientChannel() "
155 <<
" channelName " << channelName
164 cout <<
"PvaClientChannel::channelCreated"
165 <<
" channelName " << channelName
166 <<
" connectState " << connectState
167 <<
" isConnected " << (channel->isConnected() ?
"true" :
"false")
168 <<
" status.isOK " << (status.isOK() ?
"true" :
"false")
172 this->channel = channel;
173 if(connectState==connected)
return;
174 if(connectState!=connectActive) {
175 string message(
"PvaClientChannel::channelCreated");
176 message +=
" channel " + channelName
177 +
" why was this called when connectState!=ConnectState.connectActive";
178 throw std::runtime_error(
message);
181 string message(
"PvaClientChannel::channelCreated");
182 message +=
" channel " + channelName
183 +
" status " + status.getMessage() +
" why??";
184 throw std::runtime_error(
message);
189 Channel::shared_pointer
const & channel,
190 Channel::ConnectionState connectionState)
193 cout <<
" PvaClientChannel::channelStateChange "
194 <<
" channelName " << channelName
195 <<
" " << Channel::ConnectionStateNames[connectionState]
198 bool waitingForConnect =
false;
199 if(connectState==connectActive) waitingForConnect =
true;
200 if(connectionState!=Channel::CONNECTED) {
202 connectState = notConnected;
205 this->channel = channel;
206 connectState = connected;
208 if(waitingForConnect) {
210 waitForConnect.signal();
214 bool value = (connectionState==Channel::CONNECTED ? true :
false);
215 req->channelStateChange(shared_from_this(),value);
222 if(!yyy)
return string(
"PvaClientChannel::getRequesterName() PvaClient isDestroyed");
223 return yyy->getRequesterName();
227 string const & message,
228 MessageType messageType)
232 yyy->message(channelName +
" " +
message, messageType);
248 this->stateChangeRequester = stateChangeRequester;
249 bool isConnected =
false;
250 if(channel) isConnected = channel->isConnected();
251 stateChangeRequester->channelStateChange(shared_from_this(),isConnected);
257 cout <<
"PvaClientChannel::connect"
258 <<
" channelName " << channelName << endl;
262 if(status.isOK())
return;
264 string message = string(
"channel ") + channelName
265 +
" PvaClientChannel::connect " + status.getMessage();
266 throw std::runtime_error(
message);
272 cout <<
"PvaClientChannel::issueConnect"
273 <<
" channelName " << channelName << endl;
277 if(connectState==connected)
return;
278 if(connectState!=connectIdle) {
279 throw std::runtime_error(
"pvaClientChannel already connected");
281 connectState = connectActive;
283 ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
284 channelProvider = reg->getProvider(providerName);
285 if(!channelProvider) {
286 throw std::runtime_error(channelName +
" provider " + providerName +
" not registered");
288 if(
PvaClient::getDebug()) cout <<
"PvaClientChannel::issueConnect calling provider->createChannel\n";
289 channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT);
291 throw std::runtime_error(channelName +
" channelCreate failed ");
298 cout <<
"PvaClientChannel::waitConnect"
299 <<
" channelName " << channelName << endl;
303 if(!channel)
return Status(Status::STATUSTYPE_ERROR,
"");
304 if(channel->isConnected())
return Status::Ok;
307 waitForConnect.wait(timeout);
309 waitForConnect.wait();
311 if(!channel)
return Status(Status::STATUSTYPE_ERROR,
"pvaClientChannel::waitConnect channel is null");
312 if(channel->isConnected())
return Status::Ok;
313 return Status(Status::STATUSTYPE_ERROR,
" not connected");
318 PVStructurePtr pvRequest = createRequest->createRequest(request);
320 string message = string(
"channel ") + channelName
321 +
" PvaClientChannel::createProcess invalid pvRequest: "
322 + createRequest->getMessage();
323 throw std::runtime_error(
message);
330 if(connectState!=connected)
connect(5.0);
332 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
342 pvaClientGet->connect();
343 pvaClientGetCache->addGet(request,pvaClientGet);
352 PVStructurePtr pvRequest = createRequest->createRequest(request);
354 string message = string(
"channel ") + channelName
355 +
" PvaClientChannel::createGet invalid pvRequest: "
356 + createRequest->getMessage();
357 throw std::runtime_error(
message);
364 if(connectState!=connected)
connect(5.0);
366 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
372 return get(request)->getData()->getDouble();
377 return get(request)->getData()->getString();
382 return get(request)->getData()->getDoubleArray();
387 return get(request)->getData()->getStringArray();
394 if(pvaClientPut)
return pvaClientPut;
397 pvaClientPut->connect();
399 pvaClientPutCache->addPut(request,pvaClientPut);
407 PVStructurePtr pvRequest = createRequest->createRequest(request);
409 string message = string(
"channel ") + channelName
410 +
" PvaClientChannel::createPut invalid pvRequest: "
411 + createRequest->getMessage();
412 throw std::runtime_error(
message);
419 if(connectState!=connected)
connect(5.0);
421 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
429 putData->putDouble(value); clientPut->put();
436 putData->putString(value); clientPut->put();
440 shared_vector<const double>
const & value,
441 string const & request)
445 size_t n = value.size();
446 shared_vector<double> valueArray(n);
447 for(
size_t i=0; i<n; ++i) valueArray[i] = value[i];
448 putData->putDoubleArray(freeze(valueArray)); clientPut->put();
452 shared_vector<const string>
const & value,
453 string const & request)
457 size_t n = value.size();
458 shared_vector<string> valueArray(n);
459 for(
size_t i=0; i<n; ++i) valueArray[i] = value[i];
460 putData->putStringArray(freeze(valueArray)); clientPut->put();
465 PVStructurePtr pvRequest = createRequest->createRequest(request);
467 string message = string(
"channel ") + channelName
468 +
" PvaClientChannel::createPutGet invalid pvRequest: "
469 + createRequest->getMessage();
470 throw std::runtime_error(
message);
477 if(connectState!=connected)
connect(5.0);
479 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
486 pvaClientMonitor->connect();
487 pvaClientMonitor->start();
488 return pvaClientMonitor;
493 return monitor(
"field(value,alarm,timeStamp)",pvaClientMonitorRequester);
500 pvaClientMonitor->connect();
501 pvaClientMonitor->setRequester(pvaClientMonitorRequester);
502 pvaClientMonitor->start();
503 return pvaClientMonitor;
508 PVStructurePtr pvRequest = createRequest->createRequest(request);
510 string message = string(
"channel ") + channelName
511 +
" PvaClientChannel::createMonitor invalid pvRequest: "
512 + createRequest->getMessage();
513 throw std::runtime_error(
message);
520 if(connectState!=connected)
connect(5.0);
522 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
527 PVStructurePtr
const & pvRequest,
528 PVStructurePtr
const & pvArgument)
532 return rpc->request(pvArgument);
536 PVStructurePtr
const & pvArgument)
539 return rpc->request(pvArgument);
544 if(connectState!=connected)
connect(5.0);
546 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
552 if(connectState!=connected)
connect(5.0);
554 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
560 if(pvaClientGetCache->cacheSize()>=1) {
561 cout <<
" pvaClientGet cache" << endl;
562 pvaClientGetCache->showCache();
564 cout <<
" pvaClientGet cache is empty\n";
566 if(pvaClientPutCache->cacheSize()>=1) {
567 cout <<
" pvaClientPut cache" << endl;
568 pvaClientPutCache->showCache();
570 cout <<
" pvaClientPut cache is empty\n";
576 return pvaClientGetCache->cacheSize() + pvaClientPutCache->cacheSize();
PvaClientGetPtr createGet(std::string const &request="field(value,alarm,timeStamp)")
create a PvaClientGet.
void putDouble(double value, std::string const &request="field(value)")
Put the value as a double.
void putDoubleArray(epics::pvData::shared_vector< const double > const &value, std::string const &request="field(value)")
Copy the array to the value field.
size_t cacheSize()
Get the number of cached gets and puts.
PvaClientPutPtr put(std::string const &request="field(value)")
create a PvaClientPut.
void issueConnect()
Issue a connect request and return immediately.
PvaClientPutGetPtr createPutGet(std::string const &request="putField(argument)getField(result)")
create a PvaClientPutGet.
PvaClientGetPtr get(std::string const &request="field(value,alarm,timeStamp)")
create a PvaChannelGet
std::string getChannelName()
Get the name of the channel to which PvaClientChannel is connected.
epics::pvData::Status waitConnect(double timeout=5.0)
Wait until the connection completes or for timeout.
void putStringArray(epics::pvData::shared_vector< const std::string > const &value, std::string const &request="field(value)")
Copy array to the value field.
void putString(std::string const &value, std::string const &request="field(value)")
Put the value as a string.
void showCache()
Show the list of cached gets and puts.
virtual void message(std::string const &message, epics::pvData::MessageType messageType)
std::string getString(std::string const &request="field(value)")
double getDouble(std::string const &request="field(value)")
Get the value as a double.
virtual std::string getRequesterName()
epics::pvData::PVStructurePtr rpc(epics::pvData::PVStructurePtr const &pvRequest, epics::pvData::PVStructurePtr const &pvArgument)
Issue a channelRPC request.
PvaClientPutPtr createPut(std::string const &request="field(value)")
create a PvaClientPut.
void setStateChangeRequester(PvaClientChannelStateChangeRequesterPtr const &stateChangeRequester)
Set a client stateChangeRequester.
virtual void channelStateChange(epics::pvAccess::Channel::shared_pointer const &channel, epics::pvAccess::Channel::ConnectionState connectionState)
PvaClientMonitorPtr monitor(std::string const &request="field(value,alarm,timeStamp)")
Create a PvaClientMonitor.
virtual void channelCreated(const epics::pvData::Status &status, epics::pvAccess::Channel::shared_pointer const &channel)
epics::pvAccess::Channel::shared_pointer getChannel()
Get the the channel to which PvaClientChannel is connected.
PvaClientMonitorPtr createMonitor(std::string const &request="field(value,alarm,timeStamp)")
First call createRequest as implemented by pvDataJava and then call the next method.
~PvaClientChannel()
Destructor.
epics::pvData::shared_vector< const std::string > getStringArray(std::string const &request="field(value)")
Get the value as a string array.
PvaClientProcessPtr createProcess(std::string const &request="")
First call createRequest as implemented by pvDataCPP and then call the next method.
PvaClientRPCPtr createRPC()
Create a PvaClientRPC.
epics::pvData::shared_vector< const double > getDoubleArray(std::string const &request="field(value)")
Get the value as a double array.
void connect(double timeout=5.0)
Connect to the channel.
static PvaClientGetPtr create(PvaClientPtr const &pvaClient, PvaClientChannelPtr const &pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest)
Create a PvaClientGet.
static PvaClientMonitorPtr create(PvaClientPtr const &pvaClient, PvaClientChannelPtr const &pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest)
Create a PvaClientMonitor.
static PvaClientProcessPtr create(PvaClientPtr const &pvaClient, PvaClientChannelPtr const &pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest)
Create a PvaClientProcess.
static PvaClientPutGetPtr create(PvaClientPtr const &pvaClient, PvaClientChannelPtr const &pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest)
Create a PvaClientPutGet.
static PvaClientPutPtr create(PvaClientPtr const &pvaClient, PvaClientChannelPtr const &pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest)
Create a PvaClientPut.
static PvaClientRPCPtr create(PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const &channel)
Create a PvaClientRPC.
static bool getDebug()
Is debug set?
std::tr1::shared_ptr< PvaClientPutGet > PvaClientPutGetPtr
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
std::tr1::shared_ptr< PvaClientGet > PvaClientGetPtr
std::tr1::shared_ptr< PvaClientProcess > PvaClientProcessPtr
std::tr1::shared_ptr< PvaClientMonitorRequester > PvaClientMonitorRequesterPtr
std::tr1::shared_ptr< PvaClientRPC > PvaClientRPCPtr
std::tr1::shared_ptr< PvaClientChannelStateChangeRequester > PvaClientChannelStateChangeRequesterPtr
std::tr1::shared_ptr< PvaClient > PvaClientPtr
std::tr1::shared_ptr< PvaClientMonitor > PvaClientMonitorPtr
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr
std::tr1::shared_ptr< PvaClientPut > PvaClientPutPtr