diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-10 20:59:53 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-10 20:59:53 +0000 |
commit | e8f3f9981fe331526bc5db64cda1e4fce73d35f3 (patch) | |
tree | be0b433463a8f80c47f8da5b137a7aaae0f1fdef /chromeos/system | |
parent | fb49c9e221dd702608210c19c98556467cd36400 (diff) | |
download | chromium_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.cc | 149 | ||||
-rw-r--r-- | chromeos/system/name_value_pairs_parser.h | 83 | ||||
-rw-r--r-- | chromeos/system/name_value_pairs_parser_unittest.cc | 119 |
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 |