-
Notifications
You must be signed in to change notification settings - Fork 1
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
DeepCopy? CMake? #1
Comments
Thanks for your suggestions (and for mentioning this fork in the upstream issue tracker).
I'm not sure. In general, deep-copying is a valuable addition, but I don't like the API of this proposal. A couple of weeks ago, I have built a similar solution which I didn't publish on GitHub so far. I have now pushed it and opened the pull-request #2 for it. What do you think? Adding a @scanlime, what do you think? Is there an upstream issue reported for this?
I would certainly accept and merge the Cmake integration. Although I don't use the Rapidjson build infrastructure at all (instead maintain the Rapidjson sources directly within our projects), this may be useful for some people. I can see the value of the Git submodules approach, but I want to follow upstream on this (see |
Your version of DeepCopy looks good! CMake integration isn't as important as I've initially thought, because it's mostly used to build the unit tests. With your Tencent/rapidjson#1 I'd rather wait for Milo reaction. |
Is this DeepCopy in rapidjson version 1.1.0? Is there a good example of it? Otherwise I might just use http://stackoverflow.com/questions/22707814/perform-a-copy-of-document-object-of-rapidjson the copyDocument comment/answer. |
CopyFrom doesn't look like a good solution for getting a deep copy to me. I'd have to iterate over my entire (very large) json, store each value separately into a new value object, then use copyFrom. The example you show is overly simplified.
It might be easier to just re-parse it.
Yes, all of the changes in this repository are upstreamed by now. DeepCopy is called CopyFrom in the upstream API:You can find the CopyFrom documentation here and an example in the tutorial.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Just use something like Document src;
src.Parse(...);
Document dst;
dst.CopyFrom(src, dst.GetAllocator());
// dst holds the same values (recursively) as src Submitted upstream by myself as Tencent/rapidjson#20. |
Thank you so much!! I hadn't realized that. It's much better than the copy/re-parse thing I was doing.
CopyFrom already does the traversal, as does the explicit copy constructor (which requires an allocator for the allocation of the string and value copies).Just use something likeDocument src;
src.Parse(...);
Document dst;
dst.CopyFrom(src, dst.GetAllocator());
// dst holds the same values (recursively) as srcSubmitted upstream by myself as Tencent/rapidjson#202.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
I'm not sure if you would have time to answer another rapidjson question. I'm trying to retrieve nested json values like they show in the rapidjson tutorial link. The only way I can do that is by using a string buffer, but that doesn't really return what the value of m_x is, it just returns the contents of m_position, which is a string (not good use of json to get value).
My json looks like this:{ "type": "SlxROI", "m_position": { "m_x": 16, "m_y": 32, "m_z": 0 }, "m_size": { "m_widt h ":64," m_height ":128," m_depth ":3}}
This is what it looks like as a c string:static const std::string& JSON2() { static const std::string j = "{\"type\":\"SlxROI\",\"m_position\":{\"m_x\":16,\"m_y\":32,\"m_z\":0},\"m_size\":{\"m_width\":64,\"m_height\":128,\"m_depth\":3}}"; return j; }
I know it's valid because it doesn't return an error when I parse it.
rapidjson::StringStream strStream(JSON2().c_str());rapidjson::Document origDocument;
rapidjson::ParseResult result = origDocument.ParseStream(strStream);
assert(newDocument.IsObject());rapidjson::StringBuffer sb;rapidjson::Writer<rapidjson::StringBuffer> writer (sb);newDocument["m_position"].Accept(writer);std::string temp = sb.GetString(); //this works and I see the nested part inside m_position, but I'm not sure how to retrieve m_x from this without putting the buffer into a rapidjson document
//it would be better to retrieve specific value in nested json but it's not workingrapidjson::Value& mpos = newDocument["m_position"];assert(mpos.IsArray()); //this doesn't work (asserts), but this is what people do in what I'm seeing online....shouldn't it?assert(newDocument.HasMember("m_x")); //this doesn't work either...assert
How can I retrieve the nested value? All examples I'm seeing aren't working, and I'm assuming it's because of that rapidjson_disableif_return, although it does seem to be showing a bad pointer (n).
I was looking at this example (Tencent/rapidjson#336), but what they are discussing doesn't seem to work, when trying to retrieve specific things (see above):Value& parameterB = document["parameterB"];
assert(parameterB.IsArray());
I was looking at this too (http://stackoverflow.com/questions/40816266/rapidjson-how-to-receive-member-object-when-using-findmember)but for me, it doesn't seem to be the case:rapidjson::Pointer keyPointer("m_position");if(newDocument.IsArray()) { //it's not an array so doesn't fall in here for(rapidjson::SizeType i=0; i<newDocument.Size(); i++) { if (rapidjson::Value* m_pos = keyPointer.Get(newDocument[i])) { assert(m_pos->HasMember("m_x")); } }}
I'm not seeing how to retrieve the value of the nested item. I can't get it to work no matter what I try. Any help would be greatly appreciated.
Thank you very much.
CopyFrom already does the traversal, as does the explicit copy constructor (which requires an allocator for the allocation of the string and value copies).Just use something likeDocument src;
src.Parse(...);
Document dst;
dst.CopyFrom(src, dst.GetAllocator());
// dst holds the same values (recursively) as srcSubmitted upstream by myself as Tencent/rapidjson#202.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Hi Michele, I would appreciate if you could try adding some formatting to your answer. It's very hard to parse it here. Starting from your original JSON: {
"type": "SlxROI",
"m_position": { "m_x": 16, "m_y": 32, "m_z": 0 },
"m_size": { "m_width ":64," m_height ":128," m_depth ":3}
} you can access the using namespace rapidjson;
Document origDocument;
// ...
assert( origDocument.IsObject() && origDocument.HasMember("m_position");
Value& m_pos = origDocument["m_position"];
assert( m_pos.IsObject() );
for (Value::ConstMemberIterator itr = m_pos.MemberBegin(); itr != m_pos.MemberEnd(); ++itr)
{
printf("Value of 'm_position' member '%s' is %u\n",
itr->name.GetString(), itr->value.GetUint());
} Dereferencing the Hope that helps, |
Thank you so much Philipp!! That is very helpful. Have a great weekend!
Hi Michele,I would appreciate if you could try adding some formatting to your answer. It's very hard to parse it here.Starting from your original JSON:{
"type": "SlxROI",
"m_position": { "m_x": 16, "m_y": 32, "m_z": 0 },
"m_size": { "m_width ":64," m_height ":128," m_depth ":3}
}you can access the m_position member (assuming you know it's there), via using namespace rapidjson;
Document origDocument;
// ...
assert( origDocument.IsObject() && origDocument.HasMember("m_position");
Value& m_pos = origDocument["m_position"];
assert( m_pos.IsObject() );
for (Value::ConstMemberIterator itr = m_pos.MemberBegin(); itr != m_pos.MemberEnd(); ++itr)
{
printf("Value of 'm_position' member '%s' is %u\n",
itr->name.GetString(), itr->value.GetUint());
}Dereferencing the ConstMemberIterator returns a Member object, which essentially contains a name and a value element.Hope that helps,
Philipp—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Thanks a lot. If I want to copy a node at this point and not a document, it looks like GetAllocator can't be used for that...Is there another way to copy a Value?
static void copyValue(rapidjson::Value & newNode, const rapidjson::Value & originalNode) {
//better way to copy std::cout << "SlxJson2Impl::copyValue...." << std::endl; newNode.CopyFrom(originalNode, newNode.GetAllocator()); }
CopyFrom already does the traversal, as does the explicit copy constructor (which requires an allocator for the allocation of the string and value copies).Just use something likeDocument src;
src.Parse(...);
Document dst;
dst.CopyFrom(src, dst.GetAllocator());
// dst holds the same values (recursively) as srcSubmitted upstream by myself as Tencent/rapidjson#202.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
By the way, I want to copy the Value without making a Document. We are trying to keep the DOM concept out of our design for now (except for error checking) and just create Nodes/Values. That would be great if you could let me know a good way to do this. I'm sure you would have a copy concept for this like you do for the Document.
Thanks a lot. If I want to copy a node at this point and not a document, it looks like GetAllocator can't be used for that...Is there another way to copy a Value?
static void copyValue(rapidjson::Value & newNode, const rapidjson::Value & originalNode) {
//better way to copy std::cout << "SlxJson2Impl::copyValue...." << std::endl; newNode.CopyFrom(originalNode, newNode.GetAllocator()); }
CopyFrom already does the traversal, as does the explicit copy constructor (which requires an allocator for the allocation of the string and value copies).Just use something likeDocument src;
src.Parse(...);
Document dst;
dst.CopyFrom(src, dst.GetAllocator());
// dst holds the same values (recursively) as srcSubmitted upstream by myself as Tencent/rapidjson#202.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
You can't have a |
How would I add a name value pair without a document object that I'm keeping? I see AddMember used , http://stackoverflow.com/questions/24204417/rapidjson-change-key-to-another-value, but they have a document they are adding it to. I just want a Value object that I add a name value pair.
This doesn't seem to do the trick:Value val = new rapidjson::Value(n, v, GenericValue::GetAllocator());
I don't see an example of what I need anywhere.
By the way, I want to copy the Value without making a Document. We are trying to keep the DOM concept out of our design for now (except for error checking) and just create Nodes/Values. That would be great if you could let me know a good way to do this. I'm sure you would have a copy concept for this like you do for the Document.
You can't have a Value without an Allocator. With an Allocator, you can use the same concept even without a Document. A Document is more or less just a combination of an allocator and a (root) Value.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
As I said: You need to supply an allocator. The simplest solution is to use the typedef rapidjson::GenericValue<rapidjson::UTF8<>, rapidjson::CrtAllocator> JsonValue;
rapidjson::CrtAllocator& jsonAllocator() {
static rapidjson::CrtAllocator instance;
return instance;
}
// use jsonAlloctor() wherever you need one
JsonValue val = JsonValue( n, v, jsonAllocator() );
|
Thanks for replying. Do you mean GenericValue instead of rapidjson::Value? When I use Value, I'm getting that Value has no template argument list. Also, I'm not finding what rapidjson::Allocator you're using. I see it being used in document.h, but I #included all the same things in document, and still get that rapidjson namespace has no member Allocator. Is it not available externally?
Thanks!!!
How would I add a name value pair without a document object that I'm keeping?
As I said: You need to supply an allocator.
The simplest solution is to use the CrtAllocator instead of the MemoryPoolAllocator through a simple global instance:typedef rapidjson::Value<rapidjson::UTF8<>, rapidjson::CrtAllocator> JsonValue;
rapidjson::Allocator& jsonAllocator() {
static rapidjson::Allocator instance;
return instance;
}
// use jsonAlloctor() wherever you need one
JsonValue val = JsonValue( n, v, jsonAllocator() );
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Yes, obviously. I already replaced |
If I want to Deep Copy a JsonValue, how would that be? I'm trying I tried this too: Any ideas? |
It looks like you have defined |
Cool! It seems to compile with once I made copyValue method not be static anymore. It could use jsonAllocator(). Thanks! |
I'm trying to take an existing object, and get the name/value pair out of it to use in a new object. The object was created elsewhere: JsonValue name = JsonValue("name", jsonAllocator()); Then elsewhere I need to get value out to re-add it with addMember. Is there a good way to do this? Like, I have m_node, which is a kObjectType, and want to add the name/value pair in m_jsonVal to it. //So I'm trying //is there an easy way to do that? It would be great to do this, but this isn't doing the trick either: |
I think, these type of questions are better suited for Stackoverflow, as I can't give hands-on support here.
Why don't you simply do (assuming you don't need m_jsonVal.AddMember( iter->name, iter->value, jsonAllocator() ); |
I'm pretty sure, you messed up the value earlier due to the move semantics. You should read up on this. |
There's working hard and there's working efficiently. If you're set on making the rapidjson work in this particular way, instead of adjusting the algorithm, then follow the best practices by making a test case (aka http://stackoverflow.com/help/mcve) and using a debugger. Right now you remind me of someone trying to find a black cat in a dark room and asking others to help him do that. Turn on the light! Isolate the problem with MCVE, isolate it further by getting a debugging backtrace from that MCVE, then let the others help you. If you can't do those simple things, then maybe you ought to loose your job and do something else for a living, if you don't mind me saying. |
I'm trying to make my code more like the uses I'm seeing online, like not using a class JsonValue pointer. I'm trying to use a class document, and add name/value pairs to that. When I was reading about move semantics, the examples they give similar to my way say "without sufficient lifetime". I see this example , which is similar to what I need to do and would be ok to adopt in my algorithm, but what he said to do Document tempDoc(*m_document.GetAllocator()), is not compiling. Illegal indirection. VS says no operator * matches these operands. |
I don't know about Philipp, but for me a bunch of code that wasn't organized into MCVE is a non-starter. |
Free advice.
Together this should greatly increase the chance of getting an answer. |
Hi, Philipp!
Would you mind accepting a pull request of this patch
https://github.com/scanlime/rapidjson/commit/0c69df5ac098640018d9232ae71ed1036c692187 ?
Also, what do you think of Git and CMake patches at https://github.com/rjeczalik/rapidjson ? Would it be feasible to integrate these in order to have both your fixes and Git submodules and CMake?
The text was updated successfully, but these errors were encountered: