I've only been using the jsonCPP lib for a couple of month now. Im trying to add and remove an object in an array. Ive used a number of different JSON libs on different platforms but I'm finding it very difficult to work with JsonCPP.
Here is the Json:
{ "type": "Disc",
"media": "DVD",
"adapter": "DVDCodecs",
"transportControls" : [
{"Action":"Left", "ActionCode" : "1a"},
{"Action":"Right", "ActionCode" : "2a"},
{"Action":"Up", "ActionCode" : "1b"},
{"Action":"Down", "ActionCode" : "4c"},
{"Action":"Center", "ActionCode" : "5e"},
{"Action":"OK", "ActionCode" : "5a"},
{"Action":"SubTitles", "ActionCode" : "3b"},
{"Action":"SubTitlesLang", "ActionCode" : "7d"},
{"Action":"Audio", "ActionCode" : "7a"},
{"Action":"Angle", "ActionCode" : "6a"},
{"Action":"Next", "ActionCode" : "6c"},
{"Action":"Previous", "ActionCode" : "8b"},
{"Action":"DVDMenu", "ActionCode" : "8c"},
{"Action":"Search", "ActionCode" : "8d"},
{"Action":"Region", "ActionCode" : "3a"},
{"Action":"Display", "ActionCode" : "2e"},
{"Action":"RootMenu", "ActionCode" : "6b"},
{"Action":"FastForward", "ActionCode" : "81"},
{"Action":"Rewind", "ActionCode" : "8b"},
{"Action":"FrameForward", "ActionCode" : "8c"},
{"Action":"Parking"},
{"Action":"Seekable"}
]
}
I've been trying to add and remove a objectValue to and from the transportControls array. To add an object I have been doing this:
Json::Value addObj;
Json::Reader reader;
reader.parse("{\"Action\":\"BlueButton\", \"ActionCode\" : \"9a\"}", addObj );
root["transportControls"].append( addObj );
Which seems to work well. If there is a more elegant way of doing this I'd like to know that to.
My problem is how do I remove it after I added it. I can remove all the members in the object but that doesn't actually seem to remove the object from the arrayValue map.
What is the "best practice" way to remove an Object Value from an Array Value using JsonCPP?
I finally had some time to dig into the source code and the easy answer is - No.
An arrayValue object is really just an ObjectValue defined as an std::map. If you call std::map::erase() on an object in the map you will interrupt the consecutive sequence index_ Key for the array. Sdt::Maps don’t allow you to edit the Key in the map so you would have to move all the Value object pointers in the map up one and delete the last entry before end() to actually "delete" the object.
That sounds like a lot of overhead. Why do I have to move everything up? ...you may ask. Because the JsonCPP Writer Classes use the map[] index to print out the values. If it doesn't find the key ( because of a gap in the series) it returns nullValue for that index. That’s what you see when you call
root.toStyledString()
to convert back to a string. After a while you have these "null," all over the place. From a Value object, if you’re not calling the const version (const Value &operator[]( ArrayIndex index ) const;
)you will insert the nullValue object into the Array. The parser uses theValue::operator[]( ArrayIndex index )
version to insert new dafaultValue objects into the map while its tokenizing your JSON.Answer: No. You can’t delete an object from an arrayValue without making code changes to clean up the map.
More info here: Changing the key of an element inside a std::map
There is now
removeIndex()
, but as tommygr says, it is an expensive operation in the current implementation.