5

My QT-based single-threaded console app running on Linux parses JSON strings using Boost, and it works fine ordinarily, except when receiving very large chunks of JSON. I have a piece of valid JSON around 160kb in size (!) and when I attempt to parse it, the call to Boost's JSON parser never returns. I've left it a considerable time. If I subsequently break in using the debugger, my app is idly sitting in its message loop, as though nothing happened. The call throws no exceptions. There's nothing noteworthy about the JSON except for its large size - it's well-formed and entirely composed of ASCII characters.

How can execution simply "give up" and return to the QT message loop?

void IncomingRequestHandler::OnRequest(const QString& message) { try { std::stringstream ss; ss << message.toStdString(); boost::property_tree::ptree requestObject; cout << "Before read_json" << endl; // Gets here boost::property_tree::json_parser::read_json(ss, requestObject); cout << "After read_json" << endl; // Never gets here // ... Some other code ... } catch (const boost::property_tree::json_parser::json_parser_error& e) { cout << "Invalid JSON" << endl; // Never gets here } catch (const std::runtime_error& e) { cout << "Invalid JSON" << endl; // Never gets here } catch (...) { cout << "Invalid JSON" << endl; // Never gets here } } 
2
  • First thing I would try to is to remove QT from the equation and build a small program that uses just boost. If that still fails then I would take your input source and split it into smaller samples until you find where it fails. Commented Jun 19, 2012 at 17:53
  • 1
    And when you have a simple, self contained program that shows the same behavior, you create a ticket at svn.boost.org and attach the program and the input file to the ticket. Commented Jun 20, 2012 at 2:18

1 Answer 1

2

First, I agree with two comments above: try to minimize your program.

Second, I would try to check whether Qt (stl, boost, this particular version of whatever) can handle strings that large. Make sure your parser is getting the whole string.

Third, I would use ostringstream rather than sstream. :)

According to boost documentation, it seems that the only way the parser returns an error is by returning error information in your property_tree. If it continues reading forever, it probably means that it's reading garbage beyond the actual JSON data and gets stuck on it.

Finally, read_json can accept the file name, so why bother with reading the file and creating a stream? Why don't you try this:

 boost::property_tree::ptree requestObject; cout << "Before read_json" << endl; // Gets here boost::property_tree::json_parser::read_json(jsonFileName.toStdString(), requestObject); cout << "After read_json" << endl; // Never gets here 

I've just performed a little test with JSON file 400Kb big, and it works just fine:

 #include <iostream> #include <string> #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/json_parser.hpp> using namespace std; int main(int argc, char* argv[]) { string infname = argv[1]; boost::property_tree::ptree requestObject; cout << "Before read_json" << endl; // Gets here boost::property_tree::json_parser::read_json(infname, requestObject); cout << "After read_json" << endl; // Works fine return 0; } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.