Weird issues when using custom parse contexts
Closed this issue · 1 comments
Hi there,
I seem to be having some issues when trying to create parsing contexts and I was wondering what I might be missing.
This is my input data:
[
{
"entry": "blah"
},
{
"nested": "{\"dict\": 1, \"some\": \"string\"}"
}
]
I seem to get this error message when trying to parse it using a custom parsing context class, err is filled with:
syntax error at line 1 near: {
The class I'm using is pretty much copied from the streaming example:
class ParseCmdContext : public picojson::deny_parse_context
{
public:
ParseCmdContext()
: m_count(0)
{}
bool parse_array_start()
{
return true;
}
template <typename Iter>
bool parse_array_item(picojson::input<Iter>& in, size_t)
{
picojson::value item;
picojson::default_parse_context ctx(&item);
if(!picojson::_parse(ctx, in))
return false;
if(!item.is<picojson::object>())
return false;
std::cout << item.serialize(false) << std::endl;
m_count++;
return true;
}
bool parse_array_stop(size_t)
{
return true;
}
inline uint32_t count()const { return m_count; }
private:
uint32_t m_count;
};
void test(const std::string& str)
{
ParseCmdContext ctx;
std::string err;
picojson::_parse(ctx, str.c_str(), str.c_str()+strlen(str.c_str()), &err);
if(!err.empty())
{
//error is printed here <<<
std::cerr <<"ParseCmdCtx "<< err << std::endl;
}
err.clear();
picojson::value unused;
picojson::default_parse_context ctx(&unused);
picojson::_parse(ctx, str.c_str(), str.c_str()+strlen(str.c_str()), &err);
if(!err.empty())
{
// but not here, this works! which suggests that I'm doing something wrong...
std::cerr <<"default_parse_context "<< err << std::endl;
}
}
I have tried making a "bypass" context that is literally a copy of default_parse_context with prints added and it seems to show the same error as the above one when called, strangely enough, the default_parse_context works fine again.
class ParseSceneContext
{
protected:
picojson::value *out_;
public:
ParseSceneContext(picojson::value *out)
: out_(out)
{}
bool set_null() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
*out_ = picojson::value();
return true;
}
bool set_bool(bool b) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
*out_ = picojson::value(b);
return true;
}
#ifdef PICOJSON_USE_INT64
bool set_int64(int64_t i) {
*out_ = value(i);
return true;
}
#endif
bool set_number(double f) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
*out_ = picojson::value(f);
return true;
}
template <typename Iter>
bool parse_string(picojson::input<Iter> &in) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
*out_ = picojson::value(picojson::string_type, false);
return picojson::_parse_string(out_->get<std::string>(), in);
}
bool parse_array_start() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
*out_ = picojson::value(picojson::array_type, false);
return true;
}
template <typename Iter>
bool parse_array_item(picojson::input<Iter> &in, size_t) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
picojson::array &a = out_->get<picojson::array>();
a.push_back(picojson::value());
ParseSceneContext ctx(&a.back());
return picojson::_parse(ctx, in);
}
bool parse_array_stop(size_t) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return true;
}
bool parse_object_start() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
*out_ = picojson::value(picojson::object_type, false);
return true;
}
template <typename Iter>
bool parse_object_item(picojson::input<Iter> &in, const std::string &key)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::cout << key << std::endl;
picojson::object &o = out_->get<picojson::object>();
ParseSceneContext ctx(&o[key]);
return picojson::_parse(ctx, in);
}
};
What am I missing?
Another weird thing I find with the streaming example is that it shows that it inherits from picojson::deny_parse_context but none of its methods are ever declared as virtual.
Please ignore this, I did a straight copy of the streaming example which can leave things in a "bad" state but after implementing all methods and "consuming" the remaining bits that needed to be read it works well.