|
@@ -202,14 +202,18 @@ template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) {
|
|
|
* Return iterator that would be the new end of the range [begin,end), if we
|
|
|
* were to delete zeros in the end of string, but not the last zero before '.'.
|
|
|
*/
|
|
|
-template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) {
|
|
|
+template <typename Iter>
|
|
|
+Iter fixZerosInTheEnd(Iter begin, Iter end, unsigned int precision) {
|
|
|
for (; begin != end; --end) {
|
|
|
if (*(end - 1) != '0') {
|
|
|
return end;
|
|
|
}
|
|
|
// Don't delete the last zero before the decimal point.
|
|
|
- if (begin != (end - 1) && *(end - 2) == '.') {
|
|
|
- return end;
|
|
|
+ if (begin != (end - 1) && begin != (end - 2) && *(end - 2) == '.') {
|
|
|
+ if (precision) {
|
|
|
+ return end;
|
|
|
+ }
|
|
|
+ return end - 2;
|
|
|
}
|
|
|
}
|
|
|
return end;
|
|
@@ -338,8 +342,7 @@ bool Reader::parse(std::istream& is, Value& root, bool collectComments) {
|
|
|
|
|
|
// Since String is reference-counted, this at least does not
|
|
|
// create an extra copy.
|
|
|
- String doc;
|
|
|
- std::getline(is, doc, static_cast<char> EOF);
|
|
|
+ String doc(std::istreambuf_iterator<char>(is), {});
|
|
|
return parse(doc.data(), doc.data() + doc.size(), root, collectComments);
|
|
|
}
|
|
|
|
|
@@ -2155,7 +2158,7 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const {
|
|
|
if (valid_keys.count(key))
|
|
|
continue;
|
|
|
if (invalid)
|
|
|
- (*invalid)[std::move(key)] = *si;
|
|
|
+ (*invalid)[key] = *si;
|
|
|
else
|
|
|
return false;
|
|
|
}
|
|
@@ -2670,7 +2673,7 @@ Value::CZString::CZString(const CZString& other) {
|
|
|
storage_.length_ = other.storage_.length_;
|
|
|
}
|
|
|
|
|
|
-Value::CZString::CZString(CZString&& other)
|
|
|
+Value::CZString::CZString(CZString&& other) noexcept
|
|
|
: cstr_(other.cstr_), index_(other.index_) {
|
|
|
other.cstr_ = nullptr;
|
|
|
}
|
|
@@ -2696,7 +2699,7 @@ Value::CZString& Value::CZString::operator=(const CZString& other) {
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
-Value::CZString& Value::CZString::operator=(CZString&& other) {
|
|
|
+Value::CZString& Value::CZString::operator=(CZString&& other) noexcept {
|
|
|
cstr_ = other.cstr_;
|
|
|
index_ = other.index_;
|
|
|
other.cstr_ = nullptr;
|
|
@@ -2844,7 +2847,7 @@ Value::Value(const Value& other) {
|
|
|
dupMeta(other);
|
|
|
}
|
|
|
|
|
|
-Value::Value(Value&& other) {
|
|
|
+Value::Value(Value&& other) noexcept {
|
|
|
initBasic(nullValue);
|
|
|
swap(other);
|
|
|
}
|
|
@@ -2859,7 +2862,7 @@ Value& Value::operator=(const Value& other) {
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
-Value& Value::operator=(Value&& other) {
|
|
|
+Value& Value::operator=(Value&& other) noexcept {
|
|
|
other.swap(*this);
|
|
|
return *this;
|
|
|
}
|
|
@@ -3323,7 +3326,8 @@ void Value::resize(ArrayIndex newSize) {
|
|
|
if (newSize == 0)
|
|
|
clear();
|
|
|
else if (newSize > oldSize)
|
|
|
- this->operator[](newSize - 1);
|
|
|
+ for (ArrayIndex i = oldSize; i < newSize; ++i)
|
|
|
+ (*this)[i];
|
|
|
else {
|
|
|
for (ArrayIndex index = newSize; index < oldSize; ++index) {
|
|
|
value_.map_->erase(index);
|
|
@@ -3784,14 +3788,15 @@ bool Value::isObject() const { return type() == objectValue; }
|
|
|
Value::Comments::Comments(const Comments& that)
|
|
|
: ptr_{cloneUnique(that.ptr_)} {}
|
|
|
|
|
|
-Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {}
|
|
|
+Value::Comments::Comments(Comments&& that) noexcept
|
|
|
+ : ptr_{std::move(that.ptr_)} {}
|
|
|
|
|
|
Value::Comments& Value::Comments::operator=(const Comments& that) {
|
|
|
ptr_ = cloneUnique(that.ptr_);
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
-Value::Comments& Value::Comments::operator=(Comments&& that) {
|
|
|
+Value::Comments& Value::Comments::operator=(Comments&& that) noexcept {
|
|
|
ptr_ = std::move(that.ptr_);
|
|
|
return *this;
|
|
|
}
|
|
@@ -3807,13 +3812,11 @@ String Value::Comments::get(CommentPlacement slot) const {
|
|
|
}
|
|
|
|
|
|
void Value::Comments::set(CommentPlacement slot, String comment) {
|
|
|
- if (!ptr_) {
|
|
|
+ if (slot >= CommentPlacement::numberOfCommentPlacement)
|
|
|
+ return;
|
|
|
+ if (!ptr_)
|
|
|
ptr_ = std::unique_ptr<Array>(new Array());
|
|
|
- }
|
|
|
- // check comments array boundry.
|
|
|
- if (slot < CommentPlacement::numberOfCommentPlacement) {
|
|
|
- (*ptr_)[slot] = std::move(comment);
|
|
|
- }
|
|
|
+ (*ptr_)[slot] = std::move(comment);
|
|
|
}
|
|
|
|
|
|
void Value::setComment(String comment, CommentPlacement placement) {
|
|
@@ -4127,7 +4130,7 @@ Value& Path::make(Value& root) const {
|
|
|
|
|
|
#if !defined(isnan)
|
|
|
// IEEE standard states that NaN values will not compare to themselves
|
|
|
-#define isnan(x) (x != x)
|
|
|
+#define isnan(x) ((x) != (x))
|
|
|
#endif
|
|
|
|
|
|
#if !defined(__APPLE__)
|
|
@@ -4213,16 +4216,18 @@ String valueToString(double value, bool useSpecialFloats,
|
|
|
|
|
|
buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end());
|
|
|
|
|
|
- // strip the zero padding from the right
|
|
|
- if (precisionType == PrecisionType::decimalPlaces) {
|
|
|
- buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end());
|
|
|
- }
|
|
|
-
|
|
|
// try to ensure we preserve the fact that this was given to us as a double on
|
|
|
// input
|
|
|
if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) {
|
|
|
buffer += ".0";
|
|
|
}
|
|
|
+
|
|
|
+ // strip the zero padding from the right
|
|
|
+ if (precisionType == PrecisionType::decimalPlaces) {
|
|
|
+ buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end(), precision),
|
|
|
+ buffer.end());
|
|
|
+ }
|
|
|
+
|
|
|
return buffer;
|
|
|
}
|
|
|
} // namespace
|
|
@@ -4329,7 +4334,7 @@ static void appendHex(String& result, unsigned ch) {
|
|
|
result.append("\\u").append(toHex16Bit(ch));
|
|
|
}
|
|
|
|
|
|
-static String valueToQuotedStringN(const char* value, unsigned length,
|
|
|
+static String valueToQuotedStringN(const char* value, size_t length,
|
|
|
bool emitUTF8 = false) {
|
|
|
if (value == nullptr)
|
|
|
return "";
|
|
@@ -4407,7 +4412,7 @@ static String valueToQuotedStringN(const char* value, unsigned length,
|
|
|
}
|
|
|
|
|
|
String valueToQuotedString(const char* value) {
|
|
|
- return valueToQuotedStringN(value, static_cast<unsigned int>(strlen(value)));
|
|
|
+ return valueToQuotedStringN(value, strlen(value));
|
|
|
}
|
|
|
|
|
|
// Class Writer
|
|
@@ -4456,7 +4461,7 @@ void FastWriter::writeValue(const Value& value) {
|
|
|
char const* end;
|
|
|
bool ok = value.getString(&str, &end);
|
|
|
if (ok)
|
|
|
- document_ += valueToQuotedStringN(str, static_cast<unsigned>(end - str));
|
|
|
+ document_ += valueToQuotedStringN(str, static_cast<size_t>(end - str));
|
|
|
break;
|
|
|
}
|
|
|
case booleanValue:
|
|
@@ -4479,8 +4484,7 @@ void FastWriter::writeValue(const Value& value) {
|
|
|
const String& name = *it;
|
|
|
if (it != members.begin())
|
|
|
document_ += ',';
|
|
|
- document_ += valueToQuotedStringN(name.data(),
|
|
|
- static_cast<unsigned>(name.length()));
|
|
|
+ document_ += valueToQuotedStringN(name.data(), name.length());
|
|
|
document_ += yamlCompatibilityEnabled_ ? ": " : ":";
|
|
|
writeValue(value[name]);
|
|
|
}
|
|
@@ -4525,7 +4529,7 @@ void StyledWriter::writeValue(const Value& value) {
|
|
|
char const* end;
|
|
|
bool ok = value.getString(&str, &end);
|
|
|
if (ok)
|
|
|
- pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
|
|
|
+ pushValue(valueToQuotedStringN(str, static_cast<size_t>(end - str)));
|
|
|
else
|
|
|
pushValue("");
|
|
|
break;
|
|
@@ -4566,7 +4570,7 @@ void StyledWriter::writeValue(const Value& value) {
|
|
|
}
|
|
|
|
|
|
void StyledWriter::writeArrayValue(const Value& value) {
|
|
|
- unsigned size = value.size();
|
|
|
+ size_t size = value.size();
|
|
|
if (size == 0)
|
|
|
pushValue("[]");
|
|
|
else {
|
|
@@ -4575,7 +4579,7 @@ void StyledWriter::writeArrayValue(const Value& value) {
|
|
|
writeWithIndent("[");
|
|
|
indent();
|
|
|
bool hasChildValue = !childValues_.empty();
|
|
|
- unsigned index = 0;
|
|
|
+ ArrayIndex index = 0;
|
|
|
for (;;) {
|
|
|
const Value& childValue = value[index];
|
|
|
writeCommentBeforeValue(childValue);
|
|
@@ -4598,7 +4602,7 @@ void StyledWriter::writeArrayValue(const Value& value) {
|
|
|
{
|
|
|
assert(childValues_.size() == size);
|
|
|
document_ += "[ ";
|
|
|
- for (unsigned index = 0; index < size; ++index) {
|
|
|
+ for (size_t index = 0; index < size; ++index) {
|
|
|
if (index > 0)
|
|
|
document_ += ", ";
|
|
|
document_ += childValues_[index];
|
|
@@ -4743,7 +4747,7 @@ void StyledStreamWriter::writeValue(const Value& value) {
|
|
|
char const* end;
|
|
|
bool ok = value.getString(&str, &end);
|
|
|
if (ok)
|
|
|
- pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
|
|
|
+ pushValue(valueToQuotedStringN(str, static_cast<size_t>(end - str)));
|
|
|
else
|
|
|
pushValue("");
|
|
|
break;
|
|
@@ -5017,8 +5021,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
|
|
|
char const* end;
|
|
|
bool ok = value.getString(&str, &end);
|
|
|
if (ok)
|
|
|
- pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str),
|
|
|
- emitUTF8_));
|
|
|
+ pushValue(
|
|
|
+ valueToQuotedStringN(str, static_cast<size_t>(end - str), emitUTF8_));
|
|
|
else
|
|
|
pushValue("");
|
|
|
break;
|
|
@@ -5041,8 +5045,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
|
|
|
String const& name = *it;
|
|
|
Value const& childValue = value[name];
|
|
|
writeCommentBeforeValue(childValue);
|
|
|
- writeWithIndent(valueToQuotedStringN(
|
|
|
- name.data(), static_cast<unsigned>(name.length()), emitUTF8_));
|
|
|
+ writeWithIndent(
|
|
|
+ valueToQuotedStringN(name.data(), name.length(), emitUTF8_));
|
|
|
*sout_ << colonSymbol_;
|
|
|
writeValue(childValue);
|
|
|
if (++it == members.end()) {
|
|
@@ -5276,7 +5280,7 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const {
|
|
|
if (valid_keys.count(key))
|
|
|
continue;
|
|
|
if (invalid)
|
|
|
- (*invalid)[std::move(key)] = *si;
|
|
|
+ (*invalid)[key] = *si;
|
|
|
else
|
|
|
return false;
|
|
|
}
|