1 #ifndef RAPIDJSON_WRITER_H_
2 #define RAPIDJSON_WRITER_H_
5 #include "internal/stack.h"
6 #include "internal/strfunc.h"
12 #pragma warning(disable : 4127) // conditional expression is constant
31 template<
typename Stream,
typename Encoding = UTF8<>,
typename Allocator = MemoryPoolAllocator<> >
34 typedef typename Encoding::Ch Ch;
37 stream_(stream), level_stack_(allocator, levelDepth *
sizeof(
Level)) {}
41 Writer& Null() { Prefix(kNullType); WriteNull();
return *
this; }
42 Writer& Bool(
bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b);
return *
this; }
43 Writer& Int(
int i) { Prefix(kNumberType); WriteInt(i);
return *
this; }
44 Writer& Uint(
unsigned u) { Prefix(kNumberType); WriteUint(u);
return *
this; }
45 Writer& Int64(int64_t i64) { Prefix(kNumberType); WriteInt64(i64);
return *
this; }
46 Writer& Uint64(uint64_t u64) { Prefix(kNumberType); WriteUint64(u64);
return *
this; }
49 Writer& String(
const Ch* str, SizeType length,
bool copy =
false) {
52 WriteString(str, length);
58 new (level_stack_.template Push<Level>())
Level(
false);
63 Writer& EndObject(SizeType memberCount = 0) {
65 RAPIDJSON_ASSERT(level_stack_.GetSize() >=
sizeof(
Level));
66 RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
67 level_stack_.template Pop<Level>(1);
74 new (level_stack_.template Push<Level>())
Level(
true);
79 Writer& EndArray(SizeType elementCount = 0) {
81 RAPIDJSON_ASSERT(level_stack_.GetSize() >=
sizeof(
Level));
82 RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
83 level_stack_.template Pop<Level>(1);
100 static const size_t kDefaultLevelDepth = 32;
103 stream_.Put(
'n'); stream_.Put(
'u'); stream_.Put(
'l'); stream_.Put(
'l');
106 void WriteBool(
bool b) {
108 stream_.Put(
't'); stream_.Put(
'r'); stream_.Put(
'u'); stream_.Put(
'e');
111 stream_.Put(
'f'); stream_.Put(
'a'); stream_.Put(
'l'); stream_.Put(
's'); stream_.Put(
'e');
115 void WriteInt(
int i) {
120 WriteUint((
unsigned)i);
123 void WriteUint(
unsigned u) {
127 *p++ = (u % 10) +
'0';
134 }
while (p != buffer);
137 void WriteInt64(int64_t i64) {
142 WriteUint64((uint64_t)i64);
145 void WriteUint64(uint64_t u64) {
149 *p++ = char(u64 % 10) +
'0';
156 }
while (p != buffer);
163 int ret = sprintf_s(buffer,
sizeof(buffer),
"%g", d);
165 int ret = snprintf(buffer,
sizeof(buffer),
"%g", d);
167 RAPIDJSON_ASSERT(ret >= 1);
168 for (
int i = 0; i < ret; i++)
169 stream_.Put(buffer[i]);
172 void WriteString(
const Ch* str, SizeType length) {
173 static const char hexDigits[] =
"0123456789ABCDEF";
174 static const char escape[256] = {
175 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
177 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
178 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
179 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
182 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
187 for (
const Ch* p = str; p != str + length; ++p) {
188 if ((
sizeof(Ch) == 1 || *p < 256) && escape[(
unsigned char)*p]) {
190 stream_.Put(escape[(
unsigned char)*p]);
191 if (escape[(
unsigned char)*p] ==
'u') {
194 stream_.Put(hexDigits[(*p) >> 4]);
195 stream_.Put(hexDigits[(*p) & 0xF]);
204 void WriteStartObject() { stream_.Put(
'{'); }
205 void WriteEndObject() { stream_.Put(
'}'); }
206 void WriteStartArray() { stream_.Put(
'['); }
207 void WriteEndArray() { stream_.Put(
']'); }
209 void Prefix(Type type) {
211 if (level_stack_.GetSize() != 0) {
212 Level* level = level_stack_.template Top<Level>();
213 if (level->valueCount > 0) {
217 stream_.Put((level->valueCount % 2 == 0) ?
',' :
':');
219 if (!level->inArray && level->valueCount % 2 == 0)
220 RAPIDJSON_ASSERT(type == kStringType);
224 RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);
228 internal::Stack<Allocator> level_stack_;
232 Writer& operator=(
const Writer& w);
241 #endif // RAPIDJSON_RAPIDJSON_H_