94 typedef typename SourceEncoding::Ch Ch;
96 static const int kDefaultMaxDecimalPlaces = 324;
104 Writer(OutputStream& os, StackAllocator* stackAllocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
105 os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
108 Writer(StackAllocator* allocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
109 os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
111#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
113 os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) {
139 level_stack_.Clear();
147 return hasRoot_ && level_stack_.Empty();
150 int GetMaxDecimalPlaces()
const {
151 return maxDecimalPlaces_;
176 maxDecimalPlaces_ = maxDecimalPlaces;
184 bool Null() { Prefix(
kNullType);
return EndValue(WriteNull()); }
186 bool Int(
int i) { Prefix(
kNumberType);
return EndValue(WriteInt(i)); }
187 bool Uint(
unsigned u) { Prefix(
kNumberType);
return EndValue(WriteUint(u)); }
188 bool Int64(int64_t i64) { Prefix(
kNumberType);
return EndValue(WriteInt64(i64)); }
189 bool Uint64(uint64_t u64) { Prefix(
kNumberType);
return EndValue(WriteUint64(u64)); }
198 bool RawNumber(
const Ch* str,
SizeType length,
bool copy =
false) {
202 return EndValue(WriteString(str, length));
205 bool String(
const Ch* str,
SizeType length,
bool copy =
false) {
209 return EndValue(WriteString(str, length));
212#if RAPIDJSON_HAS_STDSTRING
213 bool String(
const std::basic_string<Ch>& str) {
214 return String(str.data(),
SizeType(str.size()));
220 new (level_stack_.template Push<Level>())
Level(
false);
221 return WriteStartObject();
224 bool Key(
const Ch* str,
SizeType length,
bool copy =
false) {
return String(str, length, copy); }
226#if RAPIDJSON_HAS_STDSTRING
227 bool Key(
const std::basic_string<Ch>& str)
229 return Key(str.data(),
SizeType(str.size()));
233 bool EndObject(
SizeType memberCount = 0) {
238 level_stack_.template Pop<Level>(1);
239 return EndValue(WriteEndObject());
244 new (level_stack_.template Push<Level>())
Level(
true);
245 return WriteStartArray();
248 bool EndArray(
SizeType elementCount = 0) {
252 level_stack_.template Pop<Level>(1);
253 return EndValue(WriteEndArray());
261 bool String(
const Ch*
const& str) {
return String(str, internal::StrLen(str)); }
262 bool Key(
const Ch*
const& str) {
return Key(str, internal::StrLen(str)); }
277 return EndValue(WriteRawValue(json, length));
288 static const size_t kDefaultLevelDepth = 32;
300 PutUnsafe(*os_,
'n'); PutUnsafe(*os_,
'u'); PutUnsafe(*os_,
'l'); PutUnsafe(*os_,
'l');
return true;
303 bool WriteBool(
bool b) {
306 PutUnsafe(*os_,
't'); PutUnsafe(*os_,
'r'); PutUnsafe(*os_,
'u'); PutUnsafe(*os_,
'e');
310 PutUnsafe(*os_,
'f'); PutUnsafe(*os_,
'a'); PutUnsafe(*os_,
'l'); PutUnsafe(*os_,
's'); PutUnsafe(*os_,
'e');
315 bool WriteInt(
int i) {
317 const char* end = internal::i32toa(i, buffer);
318 PutReserve(*os_,
static_cast<size_t>(end - buffer));
319 for (
const char* p = buffer; p != end; ++p)
320 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
324 bool WriteUint(
unsigned u) {
326 const char* end = internal::u32toa(u, buffer);
327 PutReserve(*os_,
static_cast<size_t>(end - buffer));
328 for (
const char* p = buffer; p != end; ++p)
329 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
333 bool WriteInt64(int64_t i64) {
335 const char* end = internal::i64toa(i64, buffer);
336 PutReserve(*os_,
static_cast<size_t>(end - buffer));
337 for (
const char* p = buffer; p != end; ++p)
338 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
342 bool WriteUint64(uint64_t u64) {
344 char* end = internal::u64toa(u64, buffer);
345 PutReserve(*os_,
static_cast<size_t>(end - buffer));
346 for (
char* p = buffer; p != end; ++p)
347 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
351 bool WriteDouble(
double d) {
352 if (internal::Double(d).IsNanOrInf()) {
353 if (!(writeFlags & kWriteNanAndInfFlag) && !(writeFlags & kWriteNanAndInfNullFlag))
355 if (writeFlags & kWriteNanAndInfNullFlag) {
357 PutUnsafe(*os_,
'n'); PutUnsafe(*os_,
'u'); PutUnsafe(*os_,
'l'); PutUnsafe(*os_,
'l');
360 if (internal::Double(d).IsNan()) {
362 PutUnsafe(*os_,
'N'); PutUnsafe(*os_,
'a'); PutUnsafe(*os_,
'N');
365 if (internal::Double(d).Sign()) {
367 PutUnsafe(*os_,
'-');
371 PutUnsafe(*os_,
'I'); PutUnsafe(*os_,
'n'); PutUnsafe(*os_,
'f');
372 PutUnsafe(*os_,
'i'); PutUnsafe(*os_,
'n'); PutUnsafe(*os_,
'i'); PutUnsafe(*os_,
't'); PutUnsafe(*os_,
'y');
377 char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
378 PutReserve(*os_,
static_cast<size_t>(end - buffer));
379 for (
char* p = buffer; p != end; ++p)
380 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(*p));
384 bool WriteString(
const Ch* str,
SizeType length) {
385 static const typename OutputStream::Ch hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
386 static const char escape[256] = {
387#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
389 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
390 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
391 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
394 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
398 if (TargetEncoding::supportUnicode)
399 PutReserve(*os_, 2 + length * 6);
401 PutReserve(*os_, 2 + length * 12);
403 PutUnsafe(*os_,
'\"');
404 GenericStringStream<SourceEncoding> is(str);
405 while (ScanWriteUnescapedString(is, length)) {
406 const Ch c = is.Peek();
407 if (!TargetEncoding::supportUnicode &&
static_cast<unsigned>(c) >= 0x80) {
412 PutUnsafe(*os_,
'\\');
413 PutUnsafe(*os_,
'u');
414 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
415 PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
416 PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]);
417 PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]);
418 PutUnsafe(*os_, hexDigits[(codepoint ) & 15]);
423 unsigned s = codepoint - 0x010000;
424 unsigned lead = (s >> 10) + 0xD800;
425 unsigned trail = (s & 0x3FF) + 0xDC00;
426 PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
427 PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]);
428 PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]);
429 PutUnsafe(*os_, hexDigits[(lead ) & 15]);
430 PutUnsafe(*os_,
'\\');
431 PutUnsafe(*os_,
'u');
432 PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
433 PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]);
434 PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]);
435 PutUnsafe(*os_, hexDigits[(trail ) & 15]);
438 else if ((
sizeof(Ch) == 1 ||
static_cast<unsigned>(c) < 256) &&
RAPIDJSON_UNLIKELY(escape[
static_cast<unsigned char>(c)])) {
440 PutUnsafe(*os_,
'\\');
441 PutUnsafe(*os_,
static_cast<typename OutputStream::Ch
>(escape[
static_cast<unsigned char>(c)]));
442 if (escape[
static_cast<unsigned char>(c)] ==
'u') {
443 PutUnsafe(*os_,
'0');
444 PutUnsafe(*os_,
'0');
445 PutUnsafe(*os_, hexDigits[
static_cast<unsigned char>(c) >> 4]);
446 PutUnsafe(*os_, hexDigits[
static_cast<unsigned char>(c) & 0xF]);
451 Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
454 PutUnsafe(*os_,
'\"');
458 bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is,
size_t length) {
462 bool WriteStartObject() { os_->Put(
'{');
return true; }
463 bool WriteEndObject() { os_->Put(
'}');
return true; }
464 bool WriteStartArray() { os_->Put(
'[');
return true; }
465 bool WriteEndArray() { os_->Put(
']');
return true; }
467 bool WriteRawValue(
const Ch* json,
size_t length) {
468 PutReserve(*os_, length);
469 GenericStringStream<SourceEncoding> is(json);
474 Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
480 void Prefix(
Type type) {
483 Level* level = level_stack_.template Top<Level>();
484 if (level->valueCount > 0) {
488 os_->Put((level->valueCount % 2 == 0) ?
',' :
':');
490 if (!level->inArray && level->valueCount % 2 == 0)
501 bool EndValue(
bool ret) {
508 internal::Stack<StackAllocator> level_stack_;
509 int maxDecimalPlaces_;