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

GenericValue: add copy constructor and CopyFrom #20

Merged
merged 3 commits into from
Jun 26, 2014

Conversation

pah
Copy link
Contributor

@pah pah commented Jun 25, 2014

To allow deep copying from an existing GenericValue, an explicit "copy constructor" (with required Allocator param) and a CopyFrom assignment function are added.

  Document d; Document::AllocatorType& a = d.GetAllocator();
  Value v1("foo");
  // Value v2(v1); // not allowed

  Value v2(v1,a);                             // make a copy
  RAPIDJSON_ASSERT(v1.IsString());            // v1 untouched
  d.SetArray().PushBack(v1,a).PushBack(v2,a);
  RAPIDJSON_ASSERT(v1.Empty() && v2.Empty());

  v2.CopyFrom(d,a);                           // copy whole document
  RAPIDJSON_ASSERT(d.IsArray() && d.Size());  // d untouched
  v1.SetObject().AddMember( "array", v2, a );
  d.PushBack(v1,a);

The strings in the source value are copied, if and only if they have been allocated as a copy during their construction (determined by kCopyFlag). This is needed to avoid double free()s or problems with differing lifetimes of the allocated string storage.

Additionally, the Handler implementation in GenericDocument is made private again, restricting access to GenericReader and GenericValue.

(resubmitted #16 against master)

pah added 3 commits June 25, 2014 18:09
Instead of always just shallowly referencing the potentially allocated
strings when calling the Handler::String function, request a copy in
case the string has been allocated from an Allocator before.

This is necessary to avoid double free()s of the string memory,
especially when using the Handler to create a deep copy of a Value.

The explicit comparison against '0' is done to suppress the warning
C4800 on MSVC, see pah/rapidjson#5.
To allow deep copying from an existing GenericValue, an
explicit "copy constructor" (with required Allocator param)
and an "CopyFrom" assignment function are added.

  Document d; Document::AllocatorType& a = d.GetAllocator();
  Value v1("foo");
  // Value v2(v1); // not allowed

  Value v2(v1,a);                             // make a copy
  RAPIDJSON_ASSERT(v1.IsString());            // v1 untouched
  d.SetArray().PushBack(v1,a).PushBack(v2,a);
  RAPIDJSON_ASSERT(v1.Empty() && v2.Empty());

  v2.CopyFrom(d,a);                           // copy whole document
  RAPIDJSON_ASSERT(d.IsArray() && d.Size());  // d untouched
  v1.SetObject().AddMember( "array", v2, a );
  d.PushBack(v1,a);

Additionally, the Handler implementation in GenericDocument is made
private again, restricting access to GenericReader and GenericValue.
This commit adds some simple tests for the deep-copying
of values, either based on the explicit constructor, or
the CopyFrom function.

It uses the CrtAllocator to test for possible double-free
errors due to insufficient copying.
miloyip added a commit that referenced this pull request Jun 26, 2014
GenericValue: add copy constructor and CopyFrom
@miloyip miloyip merged commit 9c6f7b9 into Tencent:master Jun 26, 2014
@pah pah deleted the feature/value-copy-from branch June 26, 2014 07:53
pah added a commit to pah/rapidjson-upstream that referenced this pull request Jun 27, 2014
Another instance of casting away constness via C-style cast
has been missed (introduced by Tencent#20).
@pah pah mentioned this pull request Feb 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants