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
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]);
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>();
325 os_->Put((level->
valueCount % 2 == 0) ?
',' :
':');
338 internal::Stack<StackAllocator> level_stack_;
351 char *buffer = os_->Push(11);
352 const char* end = internal::i32toa(i, buffer);
353 os_->Pop(11 - (end - buffer));
359 char *buffer = os_->Push(10);
360 const char* end = internal::u32toa(u, buffer);
361 os_->Pop(10 - (end - buffer));
367 char *buffer = os_->Push(21);
368 const char* end = internal::i64toa(i64, buffer);
369 os_->Pop(21 - (end - buffer));
375 char *buffer = os_->Push(20);
376 const char* end = internal::u64toa(u, buffer);
377 os_->Pop(20 - (end - buffer));
383 char *buffer = os_->Push(25);
384 char* end = internal::dtoa(d, buffer);
385 os_->Pop(25 - (end - buffer));
389 RAPIDJSON_NAMESPACE_END
395 #endif // RAPIDJSON_RAPIDJSON_H_ true
Definition: rapidjson.h:645
Read-only string stream.
Definition: rapidjson.h:571
bool Double(double d)
Writes the given double value to the stream
Definition: writer.h:120
Encoding conversion.
Definition: encodings.h:586
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
false
Definition: rapidjson.h:644
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: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
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