Skip to content

Commit 433107f

Browse files
BillyDonahuehjmjohnson
authored andcommitted
refactor comments_ into a class
1 parent a732207 commit 433107f

File tree

2 files changed

+69
-73
lines changed

2 files changed

+69
-73
lines changed

include/json/value.h

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#if !defined(JSON_IS_AMALGAMATION)
1010
#include "forwards.h"
1111
#endif // if !defined(JSON_IS_AMALGAMATION)
12+
#include <array>
1213
#include <exception>
14+
#include <memory>
1315
#include <string>
1416
#include <vector>
1517

@@ -587,11 +589,15 @@ Json::Value obj_value(Json::objectValue); // {}
587589

588590
/// \deprecated Always pass len.
589591
JSONCPP_DEPRECATED("Use setComment(String const&) instead.")
590-
void setComment(const char* comment, CommentPlacement placement);
592+
void setComment(const char* comment, CommentPlacement placement) {
593+
setComment(String(comment, strlen(comment)), placement);
594+
}
591595
/// Comments must be //... or /* ... */
592-
void setComment(const char* comment, size_t len, CommentPlacement placement);
596+
void setComment(const char* comment, size_t len, CommentPlacement placement) {
597+
setComment(String(comment, len), placement);
598+
}
593599
/// Comments must be //... or /* ... */
594-
void setComment(const String& comment, CommentPlacement placement);
600+
void setComment(String comment, CommentPlacement placement);
595601
bool hasComment(CommentPlacement placement) const;
596602
/// Include delimiters and embedded newlines.
597603
String getComment(CommentPlacement placement) const;
@@ -624,15 +630,6 @@ Json::Value obj_value(Json::objectValue); // {}
624630
Value& resolveReference(const char* key);
625631
Value& resolveReference(const char* key, const char* end);
626632

627-
struct CommentInfo {
628-
CommentInfo();
629-
~CommentInfo();
630-
631-
void setComment(const char* text, size_t len);
632-
633-
char* comment_{nullptr};
634-
};
635-
636633
// struct MemberNamesTransform
637634
//{
638635
// typedef const char *result_type;
@@ -658,7 +655,22 @@ Json::Value obj_value(Json::objectValue); // {}
658655
unsigned int allocated_ : 1;
659656
} bits_;
660657

661-
CommentInfo* comments_;
658+
class Comments {
659+
public:
660+
Comments() = default;
661+
Comments(const Comments& that);
662+
Comments(Comments&&) = default;
663+
Comments& operator=(const Comments& that);
664+
Comments& operator=(Comments&&) = default;
665+
bool has(CommentPlacement slot) const;
666+
String get(CommentPlacement slot) const;
667+
void set(CommentPlacement slot, String s);
668+
669+
private:
670+
using Array = std::array<String, numberOfCommentPlacement>;
671+
std::unique_ptr<Array> ptr_;
672+
};
673+
Comments comments_;
662674

663675
// [start, limit) byte offsets in the source JSON text from which this Value
664676
// was extracted.

src/lib_json/json_value.cpp

