21 #ifndef RAPIDJSON_WRITER_H_ 22 #define RAPIDJSON_WRITER_H_ 25 #include "internal/stack.h" 26 #include "internal/strfunc.h" 27 #include "internal/dtoa.h" 28 #include "internal/itoa.h" 29 #include "stringbuffer.h" 34 RAPIDJSON_DIAG_OFF(4127)
55 template<
typename OutputStream,
typename SourceEncoding = UTF8<>,
typename TargetEncoding = UTF8<>,
typename StackAllocator = CrtAllocator>
58 typedef typename SourceEncoding::Ch Ch;
65 Writer(OutputStream& os, StackAllocator* stackAllocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
66 os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(
Level)), hasRoot_(false) {}
68 Writer(StackAllocator* allocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
69 os_(0), level_stack_(allocator, levelDepth *
sizeof(
Level)), hasRoot_(
false) {}
100 return hasRoot_ && level_stack_.Empty();
108 bool Null() { Prefix(
kNullType);
return WriteNull(); }
110 bool Int(
int i) { Prefix(
kNumberType);
return WriteInt(i); }
111 bool Uint(
unsigned u) { Prefix(
kNumberType);
return WriteUint(u); }
112 bool Int64(int64_t i64) { Prefix(
kNumberType);
return WriteInt64(i64); }
113 bool Uint64(uint64_t u64) { Prefix(
kNumberType);
return WriteUint64(u64); }
122 bool String(
const Ch* str,
SizeType length,
bool copy =
false) {
125 return WriteString(str, length);
130 new (level_stack_.template Push<Level>())
Level(
false);
131 return WriteStartObject();
134 bool Key(
const Ch* str,
SizeType length,
bool copy =
false) {
return String(str, length, copy); }
136 bool EndObject(
SizeType memberCount = 0) {
140 level_stack_.template Pop<Level>(1);
141 bool ret = WriteEndObject();
142 if (level_stack_.Empty())
149 new (level_stack_.template Push<Level>())
Level(
true);
150 return WriteStartArray();
153 bool EndArray(
SizeType elementCount = 0) {
157 level_stack_.template Pop<Level>(1);
158 bool ret = WriteEndArray();
159 if (level_stack_.Empty())
169 bool String(
const Ch* str) {
return String(str, internal::StrLen(str)); }
170 bool Key(
const Ch* str) {
return Key(str, internal::StrLen(str)); }
182 static const size_t kDefaultLevelDepth = 32;
185 os_->Put(
'n'); os_->Put(
'u'); os_->Put(
'l'); os_->Put(
'l');
return true;
188 bool WriteBool(
bool b) {
190 os_->Put(
't'); os_->Put(
'r'); os_->Put(
'u'); os_->Put(
'e');
193 os_->Put(
'f'); os_->Put(
'a'); os_->Put(
'l'); os_->Put(
's'); os_->Put(
'e');
198 bool WriteInt(
int i) {
200 const char* end = internal::i32toa(i, buffer);
201 for (
const char* p = buffer; p != end; ++p)
206 bool WriteUint(
unsigned u) {
208 const char* end = internal::u32toa(u, buffer);
209 for (
const char* p = buffer; p != end; ++p)
214 bool WriteInt64(int64_t i64) {
216 const char* end = internal::i64toa(i64, buffer);
217 for (
const char* p = buffer; p != end; ++p)
222 bool WriteUint64(uint64_t u64) {
224 char* end = internal::u64toa(u64, buffer);
225 for (
char* p = buffer; p != end; ++p)
230 bool WriteDouble(
double d) {
232 char* end = internal::dtoa(d, buffer);
233 for (
char* p = buffer; p != end; ++p)
238 bool WriteString(
const Ch* str,
SizeType length) {
239 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
240 static const char escape[256] = {
241 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 243 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
244 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
245 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
247 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
248 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
254 while (is.Tell() < length) {
255 const Ch c = is.Peek();
256 if (!TargetEncoding::supportUnicode && (
unsigned)c >= 0x80) {
259 if (!SourceEncoding::Decode(is, &codepoint))
263 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
264 os_->Put(hexDigits[(codepoint >> 12) & 15]);
265 os_->Put(hexDigits[(codepoint >> 8) & 15]);
266 os_->Put(hexDigits[(codepoint >> 4) & 15]);
267 os_->Put(hexDigits[(codepoint ) & 15]);
269 else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF) {
271 unsigned s = codepoint - 0x010000;
272 unsigned lead = (s >> 10) + 0xD800;
273 unsigned trail = (s & 0x3FF) + 0xDC00;
274 os_->Put(hexDigits[(lead >> 12) & 15]);
275 os_->Put(hexDigits[(lead >> 8) & 15]);
276 os_->Put(hexDigits[(lead >> 4) & 15]);
277 os_->Put(hexDigits[(lead ) & 15]);
280 os_->Put(hexDigits[(trail >> 12) & 15]);
281 os_->Put(hexDigits[(trail >> 8) & 15]);
282 os_->Put(hexDigits[(trail >> 4) & 15]);
283 os_->Put(hexDigits[(trail ) & 15]);
288 else if ((
sizeof(Ch) == 1 || (
unsigned)c < 256) && escape[(
unsigned char)c]) {
291 os_->Put(escape[(
unsigned char)c]);
292 if (escape[(
unsigned char)c] ==
'u') {
295 os_->Put(hexDigits[(
unsigned char)c >> 4]);
296 os_->Put(hexDigits[(
unsigned char)c & 0xF]);
306 bool WriteStartObject() { os_->Put(
'{');
return true; }
307 bool WriteEndObject() { os_->Put(
'}');
return true; }
308 bool WriteStartArray() { os_->Put(
'[');
return true; }
309 bool WriteEndArray() { os_->Put(
']');
return true; }
311 void Prefix(
Type type) {
313 if (level_stack_.GetSize() != 0) {
314 Level* level = level_stack_.template Top<Level>();
319 os_->Put((level->
valueCount % 2 == 0) ?
',' :
':');
332 internal::Stack<StackAllocator> level_stack_;
345 char *buffer = os_->Push(11);
346 const char* end = internal::i32toa(i, buffer);
347 os_->Pop(11 - (end - buffer));
353 char *buffer = os_->Push(10);
354 const char* end = internal::u32toa(u, buffer);
355 os_->Pop(10 - (end - buffer));
361 char *buffer = os_->Push(21);
362 const char* end = internal::i64toa(i64, buffer);
363 os_->Pop(21 - (end - buffer));
369 char *buffer = os_->Push(20);
370 const char* end = internal::u64toa(u, buffer);
371 os_->Pop(20 - (end - buffer));
377 char *buffer = os_->Push(25);
378 char* end = internal::dtoa(d, buffer);
379 os_->Pop(25 - (end - buffer));
389 #endif // RAPIDJSON_RAPIDJSON_H_ true
Definition: rapidjson.h:570
Read-only string stream.
Definition: rapidjson.h:496
bool Double(double d)
Writes the given double value to the stream.
Definition: writer.h:120
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:247
false
Definition: rapidjson.h:569
bool IsComplete() const
Checks whether the output is a complete JSON.
Definition: writer.h:99
bool inArray
true if in array, otherwise in object
Definition: writer.h:179
Information for each nested level.
Definition: writer.h:176
bool String(const Ch *str)
Simpler but slower overload.
Definition: writer.h:169
Type
Type of JSON value.
Definition: rapidjson.h:567
object
Definition: rapidjson.h:571
Writer(OutputStream &os, StackAllocator *stackAllocator=0, size_t levelDepth=kDefaultLevelDepth)
Constructor.
Definition: writer.h:65
size_t valueCount
number of values in this level
Definition: writer.h:178
array
Definition: rapidjson.h:572
JSON writer.
Definition: writer.h:56
main RapidJSON namespace
Definition: rapidjson.h:241
null
Definition: rapidjson.h:568
string
Definition: rapidjson.h:573
common definitions and configuration
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream &is, OutputStream &os)
Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the outp...
Definition: encodings.h:594
void Reset(OutputStream &os)
Reset the writer with a new stream.
Definition: writer.h:89
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:269
number
Definition: rapidjson.h:574