Rapidjson返回对文档值的引用

时间:2016-07-29 10:46:53

标签: c++ json rapidjson

我在使用以下方法时遇到了一些麻烦,我需要一些帮助才能弄清楚我做错了什么。

我想在文档中返回对Value的引用。我从函数外部传递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"]的值时,我可以看到我期望的一切(调试代码从abode代码中删除)。

当我检查函数外部的返回值时,我可以看到它是一个数组(我期望)。数组中的成员计数也是正确的,但是当打印出来时,我只会看到垃圾。

当我将Value“打印”到方法内的字符串时,我得到了我期望的结果(即格式良好的json),但是当我在外面执行它时,所有键都显示为“IIIIIIII”,而值不是字符串显示正确。

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

由于这不起作用,我决定更改方法以接收Value作为参数并像这样深入复制

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);

但是......我得到同样的东西!!!!

我知道这将是一件愚蠢的事情,但我不能把它放在手上!

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这种情况下的问题在于使用ParseInSitu。当任何GetOperations存在时,CFileBuffer会丢失范围并进行清理。因为当文件的缓冲区进入原位时会解析json,所以数据也是如此。