2016-07-29 91 views
0

我在使用下面的方法時遇到了一些麻煩,我需要一些幫助來弄清楚我做錯了什麼。Rapidjson返回對文檔值的引用

我想返回對文檔中的值的引用。我從函數外部傳遞Document,所以當我讀入一個json文件時,我不會「失去它」。

const rapidjson::Value& CTestManager::GetOperations(rapidjson::Document& document) 
{ 
    const Value Null(kObjectType); 

    if (m_Tests.empty()) 
     return Null; 

    if (m_current > m_Tests.size() - 1) 
     return Null; 

    Test& the_test = m_Tests[m_current]; 

    CMyFile fp(the_test.file.c_str()); // non-Windows use "r" 
    if (!fp.is_open()) 
     return Null; 

    u32 operations_count = 0; 

    CFileBuffer json(fp); 
    FileReadStream is(fp.native_handle(), json, json.size()); 

    if (document.ParseInsitu<kParseCommentsFlag>(json).HasParseError()) 
    { 
     (...) 
    } 
    else 
    { 
     if (!document.IsObject()) 
     { 
      (...) 
     } 
     else 
     { 
      auto tests = document.FindMember("td_tests"); 
      if (tests != document.MemberEnd()) 
      { 
       for (SizeType i = 0; i < tests->value.Size(); i++) 
       { 
        const Value& test = tests->value[i]; 

        if (test["id"].GetInt() == the_test.id) 
        { 
         auto it = test.FindMember("operations"); 
         if (it != test.MemberEnd()) 
         { 
          //return it->value; is this legitimate? 
          return test["operations"]; 
         } 

         return Null; 
        } 
       } 
      } 
     } 
    } 

    return Null; 
} 

對此我打電話是這樣的:

Document document; 
auto operations = TestManager().GetOperations(document); 

當我檢查函數內部的test["operations"]值我所看到的一切我希望(從居所代碼中刪除調試代碼)。

當我檢查函數外的返回值時,我可以看到它是一個數組(我期望)。數組中的成員數也是正確的,但打印出來時,我只能看到垃圾。當我將值打印到方法內部的字符串時,我得到了我期望的結果(即格式良好的json),但是當我在所有鍵外部顯示爲「IIIIIIII」時,它的值不是' t串顯示正確。

rapidjson::StringBuffer strbuf2; 
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer2(strbuf2); 
    ops->Accept(writer2); 

由於這沒有工作,我決定改變方法接受一個值作爲參數,做一個深拷貝到像這樣

u32 CTestManager::GetOperationsEx(rapidjson::Document& document, rapidjson::Value& operations) 
{ 
    (...) 

    if (document.ParseInsitu<kParseCommentsFlag>(json).HasParseError()) 
    { 
     (...) 
    } 
    else 
    { 
     if (!document.IsObject()) 
     { 
      (...) 
     } 
     else 
     { 
      auto tests = document.FindMember("tests"); 
      if (tests != document.MemberEnd()) 
      { 
       for (SizeType i = 0; i < tests->value.Size(); i++) 
       { 
        const Value& test = tests->value[i]; 

        if (test["id"].GetInt() == the_test.id) 
        { 
         const Value& opv = test["operations"]; 

         Document::AllocatorType& allocator = document.GetAllocator(); 
         operations.CopyFrom(opv, allocator); //would Swap work? 
         return operations.Size(); 
        } 
       } 
      } 
     } 
    } 

    return 0; 
} 

哪個我打電話是這樣的:

Document document; 
Value operations(kObjectType); 
u32 count = TestManager().GetOperationsEx(document, operations); 

但是...我得到同樣的事情!!!!

我知道這將是愚蠢的東西,但我不能把手放在上面!

任何想法?

回答

0

這種情況下的問題在於使用ParseInSitu。當存在GetOperations中的任何一個時,​​丟失範圍並被清理。由於json在緩衝區到達文件時正在被解析,因此數據也是如此。