2 #ifdef JSON_WRITE_PRIORITY
3 #include "JSONWorker.h"
4 #include "JSONGlobals.h"
6 extern bool used_ascii_one;
9 inline json_string makeIndent(
unsigned int amount) json_nothrow json_write_priority;
10 inline json_string makeIndent(
unsigned int amount) json_nothrow {
11 if (amount == 0xFFFFFFFF)
return json_global(EMPTY_JSON_STRING);
13 result.reserve(amount * json_global(INDENT).length());
14 for(
unsigned int i = 0; i < amount; ++i){
15 result += json_global(INDENT);
17 JSON_ASSERT(result.capacity() == amount * json_global(INDENT).length(), JSON_TEXT(
"makeIndent made a string too big"));
21 inline json_string makeIndent(
unsigned int amount) json_nothrow {
22 if (amount == 0xFFFFFFFF)
return json_global(EMPTY_JSON_STRING);
23 if (json_likely(amount < 8)){
24 static const json_string cache[] = {
26 json_string(JSON_TEXT(
"\t")),
27 json_string(JSON_TEXT(
"\t\t")),
28 json_string(JSON_TEXT(
"\t\t\t")),
29 json_string(JSON_TEXT(
"\t\t\t\t")),
30 json_string(JSON_TEXT(
"\t\t\t\t\t")),
31 json_string(JSON_TEXT(
"\t\t\t\t\t\t")),
32 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t"))
36 #ifndef JSON_LESS_MEMORY
37 if (json_likely(amount < 16)){
38 static const json_string cache[] = {
39 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t")),
40 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t")),
41 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t")),
42 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t")),
43 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t")),
44 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t")),
45 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t")),
46 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"))
48 return cache[amount - 8];
50 #if JSON_WRITE_PRIORITY == HIGH
51 if (json_likely(amount < 24)){
52 static const json_string cache[] = {
53 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t")),
54 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t")),
55 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t")),
56 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t")),
57 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t")),
58 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t")),
59 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t")),
60 json_string(JSON_TEXT(
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"))
62 return cache[amount - 16];
66 return json_string(amount, JSON_TEXT(
'\t'));
70 void internalJSONNode::WriteName(
bool formatted,
bool arrayChild, json_string & output)
const json_nothrow {
72 output += JSON_TEXT(
"\"");
73 JSONWorker::UnfixString(_name, _name_encoded, output);
74 output += ((formatted) ? JSON_TEXT(
"\" : ") : JSON_TEXT(
"\":"));
78 void internalJSONNode::WriteChildren(
unsigned int indent, json_string & output)
const json_nothrow {
80 if (json_likely(CHILDREN -> empty()))
return;
82 json_string indent_plus_one;
84 if (indent != 0xFFFFFFFF){
85 indent_plus_one = json_global(NEW_LINE) + makeIndent(++indent);
89 const size_t size_minus_one = CHILDREN -> size() - 1;
91 JSONNode ** it = CHILDREN -> begin();
92 for(JSONNode ** it_end = CHILDREN -> end(); it != it_end; ++it, ++i){
94 output += indent_plus_one;
95 (*it) ->
internal -> Write(indent, type() == JSON_ARRAY, output);
96 if (json_likely(i < size_minus_one)) output += JSON_TEXT(
',');
98 if (indent != 0xFFFFFFFF){
99 output += json_global(NEW_LINE);
100 output += makeIndent(indent - 1);
104 #ifdef JSON_ARRAY_SIZE_ON_ONE_LINE
105 void internalJSONNode::WriteChildrenOneLine(
unsigned int indent, json_string & output)
const json_nothrow {
107 if (json_likely(CHILDREN -> empty()))
return;
108 if ((*CHILDREN -> begin()) ->
internal -> isContainer())
return WriteChildren(indent, output);
110 json_string comma(JSON_TEXT(
","));
111 if (indent != 0xFFFFFFFF){
112 comma += JSON_TEXT(
' ');
116 const size_t size_minus_one = CHILDREN -> size() - 1;
118 JSONNode ** it = CHILDREN -> begin();
119 for(JSONNode ** it_end = CHILDREN -> end(); it != it_end; ++it, ++i){
120 (*it) ->
internal -> Write(indent, type() == JSON_ARRAY, output);
121 if (json_likely(i < size_minus_one)) output += comma;
127 void internalJSONNode::WriteComment(
unsigned int indent, json_string & output)
const json_nothrow {
128 if (indent == 0xFFFFFFFF)
return;
129 if (json_likely(_comment.empty()))
return;
130 size_t pos = _comment.find(JSON_TEXT(
'\n'));
132 const json_string current_indent(json_global(NEW_LINE) + makeIndent(indent));
134 if (json_likely(pos == json_string::npos)){
135 output += current_indent;
136 output += json_global(SINGLELINE_COMMENT);
137 output.append(_comment.begin(), _comment.end());
138 output += current_indent;
145 output += current_indent;
146 #if !(defined(JSON_WRITE_BASH_COMMENTS) || defined(JSON_WRITE_SINGLE_LINE_COMMENTS))
147 const json_string current_indent_plus_one(json_global(NEW_LINE) + makeIndent(indent + 1));
148 output += JSON_TEXT(
"/*");
149 output += current_indent_plus_one;
152 while(pos != json_string::npos){
153 if (json_unlikely(pos && _comment[pos - 1] == JSON_TEXT(
'\r'))) --pos;
154 #if defined(JSON_WRITE_BASH_COMMENTS) || defined(JSON_WRITE_SINGLE_LINE_COMMENTS)
155 output += json_global(SINGLELINE_COMMENT);
157 output.append(_comment.begin() + old, _comment.begin() + pos);
159 #if defined(JSON_WRITE_BASH_COMMENTS) || defined(JSON_WRITE_SINGLE_LINE_COMMENTS)
160 output += current_indent;
162 output += current_indent_plus_one;
164 old = (_comment[pos] == JSON_TEXT(
'\r')) ? pos + 2 : pos + 1;
165 pos = _comment.find(JSON_TEXT(
'\n'), old);
167 #if defined(JSON_WRITE_BASH_COMMENTS) || defined(JSON_WRITE_SINGLE_LINE_COMMENTS)
168 output += json_global(SINGLELINE_COMMENT);
170 output.append(_comment.begin() + old, _comment.end());
171 output += current_indent;
172 #if !(defined(JSON_WRITE_BASH_COMMENTS) || defined(JSON_WRITE_SINGLE_LINE_COMMENTS))
173 output += JSON_TEXT(
"*/");
174 output += current_indent;
178 inline void internalJSONNode::WriteComment(
unsigned int, json_string &) const json_nothrow {}
181 void internalJSONNode::DumpRawString(json_string & output)
const json_nothrow {
184 json_string result(_string.begin(), _string.end());
185 for(json_string::iterator beg = result.begin(), en = result.end(); beg != en; ++beg){
186 if (*beg == JSON_TEXT(
'\1')) *beg = JSON_TEXT(
'\"');
191 output.append(_string.begin(), _string.end());
195 void internalJSONNode::Write(
unsigned int indent,
bool arrayChild, json_string & output)
const json_nothrow {
196 const bool formatted = indent != 0xFFFFFFFF;
197 WriteComment(indent, output);
199 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
200 if (!(formatted || fetched)){
201 WriteName(
false, arrayChild, output);
203 DumpRawString(output);
208 WriteName(formatted, arrayChild, output);
213 output += JSON_TEXT(
"{");
214 WriteChildren(indent, output);
215 output += JSON_TEXT(
"}");
219 output += JSON_TEXT(
"[");
220 #ifdef JSON_ARRAY_SIZE_ON_ONE_LINE
221 if (size() <= JSON_ARRAY_SIZE_ON_ONE_LINE){
222 WriteChildrenOneLine(indent, output);
225 WriteChildren(indent, output);
226 #ifdef JSON_ARRAY_SIZE_ON_ONE_LINE
229 output += JSON_TEXT(
"]");
234 output.append(_string.begin(), _string.end());
238 JSON_ASSERT(_type == JSON_STRING, JSON_TEXT(
"Unknown json node type"));
240 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
241 if (json_likely(fetched)){
243 output += JSON_TEXT(
"\"");
244 JSONWorker::UnfixString(_string, _string_encoded, output);
245 output += JSON_TEXT(
"\"");
246 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
248 DumpRawString(output);