make compatible with pvDataCPP-md; channelArray implemented; can be part of v3IOC.
This commit is contained in:
14
src/Makefile
14
src/Makefile
@@ -7,6 +7,10 @@ LIBRARY_IOC += pvDatabase
|
||||
pvDatabase_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
pvDatabase_LIBS += Com pvData pvAccess
|
||||
|
||||
SRC_DIRS += $(DATABASE)/pvData
|
||||
INC += pvSubArrayCopy.h
|
||||
LIBSRCS += pvSubArrayCopy.cpp
|
||||
|
||||
SRC_DIRS += $(DATABASE)/database
|
||||
INC += pvDatabase.h
|
||||
LIBSRCS += pvRecord.cpp
|
||||
@@ -17,10 +21,14 @@ INC += channelProviderLocal.h
|
||||
INC += pvCopy.h
|
||||
INC += monitorAlgorithm.h
|
||||
LIBSRCS += channelProviderLocal.cpp
|
||||
LIBSRCS += channelLocal.cpp
|
||||
LIBSRCS += pvCopy.cpp
|
||||
LIBSRCS += channelLocal.cpp
|
||||
LIBSRCS += monitorFactory.cpp
|
||||
|
||||
SRC_DIRS += $(DATABASE)/v3IOC
|
||||
DBD += PVAServerRegister.dbd
|
||||
LIBSRCS += PVAServerRegister.cpp
|
||||
|
||||
SRC_DIRS += $(DATABASE)/special
|
||||
INC += recordList.h
|
||||
INC += traceRecord.h
|
||||
@@ -28,9 +36,5 @@ INC += powerSupplyRecordTest.h
|
||||
LIBSRCS += recordList.cpp
|
||||
LIBSRCS += traceRecord.cpp
|
||||
|
||||
SRC_DIRS += $(DATABASE)/example
|
||||
INC += exampleCounter.h
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @data 2012.11.21
|
||||
* @date 2012.11.21
|
||||
*/
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
@@ -85,13 +85,13 @@ PVStringArrayPtr PVDatabase::getRecordNames()
|
||||
PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray>
|
||||
(getPVDataCreate()->createPVScalarArray(pvString));
|
||||
size_t len = recordMap.size();
|
||||
std::vector<String> names(len);
|
||||
shared_vector<String> names(len);
|
||||
PVRecordMap::iterator iter;
|
||||
size_t i = 0;
|
||||
for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) {
|
||||
names[i++] = (*iter).first;
|
||||
}
|
||||
pvStringArray->put(0,len,names,0);
|
||||
pvStringArray->replace(names);
|
||||
return pvStringArray;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @data 2012.11.21
|
||||
* @date 2012.11.21
|
||||
*/
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/* exampleCounter.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.04.02
|
||||
*/
|
||||
#ifndef EXAMPLECOUNTER_H
|
||||
#define EXAMPLECOUNTER_H
|
||||
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
class ExampleCounter;
|
||||
typedef std::tr1::shared_ptr<ExampleCounter> ExampleCounterPtr;
|
||||
|
||||
class ExampleCounter :
|
||||
public PVRecord
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ExampleCounter);
|
||||
static ExampleCounterPtr create(
|
||||
epics::pvData::String const & recordName);
|
||||
virtual ~ExampleCounter();
|
||||
virtual void destroy();
|
||||
virtual bool init();
|
||||
virtual void process();
|
||||
private:
|
||||
ExampleCounter(epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVLongPtr pvValue;
|
||||
epics::pvData::PVTimeStamp pvTimeStamp;
|
||||
epics::pvData::TimeStamp timeStamp;
|
||||
};
|
||||
|
||||
ExampleCounterPtr ExampleCounter::create(
|
||||
epics::pvData::String const & recordName)
|
||||
{
|
||||
epics::pvData::PVStructurePtr pvStructure =
|
||||
epics::pvData::getStandardPVField()->scalar(epics::pvData::pvLong,"timeStamp,alarm");
|
||||
ExampleCounterPtr pvRecord(
|
||||
new ExampleCounter(recordName,pvStructure));
|
||||
if(!pvRecord->init()) pvRecord.reset();
|
||||
return pvRecord;
|
||||
}
|
||||
|
||||
ExampleCounter::ExampleCounter(
|
||||
epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure)
|
||||
: PVRecord(recordName,pvStructure)
|
||||
{
|
||||
pvTimeStamp.attach(pvStructure->getSubField("timeStamp"));
|
||||
}
|
||||
|
||||
ExampleCounter::~ExampleCounter()
|
||||
{
|
||||
}
|
||||
|
||||
void ExampleCounter::destroy()
|
||||
{
|
||||
PVRecord::destroy();
|
||||
}
|
||||
|
||||
bool ExampleCounter::init()
|
||||
{
|
||||
|
||||
initPVRecord();
|
||||
epics::pvData::PVFieldPtr pvField;
|
||||
pvValue = getPVStructure()->getLongField("value");
|
||||
if(pvValue.get()==NULL) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExampleCounter::process()
|
||||
{
|
||||
pvValue->put(pvValue->get() + 1.0);
|
||||
timeStamp.getCurrent();
|
||||
pvTimeStamp.set(timeStamp);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif /* EXAMPLECOUNTER_H */
|
||||
@@ -15,11 +15,13 @@
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/pvSubArrayCopy.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
@@ -759,6 +761,8 @@ void ChannelPutGetLocal::getGet()
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
|
||||
|
||||
class ChannelArrayLocal :
|
||||
public ChannelArray,
|
||||
public std::tr1::enable_shared_from_this<ChannelArrayLocal>
|
||||
@@ -791,8 +795,8 @@ private:
|
||||
ChannelArrayLocal(
|
||||
ChannelLocalPtr const &channelLocal,
|
||||
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
|
||||
PVScalarArrayPtr const &pvArray,
|
||||
PVScalarArrayPtr const &pvCopy,
|
||||
PVArrayPtr const &pvArray,
|
||||
PVArrayPtr const &pvCopy,
|
||||
PVRecordPtr const &pvRecord)
|
||||
:
|
||||
isDestroyed(false),
|
||||
@@ -810,13 +814,14 @@ private:
|
||||
bool callProcess;
|
||||
ChannelLocalPtr channelLocal;
|
||||
ChannelArrayRequester::shared_pointer channelArrayRequester,;
|
||||
PVScalarArrayPtr pvArray;
|
||||
PVScalarArrayPtr pvCopy;
|
||||
PVArrayPtr pvArray;
|
||||
PVArrayPtr pvCopy;
|
||||
PVRecordPtr pvRecord;
|
||||
Mutex mutex;
|
||||
Lock thelock;
|
||||
};
|
||||
|
||||
|
||||
ChannelArrayLocalPtr ChannelArrayLocal::create(
|
||||
ChannelLocalPtr const &channelLocal,
|
||||
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
|
||||
@@ -852,18 +857,26 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
|
||||
channelArrayRequester->channelArrayConnect(status,channelArray,pvArray);
|
||||
return channelArray;
|
||||
}
|
||||
if(pvField->getField()->getType()!=scalarArray)
|
||||
if(pvField->getField()->getType()!=scalarArray && pvField->getField()->getType()!=structureArray)
|
||||
{
|
||||
Status status(
|
||||
Status::Status::STATUSTYPE_ERROR,fieldName +" not scalarArray");
|
||||
Status::Status::STATUSTYPE_ERROR,fieldName +" not array");
|
||||
ChannelArrayLocalPtr channelArray;
|
||||
PVScalarArrayPtr pvArray;
|
||||
PVArrayPtr pvArray;
|
||||
channelArrayRequester->channelArrayConnect(status,channelArray,pvArray);
|
||||
return channelArray;
|
||||
}
|
||||
PVScalarArrayPtr pvArray = static_pointer_cast<PVScalarArray>(pvField);
|
||||
PVScalarArrayPtr pvCopy = getPVDataCreate()->createPVScalarArray(
|
||||
pvArray->getScalarArray()->getElementType());
|
||||
PVArrayPtr pvArray = static_pointer_cast<PVArray>(pvField);
|
||||
PVArrayPtr pvCopy;
|
||||
if(pvField->getField()->getType()==scalarArray) {
|
||||
PVScalarArrayPtr xxx = static_pointer_cast<PVScalarArray>(pvField);
|
||||
pvCopy = getPVDataCreate()->createPVScalarArray(
|
||||
xxx->getScalarArray()->getElementType());
|
||||
} else {
|
||||
PVStructureArrayPtr xxx = static_pointer_cast<PVStructureArray>(pvField);
|
||||
pvCopy = getPVDataCreate()->createPVStructureArray(
|
||||
xxx->getStructureArray());
|
||||
}
|
||||
|
||||
ChannelArrayLocalPtr array(new ChannelArrayLocal(
|
||||
channelLocal,
|
||||
@@ -913,8 +926,13 @@ void ChannelArrayLocal::getArray(bool lastRequest,int offset, int count)
|
||||
}
|
||||
pvRecord->lock();
|
||||
try {
|
||||
size_t len = getConvert()->copyScalarArray(pvArray,offset,pvCopy,0,count);
|
||||
if(!pvCopy->isImmutable()) pvCopy->setLength(len);
|
||||
if(count<0) count = pvArray->getLength();
|
||||
size_t capacity = pvArray->getCapacity();
|
||||
if(capacity!=0) {
|
||||
pvCopy->setCapacity(capacity);
|
||||
pvCopy->setLength(count);
|
||||
copy(*pvArray.get(),offset,*pvCopy.get(),0,count);
|
||||
}
|
||||
} catch(...) {
|
||||
pvRecord->unlock();
|
||||
throw;
|
||||
@@ -937,10 +955,12 @@ void ChannelArrayLocal::putArray(bool lastRequest,int offset, int count)
|
||||
{
|
||||
cout << "ChannelArrayLocal::putArray" << endl;
|
||||
}
|
||||
if(count<=0) count = pvCopy->getLength();
|
||||
pvRecord->lock();
|
||||
try {
|
||||
getConvert()->copyScalarArray(pvCopy,0,pvArray,offset,count);
|
||||
if(count<=0) count = pvCopy->getLength();
|
||||
if(pvArray->getCapacity()<count) pvArray->setCapacity(count);
|
||||
if(pvArray->getLength()<count) pvArray->setLength(count);
|
||||
copy(*pvCopy.get(),0,*pvArray.get(),offset,count);
|
||||
} catch(...) {
|
||||
pvRecord->unlock();
|
||||
throw;
|
||||
@@ -964,21 +984,22 @@ void ChannelArrayLocal::setLength(bool lastRequest,int length, int capacity)
|
||||
{
|
||||
cout << "ChannelArrayLocal::setLength" << endl;
|
||||
}
|
||||
if(capacity>=0 && !pvArray->isCapacityMutable()) {
|
||||
Status status(
|
||||
Status::Status::STATUSTYPE_ERROR,
|
||||
"capacityImnutable");
|
||||
channelArrayRequester->setLengthDone(status);
|
||||
return;
|
||||
}
|
||||
pvRecord->lock();
|
||||
try {
|
||||
if(length>0) {
|
||||
if(pvArray->getLength()!=length) pvArray->setLength(length);
|
||||
if(capacity>=0 && !pvArray->isCapacityMutable()) {
|
||||
Status status(
|
||||
Status::Status::STATUSTYPE_ERROR,
|
||||
"capacityImnutable");
|
||||
channelArrayRequester->setLengthDone(status);
|
||||
pvRecord->unlock();
|
||||
return;
|
||||
}
|
||||
if(capacity>0) {
|
||||
if(pvArray->getCapacity()!=capacity) pvArray->setCapacity(capacity);
|
||||
}
|
||||
if(length>0) {
|
||||
if(pvArray->getLength()!=length) pvArray->setLength(length);
|
||||
}
|
||||
} catch(...) {
|
||||
pvRecord->unlock();
|
||||
throw;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
/**
|
||||
* @author Marty Kraimer
|
||||
* @data 2013.04
|
||||
* @date 2013.04
|
||||
*/
|
||||
#ifndef CHANNELPROVIDERLOCAL_H
|
||||
#define CHANNELPROVIDERLOCAL_H
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
/**
|
||||
* @author Marty Kraimer
|
||||
* @data 2013.04
|
||||
* @date 2013.04
|
||||
*/
|
||||
#ifndef MONITORALGORITHM_H
|
||||
#define MONITORALGORITHM_H
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace epics { namespace pvDatabase {
|
||||
|
||||
using namespace epics::pvData;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::size_t;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
@@ -35,13 +36,11 @@ struct CopyNode {
|
||||
CopyNode()
|
||||
: isStructure(false),
|
||||
structureOffset(0),
|
||||
nfields(0),
|
||||
shareData(false)
|
||||
nfields(0)
|
||||
{}
|
||||
bool isStructure;
|
||||
size_t structureOffset; // In the copy
|
||||
size_t nfields;
|
||||
bool shareData;
|
||||
PVStructurePtr options;
|
||||
};
|
||||
|
||||
@@ -734,23 +733,7 @@ void PVCopy::referenceImmutable(
|
||||
CopyRecordNodePtr recordNode =
|
||||
static_pointer_cast<CopyRecordNode>(node);
|
||||
PVRecordFieldPtr recordPVField = recordNode->recordPVField;
|
||||
bool shareData = false;
|
||||
if(node->options.get()!=NULL) {
|
||||
PVFieldPtr pv = node->options->getSubField("_options");
|
||||
if(pv.get()!=NULL) {
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pv);
|
||||
pv = xxx->getSubField("shareData");
|
||||
if(pv.get()!=NULL) {
|
||||
PVStringPtr yyy = xxx->getStringField("shareData");
|
||||
shareData = (yyy->get().compare("true")==0) ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(shareData) {
|
||||
makeShared(pvField,recordNode->recordPVField);
|
||||
} else {
|
||||
referenceImmutable(pvField,recordPVField);
|
||||
}
|
||||
referenceImmutable(pvField,recordPVField);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,13 +763,6 @@ void PVCopy::referenceImmutable(
|
||||
}
|
||||
}
|
||||
|
||||
void PVCopy::makeShared(
|
||||
PVFieldPtr const ©PVField,
|
||||
PVRecordFieldPtr const &recordPVField)
|
||||
{
|
||||
throw std::logic_error(String("Not Implemented"));
|
||||
}
|
||||
|
||||
void PVCopy::updateStructureNodeSetBitSet(
|
||||
PVStructurePtr const &pvCopy,
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
@@ -803,24 +779,7 @@ void PVCopy::updateStructureNodeSetBitSet(
|
||||
} else {
|
||||
CopyRecordNodePtr recordNode =
|
||||
static_pointer_cast<CopyRecordNode>(node);
|
||||
bool shareData = false;
|
||||
if(node->options.get()!=NULL) {
|
||||
PVFieldPtr pv = node->options->getSubField("_options");
|
||||
if(pv.get()!=NULL) {
|
||||
PVStructurePtr xxx =
|
||||
static_pointer_cast<PVStructure>(pv);
|
||||
pv = xxx->getSubField("shareData");
|
||||
if(pv.get()!=NULL) {
|
||||
PVStringPtr yyy = xxx->getStringField("shareData");
|
||||
shareData = (yyy->get().compare("true")==0) ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(shareData) {
|
||||
bitSet->set(pvField->getFieldOffset());
|
||||
} else {
|
||||
updateSubFieldSetBitSet(pvField,recordNode->recordPVField,bitSet);
|
||||
}
|
||||
updateSubFieldSetBitSet(pvField,recordNode->recordPVField,bitSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,6 @@ class PVCopyMonitor;
|
||||
typedef std::tr1::shared_ptr<PVCopyMonitor> PVCopyMonitorPtr;
|
||||
class PVCopyMonitorRequester;
|
||||
typedef std::tr1::shared_ptr<PVCopyMonitorRequester> PVCopyMonitorRequesterPtr;
|
||||
class SharePVScalarArray;
|
||||
typedef std::tr1::shared_ptr<SharePVScalarArray> SharePVScalarArrayPtr;
|
||||
class SharePVStructureArray;
|
||||
typedef std::tr1::shared_ptr<SharePVStructureArray> SharePVStructureArrayPtr;
|
||||
|
||||
struct CopyNode;
|
||||
typedef std::tr1::shared_ptr<CopyNode> CopyNodePtr;
|
||||
@@ -125,9 +121,6 @@ private:
|
||||
void referenceImmutable(
|
||||
epics::pvData::PVFieldPtr const ©PVField,
|
||||
PVRecordFieldPtr const &recordPVField);
|
||||
void makeShared(
|
||||
epics::pvData::PVFieldPtr const ©PVField,
|
||||
PVRecordFieldPtr const &recordPVField);
|
||||
void updateStructureNodeSetBitSet(
|
||||
epics::pvData::PVStructurePtr const &pvCopy,
|
||||
CopyStructureNodePtr const &structureNode,
|
||||
@@ -217,113 +210,6 @@ public:
|
||||
virtual void unlisten() = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef MUSTIMPLEMENT
|
||||
template<typename T>
|
||||
class SharePVScalarArray :
|
||||
public epics::pvData::PVScalarArray
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(SharePVScalarArray)
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef epics::pvData::PVArrayData<T> ArrayDataType;
|
||||
|
||||
SharePVScalarArray(
|
||||
PVRecordFieldPtr const &pvRecordField,
|
||||
epics::pvData::PVStructurePtr const &parent,
|
||||
epics::pvData::PVScalarArrayPtr const &pvShare);
|
||||
virtual ~SharePVScalarArray();
|
||||
void lockShare() const;
|
||||
void unlockShare() const;
|
||||
virtual void message(
|
||||
epics::pvData::String const & message,
|
||||
epics::pvData::MessageType messageType);
|
||||
virtual void setImmutable();
|
||||
bool isImmutable();
|
||||
virtual void setCapacity(std::size_t capacity);
|
||||
void setLength(std::size_t length);
|
||||
std::size_t getCapacity() const;
|
||||
std::size_t getLength() const;
|
||||
bool isCapacityMutable();
|
||||
void setCapacityMutable(bool isMutable);
|
||||
virtual std::size_t get(std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
|
||||
virtual std::size_t put(std::size_t offset,std::size_t length, pointer from, std::size_t fromOffset) = 0;
|
||||
virtual void shareData(pointer value,std::size_t capacity,std::size_t length) = 0;
|
||||
virtual bool equals(epics::pvData::PVFieldPtr const &pv);
|
||||
virtual void serialize(
|
||||
epics::pvData::ByteBufferPtr *pbuffer,
|
||||
epics::pvData::SerializableControl *pflusher) const;
|
||||
virtual void deserialize(
|
||||
epics::pvData::ByteBuffer *pbuffer,
|
||||
epics::pvData::DeserializableControl *pflusher);
|
||||
virtual void serialize(
|
||||
epics::pvData::ByteBuffer *pbuffer,
|
||||
epics::pvData::SerializableControl *pflusher, std::size_t offset, std::size_t count) const;
|
||||
private:
|
||||
PVRecordField &pvRecordField;
|
||||
};
|
||||
|
||||
typedef SharePVScalarArray<bool> SharePVBooleanArray;
|
||||
typedef SharePVScalarArray<epics::pvData::int8> SharePVByteArray;
|
||||
typedef SharePVScalarArray<epics::pvData::int16> SharePVShortArray;
|
||||
typedef SharePVScalarArray<epics::pvData::int32> SharePVIntArray;
|
||||
typedef SharePVScalarArray<epics::pvData::int64> SharePVLongArray;
|
||||
typedef SharePVScalarArray<float> SharePVFloatArray;
|
||||
typedef SharePVScalarArray<double> SharePVDoubleArray;
|
||||
typedef SharePVScalarArray<epics::pvData::String> SharePVStringArray;
|
||||
|
||||
|
||||
class SharePVStructureArray :
|
||||
public epics::pvData::PVStructureArray
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(SharePVStructureArray)
|
||||
SharePVStructureArray(
|
||||
PVRecordFieldPtr const &pvRecordField,
|
||||
epics::pvData::PVStructurePtr const &parent,
|
||||
epics::pvData::PVStructureArrayPtr const &pvShare);
|
||||
virtual ~SharePVStructureArray();
|
||||
virtual epics::pvData::StructureArrayConstPtr getStructureArray();
|
||||
void lockShare() const;
|
||||
void unlockShare() const;
|
||||
virtual void message(
|
||||
epics::pvData::String const &message,
|
||||
epics::pvData::MessageType messageType);
|
||||
virtual void setImmutable();
|
||||
bool isImmutable();
|
||||
virtual void setCapacity(std::size_t capacity);
|
||||
void setLength(std::size_t length);
|
||||
std::size_t getCapacity() const;
|
||||
std::size_t getLength() const;
|
||||
bool isCapacityMutable();
|
||||
void setCapacityMutable(bool isMutable);
|
||||
virtual void shareData(
|
||||
epics::pvData::PVStructurePtrArrayPtr const & value,
|
||||
std::size_t capacity,std::size_t length);
|
||||
virtual std::size_t get(std::size_t offset, std::size_t length,
|
||||
epics::pvData::StructureArrayData &data);
|
||||
virtual std::size_t put(std::size_t offset,std::size_t length,
|
||||
epics::pvData::PVStructurePtrArrayPtr const & from,
|
||||
std::size_t fromOffset);
|
||||
virtual bool equals(epics::pvData::PVField & &pv);
|
||||
virtual void serialize(
|
||||
epics::pvData::ByteBuffer *pbuffer,
|
||||
epics::pvData::SerializableControl *pflusher) const;
|
||||
virtual void deserialize(
|
||||
epics::pvData::ByteBuffer *pbuffer,
|
||||
epics::pvData::DeserializableControl *pflusher);
|
||||
virtual void serialize(
|
||||
epics::pvData::ByteBuffer *pbuffer,
|
||||
epics::pvData::SerializableControl *pflusher,
|
||||
std::size_t offset, std::size_t count) const;
|
||||
private:
|
||||
PVRecordField &pvRecordField;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif /* PVCOPY_H */
|
||||
|
||||
201
src/pvData/pvSubArrayCopy.cpp
Normal file
201
src/pvData/pvSubArrayCopy.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author Marty Kraimer
|
||||
* @date 2013.07
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
|
||||
#include <pv/pvSubArrayCopy.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
template<typename T>
|
||||
void copy(
|
||||
PVValueArray<T> & pvFrom,
|
||||
size_t fromOffset,
|
||||
PVValueArray<T> & pvTo,
|
||||
size_t toOffset,
|
||||
size_t len)
|
||||
{
|
||||
if(pvTo.isImmutable()) {
|
||||
throw std::logic_error("pvSubArrayCopy to is immutable");
|
||||
}
|
||||
size_t fromLength = pvFrom.getLength();
|
||||
if(fromOffset+len>fromLength) {
|
||||
throw std::length_error("pvSubArrayCopy from length error");
|
||||
}
|
||||
size_t capacity = pvTo.getCapacity();
|
||||
if(toOffset+len>capacity) pvTo.setCapacity(toOffset+len);
|
||||
typename PVValueArray<T>::const_svector vecFrom = pvFrom.view();
|
||||
typename PVValueArray<T>::const_svector vecTo = pvTo.view();
|
||||
shared_vector<T> temp;
|
||||
pvTo.swap(temp);
|
||||
for(size_t i=0; i<len; ++i) temp[i + toOffset] = vecFrom[i + fromOffset];
|
||||
pvTo.replace(temp);
|
||||
}
|
||||
|
||||
void copy(
|
||||
PVScalarArray & from,
|
||||
size_t fromOffset,
|
||||
PVScalarArray & to,
|
||||
size_t toOffset,
|
||||
size_t len)
|
||||
{
|
||||
ScalarType scalarType = from.getScalarArray()->getElementType();
|
||||
ScalarType otherType = to.getScalarArray()->getElementType();
|
||||
if(scalarType!=otherType) {
|
||||
throw std::invalid_argument("pvSubArrayCopy element types do not match");
|
||||
}
|
||||
switch(scalarType)
|
||||
{
|
||||
case pvBoolean:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<boolean> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<boolean>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvByte:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<int8> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<int8>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvShort:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<int16> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<int16>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvInt:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<int32> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<int32>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvLong:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<int64> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<int64>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvUByte:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<uint8> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<uint8>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvUShort:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<uint16> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<uint16>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvUInt:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<uint32> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<uint32>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvULong:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<uint64> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<uint64>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvFloat:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<float> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<float>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvDouble:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<double> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<double>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
case pvString:
|
||||
{
|
||||
copy(dynamic_cast<PVValueArray<String> &>(from),fromOffset,
|
||||
dynamic_cast<PVValueArray<String>& >(to),
|
||||
toOffset,len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void copy(
|
||||
PVStructureArray & from,
|
||||
size_t fromOffset,
|
||||
PVStructureArray & to,
|
||||
size_t toOffset,
|
||||
size_t len)
|
||||
{
|
||||
if(to.isImmutable()) {
|
||||
throw std::logic_error("pvSubArrayCopy to is immutable");
|
||||
}
|
||||
StructureArrayConstPtr fromStructure = from.getStructureArray();
|
||||
StructureArrayConstPtr toStructure = to.getStructureArray();
|
||||
if(fromStructure!=toStructure) {
|
||||
throw std::invalid_argument(
|
||||
"pvSubArrayCopy structureArray to and from have different structures");
|
||||
}
|
||||
size_t fromLength = from.getLength();
|
||||
if(fromOffset+len>fromLength) {
|
||||
throw std::length_error("pvSubArrayCopy from length error");
|
||||
}
|
||||
size_t capacity = to.getCapacity();
|
||||
if(toOffset+len>capacity) to.setCapacity(toOffset+len);
|
||||
typename PVValueArray<PVStructurePtr>::const_svector vecFrom = from.view();
|
||||
typename PVValueArray<PVStructurePtr>::const_svector vecTo = to.view();
|
||||
shared_vector<PVStructurePtr> temp;
|
||||
to.swap(temp);
|
||||
for(size_t i=0; i<len; ++i) {
|
||||
temp[i + toOffset] = vecFrom[i + fromOffset];
|
||||
}
|
||||
to.replace(temp);
|
||||
}
|
||||
|
||||
void copy(
|
||||
PVArray & from,
|
||||
size_t fromOffset,
|
||||
PVArray & to,
|
||||
size_t toOffset,
|
||||
size_t len)
|
||||
{
|
||||
Type type = from.getField()->getType();
|
||||
Type otherType = to.getField()->getType();
|
||||
if(type!=otherType) {
|
||||
throw std::invalid_argument("pvSubArrayCopy types do not match");
|
||||
}
|
||||
if(type==scalarArray) {
|
||||
copy(dynamic_cast<PVScalarArray &>(from) ,fromOffset,
|
||||
dynamic_cast<PVScalarArray&>(to),
|
||||
toOffset,len);
|
||||
}
|
||||
if(type==structureArray) {
|
||||
copy(dynamic_cast<PVStructureArray &>(from) ,fromOffset,
|
||||
dynamic_cast<PVStructureArray&>(to),
|
||||
toOffset,len);
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
83
src/pvData/pvSubArrayCopy.h
Normal file
83
src/pvData/pvSubArrayCopy.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* pvSubArrayCopy.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author Marty Kraimer
|
||||
* @date 2013.07
|
||||
*/
|
||||
#ifndef PVSUBARRAYCOPY_H
|
||||
#define PVSUBARRAYCOPY_H
|
||||
#include <pv/pvData.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
/** @brief Copy a subarray from one PVValueArray to another.
|
||||
* @warning The two PVValueArrays must both the same type
|
||||
* @param from The source
|
||||
* @param fromOffset The offset in the source
|
||||
* @param to The destination
|
||||
* @param toOffset The offset in the destination
|
||||
* @param len The total number of elements to copy
|
||||
*/
|
||||
template<typename T>
|
||||
void copy(
|
||||
PVValueArray<T> & pvFrom,
|
||||
size_t fromOffset,
|
||||
PVValueArray<T> & pvTo,
|
||||
size_t toOffset,
|
||||
size_t len);
|
||||
|
||||
/** @brief Copy a subarray from one scalar array to another.
|
||||
* @warning The two scalar arrays must both be PVValueArrays of the same type
|
||||
* @param from The source
|
||||
* @param fromOffset The offset in the source
|
||||
* @param to The destination
|
||||
* @param toOffset The offset in the destination
|
||||
* @param len The total number of elements to copy
|
||||
*/
|
||||
void copy(
|
||||
PVScalarArray & from,
|
||||
size_t fromOffset,
|
||||
PVScalarArray & to,
|
||||
size_t toOffset,
|
||||
size_t len);
|
||||
|
||||
/** @brief Copy a subarray from one structure array to another.
|
||||
* @warning The two structure arrays must have the same
|
||||
* structure introspection interface.
|
||||
* @param from The source
|
||||
* @param fromOffset The offset in the source
|
||||
* @param to The destination
|
||||
* @param toOffset The offset in the destination
|
||||
* @param len The total number of elements to copy
|
||||
*/
|
||||
void copy(
|
||||
PVStructureArray & from,
|
||||
size_t fromOffset,
|
||||
PVStructureArray & to,
|
||||
size_t toOffset,
|
||||
size_t len);
|
||||
|
||||
/** @brief Copy a subarray from one array to another.
|
||||
* @warning The two arrays must have the same
|
||||
* introspection interface.
|
||||
* @param from The source
|
||||
* @param fromOffset The offset in the source
|
||||
* @param to The destination
|
||||
* @param toOffset The offset in the destination
|
||||
* @param len The total number of elements to copy
|
||||
*/
|
||||
void copy(
|
||||
PVArray & from,
|
||||
size_t fromOffset,
|
||||
PVArray & to,
|
||||
size_t toOffset,
|
||||
size_t len);
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif /* PVSUBARRAYCOPY_H */
|
||||
@@ -90,9 +90,7 @@ bool RecordListRecord::init()
|
||||
void RecordListRecord::process()
|
||||
{
|
||||
PVStringArrayPtr pvNames = PVDatabase::getMaster()->getRecordNames();
|
||||
std::vector<String> const & xxx = pvNames->getVector();
|
||||
size_t n = xxx.size();
|
||||
names->put(0,n,xxx,0);
|
||||
names->replace(pvNames->view());
|
||||
String message("");
|
||||
if(database->get().compare("master")!=0) {
|
||||
message += " can only access master ";
|
||||
|
||||
155
src/v3IOC/PVAServerRegister.cpp
Normal file
155
src/v3IOC/PVAServerRegister.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
/*PVAServerRegister.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.07.24
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <cantProceed.h>
|
||||
#include <epicsStdio.h>
|
||||
#include <epicsMutex.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsThread.h>
|
||||
#include <iocsh.h>
|
||||
|
||||
#include <epicsExport.h>
|
||||
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/channelProviderLocal.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
class PVAServerCTX;
|
||||
typedef std::tr1::shared_ptr<PVAServerCTX> PVAServerCTXPtr;
|
||||
|
||||
class PVAServerCTX :
|
||||
public std::tr1::enable_shared_from_this<PVAServerCTX>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVAServerCTX);
|
||||
static PVAServerCTXPtr getPVAServerCTX();
|
||||
void start();
|
||||
void stop();
|
||||
virtual ~PVAServerCTX() {}
|
||||
private:
|
||||
PVAServerCTX() {}
|
||||
shared_pointer getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
ServerContext::shared_pointer ctx;
|
||||
};
|
||||
|
||||
void PVAServerCTX::start()
|
||||
{
|
||||
if(ctx!=NULL) {
|
||||
cout<< "PVAServer already started" << endl;
|
||||
return;
|
||||
}
|
||||
ctx = startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
|
||||
}
|
||||
|
||||
void PVAServerCTX::stop()
|
||||
{
|
||||
if(ctx==NULL) {
|
||||
cout<< "PVAServer already stopped" << endl;
|
||||
return;
|
||||
}
|
||||
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
|
||||
ctx->destroy();
|
||||
ctx.reset();
|
||||
epicsThreadSleep(1.0);
|
||||
channelProvider->destroy();
|
||||
}
|
||||
|
||||
PVAServerCTXPtr PVAServerCTX::getPVAServerCTX()
|
||||
{
|
||||
static PVAServerCTXPtr pvPVAServerCTX;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
|
||||
if(pvPVAServerCTX==NULL) {
|
||||
pvPVAServerCTX = PVAServerCTXPtr(new PVAServerCTX());
|
||||
}
|
||||
return pvPVAServerCTX;
|
||||
}
|
||||
|
||||
|
||||
static const iocshFuncDef startPVAServerFuncDef = {
|
||||
"startPVAServer", 0, 0
|
||||
};
|
||||
extern "C" void startPVAServer(const iocshArgBuf *args)
|
||||
{
|
||||
PVAServerCTX::getPVAServerCTX()->start();
|
||||
}
|
||||
|
||||
static const iocshFuncDef stopPVAServerFuncDef = {
|
||||
"stopPVAServer", 0, 0
|
||||
};
|
||||
extern "C" void stopPVAServer(const iocshArgBuf *args)
|
||||
{
|
||||
PVAServerCTX::getPVAServerCTX()->stop();
|
||||
}
|
||||
|
||||
|
||||
static const iocshFuncDef pvdblFuncDef = {
|
||||
"pvdbl", 0, 0
|
||||
};
|
||||
extern "C" void pvdbl(const iocshArgBuf *args)
|
||||
{
|
||||
PVDatabasePtr master = PVDatabase::getMaster();
|
||||
PVStringArrayPtr pvNames = master->getRecordNames();
|
||||
PVStringArray::const_svector xxx = pvNames->view();
|
||||
for(size_t i=0; i<xxx.size(); ++i) cout<< xxx[i] << endl;
|
||||
}
|
||||
|
||||
static void startPVAServerRegister(void)
|
||||
{
|
||||
static int firstTime = 1;
|
||||
if (firstTime) {
|
||||
firstTime = 0;
|
||||
iocshRegister(&startPVAServerFuncDef, startPVAServer);
|
||||
}
|
||||
}
|
||||
|
||||
static void stopPVAServerRegister(void)
|
||||
{
|
||||
static int firstTime = 1;
|
||||
if (firstTime) {
|
||||
firstTime = 0;
|
||||
iocshRegister(&stopPVAServerFuncDef, stopPVAServer);
|
||||
}
|
||||
}
|
||||
|
||||
static void pvdblRegister(void)
|
||||
{
|
||||
static int firstTime = 1;
|
||||
if (firstTime) {
|
||||
firstTime = 0;
|
||||
iocshRegister(&pvdblFuncDef, pvdbl);
|
||||
getChannelProviderLocal();
|
||||
}
|
||||
}
|
||||
|
||||
epicsExportRegistrar(startPVAServerRegister);
|
||||
epicsExportRegistrar(stopPVAServerRegister);
|
||||
epicsExportRegistrar(pvdblRegister);
|
||||
3
src/v3IOC/PVAServerRegister.dbd
Normal file
3
src/v3IOC/PVAServerRegister.dbd
Normal file
@@ -0,0 +1,3 @@
|
||||
registrar("startPVAServerRegister")
|
||||
registrar("stopPVAServerRegister")
|
||||
registrar("pvdblRegister")
|
||||
Reference in New Issue
Block a user