valueBuilder: support scalar array fields
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user