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_;