93 typedef typename SourceEncoding::Ch Ch;
95 static const int kDefaultMaxDecimalPlaces = 324;
110#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
111 Writer(Writer&& rhs) :
112 os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) {
138 level_stack_.Clear();
146 return hasRoot_ && level_stack_.Empty();
149 int GetMaxDecimalPlaces()
const {
150 return maxDecimalPlaces_;
183 bool Null() { Prefix(kNullType);
return EndValue(WriteNull()); }
184 bool Bool(
bool b) { Prefix(b ? kTrueType : kFalseType);
return EndValue(WriteBool(b)); }
185 bool Int(
int i) { Prefix(kNumberType);
return EndValue(WriteInt(i)); }
186 bool Uint(
unsigned u) { Prefix(kNumberType);
return EndValue(WriteUint(u)); }
187 bool Int64(int64_t i64) { Prefix(kNumberType);
return EndValue(WriteInt64(i64)); }
188 bool Uint64(uint64_t u64) { Prefix(kNumberType);
return EndValue(WriteUint64(u64)); }
197 bool RawNumber(
const Ch* str,
SizeType length,
bool copy =
false) {
201 return EndValue(WriteString(str, length));
204 bool String(
const Ch* str, SizeType length,
bool copy =
false) {
208 return EndValue(WriteString(str, length));
211#if RAPIDJSON_HAS_STDSTRING
212 bool String(
const std::basic_string<Ch>& str) {
213 return String(str.data(),
SizeType(str.size()));
219 new (level_stack_.template Push<Level>()) Level(
false);
220 return WriteStartObject();
223 bool Key(
const Ch* str, SizeType length,
bool copy =
false) {
return String(str, length, copy); }
225#if RAPIDJSON_HAS_STDSTRING
226 bool Key(
const std::basic_string<Ch>& str)
228 return Key(str.data(),
SizeType(str.size()));
232 bool EndObject(SizeType memberCount = 0) {
237 level_stack_.template Pop<Level>(1);
238 return EndValue(WriteEndObject());
243 new (level_stack_.template Push<Level>()) Level(
true);
244 return WriteStartArray();
247 bool EndArray(SizeType elementCount = 0) {
251 level_stack_.template Pop<Level>(1);
252 return EndValue(WriteEndArray());
260 bool String(
const Ch*
const& str) {
return String(str, internal::StrLen(str)); }
261 bool Key(
const Ch*
const& str) {
return Key(str, internal::StrLen(str)); }
276 return EndValue(WriteRawValue(
json, length));
295 static const size_t kDefaultLevelDepth = 32;
302 bool WriteBool(
bool b) {
309 PutUnsafe(*os_,
'f'); PutUnsafe(*os_,
'a'); PutUnsafe(*os_,
'l'); PutUnsafe(*os_,
's'); PutUnsafe(*os_,
'e');
314 bool WriteInt(
int i) {
316 const char* end = internal::i32toa(i, buffer);
317 PutReserve(*os_,
static_cast<size_t>(end - buffer));
318 for (
const char* p = buffer; p != end; ++p)
319 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
323 bool WriteUint(
unsigned u) {
325 const char* end = internal::u32toa(u, buffer);
326 PutReserve(*os_,
static_cast<size_t>(end - buffer));
327 for (
const char* p = buffer; p != end; ++p)
328 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
332 bool WriteInt64(int64_t i64) {
334 const char* end = internal::i64toa(i64, buffer);
335 PutReserve(*os_,
static_cast<size_t>(end - buffer));
336 for (
const char* p = buffer; p != end; ++p)
337 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
341 bool WriteUint64(uint64_t u64) {
343 char* end = internal::u64toa(u64, buffer);
344 PutReserve(*os_,
static_cast<size_t>(end - buffer));
345 for (
char* p = buffer; p != end; ++p)
346 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
350 bool WriteDouble(
double d) {
351 if (internal::Double(d).IsNanOrInf()) {
352 if (!(writeFlags & kWriteNanAndInfFlag))
354 if (internal::Double(d).IsNan()) {
359 if (internal::Double(d).Sign()) {
371 char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
372 PutReserve(*os_,
static_cast<size_t>(end - buffer));
373 for (
char* p = buffer; p != end; ++p)
374 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
378 bool WriteString(
const Ch* str, SizeType length) {
379 static const typename OutputStream::Ch hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
380 static const char escape[256] = {
381#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
383 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
384 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
385 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
388 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
392 if (TargetEncoding::supportUnicode)
398 GenericStringStream<SourceEncoding> is(str);
399 while (ScanWriteUnescapedString(is, length)) {
400 const Ch c = is.Peek();
401 if (!TargetEncoding::supportUnicode &&
static_cast<unsigned>(c) >= 0x80) {
408 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
409 PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
410 PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]);
411 PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]);
412 PutUnsafe(*os_, hexDigits[(codepoint ) & 15]);
417 unsigned s = codepoint - 0x010000;
418 unsigned lead = (s >> 10) + 0xD800;
419 unsigned trail = (s & 0x3FF) + 0xDC00;
420 PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
421 PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]);
422 PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]);
423 PutUnsafe(*os_, hexDigits[(lead ) & 15]);
426 PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
427 PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]);
428 PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]);
429 PutUnsafe(*os_, hexDigits[(trail ) & 15]);
432 else if ((
sizeof(Ch) == 1 ||
static_cast<unsigned>(c) < 256) &&
RAPIDJSON_UNLIKELY(escape[
static_cast<unsigned char>(c)])) {
435 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(escape[
static_cast<unsigned char>(c)]));
436 if (escape[
static_cast<unsigned char>(c)] ==
'u') {
439 PutUnsafe(*os_, hexDigits[
static_cast<unsigned char>(c) >> 4]);
440 PutUnsafe(*os_, hexDigits[
static_cast<unsigned char>(c) & 0xF]);
444 Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
445 Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
452 bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is,
size_t length) {
456 bool WriteStartObject() { os_->Put(
'{');
return true; }
457 bool WriteEndObject() { os_->Put(
'}');
return true; }
458 bool WriteStartArray() { os_->Put(
'[');
return true; }
459 bool WriteEndArray() { os_->Put(
']');
return true; }
461 bool WriteRawValue(
const Ch* json,
size_t length) {
463 for (
size_t i = 0; i < length; i++) {
470 void Prefix(Type type) {
473 Level* level = level_stack_.template Top<Level>();
474 if (level->valueCount > 0) {
478 os_->Put((level->valueCount % 2 == 0) ?
',' :
':');
480 if (!level->inArray && level->valueCount % 2 == 0)
491 bool EndValue(
bool ret) {
498 internal::Stack<StackAllocator> level_stack_;
499 int maxDecimalPlaces_;
504 Writer(
const Writer&);
505 Writer& operator=(
const Writer&);