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()
162 std::tr1::shared_ptr<Channel> ChannelProcessLocal::getChannel()
168 void ChannelProcessLocal::lock()
171 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
174 void ChannelProcessLocal::unlock()
177 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
181 void ChannelProcessLocal::process()
183 ChannelProcessRequester::shared_pointer requester = channelProcessRequester.lock();
184 if(!requester)
return;
186 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
187 if(pvr->getTraceLevel()>1)
189 cout <<
"ChannelProcessLocal::process";
190 cout <<
" nProcess " << nProcess << endl;
193 for(
int i=0; i< nProcess; i++) {
194 epicsGuard <PVRecord> guard(*pvr);
195 pvr->beginGroupPut();
199 requester->processDone(Status::Ok,getPtrSelf());
200 }
catch(std::exception& ex) {
201 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
202 requester->processDone(status,getPtrSelf());
206 class ChannelGetLocal :
208 public std::tr1::enable_shared_from_this<ChannelGetLocal>
211 POINTER_DEFINITIONS(ChannelGetLocal);
212 virtual ~ChannelGetLocal();
213 virtual void destroy() {}
214 static ChannelGetLocalPtr create(
216 ChannelGetRequester::shared_pointer
const & channelGetRequester,
217 PVStructurePtr
const & pvRequest,
220 virtual std::tr1::shared_ptr<Channel> getChannel();
221 virtual void cancel(){}
223 virtual void unlock();
224 virtual void lastRequest() {}
226 shared_pointer getPtrSelf()
228 return shared_from_this();
233 ChannelGetRequester::shared_pointer
const & channelGetRequester,
235 PVStructurePtr
const&pvStructure,
236 BitSetPtr
const & bitSet,
240 callProcess(callProcess),
241 channelLocal(channelLocal),
242 channelGetRequester(channelGetRequester),
244 pvStructure(pvStructure),
252 ChannelGetRequester::weak_pointer channelGetRequester;
254 PVStructurePtr pvStructure;
260 ChannelGetLocalPtr ChannelGetLocal::create(
262 ChannelGetRequester::shared_pointer
const & channelGetRequester,
263 PVStructurePtr
const & pvRequest,
267 pvRecord->getPVRecordStructure()->getPVStructure(),
272 Status::STATUSTYPE_ERROR,
273 "invalid pvRequest");
274 ChannelGet::shared_pointer channelGet;
275 channelGetRequester->channelGetConnect(
279 ChannelGetLocalPtr localGet;
282 PVStructurePtr pvStructure = pvCopy->createPVStructure();
283 BitSetPtr bitSet(
new BitSet(pvStructure->getNumberFields()));
284 ChannelGetLocalPtr
get(
new ChannelGetLocal(
285 getProcess(pvRequest,
false),
292 if(pvRecord->getTraceLevel()>0)
294 cout <<
"ChannelGetLocal::create";
295 cout <<
" recordName " << pvRecord->getRecordName() << endl;
297 channelGetRequester->channelGetConnect(
298 Status::Ok,
get,pvStructure->getStructure());
302 ChannelGetLocal::~ChannelGetLocal()
307 std::tr1::shared_ptr<Channel> ChannelGetLocal::getChannel()
313 void ChannelGetLocal::lock()
316 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
319 void ChannelGetLocal::unlock()
322 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
327 void ChannelGetLocal::get()
329 ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
330 if(!requester)
return;
332 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
334 bool notifyClient =
true;
337 epicsGuard <PVRecord> guard(*pvr);
339 pvr->beginGroupPut();
343 notifyClient = pvCopy->updateCopySetBitSet(pvStructure, bitSet);
359 BitSetPtr temp(
new BitSet(bitSet->size()));
366 if(pvr->getTraceLevel()>1)
368 cout <<
"ChannelGetLocal::get" << endl;
370 }
catch(std::exception& ex) {
371 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
372 requester->getDone(status,getPtrSelf(),pvStructure,bitSet);
377 class ChannelPutLocal :
379 public std::tr1::enable_shared_from_this<ChannelPutLocal>
382 POINTER_DEFINITIONS(ChannelPutLocal);
383 virtual ~ChannelPutLocal();
384 virtual void destroy() {}
385 static ChannelPutLocalPtr create(
387 ChannelPutRequester::shared_pointer
const & channelPutRequester,
388 PVStructurePtr
const & pvRequest,
390 virtual void put(PVStructurePtr
const &pvStructure,BitSetPtr
const &bitSet);
392 virtual std::tr1::shared_ptr<Channel> getChannel();
393 virtual void cancel(){}
395 virtual void unlock();
396 virtual void lastRequest() {}
398 shared_pointer getPtrSelf()
400 return shared_from_this();
405 ChannelPutRequester::shared_pointer
const & channelPutRequester,
409 callProcess(callProcess),
410 channelLocal(channelLocal),
411 channelPutRequester(channelPutRequester),
418 ChannelPutRequester::weak_pointer channelPutRequester;
424 ChannelPutLocalPtr ChannelPutLocal::create(
426 ChannelPutRequester::shared_pointer
const & channelPutRequester,
427 PVStructurePtr
const & pvRequest,
431 pvRecord->getPVRecordStructure()->getPVStructure(),
436 Status::STATUSTYPE_ERROR,
437 "invalid pvRequest");
438 ChannelPut::shared_pointer channelPut;
439 PVStructurePtr pvStructure;
441 channelPutRequester->channelPutConnect(
445 ChannelPutLocalPtr localPut;
448 ChannelPutLocalPtr put(
new ChannelPutLocal(
449 getProcess(pvRequest,
true),
454 channelPutRequester->channelPutConnect(
455 Status::Ok, put, pvCopy->getStructure());
456 if(pvRecord->getTraceLevel()>0)
458 cout <<
"ChannelPutLocal::create";
459 cout <<
" recordName " << pvRecord->getRecordName() << endl;
464 ChannelPutLocal::~ChannelPutLocal()
469 std::tr1::shared_ptr<Channel> ChannelPutLocal::getChannel()
475 void ChannelPutLocal::lock()
478 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
481 void ChannelPutLocal::unlock()
484 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
489 void ChannelPutLocal::get()
491 ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
492 if(!requester)
return;
494 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
496 PVStructurePtr pvStructure = pvCopy->createPVStructure();
497 BitSetPtr bitSet(
new BitSet(pvStructure->getNumberFields()));
501 epicsGuard <PVRecord> guard(*pvr);
502 pvCopy->updateCopyFromBitSet(pvStructure, bitSet);
505 Status::Ok,getPtrSelf(),pvStructure,bitSet);
506 if(pvr->getTraceLevel()>1)
508 cout <<
"ChannelPutLocal::get" << endl;
510 }
catch(std::exception& ex) {
511 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
512 PVStructurePtr pvStructure;
514 requester->getDone(status,getPtrSelf(),pvStructure,bitSet);
518 void ChannelPutLocal::put(
519 PVStructurePtr
const &pvStructure,BitSetPtr
const &bitSet)
521 ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
522 if(!requester)
return;
524 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
527 epicsGuard <PVRecord> guard(*pvr);
528 pvr->beginGroupPut();
529 pvCopy->updateMaster(pvStructure, bitSet);
535 requester->putDone(Status::Ok,getPtrSelf());
536 if(pvr->getTraceLevel()>1)
538 cout <<
"ChannelPutLocal::put" << endl;
540 }
catch(std::exception& ex) {
541 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
542 requester->putDone(status,getPtrSelf());
547 class ChannelPutGetLocal :
548 public ChannelPutGet,
549 public std::tr1::enable_shared_from_this<ChannelPutGetLocal>
552 POINTER_DEFINITIONS(ChannelPutGetLocal);
553 virtual ~ChannelPutGetLocal();
554 virtual void destroy() {}
555 static ChannelPutGetLocalPtr create(
557 ChannelPutGetRequester::shared_pointer
const & channelPutGetRequester,
558 PVStructurePtr
const & pvRequest,
561 PVStructurePtr
const &pvPutStructure,
562 BitSetPtr
const &putBitSet);
563 virtual void getPut();
564 virtual void getGet();
565 virtual std::tr1::shared_ptr<Channel> getChannel();
566 virtual void cancel(){}
568 virtual void unlock();
569 virtual void lastRequest() {}
571 shared_pointer getPtrSelf()
573 return shared_from_this();
578 ChannelPutGetRequester::weak_pointer
const & channelPutGetRequester,
581 PVStructurePtr
const&pvGetStructure,
582 BitSetPtr
const & getBitSet,
585 callProcess(callProcess),
586 channelLocal(channelLocal),
587 channelPutGetRequester(channelPutGetRequester),
588 pvPutCopy(pvPutCopy),
589 pvGetCopy(pvGetCopy),
590 pvGetStructure(pvGetStructure),
591 getBitSet(getBitSet),
597 ChannelPutGetRequester::weak_pointer channelPutGetRequester;
600 PVStructurePtr pvGetStructure;
606 ChannelPutGetLocalPtr ChannelPutGetLocal::create(
608 ChannelPutGetRequester::shared_pointer
const & channelPutGetRequester,
609 PVStructurePtr
const & pvRequest,
613 pvRecord->getPVRecordStructure()->getPVStructure(),
617 pvRecord->getPVRecordStructure()->getPVStructure(),
620 if(!pvPutCopy || !pvGetCopy) {
622 Status::STATUSTYPE_ERROR,
623 "invalid pvRequest");
624 ChannelPutGet::shared_pointer channelPutGet;
625 channelPutGetRequester->channelPutGetConnect(
630 ChannelPutGetLocalPtr localPutGet;
633 PVStructurePtr pvGetStructure = pvGetCopy->createPVStructure();
634 BitSetPtr getBitSet(
new BitSet(pvGetStructure->getNumberFields()));
635 ChannelPutGetLocalPtr putGet(
new ChannelPutGetLocal(
636 getProcess(pvRequest,
true),
638 channelPutGetRequester,
644 if(pvRecord->getTraceLevel()>0)
646 cout <<
"ChannelPutGetLocal::create";
647 cout <<
" recordName " << pvRecord->getRecordName() << endl;
649 channelPutGetRequester->channelPutGetConnect(
650 Status::Ok, putGet, pvPutCopy->getStructure(),pvGetCopy->getStructure());
654 ChannelPutGetLocal::~ChannelPutGetLocal()
659 std::tr1::shared_ptr<Channel> ChannelPutGetLocal::getChannel()
665 void ChannelPutGetLocal::lock()
668 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
671 void ChannelPutGetLocal::unlock()
674 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
679 void ChannelPutGetLocal::putGet(
680 PVStructurePtr
const &pvPutStructure,BitSetPtr
const &putBitSet)
682 ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
683 if(!requester)
return;
685 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
688 epicsGuard <PVRecord> guard(*pvr);
689 pvr->beginGroupPut();
690 pvPutCopy->updateMaster(pvPutStructure, putBitSet);
691 if(callProcess) pvr->process();
693 pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
696 requester->putGetDone(
697 Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
698 if(pvr->getTraceLevel()>1)
700 cout <<
"ChannelPutGetLocal::putGet" << endl;
702 }
catch(std::exception& ex) {
703 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
704 requester->putGetDone(status,getPtrSelf(),pvGetStructure,getBitSet);
708 void ChannelPutGetLocal::getPut()
710 ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
711 if(!requester)
return;
713 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
715 PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure();
716 BitSetPtr putBitSet(
new BitSet(pvPutStructure->getNumberFields()));
718 epicsGuard <PVRecord> guard(*pvr);
719 pvPutCopy->initCopy(pvPutStructure, putBitSet);
721 requester->getPutDone(
722 Status::Ok,getPtrSelf(),pvPutStructure,putBitSet);
723 if(pvr->getTraceLevel()>1)
725 cout <<
"ChannelPutGetLocal::getPut" << endl;
727 }
catch(std::exception& ex) {
728 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
729 PVStructurePtr pvPutStructure;
731 requester->getPutDone(status,getPtrSelf(),pvGetStructure,getBitSet);
735 void ChannelPutGetLocal::getGet()
737 ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
738 if(!requester)
return;
740 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
744 epicsGuard <PVRecord> guard(*pvr);
745 pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
747 requester->getGetDone(
748 Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
749 if(pvr->getTraceLevel()>1)
751 cout <<
"ChannelPutGetLocal::getGet" << endl;
753 }
catch(std::exception& ex) {
754 Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
755 PVStructurePtr pvPutStructure;
757 requester->getGetDone(status,getPtrSelf(),pvGetStructure,getBitSet);
762 class ChannelRPCLocal :
764 public RPCResponseCallback,
765 public std::tr1::enable_shared_from_this<ChannelRPCLocal>
768 POINTER_DEFINITIONS(ChannelRPCLocal);
769 virtual void destroy() {}
770 static ChannelRPCLocalPtr create(
772 ChannelRPCRequester::shared_pointer
const & channelRPCRequester,
773 PVStructurePtr
const & pvRequest,
778 ChannelRPCRequester::shared_pointer
const & channelRPCRequester,
779 RPCServiceAsync::shared_pointer
const & service,
781 channelLocal(channelLocal),
782 channelRPCRequester(channelRPCRequester),
788 virtual ~ChannelRPCLocal();
789 void processRequest(RPCService::shared_pointer
const & service,
790 PVStructurePtr
const & pvArgument);
792 virtual void requestDone(Status
const & status,
793 PVStructurePtr
const & result)
795 ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
796 if(!requester)
return;
797 requester->requestDone(status, getPtrSelf(), result);
800 void processRequest(RPCServiceAsync::shared_pointer
const & service,
801 PVStructurePtr
const & pvArgument);
803 virtual void request(PVStructurePtr
const & pvArgument);
804 virtual Channel::shared_pointer getChannel();
805 virtual void cancel() {}
806 virtual void lock() {}
807 virtual void unlock() {}
808 virtual void lastRequest() {}
810 shared_pointer getPtrSelf()
812 return shared_from_this();
815 ChannelRPCRequester::weak_pointer channelRPCRequester;
816 RPCServiceAsync::shared_pointer service;
820 ChannelRPCLocalPtr ChannelRPCLocal::create(
822 ChannelRPCRequester::shared_pointer
const & channelRPCRequester,
823 PVStructurePtr
const & pvRequest,
826 RPCServiceAsync::shared_pointer service = pvRecord->getService(pvRequest);
829 Status status(Status::STATUSTYPE_ERROR,
830 "ChannelRPC not supported");
835 if (!channelRPCRequester)
836 throw std::invalid_argument(
"channelRPCRequester == null");
839 ChannelRPCLocalPtr rpc(
840 new ChannelRPCLocal(channelLocal, channelRPCRequester, service, pvRecord)
842 channelRPCRequester->channelRPCConnect(Status::Ok, rpc);
843 if(pvRecord->getTraceLevel()>0)
845 cout <<
"ChannelRPCLocal::create";
846 cout <<
" recordName " << pvRecord->getRecordName() << endl;
851 ChannelRPCLocal::~ChannelRPCLocal()
856 std::tr1::shared_ptr<Channel> ChannelRPCLocal::getChannel()
863 void ChannelRPCLocal::processRequest(
864 RPCService::shared_pointer
const & service,
865 PVStructurePtr
const & pvArgument)
867 PVStructurePtr result;
868 Status status = Status::Ok;
872 result = service->request(pvArgument);
874 catch (RPCRequestException& rre)
876 status = Status(rre.getStatus(), rre.what());
879 catch (std::exception& ex)
881 status = Status(Status::STATUSTYPE_FATAL, ex.what());
887 status = Status(Status::STATUSTYPE_FATAL,
"Unexpected exception caught while calling RPCService.request(PVStructure).");
894 status = Status(Status::STATUSTYPE_FATAL,
"RPCService.request(PVStructure) returned null.");
896 ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
897 if(requester) requester->requestDone(status, getPtrSelf(), result);
900 void ChannelRPCLocal::processRequest(
901 RPCServiceAsync::shared_pointer
const & service,
902 PVStructurePtr
const & pvArgument)
906 service->request(pvArgument, getPtrSelf());
908 catch (std::exception& ex)
911 Status errorStatus(Status::STATUSTYPE_FATAL, ex.what());
912 ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
913 if(requester) requester->requestDone(errorStatus, getPtrSelf(), PVStructurePtr());
918 Status errorStatus(Status::STATUSTYPE_FATAL,
919 "Unexpected exception caught while calling RPCServiceAsync.request(PVStructure, RPCResponseCallback).");
920 ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
921 if(requester) requester->requestDone(errorStatus, shared_from_this(), PVStructurePtr());
928 void ChannelRPCLocal::request(PVStructurePtr
const & pvArgument)
931 if(pvr && pvr->getTraceLevel()>0) {
932 cout <<
"ChannelRPCLocal::request " << pvr->getRecordName() << endl;
934 RPCService::shared_pointer rpcService =
935 std::tr1::dynamic_pointer_cast<RPCService>(service);
938 processRequest(rpcService, pvArgument);
942 RPCServiceAsync::shared_pointer rpcServiceAsync =
943 std::tr1::dynamic_pointer_cast<RPCServiceAsync>(service);
946 processRequest(rpcServiceAsync, pvArgument);
954 class ChannelArrayLocal :
956 public std::tr1::enable_shared_from_this<ChannelArrayLocal>
959 POINTER_DEFINITIONS(ChannelArrayLocal);
960 virtual ~ChannelArrayLocal();
961 virtual void destroy() {}
962 static ChannelArrayLocalPtr create(
964 ChannelArrayRequester::shared_pointer
const & channelArrayRequester,
965 PVStructurePtr
const & pvRequest,
967 virtual void getArray(
size_t offset,
size_t count,
size_t stride);
968 virtual void putArray(
969 PVArrayPtr
const &putArray,
970 size_t offset,
size_t count,
size_t stride);
971 virtual void getLength();
972 virtual void setLength(
size_t length);
973 virtual std::tr1::shared_ptr<Channel> getChannel();
974 virtual void cancel(){}
976 virtual void unlock();
977 virtual void lastRequest() {}
979 shared_pointer getPtrSelf()
981 return shared_from_this();
985 ChannelArrayRequester::shared_pointer
const & channelArrayRequester,
986 PVArrayPtr
const &pvArray,
987 PVArrayPtr
const &pvCopy,
990 channelLocal(channelLocal),
991 channelArrayRequester(channelArrayRequester),
999 ChannelArrayRequester::weak_pointer channelArrayRequester;
1007 ChannelArrayLocalPtr ChannelArrayLocal::create(
1009 ChannelArrayRequester::shared_pointer
const & channelArrayRequester,
1010 PVStructurePtr
const & pvRequest,
1013 PVFieldPtrArray
const & pvFields = pvRequest->getPVFields();
1014 if(pvFields.size()!=1) {
1016 Status::STATUSTYPE_ERROR,
"invalid pvRequest");
1017 ChannelArrayLocalPtr channelArray;
1018 ArrayConstPtr array;
1019 channelArrayRequester->channelArrayConnect(status,channelArray,array);
1020 return channelArray;
1022 PVFieldPtr pvField = pvFields[0];
1023 string fieldName(
"");
1025 string name = pvField->getFieldName();
1026 if(fieldName.size()>0) fieldName +=
'.';
1028 PVStructurePtr pvs = static_pointer_cast<PVStructure>(pvField);
1029 PVFieldPtrArray
const & pvfs = pvs->getPVFields();
1030 if(pvfs.size()!=1)
break;
1033 size_t indfield = fieldName.find_first_of(
"field.");
1035 fieldName = fieldName.substr(6);
1037 pvField = pvRecord->getPVRecordStructure()->getPVStructure()->getSubField(fieldName);
1040 Status::STATUSTYPE_ERROR,fieldName +
" not found");
1041 ChannelArrayLocalPtr channelArray;
1042 ArrayConstPtr array;
1043 channelArrayRequester->channelArrayConnect(
1044 status,channelArray,array);
1045 return channelArray;
1047 if(pvField->getField()->getType()!=scalarArray
1048 && pvField->getField()->getType()!=structureArray
1049 && pvField->getField()->getType()!=unionArray)
1052 Status::STATUSTYPE_ERROR,fieldName +
" not array");
1053 ChannelArrayLocalPtr channelArray;
1054 ArrayConstPtr array;
1055 channelArrayRequester->channelArrayConnect(
1056 status,channelArray,array);
1057 return channelArray;
1059 PVArrayPtr pvArray = static_pointer_cast<PVArray>(pvField);
1061 if(pvField->getField()->getType()==scalarArray) {
1062 PVScalarArrayPtr xxx = static_pointer_cast<PVScalarArray>(pvField);
1063 pvCopy = getPVDataCreate()->createPVScalarArray(
1064 xxx->getScalarArray()->getElementType());
1065 }
else if(pvField->getField()->getType()==structureArray) {
1066 PVStructureArrayPtr xxx = static_pointer_cast<PVStructureArray>(pvField);
1067 pvCopy = getPVDataCreate()->createPVStructureArray(
1068 xxx->getStructureArray()->getStructure());
1070 PVUnionArrayPtr xxx = static_pointer_cast<PVUnionArray>(pvField);
1071 pvCopy = getPVDataCreate()->createPVUnionArray(
1072 xxx->getUnionArray()->getUnion());
1074 ChannelArrayLocalPtr array(
new ChannelArrayLocal(
1076 channelArrayRequester,
1080 if(pvRecord->getTraceLevel()>0)
1082 cout <<
"ChannelArrayLocal::create";
1083 cout <<
" recordName " << pvRecord->getRecordName() << endl;
1085 channelArrayRequester->channelArrayConnect(
1086 Status::Ok, array, pvCopy->getArray());
1090 ChannelArrayLocal::~ChannelArrayLocal()
1095 std::tr1::shared_ptr<Channel> ChannelArrayLocal::getChannel()
1101 void ChannelArrayLocal::lock()
1104 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1107 void ChannelArrayLocal::unlock()
1110 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1114 void ChannelArrayLocal::getArray(
size_t offset,
size_t count,
size_t stride)
1116 ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1117 if(!requester)
return;
1119 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1120 if(pvr->getTraceLevel()>1)
1122 cout <<
"ChannelArrayLocal::getArray" << endl;
1124 const char *exceptionMessage = NULL;
1127 epicsGuard <PVRecord> guard(*pvr);
1129 size_t length = pvArray->getLength();
1130 if(length<=0)
break;
1132 count = (length -offset + stride -1)/stride;
1133 if(count>0) ok =
true;
1136 size_t maxcount = (length -offset + stride -1)/stride;
1137 if(count>maxcount) count = maxcount;
1142 pvCopy->setLength(count);
1143 copy(pvArray,offset,stride,pvCopy,0,1,count);
1145 }
catch(std::exception& e) {
1146 exceptionMessage = e.what();
1148 Status status = Status::Ok;
1149 if(exceptionMessage!=NULL) {
1150 status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1152 requester->getArrayDone(status,getPtrSelf(),pvCopy);
1155 void ChannelArrayLocal::putArray(
1156 PVArrayPtr
const & pvArray,
size_t offset,
size_t count,
size_t stride)
1158 ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1159 if(!requester)
return;
1161 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1162 if(pvr->getTraceLevel()>1)
1164 cout <<
"ChannelArrayLocal::putArray" << endl;
1166 size_t newLength = offset + count*stride;
1167 if(newLength<pvArray->getLength()) pvArray->setLength(newLength);
1168 const char *exceptionMessage = NULL;
1170 epicsGuard <PVRecord> guard(*pvr);
1171 copy(pvArray,0,1,this->pvArray,offset,stride,count);
1172 }
catch(std::exception& e) {
1173 exceptionMessage = e.what();
1175 Status status = Status::Ok;
1176 if(exceptionMessage!=NULL) {
1177 status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1179 requester->putArrayDone(status,getPtrSelf());
1182 void ChannelArrayLocal::getLength()
1184 ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1185 if(!requester)
return;
1187 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1189 const char *exceptionMessage = NULL;
1191 epicsGuard <PVRecord> guard(*pvr);
1192 length = pvArray->getLength();
1193 }
catch(std::exception& e) {
1194 exceptionMessage = e.what();
1196 Status status = Status::Ok;
1197 if(exceptionMessage!=NULL) {
1198 status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1200 requester->getLengthDone(status,getPtrSelf(),length);
1203 void ChannelArrayLocal::setLength(
size_t length)
1205 ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1206 if(!requester)
return;
1208 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1209 if(pvr->getTraceLevel()>1)
1211 cout <<
"ChannelArrayLocal::setLength" << endl;
1215 epicsGuard <PVRecord> guard(*pvr);
1216 if(pvArray->getLength()!=length) pvArray->setLength(length);
1218 requester->setLengthDone(Status::Ok,getPtrSelf());
1219 }
catch(std::exception& e) {
1220 string exceptionMessage = e.what();
1221 Status status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1222 requester->setLengthDone(status,getPtrSelf());
1227 ChannelLocal::ChannelLocal(
1229 ChannelRequester::shared_pointer
const & requester,
1232 requester(requester),
1236 if(pvRecord->getTraceLevel()>0) {
1237 cout <<
"ChannelLocal::ChannelLocal()" 1238 <<
" recordName " << pvRecord->getRecordName()
1239 <<
" requester exists " << (requester ?
"true" :
"false")
1251 return provider.lock();
1256 if(pvRecord->getTraceLevel()>0) {
1257 cout <<
"ChannelLocal::detach() " 1258 <<
" recordName " << pvRecord->getRecordName()
1259 <<
" requester exists " << (requester ?
"true" :
"false")
1262 if(!requester)
return;
1263 requester->channelStateChange(shared_from_this(),Channel::DESTROYED);
1270 if(pvr && pvr->getTraceLevel()>0) {
1271 cout <<
"ChannelLocal::getRequesterName() " 1272 <<
" recordName " << pvr->getRecordName()
1273 <<
" requester exists " << (requester ?
"true" :
"false")
1277 if(!requester)
return string();
1278 return requester->getRequesterName();
1283 MessageType messageType)
1286 if(pvr && pvr->getTraceLevel()>1) {
1287 cout <<
"ChannelLocal::message() " 1288 <<
" recordName " << pvr->getRecordName()
1289 <<
" requester exists " << (requester ?
"true" :
"false")
1293 requester->message(message,messageType);
1296 string recordName(
"record deleted");
1297 if(pvr) recordName = pvr->getRecordName();
1299 <<
" message " << message
1300 <<
" messageType " << getMessageTypeName(messageType)
1306 return string(
"local");
1311 return Channel::CONNECTED;
1317 string name(
"record deleted");
1318 if(pvr) name = pvr->getRecordName();
1333 string const &subField)
1336 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1337 if(subField.size()<1) {
1338 StructureConstPtr structure =
1339 pvr->getPVRecordStructure()->getPVStructure()->getStructure();
1340 requester->getDone(Status::Ok,structure);
1343 PVFieldPtr pvField =
1344 pvr->getPVRecordStructure()->getPVStructure()->getSubField(subField);
1346 requester->getDone(Status::Ok,pvField->getField());
1349 Status status(Status::STATUSTYPE_ERROR,
1350 "client asked for illegal field");
1351 requester->getDone(status,FieldConstPtr());
1355 PVField::shared_pointer
const &pvField)
1357 throw std::logic_error(
"Not Implemented");
1361 ChannelProcessRequester::shared_pointer
const & channelProcessRequester,
1362 PVStructure::shared_pointer
const & pvRequest)
1365 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1366 if(pvr->getTraceLevel()>0) {
1367 cout <<
"ChannelLocal::createChannelProcess() " 1368 <<
" recordName " << pvr->getRecordName()
1369 <<
" requester exists " << (requester ?
"true" :
"false")
1372 ChannelProcessLocalPtr channelProcess =
1373 ChannelProcessLocal::create(
1375 channelProcessRequester,
1378 return channelProcess;
1382 ChannelGetRequester::shared_pointer
const &channelGetRequester,
1383 PVStructure::shared_pointer
const &pvRequest)
1386 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1387 if(pvr->getTraceLevel()>0) {
1388 cout <<
"ChannelLocal::createChannelGet() " 1389 <<
" recordName " << pvr->getRecordName()
1390 <<
" requester exists " << (requester ?
"true" :
"false")
1393 ChannelGetLocalPtr channelGet =
1394 ChannelGetLocal::create(
1396 channelGetRequester,
1403 ChannelPutRequester::shared_pointer
const &channelPutRequester,
1404 PVStructure::shared_pointer
const &pvRequest)
1407 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1408 if(pvr->getTraceLevel()>0) {
1409 cout <<
"ChannelLocal::createChannelPut() " 1410 <<
" recordName " << pvr->getRecordName()
1411 <<
" requester exists " << (requester ?
"true" :
"false")
1415 ChannelPutLocalPtr channelPut =
1416 ChannelPutLocal::create(
1418 channelPutRequester,
1425 ChannelPutGetRequester::shared_pointer
const &channelPutGetRequester,
1426 PVStructure::shared_pointer
const &pvRequest)
1429 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1430 if(pvr->getTraceLevel()>0) {
1431 cout <<
"ChannelLocal::createChannelPutGet() " 1432 <<
" recordName " << pvr->getRecordName()
1433 <<
" requester exists " << (requester ?
"true" :
"false")
1437 ChannelPutGetLocalPtr channelPutGet =
1438 ChannelPutGetLocal::create(
1440 channelPutGetRequester,
1443 return channelPutGet;
1447 ChannelRPCRequester::shared_pointer
const & channelRPCRequester,
1448 PVStructure::shared_pointer
const & pvRequest)
1451 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1452 if(pvr->getTraceLevel()>0) {
1453 cout <<
"ChannelLocal::createChannelRPC() " 1454 <<
" recordName " << pvr->getRecordName()
1455 <<
" requester exists " << (requester ?
"true" :
"false")
1459 ChannelRPCLocalPtr channelRPC =
1460 ChannelRPCLocal::create(
1462 channelRPCRequester,
1469 MonitorRequester::shared_pointer
const &monitorRequester,
1470 PVStructure::shared_pointer
const &pvRequest)
1473 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1474 if(pvr->getTraceLevel()>0) {
1475 cout <<
"ChannelLocal::createMonitor() " 1476 <<
" recordName " << pvr->getRecordName()
1477 <<
" requester exists " << (requester ?
"true" :
"false")
1489 ChannelArrayRequester::shared_pointer
const &channelArrayRequester,
1490 PVStructure::shared_pointer
const &pvRequest)
1493 if(!pvr)
throw std::logic_error(
"pvRecord is deleted");
1494 if(pvr->getTraceLevel()>0) {
1495 cout <<
"ChannelLocal::createChannelArray() " 1496 <<
" recordName " << pvr->getRecordName()
1497 <<
" requester exists " << (requester ?
"true" :
"false")
1500 ChannelArrayLocalPtr channelArray =
1501 ChannelArrayLocal::create(
1503 channelArrayRequester,
1506 return channelArray;
1516 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.