Index: base/json/json_writer.cc |
diff --git a/base/json/json_writer.cc b/base/json/json_writer.cc |
index e32a71671f4c4295e4bc1cf0630f7cab54a2ee47..35011281b4cf1815e75835a0b572c2fceb279b79 100644 |
--- a/base/json/json_writer.cc |
+++ b/base/json/json_writer.cc |
@@ -21,22 +21,24 @@ const char kPrettyPrintLineEnding[] = "\n"; |
#endif |
// static |
-void JSONWriter::Write(const Value* const node, std::string* json) { |
- WriteWithOptions(node, 0, json); |
+bool JSONWriter::Write(const Value* const node, std::string* json) { |
+ return WriteWithOptions(node, 0, json); |
} |
// static |
-void JSONWriter::WriteWithOptions(const Value* const node, int options, |
+bool JSONWriter::WriteWithOptions(const Value* const node, int options, |
std::string* json) { |
json->clear(); |
// Is there a better way to estimate the size of the output? |
json->reserve(1024); |
JSONWriter writer(options, json); |
- writer.BuildJSONString(node, 0U); |
+ bool result = writer.BuildJSONString(node, 0U); |
if (options & OPTIONS_PRETTY_PRINT) |
json->append(kPrettyPrintLineEnding); |
+ |
+ return result; |
} |
JSONWriter::JSONWriter(int options, std::string* json) |
@@ -48,154 +50,153 @@ JSONWriter::JSONWriter(int options, std::string* json) |
DCHECK(json); |
} |
-void JSONWriter::BuildJSONString(const Value* const node, size_t depth) { |
+bool JSONWriter::BuildJSONString(const Value* const node, size_t depth) { |
gab
2014/02/04 20:27:35
Why return a bool? It seems the only way this can
|
switch (node->GetType()) { |
case Value::TYPE_NULL: |
json_string_->append("null"); |
- break; |
- |
- case Value::TYPE_BOOLEAN: |
- { |
- bool value; |
- bool result = node->GetAsBoolean(&value); |
- DCHECK(result); |
- json_string_->append(value ? "true" : "false"); |
- break; |
- } |
- |
- case Value::TYPE_INTEGER: |
- { |
- int value; |
- bool result = node->GetAsInteger(&value); |
- DCHECK(result); |
- json_string_->append(IntToString(value)); |
- break; |
+ return true; |
+ |
+ case Value::TYPE_BOOLEAN: { |
gab
2014/02/04 20:27:35
I had also tried to fix the indent in my previous
|
+ bool value; |
+ bool result = node->GetAsBoolean(&value); |
+ DCHECK(result); |
+ json_string_->append(value ? "true" : "false"); |
+ return result; |
+ } |
+ |
+ case Value::TYPE_INTEGER: { |
+ int value; |
+ bool result = node->GetAsInteger(&value); |
+ DCHECK(result); |
+ json_string_->append(IntToString(value)); |
+ return result; |
+ } |
+ |
+ case Value::TYPE_DOUBLE: { |
+ double value; |
+ bool result = node->GetAsDouble(&value); |
+ DCHECK(result); |
+ if (omit_double_type_preservation_ && |
+ value <= kint64max && |
+ value >= kint64min && |
+ std::floor(value) == value) { |
+ json_string_->append(Int64ToString(static_cast<int64>(value))); |
+ return result; |
} |
- |
- case Value::TYPE_DOUBLE: |
- { |
- double value; |
- bool result = node->GetAsDouble(&value); |
- DCHECK(result); |
- if (omit_double_type_preservation_ && |
- value <= kint64max && |
- value >= kint64min && |
- std::floor(value) == value) { |
- json_string_->append(Int64ToString(static_cast<int64>(value))); |
- break; |
- } |
- std::string real = DoubleToString(value); |
- // Ensure that the number has a .0 if there's no decimal or 'e'. This |
- // makes sure that when we read the JSON back, it's interpreted as a |
- // real rather than an int. |
- if (real.find('.') == std::string::npos && |
- real.find('e') == std::string::npos && |
- real.find('E') == std::string::npos) { |
- real.append(".0"); |
- } |
- // The JSON spec requires that non-integer values in the range (-1,1) |
- // have a zero before the decimal point - ".52" is not valid, "0.52" is. |
- if (real[0] == '.') { |
- real.insert(0U, 1U, '0'); |
- } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') { |
- // "-.1" bad "-0.1" good |
- real.insert(1U, 1U, '0'); |
- } |
- json_string_->append(real); |
- break; |
+ std::string real = DoubleToString(value); |
+ // Ensure that the number has a .0 if there's no decimal or 'e'. This |
+ // makes sure that when we read the JSON back, it's interpreted as a |
+ // real rather than an int. |
+ if (real.find('.') == std::string::npos && |
+ real.find('e') == std::string::npos && |
+ real.find('E') == std::string::npos) { |
+ real.append(".0"); |
} |
- |
- case Value::TYPE_STRING: |
- { |
- std::string value; |
- bool result = node->GetAsString(&value); |
- DCHECK(result); |
- EscapeJSONString(value, true, json_string_); |
- break; |
+ // The JSON spec requires that non-integer values in the range (-1,1) |
+ // have a zero before the decimal point - ".52" is not valid, "0.52" is. |
+ if (real[0] == '.') { |
+ real.insert(0U, 1U, '0'); |
+ } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') { |
+ // "-.1" bad "-0.1" good |
+ real.insert(1U, 1U, '0'); |
} |
+ json_string_->append(real); |
+ return result; |
+ } |
+ |
+ case Value::TYPE_STRING: { |
+ std::string value; |
+ bool result = node->GetAsString(&value); |
+ DCHECK(result); |
+ EscapeJSONString(value, true, json_string_); |
+ return result; |
+ } |
+ |
+ case Value::TYPE_LIST: { |
+ json_string_->push_back('['); |
+ if (pretty_print_) |
+ json_string_->push_back(' '); |
+ |
+ const ListValue* list; |
+ bool first_value_output = false; |
+ bool result = node->GetAsList(&list); |
+ DCHECK(result); |
+ for (ListValue::const_iterator it = list->begin(); it != list->end(); |
+ ++it) { |
+ const Value* value = *it; |
+ if (omit_binary_values_ && value->GetType() == Value::TYPE_BINARY) |
+ continue; |
+ |
+ if (first_value_output) { |
+ json_string_->push_back(','); |
+ if (pretty_print_) |
+ json_string_->push_back(' '); |
+ } |
- case Value::TYPE_LIST: |
- { |
- json_string_->push_back('['); |
- if (pretty_print_) |
- json_string_->push_back(' '); |
- |
- const ListValue* list = static_cast<const ListValue*>(node); |
- for (ListValue::const_iterator it = list->begin(); it != list->end(); |
- ++it) { |
- const Value* value = *it; |
+ if (!BuildJSONString(value, depth)) |
+ result = false; |
- if (omit_binary_values_ && value->GetType() == Value::TYPE_BINARY) |
- continue; |
+ first_value_output = true; |
+ } |
- if (it != list->begin()) { |
- json_string_->push_back(','); |
- if (pretty_print_) |
- json_string_->push_back(' '); |
- } |
+ if (pretty_print_) |
+ json_string_->push_back(' '); |
+ json_string_->push_back(']'); |
+ return result; |
+ } |
+ |
+ case Value::TYPE_DICTIONARY: { |
+ json_string_->push_back('{'); |
+ if (pretty_print_) |
+ json_string_->append(kPrettyPrintLineEnding); |
+ |
+ const DictionaryValue* dict; |
+ bool first_value_output = false; |
+ bool result = node->GetAsDictionary(&dict); |
+ DCHECK(result); |
+ for (DictionaryValue::Iterator itr(*dict); !itr.IsAtEnd(); |
+ itr.Advance()) { |
+ if (omit_binary_values_ && |
+ itr.value().GetType() == Value::TYPE_BINARY) { |
+ continue; |
+ } |
- BuildJSONString(value, depth); |
+ if (first_value_output) { |
+ json_string_->push_back(','); |
+ if (pretty_print_) |
+ json_string_->append(kPrettyPrintLineEnding); |
} |
if (pretty_print_) |
- json_string_->push_back(' '); |
- json_string_->push_back(']'); |
- break; |
- } |
+ IndentLine(depth + 1U); |
- case Value::TYPE_DICTIONARY: |
- { |
- json_string_->push_back('{'); |
+ EscapeJSONString(itr.key(), true, json_string_); |
+ json_string_->push_back(':'); |
if (pretty_print_) |
- json_string_->append(kPrettyPrintLineEnding); |
- |
- const DictionaryValue* dict = |
- static_cast<const DictionaryValue*>(node); |
- bool first_entry = true; |
- for (DictionaryValue::Iterator itr(*dict); !itr.IsAtEnd(); |
- itr.Advance(), first_entry = false) { |
- if (omit_binary_values_ && |
- itr.value().GetType() == Value::TYPE_BINARY) { |
- continue; |
- } |
- |
- if (!first_entry) { |
- json_string_->push_back(','); |
- if (pretty_print_) |
- json_string_->append(kPrettyPrintLineEnding); |
- } |
- |
- if (pretty_print_) |
- IndentLine(depth + 1U); |
+ json_string_->push_back(' '); |
- EscapeJSONString(itr.key(), true, json_string_); |
+ if (!BuildJSONString(&itr.value(), depth + 1U)) |
+ result = false; |
- json_string_->push_back(':'); |
- if (pretty_print_) |
- json_string_->push_back(' '); |
- BuildJSONString(&itr.value(), depth + 1U); |
- } |
+ first_value_output = true; |
+ } |
- if (pretty_print_) { |
- json_string_->append(kPrettyPrintLineEnding); |
- IndentLine(depth); |
- json_string_->push_back('}'); |
- } else { |
- json_string_->push_back('}'); |
- } |
- break; |
+ if (pretty_print_) { |
+ json_string_->append(kPrettyPrintLineEnding); |
+ IndentLine(depth); |
} |
+ json_string_->push_back('}'); |
+ return result; |
+ } |
+ |
case Value::TYPE_BINARY: |
- { |
- if (!omit_binary_values_) { |
- NOTREACHED() << "Cannot serialize binary value."; |
- } |
- break; |
- } |
+ // Successful only if we're allowed to omit it. |
+ return omit_binary_values_; |
default: |
NOTREACHED() << "unknown json type"; |
+ return false; |
} |
} |