6 #if !defined(JSON_IS_AMALGAMATION)
9 #endif // if !defined(JSON_IS_AMALGAMATION)
18 #if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
20 #define isfinite _finite
21 #define snprintf _snprintf
24 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
26 #pragma warning(disable : 4996)
29 #if defined(__sun) && defined(__SVR4) //Solaris
31 #define isfinite finite
46 char* current = buffer +
sizeof(buffer);
47 bool isNegative = value < 0;
53 assert(current >= buffer);
59 char* current = buffer +
sizeof(buffer);
61 assert(current >= buffer);
65 #if defined(JSON_HAS_INT64)
75 #endif // # if defined(JSON_HAS_INT64)
86 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with
90 len = _snprintf(buffer,
sizeof(buffer),
"%.16g", value);
92 len = sprintf_s(buffer,
sizeof(buffer),
"%.16g", value);
96 len =
snprintf(buffer,
sizeof(buffer),
"%.16g", value);
100 len =
snprintf(buffer,
sizeof(buffer),
"null");
101 }
else if (value < 0) {
102 len =
snprintf(buffer,
sizeof(buffer),
"-1e+9999");
104 len =
snprintf(buffer,
sizeof(buffer),
"1e+9999");
120 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
122 return std::string(
"\"") + value +
"\"";
126 std::string::size_type maxsize =
127 strlen(value) * 2 + 3;
129 result.reserve(maxsize);
131 for (
const char* c = value; *c != 0; ++c) {
164 std::ostringstream oss;
165 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
166 << std::setw(4) <<
static_cast<int>(*c);
186 : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
187 omitEndingLineFeed_(false) {}
198 if (!omitEndingLineFeed_)
203 void FastWriter::writeValue(
const Value& value) {
204 switch (value.
type()) {
206 if (!dropNullPlaceholders_)
226 int size = value.
size();
227 for (
int index = 0; index < size; ++index) {
230 writeValue(value[index]);
237 for (Value::Members::iterator it = members.begin(); it != members.end();
239 const std::string& name = *it;
240 if (it != members.begin())
243 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
244 writeValue(value[name]);
255 : rightMargin_(74), indentSize_(3), addChildValues_() {}
259 addChildValues_ =
false;
261 writeCommentBeforeValue(root);
263 writeCommentAfterValueOnSameLine(root);
268 void StyledWriter::writeValue(
const Value& value) {
269 switch (value.
type()) {
289 writeArrayValue(value);
296 writeWithIndent(
"{");
298 Value::Members::iterator it = members.begin();
300 const std::string& name = *it;
301 const Value& childValue = value[name];
302 writeCommentBeforeValue(childValue);
305 writeValue(childValue);
306 if (++it == members.end()) {
307 writeCommentAfterValueOnSameLine(childValue);
311 writeCommentAfterValueOnSameLine(childValue);
314 writeWithIndent(
"}");
320 void StyledWriter::writeArrayValue(
const Value& value) {
321 unsigned size = value.size();
325 bool isArrayMultiLine = isMultineArray(value);
326 if (isArrayMultiLine) {
327 writeWithIndent(
"[");
329 bool hasChildValue = !childValues_.empty();
332 const Value& childValue = value[index];
333 writeCommentBeforeValue(childValue);
335 writeWithIndent(childValues_[index]);
338 writeValue(childValue);
340 if (++index == size) {
341 writeCommentAfterValueOnSameLine(childValue);
345 writeCommentAfterValueOnSameLine(childValue);
348 writeWithIndent(
"]");
351 assert(childValues_.size() == size);
353 for (
unsigned index = 0; index < size; ++index) {
356 document_ += childValues_[index];
363 bool StyledWriter::isMultineArray(
const Value& value) {
364 int size = value.size();
365 bool isMultiLine = size * 3 >= rightMargin_;
366 childValues_.clear();
367 for (
int index = 0; index < size && !isMultiLine; ++index) {
368 const Value& childValue = value[index];
370 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
371 childValue.size() > 0);
375 childValues_.reserve(size);
376 addChildValues_ =
true;
377 int lineLength = 4 + (size - 1) * 2;
378 for (
int index = 0; index < size; ++index) {
379 writeValue(value[index]);
380 lineLength += int(childValues_[index].length());
382 addChildValues_ =
false;
383 isMultiLine = isMultiLine || lineLength >= rightMargin_;
388 void StyledWriter::pushValue(
const std::string& value) {
390 childValues_.push_back(value);
395 void StyledWriter::writeIndent() {
396 if (!document_.empty()) {
397 char last = document_[document_.length() - 1];
403 document_ += indentString_;
406 void StyledWriter::writeWithIndent(
const std::string& value) {
411 void StyledWriter::indent() { indentString_ += std::string(indentSize_,
' '); }
413 void StyledWriter::unindent() {
414 assert(
int(indentString_.size()) >= indentSize_);
415 indentString_.resize(indentString_.size() - indentSize_);
418 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
424 std::string normalizedComment = normalizeEOL(root.getComment(
commentBefore));
425 std::string::const_iterator iter = normalizedComment.begin();
426 while (iter != normalizedComment.end()) {
428 if (*iter ==
'\n' && *(iter + 1) ==
'/')
437 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
443 document_ += normalizeEOL(root.getComment(
commentAfter));
448 bool StyledWriter::hasCommentForValue(
const Value& value) {
454 std::string StyledWriter::normalizeEOL(
const std::string& text) {
455 std::string normalized;
456 normalized.reserve(text.length());
457 const char* begin = text.c_str();
458 const char* end = begin + text.length();
459 const char* current = begin;
460 while (current != end) {
464 if (*current ==
'\n')
477 : document_(NULL), rightMargin_(74), indentation_(indentation),
482 addChildValues_ =
false;
484 writeCommentBeforeValue(root);
486 writeCommentAfterValueOnSameLine(root);
491 void StyledStreamWriter::writeValue(
const Value& value) {
492 switch (value.
type()) {
512 writeArrayValue(value);
519 writeWithIndent(
"{");
521 Value::Members::iterator it = members.begin();
523 const std::string& name = *it;
524 const Value& childValue = value[name];
525 writeCommentBeforeValue(childValue);
528 writeValue(childValue);
529 if (++it == members.end()) {
530 writeCommentAfterValueOnSameLine(childValue);
534 writeCommentAfterValueOnSameLine(childValue);
537 writeWithIndent(
"}");
543 void StyledStreamWriter::writeArrayValue(
const Value& value) {
544 unsigned size = value.size();
548 bool isArrayMultiLine = isMultineArray(value);
549 if (isArrayMultiLine) {
550 writeWithIndent(
"[");
552 bool hasChildValue = !childValues_.empty();
555 const Value& childValue = value[index];
556 writeCommentBeforeValue(childValue);
558 writeWithIndent(childValues_[index]);
561 writeValue(childValue);
563 if (++index == size) {
564 writeCommentAfterValueOnSameLine(childValue);
568 writeCommentAfterValueOnSameLine(childValue);
571 writeWithIndent(
"]");
574 assert(childValues_.size() == size);
576 for (
unsigned index = 0; index < size; ++index) {
579 *document_ << childValues_[index];
586 bool StyledStreamWriter::isMultineArray(
const Value& value) {
587 int size = value.size();
588 bool isMultiLine = size * 3 >= rightMargin_;
589 childValues_.clear();
590 for (
int index = 0; index < size && !isMultiLine; ++index) {
591 const Value& childValue = value[index];
593 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
594 childValue.size() > 0);
598 childValues_.reserve(size);
599 addChildValues_ =
true;
600 int lineLength = 4 + (size - 1) * 2;
601 for (
int index = 0; index < size; ++index) {
602 writeValue(value[index]);
603 lineLength += int(childValues_[index].length());
605 addChildValues_ =
false;
606 isMultiLine = isMultiLine || lineLength >= rightMargin_;
611 void StyledStreamWriter::pushValue(
const std::string& value) {
613 childValues_.push_back(value);
618 void StyledStreamWriter::writeIndent() {
631 *document_ <<
'\n' << indentString_;
634 void StyledStreamWriter::writeWithIndent(
const std::string& value) {
639 void StyledStreamWriter::indent() { indentString_ += indentation_; }
641 void StyledStreamWriter::unindent() {
642 assert(indentString_.size() >= indentation_.size());
643 indentString_.resize(indentString_.size() - indentation_.size());
646 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
653 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
659 *document_ << normalizeEOL(root.getComment(
commentAfter));
664 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
670 std::string StyledStreamWriter::normalizeEOL(
const std::string& text) {
671 std::string normalized;
672 normalized.reserve(text.length());
673 const char* begin = text.c_str();
674 const char* end = begin + text.length();
675 const char* current = begin;
676 while (current != end) {
680 if (*current ==
'\n')
691 writer.
write(sout, root);
void omitEndingLineFeed()
static void uintToString(LargestUInt value, char *¤t)
Converts an unsigned integer to string.
std::vector< std::string > Members
array value (ordered list)
LargestUInt asLargestUInt() const
std::string valueToQuotedString(const char *value)
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 '.
std::string valueToString(Int value)
virtual std::string write(const Value &root)
Serialize a Value in JSON format.
Members getMemberNames() const
Return a list of the member names.
const char * asCString() const
ArrayIndex size() const
Number of values in array or object.
a comment on the line after a value (only make sense for
LargestInt asLargestInt() const
Writes a Value in JSON format in a human friendly way, to a stream rather than to a string...
void dropNullPlaceholders()
Drop the "null" string from the writer's output for nullValues.
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.