15#ifndef RAPIDJSON_WRITER_H_
16#define RAPIDJSON_WRITER_H_
27#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
29#pragma intrinsic(_BitScanForward)
33#elif defined(RAPIDJSON_SSE2)
35#elif defined(RAPIDJSON_NEON)
41RAPIDJSON_DIAG_OFF(padded)
42RAPIDJSON_DIAG_OFF(unreachable-
code)
43RAPIDJSON_DIAG_OFF(c++98-compat)
44#elif defined(_MSC_VER)
46RAPIDJSON_DIAG_OFF(4127)
60#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS
61#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags
88template<
typename OutputStream,
typename SourceEncoding = UTF8<>,
typename TargetEncoding = UTF8<>,
typename StackAllocator = CrtAllocator,
unsigned writeFlags = kWriteDefaultFlags>
91 typedef typename SourceEncoding::Ch
Ch;
108#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
209#if RAPIDJSON_HAS_STDSTRING
210 bool String(
const std::basic_string<Ch>&
str) {
223#if RAPIDJSON_HAS_STDSTRING
224 bool Key(
const std::basic_string<Ch>&
str)
316 for (
const char* p =
buffer; p != end; ++p)
317 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
325 for (
const char* p =
buffer; p != end; ++p)
326 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
334 for (
const char* p =
buffer; p != end; ++p)
335 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
343 for (
char* p =
buffer; p != end; ++p)
344 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
371 for (
char* p =
buffer; p != end; ++p)
372 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(*p));
377 static const typename OutputStream::Ch hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
378 static const char escape[256] = {
379#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
381 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
382 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
383 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
390 if (TargetEncoding::supportUnicode)
399 if (!TargetEncoding::supportUnicode &&
static_cast<unsigned>(c) >= 0x80) {
406 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
415 unsigned s = codepoint - 0x010000;
416 unsigned lead = (
s >> 10) + 0xD800;
417 unsigned trail = (
s & 0x3FF) + 0xDC00;
430 else if ((
sizeof(
Ch) == 1 ||
static_cast<unsigned>(c) < 256) &&
RAPIDJSON_UNLIKELY(escape[
static_cast<unsigned char>(c)])) {
433 PutUnsafe(*
os_,
static_cast<typename OutputStream::Ch
>(escape[
static_cast<unsigned char>(c)]));
434 if (escape[
static_cast<unsigned char>(c)] ==
'u') {
437 PutUnsafe(*
os_, hexDigits[
static_cast<unsigned char>(c) >> 4]);
438 PutUnsafe(*
os_, hexDigits[
static_cast<unsigned char>(c) & 0xF]);
515 char *
buffer = os_->Push(11);
517 os_->Pop(
static_cast<size_t>(11 - (end -
buffer)));
523 char *
buffer = os_->Push(10);
525 os_->Pop(
static_cast<size_t>(10 - (end -
buffer)));
531 char *
buffer = os_->Push(21);
533 os_->Pop(
static_cast<size_t>(21 - (end -
buffer)));
539 char *
buffer = os_->Push(20);
541 os_->Pop(
static_cast<size_t>(20 - (end -
buffer)));
567 char *
buffer = os_->Push(25);
569 os_->Pop(
static_cast<size_t>(25 - (end -
buffer)));
573#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
582 const char* p = is.
src_;
583 const char* end = is.
head_ + length;
584 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
585 const char* endAligned =
reinterpret_cast<const char*
>(
reinterpret_cast<size_t>(end) &
static_cast<size_t>(~15));
586 if (nextAligned > end)
589 while (p != nextAligned)
590 if (*p < 0x20 || *p ==
'\"' || *p ==
'\\') {
595 os_->PutUnsafe(*p++);
598 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
599 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
600 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
601 const __m128i dq = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&dquote[0]));
602 const __m128i bs = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&bslash[0]));
603 const __m128i sp = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&space[0]));
605 for (;
p != endAligned;
p += 16) {
606 const __m128i
s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
607 const __m128i
t1 = _mm_cmpeq_epi8(
s, dq);
608 const __m128i
t2 = _mm_cmpeq_epi8(
s, bs);
609 const __m128i
t3 = _mm_cmpeq_epi8(_mm_max_epu8(
s, sp), sp);
610 const __m128i x = _mm_or_si128(_mm_or_si128(
t1,
t2),
t3);
611 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
615 unsigned long offset;
616 _BitScanForward(&offset, r);
619 len =
static_cast<SizeType>(__builtin_ffs(r) - 1);
621 char*
q =
reinterpret_cast<char*
>(os_->PushUnsafe(len));
622 for (
size_t i = 0;
i < len;
i++)
628 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(os_->PushUnsafe(16)),
s);
634#elif defined(RAPIDJSON_NEON)
643 const char*
p = is.
src_;
644 const char* end = is.
head_ + length;
645 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
646 const char* endAligned =
reinterpret_cast<const char*
>(
reinterpret_cast<size_t>(end) &
static_cast<size_t>(~15));
647 if (nextAligned > end)
650 while (p != nextAligned)
651 if (*p < 0x20 || *p ==
'\"' || *p ==
'\\') {
656 os_->PutUnsafe(*p++);
659 const uint8x16_t s0 = vmovq_n_u8(
'"');
660 const uint8x16_t s1 = vmovq_n_u8(
'\\');
661 const uint8x16_t s2 = vmovq_n_u8(
'\b');
662 const uint8x16_t s3 = vmovq_n_u8(32);
664 for (;
p != endAligned;
p += 16) {
665 const uint8x16_t
s = vld1q_u8(
reinterpret_cast<const uint8_t *
>(p));
666 uint8x16_t x = vceqq_u8(
s, s0);
667 x = vorrq_u8(x, vceqq_u8(
s, s1));
668 x = vorrq_u8(x, vceqq_u8(
s, s2));
669 x = vorrq_u8(x, vcltq_u8(
s, s3));
672 uint64_t low = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 0);
673 uint64_t high = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 1);
676 bool escaped =
false;
679 unsigned lz = (unsigned)__builtin_clzll(high);
684 unsigned lz = (unsigned)__builtin_clzll(low);
689 char*
q =
reinterpret_cast<char*
>(os_->PushUnsafe(len));
690 for (
size_t i = 0;
i < len;
i++)
696 vst1q_u8(
reinterpret_cast<uint8_t *
>(os_->PushUnsafe(16)),
s);
706#if defined(_MSC_VER) || defined(__clang__)
#define s(x, c)
Definition: aesb.c:47
cryptonote::block b
Definition: block.cpp:40
const T buffer
Definition: byte_slice.cpp:83
JSON writer.
Definition: writer.h:89
bool EndObject(SizeType memberCount=0)
Definition: writer.h:230
bool IsComplete() const
Checks whether the output is a complete JSON.
Definition: writer.h:143
bool Key(const Ch *str, SizeType length, bool copy=false)
Definition: writer.h:221
void Prefix(Type type)
Definition: writer.h:473
bool Double(double d)
Writes the given double value to the stream.
Definition: writer.h:193
bool WriteUint(unsigned u)
Definition: writer.h:321
bool String(const Ch *const &str)
Simpler but slower overload.
Definition: writer.h:258
bool WriteInt(int i)
Definition: writer.h:312
bool StartArray()
Definition: writer.h:239
OutputStream * os_
Definition: writer.h:500
bool WriteStartArray()
Definition: writer.h:456
int maxDecimalPlaces_
Definition: writer.h:502
bool Int64(int64_t i64)
Definition: writer.h:185
bool WriteBool(bool b)
Definition: writer.h:300
bool WriteNull()
Definition: writer.h:295
bool Uint64(uint64_t u64)
Definition: writer.h:186
void SetMaxDecimalPlaces(int maxDecimalPlaces)
Sets the maximum number of decimal places for double output.
Definition: writer.h:172
bool Uint(unsigned u)
Definition: writer.h:184
Writer(StackAllocator *allocator=0, size_t levelDepth=kDefaultLevelDepth)
Definition: writer.h:105
Writer & operator=(const Writer &)
bool WriteEndObject()
Definition: writer.h:455
bool WriteStartObject()
Definition: writer.h:454
bool String(const Ch *str, SizeType length, bool copy=false)
Definition: writer.h:202
void Reset(OutputStream &os)
Reset the writer with a new stream.
Definition: writer.h:133
void Flush()
Flush the output stream.
Definition: writer.h:281
bool WriteRawValue(const Ch *json, size_t length)
Definition: writer.h:459
bool ScanWriteUnescapedString(GenericStringStream< SourceEncoding > &is, size_t length)
Definition: writer.h:450
static const size_t kDefaultLevelDepth
Definition: writer.h:293
internal::Stack< StackAllocator > level_stack_
Definition: writer.h:501
bool WriteInt64(int64_t i64)
Definition: writer.h:330
bool WriteEndArray()
Definition: writer.h:457
SourceEncoding::Ch Ch
Definition: writer.h:91
static const int kDefaultMaxDecimalPlaces
Definition: writer.h:93
bool Key(const Ch *const &str)
Definition: writer.h:259
bool EndArray(SizeType elementCount=0)
Definition: writer.h:245
bool WriteString(const Ch *str, SizeType length)
Definition: writer.h:376
bool WriteUint64(uint64_t u64)
Definition: writer.h:339
int GetMaxDecimalPlaces() const
Definition: writer.h:147
bool RawNumber(const Ch *str, SizeType length, bool copy=false)
Definition: writer.h:195
bool Int(int i)
Definition: writer.h:183
bool Bool(bool b)
Definition: writer.h:182
bool EndValue(bool ret)
Definition: writer.h:494
bool RawValue(const Ch *json, size_t length, Type type)
Write a raw JSON value.
Definition: writer.h:271
bool WriteDouble(double d)
Definition: writer.h:348
bool StartObject()
Definition: writer.h:215
Writer(OutputStream &os, StackAllocator *stackAllocator=0, size_t levelDepth=kDefaultLevelDepth)
Constructor.
Definition: writer.h:101
bool Null()
Definition: writer.h:181
bool hasRoot_
Definition: writer.h:503
A type-unsafe stack for storing different types of data.
Definition: stack.h:36
void Clear()
Definition: stack.h:98
bool Empty() const
Definition: stack.h:176
size_t GetSize() const
Definition: stack.h:177
void PutUnsafe(Stream &stream, typename Stream::Ch c)
Write character to a stream, presuming buffer is reserved.
Definition: stream.h:91
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:468
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:481
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:411
#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
int q
Definition: base.py:2
char * dtoa(double value, char *buffer, int maxDecimalPlaces=324)
Definition: dtoa.h:216
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:126
char * i64toa(int64_t value, char *buffer)
Definition: itoa.h:295
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:31
char * u32toa(uint32_t value, char *buffer)
Definition: itoa.h:39
char * i32toa(int32_t value, char *buffer)
Definition: itoa.h:115
miniupnpc p
Definition: pymoduletest.py:75
int i
Definition: pymoduletest.py:23
miniupnpc r
Definition: testupnpigd.py:61
const char *const str
Definition: portlistingparse.c:23
const portMappingElt code
Definition: portlistingparse.c:22
Type
Type of JSON value.
Definition: rapidjson.h:623
@ kFalseType
false
Definition: rapidjson.h:625
@ kObjectType
object
Definition: rapidjson.h:627
@ kTrueType
true
Definition: rapidjson.h:626
@ kStringType
string
Definition: rapidjson.h:629
@ kNullType
null
Definition: rapidjson.h:624
@ kArrayType
array
Definition: rapidjson.h:628
@ kNumberType
number
Definition: rapidjson.h:630
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
t2
Definition: pow22523.h:103
t1
Definition: pow22523.h:58
t3
Definition: pow225521.h:103
#define false
Definition: stdbool.h:37
signed __int64 int64_t
Definition: stdint.h:135
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:84
Read-only string stream.
Definition: stream.h:154
Ch Peek() const
Definition: stream.h:159
Ch Take()
Definition: stream.h:160
const Ch * head_
Original head of the string.
Definition: stream.h:169
size_t Tell() const
Definition: stream.h:161
const Ch * src_
Current read position.
Definition: stream.h:168
Encoding conversion.
Definition: encodings.h:658
Information for each nested level.
Definition: writer.h:287
Level(bool inArray_)
Definition: writer.h:288
size_t valueCount
number of values in this level
Definition: writer.h:289
bool inArray
true if in array, otherwise in object
Definition: writer.h:290
rapidjson::Document json
Definition: transport.cpp:50
#define RAPIDJSON_WRITE_DEFAULT_FLAGS
Definition: writer.h:61
WriteFlag
Combination of writeFlags.
Definition: writer.h:65
@ kWriteNanAndInfFlag
Allow writing of Infinity, -Infinity and NaN.
Definition: writer.h:68
@ kWriteValidateEncodingFlag
Validate encoding of JSON strings.
Definition: writer.h:67
@ kWriteDefaultFlags
Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS.
Definition: writer.h:69
@ kWriteNoFlags
No flags are set.
Definition: writer.h:66