9 #define epicsExportSharedSymbols 29 :fld(fld), assigned(assigned)
33 typedef std::vector<frame> stack_t;
38 stack.push_back(frame(root, assigned));
42 #define TRY context *self = (context*)ctx; assert(!self->stack.empty()); try 44 #define CATCH() catch(std::exception& e) { if(self->msg.empty()) self->msg = e.what(); return 0; } 46 int jtree_null(
void * ctx)
49 self->msg =
"NULL value not permitted";
54 template<
typename PVScalarT,
typename PVArrayT>
55 void valueAssign(context *
self,
typename PVScalarT::value_type val)
57 assert(!self->stack.empty());
58 context::frame& back =
self->stack.back();
61 pvd::PVScalar* fld(static_cast<pvd::PVScalar*>(back.fld.get()));
66 self->stack.pop_back();
75 switch(carr.original_type())
78 #define CASE_REAL_INT64 79 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case epics::pvData::pv##PVACODE: { \ 80 pvd::shared_vector<const PVATYPE> arr(pvd::static_shared_vector_cast<const PVATYPE>(carr)); \ 81 pvd::shared_vector<PVATYPE> tarr(pvd::thaw(arr)); \ 82 tarr.push_back(pvd::castUnsafe<PVATYPE>(val)); \ 83 carr = pvd::static_shared_vector_cast<const void>(pvd::freeze(tarr)); \ 87 #undef CASE_REAL_INT64 96 pvd::PVUnion* fld(static_cast<pvd::PVUnion*>(back.fld.get()));
99 if(utype->isVariant()) {
111 assert(names.size()==types.size());
113 bool assigned =
false;
114 for(
size_t i=0, N=names.size();
i<N;
i++) {
121 }
catch(std::runtime_error&){
130 throw std::runtime_error(
"Unable to select union member");
134 self->stack.pop_back();
138 throw std::invalid_argument(
"Can't assign value");
142 int jtree_boolean(
void * ctx,
int boolVal)
145 valueAssign<pvd::PVBoolean, pvd::PVBooleanArray>(
self, !!boolVal);
150 int jtree_integer(
void * ctx,
integer_arg integerVal)
153 valueAssign<pvd::PVLong, pvd::PVLongArray>(
self, integerVal);
158 int jtree_double(
void * ctx,
double doubleVal)
161 valueAssign<pvd::PVDouble, pvd::PVDoubleArray>(
self, doubleVal);
166 int jtree_string(
void * ctx,
const unsigned char * stringVal,
170 std::string val((
const char*)stringVal, stringLen);
171 valueAssign<pvd::PVString, pvd::PVStringArray>(
self, val);
176 int jtree_start_map(
void * ctx)
179 assert(!self->stack.empty());
181 context::frame& back =
self->stack.back();
191 self->stack.push_back(context::frame(elem, 0));
193 throw std::runtime_error(
"Can't map (sub)structure");
201 int jtree_map_key(
void * ctx,
const unsigned char * key,
205 assert(!self->stack.empty());
206 std::string name((
const char*)key, stringLen);
212 self->stack.push_back(context::frame(fld->
getSubFieldT(name),
self->stack.back().assigned));
213 }
catch(std::runtime_error& e){
214 std::ostringstream strm;
215 strm<<
"At "<<fld->
getFullName()<<
" : "<<e.what()<<
"\n";
216 throw std::runtime_error(strm.str());
223 int jtree_end_map(
void * ctx)
226 assert(!self->stack.empty());
229 context::frame elem(self->stack.back());
230 self->stack.pop_back();
232 if(!self->stack.empty() &&
self->stack.back().fld->getField()->getType()==
pvd::structureArray) {
241 val.push_back(std::tr1::static_pointer_cast<pvd::PVStructure>(elem.fld));
243 sarr->
replace(pvd::freeze(val));
250 int jtree_start_array(
void * ctx)
253 assert(!self->stack.empty());
257 throw std::runtime_error(
"Can't assign array");
262 int jtree_end_array(
void * ctx)
265 assert(!self->stack.empty());
267 if(self->stack.back().assigned)
268 self->stack.back().assigned->set(self->stack.back().fld->getFieldOffset());
269 self->stack.pop_back();
294 throw std::runtime_error(
"Failed to allocate yajl handle");
308 namespace epics{
namespace pvData{
315 #ifndef EPICS_YAJL_VERSION 316 yajl_parser_config conf;
317 memset(&conf, 0,
sizeof(conf));
318 conf.allowComments = 1;
327 context ctxt(fakedest, assigned);
329 #ifndef EPICS_YAJL_VERSION 339 throw std::runtime_error(ctxt.msg);
341 if(!ctxt.stack.empty())
342 throw std::logic_error(
"field stack not empty");
343 assert(fakedest.use_count()==1);
PVScalar is the base class for each scalar field.
#define assert(exp)
Declare that a condition should be true.
void yajl_free(yajl_handle handle)
StructureArrayConstPtr getStructureArray() const
epicsShareFunc void parseJSON(std::istream &strm, PVField &dest, BitSet *assigned)
::epics::pvData::shared_vector< PVStructurePtr > svector
const UnionConstPtr & getUnion() const
virtual void replace(const const_svector &other) OVERRIDE FINAL
pvd::StructureConstPtr type
virtual void swap(const_svector &other) OVERRIDE FINAL
TODO only here because of the Lockable.
int yajl_config(yajl_handle h, yajl_option opt,...)
::epics::pvData::shared_vector< const PVStructurePtr > const_svector
PVField is the base class for each PVData field.
std::size_t getFieldOffset() const
std::string getFullName() const
void getAs(shared_vector< const T > &out) const
std::tr1::shared_ptr< const Union > UnionConstPtr
Base class for a scalarArray.
std::tr1::shared_ptr< PVScalar > PVScalarPtr
PVUnion has a single subfield.
std::vector< FieldConstPtr > FieldConstPtrArray
Data interface for a structure,.
void set(PVFieldPtr const &value)
std::tr1::shared_ptr< PVStructure > PVStructurePtr
PVFieldPtr select(int32 index)
Data class for a structureArray.
FORCE_INLINE std::tr1::shared_ptr< PVField > getSubFieldT(A a)
yajl_handle yajl_alloc(const yajl_callbacks *callbacks, yajl_alloc_funcs *afs, void *ctx)
std::vector< std::string > StringArray
std::tr1::shared_ptr< PVField > PVFieldPtr
void putFrom(const shared_vector< const T > &inp)
bool yajl_parse_helper(std::istream &src, yajl_handle handle)
struct yajl_handle_t * yajl_handle
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()