14 #include <epicsGuard.h> 15 #include <epicsThread.h> 16 #include <pv/pvData.h> 17 #include <pv/pvAccess.h> 18 #include <pv/pvTimeStamp.h> 19 #include <pv/rpcService.h> 20 #include <pv/timeStamp.h> 21 #include <pv/createRequest.h> 22 #include <pv/pvaVersion.h> 23 #include <pv/pvaVersionNum.h> 24 #include <pv/serverContext.h> 25 #include <pv/pvSubArrayCopy.h> 27 #define epicsExportSharedSymbols 35 using std::tr1::static_pointer_cast;
36 using std::tr1::dynamic_pointer_cast;
41 namespace epics {
namespace pvDatabase {
43 static StructureConstPtr nullStructure;
45 class ChannelProcessLocal;
47 class ChannelGetLocal;
49 class ChannelPutLocal;
51 class ChannelPutGetLocal;
53 class ChannelRPCLocal;
55 class ChannelArrayLocal;
58 static bool getProcess(PVStructurePtr pvRequest,
bool processDefault)
60 PVFieldPtr pvField = pvRequest->getSubField(
"record._options.process");
61 if(!pvField || pvField->getField()->getType()!=scalar) {
62 return processDefault;
64 ScalarConstPtr scalar = static_pointer_cast<
const Scalar>(
66 if(scalar->getScalarType()==pvString) {
67 PVStringPtr pvString = static_pointer_cast<PVString>(pvField);
68 return pvString->get().compare(
"true")==0 ? true :
false;
69 }
else if(scalar->getScalarType()==pvBoolean) {
70 PVBooleanPtr pvBoolean = static_pointer_cast<PVBoolean>(pvField);
71 return pvBoolean->get();
73 return processDefault;
76 class ChannelProcessLocal :
77 public ChannelProcess,
78 public std::tr1::enable_shared_from_this<ChannelProcessLocal>
81 POINTER_DEFINITIONS(ChannelProcessLocal);
82 virtual ~ChannelProcessLocal();
83 virtual void destroy() {}
84 static ChannelProcessLocalPtr create(
86 ChannelProcessRequester::shared_pointer
const & channelProcessRequester,
87 PVStructurePtr
const & pvRequest,
89 virtual void process();
90 virtual std::tr1::shared_ptr<Channel> getChannel();
91 virtual void cancel(){}
93 virtual void unlock();
94 virtual void lastRequest() {}
96 shared_pointer getPtrSelf()
98 return shared_from_this();
102 ChannelProcessRequester::shared_pointer
const & channelProcessRequester,
106 channelLocal(channelLocal),
107 channelProcessRequester(channelProcessRequester),
113 ChannelProcessRequester::weak_pointer channelProcessRequester;
119 ChannelProcessLocalPtr ChannelProcessLocal::create(
121 ChannelProcessRequester::shared_pointer
const & channelProcessRequester,
122 PVStructurePtr
const & pvRequest,
126 PVStructurePtr pvOptions;
128 if(pvRequest) pvField = pvRequest->getSubField(
"record._options");
130 pvOptions = static_pointer_cast<PVStructure>(pvField);
131 pvField = pvOptions->getSubField(
"nProcess");
133 PVStringPtr pvString = pvOptions->getSubField<PVString>(
"nProcess");
136 std::stringstream ss;
137 ss << pvString->get();
143 ChannelProcessLocalPtr process(
new ChannelProcessLocal(
145 channelProcessRequester,
148 if(pvRecord->getTraceLevel()>0)
150 cout <<
"ChannelProcessLocal::create";
151 cout <<
" recordName " << pvRecord->getRecordName() << endl;
153 channelProcessRequester->channelProcessConnect(Status::Ok, process);
157 ChannelProcessLocal::~ChannelProcessLocal()
160 if(pvr && pvr->getTraceLevel()>0) {
161 cout <<
"~ChannelProcessLocal() " << pvr->getRecordName() << endl;
165 std::tr1::shared_ptr<Channel> ChannelProcessLocal::getChannel()
171 void ChannelProcessLocal::lock()
174 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
177 void ChannelProcessLocal::unlock()
180 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
184 void ChannelProcessLocal::process()
186 ChannelProcessRequester::shared_pointer requester = channelProcessRequester.lock();
187 if(!requester)
return;
189 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
190 if(pvr->getTraceLevel()>1)
192 cout <<
"ChannelProcessLocal::process";
193 cout <<
" nProcess " << nProcess << endl;
196 for(
int i=0; i< nProcess; i++) {
197 epicsGuard <PVRecord> guard(*pvr);
198 pvr->beginGroupPut();
202 requester->processDone(Status::Ok,getPtrSelf());
203 }
catch(std::exception& ex) {
204 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
205 requester->processDone(status,getPtrSelf());
209 class ChannelGetLocal :
211 public std::tr1::enable_shared_from_this<ChannelGetLocal>
214 POINTER_DEFINITIONS(ChannelGetLocal);
215 virtual ~ChannelGetLocal();
216 virtual void destroy() {}
217 static ChannelGetLocalPtr create(
219 ChannelGetRequester::shared_pointer
const & channelGetRequester,
220 PVStructurePtr
const & pvRequest,
223 virtual std::tr1::shared_ptr<Channel> getChannel();
224 virtual void cancel(){}
226 virtual void unlock();
227 virtual void lastRequest() {}
229 shared_pointer getPtrSelf()
231 return shared_from_this();
236 ChannelGetRequester::shared_pointer
const & channelGetRequester,
238 PVStructurePtr
const&pvStructure,
239 BitSetPtr
const & bitSet,
243 callProcess(callProcess),
244 channelLocal(channelLocal),
245 channelGetRequester(channelGetRequester),
247 pvStructure(pvStructure),
255 ChannelGetRequester::weak_pointer channelGetRequester;
257 PVStructurePtr pvStructure;
263 ChannelGetLocalPtr ChannelGetLocal::create(
265 ChannelGetRequester::shared_pointer
const & channelGetRequester,
266 PVStructurePtr
const & pvRequest,
270 pvRecord->getPVRecordStructure()->getPVStructure(),
275 Status::STATUSTYPE_ERROR,
276 "invalid pvRequest");
277 ChannelGet::shared_pointer channelGet;
278 channelGetRequester->channelGetConnect(
282 ChannelGetLocalPtr localGet;
285 PVStructurePtr pvStructure = pvCopy->createPVStructure();
286 BitSetPtr bitSet(
new BitSet(pvStructure->getNumberFields()));
287 ChannelGetLocalPtr
get(
new ChannelGetLocal(
288 getProcess(pvRequest,
false),
295 if(pvRecord->getTraceLevel()>0)
297 cout <<
"ChannelGetLocal::create";
298 cout <<
" recordName " << pvRecord->getRecordName() << endl;
300 channelGetRequester->channelGetConnect(
301 Status::Ok,
get,pvStructure->getStructure());
305 ChannelGetLocal::~ChannelGetLocal()
308 if(pvr && pvr->getTraceLevel()>0) {
309 cout <<
"~ChannelGetLocal() " << pvr->getRecordName() << endl;
313 std::tr1::shared_ptr<Channel> ChannelGetLocal::getChannel()
319 void ChannelGetLocal::lock()
322 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
325 void ChannelGetLocal::unlock()
328 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
333 void ChannelGetLocal::get()
335 ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
336 if(!requester)
return;
338 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
340 bool notifyClient =
true;
343 epicsGuard <PVRecord> guard(*pvr);
345 pvr->beginGroupPut();
349 notifyClient = pvCopy->updateCopySetBitSet(pvStructure, bitSet);
365 BitSetPtr temp(
new BitSet(bitSet->size()));
372 if(pvr->getTraceLevel()>1)
374 cout <<
"ChannelGetLocal::get" << endl;
376 }
catch(std::exception& ex) {
377 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
378 requester->getDone(status,getPtrSelf(),pvStructure,bitSet);
383 class ChannelPutLocal :
385 public std::tr1::enable_shared_from_this<ChannelPutLocal>
388 POINTER_DEFINITIONS(ChannelPutLocal);
389 virtual ~ChannelPutLocal();
390 virtual void destroy() {}
391 static ChannelPutLocalPtr create(
393 ChannelPutRequester::shared_pointer
const & channelPutRequester,
394 PVStructurePtr
const & pvRequest,
396 virtual void put(PVStructurePtr
const &pvStructure,BitSetPtr
const &bitSet);
398 virtual std::tr1::shared_ptr<Channel> getChannel();
399 virtual void cancel(){}
401 virtual void unlock();
402 virtual void lastRequest() {}
404 shared_pointer getPtrSelf()
406 return shared_from_this();
411 ChannelPutRequester::shared_pointer
const & channelPutRequester,
415 callProcess(callProcess),
416 channelLocal(channelLocal),
417 channelPutRequester(channelPutRequester),
424 ChannelPutRequester::weak_pointer channelPutRequester;
430 ChannelPutLocalPtr ChannelPutLocal::create(
432 ChannelPutRequester::shared_pointer
const & channelPutRequester,
433 PVStructurePtr
const & pvRequest,
437 pvRecord->getPVRecordStructure()->getPVStructure(),
442 Status::STATUSTYPE_ERROR,
443 "invalid pvRequest");
444 ChannelPut::shared_pointer channelPut;
445 PVStructurePtr pvStructure;
447 channelPutRequester->channelPutConnect(
451 ChannelPutLocalPtr localPut;
454 ChannelPutLocalPtr put(
new ChannelPutLocal(
455 getProcess(pvRequest,
true),
460 channelPutRequester->channelPutConnect(
461 Status::Ok, put, pvCopy->getStructure());
462 if(pvRecord->getTraceLevel()>0)
464 cout <<
"ChannelPutLocal::create";
465 cout <<
" recordName " << pvRecord->getRecordName() << endl;
470 ChannelPutLocal::~ChannelPutLocal()
473 if(pvr && pvr->getTraceLevel()>0) {
474 cout <<
"~ChannelPutLocal() " << pvr->getRecordName() << endl;
478 std::tr1::shared_ptr<Channel> ChannelPutLocal::getChannel()
484 void ChannelPutLocal::lock()
487 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
490 void ChannelPutLocal::unlock()
493 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
498 void ChannelPutLocal::get()
500 ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
501 if(!requester)
return;
503 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
505 PVStructurePtr pvStructure = pvCopy->createPVStructure();
506 BitSetPtr bitSet(
new BitSet(pvStructure->getNumberFields()));
510 epicsGuard <PVRecord> guard(*pvr);
511 pvCopy->updateCopyFromBitSet(pvStructure, bitSet);
514 Status::Ok,getPtrSelf(),pvStructure,bitSet);
515 if(pvr->getTraceLevel()>1)
517 cout <<
"ChannelPutLocal::get" << endl;
519 }
catch(std::exception& ex) {
520 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
521 PVStructurePtr pvStructure;
523 requester->getDone(status,getPtrSelf(),pvStructure,bitSet);
527 void ChannelPutLocal::put(
528 PVStructurePtr
const &pvStructure,BitSetPtr
const &bitSet)
530 ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
531 if(!requester)
return;
533 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
536 epicsGuard <PVRecord> guard(*pvr);
537 pvr->beginGroupPut();
538 pvCopy->updateMaster(pvStructure, bitSet);
544 requester->putDone(Status::Ok,getPtrSelf());
545 if(pvr->getTraceLevel()>1)
547 cout <<
"ChannelPutLocal::put" << endl;
549 }
catch(std::exception& ex) {
550 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
551 requester->putDone(status,getPtrSelf());
556 class ChannelPutGetLocal :
557 public ChannelPutGet,
558 public std::tr1::enable_shared_from_this<ChannelPutGetLocal>
561 POINTER_DEFINITIONS(ChannelPutGetLocal);
562 virtual ~ChannelPutGetLocal();
563 virtual void destroy() {}
564 static ChannelPutGetLocalPtr create(
566 ChannelPutGetRequester::shared_pointer
const & channelPutGetRequester,
567 PVStructurePtr
const & pvRequest,
570 PVStructurePtr
const &pvPutStructure,
571 BitSetPtr
const &putBitSet);
572 virtual void getPut();
573 virtual void getGet();
574 virtual std::tr1::shared_ptr<Channel> getChannel();
575 virtual void cancel(){}
577 virtual void unlock();
578 virtual void lastRequest() {}
580 shared_pointer getPtrSelf()
582 return shared_from_this();
587 ChannelPutGetRequester::weak_pointer
const & channelPutGetRequester,
590 PVStructurePtr
const&pvGetStructure,
591 BitSetPtr
const & getBitSet,
594 callProcess(callProcess),
595 channelLocal(channelLocal),
596 channelPutGetRequester(channelPutGetRequester),
597 pvPutCopy(pvPutCopy),
598 pvGetCopy(pvGetCopy),
599 pvGetStructure(pvGetStructure),
600 getBitSet(getBitSet),
606 ChannelPutGetRequester::weak_pointer channelPutGetRequester;
609 PVStructurePtr pvGetStructure;
615 ChannelPutGetLocalPtr ChannelPutGetLocal::create(
617 ChannelPutGetRequester::shared_pointer
const & channelPutGetRequester,
618 PVStructurePtr
const & pvRequest,
622 pvRecord->getPVRecordStructure()->getPVStructure(),
626 pvRecord->getPVRecordStructure()->getPVStructure(),
629 if(!pvPutCopy || !pvGetCopy) {
631 Status::STATUSTYPE_ERROR,
632 "invalid pvRequest");
633 ChannelPutGet::shared_pointer channelPutGet;
634 channelPutGetRequester->channelPutGetConnect(
639 ChannelPutGetLocalPtr localPutGet;
642 PVStructurePtr pvGetStructure = pvGetCopy->createPVStructure();
643 BitSetPtr getBitSet(
new BitSet(pvGetStructure->getNumberFields()));
644 ChannelPutGetLocalPtr putGet(
new ChannelPutGetLocal(
645 getProcess(pvRequest,
true),
647 channelPutGetRequester,
653 if(pvRecord->getTraceLevel()>0)
655 cout <<
"ChannelPutGetLocal::create";
656 cout <<
" recordName " << pvRecord->getRecordName() << endl;
658 channelPutGetRequester->channelPutGetConnect(
659 Status::Ok, putGet, pvPutCopy->getStructure(),pvGetCopy->getStructure());
663 ChannelPutGetLocal::~ChannelPutGetLocal()
666 if(pvr && pvr->getTraceLevel()>0) {
667 cout <<
"~ChannelPutGetLocal() " << pvr->getRecordName() << endl;
671 std::tr1::shared_ptr<Channel> ChannelPutGetLocal::getChannel()
677 void ChannelPutGetLocal::lock()
680 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
683 void ChannelPutGetLocal::unlock()
686 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
691 void ChannelPutGetLocal::putGet(
692 PVStructurePtr
const &pvPutStructure,BitSetPtr
const &putBitSet)
694 ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
695 if(!requester)
return;
697 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
700 epicsGuard <PVRecord> guard(*pvr);
701 pvr->beginGroupPut();
702 pvPutCopy->updateMaster(pvPutStructure, putBitSet);
703 if(callProcess) pvr->process();
705 pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
708 requester->putGetDone(
709 Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
710 if(pvr->getTraceLevel()>1)
712 cout <<
"ChannelPutGetLocal::putGet" << endl;
714 }
catch(std::exception& ex) {
715 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
716 requester->putGetDone(status,getPtrSelf(),pvGetStructure,getBitSet);
720 void ChannelPutGetLocal::getPut()
722 ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
723 if(!requester)
return;
725 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
727 PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure();
728 BitSetPtr putBitSet(
new BitSet(pvPutStructure->getNumberFields()));
730 epicsGuard <PVRecord> guard(*pvr);
731 pvPutCopy->initCopy(pvPutStructure, putBitSet);
733 requester->getPutDone(
734 Status::Ok,getPtrSelf(),pvPutStructure,putBitSet);
735 if(pvr->getTraceLevel()>1)
737 cout <<
"ChannelPutGetLocal::getPut" << endl;
739 }
catch(std::exception& ex) {
740 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
741 PVStructurePtr pvPutStructure;
743 requester->getPutDone(status,getPtrSelf(),pvGetStructure,getBitSet);
747 void ChannelPutGetLocal::getGet()
749 ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
750 if(!requester)
return;
752 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
756 epicsGuard <PVRecord> guard(*pvr);
757 pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
759 requester->getGetDone(
760 Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
761 if(pvr->getTraceLevel()>1)
763 cout <<
"ChannelPutGetLocal::getGet" << endl;
765 }
catch(std::exception& ex) {
766 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
767 PVStructurePtr pvPutStructure;
769 requester->getGetDone(status,getPtrSelf(),pvGetStructure,getBitSet);
774 class ChannelRPCLocal :
776 public RPCResponseCallback,
777 public std::tr1::enable_shared_from_this<ChannelRPCLocal>
780 POINTER_DEFINITIONS(ChannelRPCLocal);
781 virtual void destroy() {}
782 static ChannelRPCLocalPtr create(
784 ChannelRPCRequester::shared_pointer
const & channelRPCRequester,
785 PVStructurePtr
const & pvRequest,
790 ChannelRPCRequester::shared_pointer
const & channelRPCRequester,
791 RPCServiceAsync::shared_pointer
const & service,
793 channelLocal(channelLocal),
794 channelRPCRequester(channelRPCRequester),
800 virtual ~ChannelRPCLocal();
801 void processRequest(RPCService::shared_pointer
const & service,
802 PVStructurePtr
const & pvArgument);
804 virtual void requestDone(Status
const & status,
805 PVStructurePtr
const & result)
807 ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
808 if(!requester)
return;
809 requester->requestDone(status, getPtrSelf(), result);
812 void processRequest(RPCServiceAsync::shared_pointer
const & service,
813 PVStructurePtr
const & pvArgument);
815 virtual void request(PVStructurePtr
const & pvArgument);
816 virtual Channel::shared_pointer getChannel();
817 virtual void cancel() {}
818 virtual void lock() {}
819 virtual void unlock() {}
820 virtual void lastRequest() {}
822 shared_pointer getPtrSelf()
824 return shared_from_this();
827 ChannelRPCRequester::weak_pointer channelRPCRequester;
828 RPCServiceAsync::shared_pointer service;
832 ChannelRPCLocalPtr ChannelRPCLocal::create(
834 ChannelRPCRequester::shared_pointer
const & channelRPCRequester,
835 PVStructurePtr
const & pvRequest,
838 RPCServiceAsync::shared_pointer service = pvRecord->getService(pvRequest);
841 Status status(Status::STATUSTYPE_ERROR,
842 "ChannelRPC not supported");
847 if (!channelRPCRequester)
848 throw std::invalid_argument(
"channelRPCRequester == null");
851 ChannelRPCLocalPtr rpc(
852 new ChannelRPCLocal(channelLocal, channelRPCRequester, service, pvRecord)
854 channelRPCRequester->channelRPCConnect(Status::Ok, rpc);
855 if(pvRecord->getTraceLevel()>0)
857 cout <<
"ChannelRPCLocal::create";
858 cout <<
" recordName " << pvRecord->getRecordName() << endl;
863 ChannelRPCLocal::~ChannelRPCLocal()
866 if(pvr && pvr->getTraceLevel()>0) {
867 cout <<
"~ChannelRPCLocal() " << pvr->getRecordName() << endl;
871 std::tr1::shared_ptr<Channel> ChannelRPCLocal::getChannel()
878 void ChannelRPCLocal::processRequest(
879 RPCService::shared_pointer
const & service,
880 PVStructurePtr
const & pvArgument)
882 PVStructurePtr result;
883 Status status = Status::Ok;
887 result = service->request(pvArgument);
889 catch (RPCRequestException& rre)
891 status = Status(rre.getStatus(), rre.what());
894 catch (std::exception& ex)
896 status = Status(Status::STATUSTYPE_FATAL, ex.what());
902 status = Status(Status::STATUSTYPE_FATAL,
"Unexpected exception caught while calling RPCService.request(PVStructure).");
909 status = Status(Status::STATUSTYPE_FATAL,
"RPCService.request(PVStructure) returned null.");
911 ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
912 if(requester) requester->requestDone(status, getPtrSelf(), result);
915 void ChannelRPCLocal::processRequest(
916 RPCServiceAsync::shared_pointer
const & service,
917 PVStructurePtr
const & pvArgument)
921 service->request(pvArgument, getPtrSelf());
923 catch (std::exception& ex)
926 Status errorStatus(Status::STATUSTYPE_FATAL, ex.what());
927 ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
928 if(requester) requester->requestDone(errorStatus, getPtrSelf(), PVStructurePtr());
933 Status errorStatus(Status::STATUSTYPE_FATAL,
934 "Unexpected exception caught while calling RPCServiceAsync.request(PVStructure, RPCResponseCallback).");
935 ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
936 if(requester) requester->requestDone(errorStatus, shared_from_this(), PVStructurePtr());
943 void ChannelRPCLocal::request(PVStructurePtr
const & pvArgument)
946 if(pvr && pvr->getTraceLevel()>0) {
947 cout <<
"ChannelRPCLocal::request " << pvr->getRecordName() << endl;
949 RPCService::shared_pointer rpcService =
950 std::tr1::dynamic_pointer_cast<RPCService>(service);
953 processRequest(rpcService, pvArgument);
957 RPCServiceAsync::shared_pointer rpcServiceAsync =
958 std::tr1::dynamic_pointer_cast<RPCServiceAsync>(service);
961 processRequest(rpcServiceAsync, pvArgument);
969 class ChannelArrayLocal :
971 public std::tr1::enable_shared_from_this<ChannelArrayLocal>
974 POINTER_DEFINITIONS(ChannelArrayLocal);
975 virtual ~ChannelArrayLocal();
976 virtual void destroy() {}
977 static ChannelArrayLocalPtr create(
979 ChannelArrayRequester::shared_pointer
const & channelArrayRequester,
980 PVStructurePtr
const & pvRequest,
982 virtual void getArray(
size_t offset,
size_t count,
size_t stride);
983 virtual void putArray(
984 PVArrayPtr
const &putArray,
985 size_t offset,
size_t count,
size_t stride);
986 virtual void getLength();
987 virtual void setLength(
size_t length);
988 virtual std::tr1::shared_ptr<Channel> getChannel();
989 virtual void cancel(){}
991 virtual void unlock();
992 virtual void lastRequest() {}
994 shared_pointer getPtrSelf()
996 return shared_from_this();
1000 ChannelArrayRequester::shared_pointer
const & channelArrayRequester,
1001 PVArrayPtr
const &pvArray,
1002 PVArrayPtr
const &pvCopy,
1005 channelLocal(channelLocal),
1006 channelArrayRequester(channelArrayRequester),
1014 ChannelArrayRequester::weak_pointer channelArrayRequester;
1022 ChannelArrayLocalPtr ChannelArrayLocal::create(
1024 ChannelArrayRequester::shared_pointer
const & channelArrayRequester,
1025 PVStructurePtr
const & pvRequest,
1028 PVFieldPtrArray
const & pvFields = pvRequest->getPVFields();
1029 if(pvFields.size()!=1) {
1031 Status::STATUSTYPE_ERROR,
"invalid pvRequest");
1032 ChannelArrayLocalPtr channelArray;
1033 ArrayConstPtr array;
1034 channelArrayRequester->channelArrayConnect(status,channelArray,array);
1035 return channelArray;
1037 PVFieldPtr pvField = pvFields[0];
1038 string fieldName(
"");
1040 string name = pvField->getFieldName();
1041 if(fieldName.size()>0) fieldName +=
'.';
1043 PVStructurePtr pvs = static_pointer_cast<PVStructure>(pvField);
1044 PVFieldPtrArray
const & pvfs = pvs->getPVFields();
1045 if(pvfs.size()!=1)
break;
1048 size_t indfield = fieldName.find_first_of(
"field.");
1050 fieldName = fieldName.substr(6);
1052 pvField = pvRecord->getPVRecordStructure()->getPVStructure()->getSubField(fieldName);
1055 Status::STATUSTYPE_ERROR,fieldName +
" not found");
1056 ChannelArrayLocalPtr channelArray;
1057 ArrayConstPtr array;
1058 channelArrayRequester->channelArrayConnect(
1059 status,channelArray,array);
1060 return channelArray;
1062 if(pvField->getField()->getType()!=scalarArray
1063 && pvField->getField()->getType()!=structureArray
1064 && pvField->getField()->getType()!=unionArray)
1067 Status::STATUSTYPE_ERROR,fieldName +
" not array");
1068 ChannelArrayLocalPtr channelArray;
1069 ArrayConstPtr array;
1070 channelArrayRequester->channelArrayConnect(
1071 status,channelArray,array);
1072 return channelArray;
1074 PVArrayPtr pvArray = static_pointer_cast<PVArray>(pvField);
1076 if(pvField->getField()->getType()==scalarArray) {
1077 PVScalarArrayPtr xxx = static_pointer_cast<PVScalarArray>(pvField);
1078 pvCopy = getPVDataCreate()->createPVScalarArray(
1079 xxx->getScalarArray()->getElementType());
1080 }
else if(pvField->getField()->getType()==structureArray) {
1081 PVStructureArrayPtr xxx = static_pointer_cast<PVStructureArray>(pvField);
1082 pvCopy = getPVDataCreate()->createPVStructureArray(
1083 xxx->getStructureArray()->getStructure());
1085 PVUnionArrayPtr xxx = static_pointer_cast<PVUnionArray>(pvField);
1086 pvCopy = getPVDataCreate()->createPVUnionArray(
1087 xxx->getUnionArray()->getUnion());
1089 ChannelArrayLocalPtr array(
new ChannelArrayLocal(
1091 channelArrayRequester,
1095 if(pvRecord->getTraceLevel()>0)
1097 cout <<
"ChannelArrayLocal::create";
1098 cout <<
" recordName " << pvRecord->getRecordName() << endl;
1100 channelArrayRequester->channelArrayConnect(
1101 Status::Ok, array, pvCopy->getArray());
1105 ChannelArrayLocal::~ChannelArrayLocal()
1108 if(pvr && pvr->getTraceLevel()>0) {
1109 cout <<
"~ChannelArrayLocal() " << pvr->getRecordName() << endl;
1113 std::tr1::shared_ptr<Channel> ChannelArrayLocal::getChannel()
1119 void ChannelArrayLocal::lock()
1122 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1125 void ChannelArrayLocal::unlock()
1128 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1132 void ChannelArrayLocal::getArray(
size_t offset,
size_t count,
size_t stride)
1134 ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1135 if(!requester)
return;
1137 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1138 if(pvr->getTraceLevel()>1)
1140 cout <<
"ChannelArrayLocal::getArray" << endl;
1142 const char *exceptionMessage = NULL;
1145 epicsGuard <PVRecord> guard(*pvr);
1147 size_t length = pvArray->getLength();
1148 if(length<=0)
break;
1150 count = (length -offset + stride -1)/stride;
1151 if(count>0) ok =
true;
1154 size_t maxcount = (length -offset + stride -1)/stride;
1155 if(count>maxcount) count = maxcount;
1160 pvCopy->setLength(count);
1161 copy(pvArray,offset,stride,pvCopy,0,1,count);
1163 }
catch(std::exception& e) {
1164 exceptionMessage = e.what();
1166 Status status = Status::Ok;
1167 if(exceptionMessage!=NULL) {
1168 status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1170 requester->getArrayDone(status,getPtrSelf(),pvCopy);
1173 void ChannelArrayLocal::putArray(
1174 PVArrayPtr
const & pvArray,
size_t offset,
size_t count,
size_t stride)
1176 ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1177 if(!requester)
return;
1179 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1180 if(pvr->getTraceLevel()>1)
1182 cout <<
"ChannelArrayLocal::putArray" << endl;
1184 size_t newLength = offset + count*stride;
1185 if(newLength<pvArray->getLength()) pvArray->setLength(newLength);
1186 const char *exceptionMessage = NULL;
1188 epicsGuard <PVRecord> guard(*pvr);
1189 copy(pvArray,0,1,this->pvArray,offset,stride,count);
1190 }
catch(std::exception& e) {
1191 exceptionMessage = e.what();
1193 Status status = Status::Ok;
1194 if(exceptionMessage!=NULL) {
1195 status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1197 requester->putArrayDone(status,getPtrSelf());
1200 void ChannelArrayLocal::getLength()
1202 ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1203 if(!requester)
return;
1205 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1207 const char *exceptionMessage = NULL;
1209 epicsGuard <PVRecord> guard(*pvr);
1210 length = pvArray->getLength();
1211 }
catch(std::exception& e) {
1212 exceptionMessage = e.what();
1214 Status status = Status::Ok;
1215 if(exceptionMessage!=NULL) {
1216 status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1218 requester->getLengthDone(status,getPtrSelf(),length);
1221 void ChannelArrayLocal::setLength(
size_t length)
1223 ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1224 if(!requester)
return;
1226 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1227 if(pvr->getTraceLevel()>1)
1229 cout <<
"ChannelArrayLocal::setLength" << endl;
1233 epicsGuard <PVRecord> guard(*pvr);
1234 if(pvArray->getLength()!=length) pvArray->setLength(length);
1236 requester->setLengthDone(Status::Ok,getPtrSelf());
1237 }
catch(std::exception& e) {
1238 string exceptionMessage = e.what();
1239 Status status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1240 requester->setLengthDone(status,getPtrSelf());
1245 ChannelLocal::ChannelLocal(
1247 ChannelRequester::shared_pointer
const & requester,
1250 requester(requester),
1254 if(pvRecord->getTraceLevel()>0) {
1255 cout <<
"ChannelLocal::ChannelLocal()" 1256 <<
" recordName " << pvRecord->getRecordName()
1257 <<
" requester exists " << (requester ?
"true" :
"false")
1266 if(pvr->getTraceLevel()>0)
1268 cout <<
"~ChannelLocal()" << endl;
1274 return provider.lock();
1279 if(pvRecord->getTraceLevel()>0) {
1280 cout <<
"ChannelLocal::detach() " 1281 <<
" recordName " << pvRecord->getRecordName()
1282 <<
" requester exists " << (requester ?
"true" :
"false")
1285 if(!requester)
return;
1286 requester->channelStateChange(shared_from_this(),Channel::DESTROYED);
1293 if(pvr && pvr->getTraceLevel()>0) {
1294 cout <<
"ChannelLocal::getRequesterName() " 1295 <<
" recordName " << pvr->getRecordName()
1296 <<
" requester exists " << (requester ?
"true" :
"false")
1300 if(!requester)
return string();
1301 return requester->getRequesterName();
1306 MessageType messageType)
1309 if(pvr && pvr->getTraceLevel()>1) {
1310 cout <<
"ChannelLocal::message() " 1311 <<
" recordName " << pvr->getRecordName()
1312 <<
" requester exists " << (requester ?
"true" :
"false")
1316 requester->message(message,messageType);
1319 string recordName(
"record deleted");
1320 if(pvr) recordName = pvr->getRecordName();
1322 <<
" message " << message
1323 <<
" messageType " << getMessageTypeName(messageType)
1329 return string(
"local");
1334 return Channel::CONNECTED;
1340 string name(
"record deleted");
1341 if(pvr) name = pvr->getRecordName();
1356 string const &subField)
1359 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1360 if(subField.size()<1) {
1361 StructureConstPtr structure =
1362 pvr->getPVRecordStructure()->getPVStructure()->getStructure();
1363 requester->getDone(Status::Ok,structure);
1366 PVFieldPtr pvField =
1367 pvr->getPVRecordStructure()->getPVStructure()->getSubField(subField);
1369 requester->getDone(Status::Ok,pvField->getField());
1372 Status status(Status::STATUSTYPE_ERROR,
1373 "client asked for illegal field");
1374 requester->getDone(status,FieldConstPtr());
1378 PVField::shared_pointer
const &pvField)
1380 throw std::logic_error(
"Not Implemented");
1384 ChannelProcessRequester::shared_pointer
const & channelProcessRequester,
1385 PVStructure::shared_pointer
const & pvRequest)
1388 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1389 if(pvr->getTraceLevel()>0) {
1390 cout <<
"ChannelLocal::createChannelProcess() " 1391 <<
" recordName " << pvr->getRecordName()
1392 <<
" requester exists " << (requester ?
"true" :
"false")
1395 ChannelProcessLocalPtr channelProcess =
1396 ChannelProcessLocal::create(
1398 channelProcessRequester,
1401 return channelProcess;
1405 ChannelGetRequester::shared_pointer
const &channelGetRequester,
1406 PVStructure::shared_pointer
const &pvRequest)
1409 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1410 if(pvr->getTraceLevel()>0) {
1411 cout <<
"ChannelLocal::createChannelGet() " 1412 <<
" recordName " << pvr->getRecordName()
1413 <<
" requester exists " << (requester ?
"true" :
"false")
1416 ChannelGetLocalPtr channelGet =
1417 ChannelGetLocal::create(
1419 channelGetRequester,
1426 ChannelPutRequester::shared_pointer
const &channelPutRequester,
1427 PVStructure::shared_pointer
const &pvRequest)
1430 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1431 if(pvr->getTraceLevel()>0) {
1432 cout <<
"ChannelLocal::createChannelPut() " 1433 <<
" recordName " << pvr->getRecordName()
1434 <<
" requester exists " << (requester ?
"true" :
"false")
1438 ChannelPutLocalPtr channelPut =
1439 ChannelPutLocal::create(
1441 channelPutRequester,
1448 ChannelPutGetRequester::shared_pointer
const &channelPutGetRequester,
1449 PVStructure::shared_pointer
const &pvRequest)
1452 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1453 if(pvr->getTraceLevel()>0) {
1454 cout <<
"ChannelLocal::createChannelPutGet() " 1455 <<
" recordName " << pvr->getRecordName()
1456 <<
" requester exists " << (requester ?
"true" :
"false")
1460 ChannelPutGetLocalPtr channelPutGet =
1461 ChannelPutGetLocal::create(
1463 channelPutGetRequester,
1466 return channelPutGet;
1470 ChannelRPCRequester::shared_pointer
const & channelRPCRequester,
1471 PVStructure::shared_pointer
const & pvRequest)
1474 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1475 if(pvr->getTraceLevel()>0) {
1476 cout <<
"ChannelLocal::createChannelRPC() " 1477 <<
" recordName " << pvr->getRecordName()
1478 <<
" requester exists " << (requester ?
"true" :
"false")
1482 ChannelRPCLocalPtr channelRPC =
1483 ChannelRPCLocal::create(
1485 channelRPCRequester,
1492 MonitorRequester::shared_pointer
const &monitorRequester,
1493 PVStructure::shared_pointer
const &pvRequest)
1496 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1497 if(pvr->getTraceLevel()>0) {
1498 cout <<
"ChannelLocal::createMonitor() " 1499 <<
" recordName " << pvr->getRecordName()
1500 <<
" requester exists " << (requester ?
"true" :
"false")
1512 ChannelArrayRequester::shared_pointer
const &channelArrayRequester,
1513 PVStructure::shared_pointer
const &pvRequest)
1516 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1517 if(pvr->getTraceLevel()>0) {
1518 cout <<
"ChannelLocal::createChannelArray() " 1519 <<
" recordName " << pvr->getRecordName()
1520 <<
" requester exists " << (requester ?
"true" :
"false")
1523 ChannelArrayLocalPtr channelArray =
1524 ChannelArrayLocal::create(
1526 channelArrayRequester,
1529 return channelArray;
1539 out <<
"ChannelLocal provides access to a record in the local PVDatabase";
virtual void printInfo()
calls printInfo(std::cout);
virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelPut.
shared_pointer getPtrSelf()
std::tr1::shared_ptr< PVCopy > PVCopyPtr
virtual std::string getRequesterName()
Get the requester name.
std::tr1::shared_ptr< ChannelRPCLocal > ChannelRPCLocalPtr
std::tr1::shared_ptr< ChannelLocal > ChannelLocalPtr
std::tr1::shared_ptr< PVArray > PVArrayPtr
virtual ~ChannelLocal()
Destructor.
std::tr1::weak_ptr< ChannelLocal > ChannelLocalWPtr
virtual void getField(epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField)
Get the introspection interface for subField.
virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC(epics::pvAccess::ChannelRPCRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelRPC.
virtual epics::pvData::Monitor::shared_pointer createMonitor(epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a monitor.
virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray(epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelArray.
epicsShareFunc epics::pvData::MonitorPtr createMonitorLocal(PVRecordPtr const &pvRecord, epics::pvData::MonitorRequester::shared_pointer const &monitorRequester, epics::pvData::PVStructurePtr const &pvRequest)
std::tr1::shared_ptr< ChannelProviderLocal > ChannelProviderLocalPtr
virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet(epics::pvAccess::ChannelPutGetRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelPutGet.
virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider()
Get the channel provider.
virtual epics::pvAccess::AccessRights getAccessRights(epics::pvData::PVField::shared_pointer const &pvField)
std::tr1::shared_ptr< ChannelPutGetLocal > ChannelPutGetLocalPtr
std::tr1::shared_ptr< PVRecord > PVRecordPtr
std::tr1::shared_ptr< ChannelArrayLocal > ChannelArrayLocalPtr
std::tr1::shared_ptr< ChannelProcessLocal > ChannelProcessLocalPtr
std::tr1::shared_ptr< ChannelGetLocal > ChannelGetLocalPtr
virtual std::string getChannelName()
Get the channel name.
std::tr1::weak_ptr< PVRecord > PVRecordWPtr
virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess(epics::pvAccess::ChannelProcessRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelProcess.
virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(epics::pvAccess::ChannelGetRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelGet.
std::tr1::shared_ptr< ChannelPutLocal > ChannelPutLocalPtr
virtual bool isConnected()
Is the channel connected?
virtual void message(std::string const &message, epics::pvData::MessageType messageType)
Passes the message to the channel requester.
virtual std::string getRemoteAddress()
Get the remote address.
virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester()
Get the channel requester.
virtual epics::pvAccess::Channel::ConnectionState getConnectionState()
virtual void detach(PVRecordPtr const &pvRecord)
Detach from the record.