15 #ifndef RAPIDJSON_WRITER_H_
16 #define RAPIDJSON_WRITER_H_
19 #include "internal/stack.h"
20 #include "internal/strfunc.h"
21 #include "internal/dtoa.h"
22 #include "internal/itoa.h"
23 #include "stringbuffer.h"
26 #if RAPIDJSON_HAS_STDSTRING
32 RAPIDJSON_DIAG_OFF(4127)
35 RAPIDJSON_NAMESPACE_BEGIN
53 template<
typename OutputStream,
typename SourceEncoding = UTF8<>,
typename TargetEncoding = UTF8<>,
typename StackAllocator = CrtAllocator>
56 typedef typename SourceEncoding::Ch Ch;
64 Writer(OutputStream& os, StackAllocator* stackAllocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
65 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);
128 #if RAPIDJSON_HAS_STDSTRING
129 bool String(
const std::basic_string<Ch>& str) {
130 return String(str.data(),
SizeType(str.size()));
136 new (level_stack_.template Push<Level>()) Level(
false);
137 return WriteStartObject();
140 bool Key(
const Ch* str,
SizeType length,
bool copy =
false) {
return String(str, length, copy); }
142 bool EndObject(
SizeType memberCount = 0) {
146 level_stack_.template Pop<Level>(1);
147 bool ret = WriteEndObject();
148 if (level_stack_.Empty())
155 new (level_stack_.template Push<Level>()) Level(
true);
156 return WriteStartArray();
159 bool EndArray(
SizeType elementCount = 0) {
163 level_stack_.template Pop<Level>(1);
164 bool ret = WriteEndArray();
165 if (level_stack_.Empty())
175 bool String(
const Ch* str) {
return String(str, internal::StrLen(str)); }
176 bool Key(
const Ch* str) {
return Key(str, internal::StrLen(str)); }
183 Level(
bool inArray_) : valueCount(0), inArray(inArray_) {}
188 static const size_t kDefaultLevelDepth = 32;
191 os_->Put(
'n'); os_->Put(
'u'); os_->Put(
'l'); os_->Put(
'l');
return true;
194 bool WriteBool(
bool b) {
196 os_->Put(
't'); os_->Put(
'r'); os_->Put(
'u'); os_->Put(
'e');
199 os_->Put(
'f'); os_->Put(
'a'); os_->Put(
'l'); os_->Put(
's'); os_->Put(
'e');
204 bool WriteInt(
int i) {
206 const char* end = internal::i32toa(i, buffer);
207 for (
const char* p = buffer; p != end; ++p)
212 bool WriteUint(
unsigned u) {
214 const char* end = internal::u32toa(u, buffer);
215 for (
const char* p = buffer; p != end; ++p)
220 bool WriteInt64(int64_t i64) {
222 const char* end = internal::i64toa(i64, buffer);
223 for (
const char* p = buffer; p != end; ++p)
228 bool WriteUint64(uint64_t u64) {
230 char* end = internal::u64toa(u64, buffer);
231 for (
char* p = buffer; p != end; ++p)
236 bool WriteDouble(
double d) {
238 char* end = internal::dtoa(d, buffer);
239 for (
char* p = buffer; p != end; ++p)
244 bool WriteString(
const Ch* str,
SizeType length) {
245 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
246 static const char escape[256] = {
247 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
249 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
250 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
251 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
254 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
259 GenericStringStream<SourceEncoding> is(str);
260 while (is.Tell() < length) {
261 const Ch c = is.Peek();
262 if (!TargetEncoding::supportUnicode && (
unsigned)c >= 0x80) {
265 if (!SourceEncoding::Decode(is, &codepoint))
269 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
270 os_->Put(hexDigits[(codepoint >> 12) & 15]);
271 os_->Put(hexDigits[(codepoint >> 8) & 15]);
272 os_->Put(hexDigits[(codepoint >> 4) & 15]);
273 os_->Put(hexDigits[(codepoint ) & 15]);
278 unsigned s = codepoint - 0x010000;
279 unsigned lead = (s >> 10) + 0xD800;
280 unsigned trail = (s & 0x3FF) + 0xDC00;
281 os_->Put(hexDigits[(lead >> 12) & 15]);
282 os_->Put(hexDigits[(lead >> 8) & 15]);
283 os_->Put(hexDigits[(lead >> 4) & 15]);
284 os_->Put(hexDigits[(lead ) & 15]);
287 os_->Put(hexDigits[(trail >> 12) & 15]);
288 os_->Put(hexDigits[(trail >> 8) & 15]);
289 os_->Put(hexDigits[(trail >> 4) & 15]);
290 os_->Put(hexDigits[(trail ) & 15]);
293 else if ((
sizeof(Ch) == 1 || (
unsigned)c < 256) && escape[(
unsigned char)c]) {
296 os_->Put(escape[(
unsigned char)c]);
297 if (escape[(
unsigned char)c] ==
'u') {
300 os_->Put(hexDigits[(
unsigned char)c >> 4]);
301 os_->Put(hexDigits[(
unsigned char)c & 0xF]);
305 if (!Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_))
312 bool WriteStartObject() { os_->Put(
'{');
return true; }
313 bool WriteEndObject() { os_->Put(
'}');
return true; }
314 bool WriteStartArray() { os_->Put(
'[');
return true; }
315 bool WriteEndArray() { os_->Put(
']');
return true; }
317 void Prefix(
Type type) {
319 if (level_stack_.GetSize() != 0) {
320 Level* level = level_stack_.template Top<Level>();
321 if (level->valueCount > 0) {
325 os_->Put((level->valueCount % 2 == 0) ?
',' :
':');
327 if (!level->inArray && level->valueCount % 2 == 0)
338 internal::Stack<StackAllocator> level_stack_;
343 Writer(
const Writer&);
344 Writer& operator=(
const Writer&);
350 inline bool Writer<StringBuffer>::WriteInt(
int i) {
351 char *buffer = os_->Push(11);
352 const char* end = internal::i32toa(i, buffer);
353 os_->Pop(static_cast<size_t>(11 - (end - buffer)));
358 inline bool Writer<StringBuffer>::WriteUint(
unsigned u) {
359 char *buffer = os_->Push(10);
360 const char* end = internal::u32toa(u, buffer);
361 os_->Pop(static_cast<size_t>(10 - (end - buffer)));
366 inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
367 char *buffer = os_->Push(21);
368 const char* end = internal::i64toa(i64, buffer);
369 os_->Pop(static_cast<size_t>(21 - (end - buffer)));
374 inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
375 char *buffer = os_->Push(20);
376 const char* end = internal::u64toa(u, buffer);
377 os_->Pop(static_cast<size_t>(20 - (end - buffer)));
382 inline bool Writer<StringBuffer>::WriteDouble(
double d) {
383 char *buffer = os_->Push(25);
384 char* end = internal::dtoa(d, buffer);
385 os_->Pop(static_cast<size_t>(25 - (end - buffer)));
389 RAPIDJSON_NAMESPACE_END
395 #endif // RAPIDJSON_RAPIDJSON_H_
true
Definition: rapidjson.h:645
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:322
false
Definition: rapidjson.h:644
bool inArray
true if in array, otherwise in object
Definition: writer.h:185
Information for each nested level.
Definition: writer.h:182
bool String(const Ch *str)
Simpler but slower overload.
Definition: writer.h:175
Type
Type of JSON value.
Definition: rapidjson.h:642
object
Definition: rapidjson.h:646
Writer(OutputStream &os, StackAllocator *stackAllocator=0, size_t levelDepth=kDefaultLevelDepth)
Constructor.
Definition: writer.h:64
size_t valueCount
number of values in this level
Definition: writer.h:184
array
Definition: rapidjson.h:647
JSON writer.
Definition: writer.h:54
bool IsComplete() const
Checks whether the output is a complete JSON.
Definition: writer.h:99
null
Definition: rapidjson.h:643
string
Definition: rapidjson.h:648
common definitions and configuration
void Reset(OutputStream &os)
Reset the writer with a new stream.
Definition: writer.h:89
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
number
Definition: rapidjson.h:649