pvaClientCPP  4.8.1-dev
pvaClient.h
Go to the documentation of this file.
1 
10 #ifndef PVACLIENT_H
11 #define PVACLIENT_H
12 
13 #ifdef epicsExportSharedSymbols
14 # define pvaClientEpicsExportSharedSymbols
15 # undef epicsExportSharedSymbols
16 #endif
17 
18 #include <list>
19 #include <iostream>
20 #include <ostream>
21 #include <sstream>
22 #include <pv/requester.h>
23 #include <pv/status.h>
24 #include <pv/event.h>
25 #include <pv/lock.h>
26 #include <pv/pvData.h>
27 #include <pv/pvTimeStamp.h>
28 #include <pv/timeStamp.h>
29 #include <pv/pvAlarm.h>
30 #include <pv/alarm.h>
31 #include <pv/pvAccess.h>
32 #include <pv/standardField.h>
33 #include <pv/standardPVField.h>
34 #include <pv/createRequest.h>
35 #include <pv/nt.h>
36 
37 #ifdef pvaClientEpicsExportSharedSymbols
38 # define epicsExportSharedSymbols
39 # undef pvaClientEpicsExportSharedSymbols
40 #endif
41 
42 #include <shareLib.h>
43 
44 namespace epics { namespace pvaClient {
45 
46 class PvaClient;
47 typedef std::tr1::shared_ptr<PvaClient> PvaClientPtr;
49 typedef std::tr1::shared_ptr<PvaClientData> PvaClientDataPtr;
51 typedef std::tr1::shared_ptr<PvaClientGetData> PvaClientGetDataPtr;
53 typedef std::tr1::shared_ptr<PvaClientPutData> PvaClientPutDataPtr;
55 typedef std::tr1::shared_ptr<PvaClientMonitorData> PvaClientMonitorDataPtr;
57 typedef std::tr1::shared_ptr<PvaClientChannelStateChangeRequester> PvaClientChannelStateChangeRequesterPtr;
58 typedef std::tr1::weak_ptr<PvaClientChannelStateChangeRequester> PvaClientChannelStateChangeRequesterWPtr;
60 typedef std::tr1::shared_ptr<PvaClientChannel> PvaClientChannelPtr;
62 typedef std::tr1::shared_ptr<PvaClientProcessRequester> PvaClientProcessRequesterPtr;
63 typedef std::tr1::weak_ptr<PvaClientProcessRequester> PvaClientProcessRequesterWPtr;
65 typedef std::tr1::shared_ptr<PvaClientProcess> PvaClientProcessPtr;
67 typedef std::tr1::shared_ptr<PvaClientGetRequester> PvaClientGetRequesterPtr;
68 typedef std::tr1::weak_ptr<PvaClientGetRequester> PvaClientGetRequesterWPtr;
70 typedef std::tr1::shared_ptr<PvaClientGet> PvaClientGetPtr;
72 typedef std::tr1::shared_ptr<PvaClientPutRequester> PvaClientPutRequesterPtr;
73 typedef std::tr1::weak_ptr<PvaClientPutRequester> PvaClientPutRequesterWPtr;
75 typedef std::tr1::shared_ptr<PvaClientPut> PvaClientPutPtr;
77 typedef std::tr1::shared_ptr<PvaClientPutGetRequester> PvaClientPutGetRequesterPtr;
78 typedef std::tr1::weak_ptr<PvaClientPutGetRequester> PvaClientPutGetRequesterWPtr;
80 typedef std::tr1::shared_ptr<PvaClientPutGet> PvaClientPutGetPtr;
82 typedef std::tr1::shared_ptr<PvaClientMonitor> PvaClientMonitorPtr;
84 typedef std::tr1::shared_ptr<PvaClientMonitorRequester> PvaClientMonitorRequesterPtr;
85 typedef std::tr1::weak_ptr<PvaClientMonitorRequester> PvaClientMonitorRequesterWPtr;
87 typedef std::tr1::shared_ptr<PvaClientRPC> PvaClientRPCPtr;
89 typedef std::tr1::shared_ptr<PvaClientRPCRequester> PvaClientRPCRequesterPtr;
90 typedef std::tr1::weak_ptr<PvaClientRPCRequester> PvaClientRPCRequesterWPtr;
91 
92 // following are private to pvaClient
93 class PvaClientChannelCache;
94 typedef std::tr1::shared_ptr<PvaClientChannelCache> PvaClientChannelCachePtr;
95 
96 
101 class epicsShareClass PvaClient :
102  public epics::pvData::Requester,
103  public std::tr1::enable_shared_from_this<PvaClient>
104 {
105 public:
106  POINTER_DEFINITIONS(PvaClient);
110  ~PvaClient();
116  static PvaClientPtr get(std::string const & providerNames = "pva ca");
121  static PvaClientPtr create() EPICS_DEPRECATED;
129  void message(
130  std::string const & message,
131  epics::pvData::MessageType messageType);
140  PvaClientChannelPtr channel(
141  std::string const & channelName,
142  std::string const &providerName = "pva",
143  double timeOut = 5.0);
150  PvaClientChannelPtr createChannel(
151  std::string const & channelName,
152  std::string const & providerName = "pva");
153 
159  void setRequester(epics::pvData::RequesterPtr const & requester);
166  std::string getRequesterName();
169  void clearRequester();
172  void showCache();
175  size_t cacheSize();
180  static void setDebug(bool value);
185  static bool getDebug();
186 private:
187  PvaClient(std::string const & providerNames);
188  PvaClientChannelCachePtr pvaClientChannelCache;
189  epics::pvData::Requester::weak_pointer requester;
190  bool pvaStarted;
191  bool caStarted;
192  epics::pvData::Mutex mutex;
193  epics::pvAccess::ChannelProviderRegistry::shared_pointer channelRegistry;
194 };
195 
196 // folowing private to PvaClientChannel
197 class PvaClientGetCache;
198 typedef std::tr1::shared_ptr<PvaClientGetCache> PvaClientGetCachePtr;
199 class PvaClientPutCache;
200 typedef std::tr1::shared_ptr<PvaClientPutCache> PvaClientPutCachePtr;
201 
202 
209 {
210 public:
211  POINTER_DEFINITIONS(PvaClientChannelStateChangeRequester);
223  virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected) = 0;
224 };
225 
231 class epicsShareClass PvaClientChannel :
232  public epics::pvAccess::ChannelRequester,
233  public std::tr1::enable_shared_from_this<PvaClientChannel>
234 {
235 public:
236  POINTER_DEFINITIONS(PvaClientChannel);
240  ~PvaClientChannel();
245  void setStateChangeRequester(PvaClientChannelStateChangeRequesterPtr const &stateChangeRequester);
250  std::string getChannelName();
255  epics::pvAccess::Channel::shared_pointer getChannel();
262  void connect(double timeout=5.0);
266  void issueConnect();
272  epics::pvData::Status waitConnect(double timeout = 5.0);
279  PvaClientProcessPtr createProcess(std::string const & request = "");
286  PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest);
293  PvaClientGetPtr get(std::string const & request = "field(value,alarm,timeStamp)");
301  PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)");
309  PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest);
316  double getDouble(std::string const & request = "field(value)");
323  std::string getString(std::string const & request = "field(value)");
330  epics::pvData::shared_vector<const double> getDoubleArray(
331  std::string const & request = "field(value)");
338  epics::pvData::shared_vector<const std::string> getStringArray(
339  std::string const & request = "field(value)");
348  PvaClientPutPtr put(std::string const & request = "field(value)");
356  PvaClientPutPtr createPut(std::string const & request = "field(value)");
362  PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest);
369  void putDouble(double value,std::string const & request = "field(value)");
376  void putString(std::string const & value,std::string const & request = "field(value)");
383  void putDoubleArray(
384  epics::pvData::shared_vector<const double> const & value,
385  std::string const & request = "field(value)");
392  void putStringArray(
393  epics::pvData::shared_vector<const std::string> const & value,
394  std::string const & request = "field(value)");
400  void putStringArray(std::vector<std::string> const & value,std::string const & request = "field(value)");
408  PvaClientPutGetPtr createPutGet(
409  std::string const & request = "putField(argument)getField(result)");
415  PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest);
425  PvaClientMonitorPtr monitor(std::string const & request = "field(value,alarm,timeStamp)");
432  PvaClientMonitorPtr monitor(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester);
442  PvaClientMonitorPtr monitor(
443  std::string const & request,
444  PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester);
452  PvaClientMonitorPtr createMonitor(
453  std::string const & request = "field(value,alarm,timeStamp)");
460  PvaClientMonitorPtr createMonitor(epics::pvData::PVStructurePtr const & pvRequest);
468  epics::pvData::PVStructurePtr rpc(
469  epics::pvData::PVStructurePtr const & pvRequest,
470  epics::pvData::PVStructurePtr const & pvArgument);
477  epics::pvData::PVStructurePtr rpc(
478  epics::pvData::PVStructurePtr const & pvArgument);
484  PvaClientRPCPtr createRPC();
492  PvaClientRPCPtr createRPC(epics::pvData::PVStructurePtr const & pvRequest);
495  void showCache();
498  size_t cacheSize();
499 private:
500  static PvaClientChannelPtr create(
501  PvaClientPtr const &pvaClient,
502  std::string const & channelName,
503  std::string const & providerName);
505  PvaClientPtr const &pvaClient,
506  std::string const & channelName,
507  std::string const & providerName);
508 
509  enum ConnectState {connectIdle,connectActive,notConnected,connected};
510 
511  PvaClient::weak_pointer pvaClient;
512  std::string channelName;
513  std::string providerName;
514  ConnectState connectState;
515 
516  epics::pvData::CreateRequest::shared_pointer createRequest;
517  PvaClientGetCachePtr pvaClientGetCache;
518  PvaClientPutCachePtr pvaClientPutCache;
519 
520  epics::pvData::Mutex mutex;
521  epics::pvData::Event waitForConnect;
522  epics::pvAccess::Channel::shared_pointer channel;
523  epics::pvAccess::ChannelProvider::shared_pointer channelProvider;
524  PvaClientChannelStateChangeRequesterWPtr stateChangeRequester;
525 public:
526  virtual std::string getRequesterName();
527  virtual void message(std::string const & message, epics::pvData::MessageType messageType);
528  virtual void channelCreated(
529  const epics::pvData::Status& status,
530  epics::pvAccess::Channel::shared_pointer const & channel);
531  virtual void channelStateChange(
532  epics::pvAccess::Channel::shared_pointer const & channel,
533  epics::pvAccess::Channel::ConnectionState connectionState);
534  friend class PvaClient;
535 };
536 
541 class epicsShareClass PvaClientData
542 {
543 public:
544  POINTER_DEFINITIONS(PvaClientData);
554  void setMessagePrefix(std::string const & value);
560  epics::pvData::StructureConstPtr getStructure();
566  epics::pvData::PVStructurePtr getPVStructure();
573  epics::pvData::BitSetPtr getChangedBitSet();
579  std::ostream & showChanged(std::ostream & out);
586  void setData(
587  epics::pvData::PVStructurePtr const & pvStructureFrom,
588  epics::pvData::BitSetPtr const & bitSetFrom);
589 
593  bool hasValue();
597  bool isValueScalar();
601  bool isValueScalarArray();
606  epics::pvData::PVFieldPtr getValue();
612  epics::pvData::PVScalarPtr getScalarValue();
617  std::tr1::shared_ptr<epics::pvData::PVArray> getArrayValue();
622  std::tr1::shared_ptr<epics::pvData::PVScalarArray> getScalarArrayValue();
627  double getDouble();
632  std::string getString();
637  epics::pvData::shared_vector<const double> getDoubleArray();
642  epics::pvData::shared_vector<const std::string> getStringArray();
649  epics::pvData::Alarm getAlarm();
655  epics::pvData::TimeStamp getTimeStamp();
663  void parse(const std::vector<std::string> &args);
672  void streamJSON(
673  std::ostream& strm,
674  bool ignoreUnprintable = true,
675  bool multiLine = false);
678  void zeroArrayLength();
679 protected:
680  static PvaClientDataPtr create(epics::pvData::StructureConstPtr const & structure);
681  PvaClientData(epics::pvData::StructureConstPtr const & structure);
682  epics::pvData::PVFieldPtr getSinglePVField();
683  void checkValue();
684  std::string messagePrefix;
685 private:
686  void parse(
687  const std::string &arg,
688  const epics::pvData::PVFieldPtr &dest,
689  epics::pvData::BitSetPtr &bitSet);
690  void parse(
691  const std::string &arg,
692  const epics::pvData::PVUnionPtr &dest);
693  void zeroArrayLength(const epics::pvData::PVStructurePtr &pvStructure);
694 
695  epics::pvData::StructureConstPtr structure;
696  epics::pvData::PVStructurePtr pvStructure;
697  epics::pvData::BitSetPtr bitSet;
698 
699  epics::pvData::PVFieldPtr pvValue;
700  epics::pvData::PVAlarm pvAlarm;
701  epics::pvData::PVTimeStamp pvTimeStamp;
702  friend class PvaClientGet;
703  friend class PvaClientPutGet;
704 };
705 
710 class epicsShareClass PvaClientGetData : public PvaClientData
711 {
712 public:
713  POINTER_DEFINITIONS(PvaClientGetData);
724  static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure);
725 private:
726  PvaClientGetData(epics::pvData::StructureConstPtr const & structure);
727  friend class PvaClientGet;
728  friend class PvaClientPutGet;
729 };
730 
731 class PvaClientPostHandlerPvt; // private to PvaClientPutData
736 class epicsShareClass PvaClientPutData : public PvaClientData
737 {
738 public:
739  POINTER_DEFINITIONS(PvaClientPutData);
749  void putDouble(double value);
754  void putString(std::string const & value);
759  void putDoubleArray(epics::pvData::shared_vector<const double> const & value);
764  void putStringArray(epics::pvData::shared_vector<const std::string> const & value);
769  void putStringArray(std::vector<std::string> const & value);
774  static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure);
775 private:
776  PvaClientPutData(epics::pvData::StructureConstPtr const &structure);
777  void postPut(size_t fieldNumber);
778  std::vector<epics::pvData::PostHandlerPtr> postHandler;
779  friend class PvaClientPostHandlerPvt;
780  friend class PvaClientPut;
781  friend class PvaClientPutGet;
782 };
783 
787 class epicsShareClass PvaClientMonitorData : public PvaClientData
788 {
789 public:
790  POINTER_DEFINITIONS(PvaClientMonitorData);
800  epics::pvData::BitSetPtr getOverrunBitSet();
805  std::ostream & showOverrun(std::ostream & out);
810  void setData(epics::pvData::MonitorElementPtr const & monitorElement);
815  static PvaClientMonitorDataPtr create(epics::pvData::StructureConstPtr const & structure);
816 private:
817  PvaClientMonitorData(epics::pvData::StructureConstPtr const & structure);
818  epics::pvData::BitSetPtr overrunBitSet;
819 
820  friend class PvaClientMonitor;
821 };
822 
827 class epicsShareClass PvaClientProcessRequester
828 {
829 public:
830  POINTER_DEFINITIONS(PvaClientProcessRequester);
837  virtual void channelProcessConnect(
838  const epics::pvData::Status& status,
839  PvaClientProcessPtr const & clientProcess)
840  {
841  }
847  virtual void processDone(
848  const epics::pvData::Status& status,
849  PvaClientProcessPtr const & clientProcess) = 0;
850 };
851 
852 // NOTE: must use separate class that implements ChannelProcessRequester,
853 // because pvAccess holds a shared_ptr to ChannelProcessRequester instead of weak_pointer
854 class ChannelProcessRequesterImpl;
855 typedef std::tr1::shared_ptr<ChannelProcessRequesterImpl> ChannelProcessRequesterImplPtr;
856 
861 class epicsShareClass PvaClientProcess :
862  public std::tr1::enable_shared_from_this<PvaClientProcess>
863 {
864 public:
865  POINTER_DEFINITIONS(PvaClientProcess);
872  static PvaClientProcessPtr create(
873  PvaClientPtr const &pvaClient,
874  PvaClientChannelPtr const & pvaClientChannel,
875  epics::pvData::PVStructurePtr const &pvRequest
876  );
877 
880  ~PvaClientProcess();
884  void setRequester(PvaClientProcessRequesterPtr const & pvaClientProcessRequester);
890  void connect();
895  void issueConnect();
899  epics::pvData::Status waitConnect();
904  void process();
907  void issueProcess();
911  epics::pvData::Status waitProcess();
916  PvaClientChannelPtr getPvaClientChannel();
917 private:
918  std::string getRequesterName();
919  void message(std::string const & message,epics::pvData::MessageType messageType);
920  void channelProcessConnect(
921  const epics::pvData::Status& status,
922  epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess);
923  void processDone(
924  const epics::pvData::Status& status,
925  epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess);
926 
928  PvaClientPtr const &pvaClient,
929  PvaClientChannelPtr const & pvaClientChannel,
930  epics::pvData::PVStructurePtr const &pvRequest);
931 
932  void checkProcessState();
933  enum ProcessConnectState {connectIdle,connectActive,connected};
934 
935  PvaClient::weak_pointer pvaClient;
936  PvaClientChannelPtr pvaClientChannel;
937  epics::pvData::PVStructurePtr pvRequest;
938  epics::pvData::Mutex mutex;
939  epics::pvData::Event waitForConnect;
940  epics::pvData::Event waitForProcess;
941 
942  epics::pvData::Status channelProcessConnectStatus;
943  epics::pvData::Status channelProcessStatus;
944  epics::pvAccess::ChannelProcess::shared_pointer channelProcess;
945 
946  ProcessConnectState connectState;
947 
948  PvaClientProcessRequesterWPtr pvaClientProcessRequester;
949  enum ProcessState {processIdle,processActive,processComplete};
950  ProcessState processState;
951  ChannelProcessRequesterImplPtr channelProcessRequester;
952 public:
953  friend class ChannelProcessRequesterImpl;
954 };
955 
956 // NOTE: must use separate class that implements ChannelGetRequester,
957 // because pvAccess holds a shared_ptr to ChannelGetRequester instead of weak_pointer
958 class ChannelGetRequesterImpl;
959 typedef std::tr1::shared_ptr<ChannelGetRequesterImpl> ChannelGetRequesterImplPtr;
960 
965 class epicsShareClass PvaClientGetRequester
966 {
967 public:
968  POINTER_DEFINITIONS(PvaClientGetRequester);
975  virtual void channelGetConnect(
976  const epics::pvData::Status& status,
977  PvaClientGetPtr const & clientGet)
978  {
979  }
985  virtual void getDone(
986  const epics::pvData::Status& status,
987  PvaClientGetPtr const & clientGet) = 0;
988 };
993 class epicsShareClass PvaClientGet :
994  public std::tr1::enable_shared_from_this<PvaClientGet>
995 {
996 public:
997  POINTER_DEFINITIONS(PvaClientGet);
1004  static PvaClientGetPtr create(
1005  PvaClientPtr const &pvaClient,
1006  PvaClientChannelPtr const & pvaClientChannel,
1007  epics::pvData::PVStructurePtr const &pvRequest
1008  );
1009 
1012  ~PvaClientGet();
1016  void setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester);
1022  void connect();
1028  void issueConnect();
1032  epics::pvData::Status waitConnect();
1036  void get();
1039  void issueGet();
1043  epics::pvData::Status waitGet();
1048  PvaClientGetDataPtr getData();
1053  PvaClientChannelPtr getPvaClientChannel();
1054 private:
1055  std::string getRequesterName();
1056  void message(std::string const & message,epics::pvData::MessageType messageType);
1057  void channelGetConnect(
1058  const epics::pvData::Status& status,
1059  epics::pvAccess::ChannelGet::shared_pointer const & channelGet,
1060  epics::pvData::StructureConstPtr const & structure);
1061  void getDone(
1062  const epics::pvData::Status& status,
1063  epics::pvAccess::ChannelGet::shared_pointer const & channelGet,
1064  epics::pvData::PVStructurePtr const & pvStructure,
1065  epics::pvData::BitSetPtr const & bitSet);
1066 
1067  PvaClientGet(
1068  PvaClientPtr const &pvaClient,
1069  PvaClientChannelPtr const & pvaClientChannel,
1070  epics::pvData::PVStructurePtr const &pvRequest);
1071 
1072  void checkConnectState();
1073  enum GetConnectState {connectIdle,connectActive,connected};
1074 
1075  PvaClient::weak_pointer pvaClient;
1076  PvaClientChannelPtr pvaClientChannel;
1077  epics::pvData::PVStructurePtr pvRequest;
1078  epics::pvData::Mutex mutex;
1079  epics::pvData::Event waitForConnect;
1080  epics::pvData::Event waitForGet;
1081  PvaClientGetDataPtr pvaClientData;
1082 
1083  epics::pvData::Status channelGetConnectStatus;
1084  epics::pvData::Status channelGetStatus;
1085  epics::pvAccess::ChannelGet::shared_pointer channelGet;
1086 
1087  GetConnectState connectState;
1088 
1089  PvaClientGetRequesterWPtr pvaClientGetRequester;
1090 
1091  enum GetState {getIdle,getActive,getComplete};
1092  GetState getState;
1093  ChannelGetRequesterImplPtr channelGetRequester;
1094 public:
1095  friend class ChannelGetRequesterImpl;
1096 };
1097 
1098 
1099 // NOTE: must use separate class that implements ChannelPutRequester,
1100 // because pvAccess holds a shared_ptr to ChannelPutRequester instead of weak_pointer
1101 class ChannelPutRequesterImpl;
1102 typedef std::tr1::shared_ptr<ChannelPutRequesterImpl> ChannelPutRequesterImplPtr;
1103 
1108 class epicsShareClass PvaClientPutRequester
1109 {
1110 public:
1111  POINTER_DEFINITIONS(PvaClientPutRequester);
1118  virtual void channelPutConnect(
1119  const epics::pvData::Status& status,
1120  PvaClientPutPtr const & clientPut)
1121  {
1122  }
1128  virtual void getDone(
1129  const epics::pvData::Status& status,
1130  PvaClientPutPtr const & clientPut)
1131  {
1132  }
1138  virtual void putDone(
1139  const epics::pvData::Status& status,
1140  PvaClientPutPtr const & clientPut) = 0;
1141 };
1142 
1147 class epicsShareClass PvaClientPut :
1148  public std::tr1::enable_shared_from_this<PvaClientPut>
1149 {
1150 public:
1151  POINTER_DEFINITIONS(PvaClientPut);
1158  static PvaClientPutPtr create(
1159  PvaClientPtr const &pvaClient,
1160  PvaClientChannelPtr const & pvaClientChannel,
1161  epics::pvData::PVStructurePtr const &pvRequest
1162  );
1165  ~PvaClientPut();
1169  void setRequester(PvaClientPutRequesterPtr const & pvaClientPutRequester);
1175  void connect();
1180  void issueConnect();
1184  epics::pvData::Status waitConnect();
1190  void get();
1193  void issueGet();
1197  epics::pvData::Status waitGet();
1201  void put();
1204  void issuePut();
1208  epics::pvData::Status waitPut();
1213  PvaClientPutDataPtr getData();
1218  PvaClientChannelPtr getPvaClientChannel();
1219 private :
1220  std::string getRequesterName();
1221  void message(std::string const & message,epics::pvData::MessageType messageType);
1222  void channelPutConnect(
1223  const epics::pvData::Status& status,
1224  epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
1225  epics::pvData::StructureConstPtr const & structure);
1226  void getDone(
1227  const epics::pvData::Status& status,
1228  epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
1229  epics::pvData::PVStructurePtr const & pvStructure,
1230  epics::pvData::BitSetPtr const & bitSet);
1231  void putDone(
1232  const epics::pvData::Status& status,
1233  epics::pvAccess::ChannelPut::shared_pointer const & channelPut);
1234  PvaClientPut(
1235  PvaClientPtr const &pvaClient,
1236  PvaClientChannelPtr const & pvaClientChannel,
1237  epics::pvData::PVStructurePtr const &pvRequest);
1238 
1239  void checkConnectState();
1240  enum PutConnectState {connectIdle,connectActive,connected};
1241 
1242  PvaClient::weak_pointer pvaClient;
1243  PvaClientChannelPtr pvaClientChannel;
1244  epics::pvData::PVStructurePtr pvRequest;
1245  epics::pvData::Mutex mutex;
1246  epics::pvData::Event waitForConnect;
1247  epics::pvData::Event waitForGetPut;
1248  PvaClientPutDataPtr pvaClientData;
1249 
1250  epics::pvData::Status channelPutConnectStatus;
1251  epics::pvData::Status channelGetPutStatus;
1252  epics::pvAccess::ChannelPut::shared_pointer channelPut;
1253  PutConnectState connectState;
1254 
1255  enum PutState {putIdle,getActive,putActive,putComplete};
1256  PutState putState;
1257  ChannelPutRequesterImplPtr channelPutRequester;
1258  PvaClientPutRequesterWPtr pvaClientPutRequester;
1259 public:
1260  friend class ChannelPutRequesterImpl;
1261 };
1262 
1263 // NOTE: must use separate class that implements ChannelPutGetRequester,
1264 // because pvAccess holds a shared_ptr to ChannelPutGetRequester instead of weak_pointer
1265 class ChannelPutGetRequesterImpl;
1266 typedef std::tr1::shared_ptr<ChannelPutGetRequesterImpl> ChannelPutGetRequesterImplPtr;
1267 
1272 class epicsShareClass PvaClientPutGetRequester
1273 {
1274 public:
1275  POINTER_DEFINITIONS(PvaClientPutGetRequester);
1282  virtual void channelPutGetConnect(
1283  const epics::pvData::Status& status,
1284  PvaClientPutGetPtr const & clientPutGet)
1285  {
1286  }
1292  virtual void putGetDone(
1293  const epics::pvData::Status& status,
1294  PvaClientPutGetPtr const & clientPutGet) = 0;
1300  virtual void getPutDone(
1301  const epics::pvData::Status& status,
1302  PvaClientPutGetPtr const & clientPutGet)
1303  {
1304  }
1310  virtual void getGetDone(
1311  const epics::pvData::Status& status,
1312  PvaClientPutGetPtr const & clientPutGet)
1313  {
1314  }
1315 
1316 };
1317 
1318 
1323 class epicsShareClass PvaClientPutGet :
1324  public std::tr1::enable_shared_from_this<PvaClientPutGet>
1325 {
1326 public:
1327  POINTER_DEFINITIONS(PvaClientPutGet);
1334  static PvaClientPutGetPtr create(
1335  PvaClientPtr const &pvaClient,
1336  PvaClientChannelPtr const & pvaClientChannel,
1337  epics::pvData::PVStructurePtr const &pvRequest
1338  );
1341  ~PvaClientPutGet();
1345  void setRequester(PvaClientPutGetRequesterPtr const & pvaClientPutGetRequester);
1346 
1352  void connect();
1358  void issueConnect();
1362  epics::pvData::Status waitConnect();
1367  void putGet();
1370  void issuePutGet();
1376  epics::pvData::Status waitPutGet();
1380  void getGet();
1383  void issueGetGet();
1389  epics::pvData::Status waitGetGet();
1394  void getPut();
1397  void issueGetPut();
1401  epics::pvData::Status waitGetPut();
1405  PvaClientPutDataPtr getPutData();
1409  PvaClientGetDataPtr getGetData();
1414  PvaClientChannelPtr getPvaClientChannel();
1415 private :
1416  std::string getRequesterName();
1417  void message(std::string const & message,epics::pvData::MessageType messageType);
1418  void channelPutGetConnect(
1419  const epics::pvData::Status& status,
1420  epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
1421  epics::pvData::StructureConstPtr const & putStructure,
1422  epics::pvData::StructureConstPtr const & getStructure);
1423  void putGetDone(
1424  const epics::pvData::Status& status,
1425  epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
1426  epics::pvData::PVStructurePtr const & getPVStructure,
1427  epics::pvData::BitSetPtr const & getBitSet);
1428  void getPutDone(
1429  const epics::pvData::Status& status,
1430  epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
1431  epics::pvData::PVStructurePtr const & putPVStructure,
1432  epics::pvData::BitSet::shared_pointer const & putBitSet);
1433  void getGetDone(
1434  const epics::pvData::Status& status,
1435  epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
1436  epics::pvData::PVStructurePtr const & getPVStructure,
1437  epics::pvData::BitSet::shared_pointer const & getBitSet);
1438 
1440  PvaClientPtr const &pvaClient,
1441  PvaClientChannelPtr const & pvaClientChannel,
1442  epics::pvData::PVStructurePtr const &pvRequest);
1443  void checkPutGetState();
1444  enum PutGetConnectState {connectIdle,connectActive,connected};
1445 
1446  PvaClient::weak_pointer pvaClient;
1447  PvaClientChannelPtr pvaClientChannel;
1448  epics::pvData::PVStructurePtr pvRequest;
1449  epics::pvData::Mutex mutex;
1450  epics::pvData::Event waitForConnect;
1451  epics::pvData::Event waitForPutGet;
1452  PvaClientGetDataPtr pvaClientGetData;
1453  PvaClientPutDataPtr pvaClientPutData;
1454 
1455  epics::pvData::Status channelPutGetConnectStatus;
1456  epics::pvData::Status channelPutGetStatus;
1457  epics::pvAccess::ChannelPutGet::shared_pointer channelPutGet;
1458  PutGetConnectState connectState;
1459 
1460  enum PutGetState {putGetIdle,putGetActive,putGetComplete};
1461  PutGetState putGetState;
1462  ChannelPutGetRequesterImplPtr channelPutGetRequester;
1463  PvaClientPutGetRequesterWPtr pvaClientPutGetRequester;
1464 public:
1465  friend class ChannelPutGetRequesterImpl;
1466 };
1467 
1472 class epicsShareClass PvaClientMonitorRequester
1473 {
1474 public:
1475  POINTER_DEFINITIONS(PvaClientMonitorRequester);
1482  virtual void monitorConnect(epics::pvData::Status const & status,
1483  PvaClientMonitorPtr const & monitor, epics::pvData::StructureConstPtr const & structure)
1484  {
1485  }
1490  virtual void event(PvaClientMonitorPtr const & monitor) = 0;
1495  virtual void unlisten()
1496  {
1497  std::cerr << "PvaClientMonitorRequester::unlisten called"
1498  << " but no PvaClientMonitorRequester::unlisten\n";
1499  }
1500 };
1501 
1502 
1503 // NOTE: must use separate class that implements MonitorRequester,
1504 // because pvAccess holds a shared_ptr to MonitorRequester instead of weak_pointer
1505 class MonitorRequesterImpl;
1506 typedef std::tr1::shared_ptr<MonitorRequesterImpl> MonitorRequesterImplPtr;
1507 
1512 class epicsShareClass PvaClientMonitor :
1513  public PvaClientChannelStateChangeRequester, // remove when deprecated create removed
1515  public std::tr1::enable_shared_from_this<PvaClientMonitor>
1516 {
1517 public:
1518  POINTER_DEFINITIONS(PvaClientMonitor);
1525  static PvaClientMonitorPtr create(
1526  PvaClientPtr const &pvaClient,
1527  PvaClientChannelPtr const & pvaClientChannel,
1528  epics::pvData::PVStructurePtr const &pvRequest
1529  );
1540  static PvaClientMonitorPtr create(
1541  PvaClientPtr const &pvaClient,
1542  std::string const & channelName,
1543  std::string const & providerName,
1544  std::string const & request,
1545  PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester
1547  PvaClientMonitorRequesterPtr const & monitorRequester
1549  ) EPICS_DEPRECATED;
1552  ~PvaClientMonitor();
1557  void connect();
1564  void issueConnect();
1568  epics::pvData::Status waitConnect();
1572  void setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester);
1575  void start();
1581  void start(const std::string & request);
1584  void stop();
1590  bool poll();
1597  bool waitEvent(double secondsToWait = 0.0);
1600  void releaseEvent();
1605  PvaClientChannelPtr getPvaClientChannel();
1610  PvaClientMonitorDataPtr getData();
1611 private:
1612  std::string getRequesterName();
1613  void message(std::string const & message,epics::pvData::MessageType messageType);
1614  void monitorConnect(
1615  const epics::pvData::Status& status,
1616  epics::pvData::MonitorPtr const & monitor,
1617  epics::pvData::StructureConstPtr const & structure);
1618  void unlisten(epics::pvData::MonitorPtr const & monitor);
1619  void monitorEvent(epics::pvData::MonitorPtr const & monitor);
1620 
1622  PvaClientPtr const &pvaClient,
1623  PvaClientChannelPtr const & pvaClientChannel,
1624  epics::pvData::PVStructurePtr const &pvRequest);
1625 
1626  void checkMonitorState();
1627  enum MonitorConnectState {connectIdle,connectWait,connectActive,connected};
1628 
1629  PvaClient::weak_pointer pvaClient;
1630  PvaClientChannelPtr pvaClientChannel;
1631  epics::pvData::PVStructurePtr pvRequest;
1632  epics::pvData::Mutex mutex;
1633  epics::pvData::Event waitForConnect;
1634  epics::pvData::Event waitForEvent;
1635  PvaClientMonitorDataPtr pvaClientData;
1636 
1637  bool isStarted;
1638  epics::pvData::Status monitorConnectStatus;
1639  epics::pvData::MonitorPtr monitor;
1640  epics::pvData::MonitorElementPtr monitorElement;
1641 
1642  PvaClientMonitorRequesterWPtr pvaClientMonitorRequester;
1643  MonitorConnectState connectState;
1644  bool userPoll;
1645  bool userWait;
1646  MonitorRequesterImplPtr monitorRequester;
1647  PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester; //deprecate
1648 public:
1649  void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected); //deprecate
1650  void event(PvaClientMonitorPtr const & monitor);
1651  friend class MonitorRequesterImpl;
1652 };
1653 
1654 
1655 
1661 {
1662 public:
1663  POINTER_DEFINITIONS(PvaClientRPCRequester);
1671  virtual void requestDone(
1672  const epics::pvData::Status& status,
1673  PvaClientRPCPtr const & pvaClientRPC,
1674  epics::pvData::PVStructure::shared_pointer const & pvResponse) = 0;
1675 };
1676 // NOTE: must use separate class that implements RPCRequester,
1677 // because pvAccess holds a shared_ptr to RPCRequester instead of weak_pointer
1678 class RPCRequesterImpl;
1679 typedef std::tr1::shared_ptr<RPCRequesterImpl> RPCRequesterImplPtr;
1680 
1685 class epicsShareClass PvaClientRPC :
1686  public std::tr1::enable_shared_from_this<PvaClientRPC>
1687 {
1688 public:
1689  POINTER_DEFINITIONS(PvaClientRPC);
1695  static PvaClientRPCPtr create(
1696  PvaClientPtr const &pvaClient,
1697  epics::pvAccess::Channel::shared_pointer const & channel);
1704  static PvaClientRPCPtr create(
1705  PvaClientPtr const &pvaClient,
1706  epics::pvAccess::Channel::shared_pointer const & channel,
1707  epics::pvData::PVStructurePtr const &pvRequest
1708  );
1711  ~PvaClientRPC();
1716  void setResponseTimeout(double responseTimeout)
1717  {
1718  this->responseTimeout = responseTimeout;
1719  }
1725  {
1726  return responseTimeout;
1727  }
1732  void connect();
1739  void issueConnect();
1743  epics::pvData::Status waitConnect();
1752  epics::pvData::PVStructure::shared_pointer request(
1753  epics::pvData::PVStructure::shared_pointer const & pvArgument);
1759  void request(
1760  epics::pvData::PVStructure::shared_pointer const & pvArgument,
1761  PvaClientRPCRequesterPtr const & pvaClientRPCRequester);
1762 private:
1763  PvaClientRPC(
1764  PvaClientPtr const &pvaClient,
1765  epics::pvAccess::Channel::shared_pointer const & channel,
1766  epics::pvData::PVStructurePtr const &pvRequest);
1767  std::string getRequesterName();
1768  void message(std::string const & message,epics::pvData::MessageType messageType);
1769  void rpcConnect(
1770  const epics::pvData::Status& status,
1771  epics::pvAccess::ChannelRPC::shared_pointer const & channelRPC);
1772  void requestDone(
1773  const epics::pvData::Status& status,
1774  epics::pvAccess::ChannelRPC::shared_pointer const & channelRPC,
1775  epics::pvData::PVStructure::shared_pointer const & pvResponse);
1776 
1777  void checkRPCState();
1778 
1779  enum RPCConnectState {connectIdle,connectActive,connected};
1780  epics::pvData::Status connectStatus;
1781  RPCConnectState connectState;
1782 
1783  PvaClient::weak_pointer pvaClient;
1784  epics::pvAccess::Channel::weak_pointer channel;
1785  epics::pvData::PVStructurePtr pvRequest;
1786 
1787  epics::pvData::Mutex mutex;
1788  epics::pvData::Event waitForConnect;
1789  epics::pvData::Event waitForDone;
1790 
1791  PvaClientRPCRequesterWPtr pvaClientRPCRequester;
1792  RPCRequesterImplPtr rpcRequester;
1793  epics::pvAccess::ChannelRPC::shared_pointer channelRPC;
1794  epics::pvData::PVStructurePtr pvResponse;
1795 
1796  enum RPCState {rpcIdle,rpcActive,rpcComplete};
1797  RPCState rpcState;
1798  epics::pvData::Status requestStatus;
1799  double responseTimeout;
1800  friend class RPCRequesterImpl;
1801 };
1802 
1803 }}
1804 
1805 #endif /* PVACLIENT_H */
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition: pvaClient.h:46
std::tr1::shared_ptr< PvaClientProcessRequester > PvaClientProcessRequesterPtr
Definition: pvaClient.h:61
An easy to use alternative to ChannelProcess.
Definition: pvaClient.h:861
std::tr1::shared_ptr< ChannelProcessRequesterImpl > ChannelProcessRequesterImplPtr
Definition: pvaClient.h:854
std::tr1::shared_ptr< PvaClientGetData > PvaClientGetDataPtr
Definition: pvaClient.h:50
virtual void channelProcessConnect(const epics::pvData::Status &status, PvaClientProcessPtr const &clientProcess)
A channelProcess has connected.
Definition: pvaClient.h:837
std::tr1::weak_ptr< PvaClientRPCRequester > PvaClientRPCRequesterWPtr
Definition: pvaClient.h:90
A class that holds data given to by PvaClientPut or PvaClientPutGet.
Definition: pvaClient.h:736
std::tr1::shared_ptr< PvaClientMonitorData > PvaClientMonitorDataPtr
Definition: pvaClient.h:54
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition: pvaClient.h:59
virtual void getGetDone(const epics::pvData::Status &status, PvaClientPutGetPtr const &clientPutGet)
A getGet request is complete.
Definition: pvaClient.h:1310
std::tr1::weak_ptr< PvaClientGetRequester > PvaClientGetRequesterWPtr
Definition: pvaClient.h:68
std::tr1::weak_ptr< PvaClientPutGetRequester > PvaClientPutGetRequesterWPtr
Definition: pvaClient.h:78
std::tr1::shared_ptr< ChannelGetRequesterImpl > ChannelGetRequesterImplPtr
Definition: pvaClient.h:958
virtual void channelPutConnect(const epics::pvData::Status &status, PvaClientPutPtr const &clientPut)
A channelPut has connected.
Definition: pvaClient.h:1118
An easy to use alternative to RPC.
Definition: pvaClient.h:1685
A class that holds data returned by PvaClientGet or PvaClientPutGet.
Definition: pvaClient.h:710
std::tr1::shared_ptr< PvaClientPut > PvaClientPutPtr
Definition: pvaClient.h:74
std::tr1::weak_ptr< PvaClientChannelStateChangeRequester > PvaClientChannelStateChangeRequesterWPtr
Definition: pvaClient.h:58
Optional client callback.
Definition: pvaClient.h:1108
virtual void channelPutGetConnect(const epics::pvData::Status &status, PvaClientPutGetPtr const &clientPutGet)
A channelPutGet has connected.
Definition: pvaClient.h:1282
std::tr1::shared_ptr< PvaClientPutRequester > PvaClientPutRequesterPtr
Definition: pvaClient.h:71
A base class for PvaClientGetData, PvaClientPutData, and PvaClientMonitorData.
Definition: pvaClient.h:541
std::tr1::shared_ptr< PvaClientMonitorRequester > PvaClientMonitorRequesterPtr
Definition: pvaClient.h:83
std::tr1::weak_ptr< PvaClientPutRequester > PvaClientPutRequesterWPtr
Definition: pvaClient.h:73
std::tr1::shared_ptr< PvaClientPutGetRequester > PvaClientPutGetRequesterPtr
Definition: pvaClient.h:76
std::tr1::weak_ptr< PvaClientMonitorRequester > PvaClientMonitorRequesterWPtr
Definition: pvaClient.h:85
void setResponseTimeout(double responseTimeout)
Set a timeout for a request.
Definition: pvaClient.h:1716
virtual void unlisten()
The data source is no longer available.
Definition: pvaClient.h:1495
pvaClient is a synchronous wrapper for the pvAccess API, which is a callback based API...
Definition: pvaClient.h:101
std::tr1::shared_ptr< PvaClientGet > PvaClientGetPtr
Definition: pvaClient.h:69
std::tr1::shared_ptr< MonitorRequesterImpl > MonitorRequesterImplPtr
Definition: pvaClient.h:1505
std::tr1::shared_ptr< RPCRequesterImpl > RPCRequesterImplPtr
Definition: pvaClient.h:1678
Optional client callback.
Definition: pvaClient.h:1660
A class that holds data returned by PvaClientMonitor.
Definition: pvaClient.h:787
std::tr1::shared_ptr< PvaClientRPC > PvaClientRPCPtr
Definition: pvaClient.h:86
An easy to use alternative to ChannelGet.
Definition: pvaClient.h:993
std::tr1::shared_ptr< PvaClientChannelStateChangeRequester > PvaClientChannelStateChangeRequesterPtr
Definition: pvaClient.h:56
Optional client callback.
Definition: pvaClient.h:965
An easy to use alternative to ChannelPut.
Definition: pvaClient.h:1147
std::tr1::shared_ptr< PvaClientPutCache > PvaClientPutCachePtr
Definition: pvaClient.h:199
An easy to use alternative to directly calling the Channel methods of pvAccess.
Definition: pvaClient.h:231
virtual void getDone(const epics::pvData::Status &status, PvaClientPutPtr const &clientPut)
A get request is complete.
Definition: pvaClient.h:1128
std::tr1::shared_ptr< PvaClientProcess > PvaClientProcessPtr
Definition: pvaClient.h:64
std::tr1::shared_ptr< PvaClientPutGet > PvaClientPutGetPtr
Definition: pvaClient.h:79
std::tr1::shared_ptr< PvaClientGetCache > PvaClientGetCachePtr
Definition: pvaClient.h:197
std::tr1::shared_ptr< PvaClientRPCRequester > PvaClientRPCRequesterPtr
Definition: pvaClient.h:88
std::tr1::shared_ptr< ChannelPutGetRequesterImpl > ChannelPutGetRequesterImplPtr
Definition: pvaClient.h:1265
std::tr1::shared_ptr< PvaClientChannelCache > PvaClientChannelCachePtr
Definition: pvaClient.h:93
virtual void channelGetConnect(const epics::pvData::Status &status, PvaClientGetPtr const &clientGet)
A channelGet has connected.
Definition: pvaClient.h:975
An easy to use alternative to ChannelPutGet.
Definition: pvaClient.h:1323
A callback for change in connection status.
Definition: pvaClient.h:208
std::tr1::shared_ptr< ChannelPutRequesterImpl > ChannelPutRequesterImplPtr
Definition: pvaClient.h:1101
An easy to use alternative to Monitor.
Definition: pvaClient.h:1512
std::tr1::shared_ptr< PvaClientMonitor > PvaClientMonitorPtr
Definition: pvaClient.h:81
virtual void monitorConnect(epics::pvData::Status const &status, PvaClientMonitorPtr const &monitor, epics::pvData::StructureConstPtr const &structure)
The server has returned a message that the monitor is connected.
Definition: pvaClient.h:1482
virtual void getPutDone(const epics::pvData::Status &status, PvaClientPutGetPtr const &clientPutGet)
A getPut request is complete.
Definition: pvaClient.h:1300
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr
Definition: pvaClient.h:52
double getResponseTimeout()
Get the responseTimeout.
Definition: pvaClient.h:1724
std::tr1::shared_ptr< PvaClientData > PvaClientDataPtr
Definition: pvaClient.h:48
std::tr1::weak_ptr< PvaClientProcessRequester > PvaClientProcessRequesterWPtr
Definition: pvaClient.h:63
std::tr1::shared_ptr< PvaClientGetRequester > PvaClientGetRequesterPtr
Definition: pvaClient.h:66