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), dropNullPlaceholders_(false),
288 omitEndingLineFeed_(false) {}
299 if (!omitEndingLineFeed_)
304 void FastWriter::writeValue(
const Value& value) {
305 switch (value.
type()) {
307 if (!dropNullPlaceholders_)
333 int size = value.
size();
334 for (
int index = 0; index < size; ++index) {
337 writeValue(value[index]);
344 for (Value::Members::iterator it = members.begin(); it != members.end();
346 const std::string& name = *it;
347 if (it != members.begin())
350 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
351 writeValue(value[name]);
362 : rightMargin_(74), indentSize_(3), addChildValues_() {}
366 addChildValues_ =
false;
368 writeCommentBeforeValue(root);
370 writeCommentAfterValueOnSameLine(root);
375 void StyledWriter::writeValue(
const Value& value) {
376 switch (value.
type()) {
403 writeArrayValue(value);
410 writeWithIndent(
"{");
412 Value::Members::iterator it = members.begin();
414 const std::string& name = *it;
415 const Value& childValue = value[name];
416 writeCommentBeforeValue(childValue);
419 writeValue(childValue);
420 if (++it == members.end()) {
421 writeCommentAfterValueOnSameLine(childValue);
425 writeCommentAfterValueOnSameLine(childValue);
428 writeWithIndent(
"}");
434 void StyledWriter::writeArrayValue(
const Value& value) {
435 unsigned size = value.size();
439 bool isArrayMultiLine = isMultineArray(value);
440 if (isArrayMultiLine) {
441 writeWithIndent(
"[");
443 bool hasChildValue = !childValues_.empty();
446 const Value& childValue = value[index];
447 writeCommentBeforeValue(childValue);
449 writeWithIndent(childValues_[index]);
452 writeValue(childValue);
454 if (++index == size) {
455 writeCommentAfterValueOnSameLine(childValue);
459 writeCommentAfterValueOnSameLine(childValue);
462 writeWithIndent(
"]");
465 assert(childValues_.size() == size);
467 for (
unsigned index = 0; index < size; ++index) {
470 document_ += childValues_[index];
477 bool StyledWriter::isMultineArray(
const Value& value) {
478 int size = value.size();
479 bool isMultiLine = size * 3 >= rightMargin_;
480 childValues_.clear();
481 for (
int index = 0; index < size && !isMultiLine; ++index) {
482 const Value& childValue = value[index];
484 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
485 childValue.size() > 0);
489 childValues_.reserve(size);
490 addChildValues_ =
true;
491 int lineLength = 4 + (size - 1) * 2;
492 for (
int index = 0; index < size; ++index) {
493 if (hasCommentForValue(value[index])) {
496 writeValue(value[index]);
497 lineLength += int(childValues_[index].length());
499 addChildValues_ =
false;
500 isMultiLine = isMultiLine || lineLength >= rightMargin_;
505 void StyledWriter::pushValue(
const std::string& value) {
507 childValues_.push_back(value);
512 void StyledWriter::writeIndent() {
513 if (!document_.empty()) {
514 char last = document_[document_.length() - 1];
520 document_ += indentString_;
523 void StyledWriter::writeWithIndent(
const std::string& value) {
528 void StyledWriter::indent() { indentString_ += std::string(indentSize_,
' '); }
530 void StyledWriter::unindent() {
531 assert(
int(indentString_.size()) >= indentSize_);
532 indentString_.resize(indentString_.size() - indentSize_);
535 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
542 std::string::const_iterator iter = comment.begin();
543 while (iter != comment.end()) {
546 (iter != comment.end() && *(iter + 1) ==
'/'))
555 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
566 bool StyledWriter::hasCommentForValue(
const Value& value) {
576 : document_(NULL), rightMargin_(74), indentation_(indentation),
581 addChildValues_ =
false;
584 writeCommentBeforeValue(root);
585 if (!indented_) writeIndent();
588 writeCommentAfterValueOnSameLine(root);
593 void StyledStreamWriter::writeValue(
const Value& value) {
594 switch (value.
type()) {
621 writeArrayValue(value);
628 writeWithIndent(
"{");
630 Value::Members::iterator it = members.begin();
632 const std::string& name = *it;
633 const Value& childValue = value[name];
634 writeCommentBeforeValue(childValue);
637 writeValue(childValue);
638 if (++it == members.end()) {
639 writeCommentAfterValueOnSameLine(childValue);
643 writeCommentAfterValueOnSameLine(childValue);
646 writeWithIndent(
"}");
652 void StyledStreamWriter::writeArrayValue(
const Value& value) {
653 unsigned size = value.size();
657 bool isArrayMultiLine = isMultineArray(value);
658 if (isArrayMultiLine) {
659 writeWithIndent(
"[");
661 bool hasChildValue = !childValues_.empty();
664 const Value& childValue = value[index];
665 writeCommentBeforeValue(childValue);
667 writeWithIndent(childValues_[index]);
669 if (!indented_) writeIndent();
671 writeValue(childValue);
674 if (++index == size) {
675 writeCommentAfterValueOnSameLine(childValue);
679 writeCommentAfterValueOnSameLine(childValue);
682 writeWithIndent(
"]");
685 assert(childValues_.size() == size);
687 for (
unsigned index = 0; index < size; ++index) {
690 *document_ << childValues_[index];
697 bool StyledStreamWriter::isMultineArray(
const Value& value) {
698 int size = value.size();
699 bool isMultiLine = size * 3 >= rightMargin_;
700 childValues_.clear();
701 for (
int index = 0; index < size && !isMultiLine; ++index) {
702 const Value& childValue = value[index];
704 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
705 childValue.size() > 0);
709 childValues_.reserve(size);
710 addChildValues_ =
true;
711 int lineLength = 4 + (size - 1) * 2;
712 for (
int index = 0; index < size; ++index) {
713 if (hasCommentForValue(value[index])) {
716 writeValue(value[index]);
717 lineLength += int(childValues_[index].length());
719 addChildValues_ =
false;
720 isMultiLine = isMultiLine || lineLength >= rightMargin_;
725 void StyledStreamWriter::pushValue(
const std::string& value) {
727 childValues_.push_back(value);
732 void StyledStreamWriter::writeIndent() {
737 *document_ <<
'\n' << indentString_;
740 void StyledStreamWriter::writeWithIndent(
const std::string& value) {
741 if (!indented_) writeIndent();
746 void StyledStreamWriter::indent() { indentString_ += indentation_; }
748 void StyledStreamWriter::unindent() {
749 assert(indentString_.size() >= indentation_.size());
750 indentString_.resize(indentString_.size() - indentation_.size());
753 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
757 if (!indented_) writeIndent();
759 std::string::const_iterator iter = comment.begin();
760 while (iter != comment.end()) {
763 (iter != comment.end() && *(iter + 1) ==
'/'))
765 *document_ << indentString_;
771 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
782 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
792 struct CommentStyle {
801 struct BuiltStyledStreamWriter :
public StreamWriter
803 BuiltStyledStreamWriter(
804 std::string
const& indentation,
805 CommentStyle::Enum cs,
806 std::string
const& colonSymbol,
807 std::string
const& nullSymbol,
808 std::string
const& endingLineFeedSymbol);
809 virtual int write(Value
const& root, std::ostream* sout);
811 void writeValue(Value
const& value);
812 void writeArrayValue(Value
const& value);
813 bool isMultineArray(Value
const& value);
814 void pushValue(std::string
const& value);
816 void writeWithIndent(std::string
const& value);
819 void writeCommentBeforeValue(Value
const& root);
820 void writeCommentAfterValueOnSameLine(Value
const& root);
821 static bool hasCommentForValue(
const Value& value);
823 typedef std::vector<std::string> ChildValues;
825 ChildValues childValues_;
826 std::string indentString_;
828 std::string indentation_;
829 CommentStyle::Enum cs_;
830 std::string colonSymbol_;
831 std::string nullSymbol_;
832 std::string endingLineFeedSymbol_;
833 bool addChildValues_ : 1;
836 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
837 std::string
const& indentation,
838 CommentStyle::Enum cs,
839 std::string
const& colonSymbol,
840 std::string
const& nullSymbol,
841 std::string
const& endingLineFeedSymbol)
843 , indentation_(indentation)
845 , colonSymbol_(colonSymbol)
846 , nullSymbol_(nullSymbol)
847 , endingLineFeedSymbol_(endingLineFeedSymbol)
848 , addChildValues_(false)
852 int BuiltStyledStreamWriter::write(Value
const& root, std::ostream* sout)
855 addChildValues_ =
false;
858 writeCommentBeforeValue(root);
859 if (!indented_) writeIndent();
862 writeCommentAfterValueOnSameLine(root);
863 *sout_ << endingLineFeedSymbol_;
867 void BuiltStyledStreamWriter::writeValue(Value
const& value) {
868 switch (value.type()) {
870 pushValue(nullSymbol_);
886 bool ok = value.getString(&str, &end);
895 writeArrayValue(value);
902 writeWithIndent(
"{");
904 Value::Members::iterator it = members.begin();
906 std::string
const& name = *it;
907 Value
const& childValue = value[name];
908 writeCommentBeforeValue(childValue);
910 *sout_ << colonSymbol_;
911 writeValue(childValue);
912 if (++it == members.end()) {
913 writeCommentAfterValueOnSameLine(childValue);
917 writeCommentAfterValueOnSameLine(childValue);
920 writeWithIndent(
"}");
926 void BuiltStyledStreamWriter::writeArrayValue(Value
const& value) {
927 unsigned size = value.size();
931 bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
933 writeWithIndent(
"[");
935 bool hasChildValue = !childValues_.empty();
938 Value
const& childValue = value[index];
939 writeCommentBeforeValue(childValue);
941 writeWithIndent(childValues_[index]);
943 if (!indented_) writeIndent();
945 writeValue(childValue);
948 if (++index == size) {
949 writeCommentAfterValueOnSameLine(childValue);
953 writeCommentAfterValueOnSameLine(childValue);
956 writeWithIndent(
"]");
959 assert(childValues_.size() == size);
961 if (!indentation_.empty()) *sout_ <<
" ";
962 for (
unsigned index = 0; index < size; ++index) {
965 *sout_ << childValues_[index];
967 if (!indentation_.empty()) *sout_ <<
" ";
973 bool BuiltStyledStreamWriter::isMultineArray(Value
const& value) {
974 int size = value.size();
975 bool isMultiLine = size * 3 >= rightMargin_;
976 childValues_.clear();
977 for (
int index = 0; index < size && !isMultiLine; ++index) {
978 Value
const& childValue = value[index];
980 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
981 childValue.size() > 0);
985 childValues_.reserve(size);
986 addChildValues_ =
true;
987 int lineLength = 4 + (size - 1) * 2;
988 for (
int index = 0; index < size; ++index) {
989 if (hasCommentForValue(value[index])) {
992 writeValue(value[index]);
993 lineLength += int(childValues_[index].length());
995 addChildValues_ =
false;
996 isMultiLine = isMultiLine || lineLength >= rightMargin_;
1001 void BuiltStyledStreamWriter::pushValue(std::string
const& value) {
1002 if (addChildValues_)
1003 childValues_.push_back(value);
1008 void BuiltStyledStreamWriter::writeIndent() {
1014 if (!indentation_.empty()) {
1016 *sout_ <<
'\n' << indentString_;
1020 void BuiltStyledStreamWriter::writeWithIndent(std::string
const& value) {
1021 if (!indented_) writeIndent();
1026 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1028 void BuiltStyledStreamWriter::unindent() {
1029 assert(indentString_.size() >= indentation_.size());
1030 indentString_.resize(indentString_.size() - indentation_.size());
1033 void BuiltStyledStreamWriter::writeCommentBeforeValue(Value
const& root) {
1034 if (cs_ == CommentStyle::None)
return;
1038 if (!indented_) writeIndent();
1039 const std::string& comment = root.getComment(
commentBefore);
1040 std::string::const_iterator iter = comment.begin();
1041 while (iter != comment.end()) {
1043 if (*iter ==
'\n' &&
1044 (iter != comment.end() && *(iter + 1) ==
'/'))
1046 *sout_ << indentString_;
1052 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value
const& root) {
1053 if (cs_ == CommentStyle::None)
return;
1064 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1084 setDefaults(&settings_);
1090 std::string indentation = settings_[
"indentation"].asString();
1091 std::string cs_str = settings_[
"commentStyle"].asString();
1092 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1093 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1094 CommentStyle::Enum cs = CommentStyle::All;
1095 if (cs_str ==
"All") {
1096 cs = CommentStyle::All;
1097 }
else if (cs_str ==
"None") {
1098 cs = CommentStyle::None;
1102 std::string colonSymbol =
" : ";
1105 }
else if (indentation.empty()) {
1108 std::string nullSymbol =
"null";
1112 std::string endingLineFeedSymbol =
"";
1113 return new BuiltStyledStreamWriter(
1115 colonSymbol, nullSymbol, endingLineFeedSymbol);
1119 valid_keys->clear();
1120 valid_keys->insert(
"indentation");
1121 valid_keys->insert(
"commentStyle");
1122 valid_keys->insert(
"enableYAMLCompatibility");
1123 valid_keys->insert(
"dropNullPlaceholders");
1128 if (!invalid) invalid = &my_invalid;
1130 std::set<std::string> valid_keys;
1133 size_t n = keys.size();
1134 for (
size_t i = 0; i < n; ++i) {
1135 std::string
const& key = keys[i];
1136 if (valid_keys.find(key) == valid_keys.end()) {
1137 inv[key] = settings_[key];
1140 return 0u == inv.
size();
1144 return settings_[key];
1150 (*settings)[
"commentStyle"] =
"All";
1151 (*settings)[
"indentation"] =
"\t";
1152 (*settings)[
"enableYAMLCompatibility"] =
false;
1153 (*settings)[
"dropNullPlaceholders"] =
false;
1158 std::ostringstream sout;
1160 writer->write(root, &sout);
1167 writer->write(root, &sout);
Value & operator[](std::string key)
A simple way to update a specific setting.
A simple abstract factory.
void omitEndingLineFeed()
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
void dropNullPlaceholders()
Drop the "null" string from the writer's output for nullValues.
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().