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 Allocator = MemoryPoolAllocator<> >
58 typedef typename SourceEncoding::Ch Ch;
65 Writer(OutputStream& os,
Allocator* allocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
66 os_(&os), level_stack_(allocator, levelDepth * sizeof(
Level)), hasRoot_(false) {}
68 Writer(
Allocator* 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 EndObject(
SizeType memberCount = 0) {
138 level_stack_.template Pop<Level>(1);
139 bool ret = WriteEndObject();
140 if (level_stack_.Empty())
147 new (level_stack_.template Push<Level>()) Level(
true);
148 return WriteStartArray();
151 bool EndArray(
SizeType elementCount = 0) {
155 level_stack_.template Pop<Level>(1);
156 bool ret = WriteEndArray();
157 if (level_stack_.Empty())
167 bool String(
const Ch* str) {
return String(str, internal::StrLen(str)); }
179 static const size_t kDefaultLevelDepth = 32;
182 os_->Put(
'n'); os_->Put(
'u'); os_->Put(
'l'); os_->Put(
'l');
return true;
185 bool WriteBool(
bool b) {
187 os_->Put(
't'); os_->Put(
'r'); os_->Put(
'u'); os_->Put(
'e');
190 os_->Put(
'f'); os_->Put(
'a'); os_->Put(
'l'); os_->Put(
's'); os_->Put(
'e');
195 bool WriteInt(
int i) {
197 const char* end = internal::i32toa(i, buffer);
198 for (
const char* p = buffer; p != end; ++p)
203 bool WriteUint(
unsigned u) {
205 const char* end = internal::u32toa(u, buffer);
206 for (
const char* p = buffer; p != end; ++p)
211 bool WriteInt64(int64_t i64) {
213 const char* end = internal::i64toa(i64, buffer);
214 for (
const char* p = buffer; p != end; ++p)
219 bool WriteUint64(uint64_t u64) {
221 char* end = internal::u64toa(u64, buffer);
222 for (
char* p = buffer; p != end; ++p)
227 bool WriteDouble(
double d) {
229 char* end = internal::dtoa(d, buffer);
230 for (
char* p = buffer; p != end; ++p)
235 bool WriteString(
const Ch* str,
SizeType length) {
236 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
237 static const char escape[256] = {
238 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
240 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
241 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
242 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
245 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
250 GenericStringStream<SourceEncoding> is(str);
251 while (is.Tell() < length) {
252 const Ch c = is.Peek();
253 if (!TargetEncoding::supportUnicode && (
unsigned)c >= 0x80) {
256 if (!SourceEncoding::Decode(is, &codepoint))
260 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
261 os_->Put(hexDigits[(codepoint >> 12) & 15]);
262 os_->Put(hexDigits[(codepoint >> 8) & 15]);
263 os_->Put(hexDigits[(codepoint >> 4) & 15]);
264 os_->Put(hexDigits[(codepoint ) & 15]);
266 else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF) {
268 unsigned s = codepoint - 0x010000;
269 unsigned lead = (s >> 10) + 0xD800;
270 unsigned trail = (s & 0x3FF) + 0xDC00;
271 os_->Put(hexDigits[(lead >> 12) & 15]);
272 os_->Put(hexDigits[(lead >> 8) & 15]);
273 os_->Put(hexDigits[(lead >> 4) & 15]);
274 os_->Put(hexDigits[(lead ) & 15]);
277 os_->Put(hexDigits[(trail >> 12) & 15]);
278 os_->Put(hexDigits[(trail >> 8) & 15]);
279 os_->Put(hexDigits[(trail >> 4) & 15]);
280 os_->Put(hexDigits[(trail ) & 15]);
285 else if ((
sizeof(Ch) == 1 || (
unsigned)c < 256) && escape[(
unsigned char)c]) {
288 os_->Put(escape[(
unsigned char)c]);
289 if (escape[(
unsigned char)c] ==
'u') {
292 os_->Put(hexDigits[(
unsigned char)c >> 4]);
293 os_->Put(hexDigits[(
unsigned char)c & 0xF]);
303 bool WriteStartObject() { os_->Put(
'{');
return true; }
304 bool WriteEndObject() { os_->Put(
'}');
return true; }
305 bool WriteStartArray() { os_->Put(
'[');
return true; }
306 bool WriteEndArray() { os_->Put(
']');
return true; }
308 void Prefix(
Type type) {
310 if (level_stack_.GetSize() != 0) {
311 Level* level = level_stack_.template Top<Level>();
312 if (level->valueCount > 0) {
316 os_->Put((level->valueCount % 2 == 0) ?
',' :
':');
318 if (!level->inArray && level->valueCount % 2 == 0)
329 internal::Stack<Allocator> level_stack_;
341 inline bool Writer<StringBuffer>::WriteInt(
int i) {
342 char *buffer = os_->Push(11);
343 const char* end = internal::i32toa(i, buffer);
344 os_->Pop(11 - (end - buffer));
349 inline bool Writer<StringBuffer>::WriteUint(
unsigned u) {
350 char *buffer = os_->Push(10);
351 const char* end = internal::u32toa(u, buffer);
352 os_->Pop(10 - (end - buffer));
357 inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
358 char *buffer = os_->Push(21);
359 const char* end = internal::i64toa(i64, buffer);
360 os_->Pop(21 - (end - buffer));
365 inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
366 char *buffer = os_->Push(20);
367 const char* end = internal::u64toa(u, buffer);
368 os_->Pop(20 - (end - buffer));
373 inline bool Writer<StringBuffer>::WriteDouble(
double d) {
374 char *buffer = os_->Push(25);
375 char* end = internal::dtoa(d, buffer);
376 os_->Pop(25 - (end - buffer));
386 #endif // RAPIDJSON_RAPIDJSON_H_
true
Definition: rapidjson.h:423
bool IsComplete() const
Checks whether the output is a complete JSON.
Definition: writer.h:99
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:162
false
Definition: rapidjson.h:422
bool Double(double d)
Writes the given double value to the stream.
Definition: writer.h:120
void Reset(OutputStream &os)
Reset the writer with a new stream.
Definition: writer.h:89
bool inArray
true if in array, otherwise in object
Definition: writer.h:176
Information for each nested level.
Definition: writer.h:173
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:175
bool String(const Ch *str)
Simpler but slower overload.
Definition: writer.h:167
Type
Type of JSON value.
Definition: rapidjson.h:420
object
Definition: rapidjson.h:424
array
Definition: rapidjson.h:425
JSON writer.
Definition: writer.h:56
null
Definition: rapidjson.h:421
size_t valueCount
number of values in this level
Definition: writer.h:175
string
Definition: rapidjson.h:426
common definitions and configuration
Concept for allocating, resizing and freeing memory block.
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
number
Definition: rapidjson.h:427
Writer(OutputStream &os, Allocator *allocator=0, size_t levelDepth=kDefaultLevelDepth)
Constructor.
Definition: writer.h:65