8#define epicsExportSharedSymbols
10#include <pv/valueBuilder.h>
14struct ValueBuilder::child {
17 child(
Type t) : type(t) {}
18 virtual void build(
const std::string& name, FieldBuilderPtr& builder)=0;
23struct 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
41 THROW_EXCEPTION2(std::logic_error,
"Structure type mis-match");
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);
55struct 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);
67struct 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
80 THROW_EXCEPTION2(std::logic_error,
"Scalar Array type mis-match");
88struct 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)
97 THROW_EXCEPTION2(std::logic_error,
"Scalar type mis-match");
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()) {
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);
160ValueBuilder::~ValueBuilder()
162 for(children_t::const_iterator it=children.
begin(),
end=children.
end(); it!=
end; ++it)
167void 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");
183 epics::auto_ptr<child> store;
185#define STYPE(stype) case stype: store.reset(new child_scalar<ScalarTypeTraits<stype>::type>(V)); break
201 THROW_EXCEPTION2(std::logic_error,
"Unhandled ScalarType");
203 if(it!=children.end()) {
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");
219 epics::auto_ptr<child> store(
new child_scalar_array(V));
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;
255void 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);
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);
basic_ostringstream< char > ostringstream
basic_string< char > string
constexpr auto end(_Container &__cont) -> decltype(__cont.end())
__string_type str() const
bool empty() const noexcept
element_type * get() const
const_iterator end() const noexcept
const_iterator begin() const noexcept
constexpr const_iterator begin() const noexcept
constexpr const_iterator end() const noexcept
PVScalar is the base class for each scalar field.
Data interface for a structure,.
std::tr1::shared_ptr< PVField > getSubField(A a)
const StructureConstPtr & getStructure() const
std::tr1::shared_ptr< PVStructure > buildPVStructure() const
ValueBuilder & endNested()
End a sub-structure.
ValueBuilder(const std::string &id=std::string())
empty structure
ValueBuilder & addNested(const std::string &name, Type type=structure, const std::string &id=std::string())
Start a sub-structure.
A holder for a contiguous piece of memory.
const char * name(Type type)
std::tr1::shared_ptr< const Structure > StructureConstPtr
const FieldCreatePtr & getFieldCreate()
std::tr1::shared_ptr< PVField > PVFieldPtr
std::tr1::shared_ptr< PVScalar > PVScalarPtr
std::vector< std::string > StringArray
std::tr1::shared_ptr< PVStructure > PVStructurePtr
std::tr1::shared_ptr< const Field > FieldConstPtr
std::tr1::shared_ptr< PVScalarArray > PVScalarArrayPtr