2012-06-19 56 views
4

我在Linux上運行的基於QT的單線程控制檯應用程序使用Boost解析JSON字符串,除非接收到非常大的JSON塊時,它通常工作正常。我有一個大小爲160kb左右的有效JSON(!),當我試圖解析它時,對Boost的JSON解析器的調用永遠不會返回。我已經離開了相當長的一段時間。如果我隨後使用調試器中斷,我的應用程序就閒置在它的消息循環中,就好像什麼都沒有發生。該調用不會引發異常。除了它的大尺寸外,沒有什麼值得注意的JSON - 它格式良好,完全由ASCII字符組成。調用Boost JSON解析器永不返回

如何才能執行簡單地「放棄」並返回到QT消息循環?

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 
    } 
} 
+0

第一件事我會嘗試是去除QT從這個等式中構建出一個只需提升的小程序。如果仍然失敗,我會把你的輸入源分成更小的樣本,直到找到失敗的地方。 –

+1

當您有一個簡單的,自包含的程序顯示相同的行爲時,您可以在http://svn.boost.org創建一張票據,並將程序和輸入文件附加到票據上。 –

回答

2

首先,我同意上面的兩條評論:儘量減少你的程序。其次,我會嘗試檢查Qt(stl,boost,這個特定的版本)是否可以處理大的字符串。確保你的分析器得到整個字符串。

第三,我會使用ostringstream而不是sstream。 :)

根據boost文檔,似乎解析器返回錯誤的唯一方法是通過返回property_tree中的錯誤信息。如果它一直持續閱讀,這可能意味着它正在閱讀超出實際JSON數據的垃圾並陷入其中。

最後,read_json可以接受文件名,所以爲什麼要讀取文件和創建一個流的麻煩?你爲什麼不試試這個:

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 

我剛剛完成與JSON文件400KB大一個小的測試,它工作得很好:

#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; 
    }