89 typedef typename SourceEncoding::Ch Ch;
91 static const int kDefaultMaxDecimalPlaces = 324;
99 Writer(OutputStream& os, StackAllocator* stackAllocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
100 os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(
Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
103 Writer(StackAllocator* allocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
104 os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
127 level_stack_.Clear();
135 return hasRoot_ && level_stack_.Empty();
138 int GetMaxDecimalPlaces()
const {
139 return maxDecimalPlaces_;
164 maxDecimalPlaces_ = maxDecimalPlaces;
172 bool Null() { Prefix(kNullType);
return EndValue(WriteNull()); }
173 bool Bool(
bool b) { Prefix(b ? kTrueType : kFalseType);
return EndValue(WriteBool(b)); }
174 bool Int(
int i) { Prefix(kNumberType);
return EndValue(WriteInt(i)); }
175 bool Uint(
unsigned u) { Prefix(kNumberType);
return EndValue(WriteUint(u)); }
176 bool Int64(int64_t i64) { Prefix(kNumberType);
return EndValue(WriteInt64(i64)); }
177 bool Uint64(uint64_t u64) { Prefix(kNumberType);
return EndValue(WriteUint64(u64)); }
186 bool RawNumber(
const Ch* str,
SizeType length,
bool copy =
false) {
189 return EndValue(WriteString(str, length));
192 bool String(
const Ch* str, SizeType length,
bool copy =
false) {
195 return EndValue(WriteString(str, length));
198#if RAPIDJSON_HAS_STDSTRING
199 bool String(
const std::basic_string<Ch>& str) {
200 return String(str.data(),
SizeType(str.size()));
206 new (level_stack_.template Push<Level>()) Level(
false);
207 return WriteStartObject();
210 bool Key(
const Ch* str, SizeType length,
bool copy =
false) {
return String(str, length, copy); }
212 bool EndObject(SizeType memberCount = 0) {
216 level_stack_.template Pop<Level>(1);
217 return EndValue(WriteEndObject());
222 new (level_stack_.template Push<Level>()) Level(
true);
223 return WriteStartArray();
226 bool EndArray(SizeType elementCount = 0) {
230 level_stack_.template Pop<Level>(1);
231 return EndValue(WriteEndArray());
239 bool String(
const Ch* str) {
return String(str, internal::StrLen(str)); }
240 bool Key(
const Ch* str) {
return Key(str, internal::StrLen(str)); }
252 bool RawValue(
const Ch* json,
size_t length,
Type type) { Prefix(type);
return EndValue(WriteRawValue(json, length)); }
257 Level(
bool inArray_) : valueCount(0), inArray(inArray_) {}
262 static const size_t kDefaultLevelDepth = 32;
269 bool WriteBool(
bool b) {
276 PutUnsafe(*os_,
'f'); PutUnsafe(*os_,
'a'); PutUnsafe(*os_,
'l'); PutUnsafe(*os_,
's'); PutUnsafe(*os_,
'e');
281 bool WriteInt(
int i) {
283 const char* end = internal::i32toa(i, buffer);
284 PutReserve(*os_,
static_cast<size_t>(end - buffer));
285 for (
const char* p = buffer; p != end; ++p)
286 PutUnsafe(*os_,
static_cast<typename TargetEncoding::Ch
>(*p));
290 bool WriteUint(
unsigned u) {
292 const char* end = internal::u32toa(u, buffer);
293 PutReserve(*os_,
static_cast<size_t>(end - buffer));
294 for (
const char* p = buffer; p != end; ++p)
295 PutUnsafe(*os_,
static_cast<typename TargetEncoding::Ch
>(*p));
299 bool WriteInt64(int64_t i64) {
301 const char* end = internal::i64toa(i64, buffer);
302 PutReserve(*os_,
static_cast<size_t>(end - buffer));
303 for (
const char* p = buffer; p != end; ++p)
304 PutUnsafe(*os_,
static_cast<typename TargetEncoding::Ch
>(*p));
308 bool WriteUint64(uint64_t u64) {
310 char* end = internal::u64toa(u64, buffer);
311 PutReserve(*os_,
static_cast<size_t>(end - buffer));
312 for (
char* p = buffer; p != end; ++p)
313 PutUnsafe(*os_,
static_cast<typename TargetEncoding::Ch
>(*p));
317 bool WriteDouble(
double d) {
318 if (internal::Double(d).IsNanOrInf()) {
319 if (!(writeFlags & kWriteNanAndInfFlag))
321 if (internal::Double(d).IsNan()) {
326 if (internal::Double(d).Sign()) {
338 char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
339 PutReserve(*os_,
static_cast<size_t>(end - buffer));
340 for (
char* p = buffer; p != end; ++p)
341 PutUnsafe(*os_,
static_cast<typename TargetEncoding::Ch
>(*p));
345 bool WriteString(
const Ch* str, SizeType length) {
346 static const typename TargetEncoding::Ch hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
347 static const char escape[256] = {
348#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
350 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
351 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
352 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
355 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
359 if (TargetEncoding::supportUnicode)
365 GenericStringStream<SourceEncoding> is(str);
366 while (ScanWriteUnescapedString(is, length)) {
367 const Ch c = is.Peek();
368 if (!TargetEncoding::supportUnicode &&
static_cast<unsigned>(c) >= 0x80) {
375 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
376 PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
377 PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]);
378 PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]);
379 PutUnsafe(*os_, hexDigits[(codepoint ) & 15]);
384 unsigned s = codepoint - 0x010000;
385 unsigned lead = (s >> 10) + 0xD800;
386 unsigned trail = (s & 0x3FF) + 0xDC00;
387 PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
388 PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]);
389 PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]);
390 PutUnsafe(*os_, hexDigits[(lead ) & 15]);
393 PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
394 PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]);
395 PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]);
396 PutUnsafe(*os_, hexDigits[(trail ) & 15]);
399 else if ((
sizeof(Ch) == 1 ||
static_cast<unsigned>(c) < 256) &&
RAPIDJSON_UNLIKELY(escape[
static_cast<unsigned char>(c)])) {
402 PutUnsafe(*os_,
static_cast<typename TargetEncoding::Ch
>(escape[
static_cast<unsigned char>(c)]));
403 if (escape[
static_cast<unsigned char>(c)] ==
'u') {
406 PutUnsafe(*os_, hexDigits[
static_cast<unsigned char>(c) >> 4]);
407 PutUnsafe(*os_, hexDigits[
static_cast<unsigned char>(c) & 0xF]);
411 Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
412 Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
419 bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is,
size_t length) {
423 bool WriteStartObject() { os_->Put(
'{');
return true; }
424 bool WriteEndObject() { os_->Put(
'}');
return true; }
425 bool WriteStartArray() { os_->Put(
'[');
return true; }
426 bool WriteEndArray() { os_->Put(
']');
return true; }
428 bool WriteRawValue(
const Ch* json,
size_t length) {
430 for (
size_t i = 0; i < length; i++) {
437 void Prefix(Type type) {
440 Level* level = level_stack_.template Top<Level>();
441 if (level->valueCount > 0) {
445 os_->Put((level->valueCount % 2 == 0) ?
',' :
':');
447 if (!level->inArray && level->valueCount % 2 == 0)
458 bool EndValue(
bool ret) {
465 internal::Stack<StackAllocator> level_stack_;
466 int maxDecimalPlaces_;
471 Writer(
const Writer&);
472 Writer& operator=(
const Writer&);