Lines changed: 44 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ int JSON_API msvc_pre1900_c99_snprintf(char* outBuf,
5555

5656
namespace Json {
5757

58+
template <typename T>
59+
static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) {
60+
std::unique_ptr<T> r;
61+
if (p) {
62+
r = std::unique_ptr<T>(new T(*p));
63+
}
64+
return r;
65+
}
66+
5867
// This is a walkaround to avoid the static initialization of Value::null.
5968
// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
6069
// 8 (instead of 4) as a bit of future-proofing.
@@ -229,34 +238,6 @@ JSONCPP_NORETURN void throwLogicError(String const& msg) {
229238
throw LogicError(msg);
230239
}
231240

232-
// //////////////////////////////////////////////////////////////////
233-
// //////////////////////////////////////////////////////////////////
234-
// //////////////////////////////////////////////////////////////////
235-
// class Value::CommentInfo
236-
// //////////////////////////////////////////////////////////////////
237-
// //////////////////////////////////////////////////////////////////
238-
// //////////////////////////////////////////////////////////////////
239-
240-
Value::CommentInfo::CommentInfo() = default;
241-
242-
Value::CommentInfo::~CommentInfo() {
243-
if (comment_)
244-
releaseStringValue(comment_, 0u);
245-
}
246-
247-
void Value::CommentInfo::setComment(const char* text, size_t len) {
248-
if (comment_) {
249-
releaseStringValue(comment_, 0u);
250-
comment_ = nullptr;
251-
}
252-
JSON_ASSERT(text != nullptr);
253-
JSON_ASSERT_MESSAGE(
254-
text[0] == '\0' || text[0] == '/',
255-
"in Json::Value::setComment(): Comments must start with /");
256-
// It seems that /**/ style comments are acceptable as well.
257-
comment_ = duplicateStringValue(text, len);
258-
}
259-
260241
// //////////////////////////////////////////////////////////////////
261242
// //////////////////////////////////////////////////////////////////
262243
// //////////////////////////////////////////////////////////////////
@@ -488,7 +469,6 @@ Value::Value(Value&& other) {
488469

489470
Value::~Value() {
490471
releasePayload();
491-
delete[] comments_;
492472
value_.uint_ = 0;
493473
}
494474

@@ -521,7 +501,6 @@ void Value::swap(Value& other) {
521501

522502
void Value::copy(const Value& other) {
523503
copyPayload(other);
524-
delete[] comments_;
525504
dupMeta(other);
526505
}
527506

@@ -1027,7 +1006,7 @@ const Value& Value::operator[](int index) const {
10271006
void Value::initBasic(ValueType type, bool allocated) {
10281007
setType(type);
10291008
setIsAllocated(allocated);
1030-
comments_ = nullptr;
1009+
comments_ = Comments{};
10311010
start_ = 0;
10321011
limit_ = 0;
10331012
}
@@ -1086,17 +1065,7 @@ void Value::releasePayload() {
10861065
}
10871066

10881067
void Value::dupMeta(const Value& other) {
1089-
if (other.comments_) {
1090-
comments_ = new CommentInfo[numberOfCommentPlacement];
1091-
for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
1092-
const CommentInfo& otherComment = other.comments_[comment];
1093-
if (otherComment.comment_)
1094-
comments_[comment].setComment(otherComment.comment_,
1095-
strlen(otherComment.comment_));
1096-
}
1097-
} else {
1098-
comments_ = nullptr;
1099-
}
1068+
comments_ = other.comments_;
11001069
start_ = other.start_;
11011070
limit_ = other.limit_;
11021071
}
@@ -1468,34 +1437,49 @@ bool Value::isArray() const { return type() == arrayValue; }
14681437

14691438
bool Value::isObject() const { return type() == objectValue; }
14701439

1471-
void Value::setComment(const char* comment,
1472-
size_t len,
1473-
CommentPlacement placement) {
1474-
if (!comments_)
1475-
comments_ = new CommentInfo[numberOfCommentPlacement];
1476-
if ((len > 0) && (comment[len - 1] == '\n')) {
1477-
// Always discard trailing newline, to aid indentation.
1478-
len -= 1;
1479-
}
1480-
comments_[placement].setComment(comment, len);
1440+
Value::Comments::Comments(const Comments& that)
1441+
: ptr_{cloneUnique(that.ptr_)} {}
1442+
1443+
Value::Comments& Value::Comments::operator=(const Comments& that) {
1444+
ptr_ = cloneUnique(that.ptr_);
1445+
return *this;
14811446
}
14821447

1483-
void Value::setComment(const char* comment, CommentPlacement placement) {
1484-
setComment(comment, strlen(comment), placement);
1448+
bool Value::Comments::has(CommentPlacement slot) const {
1449+
return ptr_ && !(*ptr_)[slot].empty();
14851450
}
14861451

1487-
void Value::setComment(const String& comment, CommentPlacement placement) {
1488-
setComment(comment.c_str(), comment.length(), placement);
1452+
String Value::Comments::get(CommentPlacement slot) const {
1453+
if (!ptr_)
1454+
return {};
1455+
return (*ptr_)[slot];
1456+
}
1457+
1458+
void Value::Comments::set(CommentPlacement slot, String comment) {
1459+
if (!ptr_) {
1460+
ptr_ = std::unique_ptr<Array>(new Array());
1461+
}
1462+
(*ptr_)[slot] = std::move(comment);
1463+
}
1464+
1465+
void Value::setComment(String comment, CommentPlacement placement) {
1466+
if (!comment.empty() && (comment.back() == '\n')) {
1467+
// Always discard trailing newline, to aid indentation.
1468+
comment.pop_back();
1469+
}
1470+
JSON_ASSERT(!comment.empty());
1471+
JSON_ASSERT_MESSAGE(
1472+
comment[0] == '\0' || comment[0] == '/',
1473+
"in Json::Value::setComment(): Comments must start with /");
1474+
comments_.set(placement, std::move(comment));
14891475
}
14901476

14911477
bool Value::hasComment(CommentPlacement placement) const {
1492-
return comments_ != nullptr && comments_[placement].comment_ != nullptr;
1478+
return comments_.has(placement);
14931479
}
14941480

14951481
String Value::getComment(CommentPlacement placement) const {
1496-
if (hasComment(placement))
1497-
return comments_[placement].comment_;
1498-
return "";
1482+
return comments_.get(placement);
14991483
}
15001484

15011485
void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }

0 commit comments

Comments
 (0)