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) 62 char const* end = str + len;
73 char* current = buffer +
sizeof(buffer);
74 bool isNegative = value < 0;
80 assert(current >= buffer);
86 char* current = buffer +
sizeof(buffer);
88 assert(current >= buffer);
92 #if defined(JSON_HAS_INT64) 102 #endif // # if defined(JSON_HAS_INT64) 113 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with 117 len = _snprintf(buffer,
sizeof(buffer),
"%.17g", value);
119 len = sprintf_s(buffer,
sizeof(buffer),
"%.17g", value);
123 len =
snprintf(buffer,
sizeof(buffer),
"%.17g", value);
126 if (value != value) {
127 len =
snprintf(buffer,
sizeof(buffer),
"null");
128 }
else if (value < 0) {
129 len =
snprintf(buffer,
sizeof(buffer),
"-1e+9999");
131 len =
snprintf(buffer,
sizeof(buffer),
"1e+9999");
147 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
149 return std::string(
"\"") + value +
"\"";
153 std::string::size_type maxsize =
154 strlen(value) * 2 + 3;
156 result.reserve(maxsize);
158 for (
const char* c = value; *c != 0; ++c) {
191 std::ostringstream oss;
192 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
193 << std::setw(4) <<
static_cast<int>(*c);
206 static char const*
strnpbrk(
char const* s,
char const* accept,
size_t n) {
207 assert((s || !n) && accept);
209 char const*
const end = s + n;
210 for (
char const* cur = s; cur < end; ++cur) {
212 for (
char const* a = accept; *a; ++a) {
224 if (
strnpbrk(value,
"\"\\\b\f\n\r\t", length) == NULL &&
226 return std::string(
"\"") + value +
"\"";
230 std::string::size_type maxsize =
233 result.reserve(maxsize);
235 char const* end = value + length;
236 for (
const char* c = value; c != end; ++c) {
269 std::ostringstream oss;
270 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
271 << std::setw(4) <<
static_cast<int>(*c);
291 : yamlCompatiblityEnabled_(false) {}
302 void FastWriter::writeValue(
const Value& value) {
303 switch (value.
type()) {
330 int size = value.
size();
331 for (
int index = 0; index < size; ++index) {
334 writeValue(value[index]);
341 for (Value::Members::iterator it = members.begin(); it != members.end();
343 const std::string& name = *it;
344 if (it != members.begin())
347 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
348 writeValue(value[name]);
359 : rightMargin_(74), indentSize_(3), addChildValues_() {}
363 addChildValues_ =
false;
365 writeCommentBeforeValue(root);
367 writeCommentAfterValueOnSameLine(root);
372 void StyledWriter::writeValue(
const Value& value) {
373 switch (value.
type()) {
400 writeArrayValue(value);
407 writeWithIndent(
"{");
409 Value::Members::iterator it = members.begin();
411 const std::string& name = *it;
412 const Value& childValue = value[name];
413 writeCommentBeforeValue(childValue);
416 writeValue(childValue);
417 if (++it == members.end()) {
418 writeCommentAfterValueOnSameLine(childValue);
422 writeCommentAfterValueOnSameLine(childValue);
425 writeWithIndent(
"}");
431 void StyledWriter::writeArrayValue(
const Value& value) {
432 unsigned size = value.
size();
436 bool isArrayMultiLine = isMultineArray(value);
437 if (isArrayMultiLine) {
438 writeWithIndent(
"[");
440 bool hasChildValue = !childValues_.empty();
443 const Value& childValue = value[index];
444 writeCommentBeforeValue(childValue);
446 writeWithIndent(childValues_[index]);
449 writeValue(childValue);
451 if (++index == size) {
452 writeCommentAfterValueOnSameLine(childValue);
456 writeCommentAfterValueOnSameLine(childValue);
459 writeWithIndent(
"]");
462 assert(childValues_.size() == size);
464 for (
unsigned index = 0; index < size; ++index) {
467 document_ += childValues_[index];
474 bool StyledWriter::isMultineArray(
const Value& value) {
475 int size = value.
size();
476 bool isMultiLine = size * 3 >= rightMargin_;
477 childValues_.clear();
478 for (
int index = 0; index < size && !isMultiLine; ++index) {
479 const Value& childValue = value[index];
482 childValue.
size() > 0);
486 childValues_.reserve(size);
487 addChildValues_ =
true;
488 int lineLength = 4 + (size - 1) * 2;
489 for (
int index = 0; index < size; ++index) {
490 if (hasCommentForValue(value[index])) {
493 writeValue(value[index]);
494 lineLength += int(childValues_[index].length());
496 addChildValues_ =
false;
497 isMultiLine = isMultiLine || lineLength >= rightMargin_;
502 void StyledWriter::pushValue(
const std::string& value) {
504 childValues_.push_back(value);
509 void StyledWriter::writeIndent() {
510 if (!document_.empty()) {
511 char last = document_[document_.length() - 1];
517 document_ += indentString_;
520 void StyledWriter::writeWithIndent(
const std::string& value) {
525 void StyledWriter::indent() { indentString_ += std::string(indentSize_,
' '); }
527 void StyledWriter::unindent() {
528 assert(
int(indentString_.size()) >= indentSize_);
529 indentString_.resize(indentString_.size() - indentSize_);
532 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
539 std::string::const_iterator iter = comment.begin();
540 while (iter != comment.end()) {
543 (iter != comment.end() && *(iter + 1) ==
'/'))
552 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
563 bool StyledWriter::hasCommentForValue(
const Value& value) {
573 : document_(NULL), rightMargin_(74), indentation_(indentation),
578 addChildValues_ =
false;
581 writeCommentBeforeValue(root);
582 if (!indented_) writeIndent();
585 writeCommentAfterValueOnSameLine(root);
590 void StyledStreamWriter::writeValue(
const Value& value) {
591 switch (value.
type()) {
618 writeArrayValue(value);
625 writeWithIndent(
"{");
627 Value::Members::iterator it = members.begin();
629 const std::string& name = *it;
630 const Value& childValue = value[name];
631 writeCommentBeforeValue(childValue);
634 writeValue(childValue);
635 if (++it == members.end()) {
636 writeCommentAfterValueOnSameLine(childValue);
640 writeCommentAfterValueOnSameLine(childValue);
643 writeWithIndent(
"}");
649 void StyledStreamWriter::writeArrayValue(
const Value& value) {
650 unsigned size = value.
size();
654 bool isArrayMultiLine = isMultineArray(value);
655 if (isArrayMultiLine) {
656 writeWithIndent(
"[");
658 bool hasChildValue = !childValues_.empty();
661 const Value& childValue = value[index];
662 writeCommentBeforeValue(childValue);
664 writeWithIndent(childValues_[index]);
666 if (!indented_) writeIndent();
668 writeValue(childValue);
671 if (++index == size) {
672 writeCommentAfterValueOnSameLine(childValue);
676 writeCommentAfterValueOnSameLine(childValue);
679 writeWithIndent(
"]");
682 assert(childValues_.size() == size);
684 for (
unsigned index = 0; index < size; ++index) {
687 *document_ << childValues_[index];
694 bool StyledStreamWriter::isMultineArray(
const Value& value) {
695 int size = value.
size();
696 bool isMultiLine = size * 3 >= rightMargin_;
697 childValues_.clear();
698 for (
int index = 0; index < size && !isMultiLine; ++index) {
699 const Value& childValue = value[index];
702 childValue.
size() > 0);
706 childValues_.reserve(size);
707 addChildValues_ =
true;
708 int lineLength = 4 + (size - 1) * 2;
709 for (
int index = 0; index < size; ++index) {
710 if (hasCommentForValue(value[index])) {
713 writeValue(value[index]);
714 lineLength += int(childValues_[index].length());
716 addChildValues_ =
false;
717 isMultiLine = isMultiLine || lineLength >= rightMargin_;
722 void StyledStreamWriter::pushValue(
const std::string& value) {
724 childValues_.push_back(value);
729 void StyledStreamWriter::writeIndent() {
734 *document_ <<
'\n' << indentString_;
737 void StyledStreamWriter::writeWithIndent(
const std::string& value) {
738 if (!indented_) writeIndent();
743 void StyledStreamWriter::indent() { indentString_ += indentation_; }
745 void StyledStreamWriter::unindent() {
746 assert(indentString_.size() >= indentation_.size());
747 indentString_.resize(indentString_.size() - indentation_.size());
750 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
754 if (!indented_) writeIndent();
756 std::string::const_iterator iter = comment.begin();
757 while (iter != comment.end()) {
760 (iter != comment.end() && *(iter + 1) ==
'/'))
762 *document_ << indentString_;
768 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
779 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
789 struct CommentStyle {
800 BuiltStyledStreamWriter(
801 std::string
const& indentation,
802 CommentStyle::Enum cs,
803 std::string
const& colonSymbol,
804 std::string
const& nullSymbol,
805 std::string
const& endingLineFeedSymbol);
806 virtual int write(
Value const& root, std::ostream* sout);
808 void writeValue(
Value const& value);
809 void writeArrayValue(
Value const& value);
810 bool isMultineArray(
Value const& value);
811 void pushValue(std::string
const& value);
813 void writeWithIndent(std::string
const& value);
816 void writeCommentBeforeValue(
Value const& root);
817 void writeCommentAfterValueOnSameLine(
Value const& root);
818 static bool hasCommentForValue(
const Value& value);
820 typedef std::vector<std::string> ChildValues;
822 ChildValues childValues_;
823 std::string indentString_;
825 std::string indentation_;
826 CommentStyle::Enum cs_;
827 std::string colonSymbol_;
828 std::string nullSymbol_;
829 std::string endingLineFeedSymbol_;
830 bool addChildValues_ : 1;
833 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
834 std::string
const& indentation,
835 CommentStyle::Enum cs,
836 std::string
const& colonSymbol,
837 std::string
const& nullSymbol,
838 std::string
const& endingLineFeedSymbol)
840 , indentation_(indentation)
842 , colonSymbol_(colonSymbol)
843 , nullSymbol_(nullSymbol)
844 , endingLineFeedSymbol_(endingLineFeedSymbol)
845 , addChildValues_(
false)
849 int BuiltStyledStreamWriter::write(
Value const& root, std::ostream* sout)
852 addChildValues_ =
false;
855 writeCommentBeforeValue(root);
856 if (!indented_) writeIndent();
859 writeCommentAfterValueOnSameLine(root);
860 *sout_ << endingLineFeedSymbol_;
864 void BuiltStyledStreamWriter::writeValue(
Value const& value) {
865 switch (value.
type()) {
867 pushValue(nullSymbol_);
892 writeArrayValue(value);
899 writeWithIndent(
"{");
901 Value::Members::iterator it = members.begin();
903 std::string
const& name = *it;
904 Value const& childValue = value[name];
905 writeCommentBeforeValue(childValue);
907 *sout_ << colonSymbol_;
908 writeValue(childValue);
909 if (++it == members.end()) {
910 writeCommentAfterValueOnSameLine(childValue);
914 writeCommentAfterValueOnSameLine(childValue);
917 writeWithIndent(
"}");
923 void BuiltStyledStreamWriter::writeArrayValue(
Value const& value) {
924 unsigned size = value.
size();
928 bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
930 writeWithIndent(
"[");
932 bool hasChildValue = !childValues_.empty();
935 Value const& childValue = value[index];
936 writeCommentBeforeValue(childValue);
938 writeWithIndent(childValues_[index]);
940 if (!indented_) writeIndent();
942 writeValue(childValue);
945 if (++index == size) {
946 writeCommentAfterValueOnSameLine(childValue);
950 writeCommentAfterValueOnSameLine(childValue);
953 writeWithIndent(
"]");
956 assert(childValues_.size() == size);
958 if (!indentation_.empty()) *sout_ <<
" ";
959 for (
unsigned index = 0; index < size; ++index) {
962 *sout_ << childValues_[index];
964 if (!indentation_.empty()) *sout_ <<
" ";
970 bool BuiltStyledStreamWriter::isMultineArray(
Value const& value) {
971 int size = value.
size();
972 bool isMultiLine = size * 3 >= rightMargin_;
973 childValues_.clear();
974 for (
int index = 0; index < size && !isMultiLine; ++index) {
975 Value const& childValue = value[index];
978 childValue.
size() > 0);
982 childValues_.reserve(size);
983 addChildValues_ =
true;
984 int lineLength = 4 + (size - 1) * 2;
985 for (
int index = 0; index < size; ++index) {
986 if (hasCommentForValue(value[index])) {
989 writeValue(value[index]);
990 lineLength += int(childValues_[index].length());
992 addChildValues_ =
false;
993 isMultiLine = isMultiLine || lineLength >= rightMargin_;
998 void BuiltStyledStreamWriter::pushValue(std::string
const& value) {
1000 childValues_.push_back(value);
1005 void BuiltStyledStreamWriter::writeIndent() {
1011 if (!indentation_.empty()) {
1013 *sout_ <<
'\n' << indentString_;
1017 void BuiltStyledStreamWriter::writeWithIndent(std::string
const& value) {
1018 if (!indented_) writeIndent();
1023 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1025 void BuiltStyledStreamWriter::unindent() {
1026 assert(indentString_.size() >= indentation_.size());
1027 indentString_.resize(indentString_.size() - indentation_.size());
1030 void BuiltStyledStreamWriter::writeCommentBeforeValue(
Value const& root) {
1031 if (cs_ == CommentStyle::None)
return;
1035 if (!indented_) writeIndent();
1037 std::string::const_iterator iter = comment.begin();
1038 while (iter != comment.end()) {
1040 if (*iter ==
'\n' &&
1041 (iter != comment.end() && *(iter + 1) ==
'/'))
1043 *sout_ << indentString_;
1049 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
Value const& root) {
1050 if (cs_ == CommentStyle::None)
return;
1061 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1081 setDefaults(&settings_);
1087 std::string indentation = settings_[
"indentation"].asString();
1088 std::string cs_str = settings_[
"commentStyle"].asString();
1089 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1090 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1091 CommentStyle::Enum cs = CommentStyle::All;
1092 if (cs_str ==
"All") {
1093 cs = CommentStyle::All;
1094 }
else if (cs_str ==
"None") {
1095 cs = CommentStyle::None;
1099 std::string colonSymbol =
" : ";
1102 }
else if (indentation.empty()) {
1105 std::string nullSymbol =
"null";
1109 std::string endingLineFeedSymbol =
"";
1110 return new BuiltStyledStreamWriter(
1112 colonSymbol, nullSymbol, endingLineFeedSymbol);
1116 valid_keys->clear();
1117 valid_keys->insert(
"indentation");
1118 valid_keys->insert(
"commentStyle");
1119 valid_keys->insert(
"enableYAMLCompatibility");
1120 valid_keys->insert(
"dropNullPlaceholders");
1125 if (!invalid) invalid = &my_invalid;
1127 std::set<std::string> valid_keys;
1130 size_t n = keys.size();
1131 for (
size_t i = 0; i < n; ++i) {
1132 std::string
const& key = keys[i];
1133 if (valid_keys.find(key) == valid_keys.end()) {
1134 inv[key] = settings_[key];
1137 return 0u == inv.
size();
1141 return settings_[key];
1147 (*settings)[
"commentStyle"] =
"All";
1148 (*settings)[
"indentation"] =
"\t";
1149 (*settings)[
"enableYAMLCompatibility"] =
false;
1150 (*settings)[
"dropNullPlaceholders"] =
false;
1155 std::ostringstream sout;
1157 writer->write(root, &sout);
1164 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.
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::ostream & operator<<(std::ostream &, const Value &root)
Output using the StyledStreamWriter.
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()
virtual StreamWriter * newStreamWriter() const =0
Allocate a CharReader via operator new().
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
Build a StreamWriter implementation.
bool getString(char const **begin, char const **end) const
Get raw char* of string-value.