1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
8 // http://opensource.org/licenses/MIT
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
15 #ifndef RAPIDJSON_WRITER_H_
16 #define RAPIDJSON_WRITER_H_
19 #include "internal/stack.h"
20 #include "internal/strfunc.h"
21 #include "internal/dtoa.h"
22 #include "internal/itoa.h"
23 #include "stringbuffer.h"
24 #include <new> // placement new
26 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
28 #pragma intrinsic(_BitScanForward)
30 #ifdef RAPIDJSON_SSE42
31 #include <nmmintrin.h>
32 #elif defined(RAPIDJSON_SSE2)
33 #include <emmintrin.h>
38 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
43 RAPIDJSON_DIAG_OFF(padded)
44 RAPIDJSON_DIAG_OFF(unreachable-code)
47 RAPIDJSON_NAMESPACE_BEGIN
49 ///////////////////////////////////////////////////////////////////////////////
52 /*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS
53 \ingroup RAPIDJSON_CONFIG
54 \brief User-defined kWriteDefaultFlags definition.
56 User can define this as any \c WriteFlag combinations.
58 #ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS
59 #define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags
62 //! Combination of writeFlags
64 kWriteNoFlags = 0, //!< No flags are set.
65 kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
66 kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN.
67 kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
71 /*! Writer implements the concept Handler.
72 It generates JSON text by events to an output os.
74 User may programmatically calls the functions of a writer to generate JSON text.
76 On the other side, a writer can also be passed to objects that generates events,
78 for example Reader::Parse() and Document::Accept().
80 \tparam OutputStream Type of output stream.
81 \tparam SourceEncoding Encoding of source string.
82 \tparam TargetEncoding Encoding of output stream.
83 \tparam StackAllocator Type of allocator for allocating memory of stack.
84 \note implements Handler concept
86 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
89 typedef typename SourceEncoding::Ch Ch;
91 static const int kDefaultMaxDecimalPlaces = 324;
94 /*! \param os Output stream.
95 \param stackAllocator User supplied allocator. If it is null, it will create a private one.
96 \param levelDepth Initial capacity of stack.
99 Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
100 os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
103 Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
104 os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
106 //! Reset the writer with a new stream.
108 This function reset the writer with a new stream and default settings,
109 in order to make a Writer object reusable for output multiple JSONs.
111 \param os New output stream.
113 Writer<OutputStream> writer(os1);
114 writer.StartObject();
119 writer.StartObject();
124 void Reset(OutputStream& os) {
127 level_stack_.Clear();
130 //! Checks whether the output is a complete JSON.
132 A complete JSON has a complete root object or array.
134 bool IsComplete() const {
135 return hasRoot_ && level_stack_.Empty();
138 int GetMaxDecimalPlaces() const {
139 return maxDecimalPlaces_;
142 //! Sets the maximum number of decimal places for double output.
144 This setting truncates the output with specified number of decimal places.
149 writer.SetMaxDecimalPlaces(3);
151 writer.Double(0.12345); // "0.123"
152 writer.Double(0.0001); // "0.0"
153 writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent)
154 writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent)
158 The default setting does not truncate any decimal places. You can restore to this setting by calling
160 writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces);
163 void SetMaxDecimalPlaces(int maxDecimalPlaces) {
164 maxDecimalPlaces_ = maxDecimalPlaces;
167 /*!@name Implementation of Handler
172 bool Null() { Prefix(kNullType); return EndValue(WriteNull()); }
173 bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); }
174 bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); }
175 bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); }
176 bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); }
177 bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); }
179 //! Writes the given \c double value to the stream
181 \param d The value to be written.
182 \return Whether it is succeed.
184 bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); }
186 bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
189 return EndValue(WriteString(str, length));
192 bool String(const Ch* str, SizeType length, bool copy = false) {
195 return EndValue(WriteString(str, length));
198 #if RAPIDJSON_HAS_STDSTRING
199 bool String(const std::basic_string<Ch>& str) {
200 return String(str.data(), SizeType(str.size()));
206 new (level_stack_.template Push<Level>()) Level(false);
207 return WriteStartObject();
210 bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
212 bool EndObject(SizeType memberCount = 0) {
214 RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
215 RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
216 level_stack_.template Pop<Level>(1);
217 return EndValue(WriteEndObject());
222 new (level_stack_.template Push<Level>()) Level(true);
223 return WriteStartArray();
226 bool EndArray(SizeType elementCount = 0) {
228 RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
229 RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
230 level_stack_.template Pop<Level>(1);
231 return EndValue(WriteEndArray());
235 /*! @name Convenience extensions */
238 //! Simpler but slower overload.
239 bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
240 bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
244 //! Write a raw JSON value.
246 For user to write a stringified JSON as a value.
248 \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
249 \param length Length of the json.
250 \param type Type of the root of json.
252 bool RawValue(const Ch* json, size_t length, Type type) { Prefix(type); return EndValue(WriteRawValue(json, length)); }
255 //! Information for each nested level
257 Level(bool inArray_) : valueCount(0), inArray(inArray_) {}
258 size_t valueCount; //!< number of values in this level
259 bool inArray; //!< true if in array, otherwise in object
262 static const size_t kDefaultLevelDepth = 32;
266 PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
269 bool WriteBool(bool b) {
272 PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e');
276 PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e');
281 bool WriteInt(int i) {
283 const char* end = internal::i32toa(i, buffer);
284 PutReserve(*os_, static_cast<size_t>(end - buffer));
285 for (const char* p = buffer; p != end; ++p)
286 PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
290 bool WriteUint(unsigned u) {
292 const char* end = internal::u32toa(u, buffer);
293 PutReserve(*os_, static_cast<size_t>(end - buffer));
294 for (const char* p = buffer; p != end; ++p)
295 PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
299 bool WriteInt64(int64_t i64) {
301 const char* end = internal::i64toa(i64, buffer);
302 PutReserve(*os_, static_cast<size_t>(end - buffer));
303 for (const char* p = buffer; p != end; ++p)
304 PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
308 bool WriteUint64(uint64_t u64) {
310 char* end = internal::u64toa(u64, buffer);
311 PutReserve(*os_, static_cast<size_t>(end - buffer));
312 for (char* p = buffer; p != end; ++p)
313 PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
317 bool WriteDouble(double d) {
318 if (internal::Double(d).IsNanOrInf()) {
319 if (!(writeFlags & kWriteNanAndInfFlag))
321 if (internal::Double(d).IsNan()) {
323 PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
326 if (internal::Double(d).Sign()) {
328 PutUnsafe(*os_, '-');
332 PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
333 PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
338 char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
339 PutReserve(*os_, static_cast<size_t>(end - buffer));
340 for (char* p = buffer; p != end; ++p)
341 PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
345 bool WriteString(const Ch* str, SizeType length) {
346 static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
347 static const char escape[256] = {
348 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
349 //0 1 2 3 4 5 6 7 8 9 A B C D E F
350 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
351 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
352 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20
354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50
355 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF
359 if (TargetEncoding::supportUnicode)
360 PutReserve(*os_, 2 + length * 6); // "\uxxxx..."
362 PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..."
364 PutUnsafe(*os_, '\"');
365 GenericStringStream<SourceEncoding> is(str);
366 while (ScanWriteUnescapedString(is, length)) {
367 const Ch c = is.Peek();
368 if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {
371 if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint)))
373 PutUnsafe(*os_, '\\');
374 PutUnsafe(*os_, 'u');
375 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
376 PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
377 PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]);
378 PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]);
379 PutUnsafe(*os_, hexDigits[(codepoint ) & 15]);
382 RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);
384 unsigned s = codepoint - 0x010000;
385 unsigned lead = (s >> 10) + 0xD800;
386 unsigned trail = (s & 0x3FF) + 0xDC00;
387 PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
388 PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]);
389 PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]);
390 PutUnsafe(*os_, hexDigits[(lead ) & 15]);
391 PutUnsafe(*os_, '\\');
392 PutUnsafe(*os_, 'u');
393 PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
394 PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]);
395 PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]);
396 PutUnsafe(*os_, hexDigits[(trail ) & 15]);
399 else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)])) {
401 PutUnsafe(*os_, '\\');
402 PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(escape[static_cast<unsigned char>(c)]));
403 if (escape[static_cast<unsigned char>(c)] == 'u') {
404 PutUnsafe(*os_, '0');
405 PutUnsafe(*os_, '0');
406 PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]);
407 PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
410 else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ?
411 Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
412 Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
415 PutUnsafe(*os_, '\"');
419 bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, size_t length) {
420 return RAPIDJSON_LIKELY(is.Tell() < length);
423 bool WriteStartObject() { os_->Put('{'); return true; }
424 bool WriteEndObject() { os_->Put('}'); return true; }
425 bool WriteStartArray() { os_->Put('['); return true; }
426 bool WriteEndArray() { os_->Put(']'); return true; }
428 bool WriteRawValue(const Ch* json, size_t length) {
429 PutReserve(*os_, length);
430 for (size_t i = 0; i < length; i++) {
431 RAPIDJSON_ASSERT(json[i] != '\0');
432 PutUnsafe(*os_, json[i]);
437 void Prefix(Type type) {
439 if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root
440 Level* level = level_stack_.template Top<Level>();
441 if (level->valueCount > 0) {
443 os_->Put(','); // add comma if it is not the first element in array
445 os_->Put((level->valueCount % 2 == 0) ? ',' : ':');
447 if (!level->inArray && level->valueCount % 2 == 0)
448 RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
452 RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root.
457 // Flush the value if it is the top level one.
458 bool EndValue(bool ret) {
459 if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text
465 internal::Stack<StackAllocator> level_stack_;
466 int maxDecimalPlaces_;
470 // Prohibit copy constructor & assignment operator.
471 Writer(const Writer&);
472 Writer& operator=(const Writer&);
475 // Full specialization for StringStream to prevent memory copying
478 inline bool Writer<StringBuffer>::WriteInt(int i) {
479 char *buffer = os_->Push(11);
480 const char* end = internal::i32toa(i, buffer);
481 os_->Pop(static_cast<size_t>(11 - (end - buffer)));
486 inline bool Writer<StringBuffer>::WriteUint(unsigned u) {
487 char *buffer = os_->Push(10);
488 const char* end = internal::u32toa(u, buffer);
489 os_->Pop(static_cast<size_t>(10 - (end - buffer)));
494 inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
495 char *buffer = os_->Push(21);
496 const char* end = internal::i64toa(i64, buffer);
497 os_->Pop(static_cast<size_t>(21 - (end - buffer)));
502 inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
503 char *buffer = os_->Push(20);
504 const char* end = internal::u64toa(u, buffer);
505 os_->Pop(static_cast<size_t>(20 - (end - buffer)));
510 inline bool Writer<StringBuffer>::WriteDouble(double d) {
511 if (internal::Double(d).IsNanOrInf()) {
512 // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
513 if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
515 if (internal::Double(d).IsNan()) {
517 PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
520 if (internal::Double(d).Sign()) {
522 PutUnsafe(*os_, '-');
526 PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
527 PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
531 char *buffer = os_->Push(25);
532 char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
533 os_->Pop(static_cast<size_t>(25 - (end - buffer)));
537 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
539 inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {
541 return RAPIDJSON_LIKELY(is.Tell() < length);
543 if (!RAPIDJSON_LIKELY(is.Tell() < length))
546 const char* p = is.src_;
547 const char* end = is.head_ + length;
548 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
549 const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));
550 if (nextAligned > end)
553 while (p != nextAligned)
554 if (*p < 0x20 || *p == '\"' || *p == '\\') {
556 return RAPIDJSON_LIKELY(is.Tell() < length);
559 os_->PutUnsafe(*p++);
561 // The rest of string using SIMD
562 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
563 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
564 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
565 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
566 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
567 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
569 for (; p != endAligned; p += 16) {
570 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
571 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
572 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
573 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
574 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
575 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
576 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
578 #ifdef _MSC_VER // Find the index of first escaped
579 unsigned long offset;
580 _BitScanForward(&offset, r);
583 len = static_cast<SizeType>(__builtin_ffs(r) - 1);
585 char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));
586 for (size_t i = 0; i < len; i++)
592 _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s);
596 return RAPIDJSON_LIKELY(is.Tell() < length);
598 #endif // defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
600 RAPIDJSON_NAMESPACE_END
610 #endif // RAPIDJSON_RAPIDJSON_H_