1 #ifndef RAPIDJSON_WRITER_H_
2 #define RAPIDJSON_WRITER_H_
5 #include "internal/stack.h"
6 #include "internal/strfunc.h"
7 #include "internal/itoa.h"
8 #include "stringbuffer.h"
14 RAPIDJSON_DIAG_OFF(4127)
35 template<
typename OutputStream,
typename SourceEncoding = UTF8<>,
typename TargetEncoding = UTF8<>,
typename Allocator = MemoryPoolAllocator<> >
38 typedef typename SourceEncoding::Ch Ch;
45 Writer(OutputStream& os,
Allocator* allocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
46 os_(&os), level_stack_(allocator, levelDepth * sizeof(
Level)),
47 doublePrecision_(kDefaultDoublePrecision), hasRoot_(false) {}
49 Writer(
Allocator* allocator = 0,
size_t levelDepth = kDefaultLevelDepth) :
50 os_(0), level_stack_(allocator, levelDepth * sizeof(Level)),
51 doublePrecision_(kDefaultDoublePrecision), hasRoot_(false) {}
73 doublePrecision_ = kDefaultDoublePrecision;
83 return hasRoot_ && level_stack_.Empty();
93 if (p < 0) p = kDefaultDoublePrecision;
106 bool Null() { Prefix(
kNullType);
return WriteNull(); }
108 bool Int(
int i) { Prefix(
kNumberType);
return WriteInt(i); }
109 bool Uint(
unsigned u) { Prefix(
kNumberType);
return WriteUint(u); }
110 bool Int64(int64_t i64) { Prefix(
kNumberType);
return WriteInt64(i64); }
111 bool Uint64(uint64_t u64) { Prefix(
kNumberType);
return WriteUint64(u64); }
126 bool String(
const Ch* str,
SizeType length,
bool copy =
false) {
129 return WriteString(str, length);
134 new (level_stack_.template Push<Level>()) Level(
false);
135 return WriteStartObject();
138 bool EndObject(
SizeType memberCount = 0) {
142 level_stack_.template Pop<Level>(1);
143 bool ret = WriteEndObject();
144 if (level_stack_.Empty())
151 new (level_stack_.template Push<Level>()) Level(
true);
152 return WriteStartArray();
155 bool EndArray(
SizeType elementCount = 0) {
159 level_stack_.template Pop<Level>(1);
160 bool ret = WriteEndArray();
161 if (level_stack_.Empty())
188 bool String(
const Ch* str) {
return String(str, internal::StrLen(str)); }
200 static const size_t kDefaultLevelDepth = 32;
203 os_->Put(
'n'); os_->Put(
'u'); os_->Put(
'l'); os_->Put(
'l');
return true;
206 bool WriteBool(
bool b) {
208 os_->Put(
't'); os_->Put(
'r'); os_->Put(
'u'); os_->Put(
'e');
211 os_->Put(
'f'); os_->Put(
'a'); os_->Put(
'l'); os_->Put(
's'); os_->Put(
'e');
216 bool WriteInt(
int i) {
218 const char* end = internal::i32toa(i, buffer);
219 for (
const char* p = buffer; p != end; ++p)
224 bool WriteUint(
unsigned u) {
226 const char* end = internal::u32toa(u, buffer);
227 for (
const char* p = buffer; p != end; ++p)
232 bool WriteInt64(int64_t i64) {
234 const char* end = internal::i64toa(i64, buffer);
235 for (
const char* p = buffer; p != end; ++p)
240 bool WriteUint64(uint64_t u64) {
242 const char* end = internal::u64toa(u64, buffer);
243 for (
const char* p = buffer; p != end; ++p)
249 #define RAPIDJSON_SNPRINTF sprintf_s
251 #define RAPIDJSON_SNPRINTF snprintf
257 int ret = RAPIDJSON_SNPRINTF(buffer,
sizeof(buffer),
"%.*g", doublePrecision_, d);
259 for (
int i = 0; i < ret; i++)
263 #undef RAPIDJSON_SNPRINTF
265 bool WriteString(
const Ch* str,
SizeType length) {
266 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
267 static const char escape[256] = {
268 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
270 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'b',
't',
'n',
'u',
'f',
'r',
'u',
'u',
271 'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
'u',
272 0, 0,
'"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
275 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
280 GenericStringStream<SourceEncoding> is(str);
281 while (is.Tell() < length) {
282 const Ch c = is.Peek();
283 if (!TargetEncoding::supportUnicode && (
unsigned)c >= 0x80) {
286 if (!SourceEncoding::Decode(is, &codepoint))
290 if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
291 os_->Put(hexDigits[(codepoint >> 12) & 15]);
292 os_->Put(hexDigits[(codepoint >> 8) & 15]);
293 os_->Put(hexDigits[(codepoint >> 4) & 15]);
294 os_->Put(hexDigits[(codepoint ) & 15]);
296 else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF) {
298 unsigned s = codepoint - 0x010000;
299 unsigned lead = (s >> 10) + 0xD800;
300 unsigned trail = (s & 0x3FF) + 0xDC00;
301 os_->Put(hexDigits[(lead >> 12) & 15]);
302 os_->Put(hexDigits[(lead >> 8) & 15]);
303 os_->Put(hexDigits[(lead >> 4) & 15]);
304 os_->Put(hexDigits[(lead ) & 15]);
307 os_->Put(hexDigits[(trail >> 12) & 15]);
308 os_->Put(hexDigits[(trail >> 8) & 15]);
309 os_->Put(hexDigits[(trail >> 4) & 15]);
310 os_->Put(hexDigits[(trail ) & 15]);
315 else if ((
sizeof(Ch) == 1 || (
unsigned)c < 256) && escape[(
unsigned char)c]) {
318 os_->Put(escape[(
unsigned char)c]);
319 if (escape[(
unsigned char)c] ==
'u') {
322 os_->Put(hexDigits[(
unsigned char)c >> 4]);
323 os_->Put(hexDigits[(
unsigned char)c & 0xF]);
333 bool WriteStartObject() { os_->Put(
'{');
return true; }
334 bool WriteEndObject() { os_->Put(
'}');
return true; }
335 bool WriteStartArray() { os_->Put(
'[');
return true; }
336 bool WriteEndArray() { os_->Put(
']');
return true; }
338 void Prefix(
Type type) {
340 if (level_stack_.GetSize() != 0) {
341 Level* level = level_stack_.template Top<Level>();
342 if (level->valueCount > 0) {
346 os_->Put((level->valueCount % 2 == 0) ?
',' :
':');
348 if (!level->inArray && level->valueCount % 2 == 0)
360 internal::Stack<Allocator> level_stack_;
361 int doublePrecision_;
364 static const int kDefaultDoublePrecision = 6;
375 inline bool Writer<StringBuffer>::WriteInt(
int i) {
376 char *buffer = os_->Push(11);
377 const char* end = internal::i32toa(i, buffer);
378 os_->Pop(11 - (end - buffer));
383 inline bool Writer<StringBuffer>::WriteUint(
unsigned u) {
384 char *buffer = os_->Push(10);
385 const char* end = internal::u32toa(u, buffer);
386 os_->Pop(10 - (end - buffer));
391 inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
392 char *buffer = os_->Push(21);
393 const char* end = internal::i64toa(i64, buffer);
394 os_->Pop(21 - (end - buffer));
399 inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
400 char *buffer = os_->Push(20);
401 const char* end = internal::u64toa(u, buffer);
402 os_->Pop(20 - (end - buffer));
412 #endif // RAPIDJSON_RAPIDJSON_H_
true
Definition: rapidjson.h:394
bool IsComplete() const
Checks whether the output is a complete JSON.
Definition: writer.h:82
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:133
false
Definition: rapidjson.h:393
bool Double(double d)
Writes the given double value to the stream.
Definition: writer.h:124
void Reset(OutputStream &os)
Reset the writer with a new stream.
Definition: writer.h:71
bool inArray
true if in array, otherwise in object
Definition: writer.h:197
Information for each nested level.
Definition: writer.h:194
Writer & SetDoublePrecision(int p=kDefaultDoublePrecision)
Set the number of significant digits for double values.
Definition: writer.h:92
bool Double(double d, int precision)
Writes the given double value to the stream (explicit precision)
Definition: writer.h:179
int GetDoublePrecision() const
Definition: writer.h:99
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:146
bool String(const Ch *str)
Simpler but slower overload.
Definition: writer.h:188
Type
Type of JSON value.
Definition: rapidjson.h:391
object
Definition: rapidjson.h:395
array
Definition: rapidjson.h:396
JSON writer.
Definition: writer.h:36
main RapidJSON namespace
Definition: allocators.h:6
null
Definition: rapidjson.h:392
bool WriteDouble(double d)
Definition: writer.h:255
size_t valueCount
number of values in this level
Definition: writer.h:196
string
Definition: rapidjson.h:397
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:574
number
Definition: rapidjson.h:398
Writer(OutputStream &os, Allocator *allocator=0, size_t levelDepth=kDefaultLevelDepth)
Constructor.
Definition: writer.h:45