Commit 4ef1ff4f authored by Philipp A. Hartmann's avatar Philipp A. Hartmann

GenericValue::CopyFrom: add option to force copying of strings

Copying the result of an in-situ parsing into another value/document
currently requires that the original buffer - still holding the strings
from the parsing, outlives the  destination object as well.

In order to obtain a "full" copy of a GenericValue, this commit adds
an optional flag `copyConstStrings` to `CopyFrom`, which then forces
to take a copy of all embedded strings in the source value.

This solves the problem discussed in #962.
parent 0033268c
...@@ -615,10 +615,11 @@ public: ...@@ -615,10 +615,11 @@ public:
\tparam SourceAllocator allocator of \c rhs \tparam SourceAllocator allocator of \c rhs
\param rhs Value to copy from (read-only) \param rhs Value to copy from (read-only)
\param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
\param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
\see CopyFrom() \see CopyFrom()
*/ */
template <typename SourceAllocator> template <typename SourceAllocator>
GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) { GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
switch (rhs.GetType()) { switch (rhs.GetType()) {
case kObjectType: { case kObjectType: {
SizeType count = rhs.data_.o.size; SizeType count = rhs.data_.o.size;
...@@ -645,7 +646,7 @@ public: ...@@ -645,7 +646,7 @@ public:
} }
break; break;
case kStringType: case kStringType:
if (rhs.data_.f.flags == kConstStringFlag) { if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
data_.f.flags = rhs.data_.f.flags; data_.f.flags = rhs.data_.f.flags;
data_ = *reinterpret_cast<const Data*>(&rhs.data_); data_ = *reinterpret_cast<const Data*>(&rhs.data_);
} }
...@@ -850,12 +851,13 @@ public: ...@@ -850,12 +851,13 @@ public:
\tparam SourceAllocator Allocator type of \c rhs \tparam SourceAllocator Allocator type of \c rhs
\param rhs Value to copy from (read-only) \param rhs Value to copy from (read-only)
\param allocator Allocator to use for copying \param allocator Allocator to use for copying
\param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
*/ */
template <typename SourceAllocator> template <typename SourceAllocator>
GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) { GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs)); RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
this->~GenericValue(); this->~GenericValue();
new (this) GenericValue(rhs, allocator); new (this) GenericValue(rhs, allocator, copyConstStrings);
return *this; return *this;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment