make compatible with pvDataCPP-md; channelArray implemented; can be part of v3IOC.

This commit is contained in:
Marty Kraimer
2013-07-25 10:27:17 -04:00
parent 255f58aeb8
commit e40fe7b0ac
57 changed files with 2595 additions and 318 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -6,7 +6,7 @@
*/
/**
* @author mrk
* @data 2012.11.21
* @date 2012.11.21
*/
#include <pv/pvDatabase.h>

View File

@@ -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 */

View File

@@ -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;

View File

@@ -6,7 +6,7 @@
*/
/**
* @author Marty Kraimer
* @data 2013.04
* @date 2013.04
*/
#ifndef CHANNELPROVIDERLOCAL_H
#define CHANNELPROVIDERLOCAL_H

View File

@@ -6,7 +6,7 @@
*/
/**
* @author Marty Kraimer
* @data 2013.04
* @date 2013.04
*/
#ifndef MONITORALGORITHM_H
#define MONITORALGORITHM_H

View File

@@ -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 &copyPVField,
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);
}
}
}

View File

@@ -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 &copyPVField,
PVRecordFieldPtr const &recordPVField);
void makeShared(
epics::pvData::PVFieldPtr const &copyPVField,
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 */

View 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);
}
}
}}

View 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 */

View File

@@ -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 ";

View 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);

View File

@@ -0,0 +1,3 @@
registrar("startPVAServerRegister")
registrar("stopPVAServerRegister")
registrar("pvdblRegister")