make compatible with latest pvDataCPP and pvAccessCPP; lots of work on queues.

This commit is contained in:
Marty Kraimer
2013-11-06 15:44:58 -05:00
parent 14b3640e9a
commit 006859120e
12 changed files with 78 additions and 554 deletions

View File

@ -297,7 +297,8 @@ static void scalarTest()
pvRecord = createScalar("doubleRecord",pvDouble,"alarm,timeStamp,display");
valueNameRecord = request = "value";
pvRequest = getCreateRequest()->createRequest(request,requester);
CreateRequest::shared_pointer createRequest = CreateRequest::create();
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl;
cout << "pvRequest" << endl << builder;
@ -306,7 +307,7 @@ static void scalarTest()
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "";
valueNameRecord = "value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
@ -314,7 +315,7 @@ static void scalarTest()
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "alarm,timeStamp,value";
valueNameRecord = "value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
@ -336,9 +337,10 @@ static void arrayTest()
String valueNameRecord;
String valueNameCopy;
CreateRequest::shared_pointer createRequest = CreateRequest::create();
pvRecord = createScalarArray("doubleArrayRecord",pvDouble,"alarm,timeStamp");
valueNameRecord = request = "value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl;
cout << "pvRequest" << endl << builder;
@ -347,7 +349,7 @@ static void arrayTest()
testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "";
valueNameRecord = "value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
@ -355,7 +357,7 @@ static void arrayTest()
testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "alarm,timeStamp,value";
valueNameRecord = "value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
@ -377,9 +379,10 @@ static void powerSupplyTest()
String valueNameRecord;
String valueNameCopy;
CreateRequest::shared_pointer createRequest = CreateRequest::create();
pvRecord = createPowerSupply("powerSupply");
valueNameRecord = request = "power.value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl;
cout << "pvRequest" << endl << builder;
@ -388,7 +391,7 @@ static void powerSupplyTest()
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "";
valueNameRecord = "power.value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
@ -396,7 +399,7 @@ static void powerSupplyTest()
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "alarm,timeStamp,voltage.value,power.value,current.value";
valueNameRecord = "power.value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
@ -404,7 +407,7 @@ static void powerSupplyTest()
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
request = "alarm,timeStamp,voltage{value,alarm},power{value,alarm,display},current.value";
valueNameRecord = "power.value";
pvRequest = getCreateRequest()->createRequest(request,requester);
pvRequest = createRequest->createRequest(request);
builder.clear(); pvRequest->toString(&builder);
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
pvCopy = PVCopy::create(pvRecord,pvRequest,"");

View File

@ -251,10 +251,10 @@ bool LongArrayMonitor::init(
String request("record[queueSize=");
request += queueSize;
request += "]field(value,timeStamp,alarm)";
PVStructurePtr pvRequest =
getCreateRequest()->createRequest(request,channelRequester);
CreateRequest::shared_pointer createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(pvRequest==NULL) {
cout << "request logic error " << request << endl;
cout << "request logic error " << createRequest->getMessage() << endl;
return false;
}
monitor = channel->createMonitor(monitorRequester,pvRequest);

View File

@ -83,8 +83,8 @@ bool ExamplePVADoubleArrayGet::init()
}
ChannelGetRequester::shared_pointer channelGetRequester =
dynamic_pointer_cast<ChannelGetRequester>(getPtrSelf());
PVStructurePtr pvRequest = getCreateRequest()->createRequest(
"value,alarm,timeStamp",getPtrSelf());
PVStructurePtr pvRequest = CreateRequest::create()->createRequest(
"value,alarm,timeStamp");
channelGet = channel->createChannelGet(channelGetRequester,pvRequest);
event.wait();
if(!status.isOK()) {

View File

@ -55,6 +55,13 @@ public:
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet);
virtual void getDone(const epics::pvData::Status& status);
virtual epics::pvData::String getRequesterName() {return channelName;}
virtual void message(
epics::pvData::String const & message,
epics::pvData::MessageType messageType)
{
std::cout << "Why is ExamplePVADoubleArrayGet::message called\n";
}
private:
ExamplePVADoubleArrayGet(epics::pvData::String const & recordName,
epics::pvData::String providerName,

View File

@ -7,10 +7,6 @@ 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

View File

@ -168,14 +168,4 @@ bool PVDatabase::removeRecord(PVRecordPtr const & record)
}
}
String PVDatabase::getRequesterName()
{
static String name("masterDatabase");
return name;
}
void PVDatabase::message(String const & message,MessageType messageType)
{
}
}}

