| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/json_writer.h" | 5 #include "base/json_writer.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "base/string_escape.h" | 10 #include "base/string_escape.h" |
| 11 | 11 |
| 12 const char kPrettyPrintLineEnding[] = "\r\n"; | 12 const char kPrettyPrintLineEnding[] = "\r\n"; |
| 13 | 13 |
| 14 /* static */ | 14 /* static */ |
| 15 void JSONWriter::Write(const Value* const node, bool pretty_print, | 15 void JSONWriter::Write(const Value* const node, |
| 16 bool pretty_print, |
| 16 std::string* json) { | 17 std::string* json) { |
| 18 WriteWithOptionalEscape(node, pretty_print, true, json); |
| 19 } |
| 20 |
| 21 /* static */ |
| 22 void JSONWriter::WriteWithOptionalEscape(const Value* const node, |
| 23 bool pretty_print, |
| 24 bool escape, |
| 25 std::string* json) { |
| 17 json->clear(); | 26 json->clear(); |
| 18 // Is there a better way to estimate the size of the output? | 27 // Is there a better way to estimate the size of the output? |
| 19 json->reserve(1024); | 28 json->reserve(1024); |
| 20 JSONWriter writer(pretty_print, json); | 29 JSONWriter writer(pretty_print, json); |
| 21 writer.BuildJSONString(node, 0); | 30 writer.BuildJSONString(node, 0, escape); |
| 22 if (pretty_print) | 31 if (pretty_print) |
| 23 json->append(kPrettyPrintLineEnding); | 32 json->append(kPrettyPrintLineEnding); |
| 24 } | 33 } |
| 25 | 34 |
| 26 JSONWriter::JSONWriter(bool pretty_print, std::string* json) | 35 JSONWriter::JSONWriter(bool pretty_print, std::string* json) |
| 27 : json_string_(json), | 36 : json_string_(json), |
| 28 pretty_print_(pretty_print) { | 37 pretty_print_(pretty_print) { |
| 29 DCHECK(json); | 38 DCHECK(json); |
| 30 } | 39 } |
| 31 | 40 |
| 32 void JSONWriter::BuildJSONString(const Value* const node, int depth) { | 41 void JSONWriter::BuildJSONString(const Value* const node, |
| 42 int depth, |
| 43 bool escape) { |
| 33 switch(node->GetType()) { | 44 switch(node->GetType()) { |
| 34 case Value::TYPE_NULL: | 45 case Value::TYPE_NULL: |
| 35 json_string_->append("null"); | 46 json_string_->append("null"); |
| 36 break; | 47 break; |
| 37 | 48 |
| 38 case Value::TYPE_BOOLEAN: | 49 case Value::TYPE_BOOLEAN: |
| 39 { | 50 { |
| 40 bool value; | 51 bool value; |
| 41 bool result = node->GetAsBoolean(&value); | 52 bool result = node->GetAsBoolean(&value); |
| 42 DCHECK(result); | 53 DCHECK(result); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') { | 85 } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') { |
| 75 // "-.1" bad "-0.1" good | 86 // "-.1" bad "-0.1" good |
| 76 real.insert(1, "0"); | 87 real.insert(1, "0"); |
| 77 } | 88 } |
| 78 json_string_->append(real); | 89 json_string_->append(real); |
| 79 break; | 90 break; |
| 80 } | 91 } |
| 81 | 92 |
| 82 case Value::TYPE_STRING: | 93 case Value::TYPE_STRING: |
| 83 { | 94 { |
| 84 std::wstring value; | 95 if (escape) { |
| 85 bool result = node->GetAsString(&value); | 96 std::wstring value; |
| 86 DCHECK(result); | 97 bool result = node->GetAsString(&value); |
| 87 AppendQuotedString(value); | 98 DCHECK(result); |
| 99 AppendQuotedString(value); |
| 100 } else { |
| 101 std::string value; |
| 102 bool result = node->GetAsString(&value); |
| 103 DCHECK(result); |
| 104 string_escape::JavascriptDoubleQuote(value, true, json_string_); |
| 105 } |
| 88 break; | 106 break; |
| 89 } | 107 } |
| 90 | 108 |
| 91 case Value::TYPE_LIST: | 109 case Value::TYPE_LIST: |
| 92 { | 110 { |
| 93 json_string_->append("["); | 111 json_string_->append("["); |
| 94 if (pretty_print_) | 112 if (pretty_print_) |
| 95 json_string_->append(" "); | 113 json_string_->append(" "); |
| 96 | 114 |
| 97 const ListValue* list = static_cast<const ListValue*>(node); | 115 const ListValue* list = static_cast<const ListValue*>(node); |
| 98 for (size_t i = 0; i < list->GetSize(); ++i) { | 116 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 99 if (i != 0) { | 117 if (i != 0) { |
| 100 json_string_->append(","); | 118 json_string_->append(","); |
| 101 if (pretty_print_) | 119 if (pretty_print_) |
| 102 json_string_->append(" "); | 120 json_string_->append(" "); |
| 103 } | 121 } |
| 104 | 122 |
| 105 Value* value = NULL; | 123 Value* value = NULL; |
| 106 bool result = list->Get(i, &value); | 124 bool result = list->Get(i, &value); |
| 107 DCHECK(result); | 125 DCHECK(result); |
| 108 BuildJSONString(value, depth); | 126 BuildJSONString(value, depth, escape); |
| 109 } | 127 } |
| 110 | 128 |
| 111 if (pretty_print_) | 129 if (pretty_print_) |
| 112 json_string_->append(" "); | 130 json_string_->append(" "); |
| 113 json_string_->append("]"); | 131 json_string_->append("]"); |
| 114 break; | 132 break; |
| 115 } | 133 } |
| 116 | 134 |
| 117 case Value::TYPE_DICTIONARY: | 135 case Value::TYPE_DICTIONARY: |
| 118 { | 136 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 137 DCHECK(result); | 155 DCHECK(result); |
| 138 | 156 |
| 139 if (pretty_print_) | 157 if (pretty_print_) |
| 140 IndentLine(depth + 1); | 158 IndentLine(depth + 1); |
| 141 AppendQuotedString(*key_itr); | 159 AppendQuotedString(*key_itr); |
| 142 if (pretty_print_) { | 160 if (pretty_print_) { |
| 143 json_string_->append(": "); | 161 json_string_->append(": "); |
| 144 } else { | 162 } else { |
| 145 json_string_->append(":"); | 163 json_string_->append(":"); |
| 146 } | 164 } |
| 147 BuildJSONString(value, depth + 1); | 165 BuildJSONString(value, depth + 1, escape); |
| 148 } | 166 } |
| 149 | 167 |
| 150 if (pretty_print_) { | 168 if (pretty_print_) { |
| 151 json_string_->append(kPrettyPrintLineEnding); | 169 json_string_->append(kPrettyPrintLineEnding); |
| 152 IndentLine(depth); | 170 IndentLine(depth); |
| 153 json_string_->append("}"); | 171 json_string_->append("}"); |
| 154 } else { | 172 } else { |
| 155 json_string_->append("}"); | 173 json_string_->append("}"); |
| 156 } | 174 } |
| 157 break; | 175 break; |
| 158 } | 176 } |
| 159 | 177 |
| 160 default: | 178 default: |
| 161 // TODO(jhughes): handle TYPE_BINARY | 179 // TODO(jhughes): handle TYPE_BINARY |
| 162 NOTREACHED() << "unknown json type"; | 180 NOTREACHED() << "unknown json type"; |
| 163 } | 181 } |
| 164 } | 182 } |
| 165 | 183 |
| 166 void JSONWriter::AppendQuotedString(const std::wstring& str) { | 184 void JSONWriter::AppendQuotedString(const std::wstring& str) { |
| 167 string_escape::JavascriptDoubleQuote(WideToUTF16Hack(str), true, | 185 string_escape::JavascriptDoubleQuote(WideToUTF16Hack(str), |
| 186 true, |
| 168 json_string_); | 187 json_string_); |
| 169 } | 188 } |
| 170 | 189 |
| 171 void JSONWriter::IndentLine(int depth) { | 190 void JSONWriter::IndentLine(int depth) { |
| 172 // It may be faster to keep an indent string so we don't have to keep | 191 // It may be faster to keep an indent string so we don't have to keep |
| 173 // reallocating. | 192 // reallocating. |
| 174 json_string_->append(std::string(depth * 3, ' ')); | 193 json_string_->append(std::string(depth * 3, ' ')); |
| 175 } | 194 } |
| OLD | NEW |