summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-08 22:55:29 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-08 22:55:29 +0000
commitba4fb5addfd5c0c824491e8ae11743c5fc31cdb3 (patch)
tree6c90e62b21e4982c6cec6476031a8e2c809d0c13
parented14b69482323b94341233951e1ac7edee5fa424 (diff)
downloadchromium_src-ba4fb5addfd5c0c824491e8ae11743c5fc31cdb3.zip
chromium_src-ba4fb5addfd5c0c824491e8ae11743c5fc31cdb3.tar.gz
chromium_src-ba4fb5addfd5c0c824491e8ae11743c5fc31cdb3.tar.bz2
Add a new option to JSONWriter, which instructs it not to append '.0' or
use exponential notation when writing doubles with no fractional part. This is needed so we can write an integer value larger than what a 32-bit int will hold using a double, and write the said double in such a way as to enable external JSON readers (that support int64) to convert it to an int64 instead of a double. The other alternative is to add support for int64 in the Value classes and clients. See http://codereview.chromium.org/8962042 BUG=none TEST=none Review URL: http://codereview.chromium.org/9016024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@125705 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/json/json_writer.cc25
-rw-r--r--base/json/json_writer.h13
-rw-r--r--base/json/json_writer_unittest.cc10
-rw-r--r--chrome/test/webdriver/commands/response.cc10
-rw-r--r--chrome/test/webdriver/webdriver_logging.cc11
5 files changed, 49 insertions, 20 deletions
diff --git a/base/json/json_writer.cc b/base/json/json_writer.cc
index f457331..27300c0 100644
--- a/base/json/json_writer.cc
+++ b/base/json/json_writer.cc
@@ -1,9 +1,11 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/json/json_writer.h"
+#include <cmath>
+
#include "base/json/string_escape.h"
#include "base/logging.h"
#include "base/stringprintf.h"
@@ -40,7 +42,10 @@ void JSONWriter::WriteWithOptions(const Value* const node,
JSONWriter writer(pretty_print, json);
bool escape = !(options & OPTIONS_DO_NOT_ESCAPE);
bool omit_binary_values = !!(options & OPTIONS_OMIT_BINARY_VALUES);
- writer.BuildJSONString(node, 0, escape, omit_binary_values);
+ bool omit_double_type_preservation =
+ !!(options & OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION);
+ writer.BuildJSONString(node, 0, escape, omit_binary_values,
+ omit_double_type_preservation);
if (pretty_print)
json->append(kPrettyPrintLineEnding);
}
@@ -54,7 +59,8 @@ JSONWriter::JSONWriter(bool pretty_print, std::string* json)
void JSONWriter::BuildJSONString(const Value* const node,
int depth,
bool escape,
- bool omit_binary_values) {
+ bool omit_binary_values,
+ bool omit_double_type_preservation) {
switch (node->GetType()) {
case Value::TYPE_NULL:
json_string_->append("null");
@@ -83,6 +89,13 @@ void JSONWriter::BuildJSONString(const Value* const node,
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
@@ -139,7 +152,8 @@ void JSONWriter::BuildJSONString(const Value* const node,
json_string_->append(" ");
}
- BuildJSONString(value, depth, escape, omit_binary_values);
+ BuildJSONString(value, depth, escape, omit_binary_values,
+ omit_double_type_preservation);
}
if (pretty_print_)
@@ -181,7 +195,8 @@ void JSONWriter::BuildJSONString(const Value* const node,
} else {
json_string_->append(":");
}
- BuildJSONString(value, depth + 1, escape, omit_binary_values);
+ BuildJSONString(value, depth + 1, escape, omit_binary_values,
+ omit_double_type_preservation);
}
if (pretty_print_) {
diff --git a/base/json/json_writer.h b/base/json/json_writer.h
index 88c7d58..43f8e56 100644
--- a/base/json/json_writer.h
+++ b/base/json/json_writer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -25,7 +25,13 @@ class BASE_EXPORT JSONWriter {
// For values of binary type, the value (and key if within a dictionary)
// will be omitted from the output.
- OPTIONS_OMIT_BINARY_VALUES = 1 << 1
+ OPTIONS_OMIT_BINARY_VALUES = 1 << 1,
+
+ // This option instructs the writer to write doubles that have no fractional
+ // part as a normal integer (i.e., without using exponential notation
+ // or appending a '.0') as long as the value is within the range of a
+ // 64-bit int.
+ OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION = 1 << 2
};
// Given a root node, generates a JSON string and puts it into |json|.
@@ -53,7 +59,8 @@ class BASE_EXPORT JSONWriter {
// Called recursively to build the JSON string. Whe completed, value is
// json_string_ will contain the JSON.
void BuildJSONString(const Value* const node, int depth, bool escape,
- bool ignore_binary_values);
+ bool ignore_binary_values,
+ bool omit_double_type_preservation);
// Appends a quoted, escaped, version of (UTF-8) str to json_string_.
void AppendQuotedString(const std::string& str);
diff --git a/base/json/json_writer_unittest.cc b/base/json/json_writer_unittest.cc
index 5d44c02..6e73f94 100644
--- a/base/json/json_writer_unittest.cc
+++ b/base/json/json_writer_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -119,6 +119,14 @@ TEST(JSONWriterTest, Writing) {
JSONWriter::OPTIONS_OMIT_BINARY_VALUES,
&output_js);
ASSERT_EQ("{\"a\":5,\"c\":2}", output_js);
+
+ // Test allowing a double with no fractional part to be written as an integer.
+ FundamentalValue double_value(1e10);
+ JSONWriter::WriteWithOptions(
+ &double_value, false,
+ JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION,
+ &output_js);
+ ASSERT_EQ("10000000000", output_js);
}
} // namespace base
diff --git a/chrome/test/webdriver/commands/response.cc b/chrome/test/webdriver/commands/response.cc
index bef1386..5fece6d 100644
--- a/chrome/test/webdriver/commands/response.cc
+++ b/chrome/test/webdriver/commands/response.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -71,7 +71,13 @@ const Value* Response::GetDictionary() const {
std::string Response::ToJSON() const {
std::string json;
- base::JSONWriter::Write(&data_, false, &json);
+ // The |Value| classes do not support int64 and in rare cases we need to
+ // return one. We do this by using a double and passing in the special
+ // option so that the JSONWriter doesn't add '.0' to the end and confuse
+ // the WebDriver client.
+ base::JSONWriter::WriteWithOptions(
+ &data_, false,
+ base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION, &json);
return json;
}
diff --git a/chrome/test/webdriver/webdriver_logging.cc b/chrome/test/webdriver/webdriver_logging.cc
index 26f5bb5..feae90c 100644
--- a/chrome/test/webdriver/webdriver_logging.cc
+++ b/chrome/test/webdriver/webdriver_logging.cc
@@ -161,17 +161,10 @@ InMemoryLog::~InMemoryLog() { }
void InMemoryLog::Log(LogLevel level, const base::Time& time,
const std::string& message) {
- // base's JSONWriter doesn't obey the spec, and writes
- // doubles without a fraction with a '.0' postfix. base's Value class
- // only includes doubles or int types. Instead of returning the timestamp
- // in unix epoch time, we return it based on the start of chromedriver so
- // a 32-bit int doesn't overflow.
- // TODO(kkania): Add int64_t to base Values or fix the JSONWriter/Reader and
- // use unix epoch time.
- base::TimeDelta delta(time - base::Time::FromDoubleT(start_time));
+ base::TimeDelta delta = time - base::Time::UnixEpoch();
DictionaryValue* entry = new DictionaryValue();
entry->SetInteger("level", level);
- entry->SetInteger("timestamp", delta.InMilliseconds());
+ entry->SetDouble("timestamp", std::floor(delta.InMillisecondsF()));
entry->SetString("message", message);
base::AutoLock auto_lock(entries_lock_);
entries_list_.Append(entry);