Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to cache a json object's pointer into a map? #1180

Closed
yulinwei9 opened this issue Jul 31, 2018 · 4 comments
Closed

How to cache a json object's pointer into a map? #1180

yulinwei9 opened this issue Jul 31, 2018 · 4 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@yulinwei9
Copy link

yulinwei9 commented Jul 31, 2018

Hi, I have JSON file

{
    "type":"design",
    "guid":"86a71c67-dd7b-4bdd-9104-fca9ab12f953",
    "children":[
        {
            "type":"folder",
            "guid":"2c2af70d-8b05-4453-a0e1-8c233b0f7de1",
            "children":[
                {
                    "type":"resource",
                    "guid":"b92fda27-53a8-43aa-a240-fce65762462f"
                }
            ]
        },
        {
            "type":"resource",
            "guid":"b18aa915-d268-48b7-83c9-75ee35ab6e37"
        },
        {
            "type":"resource",
            "guid":"98f8626e-964d-4ca1-b3b6-45eff9c600c8"
        }
    ]
}

It is generated by CJSON by the following code

bool BubbleWriter::AppendNode(const UTF8String& parentId)
{
        std::map<UTF8String, cJSON*>::iterator it = m_content.find(parentId);
        if (it == m_content.end())
            return false;

        cJSON* parent = it->second;
        cJSON* pChildren = cJSON_GetObjectItem(parent, "children");
        if (NULL == pChildren)
        {
            pChildren = cJSON_CreateArray();
            cJSON_AddItemToObject(parent, "children", pChildren);
        }

        cJSON* pChild = cJSON_CreateObject();
        cJSON_AddItemToArray(pChildren, pChild);
        ...
 }

m_content is a map to cache the GUID and its corresponding json object, the function AppendNode() could append an object into a json array but the function does not know how deep is the current object in the json file.

I would like to replace CJSON to json.hpp, but I don't know how to cache a json object into a map as value by json.hpp. Any ideas?

@nlohmann
Copy link
Owner

You can just use std::map<std::string, nlohmann::json>.

@yulinwei9
Copy link
Author

yulinwei9 commented Jul 31, 2018

The title of my question might not accurate enough, actually I would like to know how to cache a json object's pointer into a map, like std::map<std::string, nlohmann::json *>
Because I want to directly append child object under the cached objects, so that the original json object could be updated accordingly.

bool BubbleWriter::AppendNode(const UTF8String& parentId)
{
    std::map<UTF8String, json*>::iterator it = m_content.find(parentId);
    if (it == m_content.end())
        return false;

    json * parent = it->second;
    
    json pChild;
    pChild["type"] = "resource";
    pChild["guid"] = guid.Value();
    (*parent)["chirldren"].push_back(pChild);
    
    m_content.insert(make_pair(guid, ???));
    ...
}

The code above is my changing based on previous CJSON logic, but I don't know how to write in the ??? place.
I tried &(*parent)["children"].back(), but the cached value would be changed if I push_back another object.
I also noticed the API get() / get_ptr() might meet my requirements, but I find the warning: Writing data to the pointee of the result yields an undefined state.

@yulinwei9 yulinwei9 changed the title How to cache a json object into a map as value? How to cache a json object's pointer into a map? Jul 31, 2018
@gregmarr
Copy link
Contributor

You can cache a pointer to a json object in the map without a problem. The problem that you actually have is caching a pointer to an element of a vector whose size may change during the lifetime of the map. That is something that you can't do unless you've reserved enough space in the vector ahead of time such that it can never reallocate. What you could do is instead of caching a pointer to the object, cache a pointer to the parent and an index within the vector. So instead of std::map<std::string, nlohmann::json *>, you have std::map<std::string, std::pair<nlohmann::json *, size_t>>.

@yulinwei9
Copy link
Author

@gregmarr Thank you so much! It works well to me.

@nlohmann nlohmann added kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation labels Aug 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

3 participants