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 defined(__ANDROID__) 33 #define snprintf snprintf 34 #elif __cplusplus >= 201103L 35 #define snprintf std::snprintf 38 #if defined(__BORLANDC__) 40 #define isfinite _finite 41 #define snprintf _snprintf 44 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 46 #pragma warning(disable : 4996) 51 #if __cplusplus >= 201103L 66 char const* end = str + len;
77 char* current = buffer +
sizeof(buffer);
78 bool isNegative = value < 0;
84 assert(current >= buffer);
90 char* current = buffer +
sizeof(buffer);
92 assert(current >= buffer);
96 #if defined(JSON_HAS_INT64) 106 #endif // # if defined(JSON_HAS_INT64) 117 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with 121 len = _snprintf(buffer,
sizeof(buffer),
"%.17g", value);
123 len = sprintf_s(buffer,
sizeof(buffer),
"%.17g", value);
127 len =
snprintf(buffer,
sizeof(buffer),
"%.17g", value);
130 if (value != value) {
131 len =
snprintf(buffer,
sizeof(buffer),
"null");
132 }
else if (value < 0) {
133 len =
snprintf(buffer,
sizeof(buffer),
"-1e+9999");
135 len =
snprintf(buffer,
sizeof(buffer),
"1e+9999");
151 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
153 return std::string(
"\"") + value +
"\"";
157 std::string::size_type maxsize =
158 strlen(value) * 2 + 3;
160 result.reserve(maxsize);
162 for (
const char* c = value; *c != 0; ++c) {
195 std::ostringstream oss;
196 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
197 << std::setw(4) <<
static_cast<int>(*c);
210 static char const*
strnpbrk(
char const* s,
char const* accept,
size_t n) {
211 assert((s || !n) && accept);
213 char const*
const end = s + n;
214 for (
char const* cur = s; cur < end; ++cur) {
216 for (
char const* a = accept; *a; ++a) {
228 if (
strnpbrk(value,
"\"\\\b\f\n\r\t", length) == NULL &&
230 return std::string(
"\"") + value +
"\"";
234 std::string::size_type maxsize =
237 result.reserve(maxsize);
239 char const* end = value + length;
240 for (
const char* c = value; c != end; ++c) {
273 std::ostringstream oss;
274 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
275 << std::setw(4) <<
static_cast<int>(*c);
295 : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
296 omitEndingLineFeed_(false) {}
307 if (!omitEndingLineFeed_)
312 void FastWriter::writeValue(
const Value& value) {
313 switch (value.
type()) {
315 if (!dropNullPlaceholders_)
341 int size = value.
size();
342 for (
int index = 0; index < size; ++index) {
345 writeValue(value[index]);
352 for (Value::Members::iterator it = members.begin(); it != members.end();
354 const std::string& name = *it;
355 if (it != members.begin())
358 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
359 writeValue(value[name]);
370 : rightMargin_(74), indentSize_(3), addChildValues_() {}
374 addChildValues_ =
false;
376 writeCommentBeforeValue(root);
378 writeCommentAfterValueOnSameLine(root);
383 void StyledWriter::writeValue(
const Value& value) {
384 switch (value.
type()) {
411 writeArrayValue(value);
418 writeWithIndent(
"{");
420 Value::Members::iterator it = members.begin();
422 const std::string& name = *it;
423 const Value& childValue = value[name];
424 writeCommentBeforeValue(childValue);
427 writeValue(childValue);
428 if (++it == members.end()) {
429 writeCommentAfterValueOnSameLine(childValue);
433 writeCommentAfterValueOnSameLine(childValue);
436 writeWithIndent(
"}");
442 void StyledWriter::writeArrayValue(
const Value& value) {
443 unsigned size = value.
size();
447 bool isArrayMultiLine = isMultineArray(value);
448 if (isArrayMultiLine) {
449 writeWithIndent(
"[");
451 bool hasChildValue = !childValues_.empty();
454 const Value& childValue = value[index];
455 writeCommentBeforeValue(childValue);
457 writeWithIndent(childValues_[index]);
460 writeValue(childValue);
462 if (++index == size) {
463 writeCommentAfterValueOnSameLine(childValue);
467 writeCommentAfterValueOnSameLine(childValue);
470 writeWithIndent(
"]");
473 assert(childValues_.size() == size);
475 for (
unsigned index = 0; index < size; ++index) {
478 document_ += childValues_[index];
485 bool StyledWriter::isMultineArray(
const Value& value) {
486 int size = value.
size();
487 bool isMultiLine = size * 3 >= rightMargin_;
488 childValues_.clear();
489 for (
int index = 0; index < size && !isMultiLine; ++index) {
490 const Value& childValue = value[index];
493 childValue.
size() > 0);
497 childValues_.reserve(size);
498 addChildValues_ =
true;
499 int lineLength = 4 + (size - 1) * 2;
500 for (
int index = 0; index < size; ++index) {
501 if (hasCommentForValue(value[index])) {
504 writeValue(value[index]);
505 lineLength += int(childValues_[index].length());
507 addChildValues_ =
false;
508 isMultiLine = isMultiLine || lineLength >= rightMargin_;
513 void StyledWriter::pushValue(
const std::string& value) {
515 childValues_.push_back(value);
520 void StyledWriter::writeIndent() {
521 if (!document_.empty()) {
522 char last = document_[document_.length() - 1];
528 document_ += indentString_;
531 void StyledWriter::writeWithIndent(
const std::string& value) {
536 void StyledWriter::indent() { indentString_ += std::string(indentSize_,
' '); }
538 void StyledWriter::unindent() {
539 assert(
int(indentString_.size()) >= indentSize_);
540 indentString_.resize(indentString_.size() - indentSize_);
543 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
550 std::string::const_iterator iter = comment.begin();
551 while (iter != comment.end()) {
554 (iter != comment.end() && *(iter + 1) ==
'/'))
563 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
574 bool StyledWriter::hasCommentForValue(
const Value& value) {
584 : document_(NULL), rightMargin_(74), indentation_(indentation),
589 addChildValues_ =
false;
592 writeCommentBeforeValue(root);
593 if (!indented_) writeIndent();
596 writeCommentAfterValueOnSameLine(root);
601 void StyledStreamWriter::writeValue(
const Value& value) {
602 switch (value.
type()) {
629 writeArrayValue(value);
636 writeWithIndent(
"{");
638 Value::Members::iterator it = members.begin();
640 const std::string& name = *it;
641 const Value& childValue = value[name];
642 writeCommentBeforeValue(childValue);
645 writeValue(childValue);
646 if (++it == members.end()) {
647 writeCommentAfterValueOnSameLine(childValue);
651 writeCommentAfterValueOnSameLine(childValue);
654 writeWithIndent(
"}");
660 void StyledStreamWriter::writeArrayValue(
const Value& value) {
661 unsigned size = value.
size();
665 bool isArrayMultiLine = isMultineArray(value);
666 if (isArrayMultiLine) {
667 writeWithIndent(
"[");
669 bool hasChildValue = !childValues_.empty();
672 const Value& childValue = value[index];
673 writeCommentBeforeValue(childValue);
675 writeWithIndent(childValues_[index]);
677 if (!indented_) writeIndent();
679 writeValue(childValue);
682 if (++index == size) {
683 writeCommentAfterValueOnSameLine(childValue);
687 writeCommentAfterValueOnSameLine(childValue);
690 writeWithIndent(
"]");
693 assert(childValues_.size() == size);
695 for (
unsigned index = 0; index < size; ++index) {
698 *document_ << childValues_[index];
705 bool StyledStreamWriter::isMultineArray(
const Value& value) {
706 int size = value.
size();
707 bool isMultiLine = size * 3 >= rightMargin_;
708 childValues_.clear();
709 for (
int index = 0; index < size && !isMultiLine; ++index) {
710 const Value& childValue = value[index];
713 childValue.
size() > 0);
717 childValues_.reserve(size);
718 addChildValues_ =
true;
719 int lineLength = 4 + (size - 1) * 2;
720 for (
int index = 0; index < size; ++index) {
721 if (hasCommentForValue(value[index])) {
724 writeValue(value[index]);
725 lineLength += int(childValues_[index].length());
727 addChildValues_ =
false;
728 isMultiLine = isMultiLine || lineLength >= rightMargin_;
733 void StyledStreamWriter::pushValue(
const std::string& value) {
735 childValues_.push_back(value);
740 void StyledStreamWriter::writeIndent() {
745 *document_ <<
'\n' << indentString_;
748 void StyledStreamWriter::writeWithIndent(
const std::string& value) {
749 if (!indented_) writeIndent();
754 void StyledStreamWriter::indent() { indentString_ += indentation_; }
756 void StyledStreamWriter::unindent() {
757 assert(indentString_.size() >= indentation_.size());
758 indentString_.resize(indentString_.size() - indentation_.size());
761 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
765 if (!indented_) writeIndent();
767 std::string::const_iterator iter = comment.begin();
768 while (iter != comment.end()) {
771 (iter != comment.end() && *(iter + 1) ==
'/'))
773 *document_ << indentString_;
779 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
790 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
800 struct CommentStyle {
811 BuiltStyledStreamWriter(
812 std::string
const& indentation,
813 CommentStyle::Enum cs,
814 std::string
const& colonSymbol,
815 std::string
const& nullSymbol,
816 std::string
const& endingLineFeedSymbol);
817 virtual int write(
Value const& root, std::ostream* sout);
819 void writeValue(
Value const& value);
820 void writeArrayValue(
Value const& value);
821 bool isMultineArray(
Value const& value);
822 void pushValue(std::string
const& value);
824 void writeWithIndent(std::string
const& value);
827 void writeCommentBeforeValue(
Value const& root);
828 void writeCommentAfterValueOnSameLine(
Value const& root);
829 static bool hasCommentForValue(
const Value& value);
831 typedef std::vector<std::string> ChildValues;
833 ChildValues childValues_;
834 std::string indentString_;
836 std::string indentation_;
837 CommentStyle::Enum cs_;
838 std::string colonSymbol_;
839 std::string nullSymbol_;
840 std::string endingLineFeedSymbol_;
841 bool addChildValues_ : 1;
844 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
845 std::string
const& indentation,
846 CommentStyle::Enum cs,
847 std::string
const& colonSymbol,
848 std::string
const& nullSymbol,
849 std::string
const& endingLineFeedSymbol)
851 , indentation_(indentation)
853 , colonSymbol_(colonSymbol)
854 , nullSymbol_(nullSymbol)
855 , endingLineFeedSymbol_(endingLineFeedSymbol)
856 , addChildValues_(
false)
860 int BuiltStyledStreamWriter::write(
Value const& root, std::ostream* sout)
863 addChildValues_ =
false;
866 writeCommentBeforeValue(root);
867 if (!indented_) writeIndent();
870 writeCommentAfterValueOnSameLine(root);
871 *sout_ << endingLineFeedSymbol_;
875 void BuiltStyledStreamWriter::writeValue(
Value const& value) {
876 switch (value.
type()) {
878 pushValue(nullSymbol_);
903 writeArrayValue(value);
910 writeWithIndent(
"{");
912 Value::Members::iterator it = members.begin();
914 std::string
const& name = *it;
915 Value const& childValue = value[name];
916 writeCommentBeforeValue(childValue);
918 *sout_ << colonSymbol_;
919 writeValue(childValue);
920 if (++it == members.end()) {
921 writeCommentAfterValueOnSameLine(childValue);
925 writeCommentAfterValueOnSameLine(childValue);
928 writeWithIndent(
"}");
934 void BuiltStyledStreamWriter::writeArrayValue(
Value const& value) {
935 unsigned size = value.
size();
939 bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
941 writeWithIndent(
"[");
943 bool hasChildValue = !childValues_.empty();
946 Value const& childValue = value[index];
947 writeCommentBeforeValue(childValue);
949 writeWithIndent(childValues_[index]);
951 if (!indented_) writeIndent();
953 writeValue(childValue);
956 if (++index == size) {
957 writeCommentAfterValueOnSameLine(childValue);
961 writeCommentAfterValueOnSameLine(childValue);
964 writeWithIndent(
"]");
967 assert(childValues_.size() == size);
969 if (!indentation_.empty()) *sout_ <<
" ";
970 for (
unsigned index = 0; index < size; ++index) {
973 *sout_ << childValues_[index];
975 if (!indentation_.empty()) *sout_ <<
" ";
981 bool BuiltStyledStreamWriter::isMultineArray(
Value const& value) {
982 int size = value.
size();
983 bool isMultiLine = size * 3 >= rightMargin_;
984 childValues_.clear();
985 for (
int index = 0; index < size && !isMultiLine; ++index) {
986 Value const& childValue = value[index];
989 childValue.
size() > 0);
993 childValues_.reserve(size);
994 addChildValues_ =
true;
995 int lineLength = 4 + (size - 1) * 2;
996 for (
int index = 0; index < size; ++index) {
997 if (hasCommentForValue(value[index])) {
1000 writeValue(value[index]);
1001 lineLength += int(childValues_[index].length());
1003 addChildValues_ =
false;
1004 isMultiLine = isMultiLine || lineLength >= rightMargin_;
1009 void BuiltStyledStreamWriter::pushValue(std::string
const& value) {
1010 if (addChildValues_)
1011 childValues_.push_back(value);
1016 void BuiltStyledStreamWriter::writeIndent() {
1022 if (!indentation_.empty()) {
1024 *sout_ <<
'\n' << indentString_;
1028 void BuiltStyledStreamWriter::writeWithIndent(std::string
const& value) {
1029 if (!indented_) writeIndent();
1034 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1036 void BuiltStyledStreamWriter::unindent() {
1037 assert(indentString_.size() >= indentation_.size());
1038 indentString_.resize(indentString_.size() - indentation_.size());
1041 void BuiltStyledStreamWriter::writeCommentBeforeValue(
Value const& root) {
1042 if (cs_ == CommentStyle::None)
return;
1046 if (!indented_) writeIndent();
1048 std::string::const_iterator iter = comment.begin();
1049 while (iter != comment.end()) {
1051 if (*iter ==
'\n' &&
1052 (iter != comment.end() && *(iter + 1) ==
'/'))
1054 *sout_ << indentString_;
1060 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
Value const& root) {
1061 if (cs_ == CommentStyle::None)
return;
1072 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1092 setDefaults(&settings_);
1098 std::string indentation = settings_[
"indentation"].asString();
1099 std::string cs_str = settings_[
"commentStyle"].asString();
1100 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1101 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1102 CommentStyle::Enum cs = CommentStyle::All;
1103 if (cs_str ==
"All") {
1104 cs = CommentStyle::All;
1105 }
else if (cs_str ==
"None") {
1106 cs = CommentStyle::None;
1110 std::string colonSymbol =
" : ";
1113 }
else if (indentation.empty()) {
1116 std::string nullSymbol =
"null";
1120 std::string endingLineFeedSymbol =
"";
1121 return new BuiltStyledStreamWriter(
1123 colonSymbol, nullSymbol, endingLineFeedSymbol);
1127 valid_keys->clear();
1128 valid_keys->insert(
"indentation");
1129 valid_keys->insert(
"commentStyle");
1130 valid_keys->insert(
"enableYAMLCompatibility");
1131 valid_keys->insert(
"dropNullPlaceholders");
1136 if (!invalid) invalid = &my_invalid;
1138 std::set<std::string> valid_keys;
1141 size_t n = keys.size();
1142 for (
size_t i = 0; i < n; ++i) {
1143 std::string
const& key = keys[i];
1144 if (valid_keys.find(key) == valid_keys.end()) {
1145 inv[key] = settings_[key];
1148 return 0u == inv.
size();
1152 return settings_[key];
1158 (*settings)[
"commentStyle"] =
"All";
1159 (*settings)[
"indentation"] =
"\t";
1160 (*settings)[
"enableYAMLCompatibility"] =
false;
1161 (*settings)[
"dropNullPlaceholders"] =
false;
1166 std::ostringstream sout;
1168 writer->write(root, &sout);
1175 writer->write(root, &sout);
bool hasComment(CommentPlacement placement) const
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
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 [1,31]).
static void fixNumericLocale(char *begin, char *end)
Change ',' to '.
static void getValidWriterKeys(std::set< std::string > *valid_keys)
std::string getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
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().
bool getString(char const **begin, char const **end) const
Get raw char* of string-value.