6 #if !defined(JSON_IS_AMALGAMATION)
9 #endif // if !defined(JSON_IS_AMALGAMATION)
19 #if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
21 #define isfinite _finite
22 #elif defined(__sun) && defined(__SVR4) //Solaris
24 #define isfinite finite
27 #define isfinite std::isfinite
30 #if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
31 #define snprintf _snprintf
32 #elif __cplusplus >= 201103L
33 #define snprintf std::snprintf
36 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
38 #pragma warning(disable : 4996)
43 #if __cplusplus >= 201103L
58 char const* end = str + len;
69 char* current = buffer +
sizeof(buffer);
70 bool isNegative = value < 0;
76 assert(current >= buffer);
82 char* current = buffer +
sizeof(buffer);
84 assert(current >= buffer);
88 #if defined(JSON_HAS_INT64)
98 #endif // # if defined(JSON_HAS_INT64)
109 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with
113 len = _snprintf(buffer,
sizeof(buffer),
"%.17g", value);
115 len = sprintf_s(buffer,
sizeof(buffer),
"%.17g", value);
119 len =
snprintf(buffer,
sizeof(buffer),
"%.17g", value);
122 if (value != value) {
123 len =
snprintf(buffer,
sizeof(buffer),
"null");
124 }
else if (value < 0) {
125 len =
snprintf(buffer,
sizeof(buffer),
"-1e+9999");
127 len =
snprintf(buffer,
sizeof(buffer),
"1e+9999");
143 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
145 return std::string(
"\"") + value +
"\"";
149 std::string::size_type maxsize =
150 strlen(value) * 2 + 3;
152 result.reserve(maxsize);
154 for (
const char* c = value; *c != 0; ++c) {
187 std::ostringstream oss;
188 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
189 << std::setw(4) <<
static_cast<int>(*c);
202 static char const*
strnpbrk(
char const* s,
char const* accept,
size_t n) {
203 assert((s || !n) && accept);
205 char const*
const end = s + n;
206 for (
char const* cur = s; cur < end; ++cur) {
208 for (
char const* a = accept; *a; ++a) {
220 if (
strnpbrk(value,
"\"\\\b\f\n\r\t", length) == NULL &&
222 return std::string(
"\"") + value +
"\"";
226 std::string::size_type maxsize =
229 result.reserve(maxsize);
231 char const* end = value + length;
232 for (
const char* c = value; c != end; ++c) {
265 std::ostringstream oss;
266 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
267 << std::setw(4) <<
static_cast<int>(*c);
287 : yamlCompatiblityEnabled_(false) {}
298 void FastWriter::writeValue(
const Value& value) {
299 switch (value.
type()) {
326 int size = value.
size();
327 for (
int index = 0; index < size; ++index) {
330 writeValue(value[index]);
337 for (Value::Members::iterator it = members.begin(); it != members.end();
339 const std::string& name = *it;
340 if (it != members.begin())
343 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
344 writeValue(value[name]);
355 : rightMargin_(74), indentSize_(3), addChildValues_() {}
359 addChildValues_ =
false;
361 writeCommentBeforeValue(root);
363 writeCommentAfterValueOnSameLine(root);
368 void StyledWriter::writeValue(
const Value& value) {
369 switch (value.
type()) {
396 writeArrayValue(value);
403 writeWithIndent(
"{");
405 Value::Members::iterator it = members.begin();
407 const std::string& name = *it;
408 const Value& childValue = value[name];
409 writeCommentBeforeValue(childValue);
412 writeValue(childValue);
413 if (++it == members.end()) {
414 writeCommentAfterValueOnSameLine(childValue);
418 writeCommentAfterValueOnSameLine(childValue);
421 writeWithIndent(
"}");
427 void StyledWriter::writeArrayValue(
const Value& value) {
428 unsigned size = value.size();
432 bool isArrayMultiLine = isMultineArray(value);
433 if (isArrayMultiLine) {
434 writeWithIndent(
"[");
436 bool hasChildValue = !childValues_.empty();
439 const Value& childValue = value[index];
440 writeCommentBeforeValue(childValue);
442 writeWithIndent(childValues_[index]);
445 writeValue(childValue);
447 if (++index == size) {
448 writeCommentAfterValueOnSameLine(childValue);
452 writeCommentAfterValueOnSameLine(childValue);
455 writeWithIndent(
"]");
458 assert(childValues_.size() == size);
460 for (
unsigned index = 0; index < size; ++index) {
463 document_ += childValues_[index];
470 bool StyledWriter::isMultineArray(
const Value& value) {
471 int size = value.size();
472 bool isMultiLine = size * 3 >= rightMargin_;
473 childValues_.clear();
474 for (
int index = 0; index < size && !isMultiLine; ++index) {
475 const Value& childValue = value[index];
477 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
478 childValue.size() > 0);
482 childValues_.reserve(size);
483 addChildValues_ =
true;
484 int lineLength = 4 + (size - 1) * 2;
485 for (
int index = 0; index < size; ++index) {
486 if (hasCommentForValue(value[index])) {
489 writeValue(value[index]);
490 lineLength += int(childValues_[index].length());
492 addChildValues_ =
false;
493 isMultiLine = isMultiLine || lineLength >= rightMargin_;
498 void StyledWriter::pushValue(
const std::string& value) {
500 childValues_.push_back(value);
505 void StyledWriter::writeIndent() {
506 if (!document_.empty()) {
507 char last = document_[document_.length() - 1];
513 document_ += indentString_;
516 void StyledWriter::writeWithIndent(
const std::string& value) {
521 void StyledWriter::indent() { indentString_ += std::string(indentSize_,
' '); }
523 void StyledWriter::unindent() {
524 assert(
int(indentString_.size()) >= indentSize_);
525 indentString_.resize(indentString_.size() - indentSize_);
528 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
535 std::string::const_iterator iter = comment.begin();
536 while (iter != comment.end()) {
539 (iter != comment.end() && *(iter + 1) ==
'/'))
548 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
559 bool StyledWriter::hasCommentForValue(
const Value& value) {
569 : document_(NULL), rightMargin_(74), indentation_(indentation),
574 addChildValues_ =
false;
577 writeCommentBeforeValue(root);
578 if (!indented_) writeIndent();
581 writeCommentAfterValueOnSameLine(root);
586 void StyledStreamWriter::writeValue(
const Value& value) {
587 switch (value.
type()) {
614 writeArrayValue(value);
621 writeWithIndent(
"{");
623 Value::Members::iterator it = members.begin();
625 const std::string& name = *it;
626 const Value& childValue = value[name];
627 writeCommentBeforeValue(childValue);
630 writeValue(childValue);
631 if (++it == members.end()) {
632 writeCommentAfterValueOnSameLine(childValue);
636 writeCommentAfterValueOnSameLine(childValue);
639 writeWithIndent(
"}");
645 void StyledStreamWriter::writeArrayValue(
const Value& value) {
646 unsigned size = value.size();
650 bool isArrayMultiLine = isMultineArray(value);
651 if (isArrayMultiLine) {
652 writeWithIndent(
"[");
654 bool hasChildValue = !childValues_.empty();
657 const Value& childValue = value[index];
658 writeCommentBeforeValue(childValue);
660 writeWithIndent(childValues_[index]);
662 if (!indented_) writeIndent();
664 writeValue(childValue);
667 if (++index == size) {
668 writeCommentAfterValueOnSameLine(childValue);
672 writeCommentAfterValueOnSameLine(childValue);
675 writeWithIndent(
"]");
678 assert(childValues_.size() == size);
680 for (
unsigned index = 0; index < size; ++index) {
683 *document_ << childValues_[index];
690 bool StyledStreamWriter::isMultineArray(
const Value& value) {
691 int size = value.size();
692 bool isMultiLine = size * 3 >= rightMargin_;
693 childValues_.clear();
694 for (
int index = 0; index < size && !isMultiLine; ++index) {
695 const Value& childValue = value[index];
697 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
698 childValue.size() > 0);
702 childValues_.reserve(size);
703 addChildValues_ =
true;
704 int lineLength = 4 + (size - 1) * 2;
705 for (
int index = 0; index < size; ++index) {
706 if (hasCommentForValue(value[index])) {
709 writeValue(value[index]);
710 lineLength += int(childValues_[index].length());
712 addChildValues_ =
false;
713 isMultiLine = isMultiLine || lineLength >= rightMargin_;
718 void StyledStreamWriter::pushValue(
const std::string& value) {
720 childValues_.push_back(value);
725 void StyledStreamWriter::writeIndent() {
730 *document_ <<
'\n' << indentString_;
733 void StyledStreamWriter::writeWithIndent(
const std::string& value) {
734 if (!indented_) writeIndent();
739 void StyledStreamWriter::indent() { indentString_ += indentation_; }
741 void StyledStreamWriter::unindent() {
742 assert(indentString_.size() >= indentation_.size());
743 indentString_.resize(indentString_.size() - indentation_.size());
746 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
750 if (!indented_) writeIndent();
752 std::string::const_iterator iter = comment.begin();
753 while (iter != comment.end()) {
756 (iter != comment.end() && *(iter + 1) ==
'/'))
758 *document_ << indentString_;
764 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
775 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
785 struct CommentStyle {
794 struct BuiltStyledStreamWriter :
public StreamWriter
796 BuiltStyledStreamWriter(
797 std::string
const& indentation,
798 CommentStyle::Enum cs,
799 std::string
const& colonSymbol,
800 std::string
const& nullSymbol,
801 std::string
const& endingLineFeedSymbol);
802 virtual int write(Value
const& root, std::ostream* sout);
804 void writeValue(Value
const& value);
805 void writeArrayValue(Value
const& value);
806 bool isMultineArray(Value
const& value);
807 void pushValue(std::string
const& value);
809 void writeWithIndent(std::string
const& value);
812 void writeCommentBeforeValue(Value
const& root);
813 void writeCommentAfterValueOnSameLine(Value
const& root);
814 static bool hasCommentForValue(
const Value& value);
816 typedef std::vector<std::string> ChildValues;
818 ChildValues childValues_;
819 std::string indentString_;
821 std::string indentation_;
822 CommentStyle::Enum cs_;
823 std::string colonSymbol_;
824 std::string nullSymbol_;
825 std::string endingLineFeedSymbol_;
826 bool addChildValues_ : 1;
829 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
830 std::string
const& indentation,
831 CommentStyle::Enum cs,
832 std::string
const& colonSymbol,
833 std::string
const& nullSymbol,
834 std::string
const& endingLineFeedSymbol)
836 , indentation_(indentation)
838 , colonSymbol_(colonSymbol)
839 , nullSymbol_(nullSymbol)
840 , endingLineFeedSymbol_(endingLineFeedSymbol)
841 , addChildValues_(false)
845 int BuiltStyledStreamWriter::write(Value
const& root, std::ostream* sout)
848 addChildValues_ =
false;
851 writeCommentBeforeValue(root);
852 if (!indented_) writeIndent();
855 writeCommentAfterValueOnSameLine(root);
856 *sout_ << endingLineFeedSymbol_;
860 void BuiltStyledStreamWriter::writeValue(Value
const& value) {
861 switch (value.type()) {
863 pushValue(nullSymbol_);
879 bool ok = value.getString(&str, &end);
888 writeArrayValue(value);
895 writeWithIndent(
"{");
897 Value::Members::iterator it = members.begin();
899 std::string
const& name = *it;
900 Value
const& childValue = value[name];
901 writeCommentBeforeValue(childValue);
903 *sout_ << colonSymbol_;
904 writeValue(childValue);
905 if (++it == members.end()) {
906 writeCommentAfterValueOnSameLine(childValue);
910 writeCommentAfterValueOnSameLine(childValue);
913 writeWithIndent(
"}");
919 void BuiltStyledStreamWriter::writeArrayValue(Value
const& value) {
920 unsigned size = value.size();
924 bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
926 writeWithIndent(
"[");
928 bool hasChildValue = !childValues_.empty();
931 Value
const& childValue = value[index];
932 writeCommentBeforeValue(childValue);
934 writeWithIndent(childValues_[index]);
936 if (!indented_) writeIndent();
938 writeValue(childValue);
941 if (++index == size) {
942 writeCommentAfterValueOnSameLine(childValue);
946 writeCommentAfterValueOnSameLine(childValue);
949 writeWithIndent(
"]");
952 assert(childValues_.size() == size);
954 if (!indentation_.empty()) *sout_ <<
" ";
955 for (
unsigned index = 0; index < size; ++index) {
958 *sout_ << childValues_[index];
960 if (!indentation_.empty()) *sout_ <<
" ";
966 bool BuiltStyledStreamWriter::isMultineArray(Value
const& value) {
967 int size = value.size();
968 bool isMultiLine = size * 3 >= rightMargin_;
969 childValues_.clear();
970 for (
int index = 0; index < size && !isMultiLine; ++index) {
971 Value
const& childValue = value[index];
973 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
974 childValue.size() > 0);
978 childValues_.reserve(size);
979 addChildValues_ =
true;
980 int lineLength = 4 + (size - 1) * 2;
981 for (
int index = 0; index < size; ++index) {
982 if (hasCommentForValue(value[index])) {
985 writeValue(value[index]);
986 lineLength += int(childValues_[index].length());
988 addChildValues_ =
false;
989 isMultiLine = isMultiLine || lineLength >= rightMargin_;
994 void BuiltStyledStreamWriter::pushValue(std::string
const& value) {
996 childValues_.push_back(value);
1001 void BuiltStyledStreamWriter::writeIndent() {
1007 if (!indentation_.empty()) {
1009 *sout_ <<
'\n' << indentString_;
1013 void BuiltStyledStreamWriter::writeWithIndent(std::string
const& value) {
1014 if (!indented_) writeIndent();
1019 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1021 void BuiltStyledStreamWriter::unindent() {
1022 assert(indentString_.size() >= indentation_.size());
1023 indentString_.resize(indentString_.size() - indentation_.size());
1026 void BuiltStyledStreamWriter::writeCommentBeforeValue(Value
const& root) {
1027 if (cs_ == CommentStyle::None)
return;
1031 if (!indented_) writeIndent();
1032 const std::string& comment = root.getComment(
commentBefore);
1033 std::string::const_iterator iter = comment.begin();
1034 while (iter != comment.end()) {
1036 if (*iter ==
'\n' &&
1037 (iter != comment.end() && *(iter + 1) ==
'/'))
1039 *sout_ << indentString_;
1045 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value
const& root) {
1046 if (cs_ == CommentStyle::None)
return;
1057 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1077 setDefaults(&settings_);
1083 std::string indentation = settings_[
"indentation"].asString();
1084 std::string cs_str = settings_[
"commentStyle"].asString();
1085 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1086 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1087 CommentStyle::Enum cs = CommentStyle::All;
1088 if (cs_str ==
"All") {
1089 cs = CommentStyle::All;
1090 }
else if (cs_str ==
"None") {
1091 cs = CommentStyle::None;
1095 std::string colonSymbol =
" : ";
1098 }
else if (indentation.empty()) {
1101 std::string nullSymbol =
"null";
1105 std::string endingLineFeedSymbol =
"";
1106 return new BuiltStyledStreamWriter(
1108 colonSymbol, nullSymbol, endingLineFeedSymbol);
1112 valid_keys->clear();
1113 valid_keys->insert(
"indentation");
1114 valid_keys->insert(
"commentStyle");
1115 valid_keys->insert(
"enableYAMLCompatibility");
1116 valid_keys->insert(
"dropNullPlaceholders");
1121 if (!invalid) invalid = &my_invalid;
1123 std::set<std::string> valid_keys;
1126 size_t n = keys.size();
1127 for (
size_t i = 0; i < n; ++i) {
1128 std::string
const& key = keys[i];
1129 if (valid_keys.find(key) == valid_keys.end()) {
1130 inv[key] = settings_[key];
1133 return 0u == inv.
size();
1137 return settings_[key];
1143 (*settings)[
"commentStyle"] =
"All";
1144 (*settings)[
"indentation"] =
"\t";
1145 (*settings)[
"enableYAMLCompatibility"] =
false;
1146 (*settings)[
"dropNullPlaceholders"] =
false;
1151 std::ostringstream sout;
1153 writer->write(root, &sout);
1160 writer->write(root, &sout);
Value & operator[](std::string key)
A simple way to update a specific setting.
A simple abstract factory.
static void uintToString(LargestUInt value, char *¤t)
Converts an unsigned integer to string.
static void setDefaults(Json::Value *settings)
Called by ctor, but you can use this to reset settings_.
std::vector< std::string > Members
array value (ordered list)
LargestUInt asLargestUInt() const
bool getString(char const **str, char const **end) const
Get raw char* of string-value.
std::string valueToQuotedString(const char *value)
virtual StreamWriter * newStreamWriter() const
object value (collection of name/value pairs).
virtual std::string write(const Value &root)
void enableYAMLCompatibility()
StyledStreamWriter(std::string indentation="\t")
void write(std::ostream &out, const Value &root)
Serialize a Value in JSON format.
char UIntToStringBuffer[uintToStringBufferSize]
static bool isControlCharacter(char ch)
Returns true if ch is a control character (in range [0,32[).
static void fixNumericLocale(char *begin, char *end)
Change ',' to '.
static void getValidWriterKeys(std::set< std::string > *valid_keys)
virtual ~StreamWriterBuilder()
std::string valueToString(Int value)
bool validate(Json::Value *invalid) const
virtual std::string write(const Value &root)
Serialize a Value in JSON format.
JSON (JavaScript Object Notation).
Members getMemberNames() const
Return a list of the member names.
std::auto_ptr< StreamWriter > StreamWriterPtr
void throwRuntimeError(std::string const &msg)
used internally
static std::string valueToQuotedStringN(const char *value, unsigned length)
ArrayIndex size() const
Number of values in array or object.
static bool containsControlCharacter0(const char *str, unsigned len)
a comment on the line after a value (only make sense for
LargestInt asLargestInt() const
std::string writeString(StreamWriter::Factory const &factory, Value const &root)
Write into stringstream, then return string, for convenience.
static char const * strnpbrk(char const *s, char const *accept, size_t n)
static bool containsControlCharacter(const char *str)
a comment placed on the line before a value
a comment just after a value on the same line
std::ostream & operator<<(std::ostream &, const Value &root)
Output using the StyledStreamWriter.
Build a StreamWriter implementation.
virtual StreamWriter * newStreamWriter() const =0
Allocate a CharReader via operator new().