From ebef394fe3772dad5d6b815787b75d20c95f71e3 Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Mon, 2 Dec 2013 10:27:48 +0100 Subject: [PATCH] testServer: added ChannelArray impl. --- pvAccessApp/Makefile | 3 + pvAccessApp/rpcService/rpcService.cpp | 8 ++ testApp/remote/testServer.cpp | 126 +++++++++++++++++++++++--- 3 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 pvAccessApp/rpcService/rpcService.cpp diff --git a/pvAccessApp/Makefile b/pvAccessApp/Makefile index b0e7faa..41fbdc5 100644 --- a/pvAccessApp/Makefile +++ b/pvAccessApp/Makefile @@ -79,6 +79,7 @@ LIBSRCS += beaconServerStatusProvider.cpp SRC_DIRS += $(PVACCESS)/rpcService INC += rpcService.h INC += rpcServer.h +LIBSRCS += rpcService.cpp LIBSRCS += rpcServer.cpp SRC_DIRS += $(PVACCESS)/rpcClient @@ -99,5 +100,7 @@ LIBRARY = pvAccess pvAccess_LIBS += Com pvAccess_LIBS += pvData pvAccess_LIBS += ca +# needed for 64-bit Windows +pvAccess_SYS_LIBS_WIN32 += ws2_32 include $(TOP)/configure/RULES diff --git a/pvAccessApp/rpcService/rpcService.cpp b/pvAccessApp/rpcService/rpcService.cpp new file mode 100644 index 0000000..1d2e360 --- /dev/null +++ b/pvAccessApp/rpcService/rpcService.cpp @@ -0,0 +1,8 @@ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * pvAccessCPP is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ + +#define epicsExportSharedSymbols +#include diff --git a/testApp/remote/testServer.cpp b/testApp/remote/testServer.cpp index eccb720..88534ce 100644 --- a/testApp/remote/testServer.cpp +++ b/testApp/remote/testServer.cpp @@ -1330,14 +1330,19 @@ class MockChannelArray : public ChannelArray private: ChannelArrayRequester::shared_pointer m_channelArrayRequester; PVArray::shared_pointer m_pvArray; + PVArray::shared_pointer m_pvStructureArray; protected: MockChannelArray(ChannelArrayRequester::shared_pointer const & channelArrayRequester, - PVStructure::shared_pointer const & /*pvStructure*/, PVStructure::shared_pointer const & /*pvRequest*/) : - m_channelArrayRequester(channelArrayRequester), - m_pvArray(getPVDataCreate()->createPVScalarArray(pvDouble)) + PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & /*pvRequest*/) : + m_channelArrayRequester(channelArrayRequester) { PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelArray); + + m_pvStructureArray = pvStructure->getSubField("value"); + if (m_pvStructureArray != 0) + m_pvArray = std::tr1::dynamic_pointer_cast( + getPVDataCreate()->createPVField(m_pvStructureArray->getField())); } public: @@ -1345,9 +1350,15 @@ public: { ChannelArray::shared_pointer thisPtr(new MockChannelArray(channelArrayRequester, pvStructure, pvRequest)); - // TODO pvRequest - channelArrayRequester->channelArrayConnect(Status::Ok, thisPtr, static_cast(thisPtr.get())->m_pvArray); - + PVArray::shared_pointer array(static_cast(thisPtr.get())->m_pvArray); + if (array.get()) + channelArrayRequester->channelArrayConnect(Status::Ok, thisPtr, array); + else + { + Status errorStatus(Status::STATUSTYPE_ERROR, "no 'value' subfield of array type"); + channelArrayRequester->channelArrayConnect(errorStatus, thisPtr, array); + } + return thisPtr; } @@ -1356,25 +1367,116 @@ public: PVACCESS_REFCOUNT_MONITOR_DESTRUCT(mockChannelArray); } - virtual void putArray(bool lastRequest, int /*offset*/, int /*count*/) + template + void put(PVArray::shared_pointer const & pvfrom, + PVArray::shared_pointer const & pvto, + size_t offset, size_t count) { - // TODO offset, count + typename APVF::shared_pointer from = std::tr1::static_pointer_cast(pvfrom); + typename APVF::shared_pointer to = std::tr1::static_pointer_cast(pvto); + + typename APVF::svector temp(to->reuse()); + typename APVF::const_svector ref(from->view()); + + // TODO range check + + std::copy(ref.begin(), ref.begin() + count, temp.begin() + offset); + + to->replace(freeze(temp)); + } + + virtual void putArray(bool lastRequest, int offset, int count) + { + size_t o = static_cast(offset); + if (count == -1) count = static_cast(m_pvArray->getLength()); + size_t c = static_cast(count); + + Field::const_shared_pointer field = m_pvArray->getField(); + Type type = field->getType(); + if (type == scalarArray) + { + switch (std::tr1::static_pointer_cast(field)->getElementType()) + { + case pvBoolean: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvByte: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvShort: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvInt: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvLong: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvUByte: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvUShort: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvUInt: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvULong: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvFloat: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvDouble: put(m_pvArray, m_pvStructureArray, o, c); break; + case pvString: put(m_pvArray, m_pvStructureArray, o, c); break; + } + } + else if (type == structureArray) + put(m_pvArray, m_pvStructureArray, o, c); + else if (type == unionArray) + put(m_pvArray, m_pvStructureArray, o, c); + m_channelArrayRequester->putArrayDone(Status::Ok); if (lastRequest) destroy(); } - virtual void getArray(bool lastRequest, int /*offset*/, int /*count*/) + template + void get(PVArray::shared_pointer const & pvfrom, + PVArray::shared_pointer const & pvto, + size_t offset, size_t count) { - // TODO offset, count + typename APVF::shared_pointer from = std::tr1::static_pointer_cast(pvfrom); + typename APVF::shared_pointer to = std::tr1::static_pointer_cast(pvto); + + // TODO range check + + typename APVF::const_svector temp(from->view()); + temp.slice(offset, count); + to->replace(temp); + } + + + virtual void getArray(bool lastRequest, int offset, int count) + { + size_t o = static_cast(offset); + if (count == -1) count = static_cast(m_pvStructureArray->getLength()); + size_t c = static_cast(count); + + Field::const_shared_pointer field = m_pvArray->getField(); + Type type = field->getType(); + if (type == scalarArray) + { + switch (std::tr1::static_pointer_cast(field)->getElementType()) + { + case pvBoolean: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvByte: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvShort: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvInt: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvLong: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvUByte: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvUShort: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvUInt: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvULong: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvFloat: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvDouble: get(m_pvStructureArray, m_pvArray, o, c); break; + case pvString: get(m_pvStructureArray, m_pvArray, o, c); break; + } + } + else if (type == structureArray) + get(m_pvStructureArray, m_pvArray, o, c); + else if (type == unionArray) + get(m_pvStructureArray, m_pvArray, o, c); + m_channelArrayRequester->getArrayDone(Status::Ok); if (lastRequest) destroy(); } - virtual void setLength(bool lastRequest, int /*length*/, int /*capacity*/) + virtual void setLength(bool lastRequest, int length, int capacity) { - // TODO offset, capacity + m_pvStructureArray->setCapacity(capacity); + m_pvStructureArray->setLength(length); m_channelArrayRequester->setLengthDone(Status::Ok); if (lastRequest) destroy();