mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2025-05-04 00:08:21 +02:00
Fix Value::copyPayload() and Value::copy() (#704)
Value copy constructor shares the same code with Value::copy() and Value::copyPayload(). New Value::releasePayload() is used to free payload memory. Fixes: #704
This commit is contained in:
parent
2f227cb122
commit
c69148c946
@ -606,6 +606,7 @@ Json::Value obj_value(Json::objectValue); // {}
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void initBasic(ValueType type, bool allocated = false);
|
void initBasic(ValueType type, bool allocated = false);
|
||||||
|
void releasePayload();
|
||||||
|
|
||||||
Value& resolveReference(const char* key);
|
Value& resolveReference(const char* key);
|
||||||
Value& resolveReference(const char* key, const char* end);
|
Value& resolveReference(const char* key, const char* end);
|
||||||
|
@ -441,48 +441,11 @@ Value::Value(bool value) {
|
|||||||
value_.bool_ = value;
|
value_.bool_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::Value(Value const& other)
|
Value::Value(const Value& other) {
|
||||||
: type_(other.type_), allocated_(false)
|
type_ = nullValue;
|
||||||
,
|
allocated_ = false;
|
||||||
comments_(0), start_(other.start_), limit_(other.limit_)
|
comments_ = 0;
|
||||||
{
|
copy(other);
|
||||||
switch (type_) {
|
|
||||||
case nullValue:
|
|
||||||
case intValue:
|
|
||||||
case uintValue:
|
|
||||||
case realValue:
|
|
||||||
case booleanValue:
|
|
||||||
value_ = other.value_;
|
|
||||||
break;
|
|
||||||
case stringValue:
|
|
||||||
if (other.value_.string_ && other.allocated_) {
|
|
||||||
unsigned len;
|
|
||||||
char const* str;
|
|
||||||
decodePrefixedString(other.allocated_, other.value_.string_,
|
|
||||||
&len, &str);
|
|
||||||
value_.string_ = duplicateAndPrefixStringValue(str, len);
|
|
||||||
allocated_ = true;
|
|
||||||
} else {
|
|
||||||
value_.string_ = other.value_.string_;
|
|
||||||
allocated_ = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case arrayValue:
|
|
||||||
case objectValue:
|
|
||||||
value_.map_ = new ObjectValues(*other.value_.map_);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
JSON_ASSERT_UNREACHABLE;
|
|
||||||
}
|
|
||||||
if (other.comments_) {
|
|
||||||
comments_ = new CommentInfo[numberOfCommentPlacement];
|
|
||||||
for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
|
|
||||||
const CommentInfo& otherComment = other.comments_[comment];
|
|
||||||
if (otherComment.comment_)
|
|
||||||
comments_[comment].setComment(
|
|
||||||
otherComment.comment_, strlen(otherComment.comment_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if JSON_HAS_RVALUE_REFERENCES
|
#if JSON_HAS_RVALUE_REFERENCES
|
||||||
@ -494,24 +457,7 @@ Value::Value(Value&& other) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Value::~Value() {
|
Value::~Value() {
|
||||||
switch (type_) {
|
releasePayload();
|
||||||
case nullValue:
|
|
||||||
case intValue:
|
|
||||||
case uintValue:
|
|
||||||
case realValue:
|
|
||||||
case booleanValue:
|
|
||||||
break;
|
|
||||||
case stringValue:
|
|
||||||
if (allocated_)
|
|
||||||
releasePrefixedStringValue(value_.string_);
|
|
||||||
break;
|
|
||||||
case arrayValue:
|
|
||||||
case objectValue:
|
|
||||||
delete value_.map_;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
JSON_ASSERT_UNREACHABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] comments_;
|
delete[] comments_;
|
||||||
|
|
||||||
@ -534,9 +480,36 @@ void Value::swapPayload(Value& other) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Value::copyPayload(const Value& other) {
|
void Value::copyPayload(const Value& other) {
|
||||||
|
releasePayload();
|
||||||
type_ = other.type_;
|
type_ = other.type_;
|
||||||
value_ = other.value_;
|
allocated_ = false;
|
||||||
allocated_ = other.allocated_;
|
switch (type_) {
|
||||||
|
case nullValue:
|
||||||
|
case intValue:
|
||||||
|
case uintValue:
|
||||||
|
case realValue:
|
||||||
|
case booleanValue:
|
||||||
|
value_ = other.value_;
|
||||||
|
break;
|
||||||
|
case stringValue:
|
||||||
|
if (other.value_.string_ && other.allocated_) {
|
||||||
|
unsigned len;
|
||||||
|
char const* str;
|
||||||
|
decodePrefixedString(other.allocated_, other.value_.string_,
|
||||||
|
&len, &str);
|
||||||
|
value_.string_ = duplicateAndPrefixStringValue(str, len);
|
||||||
|
allocated_ = true;
|
||||||
|
} else {
|
||||||
|
value_.string_ = other.value_.string_;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case arrayValue:
|
||||||
|
case objectValue:
|
||||||
|
value_.map_ = new ObjectValues(*other.value_.map_);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
JSON_ASSERT_UNREACHABLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::swap(Value& other) {
|
void Value::swap(Value& other) {
|
||||||
@ -548,7 +521,18 @@ void Value::swap(Value& other) {
|
|||||||
|
|
||||||
void Value::copy(const Value& other) {
|
void Value::copy(const Value& other) {
|
||||||
copyPayload(other);
|
copyPayload(other);
|
||||||
comments_ = other.comments_;
|
delete[] comments_;
|
||||||
|
if (other.comments_) {
|
||||||
|
comments_ = new CommentInfo[numberOfCommentPlacement];
|
||||||
|
for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
|
||||||
|
const CommentInfo& otherComment = other.comments_[comment];
|
||||||
|
if (otherComment.comment_)
|
||||||
|
comments_[comment].setComment(
|
||||||
|
otherComment.comment_, strlen(otherComment.comment_));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
comments_ = 0;
|
||||||
|
}
|
||||||
start_ = other.start_;
|
start_ = other.start_;
|
||||||
limit_ = other.limit_;
|
limit_ = other.limit_;
|
||||||
}
|
}
|
||||||
@ -1049,6 +1033,27 @@ void Value::initBasic(ValueType vtype, bool allocated) {
|
|||||||
limit_ = 0;
|
limit_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Value::releasePayload() {
|
||||||
|
switch (type_) {
|
||||||
|
case nullValue:
|
||||||
|
case intValue:
|
||||||
|
case uintValue:
|
||||||
|
case realValue:
|
||||||
|
case booleanValue:
|
||||||
|
break;
|
||||||
|
case stringValue:
|
||||||
|
if (allocated_)
|
||||||
|
releasePrefixedStringValue(value_.string_);
|
||||||
|
break;
|
||||||
|
case arrayValue:
|
||||||
|
case objectValue:
|
||||||
|
delete value_.map_;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
JSON_ASSERT_UNREACHABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Access an object value by name, create a null member if it does not exist.
|
// Access an object value by name, create a null member if it does not exist.
|
||||||
// @pre Type of '*this' is object or null.
|
// @pre Type of '*this' is object or null.
|
||||||
// @param key is null-terminated.
|
// @param key is null-terminated.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user