Rapidjson 返回对文档值的引用
Rapidjson returning reference to Document Value
我在使用以下方法时遇到了一些问题,我需要一些帮助来弄清楚我做错了什么。
我想 return 引用文档中的值。我从函数外部传递文档,这样当我将 json 文件读入其中时,我不会 "lose it".
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"]
的值时,我可以看到我期望的一切(调试代码从居留代码中删除)。
当我检查函数外部的 returned 值时,我可以看到它是一个数组(我希望如此)。数组中的成员计数也是正确的,但是当打印出来时,我只看到垃圾。
当我 "print" 方法内的字符串的值时,我得到了我所期望的(即格式正确的 json),但是当我在外部执行时,所有键都显示为 "IIIIIIII" 并且不是字符串的值会正确显示。
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);
但是...我得到了同样的东西!!!!
我知道这会很傻,但我不能动手!
有什么想法吗?
本例中的问题出在 ParseInSitu
的使用上。当任何 GetOperations
存在时,CFileBuffer
就会失去作用域并被清除。因为当文件缓冲区消失时 json 正在原位解析,所以数据也消失了。
我在使用以下方法时遇到了一些问题,我需要一些帮助来弄清楚我做错了什么。
我想 return 引用文档中的值。我从函数外部传递文档,这样当我将 json 文件读入其中时,我不会 "lose it".
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"]
的值时,我可以看到我期望的一切(调试代码从居留代码中删除)。
当我检查函数外部的 returned 值时,我可以看到它是一个数组(我希望如此)。数组中的成员计数也是正确的,但是当打印出来时,我只看到垃圾。
当我 "print" 方法内的字符串的值时,我得到了我所期望的(即格式正确的 json),但是当我在外部执行时,所有键都显示为 "IIIIIIII" 并且不是字符串的值会正确显示。
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);
但是...我得到了同样的东西!!!!
我知道这会很傻,但我不能动手!
有什么想法吗?
本例中的问题出在 ParseInSitu
的使用上。当任何 GetOperations
存在时,CFileBuffer
就会失去作用域并被清除。因为当文件缓冲区消失时 json 正在原位解析,所以数据也消失了。