93 typedef typename SourceEncoding::Ch Ch;
95 static const int kDefaultMaxDecimalPlaces = 324;
103 Writer(OutputStream& os, StackAllocator* stackAllocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
104 os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(
Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
107 Writer(StackAllocator* allocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
108 os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
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_;
175 maxDecimalPlaces_ = 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));
287 static const size_t kDefaultLevelDepth = 32;
292 Level(
bool inArray_) : valueCount(0), inArray(inArray_) {}
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) && !(writeFlags & kWriteNanAndInfNullFlag))
354 if (writeFlags & kWriteNanAndInfNullFlag) {
359 if (internal::Double(d).IsNan()) {
364 if (internal::Double(d).Sign()) {
376 char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
377 PutReserve(*os_,
static_cast<size_t>(end - buffer));
378 for (
char* p = buffer; p != end; ++p)
379 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
383 bool WriteString(
const Ch* str, SizeType length) {
384 static const typename OutputStream::Ch hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
385 static const char escape[256] = {
386#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
388 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
389 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
390 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
392 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
393 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
397 if (TargetEncoding::supportUnicode)
403 GenericStringStream<SourceEncoding> is(str);
404 while (ScanWriteUnescapedString(is, length)) {
405 const Ch c = is.Peek();
406 if (!TargetEncoding::supportUnicode &&
static_cast<unsigned>(c) >= 0x80) {
413 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
414 PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
415 PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]);
416 PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]);
417 PutUnsafe(*os_, hexDigits[(codepoint ) & 15]);
422 unsigned s = codepoint - 0x010000;
423 unsigned lead = (s >> 10) + 0xD800;
424 unsigned trail = (s & 0x3FF) + 0xDC00;
425 PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
426 PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]);
427 PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]);
428 PutUnsafe(*os_, hexDigits[(lead ) & 15]);
431 PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
432 PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]);
433 PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]);
434 PutUnsafe(*os_, hexDigits[(trail ) & 15]);
437 else if ((
sizeof(Ch) == 1 ||
static_cast<unsigned>(c) < 256) &&
RAPIDJSON_UNLIKELY(escape[
static_cast<unsigned char>(c)])) {
440 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(escape[
static_cast<unsigned char>(c)]));
441 if (escape[
static_cast<unsigned char>(c)] ==
'u') {
444 PutUnsafe(*os_, hexDigits[
static_cast<unsigned char>(c) >> 4]);
445 PutUnsafe(*os_, hexDigits[
static_cast<unsigned char>(c) & 0xF]);
449 Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
450 Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
457 bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is,
size_t length) {
461 bool WriteStartObject() { os_->Put(
'{');
return true; }
462 bool WriteEndObject() { os_->Put(
'}');
return true; }
463 bool WriteStartArray() { os_->Put(
'[');
return true; }
464 bool WriteEndArray() { os_->Put(
']');
return true; }
466 bool WriteRawValue(
const Ch* json,
size_t length) {
468 GenericStringStream<SourceEncoding> is(json);
472 Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
473 Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
479 void Prefix(Type type) {
482 Level* level = level_stack_.template Top<Level>();
483 if (level->valueCount > 0) {
487 os_->Put((level->valueCount % 2 == 0) ?
',' :
':');
489 if (!level->inArray && level->valueCount % 2 == 0)
500 bool EndValue(
bool ret) {
507 internal::Stack<StackAllocator> level_stack_;
508 int maxDecimalPlaces_;
513 Writer(
const Writer&);
514 Writer& operator=(
const Writer&);