valueBuilder: support scalar array fields

This commit is contained in:
Michael Davidsaver
2017-07-12 18:33:20 +02:00
parent ef55345665
commit 918b7f96db
3 changed files with 73 additions and 5 deletions

View File

@@ -64,6 +64,26 @@ struct ValueBuilder::child_scalar_base : public ValueBuilder::child
}
};
struct ValueBuilder::child_scalar_array : public ValueBuilder::child
{
virtual ~child_scalar_array() {}
shared_vector<const void> array;
child_scalar_array(const shared_vector<const void>& v) : child(scalarArray), array(v) {}
virtual void build(const std::string& name, FieldBuilderPtr& builder) OVERRIDE FINAL
{
builder->addArray(name, array.original_type());
}
virtual void store(const PVFieldPtr& val)
{
if(val->getField()->getType()!=scalarArray)
THROW_EXCEPTION2(std::logic_error, "Scalar Array type mis-match");
PVScalarArrayPtr arr(std::tr1::static_pointer_cast<PVScalarArray>(val));
arr->putFrom(array);
}
};
template <typename T>
struct ValueBuilder::child_scalar : public ValueBuilder::child_scalar_base
{
@@ -188,6 +208,20 @@ void ValueBuilder::_add(const std::string& name, ScalarType stype, const void *V
store.release();
}
void ValueBuilder::_add(const std::string& name, const shared_vector<const void>& V)
{
const children_t::iterator it(children.find(name));
if(it!=children.end()) {
if(it->second->type!=scalar && it->second->type!=scalarArray)
THROW_EXCEPTION2(std::logic_error, "Not allowed to replace field. wrong type");
}
std::auto_ptr<child> store(new child_scalar_array(V));
children[name] = store.get();
store.release();
}
ValueBuilder& ValueBuilder::addNested(const std::string& name, Type type, const std::string &id)
{
if(type!=structure)

View File

@@ -9,6 +9,7 @@
#include <pv/templateMeta.h>
#include <pv/pvIntrospect.h>
#include <pv/sharedVector.h>
namespace epics{namespace pvData{
@@ -44,6 +45,14 @@ public:
return *this;
}
//! Add a scalar array field
template<class T>
FORCE_INLINE ValueBuilder& add(const std::string& name, const shared_vector<const T>& V)
{
_add(name, V);
return *this;
}
FORCE_INLINE ValueBuilder& add(const std::string& name, const PVStructure& V) {
_add(name, V);
return *this;
@@ -62,6 +71,7 @@ public:
private:
void _add(const std::string& name, ScalarType stype, const void *V);
void _add(const std::string& name, const shared_vector<const void> &V);
void _add(const std::string& name, const PVStructure& V);
ValueBuilder(ValueBuilder*, const std::string &id = std::string());
@@ -73,10 +83,10 @@ private:
friend struct child_struct;
struct child_scalar_base;
friend struct child_scalar_base;
template <typename T>
struct child_scalar;
template <typename T>
friend struct child_scalar;
template <typename T> struct child_scalar;
template <typename T> friend struct child_scalar;
struct child_scalar_array;
friend struct child_scalar_array;
typedef std::map<std::string, child*> children_t;
children_t children;

View File

@@ -10,6 +10,7 @@
#include <pv/valueBuilder.h>
#include <pv/pvData.h>
#include <pv/createRequest.h>
#include <pv/pvUnitTest.h>
namespace pvd = epics::pvData;
@@ -136,16 +137,39 @@ void testAppend()
testOk1(mod->getSubFieldT<pvd::PVInt>("record._options.foo")->get()==1);
}
void testArray()
{
testDiag("testArray()");
pvd::ValueBuilder builder;
pvd::shared_vector<pvd::int32> V(2);
V[0] = 1;
V[1] = 2;
pvd::shared_vector<const pvd::int32> SV(pvd::freeze(V));
pvd::PVStructurePtr S(builder
.add("foo", pvd::static_shared_vector_cast<const void>(SV))
.buildPVStructure());
pvd::PVIntArrayPtr I(S->getSubFieldT<pvd::PVIntArray>("foo"));
pvd::PVIntArray::const_svector out(I->view());
testFieldEqual<pvd::PVIntArray>(S, "foo", SV);
}
} // namespace
MAIN(testValueBuilder)
{
testPlan(27);
testPlan(28);
try {
testBuild();
testSubStruct();
testReplace();
testAppend();
testArray();
}catch(std::exception& e){
PRINT_EXCEPTION(e);
testAbort("Unexpected exception: %s", e.what());