15 #ifndef RAPIDJSON_WRITER_H_
16 #define RAPIDJSON_WRITER_H_
28 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
30 #pragma intrinsic(_BitScanForward)
32 #ifdef RAPIDJSON_SSE42
33 #include <nmmintrin.h>
34 #elif defined(RAPIDJSON_SSE2)
35 #include <emmintrin.h>
36 #elif defined(RAPIDJSON_NEON)
42 RAPIDJSON_DIAG_OFF(padded)
43 RAPIDJSON_DIAG_OFF(unreachable - code)
44 RAPIDJSON_DIAG_OFF(c++ 98 - compat)
45 #elif defined(_MSC_VER)
47 RAPIDJSON_DIAG_OFF(4127)
61 #ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS
62 #define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags
93 template <
typename OutputStream,
94 typename SourceEncoding =
UTF8<>,
95 typename TargetEncoding =
UTF8<>,
101 typedef typename SourceEncoding::Ch
Ch;
111 StackAllocator* stackAllocator = 0,
128 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
255 #if RAPIDJSON_HAS_STDSTRING
256 bool String(
const std::basic_string<Ch>& str)
274 #if RAPIDJSON_HAS_STDSTRING
275 bool Key(
const std::basic_string<Ch>& str) {
return Key(str.data(),
SizeType(str.size())); }
384 for(
const char* p = buffer; p != end; ++p)
385 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
394 for(
const char* p = buffer; p != end; ++p)
395 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
404 for(
const char* p = buffer; p != end; ++p)
405 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
414 for(
char* p = buffer; p != end; ++p)
415 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
463 for(
char* p = buffer; p != end; ++p)
464 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
470 static const typename OutputStream::Ch hexDigits[16] = {
471 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'};
472 static const char escape[256] = {
473 #define Z16 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
475 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
476 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
477 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
479 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
484 if(TargetEncoding::supportUnicode)
494 if(!TargetEncoding::supportUnicode &&
static_cast<unsigned>(c) >= 0x80)
502 if(codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF))
513 unsigned s = codepoint - 0x010000;
514 unsigned lead = (s >> 10) + 0xD800;
515 unsigned trail = (s & 0x3FF) + 0xDC00;
528 else if((
sizeof(
Ch) == 1 ||
static_cast<unsigned>(c) < 256) &&
535 static_cast<typename OutputStream::Ch
>(escape[
static_cast<unsigned char>(c)]));
536 if(escape[
static_cast<unsigned char>(c)] ==
'u')
540 PutUnsafe(*
os_, hexDigits[
static_cast<unsigned char>(c) >> 4]);
541 PutUnsafe(*
os_, hexDigits[
static_cast<unsigned char>(c) & 0xF]);
646 char* buffer = os_->Push(11);
648 os_->Pop(
static_cast<size_t>(11 - (end - buffer)));
655 char* buffer = os_->Push(10);
657 os_->Pop(
static_cast<size_t>(10 - (end - buffer)));
664 char* buffer = os_->Push(21);
666 os_->Pop(
static_cast<size_t>(21 - (end - buffer)));
673 char* buffer = os_->Push(20);
675 os_->Pop(
static_cast<size_t>(20 - (end - buffer)));
723 char* buffer = os_->Push(25);
725 os_->Pop(
static_cast<size_t>(25 - (end - buffer)));
729 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
739 const char* p = is.
src_;
740 const char* end = is.
head_ + length;
741 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
742 static_cast<size_t>(~15));
743 const char* endAligned =
744 reinterpret_cast<const char*
>(
reinterpret_cast<size_t>(end) &
static_cast<size_t>(~15));
745 if(nextAligned > end)
748 while(p != nextAligned)
749 if(*p < 0x20 || *p ==
'\"' || *p ==
'\\')
755 os_->PutUnsafe(*p++);
758 static const char dquote[16] = {
'\"',
774 static const char bslash[16] = {
'\\',
790 static const char space[16] = {0x1F,
806 const __m128i dq = _mm_loadu_si128(
reinterpret_cast<const __m128i*
>(&dquote[0]));
807 const __m128i bs = _mm_loadu_si128(
reinterpret_cast<const __m128i*
>(&bslash[0]));
808 const __m128i sp = _mm_loadu_si128(
reinterpret_cast<const __m128i*
>(&space[0]));
810 for(; p != endAligned; p += 16)
812 const __m128i s = _mm_load_si128(
reinterpret_cast<const __m128i*
>(p));
813 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
814 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
816 _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
817 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
818 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
824 _BitScanForward(&offset, r);
827 len =
static_cast<SizeType>(__builtin_ffs(r) - 1);
829 char* q =
reinterpret_cast<char*
>(os_->PushUnsafe(len));
830 for(
size_t i = 0; i < len; i++)
836 _mm_storeu_si128(
reinterpret_cast<__m128i*
>(os_->PushUnsafe(16)), s);
842 #elif defined(RAPIDJSON_NEON)
852 const char* p = is.
src_;
853 const char* end = is.
head_ + length;
854 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
855 static_cast<size_t>(~15));
856 const char* endAligned =
857 reinterpret_cast<const char*
>(
reinterpret_cast<size_t>(end) &
static_cast<size_t>(~15));
858 if(nextAligned > end)
861 while(p != nextAligned)
862 if(*p < 0x20 || *p ==
'\"' || *p ==
'\\')
868 os_->PutUnsafe(*p++);
876 for(; p != endAligned; p += 16)
880 x = vorrq_u8(x, vceqq_u8(s, s1));
881 x = vorrq_u8(x, vceqq_u8(s, s2));
882 x = vorrq_u8(x, vcltq_u8(s, s3));
885 uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);
886 uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);
889 bool escaped =
false;
907 char* q =
reinterpret_cast<char*
>(os_->PushUnsafe(len));
908 for(
size_t i = 0; i < len; i++)
914 vst1q_u8(
reinterpret_cast<uint8_t*
>(os_->PushUnsafe(16)), s);
924 #if defined(_MSC_VER) || defined(__clang__)
C-runtime library allocator.
Definition: allocators.h:83
JSON writer.
Definition: writer.h:99
bool EndObject(SizeType memberCount=0)
Writes the given double value to the stream.
Definition: writer.h:278
bool IsComplete() const
Checks whether the output is a complete JSON.
Definition: writer.h:168
bool Key(const Ch *str, SizeType length, bool copy=false)
Writes the given double value to the stream.
Definition: writer.h:269
void Prefix(Type type)
Simpler but slower overload.
Definition: writer.h:597
bool Double(double d)
Writes the given double value to the stream.
Definition: writer.h:233
bool WriteUint(unsigned u)
Simpler but slower overload.
Definition: writer.h:389
bool String(const Ch *const &str)
Simpler but slower overload.
Definition: writer.h:311
bool WriteInt(int i)
Simpler but slower overload.
Definition: writer.h:379
bool StartArray()
Writes the given double value to the stream.
Definition: writer.h:290
OutputStream * os_
Simpler but slower overload.
Definition: writer.h:630
bool WriteStartArray()
Simpler but slower overload.
Definition: writer.h:570
int maxDecimalPlaces_
Simpler but slower overload.
Definition: writer.h:632
bool Int64(int64_t i64)
Writes the given double value to the stream.
Definition: writer.h:217
bool WriteBool(bool b)
Simpler but slower overload.
Definition: writer.h:357
bool WriteNull()
Simpler but slower overload.
Definition: writer.h:347
bool Uint64(uint64_t u64)
Writes the given double value to the stream.
Definition: writer.h:222
void SetMaxDecimalPlaces(int maxDecimalPlaces)
Sets the maximum number of decimal places for double output.
Definition: writer.h:190
bool Uint(unsigned u)
Writes the given double value to the stream.
Definition: writer.h:212
Writer(StackAllocator *allocator=0, size_t levelDepth=kDefaultLevelDepth)
Definition: writer.h:120
bool WriteEndObject()
Simpler but slower overload.
Definition: writer.h:565
bool WriteStartObject()
Simpler but slower overload.
Definition: writer.h:560
bool String(const Ch *str, SizeType length, bool copy=false)
Writes the given double value to the stream.
Definition: writer.h:247
void Reset(OutputStream &os)
Reset the writer with a new stream.
Definition: writer.h:157
void Flush()
Flush the output stream.
Definition: writer.h:334
bool WriteRawValue(const Ch *json, size_t length)
Simpler but slower overload.
Definition: writer.h:581
bool ScanWriteUnescapedString(GenericStringStream< SourceEncoding > &is, size_t length)
Simpler but slower overload.
Definition: writer.h:555
static const size_t kDefaultLevelDepth
Simpler but slower overload.
Definition: writer.h:336
internal::Stack< StackAllocator > level_stack_
Simpler but slower overload.
Definition: writer.h:631
bool WriteInt64(int64_t i64)
Simpler but slower overload.
Definition: writer.h:399
bool WriteEndArray()
Simpler but slower overload.
Definition: writer.h:575
SourceEncoding::Ch Ch
Definition: writer.h:101
static const int kDefaultMaxDecimalPlaces
Definition: writer.h:103
bool Key(const Ch *const &str)
Simpler but slower overload.
Definition: writer.h:312
bool EndArray(SizeType elementCount=0)
Writes the given double value to the stream.
Definition: writer.h:297
bool WriteString(const Ch *str, SizeType length)
Simpler but slower overload.
Definition: writer.h:468
bool WriteUint64(uint64_t u64)
Simpler but slower overload.
Definition: writer.h:409
int GetMaxDecimalPlaces() const
Definition: writer.h:170
bool RawNumber(const Ch *str, SizeType length, bool copy=false)
Writes the given double value to the stream.
Definition: writer.h:239
bool Int(int i)
Writes the given double value to the stream.
Definition: writer.h:207
bool Bool(bool b)
Writes the given double value to the stream.
Definition: writer.h:202
bool EndValue(bool ret)
Simpler but slower overload.
Definition: writer.h:623
bool RawValue(const Ch *json, size_t length, Type type)
Write a raw JSON value.
Definition: writer.h:323
bool WriteDouble(double d)
Simpler but slower overload.
Definition: writer.h:419
bool StartObject()
Writes the given double value to the stream.
Definition: writer.h:262
Writer(OutputStream &os, StackAllocator *stackAllocator=0, size_t levelDepth=kDefaultLevelDepth)
Constructor.
Definition: writer.h:110
bool Null()
Writes the given double value to the stream.
Definition: writer.h:197
bool hasRoot_
Simpler but slower overload.
Definition: writer.h:633
void Clear()
Definition: stack.h:107
bool Empty() const
Definition: stack.h:205
size_t GetSize() const
Definition: stack.h:206
void PutUnsafe(Stream &stream, typename Stream::Ch c)
Write character to a stream, presuming buffer is reserved.
Definition: stream.h:96
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:518
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:531
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:451
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
auto copy(InputRange &&range, OutputIterator iter) -> decltype(std::copy(std::begin(std::forward< InputRange >(range)), std::end(std::forward< InputRange >(range)), iter))
Definition: algorithm.hpp:14
typename vector_type< uint8_t, 16 >::type uint8x16_t
Definition: dtype_vector.hpp:2253
char * dtoa(double value, char *buffer, int maxDecimalPlaces=324)
Definition: dtoa.h:296
char * i64toa(int64_t value, char *buffer)
Definition: itoa.h:312
char * i32toa(int32_t value, char *buffer)
Definition: itoa.h:122
char * u32toa(uint32_t value, char *buffer)
Definition: itoa.h:41
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:32
uint32_t clzll(uint64_t x)
Definition: clzll.h:32
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:135
Type
Type of JSON value.
Definition: rapidjson.h:760
@ kFalseType
false
Definition: rapidjson.h:762
@ kObjectType
object
Definition: rapidjson.h:764
@ kTrueType
true
Definition: rapidjson.h:763
@ kStringType
string
Definition: rapidjson.h:766
@ kNullType
null
Definition: rapidjson.h:761
@ kArrayType
array
Definition: rapidjson.h:765
@ kNumberType
number
Definition: rapidjson.h:767
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:429
signed __int64 int64_t
Definition: stdint.h:135
unsigned int uint32_t
Definition: stdint.h:126
unsigned char uint8_t
Definition: stdint.h:124
unsigned __int64 uint64_t
Definition: stdint.h:136
void PutReserve(Stream &stream, size_t count)
Reserve n characters for writing to a stream.
Definition: stream.h:88
Read-only string stream.
Definition: stream.h:163
Ch Peek() const
Definition: stream.h:168
Ch Take()
Definition: stream.h:169
const Ch * head_
Original head of the string.
Definition: stream.h:186
size_t Tell() const
Definition: stream.h:170
const Ch * src_
Current read position.
Definition: stream.h:185
Encoding conversion.
Definition: encodings.h:823
UTF-8 encoding.
Definition: encodings.h:98
Information for each nested level.
Definition: writer.h:341
Level(bool inArray_)
Definition: writer.h:342
size_t valueCount
number of values in this level
Definition: writer.h:343
bool inArray
true if in array, otherwise in object
Definition: writer.h:344
#define RAPIDJSON_WRITE_DEFAULT_FLAGS
Definition: writer.h:62
WriteFlag
Combination of writeFlags.
Definition: writer.h:67
@ kWriteNanAndInfFlag
Allow writing of Infinity, -Infinity and NaN.
Definition: writer.h:70
@ kWriteValidateEncodingFlag
Validate encoding of JSON strings.
Definition: writer.h:69
@ kWriteNanAndInfNullFlag
Allow writing of Infinity, -Infinity and NaN as null.
Definition: writer.h:71
@ kWriteDefaultFlags
Definition: writer.h:72
@ kWriteNoFlags
No flags are set.
Definition: writer.h:68