6 #if !defined(JSON_IS_AMALGAMATION)
9 #endif // if !defined(JSON_IS_AMALGAMATION)
17 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
19 #pragma warning(disable : 4996)
34 char *current = buffer +
sizeof(buffer);
35 bool isNegative = value < 0;
41 assert(current >= buffer);
47 char *current = buffer +
sizeof(buffer);
49 assert(current >= buffer);
53 #if defined(JSON_HAS_INT64)
63 #endif // # if defined(JSON_HAS_INT64)
73 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with
77 _snprintf(buffer,
sizeof(buffer),
"%.16g", value);
79 sprintf_s(buffer,
sizeof(buffer),
"%.16g", value);
82 snprintf(buffer,
sizeof(buffer),
"%.16g", value);
88 std::string
valueToString(
bool value) {
return value ?
"true" :
"false"; }
94 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
96 return std::string(
"\"") + value +
"\"";
100 std::string::size_type maxsize =
101 strlen(value) * 2 + 3;
103 result.reserve(maxsize);
105 for (
const char *c = value; *c != 0; ++c) {
138 std::ostringstream oss;
139 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
140 << std::setw(4) << static_cast<int>(*c);
160 : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false) {}
173 void FastWriter::writeValue(
const Value &value) {
174 switch (value.
type()) {
176 if (!dropNullPlaceholders_)
196 int size = value.
size();
197 for (
int index = 0; index < size; ++index) {
200 writeValue(value[index]);
207 for (Value::Members::iterator it = members.begin(); it != members.end();
209 const std::string &name = *it;
210 if (it != members.begin())
213 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
214 writeValue(value[name]);
225 : rightMargin_(74), indentSize_(3), addChildValues_() {}
229 addChildValues_ =
false;
231 writeCommentBeforeValue(root);
233 writeCommentAfterValueOnSameLine(root);
238 void StyledWriter::writeValue(
const Value &value) {
239 switch (value.
type()) {
259 writeArrayValue(value);
266 writeWithIndent(
"{");
268 Value::Members::iterator it = members.begin();
270 const std::string &name = *it;
271 const Value &childValue = value[name];
272 writeCommentBeforeValue(childValue);
275 writeValue(childValue);
276 if (++it == members.end()) {
277 writeCommentAfterValueOnSameLine(childValue);
281 writeCommentAfterValueOnSameLine(childValue);
284 writeWithIndent(
"}");
290 void StyledWriter::writeArrayValue(
const Value &value) {
291 unsigned size = value.size();
295 bool isArrayMultiLine = isMultineArray(value);
296 if (isArrayMultiLine) {
297 writeWithIndent(
"[");
299 bool hasChildValue = !childValues_.empty();
302 const Value &childValue = value[index];
303 writeCommentBeforeValue(childValue);
305 writeWithIndent(childValues_[index]);
308 writeValue(childValue);
310 if (++index == size) {
311 writeCommentAfterValueOnSameLine(childValue);
315 writeCommentAfterValueOnSameLine(childValue);
318 writeWithIndent(
"]");
321 assert(childValues_.size() == size);
323 for (
unsigned index = 0; index < size; ++index) {
326 document_ += childValues_[index];
333 bool StyledWriter::isMultineArray(
const Value &value) {
334 int size = value.size();
335 bool isMultiLine = size * 3 >= rightMargin_;
336 childValues_.clear();
337 for (
int index = 0; index < size && !isMultiLine; ++index) {
338 const Value &childValue = value[index];
340 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
341 childValue.size() > 0);
345 childValues_.reserve(size);
346 addChildValues_ =
true;
347 int lineLength = 4 + (size - 1) * 2;
348 for (
int index = 0; index < size; ++index) {
349 writeValue(value[index]);
350 lineLength += int(childValues_[index].length());
352 addChildValues_ =
false;
353 isMultiLine = isMultiLine || lineLength >= rightMargin_;
358 void StyledWriter::pushValue(
const std::string &value) {
360 childValues_.push_back(value);
365 void StyledWriter::writeIndent() {
366 if (!document_.empty()) {
367 char last = document_[document_.length() - 1];
373 document_ += indentString_;
376 void StyledWriter::writeWithIndent(
const std::string &value) {
381 void StyledWriter::indent() { indentString_ += std::string(indentSize_,
' '); }
383 void StyledWriter::unindent() {
384 assert(
int(indentString_.size()) >= indentSize_);
385 indentString_.resize(indentString_.size() - indentSize_);
388 void StyledWriter::writeCommentBeforeValue(
const Value &root) {
394 std::string normalizedComment = normalizeEOL(root.getComment(
commentBefore));
395 std::string::const_iterator iter = normalizedComment.begin();
396 while (iter != normalizedComment.end()) {
398 if (*iter ==
'\n' && *(iter + 1) ==
'/')
407 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value &root) {
413 document_ += normalizeEOL(root.getComment(
commentAfter));
418 bool StyledWriter::hasCommentForValue(
const Value &value) {
424 std::string StyledWriter::normalizeEOL(
const std::string &text) {
425 std::string normalized;
426 normalized.reserve(text.length());
427 const char *begin = text.c_str();
428 const char *end = begin + text.length();
429 const char *current = begin;
430 while (current != end) {
434 if (*current ==
'\n')
447 : document_(NULL), rightMargin_(74), indentation_(indentation),
452 addChildValues_ =
false;
454 writeCommentBeforeValue(root);
456 writeCommentAfterValueOnSameLine(root);
461 void StyledStreamWriter::writeValue(
const Value &value) {
462 switch (value.
type()) {
482 writeArrayValue(value);
489 writeWithIndent(
"{");
491 Value::Members::iterator it = members.begin();
493 const std::string &name = *it;
494 const Value &childValue = value[name];
495 writeCommentBeforeValue(childValue);
498 writeValue(childValue);
499 if (++it == members.end()) {
500 writeCommentAfterValueOnSameLine(childValue);
504 writeCommentAfterValueOnSameLine(childValue);
507 writeWithIndent(
"}");
513 void StyledStreamWriter::writeArrayValue(
const Value &value) {
514 unsigned size = value.size();
518 bool isArrayMultiLine = isMultineArray(value);
519 if (isArrayMultiLine) {
520 writeWithIndent(
"[");
522 bool hasChildValue = !childValues_.empty();
525 const Value &childValue = value[index];
526 writeCommentBeforeValue(childValue);
528 writeWithIndent(childValues_[index]);
531 writeValue(childValue);
533 if (++index == size) {
534 writeCommentAfterValueOnSameLine(childValue);
538 writeCommentAfterValueOnSameLine(childValue);
541 writeWithIndent(
"]");
544 assert(childValues_.size() == size);
546 for (
unsigned index = 0; index < size; ++index) {
549 *document_ << childValues_[index];
556 bool StyledStreamWriter::isMultineArray(
const Value &value) {
557 int size = value.size();
558 bool isMultiLine = size * 3 >= rightMargin_;
559 childValues_.clear();
560 for (
int index = 0; index < size && !isMultiLine; ++index) {
561 const Value &childValue = value[index];
563 isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
564 childValue.size() > 0);
568 childValues_.reserve(size);
569 addChildValues_ =
true;
570 int lineLength = 4 + (size - 1) * 2;
571 for (
int index = 0; index < size; ++index) {
572 writeValue(value[index]);
573 lineLength += int(childValues_[index].length());
575 addChildValues_ =
false;
576 isMultiLine = isMultiLine || lineLength >= rightMargin_;
581 void StyledStreamWriter::pushValue(
const std::string &value) {
583 childValues_.push_back(value);
588 void StyledStreamWriter::writeIndent() {
601 *document_ <<
'\n' << indentString_;
604 void StyledStreamWriter::writeWithIndent(
const std::string &value) {
609 void StyledStreamWriter::indent() { indentString_ += indentation_; }
611 void StyledStreamWriter::unindent() {
612 assert(indentString_.size() >= indentation_.size());
613 indentString_.resize(indentString_.size() - indentation_.size());
616 void StyledStreamWriter::writeCommentBeforeValue(
const Value &root) {
623 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value &root) {
629 *document_ << normalizeEOL(root.getComment(
commentAfter));
634 bool StyledStreamWriter::hasCommentForValue(
const Value &value) {
640 std::string StyledStreamWriter::normalizeEOL(
const std::string &text) {
641 std::string normalized;
642 normalized.reserve(text.length());
643 const char *begin = text.c_str();
644 const char *end = begin + text.length();
645 const char *current = begin;
646 while (current != end) {
650 if (*current ==
'\n')
661 writer.
write(sout, root);