From 4ef1ff4fbac491676702cf9e4f300d504d56cee9 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Thu, 18 May 2017 19:08:23 +0200 Subject: [PATCH] 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. --- include/rapidjson/document.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index c12820e..0d13b60 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -615,10 +615,11 @@ public: \tparam SourceAllocator allocator of \c rhs \param rhs Value to copy from (read-only) \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() */ template - GenericValue(const GenericValue& rhs, Allocator& allocator) { + GenericValue(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings = false) { switch (rhs.GetType()) { case kObjectType: { SizeType count = rhs.data_.o.size; @@ -645,7 +646,7 @@ public: } break; case kStringType: - if (rhs.data_.f.flags == kConstStringFlag) { + if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) { data_.f.flags = rhs.data_.f.flags; data_ = *reinterpret_cast(&rhs.data_); } @@ -850,12 +851,13 @@ public: \tparam SourceAllocator Allocator type of \c rhs \param rhs Value to copy from (read-only) \param allocator Allocator to use for copying + \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer) */ template - GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator) { + GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings = false) { RAPIDJSON_ASSERT(static_cast(this) != static_cast(&rhs)); this->~GenericValue(); - new (this) GenericValue(rhs, allocator); + new (this) GenericValue(rhs, allocator, copyConstStrings); return *this; }