8 #define epicsExportSharedSymbols
10 #include <pv/valueBuilder.h>
12 namespace epics{
namespace pvData{
14 struct ValueBuilder::child {
17 child(
Type t) : type(t) {}
18 virtual void build(
const std::string& name, FieldBuilderPtr& builder)=0;
23 struct ValueBuilder::child_struct :
public ValueBuilder::child
25 virtual ~child_struct() {}
32 virtual void build(
const std::string& name, FieldBuilderPtr& builder) OVERRIDE FINAL
34 FieldBuilderPtr nest(builder->addNestedStructure(name));
35 buildStruct(this->builder, nest);
36 builder = nest->endNested();
38 virtual void store(
const PVFieldPtr& val) OVERRIDE FINAL
42 PVStructurePtr str(std::tr1::static_pointer_cast<PVStructure>(val));
43 storeStruct(builder, str);
47 void buildStruct(
const ValueBuilder&
self, FieldBuilderPtr& builder);
52 void fillStruct(
ValueBuilder&
self,
const PVStructure& val);
55 struct ValueBuilder::child_scalar_base :
public ValueBuilder::child
57 virtual ~child_scalar_base() {}
61 virtual void build(
const std::string& name, FieldBuilderPtr& builder) OVERRIDE FINAL
63 builder->add(name, stype);
67 struct ValueBuilder::child_scalar_array :
public ValueBuilder::child
69 virtual ~child_scalar_array() {}
70 shared_vector<const void> array;
71 child_scalar_array(
const shared_vector<const void>& v) : child(
scalarArray), array(v) {}
73 virtual void build(
const std::string& name, FieldBuilderPtr& builder) OVERRIDE FINAL
75 builder->addArray(name, array.original_type());
77 virtual void store(
const PVFieldPtr& val) OVERRIDE FINAL
88 struct ValueBuilder::child_scalar :
public ValueBuilder::child_scalar_base
90 virtual ~child_scalar() {}
92 child_scalar(
const void* v) : child_scalar_base(static_cast<
ScalarType>(ScalarTypeID<T>::value)), value(*static_cast<const T*>(v)) {}
94 virtual void store(
const PVFieldPtr& val) OVERRIDE FINAL
96 if(val->getField()->getType()!=
scalar)
110 for(StringArray::const_iterator it=field.begin(),
end=field.end(); it!=
end; ++it)
112 PVField::const_shared_pointer sub(val.
getSubField(*it));
115 switch(subtype->getType()) {
118 const PVScalar* subs(static_cast<const PVScalar*>(sub.get()));
119 ScalarType stype = subs->getScalar()->getScalarType();
121 #define STYPE(stype) case pv##stype: { const PV ##stype* ptr(static_cast<const PV##stype*>(subs)); PV##stype::value_type temp(ptr->get()); self._add(*it, pv##stype, &temp); } break
139 self._add(*it, *static_cast<const PVStructure*>(sub.get()));
142 THROW_EXCEPTION2(
std::runtime_error,
"ValueBuilder can only clone scalar and structure");
151 child_struct::fillStruct(*
this, clone);
160 ValueBuilder::~ValueBuilder()
162 for(children_t::const_iterator it=children.
begin(),
end=children.
end(); it!=
end; ++it)
167 void ValueBuilder::_add(
const std::string& name,
const PVStructure& V)
171 child_struct::fillStruct(
self, V);
177 const children_t::iterator it(children.
find(name));
178 if(it!=children.
end()) {
180 THROW_EXCEPTION2(
std::logic_error,
"Not allowed to replace field. wrong type");
185 #define STYPE(stype) case stype: store.reset(new child_scalar<ScalarTypeTraits<stype>::type>(V)); break
203 if(it!=children.
end()) {
207 children[name] = store.
get();
211 void ValueBuilder::_add(
const std::string& name,
const shared_vector<const void>& V)
213 const children_t::iterator it(children.
find(name));
214 if(it!=children.
end()) {
216 THROW_EXCEPTION2(
std::logic_error,
"Not allowed to replace field. wrong type");
221 children[name] = store.
get();
230 children_t::const_iterator it(children.
find(name));
231 if(it==children.
end()) {
234 children[name] = store.
get();
237 sub =
static_cast<child_struct*
>(it->second);
240 msg<<
"Can't replace non-struct field '"<<name<<
"' with struct";
243 sub->builder.id = id;
255 void ValueBuilder::child_struct::buildStruct(
const ValueBuilder&
self, FieldBuilderPtr& builder)
258 builder->setId(
self.
id);
260 for(children_t::const_iterator it=
self.children.begin(),
end=
self.children.end(); it!=
end; ++it)
262 it->second->build(it->first, builder);
266 void ValueBuilder::child_struct::storeStruct(
const ValueBuilder&
self,
const PVStructurePtr& val)
268 for(children_t::const_iterator it=
self.children.begin(),
end=
self.children.end(); it!=
end; ++it)
270 it->second->store(val->getSubFieldT(it->first));
277 THROW_EXCEPTION2(
std::logic_error,
"Only top level structure may be built. Missing endNested() ?");
283 child_struct::buildStruct(*
this, tbuild);
285 type = tbuild->createStructure();
288 PVStructure::shared_pointer root(type->build());
290 child_struct::storeStruct(*
this, root);
ValueBuilder & endNested()
End a sub-structure.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
directory_iterator end(directory_iterator) noexcept
const_iterator begin() const noexcept
iterator find(const key_type &__x)
__string_type str() const
Data interface for a structure,.
std::tr1::shared_ptr< PVScalar > PVScalarPtr
std::tr1::shared_ptr< const Structure > StructureConstPtr
std::tr1::shared_ptr< PVStructure > buildPVStructure() const
std::tr1::shared_ptr< const Field > FieldConstPtr
ValueBuilder & addNested(const std::string &name, Type type=structure, const std::string &id=std::string())
Start a sub-structure.
std::tr1::shared_ptr< PVScalarArray > PVScalarArrayPtr
std::tr1::shared_ptr< PVField > PVFieldPtr
PVScalar is the base class for each scalar field.
const_iterator end() const noexcept
const StructureConstPtr & getStructure() const
std::tr1::shared_ptr< PVField > getSubField(A a)
ValueBuilder(const std::string &id=std::string())
empty structure
element_type * get() const
std::tr1::shared_ptr< PVStructure > PVStructurePtr
const FieldCreatePtr & getFieldCreate()
size_type erase(const key_type &__x)