View File

@ -46,7 +46,6 @@ typedef std::tr1::shared_ptr<PVDatabase> PVDatabasePtr;
* @author mrk
*/
class PVRecord :
public virtual epics::pvData::Requester,
public std::tr1::enable_shared_from_this<PVRecord>
{
public:
@ -108,18 +107,6 @@ public:
*/
PVRecordFieldPtr findPVRecordField(
epics::pvData::PVFieldPtr const & pvField);
/**
* Add a requester to receive messages.
* @param requester The requester.
* @return <b>true</b> if requester was added.
*/
bool addRequester(epics::pvData::RequesterPtr const & requester);
/**
* Remove a requester.
* @param requester The requester.`
* @return <b>true</b> if requester was removed.
*/
bool removeRequester(epics::pvData::RequesterPtr const & requester);
/**
* Lock the record.
* Any code must lock while accessing a record.
@ -183,31 +170,6 @@ public:
* Ends a group of puts.
*/
void endGroupPut();
/**
* Virtual method of <b>Requester</b>
* @return the name of the requester.
*/
epics::pvData::String getRequesterName() {return getRecordName();}
/**
* Can be called by implementation code.
* The message will be sent to every requester.
* @param message The message.
* @param messageType The severity of the message.
*/
virtual void message(
epics::pvData::String const & message,
epics::pvData::MessageType messageType);
/**
* Called for a field. It will call the previous method
* after adding field name.
* @param pvRecordField The field for which the message is associated.
* @param message The message.
* @param messageType The severity of the message.
*/
void message(
PVRecordFieldPtr const & pvRecordField,
epics::pvData::String const & message,
epics::pvData::MessageType messageType);
/**
* Calls the next method with indentLevel = 0.
* @param buf String Builder.
@ -261,7 +223,6 @@ private:
PVRecordStructurePtr pvRecordStructure;
std::list<PVListenerPtr> pvListenerList;
std::list<PVRecordClientPtr> pvRecordClientList;
std::list<epics::pvData::RequesterPtr> requesterList;
epics::pvData::Mutex mutex;
std::size_t depthGroupPut;
int traceLevel;
@ -341,16 +302,6 @@ public:
* It is called whenever the put method is called.
*/
virtual void postPut();
/**
* Called by implementation code.
* It calls PVRecord::message after prepending the full fieldname.
* @param message The message,
* @param messageType The message severity.
* @return
*/
virtual void message(
epics::pvData::String const & message,
epics::pvData::MessageType messageType);
protected:
PVRecordFieldPtr getPtrSelf()
{
@ -495,7 +446,7 @@ public:
* The interface to a database of PVRecords.
* @author mrk
*/
class PVDatabase : virtual public epics::pvData::Requester {
class PVDatabase {
public:
POINTER_DEFINITIONS(PVDatabase);
/**
@ -535,20 +486,6 @@ public:
* @return The names.
*/
epics::pvData::PVStringArrayPtr getRecordNames();
/**
* Virtual method of Requester.
* @return The name.
*/
virtual epics::pvData::String getRequesterName();
/**
* Virtual method of Requester.
* @param message The message.
* @param messageType The message severity.
* @return
*/
virtual void message(
epics::pvData::String const & message,
epics::pvData::MessageType messageType);
private:
PVDatabase();
void lock();
@ -556,7 +493,6 @@ private:
PVRecordMap recordMap;
epics::pvData::Mutex mutex;
bool isDestroyed;
};
}}

View File

@ -56,7 +56,6 @@ void PVRecord::initPVRecord()
pvRecordStructure = PVRecordStructurePtr(
new PVRecordStructure(pvStructure,parent,getPtrSelf()));
pvRecordStructure->init();
pvStructure->setRequester(getPtrSelf());
}
void PVRecord::destroy()
@ -72,16 +71,6 @@ void PVRecord::destroy()
}
isDestroyed = true;
std::list<RequesterPtr>::iterator requesterIter;
while(true) {
requesterIter = requesterList.begin();
if(requesterIter==requesterList.end()) break;
requesterList.erase(requesterIter);
unlock();
(*requesterIter)->message("record destroyed",fatalErrorMessage);
lock();
}
std::list<PVRecordClientPtr>::iterator clientIter;
while(true) {
clientIter = pvRecordClientList.begin();
@ -122,60 +111,6 @@ PVRecordFieldPtr PVRecord::findPVRecordField(PVFieldPtr const & pvField)
return findPVRecordField(pvRecordStructure,pvField);
}
bool PVRecord::addRequester(epics::pvData::RequesterPtr const & requester)
{
if(traceLevel>2) {
cout << "PVRecord::addRequester() " << recordName << endl;
}
lock();
try {
if(isDestroyed) {
unlock();
return false;
}
std::list<RequesterPtr>::iterator iter;
for (iter = requesterList.begin(); iter!=requesterList.end(); iter++ ) {
if((*iter).get()==requester.get()) {
unlock();
return false;
}
}
requesterList.push_back(requester);
unlock();
return true;
} catch (...) {
unlock();
throw;
}
}
bool PVRecord::removeRequester(epics::pvData::RequesterPtr const & requester)
{
if(traceLevel>2) {
cout << "PVRecord::removeRequester() " << recordName << endl;
}
lock();
try {
if(isDestroyed) {
unlock();
return false;
}
std::list<RequesterPtr>::iterator iter;
for (iter = requesterList.begin(); iter!=requesterList.end(); iter++ ) {
if((*iter).get()==requester.get()) {
requesterList.erase(iter);
unlock();
return true;
}
}
unlock();
return false;
} catch (...) {
unlock();
throw;
}
}
PVRecordFieldPtr PVRecord::findPVRecordField(
PVRecordStructurePtr const & pvrs,
PVFieldPtr const & pvField)
@ -408,28 +343,6 @@ void PVRecord::endGroupPut()
}
}
void PVRecord::message(String const & message,MessageType messageType)
{
if(isDestroyed) return;
if(requesterList.size()==0 ) {
String xxx(getMessageTypeName(messageType) + " " + message);
printf("%s\n",xxx.c_str());
return;
}
std::list<epics::pvData::RequesterPtr>::iterator iter;
for(iter = requesterList.begin(); iter != requesterList.end(); ++iter) {
(*iter)->message(message,messageType);
}
}
void PVRecord::message(
PVRecordFieldPtr const & pvRecordField,
String const & message,
MessageType messageType)
{
this->message(pvRecordField->getFullName() + " " + message,messageType);
}
void PVRecord::toString(StringBuilder buf)
{
toString(buf,0);
@ -549,11 +462,6 @@ void PVRecordField::postSubField()
}
}
void PVRecordField::message(String const & message,MessageType messageType)
{
pvRecord->message(getPtrSelf(),message,messageType);
}
void PVRecordField::callListener()
{
std::list<PVListenerPtr>::iterator iter;

View File

@ -98,7 +98,8 @@ public:
virtual ~RealQueue(){}
RealQueue(
MonitorLocalPtr const &monitorLocal,
std::vector<MonitorElementPtr> &monitorElementArray);
std::vector<MonitorElementPtr> &monitorElementArray,
size_t nfields);
virtual Status start();
virtual void stop();
virtual bool dataChanged();
@ -107,8 +108,10 @@ public:
private:
std::tr1::weak_ptr<MonitorLocal> monitorLocal;
Queue<MonitorElement> queue;
BitSetPtr changedBitSet;
BitSetPtr overrunBitSet;
MonitorElementPtr latestMonitorElement;
bool queueIsFull;
MonitorElementPtr monitorElement;
};
@ -333,7 +336,8 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
new MonitorElement(pvStructure));
monitorElementArray.push_back(monitorElement);
}
queue = RealQueuePtr(new RealQueue(getPtrSelf(),monitorElementArray));
size_t nfields = monitorElementArray[0]->pvStructurePtr->getNumberFields();
queue = RealQueuePtr(new RealQueue(getPtrSelf(),monitorElementArray,nfields));
}
// MARTY MUST IMPLEMENT algorithm
monitorRequester->monitorConnect(
@ -447,11 +451,12 @@ MonitorElementPtr NOQueue::poll()
if(ml==NULL) return NULLMonitorElement;
ml->getPVCopy()->updateCopyFromBitSet(
pvCopyStructure, changedBitSet);
getConvert()->copyStructure(pvCopyStructure,monitorElement->pvStructurePtr);
BitSetUtil::compress(changedBitSet,pvCopyStructure);
BitSetUtil::compress(overrunBitSet,pvCopyStructure);
(*monitorElement->changedBitSet) = (*changedBitSet);
(*monitorElement->overrunBitSet) = (*overrunBitSet);
monitorElement->changedBitSet->clear();
monitorElement->overrunBitSet->clear();
(*monitorElement->changedBitSet) |= (*changedBitSet);
(*monitorElement->overrunBitSet) |= (*overrunBitSet);
changedBitSet->clear();
overrunBitSet->clear();
return monitorElement;
@ -464,9 +469,12 @@ void NOQueue::release(MonitorElementPtr const &monitorElement)
RealQueue::RealQueue(
MonitorLocalPtr const &monitorLocal,
std::vector<MonitorElementPtr> &monitorElementArray)
std::vector<MonitorElementPtr> &monitorElementArray,
size_t nfields)
: monitorLocal(monitorLocal),
queue(monitorElementArray),
changedBitSet(new BitSet(nfields)),
overrunBitSet(new BitSet(nfields)),
queueIsFull(false)
{
}
@ -474,14 +482,11 @@ RealQueue::RealQueue(
Status RealQueue::start()
{
queue.clear();
monitorElement = queue.getFree();
monitorElement->changedBitSet->clear();
monitorElement->overrunBitSet->clear();
changedBitSet->clear();
overrunBitSet->clear();
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return wasDestroyedStatus;
ml->getPVCopyMonitor()->startMonitoring(
monitorElement->changedBitSet,
monitorElement->overrunBitSet);
ml->getPVCopyMonitor()->startMonitoring(changedBitSet,overrunBitSet);
return Status::Ok;
}
@ -491,29 +496,38 @@ void RealQueue::stop()
bool RealQueue::dataChanged()
{
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
MonitorLocalPtr ml = monitorLocal.lock();
if(ml==NULL) return false;
ml->getPVCopy()->updateCopyFromBitSet(
pvStructure,monitorElement->changedBitSet);
if(queue.getNumberFree()==0) {
if(queueIsFull) return false;
queueIsFull = true;
return true;
if(queueIsFull) {
MonitorElementPtr monitorElement = latestMonitorElement;
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
ml->getPVCopy()->updateCopyFromBitSet(pvStructure,changedBitSet);
(*monitorElement->changedBitSet)|= (*changedBitSet);
(*monitorElement->overrunBitSet)|= (*changedBitSet);
changedBitSet->clear();
overrunBitSet->clear();
return false;
}
MonitorElementPtr newElement = queue.getFree();
if(newElement==NULL) {
MonitorElementPtr monitorElement = queue.getFree();
if(monitorElement==NULL) {
throw std::logic_error(String("RealQueue::dataChanged() logic error"));
}
BitSetUtil::compress(monitorElement->changedBitSet,pvStructure);
BitSetUtil::compress(monitorElement->overrunBitSet,pvStructure);
convert->copy(pvStructure,newElement->pvStructurePtr);
newElement->changedBitSet->clear();
newElement->overrunBitSet->clear();
ml->getPVCopyMonitor()->switchBitSets(
newElement->changedBitSet,newElement->overrunBitSet);
if(queue.getNumberFree()==0){
queueIsFull = true;
latestMonitorElement = monitorElement;
}
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
ml->getPVCopy()->updateCopyFromBitSet(
pvStructure,changedBitSet);
BitSetUtil::compress(changedBitSet,pvStructure);
BitSetUtil::compress(overrunBitSet,pvStructure);
monitorElement->changedBitSet->clear();
(*monitorElement->changedBitSet)|=(*changedBitSet);
monitorElement->overrunBitSet->clear();
(*monitorElement->overrunBitSet)|=(*overrunBitSet);
changedBitSet->clear();
overrunBitSet->clear();
queue.setUsed(monitorElement);
monitorElement = newElement;
return true;
}
@ -524,8 +538,15 @@ MonitorElementPtr RealQueue::poll()
void RealQueue::release(MonitorElementPtr const &currentElement)
{
if(queueIsFull) {
MonitorElementPtr monitorElement = latestMonitorElement;
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
BitSetUtil::compress(monitorElement->changedBitSet,pvStructure);
BitSetUtil::compress(monitorElement->overrunBitSet,pvStructure);
queueIsFull = false;
latestMonitorElement.reset();
}
queue.releaseUsed(currentElement);
queueIsFull = false;
}
MonitorFactoryPtr getMonitorFactory()

View File

@ -350,7 +350,6 @@ bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
pvRecord->getPVRecordStructure(),
pvRequest,
cacheInitStructure);
referenceImmutable(cacheInitStructure,headNode);
return true;
}
@ -696,56 +695,6 @@ CopyNodePtr PVCopy::createStructureNodes(
return structureNode;
}
void PVCopy::referenceImmutable(
PVFieldPtr const &pvField,
CopyNodePtr const & node)
{
if(node->isStructure) {
CopyStructureNodePtr structureNode =
static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structureNode->nodes;
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
for(size_t i=0; i<nodes->size(); i++) {
CopyNodePtr nextNode = (*nodes)[i];
referenceImmutable(
pvStructure->getSubField(nextNode->structureOffset),
nextNode);
}
} else {
CopyRecordNodePtr recordNode =
static_pointer_cast<CopyRecordNode>(node);
PVRecordFieldPtr recordPVField = recordNode->recordPVField;
referenceImmutable(pvField,recordPVField);
}
}
void PVCopy::referenceImmutable(
PVFieldPtr const &copyPVField,
PVRecordFieldPtr const &recordPVField)
{
if(recordPVField->getPVField()->getField()->getType()
==epics::pvData::structure) {
if(copyPVField->getField()->getType()!=epics::pvData::structure) {
throw std::logic_error(String("Logic error"));
}
PVStructurePtr pvStructure =
static_pointer_cast<PVStructure>(copyPVField);
PVFieldPtrArray const & copyPVFields = pvStructure->getPVFields();
PVRecordStructurePtr pvRecordStructure =
static_pointer_cast<PVRecordStructure>(recordPVField);
PVRecordFieldPtrArrayPtr recordPVFields =
pvRecordStructure->getPVRecordFields();
for(size_t i=0; i<copyPVFields.size(); i++) {
referenceImmutable(copyPVFields[i],(*recordPVFields)[i]);
}
return;
}
if(recordPVField->getPVField()->isImmutable()) {
getConvert()->copy(recordPVField->getPVField(), copyPVField);
}
}
void PVCopy::updateStructureNodeSetBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,

View File

@ -1,203 +0,0 @@
/**
* 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) capacity = toOffset + len;
shared_vector<T> temp(capacity);
typename PVValueArray<T>::const_svector vecFrom = pvFrom.view();
typename PVValueArray<T>::const_svector vecTo = pvTo.view();
for(size_t i=0; i<toOffset; ++i) temp[i] = vecTo[i];
for(size_t i=0; i<len; ++i) temp[i + toOffset] = vecFrom[i + fromOffset];
for(size_t i=len + toOffset; i<capacity; ++i) temp[i] = vecTo[i];
shared_vector<const T> temp2(freeze(temp));
pvTo.replace(temp2);
}
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) capacity = toOffset+len;
shared_vector<PVStructurePtr> temp(capacity);
PVValueArray<PVStructurePtr>::const_svector vecFrom = from.view();
PVValueArray<PVStructurePtr>::const_svector vecTo = to.view();
for(size_t i=0; i<toOffset; ++i) temp[i] = vecTo[i];
for(size_t i=0; i<len; ++i) temp[i + toOffset] = vecFrom[i + fromOffset];
for(size_t i=len + toOffset; i<capacity; ++i) temp[i] = vecTo[i];
shared_vector<const PVStructurePtr> temp2(freeze(temp));
to.replace(temp2);
}
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

@ -1,83 +0,0 @@
/* 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 */