diff --git a/src/json/parseany.cpp b/src/json/parseany.cpp index b7119bd..7d1a2f6 100644 --- a/src/json/parseany.cpp +++ b/src/json/parseany.cpp @@ -15,6 +15,8 @@ #include "pv/json.h" namespace pvd = epics::pvData; +using pvd::yajl::integer_arg; +using pvd::yajl::size_arg; namespace { @@ -77,7 +79,7 @@ int jtree_boolean(void * ctx, int boolVal) }CATCH() } -int jtree_integer(void * ctx, long integerVal) +int jtree_integer(void * ctx, integer_arg integerVal) { TRY { if(self->depth==0) throw std::runtime_error("Bare value not supported"); @@ -130,7 +132,7 @@ int jtree_double(void * ctx, double doubleVal) } int jtree_string(void * ctx, const unsigned char * stringVal, - unsigned int stringLen) + size_arg stringLen) { TRY { if(self->depth==0) throw std::runtime_error("Bare value not supported"); @@ -172,7 +174,7 @@ int jtree_start_map(void * ctx) } int jtree_map_key(void * ctx, const unsigned char * key, - unsigned int stringLen) + size_arg stringLen) { TRY { if(!self->key.empty()) @@ -254,16 +256,24 @@ namespace epics{namespace pvData{ epics::pvData::PVStructure::shared_pointer parseJSON(std::istream& strm) { +#ifndef EPICS_YAJL_VERSION yajl_parser_config conf; memset(&conf, 0, sizeof(conf)); conf.allowComments = 1; conf.checkUTF8 = 1; +#endif context ctxt; +#ifndef EPICS_YAJL_VERSION handler handle(yajl_alloc(&jtree_cbs, &conf, NULL, &ctxt)); +#else + handler handle(yajl_alloc(&jtree_cbs, NULL, &ctxt)); - if(!yajl_parse_helper(strm, handle, conf)) + yajl_config(handle, yajl_allow_comments, 1); +#endif + + if(!yajl_parse_helper(strm, handle)) throw std::runtime_error(ctxt.msg); return ctxt.cur->buildPVStructure(); diff --git a/src/json/parsehelper.cpp b/src/json/parsehelper.cpp index 34ed895..bd53db0 100644 --- a/src/json/parsehelper.cpp +++ b/src/json/parsehelper.cpp @@ -15,7 +15,7 @@ namespace { -void check_trailing(const std::string& line, bool commentok) +void check_trailing(const std::string& line) { size_t idx = line.find_first_not_of(" \t\n\r"); if(idx==line.npos) return; @@ -29,37 +29,46 @@ void check_trailing(const std::string& line, bool commentok) namespace epics{namespace pvData{ bool yajl_parse_helper(std::istream& src, - yajl_handle handle, - const yajl_parser_config& config) + yajl_handle handle) { unsigned linenum=0; +#ifndef EPICS_YAJL_VERSION bool done = false; +#endif std::string line; while(std::getline(src, line)) { linenum++; +#ifndef EPICS_YAJL_VERSION if(done) { - check_trailing(line, config.allowComments); + check_trailing(line); continue; } +#endif yajl_status sts = yajl_parse(handle, (const unsigned char*)line.c_str(), line.size()); switch(sts) { case yajl_status_ok: { size_t consumed = yajl_get_bytes_consumed(handle); + if(consumed(self, integerVal); @@ -165,7 +167,7 @@ int jtree_double(void * ctx, double doubleVal) } int jtree_string(void * ctx, const unsigned char * stringVal, - unsigned int stringLen) + size_arg stringLen) { TRY { std::string val((const char*)stringVal, stringLen); @@ -200,7 +202,7 @@ int jtree_start_map(void * ctx) } int jtree_map_key(void * ctx, const unsigned char * key, - unsigned int stringLen) + size_arg stringLen) { TRY { assert(!self->stack.empty()); @@ -309,16 +311,25 @@ void parseJSON(std::istream& strm, const PVField::shared_pointer& dest, BitSet *assigned) { +#ifndef EPICS_YAJL_VERSION yajl_parser_config conf; memset(&conf, 0, sizeof(conf)); conf.allowComments = 1; conf.checkUTF8 = 1; +#endif context ctxt(dest, assigned); +#ifndef EPICS_YAJL_VERSION handler handle(yajl_alloc(&jtree_cbs, &conf, NULL, &ctxt)); +#else + handler handle(yajl_alloc(&jtree_cbs, NULL, &ctxt)); - if(!yajl_parse_helper(strm, handle, conf)) + yajl_config(handle, yajl_allow_comments, 1); +#endif + + + if(!yajl_parse_helper(strm, handle)) throw std::runtime_error(ctxt.msg); if(!ctxt.stack.empty()) diff --git a/src/json/pv/json.h b/src/json/pv/json.h index 5455fe8..5a7bc19 100644 --- a/src/json/pv/json.h +++ b/src/json/pv/json.h @@ -96,14 +96,25 @@ void parseJSON(std::istream& strm, * * @param src The stream from which input charactors are read * @param handle A parser handle previously allocated with yajl_alloc(). Not free'd on success or failure. - * @param config The same configuration passed to yajl_alloc(). Used to decide if trailing comments are allowed * * @returns true if parsing completes successfully. false if parsing cancelled by callback. throws other errors + * + * @note The form of this call depends on EPICS_YAJL_VERSION */ epicsShareFunc bool yajl_parse_helper(std::istream& src, - yajl_handle handle, - const yajl_parser_config& config); + yajl_handle handle); + +namespace yajl { +// undef implies API version 0 +#ifndef EPICS_YAJL_VERSION +typedef long integer_arg; +typedef unsigned size_arg; +#else +typedef long long integer_arg; +typedef size_t size_arg; +#endif +} // namespace epics::pvData::yajl /** @} */ diff --git a/testApp/misc/testjson.cpp b/testApp/misc/testjson.cpp index afa9eef..f156a25 100644 --- a/testApp/misc/testjson.cpp +++ b/testApp/misc/testjson.cpp @@ -97,12 +97,16 @@ void testparseanyjunk() { testThrows(std::runtime_error, std::istringstream strm("{} x"); std::cout<= 2.1.0 handles trailing comments for us"); +#endif { testThrows(std::runtime_error, std::istringstream strm("{}\n\n{}"); std::cout<