summaryrefslogtreecommitdiffstats
path: root/chromeos/system
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-10 20:59:53 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-10 20:59:53 +0000
commite8f3f9981fe331526bc5db64cda1e4fce73d35f3 (patch)
treebe0b433463a8f80c47f8da5b137a7aaae0f1fdef /chromeos/system
parentfb49c9e221dd702608210c19c98556467cd36400 (diff)
downloadchromium_src-e8f3f9981fe331526bc5db64cda1e4fce73d35f3.zip
chromium_src-e8f3f9981fe331526bc5db64cda1e4fce73d35f3.tar.gz
chromium_src-e8f3f9981fe331526bc5db64cda1e4fce73d35f3.tar.bz2
[chromeos] Remove dependencies of StatisticsProvider on chrome.
This is a resubmit of https://codereview.chromium.org/14643006 with compile error fixed. TBR=davemoore BUG=180711 Review URL: https://codereview.chromium.org/14982005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@199534 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/system')
-rw-r--r--chromeos/system/name_value_pairs_parser.cc149
-rw-r--r--chromeos/system/name_value_pairs_parser.h83
-rw-r--r--chromeos/system/name_value_pairs_parser_unittest.cc119
3 files changed, 351 insertions, 0 deletions
diff --git a/chromeos/system/name_value_pairs_parser.cc b/chromeos/system/name_value_pairs_parser.cc
new file mode 100644
index 0000000..df65d50
--- /dev/null
+++ b/chromeos/system/name_value_pairs_parser.cc
@@ -0,0 +1,149 @@
+// 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 "chromeos/system/name_value_pairs_parser.h"
+
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/process_util.h"
+#include "base/stl_util.h"
+#include "base/string_util.h"
+#include "base/strings/string_tokenizer.h"
+
+namespace chromeos { // NOLINT
+namespace system {
+
+namespace {
+
+const char kQuoteChars[] = "\"";
+const char kTrimChars[] = "\" ";
+
+bool GetToolOutput(int argc, const char* argv[], std::string& output) {
+ DCHECK_GE(argc, 1);
+
+ if (!file_util::PathExists(base::FilePath(argv[0]))) {
+ LOG(WARNING) << "Tool for statistics not found: " << argv[0];
+ return false;
+ }
+
+ std::vector<std::string> args;
+ for (int argn = 0; argn < argc; ++argn)
+ args.push_back(argv[argn]);
+ if (!base::GetAppOutput(args, &output)) {
+ LOG(WARNING) << "Error executing " << argv[0];
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace
+
+NameValuePairsParser::NameValuePairsParser(NameValueMap* map)
+ : map_(map) {
+}
+
+void NameValuePairsParser::AddNameValuePair(const std::string& key,
+ const std::string& value) {
+ if (!ContainsKey(*map_, key)) {
+ (*map_)[key] = value;
+ VLOG(1) << "name: " << key << ", value: " << value;
+ } else {
+ LOG(WARNING) << "Key " << key << " already has value " << (*map_)[key]
+ << ", ignoring new value: " << value;
+ }
+}
+
+bool NameValuePairsParser::ParseNameValuePairs(const std::string& in_string,
+ const std::string& eq,
+ const std::string& delim) {
+ return ParseNameValuePairsWithComments(in_string, eq, delim, "");
+}
+
+bool NameValuePairsParser::ParseNameValuePairsWithComments(
+ const std::string& in_string,
+ const std::string& eq,
+ const std::string& delim,
+ const std::string& comment_delim) {
+ bool all_valid = true;
+ // Set up the pair tokenizer.
+ base::StringTokenizer pair_toks(in_string, delim);
+ pair_toks.set_quote_chars(kQuoteChars);
+ // Process token pairs.
+ while (pair_toks.GetNext()) {
+ std::string pair(pair_toks.token());
+ // Anything before the first |eq| is the key, anything after is the value.
+ // |eq| must exist.
+ size_t eq_pos = pair.find(eq);
+ if (eq_pos != std::string::npos) {
+ // First |comment_delim| after |eq_pos| starts the comment.
+ // A value of |std::string::npos| means that the value spans to the end
+ // of |pair|.
+ size_t value_size = std::string::npos;
+ if (!comment_delim.empty()) {
+ size_t comment_pos = pair.find(comment_delim, eq_pos + 1);
+ if (comment_pos != std::string::npos)
+ value_size = comment_pos - eq_pos - 1;
+ }
+
+ std::string key;
+ std::string value;
+ TrimString(pair.substr(0, eq_pos), kTrimChars, &key);
+ TrimString(pair.substr(eq_pos + 1, value_size), kTrimChars, &value);
+
+ if (!key.empty()) {
+ AddNameValuePair(key, value);
+ continue;
+ }
+ }
+
+ LOG(WARNING) << "Invalid token pair: " << pair << ". Ignoring.";
+ all_valid = false;
+ }
+ return all_valid;
+}
+
+bool NameValuePairsParser::GetSingleValueFromTool(int argc,
+ const char* argv[],
+ const std::string& key) {
+ std::string output_string;
+ if (!GetToolOutput(argc, argv, output_string))
+ return false;
+
+ TrimWhitespaceASCII(output_string, TRIM_ALL, &output_string);
+ AddNameValuePair(key, output_string);
+ return true;
+}
+
+bool NameValuePairsParser::GetNameValuePairsFromFile(
+ const base::FilePath& file_path,
+ const std::string& eq,
+ const std::string& delim) {
+ std::string contents;
+ if (file_util::ReadFileToString(file_path, &contents)) {
+ return ParseNameValuePairs(contents, eq, delim);
+ } else {
+ LOG(WARNING) << "Unable to read statistics file: " << file_path.value();
+ return false;
+ }
+}
+
+bool NameValuePairsParser::ParseNameValuePairsFromTool(
+ int argc,
+ const char* argv[],
+ const std::string& eq,
+ const std::string& delim,
+ const std::string& comment_delim) {
+ std::string output_string;
+ if (!GetToolOutput(argc, argv, output_string))
+ return false;
+
+ return ParseNameValuePairsWithComments(
+ output_string, eq, delim, comment_delim);
+}
+
+} // namespace system
+} // namespace chromeos
diff --git a/chromeos/system/name_value_pairs_parser.h b/chromeos/system/name_value_pairs_parser.h
new file mode 100644
index 0000000..2cb704b
--- /dev/null
+++ b/chromeos/system/name_value_pairs_parser.h
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef CHROMEOS_SYSTEM_NAME_VALUE_PAIRS_PARSER_H_
+#define CHROMEOS_SYSTEM_NAME_VALUE_PAIRS_PARSER_H_
+
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "chromeos/chromeos_export.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace chromeos {
+namespace system {
+
+// The parser is used to get machine info as name-value pairs. Defined
+// here to be accessible by tests.
+class CHROMEOS_EXPORT NameValuePairsParser {
+ public:
+ typedef std::map<std::string, std::string> NameValueMap;
+
+ // The obtained info will be written into the given map.
+ explicit NameValuePairsParser(NameValueMap* map);
+
+ void AddNameValuePair(const std::string& key, const std::string& value);
+
+ // Executes tool and inserts (key, <output>) into map_.
+ // The program name (argv[0]) should be an absolute path. The function
+ // checks if the program exists before executing it as some programs
+ // don't exist on Linux desktop; returns false in that case.
+ bool GetSingleValueFromTool(int argc, const char* argv[],
+ const std::string& key);
+
+ // Parses name-value pairs from the file.
+ // Returns false if there was any error in the file. Valid pairs will still be
+ // added to the map.
+ bool GetNameValuePairsFromFile(const base::FilePath& file_path,
+ const std::string& eq,
+ const std::string& delim);
+
+ // These will parse strings with output in the format:
+ // <key><EQ><value><DELIM>[<key><EQ><value>][...]
+ // e.g. ParseNameValuePairs("key1=value1 key2=value2", "=", " ")
+ // Returns false if there was any error in in_string. Valid pairs will still
+ // be added to the map.
+ bool ParseNameValuePairs(const std::string& in_string,
+ const std::string& eq,
+ const std::string& delim);
+
+ // This version allows for values which end with a comment
+ // beginning with comment_delim.
+ // e.g. "key2=value2 # Explanation of value\n"
+ // Returns false if there was any error in in_string. Valid pairs will still
+ // be added to the map.
+ bool ParseNameValuePairsWithComments(const std::string& in_string,
+ const std::string& eq,
+ const std::string& delim,
+ const std::string& comment_delim);
+
+ // Same as ParseNameValuePairsWithComments(), but uses the output of the given
+ // tool as the input to parse.
+ bool ParseNameValuePairsFromTool(
+ int argc,
+ const char* argv[],
+ const std::string& eq,
+ const std::string& delim,
+ const std::string& comment_delim);
+
+ private:
+ NameValueMap* map_;
+
+ DISALLOW_COPY_AND_ASSIGN(NameValuePairsParser);
+};
+
+} // namespace system
+} // namespace chromeos
+
+#endif // CHROMEOS_SYSTEM_NAME_VALUE_PAIRS_PARSER_H_
diff --git a/chromeos/system/name_value_pairs_parser_unittest.cc b/chromeos/system/name_value_pairs_parser_unittest.cc
new file mode 100644
index 0000000..e627521
--- /dev/null
+++ b/chromeos/system/name_value_pairs_parser_unittest.cc
@@ -0,0 +1,119 @@
+// 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 "chromeos/system/name_value_pairs_parser.h"
+
+#include "base/basictypes.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace system {
+
+TEST(NameValuePairsParser, TestGetSingleValueFromTool) {
+ NameValuePairsParser::NameValueMap map;
+ NameValuePairsParser parser(&map);
+ const char* command[] = { "/bin/echo", "Foo" };
+ EXPECT_TRUE(parser.GetSingleValueFromTool(arraysize(command), command,
+ "foo"));
+ ASSERT_EQ(1U, map.size());
+ EXPECT_EQ("Foo", map["foo"]);
+}
+
+TEST(NameValuePairsParser, TestParseNameValuePairs) {
+ NameValuePairsParser::NameValueMap map;
+ NameValuePairsParser parser(&map);
+ const std::string contents1 = "foo=Foo bar=Bar\nfoobar=FooBar\n";
+ EXPECT_TRUE(parser.ParseNameValuePairs(contents1, "=", " \n"));
+ EXPECT_EQ(3U, map.size());
+ EXPECT_EQ("Foo", map["foo"]);
+ EXPECT_EQ("Bar", map["bar"]);
+ EXPECT_EQ("FooBar", map["foobar"]);
+
+ map.clear();
+ const std::string contents2 = "foo=Foo,bar=Bar";
+ EXPECT_TRUE(parser.ParseNameValuePairs(contents2, "=", ",\n"));
+ EXPECT_EQ(2U, map.size());
+ EXPECT_EQ("Foo", map["foo"]);
+ EXPECT_EQ("Bar", map["bar"]);
+
+ map.clear();
+ const std::string contents3 = "foo=Foo=foo,bar=Bar";
+ EXPECT_TRUE(parser.ParseNameValuePairs(contents3, "=", ",\n"));
+ EXPECT_EQ(2U, map.size());
+ EXPECT_EQ("Foo=foo", map["foo"]);
+ EXPECT_EQ("Bar", map["bar"]);
+
+ map.clear();
+ const std::string contents4 = "foo=Foo,=Bar";
+ EXPECT_FALSE(parser.ParseNameValuePairs(contents4, "=", ",\n"));
+ EXPECT_EQ(1U, map.size());
+ EXPECT_EQ("Foo", map["foo"]);
+
+ map.clear();
+ const std::string contents5 =
+ "\"initial_locale\"=\"ja\"\n"
+ "\"initial_timezone\"=\"Asia/Tokyo\"\n"
+ "\"keyboard_layout\"=\"mozc-jp\"\n";
+ EXPECT_TRUE(parser.ParseNameValuePairs(contents5, "=", "\n"));
+ EXPECT_EQ(3U, map.size());
+ EXPECT_EQ("ja", map["initial_locale"]);
+ EXPECT_EQ("Asia/Tokyo", map["initial_timezone"]);
+ EXPECT_EQ("mozc-jp", map["keyboard_layout"]);
+}
+
+TEST(NameValuePairsParser, TestParseNameValuePairsWithComments) {
+ NameValuePairsParser::NameValueMap map;
+ NameValuePairsParser parser(&map);
+
+ const std::string contents1 = "foo=Foo,bar=#Bar,baz= 0 #Baz";
+ EXPECT_TRUE(parser.ParseNameValuePairsWithComments(
+ contents1, "=", ",\n", "#"));
+ EXPECT_EQ(3U, map.size());
+ EXPECT_EQ("Foo", map["foo"]);
+ EXPECT_EQ("", map["bar"]);
+ EXPECT_EQ("0", map["baz"]);
+
+ map.clear();
+ const std::string contents2 = "foo=";
+ EXPECT_TRUE(parser.ParseNameValuePairsWithComments(
+ contents2, "=", ",\n", "#"));
+ EXPECT_EQ(1U, map.size());
+ EXPECT_EQ("", map["foo"]);
+
+ map.clear();
+ const std::string contents3 = " \t ,,#all empty,";
+ EXPECT_FALSE(parser.ParseNameValuePairsWithComments(
+ contents3, "=", ",\n", "#"));
+ EXPECT_EQ(0U, map.size());
+}
+
+TEST(NameValuePairsParser, TestParseNameValuePairsFromTool) {
+ // Sample output is taken from the /usr/bin/crosssytem tool.
+ const char* command[] = { "/bin/echo",
+ "arch = x86 # Platform architecture\n" \
+ "cros_debug = 1 # OS should allow debug\n" \
+ "dbg_reset = (error) # Debug reset mode request\n" \
+ "key#with_comment = some value # Multiple # comment # delims\n" \
+ "key = # No value.\n" \
+ "vdat_timers = " \
+ "LFS=0,0 LF=1784220250,2971030570 LK=9064076660,9342689170 " \
+ "# Timer values from VbSharedData\n"
+ };
+
+ NameValuePairsParser::NameValueMap map;
+ NameValuePairsParser parser(&map);
+ parser.ParseNameValuePairsFromTool(
+ arraysize(command), command, "=", "\n", "#");
+ EXPECT_EQ(6u, map.size());
+ EXPECT_EQ("x86", map["arch"]);
+ EXPECT_EQ("1", map["cros_debug"]);
+ EXPECT_EQ("(error)", map["dbg_reset"]);
+ EXPECT_EQ("some value", map["key#with_comment"]);
+ EXPECT_EQ("", map["key"]);
+ EXPECT_EQ("LFS=0,0 LF=1784220250,2971030570 LK=9064076660,9342689170",
+ map["vdat_timers"]);
+}
+
+} // namespace system
+} // namespace chromeos